Codebase list i3-gaps / upstream/4.18.1
New upstream version 4.18.1 Joseph O'Gorman 4 years ago
586 changed file(s) with 133326 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 BasedOnStyle: google
1 AllowShortIfStatementsOnASingleLine: false
2 AllowShortLoopsOnASingleLine: false
3 AllowShortFunctionsOnASingleLine: None
4 AllowShortBlocksOnASingleLine: false
5 AlwaysBreakBeforeMultilineStrings: false
6 IndentWidth: 4
7 PointerBindsToType: false
8 ColumnLimit: 0
9 SpaceBeforeParens: ControlStatements
10 SortIncludes: false
11 ForEachMacros: [ TAILQ_FOREACH, TAILQ_FOREACH_REVERSE, SLIST_FOREACH, CIRCLEQ_FOREACH, CIRCLEQ_FOREACH_REVERSE, NODES_FOREACH, NODES_FOREACH_REVERSE, FOREACH_NONINTERNAL]
0 root = true
1
2 [*]
3 end_of_line = lf
4 insert_final_newline = true
5 charset = utf-8
6
7 [*.{c,h}]
8 indent_style = space
9 indent_size = 4
10 trim_trailing_whitespace = true
0 dist: trusty
1 services:
2 - docker
3 language: c
4 compiler:
5 - gcc
6 - clang
7 addons:
8 apt:
9 packages:
10 # For https support in HTTP::Tiny.
11 - libio-socket-ssl-perl
12 env:
13 global:
14 - BASENAME="i3wm/travis-base:$(date +'%Y-%m')-$(./travis/ha.sh travis/travis-base.Dockerfile)"
15 - BASENAME_386="i3wm/travis-base-386:$(date +'%Y-%m')-$(./travis/ha.sh travis/travis-base-386.Dockerfile)"
16 - BASENAME_UBUNTU="i3wm/travis-base-ubuntu:$(date +'%Y-%m')-$(./travis/ha.sh travis/travis-base-ubuntu.Dockerfile)"
17 - BASENAME_UBUNTU_386="i3wm/travis-base-ubuntu-386:$(date +'%Y-%m')-$(./travis/ha.sh travis/travis-base-ubuntu-386.Dockerfile)"
18 - secure: "B5IICA8MPx/FKaB50rTPqL8P1NU+Q0yuWl+lElL4+a9xSyLikfm3NzUPHoVwx8lNw2AVK6br7p0OmF7vMFjqAgrgc1cajTtEae5uFRKNUrWLpXM046YgNEYLLIHsQOjInxE+S4O6EFVzsUqsu8aeo2Xhq4sm4iUocG7e5isYgYo=" # DOCKER_PASS
19 - secure: "EIvrq8PG7lRjidppG0RCv4F0X4GP3DT9F5+ixVuGPfhK/hZT3jYC2AVY9G+NnUcXVwQEpW92rlqpftQ/qZ13FoyWokC8ZyoyD06fr5FPCfoFF3OczZwAJzZYkObI/hE9+/hXcylx/Os6N4INd2My1ntGk3JPsWL9riopod5EjSg=" # DOCKER_EMAIL
20 - secure: "hvhBunS4xXTgnIOsk/BPT7I7FrJhvVwCSt5PfxxvMqNaztOJI9BuK7ZrZ5Cy38KyHwlh3VHAH5AaCygJcPauoSQCV3bpnlbaWn3ruq2F0Q697Q5uNf73liXzyUqb9/Zvfvge4y4WWOhP5tVz1C6ZBe/NfhU7pqKLMA+6ads+99c=" # DOCKER_USER
21 - secure: "uJuuefmnJUuEH15ZD8xQilibx7EeBvMHBLoIZ8bgGHeleEImBD0XbD1ypvhYJKpviOmw5BkZmc9bVO8DGDEHYbSlIa2xDlF6vGrwgCEaxcMIhOAhv+dW9C/maJVieLOEPM01/fK2qdKESZaLvlopkWmxZwDyMObI9L7AMW9zQD8=" # BINTRAY_USER
22 - secure: "L3aPSNLySPXtWCW+xf8h/AAdquwNgxyTQpYOwexJmTPav82Qx8uQlp1yJkUmt+a+FLZDFfQeMivaHq0311RvuQVmkAJx49DjaddrwqOJut2UPsoVDn1WeuAcSHIXOq/0H+zgFMr/PGY0HXIsw1mTMhgheGJNqg09BvYWROCEAcA=" # BINTRAY_KEY
23 - secure: "sBMVn4C/WRWgoAytEFGx4CC5O55Q63h02AcuBnb1jXcBm0RenoBpzUPtxSseJwDPUA1o/UkuEDDjm3PosT5NF+dvED01VDFMsPVE11K0u6+avYy3jYXqyUEDW3G2o6Wo/2aqNjmd++8jskBdS9+Cx9gaFbgxfzSp0Yfu3oJm/4c=" # GH_TOKEN
24 install:
25 - if [ -a .git/shallow ]; then git fetch --unshallow; fi
26 - docker pull ${BASENAME} || ./travis/docker-build-and-push.sh ${BASENAME} travis/travis-base.Dockerfile
27 - ./travis/skip-pkg.sh || docker pull ${BASENAME_UBUNTU} || ./travis/docker-build-and-push.sh ${BASENAME_UBUNTU} travis/travis-base-ubuntu.Dockerfile
28 - ./travis/skip-pkg.sh || docker pull ${BASENAME_386} || ./travis/docker-build-and-push.sh ${BASENAME_386} travis/travis-base-386.Dockerfile
29 - ./travis/skip-pkg.sh || docker pull ${BASENAME_UBUNTU_386} || ./travis/docker-build-and-push.sh ${BASENAME_UBUNTU_386} travis/travis-base-ubuntu-386.Dockerfile
30 script:
31 - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/check-safe-wrappers.sh
32 - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/check-formatting.sh
33 - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 -e CC ${BASENAME} /bin/sh -c 'autoreconf -fi && mkdir -p build && cd build && (../configure || (cat config.log; false)) && make -j CFLAGS="-Wformat -Wformat-security -Wextra -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Werror -fno-common"'
34 - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/check-spelling.pl
35 - docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 -e CC ${BASENAME} ./travis/run-tests.sh
36 - ./travis/skip-pkg.sh || docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/debian-build.sh deb/debian-amd64/DIST
37 - ./travis/skip-pkg.sh || docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME_UBUNTU} ./travis/debian-build.sh deb/ubuntu-amd64/DIST
38 - ./travis/skip-pkg.sh || docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME_386} linux32 ./travis/debian-build.sh deb/debian-i386/DIST
39 - ./travis/skip-pkg.sh || docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME_UBUNTU_386} linux32 ./travis/debian-build.sh deb/ubuntu-i386/DIST
40 - ./travis/skip-pkg.sh || docker run -v $PWD:/usr/src/i3/ -w /usr/src/i3 ${BASENAME} ./travis/docs.sh
41 - ./travis/skip-pkg.sh || travis/prep-bintray.sh
42
43 deploy:
44 - provider: bintray
45 file: travis/bintray-autobuild-debian.json
46 user: $BINTRAY_USER
47 key: $BINTRAY_KEY
48 skip_cleanup: true
49 on:
50 branch: next
51 condition: $CC = gcc
52 - provider: bintray
53 file: travis/bintray-autobuild-ubuntu.json
54 user: $BINTRAY_USER
55 key: $BINTRAY_KEY
56 skip_cleanup: true
57 on:
58 branch: next
59 condition: $CC = gcc
60 - provider: script
61 script: travis/deploy-github-pages.sh
62 skip_cleanup: true
63 on:
64 branch: next
65 condition: $CC = gcc
66
67 after_deploy:
68 - travis/cleanup-bintray.pl i3-autobuild
69 - travis/cleanup-bintray.pl i3-autobuild-ubuntu
0 Revision history for AnyEvent-I3
1
2 0.18 2017-08-19
3
4 * support the GET_CONFIG command
5
6 0.17 2017-04-09
7
8 * support the shutdown event
9 * use lib '.' for Perl 5.25.11+
10
11 0.16 2014-10-03
12
13 * support the barconfig_update and binding event
14
15 0.15 2013-02-18
16
17 * support the window event
18
19 0.14 2012-09-22
20
21 * support the mode event
22
23 0.13 2012-08-05
24
25 * support the GET_VERSION request with a fall-back to i3 --version
26
27 0.12 2012-07-11
28
29 * taint mode fix: remove relative directories from $ENV{PATH}
30
31 0.11 2012-07-10
32
33 * taint mode fix for FreeBSD
34
35 0.10 2012-07-09
36
37 * Use i3 --get-socketpath by default for determining the socket path
38 * Bugfix: Also delete callbacks which are triggered due to an error
39
40 0.09 2011-10-12
41
42 * Implement GET_BAR_CONFIG request
43
44 0.08 2011-09-26
45
46 * Implement GET_MARKS request
47 * The synopsis mentioned ->workspaces, but it’s ->get_workspaces
48
49 0.07 2010-11-21
50
51 * Implement GET_TREE request
52
53 0.06 2010-06-16
54
55 * Add check to Makefile to abort in a Windows environment (neither i3 nor
56 unix sockets available)
57
58 0.05 2010-06-09
59
60 * use getpwuid() to resolve ~ in socket paths instead of glob()
61
62 0.04 2010-03-27
63
64 * use new default ipc-socket path, glob() path, bump version
65
66 0.03 2010-03-26
67
68 * fix MANIFEST
69
70 0.02 2010-03-23
71
72 * first upload to CPAN
0 Changes
1 lib/AnyEvent/I3.pm
2 Makefile.PL
3 MANIFEST This list of files
4 MANIFEST.SKIP
5 README
6 t/00-load.t
7 t/01-workspaces.t
8 t/02-sugar.t
9 t/boilerplate.t
10 t/manifest.t
11 t/pod-coverage.t
12 t/pod.t
0 ^\.git/
1 \.bak$
2 blib/
3 ^Makefile$
4 ^Makefile.old$
5 Build
6 Build.bat
7 ^pm_to_blib
8 \.tar\.gz$
9 ^pod2htm(.*).tmp$
10 ^AnyEvent-I3-
11 ^MYMETA.*
12 ^MANIFEST\.bak
0 use strict;
1 use warnings;
2
3 use 5.006;
4 use ExtUtils::MakeMaker;
5
6 if ( $^O eq 'MSWin32' ) {
7 die "AnyEvent::I3 cannot be used on win32 (unix sockets are missing)";
8 }
9
10 my %meta = (
11 name => 'AnyEvent-I3',
12 author => 'Michael Stapelberg, C<< <michael at i3wm.org> >>',
13 license => ['perl'],
14 'meta-spec' => { version => 2 },
15 resources => {
16 repository => {
17 url => 'git://github.com/i3/i3',
18 web => 'https://github.com/i3/i3',
19 type => 'git',
20 },
21 bugtracker => {
22 web => 'https://github.com/i3/i3/issues',
23 },
24 homepage => 'https://i3wm.org/',
25 license => ['https://dev.perl.org/licenses'],
26 },
27 );
28
29 my %requirements = (
30 configure_requires => {
31 'ExtUtils::MakeMaker' => 6.36,
32 },
33 build_requires => {
34 'ExtUtils::MakeMaker' => 6.36
35 },
36 runtime_requires => {
37 'AnyEvent' => 0,
38 'AnyEvent::Handle' => 0,
39 'AnyEvent::Socket' => 0,
40 'JSON::XS' => 0,
41 },
42 test_requires => {
43 'Test::More' => 0.80,
44 },
45 );
46
47 my %merged_requirements = (
48 'ExtUtils::MakeMaker' => 0,
49 'AnyEvent' => 0,
50 'AnyEvent::Handle' => 0,
51 'AnyEvent::Socket' => 0,
52 'JSON::XS' => 0,
53 'Test::More' => 0.80,
54 );
55
56 $meta{prereqs}{configure}{requires} = $requirements{configure_requires};
57 $meta{prereqs}{build}{requires} = $requirements{build_requires};
58 $meta{prereqs}{runtime}{requires} = $requirements{runtime_requires};
59 $meta{prereqs}{test}{requires} = $requirements{test_requires};
60
61 my %MM_Args = (
62 AUTHOR => 'Michael Stapelberg',
63 NAME => 'AnyEvent::I3',
64 DISTNAME => 'AnyEvent-I3',
65 EXE_FILES => [],
66 MIN_PERL_VERSION => '5.006',
67 VERSION_FROM => 'lib/AnyEvent/I3.pm',
68 ABSTRACT_FROM => 'lib/AnyEvent/I3.pm',
69 test => {
70 TESTS => 't/*.t',
71 },
72 );
73
74 sub is_eumm {
75 eval { ExtUtils::MakeMaker->VERSION( $_[0] ) };
76 }
77
78 is_eumm(6.30) and $MM_Args{LICENSE} = $meta{license}[0];
79 is_eumm(6.47_01) or delete $MM_Args{MIN_PERL_VERSION};
80 is_eumm(6.52)
81 and $MM_Args{CONFIGURE_REQUIRES} = $requirements{configure_requires};
82
83 is_eumm(6.57_02) and !is_eumm(6.57_07) and $MM_Args{NO_MYMETA} = 1;
84
85 if ( is_eumm(6.63_03) ) {
86 %MM_Args = (
87 %MM_Args,
88 TEST_REQUIRES => $requirements{test_requires},
89 BUILD_REQUIRES => $requirements{build_requires},
90 PREREQ_PM => $requirements{runtime_requires},
91 );
92 }
93 else {
94 $MM_Args{PREREQ_PM} = \%merged_requirements;
95 }
96 unless ( -f 'META.yml' ) {
97 $MM_Args{META_ADD} = \%meta;
98 }
99 WriteMakefile(%MM_Args);
0 AnyEvent-I3
1
2 This module connects to the i3 window manager using the UNIX socket based
3 IPC interface it provides (if enabled in the configuration file). You can
4 then subscribe to events or send messages and receive their replies.
5
6 INSTALLATION
7
8 To install this module, run the following commands:
9
10 perl Makefile.PL
11 make
12 make test
13 make install
14
15 SUPPORT AND DOCUMENTATION
16
17 After installing, you can find documentation for this module with the
18 perldoc command.
19
20 perldoc AnyEvent::I3
21
22 You can also look for information at:
23
24 RT, CPAN's request tracker
25 https://rt.cpan.org/NoAuth/Bugs.html?Dist=AnyEvent-I3
26
27 The i3 window manager website
28 https://i3wm.org
29
30
31 LICENSE AND COPYRIGHT
32
33 Copyright (C) 2010 Michael Stapelberg
34
35 This program is free software; you can redistribute it and/or modify it
36 under the terms of either: the GNU General Public License as published
37 by the Free Software Foundation; or the Artistic License.
38
39 See https://dev.perl.org/licenses/ for more information.
0 package AnyEvent::I3;
1 # vim:ts=4:sw=4:expandtab
2
3 use strict;
4 use warnings;
5 use JSON::XS;
6 use AnyEvent::Handle;
7 use AnyEvent::Socket;
8 use AnyEvent;
9 use Encode;
10 use Scalar::Util qw(tainted);
11 use Carp;
12
13 =head1 NAME
14
15 AnyEvent::I3 - communicate with the i3 window manager
16
17 =cut
18
19 our $VERSION = '0.18';
20
21 =head1 VERSION
22
23 Version 0.18
24
25 =head1 SYNOPSIS
26
27 This module connects to the i3 window manager using the UNIX socket based
28 IPC interface it provides (if enabled in the configuration file). You can
29 then subscribe to events or send messages and receive their replies.
30
31 use AnyEvent::I3 qw(:all);
32
33 my $i3 = i3();
34
35 $i3->connect->recv or die "Error connecting";
36 say "Connected to i3";
37
38 my $workspaces = $i3->message(TYPE_GET_WORKSPACES)->recv;
39 say "Currently, you use " . @{$workspaces} . " workspaces";
40
41 ...or, using the sugar methods:
42
43 use AnyEvent::I3;
44
45 my $workspaces = i3->get_workspaces->recv;
46 say "Currently, you use " . @{$workspaces} . " workspaces";
47
48 A somewhat more involved example which dumps the i3 layout tree whenever there
49 is a workspace event:
50
51 use Data::Dumper;
52 use AnyEvent;
53 use AnyEvent::I3;
54
55 my $i3 = i3();
56
57 $i3->connect->recv or die "Error connecting to i3";
58
59 $i3->subscribe({
60 workspace => sub {
61 $i3->get_tree->cb(sub {
62 my ($tree) = @_;
63 say "tree: " . Dumper($tree);
64 });
65 }
66 })->recv->{success} or die "Error subscribing to events";
67
68 AE::cv->recv
69
70 =head1 EXPORT
71
72 =head2 $i3 = i3([ $path ]);
73
74 Creates a new C<AnyEvent::I3> object and returns it.
75
76 C<path> is an optional path of the UNIX socket to connect to. It is strongly
77 advised to NOT specify this unless you're absolutely sure you need it.
78 C<AnyEvent::I3> will automatically figure it out by querying the running i3
79 instance on the current DISPLAY which is almost always what you want.
80
81 =head1 SUBROUTINES/METHODS
82
83 =cut
84
85 use Exporter qw(import);
86 use base 'Exporter';
87
88 our @EXPORT = qw(i3);
89
90 use constant TYPE_RUN_COMMAND => 0;
91 use constant TYPE_COMMAND => 0;
92 use constant TYPE_GET_WORKSPACES => 1;
93 use constant TYPE_SUBSCRIBE => 2;
94 use constant TYPE_GET_OUTPUTS => 3;
95 use constant TYPE_GET_TREE => 4;
96 use constant TYPE_GET_MARKS => 5;
97 use constant TYPE_GET_BAR_CONFIG => 6;
98 use constant TYPE_GET_VERSION => 7;
99 use constant TYPE_GET_BINDING_MODES => 8;
100 use constant TYPE_GET_CONFIG => 9;
101 use constant TYPE_SEND_TICK => 10;
102 use constant TYPE_SYNC => 11;
103
104 our %EXPORT_TAGS = ( 'all' => [
105 qw(i3 TYPE_RUN_COMMAND TYPE_COMMAND TYPE_GET_WORKSPACES TYPE_SUBSCRIBE TYPE_GET_OUTPUTS
106 TYPE_GET_TREE TYPE_GET_MARKS TYPE_GET_BAR_CONFIG TYPE_GET_VERSION
107 TYPE_GET_BINDING_MODES TYPE_GET_CONFIG TYPE_SEND_TICK TYPE_SYNC)
108 ] );
109
110 our @EXPORT_OK = ( @{ $EXPORT_TAGS{all} } );
111
112 my $magic = "i3-ipc";
113
114 # TODO: auto-generate this from the header file? (i3/ipc.h)
115 my $event_mask = (1 << 31);
116 my %events = (
117 workspace => ($event_mask | 0),
118 output => ($event_mask | 1),
119 mode => ($event_mask | 2),
120 window => ($event_mask | 3),
121 barconfig_update => ($event_mask | 4),
122 binding => ($event_mask | 5),
123 shutdown => ($event_mask | 6),
124 tick => ($event_mask | 7),
125 _error => 0xFFFFFFFF,
126 );
127
128 sub i3 {
129 AnyEvent::I3->new(@_)
130 }
131
132 # Calls i3, even when running in taint mode.
133 sub _call_i3 {
134 my ($args) = @_;
135
136 my $path_tainted = tainted($ENV{PATH});
137 # This effectively circumvents taint mode checking for $ENV{PATH}. We
138 # do this because users might specify PATH explicitly to call i3 in a
139 # custom location (think ~/.bin/).
140 (local $ENV{PATH}) = ($ENV{PATH} =~ /(.*)/);
141
142 # In taint mode, we also need to remove all relative directories from
143 # PATH (like . or ../bin). We only do this in taint mode and warn the
144 # user, since this might break a real-world use case for some people.
145 if ($path_tainted) {
146 my @dirs = split /:/, $ENV{PATH};
147 my @filtered = grep !/^\./, @dirs;
148 if (scalar @dirs != scalar @filtered) {
149 $ENV{PATH} = join ':', @filtered;
150 warn qq|Removed relative directories from PATH because you | .
151 qq|are running Perl with taint mode enabled. Remove -T | .
152 qq|to be able to use relative directories in PATH. | .
153 qq|New PATH is "$ENV{PATH}"|;
154 }
155 }
156 # Otherwise the qx() operator wont work:
157 delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
158 chomp(my $result = qx(i3 $args));
159 # Circumventing taint mode again: the socket can be anywhere on the
160 # system and that’s okay.
161 if ($result =~ /^([^\0]+)$/) {
162 return $1;
163 }
164
165 warn "Calling i3 $args failed. Is DISPLAY set and is i3 in your PATH?";
166 return undef;
167 }
168
169 =head2 $i3 = AnyEvent::I3->new([ $path ])
170
171 Creates a new C<AnyEvent::I3> object and returns it.
172
173 C<path> is an optional path of the UNIX socket to connect to. It is strongly
174 advised to NOT specify this unless you're absolutely sure you need it.
175 C<AnyEvent::I3> will automatically figure it out by querying the running i3
176 instance on the current DISPLAY which is almost always what you want.
177
178 =cut
179 sub new {
180 my ($class, $path) = @_;
181
182 $path = _call_i3('--get-socketpath') unless $path;
183
184 # This is the old default path (v3.*). This fallback line can be removed in
185 # a year from now. -- Michael, 2012-07-09
186 $path ||= '~/.i3/ipc.sock';
187
188 # Check if we need to resolve ~
189 if ($path =~ /~/) {
190 # We use getpwuid() instead of $ENV{HOME} because the latter is tainted
191 # and thus produces warnings when running tests with perl -T
192 my $home = (getpwuid($<))[7];
193 confess "Could not get home directory" unless $home and -d $home;
194 $path =~ s/~/$home/g;
195 }
196
197 bless { path => $path } => $class;
198 }
199
200 =head2 $i3->connect
201
202 Establishes the connection to i3. Returns an C<AnyEvent::CondVar> which will
203 be triggered with a boolean (true if the connection was established) as soon as
204 the connection has been established.
205
206 if ($i3->connect->recv) {
207 say "Connected to i3";
208 }
209
210 =cut
211 sub connect {
212 my ($self) = @_;
213 my $cv = AnyEvent->condvar;
214
215 tcp_connect "unix/", $self->{path}, sub {
216 my ($fh) = @_;
217
218 return $cv->send(0) unless $fh;
219
220 $self->{ipchdl} = AnyEvent::Handle->new(
221 fh => $fh,
222 on_read => sub { my ($hdl) = @_; $self->_data_available($hdl) },
223 on_error => sub {
224 my ($hdl, $fatal, $msg) = @_;
225 delete $self->{ipchdl};
226 $hdl->destroy;
227
228 my $cb = $self->{callbacks};
229
230 # Trigger all one-time callbacks with undef
231 for my $type (keys %{$cb}) {
232 next if ($type & $event_mask) == $event_mask;
233 $cb->{$type}->();
234 delete $cb->{$type};
235 }
236
237 # Trigger _error callback, if set
238 my $type = $events{_error};
239 return unless defined($cb->{$type});
240 $cb->{$type}->($msg);
241 }
242 );
243
244 $cv->send(1)
245 };
246
247 $cv
248 }
249
250 sub _data_available {
251 my ($self, $hdl) = @_;
252
253 $hdl->unshift_read(
254 chunk => length($magic) + 4 + 4,
255 sub {
256 my $header = $_[1];
257 # Unpack message length and read the payload
258 my ($len, $type) = unpack("LL", substr($header, length($magic)));
259 $hdl->unshift_read(
260 chunk => $len,
261 sub { $self->_handle_i3_message($type, $_[1]) }
262 );
263 }
264 );
265 }
266
267 sub _handle_i3_message {
268 my ($self, $type, $payload) = @_;
269
270 return unless defined($self->{callbacks}->{$type});
271
272 my $cb = $self->{callbacks}->{$type};
273 $cb->(decode_json $payload);
274
275 return if ($type & $event_mask) == $event_mask;
276
277 # If this was a one-time callback, we delete it
278 # (when connection is lost, all one-time callbacks get triggered)
279 delete $self->{callbacks}->{$type};
280 }
281
282 =head2 $i3->subscribe(\%callbacks)
283
284 Subscribes to the given event types. This function awaits a hashref with the
285 key being the name of the event and the value being a callback.
286
287 my %callbacks = (
288 workspace => sub { say "Workspaces changed" }
289 );
290
291 if ($i3->subscribe(\%callbacks)->recv->{success}) {
292 say "Successfully subscribed";
293 }
294
295 The special callback with name C<_error> is called when the connection to i3
296 is killed (because of a crash, exit or restart of i3 most likely). You can
297 use it to print an appropriate message and exit cleanly or to try to reconnect.
298
299 my %callbacks = (
300 _error => sub {
301 my ($msg) = @_;
302 say "I am sorry. I am so sorry: $msg";
303 exit 1;
304 }
305 );
306
307 $i3->subscribe(\%callbacks)->recv;
308
309 =cut
310 sub subscribe {
311 my ($self, $callbacks) = @_;
312
313 # Register callbacks for each message type
314 for my $key (keys %{$callbacks}) {
315 my $type = $events{$key};
316 $self->{callbacks}->{$type} = $callbacks->{$key};
317 }
318
319 $self->message(TYPE_SUBSCRIBE, [ keys %{$callbacks} ])
320 }
321
322 =head2 $i3->message($type, $content)
323
324 Sends a message of the specified C<type> to i3, possibly containing the data
325 structure C<content> (or C<content>, encoded as utf8, if C<content> is a
326 scalar), if specified.
327
328 my $reply = $i3->message(TYPE_RUN_COMMAND, "reload")->recv;
329 if ($reply->{success}) {
330 say "Configuration successfully reloaded";
331 }
332
333 =cut
334 sub message {
335 my ($self, $type, $content) = @_;
336
337 confess "No message type specified" unless defined($type);
338
339 confess "No connection to i3" unless defined($self->{ipchdl});
340
341 my $payload = "";
342 if ($content) {
343 if (not ref($content)) {
344 # Convert from Perl’s internal encoding to UTF8 octets
345 $payload = encode_utf8($content);
346 } else {
347 $payload = encode_json $content;
348 }
349 }
350 my $message = $magic . pack("LL", length($payload), $type) . $payload;
351 $self->{ipchdl}->push_write($message);
352
353 my $cv = AnyEvent->condvar;
354
355 # We don’t preserve the old callback as it makes no sense to
356 # have a callback on message reply types (only on events)
357 $self->{callbacks}->{$type} =
358 sub {
359 my ($reply) = @_;
360 $cv->send($reply);
361 undef $self->{callbacks}->{$type};
362 };
363
364 $cv
365 }
366
367 =head1 SUGAR METHODS
368
369 These methods intend to make your scripts as beautiful as possible. All of
370 them automatically establish a connection to i3 blockingly (if it does not
371 already exist).
372
373 =cut
374
375 sub _ensure_connection {
376 my ($self) = @_;
377
378 return if defined($self->{ipchdl});
379
380 $self->connect->recv or confess "Unable to connect to i3 (socket path " . $self->{path} . ")";
381 }
382
383 =head2 get_workspaces
384
385 Gets the current workspaces from i3.
386
387 my $ws = i3->get_workspaces->recv;
388 say Dumper($ws);
389
390 =cut
391 sub get_workspaces {
392 my ($self) = @_;
393
394 $self->_ensure_connection;
395
396 $self->message(TYPE_GET_WORKSPACES)
397 }
398
399 =head2 get_outputs
400
401 Gets the current outputs from i3.
402
403 my $outs = i3->get_outputs->recv;
404 say Dumper($outs);
405
406 =cut
407 sub get_outputs {
408 my ($self) = @_;
409
410 $self->_ensure_connection;
411
412 $self->message(TYPE_GET_OUTPUTS)
413 }
414
415 =head2 get_tree
416
417 Gets the layout tree from i3 (>= v4.0).
418
419 my $tree = i3->get_tree->recv;
420 say Dumper($tree);
421
422 =cut
423 sub get_tree {
424 my ($self) = @_;
425
426 $self->_ensure_connection;
427
428 $self->message(TYPE_GET_TREE)
429 }
430
431 =head2 get_marks
432
433 Gets all the window identifier marks from i3 (>= v4.1).
434
435 my $marks = i3->get_marks->recv;
436 say Dumper($marks);
437
438 =cut
439 sub get_marks {
440 my ($self) = @_;
441
442 $self->_ensure_connection;
443
444 $self->message(TYPE_GET_MARKS)
445 }
446
447 =head2 get_bar_config
448
449 Gets the bar configuration for the specific bar id from i3 (>= v4.1).
450
451 my $config = i3->get_bar_config($id)->recv;
452 say Dumper($config);
453
454 =cut
455 sub get_bar_config {
456 my ($self, $id) = @_;
457
458 $self->_ensure_connection;
459
460 $self->message(TYPE_GET_BAR_CONFIG, $id)
461 }
462
463 =head2 get_version
464
465 Gets the i3 version via IPC, with a fall-back that parses the output of i3
466 --version (for i3 < v4.3).
467
468 my $version = i3->get_version()->recv;
469 say "major: " . $version->{major} . ", minor = " . $version->{minor};
470
471 =cut
472 sub get_version {
473 my ($self) = @_;
474
475 $self->_ensure_connection;
476
477 my $cv = AnyEvent->condvar;
478
479 my $version_cv = $self->message(TYPE_GET_VERSION);
480 my $timeout;
481 $timeout = AnyEvent->timer(
482 after => 1,
483 cb => sub {
484 warn "Falling back to i3 --version since the running i3 doesn’t support GET_VERSION yet.";
485 my $version = _call_i3('--version');
486 $version =~ s/^i3 version //;
487 my $patch = 0;
488 my ($major, $minor) = ($version =~ /^([0-9]+)\.([0-9]+)/);
489 if ($version =~ /^[0-9]+\.[0-9]+\.([0-9]+)/) {
490 $patch = $1;
491 }
492 # Strip everything from the © sign on.
493 $version =~ s/ ©.*$//g;
494 $cv->send({
495 major => int($major),
496 minor => int($minor),
497 patch => int($patch),
498 human_readable => $version,
499 });
500 undef $timeout;
501 },
502 );
503 $version_cv->cb(sub {
504 undef $timeout;
505 $cv->send($version_cv->recv);
506 });
507
508 return $cv;
509 }
510
511 =head2 get_config
512
513 Gets the raw last read config from i3. Requires i3 >= 4.14
514
515 =cut
516 sub get_config {
517 my ($self) = @_;
518
519 $self->_ensure_connection;
520
521 $self->message(TYPE_GET_CONFIG);
522 }
523
524 =head2 send_tick
525
526 Sends a tick event. Requires i3 >= 4.15
527
528 =cut
529 sub send_tick {
530 my ($self, $payload) = @_;
531
532 $self->_ensure_connection;
533
534 $self->message(TYPE_SEND_TICK, $payload);
535 }
536
537 =head2 sync
538
539 Sends an i3 sync event. Requires i3 >= 4.16
540
541 =cut
542 sub sync {
543 my ($self, $payload) = @_;
544
545 $self->_ensure_connection;
546
547 $self->message(TYPE_SYNC, $payload);
548 }
549
550 =head2 command($content)
551
552 Makes i3 execute the given command
553
554 my $reply = i3->command("reload")->recv;
555 die "command failed" unless $reply->{success};
556
557 =cut
558 sub command {
559 my ($self, $content) = @_;
560
561 $self->_ensure_connection;
562
563 $self->message(TYPE_RUN_COMMAND, $content)
564 }
565
566 =head1 AUTHOR
567
568 Michael Stapelberg, C<< <michael at i3wm.org> >>
569
570 =head1 BUGS
571
572 Please report any bugs or feature requests to C<bug-anyevent-i3 at
573 rt.cpan.org>, or through the web interface at
574 L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=AnyEvent-I3>. I will be
575 notified, and then you'll automatically be notified of progress on your bug as
576 I make changes.
577
578 =head1 SUPPORT
579
580 You can find documentation for this module with the perldoc command.
581
582 perldoc AnyEvent::I3
583
584 You can also look for information at:
585
586 =over 2
587
588 =item * RT: CPAN's request tracker
589
590 L<https://rt.cpan.org/NoAuth/Bugs.html?Dist=AnyEvent-I3>
591
592 =item * The i3 window manager website
593
594 L<https://i3wm.org>
595
596 =back
597
598
599 =head1 ACKNOWLEDGEMENTS
600
601
602 =head1 LICENSE AND COPYRIGHT
603
604 Copyright 2010-2012 Michael Stapelberg.
605
606 This program is free software; you can redistribute it and/or modify it
607 under the terms of either: the GNU General Public License as published
608 by the Free Software Foundation; or the Artistic License.
609
610 See https://dev.perl.org/licenses/ for more information.
611
612
613 =cut
614
615 1; # End of AnyEvent::I3
0 #!perl -T
1
2 use Test::More tests => 1;
3
4 BEGIN {
5 use_ok( 'AnyEvent::I3' ) || print "Bail out!
6 ";
7 }
8
9 diag( "Testing AnyEvent::I3 $AnyEvent::I3::VERSION, Perl $], $^X" );
0 #!perl -T
1 # vim:ts=4:sw=4:expandtab
2
3 use Test::More tests => 3;
4 use AnyEvent::I3;
5 use AnyEvent;
6
7 my $i3 = i3();
8 my $cv = AnyEvent->condvar;
9
10 # Try to connect to i3
11 $i3->connect->cb(sub { my ($v) = @_; $cv->send($v->recv) });
12
13 # But cancel if we are not connected after 0.5 seconds
14 my $t = AnyEvent->timer(after => 0.5, cb => sub { $cv->send(0) });
15 my $connected = $cv->recv;
16
17 SKIP: {
18 skip 'No connection to i3', 3 unless $connected;
19
20 my $workspaces = $i3->message(1)->recv;
21 isa_ok($workspaces, 'ARRAY');
22
23 ok(@{$workspaces} > 0, 'More than zero workspaces found');
24
25 ok(defined(@{$workspaces}[0]->{num}), 'JSON deserialized');
26 }
27
28 diag( "Testing AnyEvent::I3 $AnyEvent::I3::VERSION, Perl $], $^X" );
0 #!perl -T
1 # vim:ts=4:sw=4:expandtab
2
3 use Test::More tests => 3;
4 use AnyEvent::I3;
5 use AnyEvent;
6
7 my $i3 = i3();
8 my $cv = AnyEvent->condvar;
9
10 # Try to connect to i3
11 $i3->connect->cb(sub { my ($v) = @_; $cv->send($v->recv) });
12
13 # But cancel if we are not connected after 0.5 seconds
14 my $t = AnyEvent->timer(after => 0.5, cb => sub { $cv->send(0) });
15 my $connected = $cv->recv;
16
17 SKIP: {
18 skip 'No connection to i3', 3 unless $connected;
19
20 my $workspaces = i3->get_workspaces->recv;
21 isa_ok($workspaces, 'ARRAY');
22
23 ok(@{$workspaces} > 0, 'More than zero workspaces found');
24
25 ok(defined(@{$workspaces}[0]->{num}), 'JSON deserialized');
26 }
27
28 diag( "Testing AnyEvent::I3 $AnyEvent::I3::VERSION, Perl $], $^X" );
0 #!perl -T
1
2 use strict;
3 use warnings;
4 use Test::More tests => 3;
5
6 sub not_in_file_ok {
7 my ($filename, %regex) = @_;
8 open( my $fh, '<', $filename )
9 or die "couldn't open $filename for reading: $!";
10
11 my %violated;
12
13 while (my $line = <$fh>) {
14 while (my ($desc, $regex) = each %regex) {
15 if ($line =~ $regex) {
16 push @{$violated{$desc}||=[]}, $.;
17 }
18 }
19 }
20
21 if (%violated) {
22 fail("$filename contains boilerplate text");
23 diag "$_ appears on lines @{$violated{$_}}" for keys %violated;
24 } else {
25 pass("$filename contains no boilerplate text");
26 }
27 }
28
29 sub module_boilerplate_ok {
30 my ($module) = @_;
31 not_in_file_ok($module =>
32 'the great new $MODULENAME' => qr/ - The great new /,
33 'boilerplate description' => qr/Quick summary of what the module/,
34 'stub function definition' => qr/function[12]/,
35 );
36 }
37
38 TODO: {
39 local $TODO = "Need to replace the boilerplate text";
40
41 not_in_file_ok(README =>
42 "The README is used..." => qr/The README is used/,
43 "'version information here'" => qr/to provide version information/,
44 );
45
46 not_in_file_ok(Changes =>
47 "placeholder date/time" => qr(Date/time)
48 );
49
50 module_boilerplate_ok('lib/AnyEvent/I3.pm');
51
52
53 }
54
0 #!perl -T
1
2 use strict;
3 use warnings;
4 use Test::More;
5
6 unless ( $ENV{RELEASE_TESTING} ) {
7 plan( skip_all => "Author tests not required for installation" );
8 }
9
10 eval "use Test::CheckManifest 0.9";
11 plan skip_all => "Test::CheckManifest 0.9 required" if $@;
12 ok_manifest();
0 use strict;
1 use warnings;
2 use Test::More;
3
4 # Ensure a recent version of Test::Pod::Coverage
5 my $min_tpc = 1.08;
6 eval "use Test::Pod::Coverage $min_tpc";
7 plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage"
8 if $@;
9
10 # Test::Pod::Coverage doesn't require a minimum Pod::Coverage version,
11 # but older versions don't recognize some common documentation styles
12 my $min_pc = 0.18;
13 eval "use Pod::Coverage $min_pc";
14 plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage"
15 if $@;
16
17 all_pod_coverage_ok();
0 #!perl -T
1
2 use strict;
3 use warnings;
4 use Test::More;
5
6 # Ensure a recent version of Test::Pod
7 my $min_tp = 1.22;
8 eval "use Test::Pod $min_tp";
9 plan skip_all => "Test::Pod $min_tp required for testing POD" if $@;
10
11 all_pod_files_ok();
0
1 i3 has the following dependencies:
2
3 "min" means minimum required version
4 "lkgv" means last known good version
5
6 ┌──────────────┬────────┬────────┬─────────────────────────────────────────────────────────────┐
7 │ dependency │ min. │ lkgv │ URL │
8 ├──────────────┼────────┼────────┼─────────────────────────────────────────────────────────────┤
9 │ pkg-config │ 0.25 │ 0.29 │ https://pkgconfig.freedesktop.org/ │
10 │ libxcb │ 1.1.93 │ 1.12 │ https://xcb.freedesktop.org/dist/ │
11 │ xcb-util │ 0.3.3 │ 0.4.1 │ https://xcb.freedesktop.org/dist/ │
12 │ xkbcommon │ 0.4.0 │ 0.6.1 │ https://xkbcommon.org/ │
13 │ xkbcommon-x11│ 0.4.0 │ 0.6.1 │ https://xkbcommon.org/ │
14 │ util-cursor³⁴│ 0.0.99 │ 0.1.3 │ https://xcb.freedesktop.org/dist/ │
15 │ util-wm⁴ │ 0.3.8 │ 0.3.8 │ https://xcb.freedesktop.org/dist/ │
16 │ util-keysyms⁴│ 0.3.8 │ 0.4.0 │ https://xcb.freedesktop.org/dist/ │
17 │ util-xrm⁴ │ 1.0.0 │ 1.0.0 │ https://github.com/Airblader/xcb-util-xrm/ │
18 │ libev │ 4.0 │ 4.19 │ http://libev.schmorp.de/ │
19 │ yajl │ 2.0.1 │ 2.1.0 │ https://lloyd.github.com/yajl/ │
20 │ asciidoc │ 8.3.0 │ 8.6.9 │ http://www.methods.co.nz/asciidoc/ │
21 │ xmlto │ 0.0.23 │ 0.0.23 │ http://www.methods.co.nz/asciidoc/ │
22 │ Pod::Simple² │ 3.22 │ 3.22 │ http://search.cpan.org/dist/Pod-Simple/ │
23 │ docbook-xml │ 4.5 │ 4.5 │ http://www.methods.co.nz/asciidoc/ │
24 │ PCRE │ 8.12 │ 8.38 │ https://www.pcre.org/ │
25 │ libsn¹ │ 0.10 │ 0.12 │ https://freedesktop.org/wiki/Software/startup-notification/ │
26 │ pango │ 1.30.0 │ 1.40.1 │ http://www.pango.org/ │
27 │ cairo │ 1.14.4 │ 1.14.6 │ https://cairographics.org/ │
28 └──────────────┴────────┴────────┴─────────────────────────────────────────────────────────────┘
29 ¹ libsn = libstartup-notification
30 ² Pod::Simple is a Perl module required for converting the testsuite
31 documentation to HTML. See https://michael.stapelberg.de/cpan/#Pod::Simple
32 ³ xcb-util-cursor, to be precise.
33 ⁴ Depending on your distribution, this might be considered part of xcb-util.
34
35 i3bar, i3-msg, i3-input, i3-nagbar and i3-config-wizard do not introduce any
36 new dependencies.
37
38 i3-migrate-config-to-v4 and i3-dmenu-desktop are implemented in Perl, but have
39 no dependencies besides Perl 5.10.
40
41 i3-save-tree is also implemented in Perl and needs AnyEvent::I3 (>= 0.12) and
42 JSON::XS. While i3-save-tree is not required for running i3 itself, it is
43 strongly recommended to provide it in distribution packages.
0 4.18.1-non-git
0 Copyright © 2009, Michael Stapelberg and contributors
1 All rights reserved.
2
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions are met:
5
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12
13 * Neither the name of Michael Stapelberg nor the
14 names of contributors may be used to endorse or promote products
15 derived from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY Michael Stapelberg ''AS IS'' AND ANY
18 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL Michael Stapelberg BE LIABLE FOR ANY
21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0 @CODE_COVERAGE_RULES@
1
2 echo-version:
3 @echo "@I3_VERSION@"
4
5 bin_PROGRAMS = \
6 i3 \
7 i3bar/i3bar \
8 i3-config-wizard/i3-config-wizard \
9 i3-dump-log/i3-dump-log \
10 i3-input/i3-input \
11 i3-msg/i3-msg \
12 i3-nagbar/i3-nagbar
13
14 install-exec-hook:
15 $(LN_S) -f i3 $(DESTDIR)$(bindir)/i3-with-shmlog
16
17 uninstall-hook:
18 rm -f $(DESTDIR)$(bindir)/i3-with-shmlog
19
20 i3includedir=$(includedir)/i3
21 i3include_HEADERS = \
22 include/i3/ipc.h
23
24 dist_bin_SCRIPTS = \
25 i3-dmenu-desktop \
26 i3-migrate-config-to-v4 \
27 i3-save-tree \
28 i3-sensible-editor \
29 i3-sensible-pager \
30 i3-sensible-terminal
31
32 i3confdir = $(sysconfdir)/i3
33 dist_i3conf_DATA = \
34 etc/config \
35 etc/config.keycodes
36
37 I3STATUS_INSTALL_NAME = $(shell echo i3status | sed '@program_transform_name@')
38
39 etc/config: etc/$(dirstamp)
40 $(AM_V_GEN) sed "s,status_command i3status,status_command $(I3STATUS_INSTALL_NAME),g" $(top_srcdir)/etc/config > etc/config
41
42 etc/config.keycodes: etc/$(dirstamp)
43 $(AM_V_GEN) sed "s,status_command i3status,status_command $(I3STATUS_INSTALL_NAME),g" $(top_srcdir)/etc/config.keycodes > etc/config.keycodes
44
45 applicationsdir = $(datarootdir)/applications
46 xsessionsdir = $(datarootdir)/xsessions
47 dist_applications_DATA = \
48 share/applications/i3.desktop
49 dist_xsessions_DATA = \
50 share/xsessions/i3.desktop \
51 share/xsessions/i3-with-shmlog.desktop
52
53 noinst_LIBRARIES = libi3.a
54
55 check_PROGRAMS = \
56 test.commands_parser \
57 test.config_parser \
58 test.inject_randr15
59
60 check_SCRIPTS = \
61 testcases/complete-run.pl
62
63 check_DATA = \
64 anyevent-i3.stamp
65
66 clean-check:
67 rm -rf testsuite-* latest i3-cfg-for-* _Inline
68 clean-local: clean-check
69
70 TESTS = testcases/complete-run.pl
71
72 EXTRA_DIST = \
73 $(dist_docs_toc_DATA:.html=) \
74 $(dist_docs_notoc_DATA:.html=) \
75 AnyEvent-I3/Changes \
76 AnyEvent-I3/MANIFEST \
77 AnyEvent-I3/MANIFEST.SKIP \
78 AnyEvent-I3/Makefile.PL \
79 AnyEvent-I3/README \
80 AnyEvent-I3/lib/AnyEvent/I3.pm \
81 AnyEvent-I3/t/00-load.t \
82 AnyEvent-I3/t/01-workspaces.t \
83 AnyEvent-I3/t/02-sugar.t \
84 AnyEvent-I3/t/boilerplate.t \
85 AnyEvent-I3/t/manifest.t \
86 AnyEvent-I3/t/pod-coverage.t \
87 AnyEvent-I3/t/pod.t \
88 contrib/dump-asy.pl \
89 contrib/gtk-tree-watch.pl \
90 contrib/i3-wsbar \
91 contrib/per-workspace-layout.pl \
92 contrib/trivial-bar-script.sh \
93 docs/asciidoc-git.conf \
94 docs/bigpicture.png \
95 docs/i3-pod2html \
96 docs/i3-sync.dia \
97 docs/i3-sync.png \
98 docs/i3-sync-working.dia \
99 docs/i3-sync-working.png \
100 docs/keyboard-layer1.png \
101 docs/keyboard-layer2.png \
102 docs/layout-saving-1.png \
103 docs/logo-30.png \
104 docs/modes.png \
105 docs/refcard.html \
106 docs/refcard_style.css \
107 docs/single_terminal.png \
108 docs/snapping.png \
109 docs/tree-layout1.png \
110 docs/tree-layout2.png \
111 docs/tree-shot1.png \
112 docs/tree-shot2.png \
113 docs/tree-shot3.png \
114 docs/tree-shot4.png \
115 docs/two_columns.png \
116 docs/two_terminals.png \
117 docs/wsbar.dia \
118 docs/wsbar.png \
119 i3bar/LICENSE \
120 libi3/README \
121 $(asciidoc_MANS:.1=.man) \
122 $(asciidoc_MANS:.1=.man) \
123 man/asciidoc.conf.in \
124 DEPENDS \
125 I3_VERSION \
126 LICENSE \
127 PACKAGE-MAINTAINER \
128 RELEASE-NOTES-4.18.1 \
129 generate-command-parser.pl \
130 parser-specs/commands.spec \
131 parser-specs/config.spec \
132 parser-specs/highlighting.vim \
133 pseudo-doc.doxygen \
134 testcases/complete-run.pl.in \
135 testcases/i3-test.config \
136 testcases/lib/i3test/Test.pm \
137 testcases/lib/i3test/Util.pm \
138 testcases/lib/i3test/XTEST.pm \
139 testcases/lib/i3test.pm.in \
140 testcases/lib/SocketActivation.pm \
141 testcases/lib/StartXServer.pm \
142 testcases/lib/StatusLine.pm \
143 testcases/lib/TestWorker.pm \
144 testcases/Makefile.PL \
145 testcases/new-test \
146 testcases/restart-state.golden \
147 testcases/t \
148 testcases/valgrind.supp
149
150 # dirstamps contains directories which we want to be created in $(top_builddir)
151 # so that our custom rules can store files in them.
152 dirstamp = .dirstamp
153 dirstamps = \
154 docs/$(dirstamp) \
155 man/$(dirstamp) \
156 parser/$(dirstamp) \
157 etc/$(dirstamp)
158 DISTCLEANFILES = $(dirstamps)
159
160 $(dirstamps):
161 @stamp='$@'; $(MKDIR_P) "$${stamp%/*}"
162 @: > $@
163
164 ################################################################################
165 # docs generation
166 ################################################################################
167
168 docs_tocdir = ${docdir}
169 docs_notocdir = ${docdir}
170 docs_poddir = ${docdir}
171 if BUILD_DOCS
172 dist_docs_toc_DATA = \
173 docs/hacking-howto.html \
174 docs/userguide.html \
175 docs/ipc.html \
176 docs/multi-monitor.html \
177 docs/wsbar.html \
178 docs/testsuite.html \
179 docs/i3bar-protocol.html \
180 docs/layout-saving.html
181
182 dist_docs_notoc_DATA = \
183 docs/debugging.html
184
185 dist_docs_pod_DATA = \
186 docs/lib-i3test.html \
187 docs/lib-i3test-test.html
188
189 $(dist_docs_toc_DATA): docs/%.html: docs/% docs/$(dirstamp)
190 $(AM_V_GEN) @PATH_ASCIIDOC@ -a toc -n -o $@ $<
191
192 $(dist_docs_notoc_DATA): docs/%.html: docs/% docs/$(dirstamp)
193 $(AM_V_GEN) @PATH_ASCIIDOC@ -n -o $@ $<
194
195 docs/lib-i3test.html: testcases/lib/i3test.pm docs/$(dirstamp)
196 $(AM_V_GEN) $(top_srcdir)/docs/i3-pod2html $< $@
197
198 docs/lib-i3test-test.html: testcases/lib/i3test/Test.pm docs/$(dirstamp)
199 $(AM_V_GEN) $(top_srcdir)/docs/i3-pod2html $< $@
200
201 else
202 dist_docs_toc_DATA =
203 dist_docs_notoc_DATA =
204 dist_docs_pod_DATA =
205 endif
206
207 ################################################################################
208 # manpage generation
209 ################################################################################
210
211 if BUILD_MANS
212 dist_man1_MANS = \
213 $(asciidoc_MANS) \
214 $(pod_MANS)
215
216 asciidoc_MANS = \
217 man/i3.1 \
218 man/i3bar.1 \
219 man/i3-msg.1 \
220 man/i3-input.1 \
221 man/i3-nagbar.1 \
222 man/i3-config-wizard.1 \
223 man/i3-migrate-config-to-v4.1 \
224 man/i3-sensible-editor.1 \
225 man/i3-sensible-pager.1 \
226 man/i3-sensible-terminal.1 \
227 man/i3-dump-log.1
228
229 pod_MANS = \
230 man/i3-dmenu-desktop.1 \
231 man/i3-save-tree.1
232
233 $(asciidoc_MANS): man/%.1: man/%.xml man/$(dirstamp)
234 $(AM_V_GEN) out='$@'; @PATH_XMLTO@ man -o "$${out%/*}" $<
235 @stamp='$@'; $(MKDIR_P) "$${stamp%/*}"
236
237 man/%.xml: man/%.man man/asciidoc.conf man/$(dirstamp)
238 $(AM_V_GEN) @PATH_ASCIIDOC@ -d manpage -b docbook -f $(top_builddir)/man/asciidoc.conf -o $@ $<
239
240 $(pod_MANS): man/%.1: % man/$(dirstamp)
241 $(AM_V_GEN) @PATH_POD2MAN@ --utf8 $< > $@
242 else
243 asciidoc_MANS =
244 endif
245
246 AM_CPPFLAGS = \
247 -DSYSCONFDIR="\"$(sysconfdir)\"" \
248 -I$(top_builddir)/parser \
249 -I$(top_srcdir)/include \
250 @AX_EXTEND_SRCDIR_CPPFLAGS@
251
252 i3_CFLAGS = \
253 $(AM_CFLAGS) \
254 $(libi3_CFLAGS) \
255 $(LIBSN_CFLAGS) \
256 $(XCB_CFLAGS) \
257 $(XCB_UTIL_CURSOR_CFLAGS) \
258 $(XCB_UTIL_KEYSYM_CFLAGS) \
259 $(XCB_UTIL_WM_CFLAGS) \
260 $(XCB_UTIL_XRM_CFLAGS) \
261 $(XKBCOMMON_CFLAGS) \
262 $(YAJL_CFLAGS) \
263 $(LIBPCRE_CFLAGS) \
264 $(PTHREAD_CFLAGS) \
265 $(CODE_COVERAGE_CFLAGS)
266
267 i3_CPPFLAGS = \
268 $(AM_CPPFLAGS) \
269 $(CODE_COVERAGE_CPPFLAGS)
270
271 i3_LDADD = \
272 $(libi3_LIBS) \
273 $(LIBSN_LIBS) \
274 $(XCB_LIBS) \
275 $(XCB_UTIL_CURSOR_LIBS) \
276 $(XCB_UTIL_KEYSYMS_LIBS) \
277 $(XCB_UTIL_WM_LIBS) \
278 $(XCB_UTIL_XRM_LIBS) \
279 $(XKBCOMMON_LIBS) \
280 $(YAJL_LIBS) \
281 $(LIBPCRE_LIBS) \
282 $(PANGOCAIRO_LIBS) \
283 $(PTHREAD_LIBS) \
284 $(CODE_COVERAGE_LDFLAGS)
285
286 libi3_CFLAGS = \
287 $(AM_CFLAGS) \
288 $(GLIBGOBJECT_CFLAGS) \
289 $(XCB_CFLAGS) \
290 $(XCB_UTIL_CFLAGS) \
291 $(XCB_UTIL_XRM_CFLAGS) \
292 $(YAJL_CFLAGS) \
293 $(PANGOCAIRO_CFLAGS)
294
295 libi3_LIBS = \
296 $(top_builddir)/libi3.a \
297 $(GLIBGOBJECT_LIBS) \
298 $(XCB_LIBS) \
299 $(XCB_UTIL_LIBS) \
300 $(XCB_UTIL_XRM_LIBS) \
301 $(YAJL_LIBS) \
302 $(PANGOCAIRO_LIBS)
303
304 libi3_a_CFLAGS = \
305 $(libi3_CFLAGS)
306
307 libi3_a_SOURCES = \
308 include/libi3.h \
309 libi3/dpi.c \
310 libi3/draw_util.c \
311 libi3/fake_configure_notify.c \
312 libi3/font.c \
313 libi3/format_placeholders.c \
314 libi3/g_utf8_make_valid.c \
315 libi3/get_colorpixel.c \
316 libi3/get_config_path.c \
317 libi3/get_exe_path.c \
318 libi3/get_mod_mask.c \
319 libi3/get_process_filename.c \
320 libi3/get_visualtype.c \
321 libi3/ipc_connect.c \
322 libi3/ipc_recv_message.c \
323 libi3/ipc_send_message.c \
324 libi3/is_debug_build.c \
325 libi3/mkdirp.c \
326 libi3/resolve_tilde.c \
327 libi3/root_atom_contents.c \
328 libi3/safewrappers.c \
329 libi3/string.c \
330 libi3/strndup.c \
331 libi3/ucs2_conversion.c
332
333 i3_dump_log_i3_dump_log_CFLAGS = \
334 $(AM_CFLAGS) \
335 $(PTHREAD_CFLAGS) \
336 $(libi3_CFLAGS)
337
338 i3_dump_log_i3_dump_log_LDADD = \
339 $(PTHREAD_LIBS) \
340 $(libi3_LIBS)
341
342 i3_dump_log_i3_dump_log_SOURCES = \
343 i3-dump-log/main.c
344
345 i3_input_i3_input_CFLAGS = \
346 $(AM_CFLAGS) \
347 $(libi3_CFLAGS)
348
349 i3_input_i3_input_LDADD = \
350 $(libi3_LIBS) \
351 $(XCB_UTIL_KEYSYMS_LIBS)
352
353 i3_input_i3_input_SOURCES = \
354 i3-input/i3-input.h \
355 i3-input/keysym2ucs.c \
356 i3-input/keysym2ucs.h \
357 i3-input/main.c
358
359 i3_msg_i3_msg_CFLAGS = \
360 $(AM_CFLAGS) \
361 $(libi3_CFLAGS)
362
363 i3_msg_i3_msg_LDADD = \
364 $(libi3_LIBS)
365
366 i3_msg_i3_msg_SOURCES = \
367 i3-msg/main.c
368
369 i3_nagbar_i3_nagbar_CFLAGS = \
370 $(AM_CFLAGS) \
371 $(LIBSN_CFLAGS) \
372 $(libi3_CFLAGS)
373
374 i3_nagbar_i3_nagbar_LDADD = \
375 $(libi3_LIBS) \
376 $(LIBSN_LIBS) \
377 $(XCB_UTIL_CURSOR_LIBS)
378
379 i3_nagbar_i3_nagbar_SOURCES = \
380 i3-nagbar/atoms.xmacro \
381 i3-nagbar/i3-nagbar.h \
382 i3-nagbar/main.c
383
384 i3bar_i3bar_CPPFLAGS = \
385 $(AM_CPPFLAGS) \
386 -I$(top_srcdir)/i3bar/include
387
388 i3bar_i3bar_CFLAGS = \
389 $(AM_CFLAGS) \
390 $(libi3_CFLAGS) \
391 $(XCB_CFLAGS) \
392 $(XKBCOMMON_CFLAGS) \
393 $(PANGOCAIRO_CFLAGS) \
394 $(YAJL_CFLAGS)
395
396 i3bar_i3bar_LDADD = \
397 $(libi3_LIBS) \
398 $(XCB_LIBS) \
399 $(XCB_UTIL_CURSOR_LIBS) \
400 $(XKBCOMMON_LIBS) \
401 $(PANGOCAIRO_LIBS) \
402 $(YAJL_LIBS)
403
404 i3bar_i3bar_SOURCES = \
405 i3bar/include/child.h \
406 i3bar/include/common.h \
407 i3bar/include/configuration.h \
408 i3bar/include/ipc.h \
409 i3bar/include/mode.h \
410 i3bar/include/outputs.h \
411 i3bar/include/parse_json_header.h \
412 i3bar/include/trayclients.h \
413 i3bar/include/util.h \
414 i3bar/include/workspaces.h \
415 i3bar/include/xcb_atoms.def \
416 i3bar/include/xcb.h \
417 i3bar/src/child.c \
418 i3bar/src/config.c \
419 i3bar/src/ipc.c \
420 i3bar/src/main.c \
421 i3bar/src/mode.c \
422 i3bar/src/outputs.c \
423 i3bar/src/parse_json_header.c \
424 i3bar/src/workspaces.c \
425 i3bar/src/xcb.c
426
427 i3_config_wizard_i3_config_wizard_CFLAGS = \
428 $(AM_CFLAGS) \
429 $(libi3_CFLAGS) \
430 $(LIBSN_CFLAGS) \
431 $(XKBCOMMON_CFLAGS)
432
433 i3_config_wizard_i3_config_wizard_LDADD = \
434 $(libi3_LIBS) \
435 $(LIBSN_LIBS) \
436 $(XCB_UTIL_KEYSYMS_LIBS) \
437 $(XKBCOMMON_LIBS)
438
439 i3_config_wizard_i3_config_wizard_SOURCES = \
440 i3-config-wizard/atoms.xmacro \
441 i3-config-wizard/main.c \
442 i3-config-wizard/xcb.h
443
444 i3_config_wizard_i3_config_wizard_DEPENDENCIES = \
445 $(config_parser_SOURCES)
446
447 test_inject_randr15_CPPFLAGS = \
448 $(AM_CPPFLAGS)
449
450 test_inject_randr15_CFLAGS = \
451 $(AM_CFLAGS) \
452 $(i3_CFLAGS)
453
454 test_inject_randr15_SOURCES = \
455 testcases/inject_randr1.5.c
456
457 test_inject_randr15_LDADD = \
458 $(i3_LDADD)
459
460 test_commands_parser_CPPFLAGS = \
461 $(AM_CPPFLAGS) \
462 -DTEST_PARSER
463
464 test_commands_parser_CFLAGS = \
465 $(AM_CFLAGS) \
466 $(i3_CFLAGS)
467
468 test_commands_parser_SOURCES = \
469 src/commands_parser.c
470
471 test_commands_parser_LDADD = \
472 $(i3_LDADD)
473
474 test_config_parser_CPPFLAGS = \
475 $(AM_CPPFLAGS) \
476 -DTEST_PARSER
477
478 test_config_parser_CFLAGS = \
479 $(AM_CFLAGS) \
480 $(i3_CFLAGS)
481
482 test_config_parser_SOURCES = \
483 src/config_parser.c
484
485 test_config_parser_LDADD = \
486 $(i3_LDADD)
487
488 command_parser_SOURCES = \
489 parser/GENERATED_command_enums.h \
490 parser/GENERATED_command_tokens.h \
491 parser/GENERATED_command_call.h
492
493 config_parser_SOURCES = \
494 parser/GENERATED_config_enums.h \
495 parser/GENERATED_config_tokens.h \
496 parser/GENERATED_config_call.h
497
498 i3_SOURCES = \
499 $(command_parser_SOURCES) \
500 $(config_parser_SOURCES) \
501 include/all.h \
502 include/assignments.h \
503 include/atoms_NET_SUPPORTED.xmacro \
504 include/atoms_rest.xmacro \
505 include/atoms.xmacro \
506 include/bindings.h \
507 include/click.h \
508 include/cmdparse.h \
509 include/commands.h \
510 include/commands_parser.h \
511 include/config_directives.h \
512 include/configuration.h \
513 include/config_parser.h \
514 include/con.h \
515 include/data.h \
516 include/display_version.h \
517 include/drag.h \
518 include/ewmh.h \
519 include/fake_outputs.h \
520 include/floating.h \
521 include/handlers.h \
522 include/i3.h \
523 include/ipc.h \
524 include/key_press.h \
525 include/load_layout.h \
526 include/log.h \
527 include/main.h \
528 include/manage.h \
529 include/match.h \
530 include/move.h \
531 include/output.h \
532 include/queue.h \
533 include/randr.h \
534 include/regex.h \
535 include/render.h \
536 include/resize.h \
537 include/restore_layout.h \
538 include/scratchpad.h \
539 include/sd-daemon.h \
540 include/shmlog.h \
541 include/sighandler.h \
542 include/startup.h \
543 include/sync.h \
544 include/tree.h \
545 include/util.h \
546 include/window.h \
547 include/workspace.h \
548 include/xcb.h \
549 include/xcursor.h \
550 include/x.h \
551 include/xinerama.h \
552 include/yajl_utils.h \
553 src/assignments.c \
554 src/bindings.c \
555 src/click.c \
556 src/commands.c \
557 src/commands_parser.c \
558 src/con.c \
559 src/config.c \
560 src/config_directives.c \
561 src/config_parser.c \
562 src/display_version.c \
563 src/drag.c \
564 src/ewmh.c \
565 src/fake_outputs.c \
566 src/floating.c \
567 src/handlers.c \
568 src/ipc.c \
569 src/key_press.c \
570 src/load_layout.c \
571 src/log.c \
572 src/main.c \
573 src/manage.c \
574 src/match.c \
575 src/move.c \
576 src/output.c \
577 src/randr.c \
578 src/regex.c \
579 src/render.c \
580 src/resize.c \
581 src/restore_layout.c \
582 src/scratchpad.c \
583 src/sd-daemon.c \
584 src/sighandler.c \
585 src/startup.c \
586 src/sync.c \
587 src/tree.c \
588 src/util.c \
589 src/version.c \
590 src/window.c \
591 src/workspace.c \
592 src/x.c \
593 src/xcb.c \
594 src/xcursor.c \
595 src/xinerama.c
596
597 ################################################################################
598 # parser generation
599 ################################################################################
600
601 $(command_parser_SOURCES): %.h: i3-command-parser.stamp
602
603 $(config_parser_SOURCES): %.h: i3-config-parser.stamp
604
605 src/i3-commands_parser.$(OBJEXT): i3-command-parser.stamp
606
607 src/i3-config_parser.$(OBJEXT): i3-config-parser.stamp
608
609 i3-command-parser.stamp: parser/$(dirstamp) generate-command-parser.pl parser-specs/commands.spec
610 $(AM_V_GEN) $(top_srcdir)/generate-command-parser.pl --input=$(top_srcdir)/parser-specs/commands.spec --prefix=command
611 $(AM_V_at) mv GENERATED_command_* $(top_builddir)/parser
612 $(AM_V_at) touch $@
613
614 i3-config-parser.stamp: parser/$(dirstamp) generate-command-parser.pl parser-specs/config.spec
615 $(AM_V_GEN) $(top_srcdir)/generate-command-parser.pl --input=$(top_srcdir)/parser-specs/config.spec --prefix=config
616 $(AM_V_at) mv GENERATED_config_* $(top_builddir)/parser
617 $(AM_V_at) touch $@
618
619 ################################################################################
620 # AnyEvent-I3 build process
621 ################################################################################
622
623 anyevent-i3.stamp: AnyEvent-I3/lib/AnyEvent/I3.pm
624 $(AM_V_BUILD) (cd $(top_srcdir)/AnyEvent-I3 && perl Makefile.PL && make)
625 $(AM_V_at) touch $@
626
627 CLEANFILES = \
628 i3-command-parser.stamp \
629 i3-config-parser.stamp \
630 anyevent-i3.stamp
631
632 ################################################################################
633 # Language Server support
634 ################################################################################
635
636 # Recursively run make through https://github.com/rizsotto/Bear,
637 # which generates a compile_commands.json file in the source directory.
638 # This is useful for running e.g. the clangd or ccls language servers:
639 # https://clang.llvm.org/extra/clangd/
640 # https://github.com/MaskRay/ccls/wiki
641 .PHONY: bear
642 bear: clean
643 bear -o $(top_srcdir)/compile_commands.json $(MAKE) $(MAKEFLAGS)
0 Dear package maintainer,
1
2 thanks for packaging i3. By doing so, you are improving your distribution
3 and i3 in general.
4
5 Please read the file DEPENDS now, so you know which libraries are necessary
6 and where to get them from if your distribution does not already have
7 packages for them.
8
9 Please make sure the manpage for i3 will be properly created and installed
10 in your package.
11
12 Please check the i3-sensible-{editor,pager,terminal} scripts and modify them if
13 necessary. The former two provide fallbacks in case $PAGER or $EDITOR is not
14 set (which might be more common than you think, because they have to be set in
15 ~/.xsession, not in the shell configuration!) while the latter tries to launch
16 a terminal emulator. The scripts are most prominently used in i3-nagbar, which
17 alerts the user when the configuration is broken for some reason. Also,
18 i3-sensible-terminal is used in the default configuration.
19
20 If your distribution has a mechanism to get the preferred terminal, such as the
21 x-terminal-emulator symlink in Debian, please use it in i3-sensible-terminal.
22
23 On debian, compilation and installing the manpages looks like this:
24
25 autoreconf -fi
26 mkdir -p build && cd build
27 ../configure
28 make -j8 install
29
30 Please make sure that i3-migrate-config-to-v4 and i3-config-wizard are
31 installed with i3. The Perl script is necessary to (automatically) convert v3
32 configs to v4. The wizard provides the possibility to create a keysym-based
33 config with the user’s preferred modifier and should be started on the first
34 start of i3 (it will automatically exit if it finds a config file).
35
36 If you have any questions, ideas, hints, problems or whatever, please do not
37 hesitate to contact me. I will help you out. Just drop me an E-Mail (find the
38 address at https://michael.stapelberg.de/Impressum/, scroll down to bottom),
39 contact me using the same address in jabber or ask on our IRC channel:
40 (#i3 on irc.freenode.net).
41
42 Thanks again for your efforts,
43 Michael
0 [![Travis](https://img.shields.io/travis/Airblader/i3.svg)](https://travis-ci.org/Airblader/i3)
1 [![Issues](https://img.shields.io/github/issues/Airblader/i3.svg)](https://github.com/Airblader/i3/issues)
2 [![Forks](https://img.shields.io/github/forks/Airblader/i3.svg)](https://github.com/Airblader/i3/network)
3 [![Stars](https://img.shields.io/github/stars/Airblader/i3.svg)](https://github.com/Airblader/i3/stargazers)
4
5 # i3-gaps
6
7 ## What is i3-gaps?
8
9 i3-gaps is a fork of [i3wm](https://www.i3wm.org), a tiling window manager for X11. It is kept up to date with upstream, adding a few additional features such as gaps between windows (see below for a complete list).
10
11 ![i3](http://i.imgur.com/y8sZE6o.jpg)
12
13 ## How do I install i3-gaps?
14
15 Please refer to the [wiki](https://github.com/Airblader/i3/wiki).
16
17 ## Where can I get help?
18
19 For bug reports or feature requests regarding i3-gaps specifically, open an issue on [GitHub](https://www.github.com/Airblader/i3). If your issue is with core i3 functionality, please report it [upstream](https://www.github.com/i3/i3).
20
21 For support & all other kinds of questions, you can ask your question on the official [subreddit /r/i3wm](https://www.reddit.com/r/i3wm).
22
23 # Features
24
25 ## i3
26
27 ### gaps
28
29 *Note:* In order to use gaps you need to disable window titlebars. This can be done by adding the following line to your config.
30
31 ```
32 # You can also use any non-zero value if you'd like to have a border
33 for_window [class=".*"] border pixel 0
34 ```
35
36 Gaps are the namesake feature of i3-gaps and add spacing between windows/containers. Gaps come in two flavors, inner and outer gaps wherein inner gaps are those between two adjacent containers (or a container and an edge) and outer gaps are an additional spacing along the screen edges. Gaps can be configured in your config either globally or per workspace, and can additionally be changed during runtime using commands (e.g., through `i3-msg`).
37
38 *Note:* Outer gaps are added to the inner gaps, i.e., the gaps between a screen edge and a container will be the sum of outer and inner gaps.
39
40 #### Configuration
41
42 You can define gaps either globally or per workspace using the following syntax. Note that the gaps configurations should be ordered from least specific to most specific as some directives can overwrite others.
43
44 ```
45 gaps [inner|outer|horizontal|vertical|top|left|bottom|right] <px>
46 workspace <ws> gaps [inner|outer|horizontal|vertical|top|left|bottom|right] <px>
47 ```
48
49 The `inner` and `outer` keywords are as explained above. With `top`, `left`, `bottom` and `right` you can specify outer gaps on specific sides, and `horizontal` and `vertical` are shortcuts for the respective sides. `<px>` stands for a numeric value in pixels and `<ws>` for either a workspace number or a workspace name.
50
51 #### Commands
52
53 Gaps can be modified at runtime with the following command syntax:
54
55 ```
56 gaps inner|outer|horizontal|vertical|top|right|bottom|left current|all set|plus|minus|toggle <px>
57
58 # Examples
59 gaps inner all set 20
60 gaps outer current plus 5
61 gaps horizontal current plus 40
62 gaps outer current toggle 60
63 ```
64
65 With `current` or `all` you can change gaps either for only the currently focused or all currently existing workspaces (note that this does not affect the global configuration itself).
66
67 You can find an example configuration in the [wiki](https://github.com/Airblader/i3/wiki/Example-Configuration).
68
69 ### Smart Gaps
70
71 Gaps can be automatically turned on/off on a workspace in certain scenarios using the following config directives:
72
73 ```
74 # Only enable gaps on a workspace when there is at least one container
75 smart_gaps on
76
77 # Only enable outer gaps when there is exactly one container
78 smart_gaps inverse_outer
79 ```
80
81 ### Smart Borders
82
83 Smart borders will draw borders on windows only if there is more than one window in a workspace. This feature can also be enabled only if the gap size between window and screen edge is `0`.
84
85 ```
86 # Activate smart borders (always)
87 smart_borders on
88
89 # Activate smart borders (only when there are effectively no gaps)
90 smart_borders no_gaps
91 ```
92
93 ### Smart Edge Borders
94
95 This extends i3's `hide_edge_borders` with a new option. When set, edge-specific borders of a container will be hidden if it's the only container on the workspace and the gaps to the screen edge is `0`.
96
97 ```
98 # Hide edge borders only if there is one window with no gaps
99 hide_edge_borders smart_no_gaps
100 ```
101
102 ## i3bar
103
104 ### Bar Height
105
106 The height of an i3bar instance can be specified explicitly by defining the `height` key in the bar configuration. If not set, the height will be calculated automatically depending on the font size.
107
108 ```
109 bar {
110 # Height in pixels
111 height 25
112 }
113 ```
0
1 ┌──────────────────────────────┐
2 │ Release notes for i3 v4.18.1 │
3 └──────────────────────────────┘
4
5 This is i3 v4.18.1. This version is considered stable. All users of i3 are
6 strongly encouraged to upgrade.
7
8 This is a bugfix release for v4.18.
9
10 ┌────────────────────────────┐
11 │ Bugfixes │
12 └────────────────────────────┘
13
14 • Move parent nodes in scratchpad correctly
15 • i3bar: Call cont_child() more liberally
16 • Fix load_layout crash when floating node doesn't have CT_FLOATING_CON parent
17 • Fix SEGFAULT when i3bar receives invalid input
18 • Revert "floating_reposition: avoid extra tree_render"
19 • Call tree_render if floating move changes workspace
20 • Update EWMH properties on workspace move
21 • cmd_focus_sibling: Fix crash on workspace level
22
23 ┌────────────────────────────┐
24 │ Thanks! │
25 └────────────────────────────┘
26
27 Thanks for testing, bugfixes, discussions and everything I forgot go out to:
28
29 Heman Gandhi, Orestis Floros
30
31 -- Michael Stapelberg, 2020-04-22
0 # -*- Autoconf -*-
1 # Run autoreconf -fi to generate a configure script from this file.
2
3 AC_PREREQ([2.69])
4 AC_INIT([i3], [4.18.1], [https://github.com/i3/i3/issues])
5 # For AX_EXTEND_SRCDIR
6 AX_ENABLE_BUILDDIR
7 AM_INIT_AUTOMAKE([foreign subdir-objects -Wall no-dist-gzip dist-bzip2])
8 # Default to silent rules, use V=1 to get verbose compilation output.
9 AM_SILENT_RULES([yes])
10 # Make it possible to disable maintainer mode to disable re-generation of build
11 # system files.
12 AM_MAINTAINER_MODE([enable])
13 AC_CONFIG_SRCDIR([libi3/ipc_recv_message.c])
14 AC_CONFIG_HEADERS([config.h])
15 AC_CONFIG_MACRO_DIR([m4])
16
17 dnl Verify macros defined in m4/ such as AX_SANITIZERS are not present in the
18 dnl output, i.e. are replaced as expected. This line results in a better error
19 dnl message when using aclocal < 1.13 (which does not understand
20 dnl AC_CONFIG_MACRO_DIR) without passing the -I m4 parameter.
21 m4_pattern_forbid([AX_SANITIZERS])
22
23 # Verify we are using GNU make because we use '%'-style pattern rules in
24 # Makefile.am, which are a GNU make extension. Pull requests to replace
25 # '%'-style pattern rules with a more portable alternative are welcome.
26 AX_CHECK_GNU_MAKE
27 AS_VAR_IF([_cv_gnu_make_command], [""], [AC_MSG_ERROR([the i3 Makefile.am requires GNU make])])
28
29 AX_EXTEND_SRCDIR
30
31 AS_IF([test -e ${srcdir}/.git],
32 [
33 VERSION="$(git -C ${srcdir} describe --tags --abbrev=0)"
34 I3_VERSION="$(git -C ${srcdir} describe --tags --always) ($(git -C ${srcdir} rev-list --format=%cd --date=short -n1 $(git rev-parse HEAD) | tail -n1), branch \\\"$(git -C ${srcdir} describe --tags --always --all | sed s:heads/::)\\\")"
35 # Mirrors what libi3/is_debug_build.c does:
36 is_release=$(test $(echo "${I3_VERSION}" | cut -d '(' -f 1 | wc -m) -lt 10 && echo yes || echo no)
37 ],
38 [
39 VERSION="$(cut -d '-' -f 1 ${srcdir}/I3_VERSION | cut -d ' ' -f 1)"
40 I3_VERSION="$(sed -e 's/@<:@\"?\\@:>@/\\&/g' ${srcdir}/I3_VERSION)"
41 is_release="$(grep -q non-git ${srcdir}/I3_VERSION && echo no || echo yes)"
42 ])
43 AC_SUBST([I3_VERSION], [$I3_VERSION])
44 MAJOR_VERSION="$(echo ${VERSION} | cut -d '.' -f 1)"
45 MINOR_VERSION="$(echo ${VERSION} | cut -d '.' -f 2)"
46 PATCH_VERSION="$(echo ${VERSION} | cut -d '.' -f 3)"
47 AS_IF([test "x${PATCH_VERSION}" = x], [PATCH_VERSION=0])
48 AC_DEFINE_UNQUOTED([I3_VERSION], ["${I3_VERSION}"], [i3 version])
49 AC_DEFINE_UNQUOTED([MAJOR_VERSION], [${MAJOR_VERSION}], [i3 major version])
50 AC_DEFINE_UNQUOTED([MINOR_VERSION], [${MINOR_VERSION}], [i3 minor version])
51 AC_DEFINE_UNQUOTED([PATCH_VERSION], [${PATCH_VERSION}], [i3 patch version])
52
53 AX_CODE_COVERAGE
54
55 dnl is_release must be lowercase because AX_CHECK_ENABLE_DEBUG calls m4_tolower
56 dnl on its fourth argument.
57 AX_CHECK_ENABLE_DEBUG([yes], , [UNUSED_NDEBUG], [$is_release])
58
59 AC_PROG_CC_C99
60
61 # For strnlen() and vasprintf().
62 AC_USE_SYSTEM_EXTENSIONS
63
64 # Checks for typedefs, structures, and compiler characteristics.
65 AC_CHECK_HEADER_STDBOOL
66 dnl The error message should include the specific type which could not be
67 dnl found, but I do not see a way to achieve that.
68 AC_CHECK_TYPES([mode_t, off_t, pid_t, size_t, ssize_t], , [AC_MSG_FAILURE([cannot find required type])])
69
70 # Checks for library functions.
71 AC_FUNC_FORK
72 AC_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK
73 AC_FUNC_STRNLEN
74 AC_CHECK_FUNCS([atexit dup2 ftruncate getcwd gettimeofday localtime_r memchr memset mkdir rmdir setlocale socket strcasecmp strchr strdup strerror strncasecmp strrchr strspn strstr strtol strtoul], , [AC_MSG_FAILURE([cannot find the $ac_func function, which i3 requires])])
75 AC_REPLACE_FUNCS([mkdirp strndup])
76
77 # Checks for libraries.
78
79 AC_SEARCH_LIBS([floor], [m], , [AC_MSG_FAILURE([cannot find the required floor() function despite trying to link with -lm])])
80
81 # libev does not ship with a pkg-config file :(.
82 AC_SEARCH_LIBS([ev_run], [ev], , [AC_MSG_FAILURE([cannot find the required ev_run() function despite trying to link with -lev])])
83
84 AC_SEARCH_LIBS([shm_open], [rt], [], [], [-pthread])
85
86 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <iconv.h>], [iconv_open(0, 0)])], ,
87 [LIBS="-liconv $LIBS"
88 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <iconv.h>], [iconv_open(0, 0)])], ,
89 [AC_MSG_FAILURE([cannot find the required iconv_open() function despite trying to link with -liconv])])]
90 )
91
92 AX_PTHREAD
93
94 dnl Each prefix corresponds to a source tarball which users might have
95 dnl downloaded in a newer version and would like to overwrite.
96 PKG_CHECK_MODULES([LIBSN], [libstartup-notification-1.0])
97 PKG_CHECK_MODULES([XCB], [xcb xcb-xkb xcb-xinerama xcb-randr xcb-shape])
98 PKG_CHECK_MODULES([XCB_UTIL], [xcb-event xcb-util])
99 PKG_CHECK_MODULES([XCB_UTIL_CURSOR], [xcb-cursor])
100 PKG_CHECK_MODULES([XCB_UTIL_KEYSYMS], [xcb-keysyms])
101 PKG_CHECK_MODULES([XCB_UTIL_WM], [xcb-icccm])
102 PKG_CHECK_MODULES([XCB_UTIL_XRM], [xcb-xrm])
103 PKG_CHECK_MODULES([XKBCOMMON], [xkbcommon xkbcommon-x11])
104 PKG_CHECK_MODULES([YAJL], [yajl])
105 PKG_CHECK_MODULES([LIBPCRE], [libpcre >= 8.10])
106 PKG_CHECK_MODULES([PANGOCAIRO], [cairo >= 1.14.4 pangocairo])
107 PKG_CHECK_MODULES([GLIBGOBJECT], [glib-2.0 gobject-2.0])
108
109 # Checks for programs.
110 AC_PROG_AWK
111 AC_PROG_CPP
112 AC_PROG_INSTALL
113 AC_PROG_MAKE_SET
114 AC_PROG_RANLIB
115 AC_PROG_LN_S
116
117 AC_ARG_ENABLE(docs,
118 AS_HELP_STRING(
119 [--disable-docs],
120 [disable building documentation]),
121 [ax_docs=$enableval],
122 [ax_docs=yes])
123 AC_ARG_ENABLE(mans,
124 AS_HELP_STRING(
125 [--disable-mans],
126 [disable building manual pages]),
127 [ax_mans=$enableval],
128 [ax_mans=yes])
129 AS_IF([test x$ax_docs = xyes || test x$ax_mans = xyes], [
130 AC_PATH_PROG([PATH_ASCIIDOC], [asciidoc])
131 ])
132 AS_IF([test x$ax_mans = xyes], [
133 AC_PATH_PROG([PATH_XMLTO], [xmlto])
134 AC_PATH_PROG([PATH_POD2MAN], [pod2man])
135 ])
136 AM_CONDITIONAL([BUILD_MANS], [test x$ax_mans = xyes && test x$PATH_ASCIIDOC != x && test x$PATH_XMLTO != x && test x$PATH_POD2MAN != x])
137 AM_CONDITIONAL([BUILD_DOCS], [test x$ax_docs = xyes && test x$PATH_ASCIIDOC != x])
138
139 AM_PROG_AR
140
141 AX_FLAGS_WARN_ALL
142 AX_CHECK_COMPILE_FLAG([-Wunused-value], [AX_APPEND_FLAG([-Wunused-value], [AM_CFLAGS])])
143 AC_SUBST(AM_CFLAGS)
144
145 # Checks for header files.
146 AC_CHECK_HEADERS([fcntl.h float.h inttypes.h limits.h locale.h netinet/in.h paths.h stddef.h stdint.h stdlib.h string.h sys/param.h sys/socket.h sys/time.h unistd.h], , [AC_MSG_FAILURE([cannot find the $ac_header header, which i3 requires])])
147
148 AC_CONFIG_FILES([Makefile testcases/lib/i3test.pm man/asciidoc.conf])
149 AC_CONFIG_FILES([testcases/complete-run.pl], [chmod +x testcases/complete-run.pl])
150
151 # Enable address sanitizer for non-release builds. The performance hit is a
152 # 50% increase of wallclock time for the testsuite on my machine.
153 if test x$is_release = xyes; then
154 default_sanitizers=
155 else
156 default_sanitizers=address
157 fi
158 AX_SANITIZERS(, [$default_sanitizers], [AC_DEFINE([I3_ASAN_ENABLED], [], [Enable ASAN])])
159
160 AC_OUTPUT
161
162 if test -z "${BUILD_DOCS_TRUE}"; then
163 print_BUILD_DOCS=yes
164 else
165 print_BUILD_DOCS=no
166 fi
167
168
169 if test -z "${BUILD_MANS_TRUE}"; then
170 print_BUILD_MANS=yes
171 else
172 print_BUILD_MANS=no
173 fi
174
175 in_git_worktree=`git rev-parse --is-inside-work-tree 2>/dev/null`
176 if [[ "$in_git_worktree" = "true" ]]; then
177 git_dir=`git rev-parse --git-dir 2>/dev/null`
178 srcdir=`dirname "$git_dir"`
179 exclude_dir=`pwd | sed "s,^$srcdir,,g"`
180 if ! grep -q "^$exclude_dir" "$git_dir/info/exclude"; then
181 echo "$exclude_dir" >> "$git_dir/info/exclude"
182 fi
183 fi
184
185 echo \
186 "--------------------------------------------------------------------------------
187 build configured:
188
189 AS_HELP_STRING([i3 version:], [`echo ${I3_VERSION} | sed 's,\\\\,,g'`])
190 AS_HELP_STRING([is release version:], [${is_release}])
191
192 AS_HELP_STRING([build manpages:], [${print_BUILD_MANS}])
193 AS_HELP_STRING([build docs:], [${print_BUILD_DOCS}])
194 AS_HELP_STRING([enable debug flags:], [${ax_enable_debug}])
195 AS_HELP_STRING([code coverage:], [${CODE_COVERAGE_ENABLED}])
196 AS_HELP_STRING([enabled sanitizers:], [${ax_enabled_sanitizers}])
197
198 To compile, run:
199
200 cd `pwd` && make -j8
201 --------------------------------------------------------------------------------"
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="7086.6138"
13 height="2622.0471"
14 id="svg2"
15 sodipodi:version="0.32"
16 inkscape:version="0.48.1 r9760"
17 sodipodi:docname="banner.pdf"
18 inkscape:output_extension="org.inkscape.output.svg.inkscape"
19 version="1.1">
20 <defs
21 id="defs4">
22 <linearGradient
23 id="linearGradient3750">
24 <stop
25 style="stop-color:#17273b;stop-opacity:1;"
26 offset="0"
27 id="stop3752" />
28 <stop
29 id="stop4356"
30 offset="0.41666666"
31 style="stop-color:#008cd4;stop-opacity:0.78039217;" />
32 <stop
33 style="stop-color:#6eb5de;stop-opacity:0.69803923;"
34 offset="0.87847221"
35 id="stop4358" />
36 <stop
37 style="stop-color:#88bfe5;stop-opacity:0.61960787;"
38 offset="1"
39 id="stop3754" />
40 </linearGradient>
41 <inkscape:perspective
42 id="perspective3661"
43 inkscape:persp3d-origin="750.50629 : 505.26732 : 1"
44 inkscape:vp_z="683.5728 : 1230.5721 : 1"
45 inkscape:vp_y="0 : 1946.8917 : 0"
46 inkscape:vp_x="-526.84957 : 2.2065866e-13 : 0"
47 sodipodi:type="inkscape:persp3d" />
48 <linearGradient
49 id="linearGradient3284">
50 <stop
51 style="stop-color:#ffffff;stop-opacity:1;"
52 offset="0"
53 id="stop3286" />
54 <stop
55 style="stop-color:#ffffff;stop-opacity:0.7518248;"
56 offset="1"
57 id="stop3288" />
58 </linearGradient>
59 <linearGradient
60 id="linearGradient3278">
61 <stop
62 id="stop3280"
63 offset="0"
64 style="stop-color:#33bff7;stop-opacity:0.38039216;" />
65 <stop
66 id="stop3282"
67 offset="1"
68 style="stop-color:#2d446b;stop-opacity:1;" />
69 </linearGradient>
70 <linearGradient
71 id="linearGradient3272">
72 <stop
73 id="stop3274"
74 offset="0"
75 style="stop-color:#2596f6;stop-opacity:0.38039216;" />
76 <stop
77 id="stop3276"
78 offset="1"
79 style="stop-color:#2d446b;stop-opacity:1;" />
80 </linearGradient>
81 <linearGradient
82 id="linearGradient3266">
83 <stop
84 id="stop3268"
85 offset="0"
86 style="stop-color:#189fff;stop-opacity:0.38039216;" />
87 <stop
88 id="stop3270"
89 offset="1"
90 style="stop-color:#010b2b;stop-opacity:1;" />
91 </linearGradient>
92 <linearGradient
93 id="linearGradient3244">
94 <stop
95 id="stop3246"
96 offset="0"
97 style="stop-color:#419bff;stop-opacity:1;" />
98 <stop
99 id="stop3248"
100 offset="1"
101 style="stop-color:#002359;stop-opacity:1;" />
102 </linearGradient>
103 <linearGradient
104 id="linearGradient3159">
105 <stop
106 style="stop-color:#33bff7;stop-opacity:0.38039216;"
107 offset="0"
108 id="stop3161" />
109 <stop
110 style="stop-color:#2d446b;stop-opacity:1;"
111 offset="1"
112 id="stop3163" />
113 </linearGradient>
114 <inkscape:perspective
115 sodipodi:type="inkscape:persp3d"
116 inkscape:vp_x="-526.84957 : 2.9848654e-13 : 0"
117 inkscape:vp_y="1.192088e-13 : 1946.8917 : 0"
118 inkscape:vp_z="680.54236 : 1232.3792 : 1"
119 inkscape:persp3d-origin="730.30325 : 937.39936 : 1"
120 id="perspective10" />
121 <radialGradient
122 inkscape:collect="always"
123 xlink:href="#linearGradient3244"
124 id="radialGradient3256"
125 cx="344.73471"
126 cy="77.263504"
127 fx="344.73471"
128 fy="77.263504"
129 r="196.15704"
130 gradientTransform="matrix(-1.39796,-0.05336032,0.08355111,-2.1889079,820.20461,272.08319)"
131 gradientUnits="userSpaceOnUse" />
132 <radialGradient
133 inkscape:collect="always"
134 xlink:href="#linearGradient3159"
135 id="radialGradient3264"
136 cx="140.3363"
137 cy="300.27451"
138 fx="140.3363"
139 fy="300.27451"
140 r="206.15704"
141 gradientTransform="matrix(0.6771172,-0.6830119,1.1802789,1.1700925,-161.83993,77.639162)"
142 gradientUnits="userSpaceOnUse" />
143 <radialGradient
144 inkscape:collect="always"
145 xlink:href="#linearGradient3284"
146 id="radialGradient3290"
147 cx="267.50388"
148 cy="337.12692"
149 fx="267.50388"
150 fy="337.12692"
151 r="77.845421"
152 gradientTransform="matrix(1,0,0,0.7430849,0,86.613009)"
153 gradientUnits="userSpaceOnUse" />
154 <inkscape:perspective
155 id="perspective3373"
156 inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
157 inkscape:vp_z="744.09448 : 526.18109 : 1"
158 inkscape:vp_y="0 : 1000 : 0"
159 inkscape:vp_x="0 : 526.18109 : 1"
160 sodipodi:type="inkscape:persp3d" />
161 <linearGradient
162 id="linearGradient3211">
163 <stop
164 id="stop3213"
165 offset="0"
166 style="stop-color: rgb(0, 160, 255); stop-opacity: 1;" />
167 <stop
168 id="stop3215"
169 offset="1"
170 style="stop-color: rgb(0, 37, 255); stop-opacity: 1;" />
171 </linearGradient>
172 <filter
173 inkscape:collect="always"
174 id="filter3406"
175 color-interpolation-filters="sRGB">
176 <feGaussianBlur
177 inkscape:collect="always"
178 stdDeviation="13.396228"
179 id="feGaussianBlur3408" />
180 </filter>
181 <radialGradient
182 inkscape:collect="always"
183 xlink:href="#linearGradient3284"
184 id="radialGradient3416"
185 cx="119.96373"
186 cy="229.28981"
187 fx="119.96373"
188 fy="229.28981"
189 r="203.19508"
190 gradientTransform="matrix(0.7210805,2.1168143,-1.4722239,0.5015047,347.53034,-320.94088)"
191 gradientUnits="userSpaceOnUse" />
192 <radialGradient
193 inkscape:collect="always"
194 xlink:href="#linearGradient3266"
195 id="radialGradient3423"
196 gradientUnits="userSpaceOnUse"
197 gradientTransform="matrix(9.0785365,-9.2630105,16.085822,15.212343,-6979.1531,-2584.4202)"
198 cx="351.15485"
199 cy="372.06332"
200 fx="351.15485"
201 fy="372.06332"
202 r="163.57143" />
203 <radialGradient
204 inkscape:collect="always"
205 xlink:href="#linearGradient3284"
206 id="radialGradient3734"
207 gradientUnits="userSpaceOnUse"
208 gradientTransform="matrix(0.7210805,2.1168143,-1.4722239,0.5015047,347.53034,-320.94088)"
209 cx="119.96373"
210 cy="229.28981"
211 fx="119.96373"
212 fy="229.28981"
213 r="203.19508" />
214 <radialGradient
215 inkscape:collect="always"
216 xlink:href="#linearGradient3284"
217 id="radialGradient3736"
218 gradientUnits="userSpaceOnUse"
219 gradientTransform="matrix(0.7210805,2.1168143,-1.4722239,0.5015047,347.53034,-320.94088)"
220 cx="119.96373"
221 cy="229.28981"
222 fx="119.96373"
223 fy="229.28981"
224 r="203.19508" />
225 <radialGradient
226 inkscape:collect="always"
227 xlink:href="#linearGradient3750"
228 id="radialGradient3758"
229 cx="390.69662"
230 cy="258.92429"
231 fx="390.69662"
232 fy="258.92429"
233 r="32.03125"
234 gradientTransform="matrix(4.0292425,-5.5974184,5.1695404,3.721239,-2510.9809,1613.1551)"
235 gradientUnits="userSpaceOnUse" />
236 <radialGradient
237 inkscape:collect="always"
238 xlink:href="#linearGradient3750"
239 id="radialGradient3760"
240 cx="59.046589"
241 cy="248.2272"
242 fx="59.046589"
243 fy="248.2272"
244 r="197.15625"
245 gradientTransform="matrix(1.7105919,-0.04370519,0.03334715,1.3051856,-58.593126,-250.18318)"
246 gradientUnits="userSpaceOnUse" />
247 <radialGradient
248 inkscape:collect="always"
249 xlink:href="#linearGradient3750"
250 id="radialGradient3762"
251 cx="192.64008"
252 cy="282.40387"
253 fx="192.64008"
254 fy="282.40387"
255 r="133.09375"
256 gradientTransform="matrix(1.0081228,0.4493093,-1.0529321,2.3624813,273.13721,-455.12138)"
257 gradientUnits="userSpaceOnUse" />
258 <radialGradient
259 inkscape:collect="always"
260 xlink:href="#linearGradient3750"
261 id="radialGradient4344"
262 gradientUnits="userSpaceOnUse"
263 gradientTransform="matrix(5.7478532,-0.5889281,0.4834745,4.7186431,-260.98332,-919.446)"
264 cx="24"
265 cy="280.45392"
266 fx="24"
267 fy="280.45392"
268 r="65.0625" />
269 <linearGradient
270 inkscape:collect="always"
271 xlink:href="#linearGradient3750"
272 id="linearGradient4354"
273 x1="-125.59599"
274 y1="-100.47679"
275 x2="-5.2882538"
276 y2="-100.47679"
277 gradientUnits="userSpaceOnUse" />
278 </defs>
279 <sodipodi:namedview
280 id="base"
281 pagecolor="#ffffff"
282 bordercolor="#666666"
283 borderopacity="1.0"
284 inkscape:pageopacity="0.0"
285 inkscape:pageshadow="2"
286 inkscape:zoom="0.062500002"
287 inkscape:cx="2861.2881"
288 inkscape:cy="656.52996"
289 inkscape:document-units="px"
290 inkscape:current-layer="layer1"
291 showgrid="false"
292 inkscape:window-width="956"
293 inkscape:window-height="1018"
294 inkscape:window-x="2560"
295 inkscape:window-y="162"
296 fit-margin-top="0"
297 fit-margin-left="0"
298 fit-margin-right="0"
299 fit-margin-bottom="0"
300 inkscape:window-maximized="0"
301 units="cm" />
302 <metadata
303 id="metadata7">
304 <rdf:RDF>
305 <cc:Work
306 rdf:about="">
307 <dc:format>image/svg+xml</dc:format>
308 <dc:type
309 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
310 <dc:title></dc:title>
311 <dc:contributor>
312 <cc:Agent>
313 <dc:title>yellowiscool, farvardin</dc:title>
314 </cc:Agent>
315 </dc:contributor>
316 <dc:creator>
317 <cc:Agent>
318 <dc:title>steckdenis</dc:title>
319 </cc:Agent>
320 </dc:creator>
321 <dc:description>Logo for I3, an improved dynamic tiling window manager: http://i3.zekjur.net/</dc:description>
322 <cc:license
323 rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
324 </cc:Work>
325 <cc:License
326 rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
327 <cc:permits
328 rdf:resource="http://creativecommons.org/ns#Reproduction" />
329 <cc:permits
330 rdf:resource="http://creativecommons.org/ns#Distribution" />
331 <cc:requires
332 rdf:resource="http://creativecommons.org/ns#Notice" />
333 <cc:requires
334 rdf:resource="http://creativecommons.org/ns#Attribution" />
335 <cc:permits
336 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
337 <cc:requires
338 rdf:resource="http://creativecommons.org/ns#ShareAlike" />
339 </cc:License>
340 </rdf:RDF>
341 </metadata>
342 <g
343 inkscape:groupmode="layer"
344 id="layer4"
345 inkscape:label="fond"
346 style="display:none"
347 transform="translate(-39.157291,2258.4378)">
348 <rect
349 style="opacity:0.87000002;fill:#5599ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:60;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
350 id="rect3241"
351 width="330"
352 height="313.5"
353 x="39"
354 y="103.86218" />
355 </g>
356 <g
357 inkscape:label="Calque 1"
358 inkscape:groupmode="layer"
359 id="layer1"
360 style="display:inline"
361 transform="translate(-39.157291,2258.4378)">
362 <rect
363 style="fill:#2e2e2e;fill-opacity:1;stroke:none"
364 id="rect3834"
365 width="7229.6289"
366 height="2725.7007"
367 x="37.157291"
368 y="-2261.1418" />
369 <rect
370 style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:155.6656189;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
371 id="rect3836"
372 width="2380.248"
373 height="2290.5771"
374 x="507.66498"
375 y="-2114.5522" />
376 <rect
377 style="fill:url(#radialGradient3423);fill-opacity:1;fill-rule:nonzero;stroke:none"
378 id="rect2383"
379 width="2558.9255"
380 height="2445.6987"
381 x="407.12625"
382 y="-2192.6528" />
383 <path
384 style="opacity:0.09583333;fill:#ffffff;fill-opacity:1;stroke:none"
385 d="m 413.86349,-2192.5867 c -15.25265,33.2522 -2.32827,78.5617 -6.30947,116.6372 1.72096,380.4493 3.44192,760.8985 5.16287,1141.34766 93.88235,82.98568 229.27384,70.38365 345.4922,86.49033 423.97831,27.2898 850.31151,28.61862 1272.94371,-19.4116 269.6865,-27.22552 539.3778,-69.20434 799.6418,-145.93839 66.2578,-22.2482 149.4887,-73.1004 135.2925,-153.3025 0,-341.9409 0,-683.8819 0,-1025.8227 -850.7413,0 -1701.4825,0 -2552.22361,0 z"
386 id="path3221"
387 inkscape:connector-curvature="0" />
388 <g
389 transform="matrix(2.6849003,-2.6961195,2.6961195,2.6849003,536.88627,-838.56295)"
390 style="opacity:0.5;fill:#000000;fill-opacity:1;filter:url(#filter3406)"
391 id="g3394">
392 <path
393 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
394 d="M 412.75,98.59375 C 396.19379,98.835333 382.96319,112.44354 383.1875,129 c 0,0 -10e-6,87.25107 0,196.3125 0,23.30736 -12.11655,39.13192 -38.21875,53.46875 -26.1022,14.33683 -64.97276,22.875 -103.875,22.875 -38.90224,0 -77.7728,-8.53817 -103.875,-22.875 C 111.11655,364.44442 99,348.61986 99,325.3125 c 0,-54.37333 0.441249,-103.35555 0.65625,-138.875 0.1075,-17.75973 0.177008,-32.11577 0.09375,-42.34375 -0.04163,-5.11399 -0.129499,-9.10767 -0.28125,-12.46875 -0.07588,-1.68054 -0.136902,-3.05581 -0.40625,-5.25 -0.134674,-1.09709 -0.168072,-2.2122 -1,-5.1875 C 97.646536,119.69985 97.275733,117.79087 94.875,113.75 92.474267,109.70913 84.912085,98.999943 69,99 59.653467,98.879464 50.78473,103.12192 45.013008,110.47443 39.241286,117.82694 37.226064,127.44941 39.5625,136.5 c 0.06318,2.03091 0.15684,4.32729 0.1875,8.09375 0.07765,9.5394 0.0133,23.81477 -0.09375,41.5 C 39.442151,221.46421 39,270.62442 39,325.3125 c -10e-7,47.58256 30.913445,84.95437 69.34375,106.0625 38.43031,21.10813 85.6089,30.28125 132.75,30.28125 47.1411,0 94.31969,-9.17312 132.75,-30.28125 38.43031,-21.10813 69.34375,-58.47994 69.34375,-106.0625 -10e-6,-109.06142 0,-196.3125 0,-196.3125 0.10978,-8.10283 -3.06279,-15.9055 -8.79582,-21.63265 -5.73304,-5.72715 -13.53896,-8.891699 -21.64168,-8.7736 l 0,0 z"
395 id="path3396"
396 inkscape:connector-curvature="0" />
397 <path
398 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
399 d="M 239.5625,99.5 C 223.00629,99.741583 209.77569,113.34979 210,129.90625 L 210,350 c -0.15301,10.81908 5.53126,20.88244 14.87619,26.33663 9.34492,5.45419 20.9027,5.45419 30.24762,0 C 264.46874,370.88244 270.15301,360.81908 270,350 l 0,-220.09375 c 0.10978,-8.10283 -3.06279,-15.9055 -8.79582,-21.63265 -5.73304,-5.72715 -13.53896,-8.891699 -21.64168,-8.7736 l 0,0 z"
400 id="path3398"
401 inkscape:connector-curvature="0" />
402 <path
403 sodipodi:type="arc"
404 style="fill:#000000;fill-opacity:1;stroke-width:60;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
405 id="path3400"
406 sodipodi:cx="70"
407 sodipodi:cy="40"
408 sodipodi:rx="30"
409 sodipodi:ry="30"
410 d="M 100,40 C 100,56.568542 86.568542,70 70,70 53.431458,70 40,56.568542 40,40 40,23.431458 53.431458,10 70,10 c 16.568542,0 30,13.431458 30,30 z"
411 transform="translate(0,-10)" />
412 <path
413 transform="translate(170,-10)"
414 d="M 100,40 C 100,56.568542 86.568542,70 70,70 53.431458,70 40,56.568542 40,40 40,23.431458 53.431458,10 70,10 c 16.568542,0 30,13.431458 30,30 z"
415 sodipodi:ry="30"
416 sodipodi:rx="30"
417 sodipodi:cy="40"
418 sodipodi:cx="70"
419 id="path3402"
420 style="fill:#000000;fill-opacity:1;stroke-width:60;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
421 sodipodi:type="arc" />
422 <path
423 sodipodi:type="arc"
424 style="fill:#000000;fill-opacity:1;stroke-width:60;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
425 id="path3404"
426 sodipodi:cx="70"
427 sodipodi:cy="40"
428 sodipodi:rx="30"
429 sodipodi:ry="30"
430 d="M 100,40 C 100,56.568542 86.568542,70 70,70 53.431458,70 40,56.568542 40,40 40,23.431458 53.431458,10 70,10 c 16.568542,0 30,13.431458 30,30 z"
431 transform="translate(345,-10)" />
432 </g>
433 <text
434 xml:space="preserve"
435 style="font-size:110.96224976px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#3a8ecd;fill-opacity:1;stroke:none;font-family:Union;-inkscape-font-specification:Union"
436 x="3376.4146"
437 y="-1172.4049"
438 id="text3058"
439 sodipodi:linespacing="125%"><tspan
440 sodipodi:role="line"
441 id="tspan3060"
442 x="3376.4146"
443 y="-1172.4049"
444 style="font-size:1141.3260498px;font-weight:bold;fill:#3a8ecd;fill-opacity:1;-inkscape-font-specification:Union Bold">i3</tspan></text>
445 <text
446 xml:space="preserve"
447 style="font-size:110.96224976px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Union;-inkscape-font-specification:Union"
448 x="3400.1733"
449 y="-565.84204"
450 id="text3062"
451 sodipodi:linespacing="125%"><tspan
452 sodipodi:role="line"
453 id="tspan3064"
454 x="3400.1733"
455 y="-565.84204"
456 style="font-size:570.6630249px;fill:#ffffff;fill-opacity:1">improved</tspan><tspan
457 sodipodi:role="line"
458 x="3400.1733"
459 y="147.48674"
460 style="font-size:570.6630249px;fill:#ffffff;fill-opacity:1"
461 id="tspan3063">tiling wm</tspan></text>
462 </g>
463 <g
464 inkscape:groupmode="layer"
465 id="layer2"
466 inkscape:label="tiling"
467 style="display:none"
468 transform="translate(-39.157291,2258.4378)">
469 <rect
470 y="106.6479"
471 x="42.85714"
472 height="308.57144"
473 width="322.85715"
474 id="rect3247"
475 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
476 <rect
477 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
478 id="rect3253"
479 width="212.07706"
480 height="98.216858"
481 x="42.85096"
482 y="218.0385" />
483 <rect
484 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
485 id="rect3257"
486 width="110.75323"
487 height="70.943619"
488 x="254.94135"
489 y="274.26196" />
490 <rect
491 y="218.02481"
492 x="254.93958"
493 height="56.235466"
494 width="110.76914"
495 id="rect3259"
496 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
497 <rect
498 y="345.25272"
499 x="254.91608"
500 height="69.955116"
501 width="110.78036"
502 id="rect3255"
503 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
504 <rect
505 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
506 id="rect3249"
507 width="106.87583"
508 height="111.69163"
509 x="42.849949"
510 y="106.32091" />
511 <rect
512 y="106.45182"
513 x="149.72185"
514 height="111.57816"
515 width="105.18911"
516 id="rect3261"
517 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
518 <rect
519 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
520 id="rect3263"
521 width="110.786"
522 height="111.57211"
523 x="254.91632"
524 y="106.45485" />
525 <rect
526 y="316.22876"
527 x="42.847878"
528 height="98.979958"
529 width="212.0791"
530 id="rect3251"
531 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" />
532 </g>
533 <g
534 inkscape:groupmode="layer"
535 id="layer5"
536 inkscape:label="tiling2"
537 style="display:inline"
538 transform="translate(-39.157291,2258.4378)">
539 <rect
540 y="-2192.6528"
541 x="407.12625"
542 height="2445.6987"
543 width="2558.9255"
544 id="rect3244"
545 style="fill:none;stroke:#000000;stroke-width:7.92587519;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" />
546 <rect
547 style="fill:none;stroke:#000000;stroke-width:7.92587519;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
548 id="rect3246"
549 width="2558.9255"
550 height="2445.6987"
551 x="407.12625"
552 y="-2192.6528" />
553 <path
554 style="fill:none;stroke:#000000;stroke-width:7.92587519;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
555 d="m 1516.7488,-2192.653 0,2445.6988 0,-2445.6988 z"
556 id="path73"
557 sodipodi:nodetypes="ccc"
558 inkscape:connector-curvature="0" />
559 <path
560 sodipodi:nodetypes="ccc"
561 id="path3254"
562 d="m 1513.2638,-1393.8379 -1102.65249,0 1102.65249,0 z"
563 style="fill:none;stroke:#000000;stroke-width:7.92587519;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
564 inkscape:connector-curvature="0" />
565 <path
566 style="fill:none;stroke:#000000;stroke-width:7.92587519;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
567 d="m 1513.2638,-553.69513 -1102.65249,0 1102.65249,0 z"
568 id="path3256"
569 sodipodi:nodetypes="ccc"
570 inkscape:connector-curvature="0" />
571 </g>
572 <g
573 inkscape:groupmode="layer"
574 id="layer3"
575 inkscape:label="I3"
576 style="display:inline"
577 transform="translate(-39.157291,2258.4378)">
578 <path
579 style="opacity:0.87000002;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:60;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
580 d="m 1910.8996,-1686.6719 c -43.8006,45.2862 -42.6341,117.4941 2.6064,161.3419 0,0 235.2392,234.2605 529.282,527.07952 62.8393,62.57796 72.9725,137.7329 41.5446,246.60061 -31.428,108.86761 -112.7716,236.59139 -217.2204,341.47644 -104.4485,104.88515 -231.8323,186.76064 -340.5677,218.64229 -108.7357,31.88176 -183.9323,22.06207 -246.7717,-40.51589 -146.597,-145.98708 -277.4742,-278.68913 -372.6616,-374.63493 -47.5938,-47.97291 -86.1127,-86.70483 -113.9122,-113.94145 -13.8996,-13.61834 -24.903,-24.10409 -34.3723,-32.71913 -4.7346,-4.30745 -8.6064,-7.83547 -15.2454,-13.00042 -3.3194,-2.58251 -6.4155,-5.48637 -16.671,-11.23181 -5.1277,-2.87267 -11.2701,-6.9983 -28.6106,-11.375 -17.3403,-4.37678 -66.5173,-12.74127 -109.2395,30.15978 -25.41947,24.87572 -37.79297,60.17755 -33.46619,95.47948 4.32669,35.30205 24.85939,66.57063 55.53399,84.57122 5.6452,5.28257 12.088,11.19556 22.3251,21.22547 25.9279,25.40294 64.2432,63.90443 111.6373,111.67611 94.7881,95.54346 226.1427,228.72579 373.5883,375.557869 128.2883,127.754376 312.0468,144.747557 472.1383,97.808209 160.0916,-46.939459 311.4932,-149.509768 438.0623,-276.607698 126.5694,-127.09813 228.5073,-278.92621 274.7788,-439.21204 46.2715,-160.28596 28.5121,-343.97193 -99.7762,-471.72633 -294.0426,-292.819 -529.282,-527.0795 -529.282,-527.0795 -21.5513,-22.0513 -51.1063,-34.4471 -81.9399,-34.3669 -30.8338,0.079 -60.324,12.6292 -81.7604,34.7922 l 0,0 z"
581 id="path2405"
582 inkscape:connector-curvature="0" />
583 <path
584 style="opacity:0.87000002;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
585 d="m 1448.3517,-1217.3044 c -43.8005,45.2861 -42.6341,117.494 2.6065,161.3418 l 593.3989,590.92975 c 28.7587,29.46065 71.1525,41.15432 110.9479,30.60322 39.7953,-10.551 70.8268,-41.71214 81.2117,-81.55118 10.3852,-39.83905 -1.4851,-82.18356 -31.0655,-110.81923 l -593.399,-590.92976 c -21.5515,-22.0513 -51.1064,-34.447 -81.9402,-34.367 -30.8336,0.079 -60.3238,12.6293 -81.7603,34.7924 l 0,0 z"
586 id="path3179"
587 inkscape:connector-curvature="0" />
588 <path
589 sodipodi:type="arc"
590 style="opacity:0.87000002;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:124.98213196;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
591 id="path3181"
592 sodipodi:cx="70"
593 sodipodi:cy="40"
594 sodipodi:rx="30"
595 sodipodi:ry="30"
596 d="m 100,40 a 30,30 0 1 1 -60,0 30,30 0 1 1 60,0 z"
597 transform="matrix(2.6849003,-2.6961195,2.6961195,2.6849003,509.92508,-865.41186)" />
598 <path
599 transform="matrix(2.6849003,-2.6961195,2.6961195,2.6849003,966.35812,-1323.7522)"
600 d="m 100,40 a 30,30 0 1 1 -60,0 30,30 0 1 1 60,0 z"
601 sodipodi:ry="30"
602 sodipodi:rx="30"
603 sodipodi:cy="40"
604 sodipodi:cx="70"
605 id="path3183"
606 style="opacity:0.87000002;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:124.98213196;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
607 sodipodi:type="arc" />
608 <path
609 sodipodi:type="arc"
610 style="opacity:0.87000002;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:124.98213196;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
611 id="path3185"
612 sodipodi:cx="70"
613 sodipodi:cy="40"
614 sodipodi:rx="30"
615 sodipodi:ry="30"
616 d="m 100,40 a 30,30 0 1 1 -60,0 30,30 0 1 1 60,0 z"
617 transform="matrix(2.6849003,-2.6961195,2.6961195,2.6849003,1436.2157,-1795.5732)" />
618 </g>
619 </svg>
0 #!/usr/bin/env perl
1 # vim:ts=4:sw=4:expandtab
2
3 use strict;
4 use warnings;
5 use Data::Dumper;
6 use Getopt::Long;
7 use Pod::Usage;
8 use AnyEvent::I3;
9 use File::Temp;
10 use File::Spec;
11 use File::Basename;
12 use v5.10;
13 use IPC::Cmd qw[can_run];
14
15 my %options = (
16 gv => 1,
17 save => undef,
18 help => 0,
19 );
20 my $result = GetOptions(
21 "gv!" => \$options{gv},
22 "save=s" => \$options{save},
23 "help|?" => \$options{help},
24 );
25
26 pod2usage(-verbose => 2, -exitcode => 0) if $options{help};
27
28 # prerequisites check so we can be specific about failures caused
29 # by not having these tools in the path
30 can_run('asy') or die 'Please install asymptote';
31 can_run('gv') or die 'Please install gv' unless !$options{gv};
32
33 my $i3 = i3();
34
35 my $tree = $i3->get_tree->recv;
36
37 my $tmp = File::Temp->new(UNLINK => 0, SUFFIX => '.asy');
38
39 say $tmp "import drawtree;";
40
41 say $tmp "treeLevelStep = 2cm;";
42
43 sub dump_node {
44 my ($n, $parent) = @_;
45
46 my $o = ($n->{orientation} eq 'none' ? "u" : ($n->{orientation} eq 'horizontal' ? "h" : "v"));
47 my $w = (defined($n->{window}) ? $n->{window} : "N");
48 my $na = ($n->{name} or ($n->{type} eq "floating_con" ? "[Floating con]" : "[Empty]"));
49 $na =~ s/#/\\#/g;
50 $na =~ s/\$/\\\$/g;
51 $na =~ s/&/\\&/g;
52 $na =~ s/_/\\_/g;
53 $na =~ s/~/\\textasciitilde{}/g;
54 my $type = 'leaf';
55 if (!defined($n->{window})) {
56 $type = $n->{layout};
57 }
58 my $marks = $n->{marks} ? ' [' . join('][', @{$n->{marks}}) . ']' : '';
59 my $name = qq|``$na'' ($type)$marks|;
60
61 print $tmp "TreeNode n" . $n->{id} . " = makeNode(";
62
63 print $tmp "n" . $parent->{id} . ", " if defined($parent);
64 print $tmp "\"" . $name . "\");\n";
65
66 dump_node($_, $n) for @{$n->{nodes}};
67 dump_node($_, $n) for @{$n->{floating_nodes}};
68 }
69
70 sub find_node_with_name {
71 my ($node, $name) = @_;
72
73 return $node if ($node->{name} eq $name);
74 for my $child (@{$node->{nodes}}) {
75 my $res = find_node_with_name($child, $name);
76 return $res if defined($res);
77 }
78 return undef;
79 }
80
81 my $start = shift;
82 my $root;
83 if ($start) {
84 # Find the specified node in the tree
85 $root = find_node_with_name($tree, $start);
86 } else {
87 $root = $tree;
88 }
89 dump_node($root);
90 say $tmp "draw(n" . $root->{id} . ", (0, 0));";
91
92 close($tmp);
93 my $rep = "$tmp";
94 $rep =~ s/asy$/eps/;
95 if ($options{gv}) {
96 my $tmp_dir = dirname($rep);
97 $options{save} = File::Spec->rel2abs($options{save}) if $options{save};
98 chdir($tmp_dir);
99 } else {
100 $rep = basename($rep); # Output in current dir.
101 }
102 system("asy $tmp"); # Create the .eps file.
103 system("gv --scale=-1000 --noresize --widgetless $rep") if $options{gv};
104 if ($options{save}) {
105 system("mv $rep ${options{save}}");
106 } elsif ($options{gv}) {
107 system("rm $rep");
108 }
109 system("rm $tmp");
110
111 __END__
112
113 =head1 NAME
114
115 dump-asy.pl - Render the layout tree using asymptote
116
117 =head1 SYNOPSIS
118
119 dump-asy.pl [workspace]
120
121 =head1 EXAMPLE
122
123 Render the entire tree, run:
124
125 ./dump-asy.pl
126
127 Render the tree starting from the node with the specified name, run:
128
129 ./dump-asy.pl 'name'
130
131 Render the entire tree, save in file 'file.eps' and show using gv, run:
132
133 ./dump-asy.pl --save file.eps
134
135 =head1 OPTIONS
136
137 =over 8
138
139 =item B<--gv>
140
141 =item B<--no-gv>
142
143 Enable or disable showing the result through gv. If disabled, an .eps file will
144 be saved in the current working directory. Enabled by default.
145
146 =item B<--save>
147
148 Save result using the specified file-name. If omitted, no file will be saved
149 when using '--gv' or a random name will be used when using '--no-gv'.
150
151 =back
0 #!/usr/bin/env perl
1 # vim:ts=4:sw=4:expandtab
2 # renders the layout tree using asymptote
3
4 use strict;
5 use warnings;
6
7 use JSON::XS;
8 use Data::Dumper;
9 use AnyEvent::I3;
10 use v5.10;
11
12 use Gtk2 '-init';
13 use Gtk2::SimpleMenu;
14 use Glib qw/TRUE FALSE/;
15
16 my $window = Gtk2::Window->new('toplevel');
17 $window->signal_connect('delete_event' => sub { Gtk2->main_quit; });
18
19 my $tree_store = Gtk2::TreeStore->new(qw/Glib::String/, qw/Glib::String/, qw/Glib::String/, qw/Glib::String/, qw/Glib::String/, qw/Glib::String/, qw/Glib::String/, qw/Glib::String/);
20
21 my $i3 = i3();
22
23 my $tree_view = Gtk2::TreeView->new($tree_store);
24
25 my $layout_box = undef;
26
27 sub copy_node {
28 my ($n, $parent, $piter, $pbox) = @_;
29
30 my $o = ($n->{orientation} == 0 ? "u" : ($n->{orientation} == 1 ? "h" : "v"));
31 my $w = (defined($n->{window}) ? $n->{window} : "N");
32
33 # convert a rectangle struct to X11 notation (WxH+X+Y)
34 my $r = $n->{rect};
35 my $x = $r->{x};
36 my $y = $r->{y};
37 my $dim = $r->{width}."x".$r->{height}.($x<0?$x:"+$x").($y<0?$y:"+$y");
38
39 # add node to the tree with all known properties
40 my $iter = $tree_store->append($piter);
41 $tree_store->set($iter, 0 => $n->{name}, 1 => $w, 2 => $o, 3 => sprintf("0x%08x", $n->{id}), 4 => $n->{urgent}, 5 => $n->{focused}, 6 => $n->{layout}, 7 => $dim);
42
43 # also create a box for the node, each node has a vbox
44 # for combining the title (and properties) with the
45 # container itself, the container will be empty in case
46 # of no children, a vbox or hbox
47 my $box;
48 if($n->{orientation} == 1) {
49 $box = Gtk2::HBox->new(1, 5);
50 } else {
51 $box = Gtk2::VBox->new(1, 5);
52 }
53
54 # combine label and container
55 my $node = Gtk2::Frame->new($n->{name}.",".$o.",".$w);
56 $node->set_shadow_type('etched-out');
57 $node->add($box);
58
59 # the parent is added onto a scrolled window, so add it with a viewport
60 if(defined($pbox)) {
61 $pbox->pack_start($node, 1, 1, 0);
62 } else {
63 $layout_box = $node;
64 }
65
66 # recurse into children
67 copy_node($_, $n, $iter, $box) for @{$n->{nodes}};
68
69 # if it is a window draw a nice color
70 if(defined($n->{window})) {
71 # use a drawing area to fill a colored rectangle
72 my $area = Gtk2::DrawingArea->new();
73
74 # the color is stored as hex in the name
75 $area->{"user-data"} = $n->{name};
76
77 $area->signal_connect(expose_event => sub {
78 my ($widget, $event) = @_;
79
80 # fetch a cairo context and it width/height to start drawing nodes
81 my $cr = Gtk2::Gdk::Cairo::Context->create($widget->window());
82
83 my $w = $widget->allocation->width;
84 my $h = $widget->allocation->height;
85
86 my $hc = $widget->{"user-data"};
87 my $r = hex(substr($hc, 1, 2)) / 255.0;
88 my $g = hex(substr($hc, 3, 2)) / 255.0;
89 my $b = hex(substr($hc, 5, 2)) / 255.0;
90
91 $cr->set_source_rgb($r, $g, $b);
92 $cr->rectangle(0, 0, $w, $h);
93 $cr->fill();
94
95 return FALSE;
96 });
97
98 $box->pack_end($area, 1, 1, 0);
99 }
100 }
101
102 # Replaced by Gtk2 Boxes:
103 #sub draw_node {
104 # my ($n, $cr, $x, $y, $w, $h) = @_;
105 #
106 # $cr->set_source_rgb(1.0, 1.0, 1.0);
107 # $cr->rectangle($x, $y, $w/2, $h/2);
108 # $cr->fill();
109 #}
110
111 my $json_prev = "";
112
113 my $layout_sw = Gtk2::ScrolledWindow->new(undef, undef);
114 my $layout_container = Gtk2::HBox->new(0, 0);
115 $layout_sw->add_with_viewport($layout_container);
116
117 sub copy_tree {
118 my $tree = $i3->get_tree->recv;
119
120 # convert the tree back to json so we only rebuild/redraw when the tree is changed
121 my $json = encode_json($tree);
122 if ($json ne $json_prev) {
123 $json_prev = $json;
124
125 # rebuild the tree and the layout
126 $tree_store->clear();
127 if(defined($layout_box)) {
128 $layout_container->remove($layout_box);
129 }
130 copy_node($tree);
131 $layout_container->add($layout_box);
132 $layout_container->show_all();
133
134 # keep things expanded, otherwise the tree collapses every reload which is more annoying then this :-)
135 $tree_view->expand_all();
136 }
137
138 return(TRUE);
139 }
140
141 sub new_column {
142 my $tree_column = Gtk2::TreeViewColumn->new();
143 $tree_column->set_title(shift);
144
145 my $renderer = Gtk2::CellRendererText->new();
146 $tree_column->pack_start($renderer, FALSE);
147 $tree_column->add_attribute($renderer, text => shift);
148
149 return($tree_column);
150 }
151
152 my $col = 0;
153 $tree_view->append_column(new_column("Name", $col++));
154 $tree_view->append_column(new_column("Window", $col++));
155 $tree_view->append_column(new_column("Orientation", $col++));
156 $tree_view->append_column(new_column("ID", $col++));
157 $tree_view->append_column(new_column("Urgent", $col++));
158 $tree_view->append_column(new_column("Focused", $col++));
159 $tree_view->append_column(new_column("Layout", $col++));
160 $tree_view->append_column(new_column("Rect", $col++));
161
162 $tree_view->set_grid_lines("both");
163
164 my $tree_sw = Gtk2::ScrolledWindow->new(undef, undef);
165 $tree_sw->add($tree_view);
166
167 # Replaced by Gtk2 Boxes:
168 #my $area = Gtk2::DrawingArea->new();
169 #$area->signal_connect(expose_event => sub {
170 # my ($widget, $event) = @_;
171 #
172 # # fetch a cairo context and it width/height to start drawing nodes
173 # my $cr = Gtk2::Gdk::Cairo::Context->create($widget->window());
174 #
175 # my $w = $widget->allocation->width;
176 # my $h = $widget->allocation->height;
177 #
178 # draw_node($gtree, $cr, 0, 0, $w, $h);
179 #
180 # return FALSE;
181 #});
182
183 sub menu_export {
184 print("TODO: EXPORT\n");
185 }
186
187 my $menu_tree = [
188 _File => {
189 item_type => '<Branch>',
190 children => [
191 _Export => {
192 callback => \&menu_export,
193 accelerator => '<ctrl>E',
194 },
195 _Quit => {
196 callback => sub { Gtk2->main_quit; },
197 accelerator => '<ctrl>Q',
198 },
199 ],
200 },
201 ];
202
203 my $menu = Gtk2::SimpleMenu->new(menu_tree => $menu_tree);
204
205 my $vbox = Gtk2::VBox->new(0, 0);
206 $vbox->pack_start($menu->{widget}, 0, 0, 0);
207 $vbox->pack_end($tree_sw, 1, 1, 0);
208 $vbox->pack_end($layout_sw, 1, 1, 0);
209
210 $window->add($vbox);
211 $window->show_all();
212 $window->set_size_request(500,500);
213
214 Glib::Timeout->add(1000, "copy_tree", undef, Glib::G_PRIORITY_DEFAULT);
215 copy_tree();
216
217 Gtk2->main();
218
0 #!/usr/bin/env perl
1 # vim:ts=4:sw=4:expandtab:ft=perl
2 # © 2010 Michael Stapelberg, see LICENSE for license information
3
4 use strict;
5 use warnings;
6 use Getopt::Long;
7 use Pod::Usage;
8 use IPC::Run qw(start pump);
9 use Try::Tiny;
10 use AnyEvent::I3;
11 use AnyEvent;
12 use v5.10;
13
14 my $stdin;
15 my $socket_path = undef;
16 my ($workspaces, $outputs) = ([], {});
17 my $last_line = "";
18 my $w = AnyEvent->timer(
19 after => 2,
20 cb => sub {
21 say "Connection to i3 timed out. Verify socket path ($socket_path)";
22 exit 1;
23 }
24 );
25
26 my $command = "";
27 my $input_on = "";
28 my $output_on = "";
29 my $show_all = 0;
30
31 my $result = GetOptions(
32 'command=s' => \$command,
33 'socket=s' => \$socket_path,
34 'input-on=s' => \$input_on,
35 'output-on=s' => \$output_on,
36 'show-all' => \$show_all,
37 'help' => sub { pod2usage(1); exit 0 },
38 );
39
40 if ($command eq '') {
41 say "i3-wsbar is only useful in combination with dzen2.";
42 say "Please specify -c (command)";
43 exit 1;
44 }
45
46 my $i3 = i3($socket_path);
47
48 my @input_on = split(/,/, $input_on);
49 my @output_on = split(/,/, $output_on);
50
51 # Disable buffering
52 $| = 1;
53
54 # Wait a short amount of time and try to connect to i3 again
55 sub reconnect {
56 my $timer;
57 if (!defined($w)) {
58 $w = AnyEvent->timer(
59 after => 2,
60 cb => sub {
61 say "Connection to i3 timed out. Verify socket path ($socket_path)";
62 exit 1;
63 }
64 );
65 }
66
67 my $c = sub {
68 $timer = AnyEvent->timer(
69 after => 0.01,
70 cb => sub { $i3->connect->cb(\&connected) }
71 );
72 };
73 $c->();
74 }
75
76 # Connection attempt succeeded or failed
77 sub connected {
78 my ($cv) = @_;
79
80 if (!$cv->recv) {
81 reconnect();
82 return;
83 }
84
85 $w = undef;
86
87 $i3->subscribe({
88 workspace => \&ws_change,
89 output => \&output_change,
90 _error => sub { reconnect() }
91 });
92 ws_change();
93 output_change();
94 }
95
96 # Called when a ws changes
97 sub ws_change {
98 # Request the current workspaces and update the output afterwards
99 $i3->get_workspaces->cb(
100 sub {
101 my ($cv) = @_;
102 $workspaces = $cv->recv;
103 update_output();
104 });
105 }
106
107 # Called when the reply to the GET_OUTPUTS message arrives
108 # Compares old outputs with new outputs and starts/kills
109 # $command for each output (if specified)
110 sub got_outputs {
111 my $reply = shift->recv;
112 my %old = %{$outputs};
113 my %new = map { ($_->{name}, $_) } grep { $_->{active} } @{$reply};
114
115 # If no command was given, we do not need to compare outputs
116 if ($command eq '') {
117 update_output();
118 return;
119 }
120
121 # Handle new outputs
122 for my $name (keys %new) {
123 next if @output_on and !($name ~~ @output_on);
124
125 if (defined($old{$name})) {
126 # Check if the mode changed (by reversing the hashes so
127 # that we can check for equality using the smartmatch op)
128 my %oldrect = reverse %{$old{$name}->{rect}};
129 my %newrect = reverse %{$new{$name}->{rect}};
130 next if (%oldrect ~~ %newrect);
131
132 # On mode changes, we re-start the command
133 $outputs->{$name}->{cmd}->finish;
134 delete $outputs->{$name};
135 }
136
137 my $x = $new{$name}->{rect}->{x};
138 my $w = $new{$name}->{rect}->{width};
139 my $launch = $command;
140 $launch =~ s/([^%])%x/$1$x/g;
141 $launch =~ s/([^%])%w/$1$w/g;
142 $launch =~ s/%%x/%x/g;
143 $launch =~ s/%%w/%w/g;
144
145 $new{$name}->{cmd_input} = '';
146 my @cmd = ('/bin/sh', '-c', $launch);
147 $new{$name}->{cmd} = start \@cmd, \$new{$name}->{cmd_input};
148 $outputs->{$name} = $new{$name};
149 }
150
151 # Handle old outputs
152 for my $name (keys %old) {
153 next if defined($new{$name});
154
155 $outputs->{$name}->{cmd}->finish;
156 delete $outputs->{$name};
157 }
158
159 update_output();
160 }
161
162 sub output_change {
163 $i3->get_outputs->cb(\&got_outputs)
164 }
165
166 sub update_output {
167 my $dzen_bg = "#111111";
168 my $out;
169 my $previous_output;
170
171 for my $name (keys %{$outputs}) {
172 my $width = $outputs->{$name}->{rect}->{width};
173
174 $previous_output = undef;
175 $out = qq|^pa(;2)|;
176 for my $ws (@{$workspaces}) {
177 next if $ws->{output} ne $name and !$show_all;
178
179 # Display a separator if we are on a different output now
180 if (defined($previous_output) and
181 ($ws->{output} ne $previous_output)) {
182 $out .= qq|^fg(#900000)^ib(1)\|^ib(0)^p(+4)|;
183 }
184 $previous_output = $ws->{output};
185
186 my ($bg, $fg) = qw(333333 888888);
187 ($bg, $fg) = qw(4c7899 ffffff) if $ws->{visible};
188 ($bg, $fg) = qw(900000 ffffff) if $ws->{urgent};
189
190 my $cmd = q|i3-msg "workspace | . $ws->{name} . q|"|;
191 my $name = $ws->{name};
192
193 # Begin the clickable area
194 $out .= qq|^ca(1,$cmd)|;
195
196 # Draw the rest of the bar in the background color, but
197 # don’t move the "cursor"
198 $out .= qq|^p(_LOCK_X)^fg(#$bg)^r(${width}x17)^p(_UNLOCK_X)|;
199 # Draw the name of the workspace without overwriting the
200 # background color
201 $out .= qq|^p(+3)^fg(#$fg)^ib(1)$name^ib(0)^p(+5)|;
202 # Draw the rest of the bar in the normal background color
203 # without moving the "cursor"
204 $out .= qq|^p(_LOCK_X)^fg($dzen_bg)^r(${width}x17)^p(_UNLOCK_X)|;
205
206 # End the clickable area
207 $out .= qq|^ca()|;
208
209 # Move to the next rect, reset Y coordinate
210 $out .= qq|^p(2)^pa(;2)|;
211 }
212
213 $out .= qq|^p(_LOCK_X)^fg($dzen_bg)^r(${width}x17)^p(_UNLOCK_X)^fg()|;
214 $out .= qq|^p(+5)|;
215 $out .= $last_line if (!@input_on or $name ~~ @input_on);
216 $out .= "\n";
217
218 $outputs->{$name}->{cmd_input} = $out;
219 try {
220 pump $outputs->{$name}->{cmd} while length $outputs->{$name}->{cmd_input};
221 } catch {
222 warn "Could not write to dzen2";
223 exit 1;
224 }
225 }
226 }
227
228 $i3->connect->cb(\&connected);
229
230 $stdin = AnyEvent->io(
231 fh => \*STDIN,
232 poll => 'r',
233 cb => sub {
234 my $line = <STDIN>;
235 if (!defined($line)) {
236 undef $stdin;
237 return;
238 }
239 chomp($line);
240 $last_line = $line;
241 update_output();
242 });
243
244 # let AnyEvent do the rest ("endless loop")
245 AnyEvent->condvar->recv
246
247 __END__
248
249 =head1 NAME
250
251 i3-wsbar - sample implementation of a standalone workspace bar
252
253 =head1 SYNOPSIS
254
255 i3-wsbar -c <dzen2-commandline> [options]
256
257 =head1 OPTIONS
258
259 =over 4
260
261 =item B<--command> <command>
262
263 This command (at the moment only dzen2 is supported) will be started for each
264 output. C<%x> will be replaced with the X coordinate of the output, C<%w> will
265 be replaced with the width of the output.
266
267 Example:
268 --command "dzen2 -dock -x %x -w %w"
269
270 =item B<--input-on> <list-of-RandR-outputs>
271
272 Specifies on which outputs the contents of stdin should be appended to the
273 workspace bar.
274
275 Example:
276 --input-on "LVDS1"
277
278 =item B<--output-on> <list-of-RandR-outputs>
279
280 Specifies for which outputs i3-wsbar should start C<command>.
281
282 =item B<--show-all>
283
284 If enabled, all workspaces are shown (not only those of the current output).
285 Handy to use with C<--output-on>.
286
287 =back
288
289 =cut
0 #!/usr/bin/env perl
1 # vim:ts=4:sw=4:expandtab
2 # © 2012 Michael Stapelberg
3 # Licensed under BSD license, see https://github.com/i3/i3/blob/next/LICENSE
4 #
5 # Append this line to your i3 config file:
6 # exec_always ~/per-workspace-layout.pl
7 #
8 # Then, change the %layouts hash like you want your workspaces to be set up.
9 # This script requires i3 >= v4.4 for the extended workspace event.
10
11 use strict;
12 use warnings;
13 use AnyEvent;
14 use AnyEvent::I3;
15 use v5.10;
16 use utf8;
17
18 my %layouts = (
19 '4' => 'tabbed',
20 '5' => 'stacked',
21 );
22
23 my $i3 = i3();
24
25 die "Could not connect to i3: $!" unless $i3->connect->recv();
26
27 die "Could not subscribe to the workspace event: $!" unless
28 $i3->subscribe({
29 workspace => sub {
30 my ($msg) = @_;
31 return unless $msg->{change} eq 'focus';
32 die "Your version of i3 is too old. You need >= v4.4"
33 unless exists($msg->{current});
34 my $ws = $msg->{current};
35
36 # If the workspace already has children, don’t change the layout.
37 return unless scalar @{$ws->{nodes}} == 0;
38
39 my $name = $ws->{name};
40 my $con_id = $ws->{id};
41
42 return unless exists $layouts{$name};
43
44 $i3->command(qq|[con_id="$con_id"] layout | . $layouts{$name});
45 },
46 _error => sub {
47 my ($msg) = @_;
48 say "AnyEvent::I3 error: $msg";
49 say "Exiting.";
50 exit 1;
51 },
52 })->recv->{success};
53
54 # Run forever.
55 AnyEvent->condvar->recv
0 #!/bin/sh
1 # © 2012 Han Boetes <[email protected]> (see also: LICENSE)
2
3 YEAR=`date "+%Y"`
4 weblog=$(mktemp)
5 zcat $(find /var/log/lighttpd/build.i3wm.org -type f -name "access.log.*.gz" | sort | tail -5) > $weblog
6 # this will match the latest logfile, which is not yet gzipped
7 find /var/log/lighttpd/build.i3wm.org/log$YEAR -type f \! -name "access.log.*.gz" -exec cat '{}' \; >> $weblog
8 cat /var/log/lighttpd/build.i3wm.org/access.log >> $weblog
9 gitlog=$(mktemp)
10
11 # create a git output logfile. Only keep the first 6 chars of the release hash
12 git log -150 --pretty=' %h %s' next > $gitlog
13
14 awk '/i3-wm_.*\.deb/ {print $7}' $weblog|awk -F'/' '{print $NF}'|awk -F'_' '{print $2 }'|awk -F'-' '{print $NF}' |cut -c 2-8|sort |uniq -c | while read line; do
15 set -- $line
16 # $1 is the number of downloads, $2 is the release md5sum
17 sed -i "/$2/s|^ |$(printf '%3i' $1) d/l |" $gitlog
18 done
19
20 cat $gitlog
21 rm $gitlog
22 rm $weblog
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="269.29132"
13 height="187.79527"
14 id="svg2"
15 sodipodi:version="0.32"
16 inkscape:version="0.48.1 r9760"
17 sodipodi:docname="sticker_stickma_black.svg"
18 inkscape:output_extension="org.inkscape.output.svg.inkscape"
19 version="1.1"
20 inkscape:export-filename="/home/michael/i3/sticker.png"
21 inkscape:export-xdpi="116.12904"
22 inkscape:export-ydpi="116.12904">
23 <defs
24 id="defs4">
25 <linearGradient
26 id="linearGradient3750">
27 <stop
28 style="stop-color:#17273b;stop-opacity:1;"
29 offset="0"
30 id="stop3752" />
31 <stop
32 id="stop4356"
33 offset="0.41666666"
34 style="stop-color:#008cd4;stop-opacity:0.78039217;" />
35 <stop
36 style="stop-color:#6eb5de;stop-opacity:0.69803923;"
37 offset="0.87847221"
38 id="stop4358" />
39 <stop
40 style="stop-color:#88bfe5;stop-opacity:0.61960787;"
41 offset="1"
42 id="stop3754" />
43 </linearGradient>
44 <inkscape:perspective
45 id="perspective3661"
46 inkscape:persp3d-origin="750.50629 : 505.26732 : 1"
47 inkscape:vp_z="683.5728 : 1230.5721 : 1"
48 inkscape:vp_y="0 : 1946.8917 : 0"
49 inkscape:vp_x="-526.84957 : 2.2065866e-13 : 0"
50 sodipodi:type="inkscape:persp3d" />
51 <linearGradient
52 id="linearGradient3284">
53 <stop
54 style="stop-color:#ffffff;stop-opacity:1;"
55 offset="0"
56 id="stop3286" />
57 <stop
58 style="stop-color:#ffffff;stop-opacity:0.7518248;"
59 offset="1"
60 id="stop3288" />
61 </linearGradient>
62 <linearGradient
63 id="linearGradient3278">
64 <stop
65 id="stop3280"
66 offset="0"
67 style="stop-color:#33bff7;stop-opacity:0.38039216;" />
68 <stop
69 id="stop3282"
70 offset="1"
71 style="stop-color:#2d446b;stop-opacity:1;" />
72 </linearGradient>
73 <linearGradient
74 id="linearGradient3272">
75 <stop
76 id="stop3274"
77 offset="0"
78 style="stop-color:#2596f6;stop-opacity:0.38039216;" />
79 <stop
80 id="stop3276"
81 offset="1"
82 style="stop-color:#2d446b;stop-opacity:1;" />
83 </linearGradient>
84 <linearGradient
85 id="linearGradient3266">
86 <stop
87 id="stop3268"
88 offset="0"
89 style="stop-color:#189fff;stop-opacity:0.38039216;" />
90 <stop
91 id="stop3270"
92 offset="1"
93 style="stop-color:#010b2b;stop-opacity:1;" />
94 </linearGradient>
95 <linearGradient
96 id="linearGradient3244">
97 <stop
98 id="stop3246"
99 offset="0"
100 style="stop-color:#419bff;stop-opacity:1;" />
101 <stop
102 id="stop3248"
103 offset="1"
104 style="stop-color:#002359;stop-opacity:1;" />
105 </linearGradient>
106 <linearGradient
107 id="linearGradient3159">
108 <stop
109 style="stop-color:#33bff7;stop-opacity:0.38039216;"
110 offset="0"
111 id="stop3161" />
112 <stop
113 style="stop-color:#2d446b;stop-opacity:1;"
114 offset="1"
115 id="stop3163" />
116 </linearGradient>
117 <inkscape:perspective
118 sodipodi:type="inkscape:persp3d"
119 inkscape:vp_x="-526.84957 : 2.9848654e-13 : 0"
120 inkscape:vp_y="1.192088e-13 : 1946.8917 : 0"
121 inkscape:vp_z="680.54236 : 1232.3792 : 1"
122 inkscape:persp3d-origin="730.30325 : 937.39936 : 1"
123 id="perspective10" />
124 <radialGradient
125 inkscape:collect="always"
126 xlink:href="#linearGradient3244"
127 id="radialGradient3256"
128 cx="344.73471"
129 cy="77.263504"
130 fx="344.73471"
131 fy="77.263504"
132 r="196.15704"
133 gradientTransform="matrix(-1.39796,-0.05336032,0.08355111,-2.1889079,820.20461,272.08319)"
134 gradientUnits="userSpaceOnUse" />
135 <radialGradient
136 inkscape:collect="always"
137 xlink:href="#linearGradient3159"
138 id="radialGradient3264"
139 cx="140.3363"
140 cy="300.27451"
141 fx="140.3363"
142 fy="300.27451"
143 r="206.15704"
144 gradientTransform="matrix(0.6771172,-0.6830119,1.1802789,1.1700925,-161.83993,77.639162)"
145 gradientUnits="userSpaceOnUse" />
146 <radialGradient
147 inkscape:collect="always"
148 xlink:href="#linearGradient3284"
149 id="radialGradient3290"
150 cx="267.50388"
151 cy="337.12692"
152 fx="267.50388"
153 fy="337.12692"
154 r="77.845421"
155 gradientTransform="matrix(1,0,0,0.7430849,0,86.613009)"
156 gradientUnits="userSpaceOnUse" />
157 <inkscape:perspective
158 id="perspective3373"
159 inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
160 inkscape:vp_z="744.09448 : 526.18109 : 1"
161 inkscape:vp_y="0 : 1000 : 0"
162 inkscape:vp_x="0 : 526.18109 : 1"
163 sodipodi:type="inkscape:persp3d" />
164 <linearGradient
165 id="linearGradient3211">
166 <stop
167 id="stop3213"
168 offset="0"
169 style="stop-color: rgb(0, 160, 255); stop-opacity: 1;" />
170 <stop
171 id="stop3215"
172 offset="1"
173 style="stop-color: rgb(0, 37, 255); stop-opacity: 1;" />
174 </linearGradient>
175 <filter
176 inkscape:collect="always"
177 id="filter3406"
178 color-interpolation-filters="sRGB">
179 <feGaussianBlur
180 inkscape:collect="always"
181 stdDeviation="13.396228"
182 id="feGaussianBlur3408" />
183 </filter>
184 <radialGradient
185 inkscape:collect="always"
186 xlink:href="#linearGradient3284"
187 id="radialGradient3416"
188 cx="119.96373"
189 cy="229.28981"
190 fx="119.96373"
191 fy="229.28981"
192 r="203.19508"
193 gradientTransform="matrix(0.7210805,2.1168143,-1.4722239,0.5015047,347.53034,-320.94088)"
194 gradientUnits="userSpaceOnUse" />
195 <radialGradient
196 inkscape:collect="always"
197 xlink:href="#linearGradient3284"
198 id="radialGradient3734"
199 gradientUnits="userSpaceOnUse"
200 gradientTransform="matrix(0.7210805,2.1168143,-1.4722239,0.5015047,347.53034,-320.94088)"
201 cx="119.96373"
202 cy="229.28981"
203 fx="119.96373"
204 fy="229.28981"
205 r="203.19508" />
206 <radialGradient
207 inkscape:collect="always"
208 xlink:href="#linearGradient3284"
209 id="radialGradient3736"
210 gradientUnits="userSpaceOnUse"
211 gradientTransform="matrix(0.7210805,2.1168143,-1.4722239,0.5015047,347.53034,-320.94088)"
212 cx="119.96373"
213 cy="229.28981"
214 fx="119.96373"
215 fy="229.28981"
216 r="203.19508" />
217 <radialGradient
218 inkscape:collect="always"
219 xlink:href="#linearGradient3750"
220 id="radialGradient3758"
221 cx="390.69662"
222 cy="258.92429"
223 fx="390.69662"
224 fy="258.92429"
225 r="32.03125"
226 gradientTransform="matrix(4.0292425,-5.5974184,5.1695404,3.721239,-2510.9809,1613.1551)"
227 gradientUnits="userSpaceOnUse" />
228 <radialGradient
229 inkscape:collect="always"
230 xlink:href="#linearGradient3750"
231 id="radialGradient3760"
232 cx="59.046589"
233 cy="248.2272"
234 fx="59.046589"
235 fy="248.2272"
236 r="197.15625"
237 gradientTransform="matrix(1.7105919,-0.04370519,0.03334715,1.3051856,-58.593126,-250.18318)"
238 gradientUnits="userSpaceOnUse" />
239 <radialGradient
240 inkscape:collect="always"
241 xlink:href="#linearGradient3750"
242 id="radialGradient3762"
243 cx="192.64008"
244 cy="282.40387"
245 fx="192.64008"
246 fy="282.40387"
247 r="133.09375"
248 gradientTransform="matrix(1.0081228,0.4493093,-1.0529321,2.3624813,273.13721,-455.12138)"
249 gradientUnits="userSpaceOnUse" />
250 <radialGradient
251 inkscape:collect="always"
252 xlink:href="#linearGradient3750"
253 id="radialGradient4344"
254 gradientUnits="userSpaceOnUse"
255 gradientTransform="matrix(5.7478532,-0.5889281,0.4834745,4.7186431,-260.98332,-919.446)"
256 cx="24"
257 cy="280.45392"
258 fx="24"
259 fy="280.45392"
260 r="65.0625" />
261 <linearGradient
262 inkscape:collect="always"
263 xlink:href="#linearGradient3750"
264 id="linearGradient4354"
265 x1="-125.59599"
266 y1="-100.47679"
267 x2="-5.2882538"
268 y2="-100.47679"
269 gradientUnits="userSpaceOnUse" />
270 <radialGradient
271 inkscape:collect="always"
272 xlink:href="#linearGradient3266"
273 id="radialGradient3721"
274 gradientUnits="userSpaceOnUse"
275 gradientTransform="matrix(1.1454302,-1.1687051,2.0295327,1.9193266,-924.0626,56.219022)"
276 cx="351.15485"
277 cy="372.06332"
278 fx="351.15485"
279 fy="372.06332"
280 r="163.57143" />
281 <radialGradient
282 inkscape:collect="always"
283 xlink:href="#linearGradient3266"
284 id="radialGradient3303"
285 gradientUnits="userSpaceOnUse"
286 gradientTransform="matrix(0.54985655,-0.5425676,0.97426436,0.89104123,-423.22152,225.74786)"
287 cx="351.15485"
288 cy="372.06332"
289 fx="351.15485"
290 fy="372.06332"
291 r="163.57143" />
292 </defs>
293 <sodipodi:namedview
294 id="base"
295 pagecolor="#ffffff"
296 bordercolor="#666666"
297 borderopacity="1.0"
298 inkscape:pageopacity="0.0"
299 inkscape:pageshadow="2"
300 inkscape:zoom="2.632258"
301 inkscape:cx="136.32251"
302 inkscape:cy="106.81637"
303 inkscape:document-units="px"
304 inkscape:current-layer="layer3"
305 showgrid="false"
306 inkscape:window-width="1208"
307 inkscape:window-height="1089"
308 inkscape:window-x="2308"
309 inkscape:window-y="90"
310 inkscape:window-maximized="0"
311 units="mm" />
312 <metadata
313 id="metadata7">
314 <rdf:RDF>
315 <cc:Work
316 rdf:about="">
317 <dc:format>image/svg+xml</dc:format>
318 <dc:type
319 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
320 <dc:title></dc:title>
321 <dc:contributor>
322 <cc:Agent>
323 <dc:title>yellowiscool, farvardin</dc:title>
324 </cc:Agent>
325 </dc:contributor>
326 <dc:creator>
327 <cc:Agent>
328 <dc:title>steckdenis</dc:title>
329 </cc:Agent>
330 </dc:creator>
331 <dc:description>Logo for I3, an improved dynamic tiling window manager: http://i3.zekjur.net/</dc:description>
332 <cc:license
333 rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
334 </cc:Work>
335 <cc:License
336 rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
337 <cc:permits
338 rdf:resource="http://creativecommons.org/ns#Reproduction" />
339 <cc:permits
340 rdf:resource="http://creativecommons.org/ns#Distribution" />
341 <cc:requires
342 rdf:resource="http://creativecommons.org/ns#Notice" />
343 <cc:requires
344 rdf:resource="http://creativecommons.org/ns#Attribution" />
345 <cc:permits
346 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
347 <cc:requires
348 rdf:resource="http://creativecommons.org/ns#ShareAlike" />
349 </cc:License>
350 </rdf:RDF>
351 </metadata>
352 <g
353 inkscape:groupmode="layer"
354 id="layer4"
355 inkscape:label="fond"
356 style="display:none"
357 transform="translate(-7.8571396,-226.42406)">
358 <rect
359 style="opacity:0.87000002;fill:#5599ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:60;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
360 id="rect3241"
361 width="330"
362 height="313.5"
363 x="39"
364 y="103.86218" />
365 </g>
366 <g
367 inkscape:label="Calque 1"
368 inkscape:groupmode="layer"
369 id="layer1"
370 style="display:inline"
371 transform="translate(-7.8571396,-226.42406)" />
372 <g
373 inkscape:groupmode="layer"
374 id="layer2"
375 inkscape:label="tiling"
376 style="display:none"
377 transform="translate(-7.8571396,-226.42406)">
378 <rect
379 y="106.6479"
380 x="42.85714"
381 height="308.57144"
382 width="322.85715"
383 id="rect3247"
384 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
385 <rect
386 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
387 id="rect3253"
388 width="212.07706"
389 height="98.216858"
390 x="42.85096"
391 y="218.0385" />
392 <rect
393 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
394 id="rect3257"
395 width="110.75323"
396 height="70.943619"
397 x="254.94135"
398 y="274.26196" />
399 <rect
400 y="218.02481"
401 x="254.93958"
402 height="56.235466"
403 width="110.76914"
404 id="rect3259"
405 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
406 <rect
407 y="345.25272"
408 x="254.91608"
409 height="69.955116"
410 width="110.78036"
411 id="rect3255"
412 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
413 <rect
414 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
415 id="rect3249"
416 width="106.87583"
417 height="111.69163"
418 x="42.849949"
419 y="106.32091" />
420 <rect
421 y="106.45182"
422 x="149.72185"
423 height="111.57816"
424 width="105.18911"
425 id="rect3261"
426 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
427 <rect
428 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
429 id="rect3263"
430 width="110.786"
431 height="111.57211"
432 x="254.91632"
433 y="106.45485" />
434 <rect
435 y="316.22876"
436 x="42.847878"
437 height="98.979958"
438 width="212.0791"
439 id="rect3251"
440 style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" />
441 </g>
442 <g
443 inkscape:groupmode="layer"
444 id="layer5"
445 inkscape:label="tiling2"
446 style="display:inline"
447 transform="translate(-7.8571396,-226.42406)" />
448 <g
449 inkscape:groupmode="layer"
450 id="layer3"
451 inkscape:label="I3"
452 style="display:inline"
453 transform="translate(-7.8571396,-226.42406)">
454 <rect
455 style="fill:#000000;fill-opacity:1;stroke:none"
456 id="rect4331"
457 width="300.32974"
458 height="228.87383"
459 x="-15.04335"
460 y="-28.721518"
461 transform="translate(7.8571396,226.42406)" />
462 <text
463 xml:space="preserve"
464 style="font-size:11.90824985999999974px;font-style:normal;font-weight:normal;fill:#0b5bb4;fill-opacity:1;stroke:none;display:inline;font-family:Bitstream Vera Sans"
465 x="191.96429"
466 y="287.08801"
467 id="text2939"
468 transform="scale(1.0168712,0.98340872)"><tspan
469 sodipodi:role="line"
470 x="191.96429"
471 y="287.08801"
472 style="font-size:48px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;fill:#0b5bb4;fill-opacity:1;font-family:Georgia;-inkscape-font-specification:Georgia Bold"
473 id="tspan2951">i3</tspan></text>
474 <text
475 xml:space="preserve"
476 style="font-size:11.90824985999999974px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;display:inline;font-family:Bitstream Vera Sans"
477 x="212.13477"
478 y="327.17087"
479 id="text2943"
480 transform="scale(1.0168712,0.98340872)"><tspan
481 sodipodi:role="line"
482 id="tspan2945"
483 x="212.13477"
484 y="327.17087"
485 style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;font-family:Georgia;-inkscape-font-specification:Georgia;fill:#ffffff;fill-opacity:1">improved</tspan><tspan
486 sodipodi:role="line"
487 x="212.13477"
488 y="349.67087"
489 style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;text-anchor:middle;font-family:Georgia;-inkscape-font-specification:Georgia;fill:#ffffff;fill-opacity:1"
490 id="tspan3835">tiling wm</tspan></text>
491 <rect
492 style="fill:#ffffff;fill-opacity:1;stroke:none"
493 id="rect4329"
494 width="145.562"
495 height="134.577"
496 x="23.920139"
497 y="253.03334" />
498 <g
499 id="g3837"
500 transform="matrix(0.93634729,0,0,0.93634729,1.5366196,20.389339)">
501 <rect
502 y="248.69504"
503 x="24.140676"
504 height="143.2533"
505 width="154.98553"
506 id="rect2383"
507 style="fill:url(#radialGradient3303);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
508 <path
509 id="path3221"
510 d="m 24.548726,248.69894 c -0.923802,1.94771 -0.141016,4.60164 -0.382144,6.83186 0.104234,22.28427 0.208466,44.56854 0.312698,66.85282 5.686139,4.86076 13.886347,4.12262 20.925306,5.06603 25.678942,1.59846 51.500522,1.6763 77.097934,-1.13701 16.33402,-1.59469 32.66831,-4.05353 48.43162,-8.54811 4.01303,-1.30316 9.05404,-4.28177 8.19421,-8.97949 0,-20.02869 0,-40.0574 0,-60.0861 -51.52654,0 -103.053082,0 -154.579624,0 z"
511 style="opacity:0.09583333;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
512 inkscape:connector-curvature="0" />
513 <g
514 id="g3394"
515 style="opacity:0.5;fill:#000000;fill-opacity:1;display:inline;filter:url(#filter3406)"
516 transform="matrix(0.16261542,-0.15792135,0.16329493,0.15726421,31.999803,328.00895)">
517 <path
518 id="path3396"
519 d="M 412.75,98.59375 C 396.19379,98.835333 382.96319,112.44354 383.1875,129 c 0,0 -10e-6,87.25107 0,196.3125 0,23.30736 -12.11655,39.13192 -38.21875,53.46875 -26.1022,14.33683 -64.97276,22.875 -103.875,22.875 -38.90224,0 -77.7728,-8.53817 -103.875,-22.875 C 111.11655,364.44442 99,348.61986 99,325.3125 c 0,-54.37333 0.441249,-103.35555 0.65625,-138.875 0.1075,-17.75973 0.177008,-32.11577 0.09375,-42.34375 -0.04163,-5.11399 -0.129499,-9.10767 -0.28125,-12.46875 -0.07588,-1.68054 -0.136902,-3.05581 -0.40625,-5.25 -0.134674,-1.09709 -0.168072,-2.2122 -1,-5.1875 C 97.646536,119.69985 97.275733,117.79087 94.875,113.75 92.474267,109.70913 84.912085,98.999943 69,99 59.653467,98.879464 50.78473,103.12192 45.013008,110.47443 39.241286,117.82694 37.226064,127.44941 39.5625,136.5 c 0.06318,2.03091 0.15684,4.32729 0.1875,8.09375 0.07765,9.5394 0.0133,23.81477 -0.09375,41.5 C 39.442151,221.46421 39,270.62442 39,325.3125 c -10e-7,47.58256 30.913445,84.95437 69.34375,106.0625 38.43031,21.10813 85.6089,30.28125 132.75,30.28125 47.1411,0 94.31969,-9.17312 132.75,-30.28125 38.43031,-21.10813 69.34375,-58.47994 69.34375,-106.0625 -10e-6,-109.06142 0,-196.3125 0,-196.3125 0.10978,-8.10283 -3.06279,-15.9055 -8.79582,-21.63265 -5.73304,-5.72715 -13.53896,-8.891699 -21.64168,-8.7736 l 0,0 z"
520 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
521 inkscape:connector-curvature="0" />
522 <path
523 id="path3398"
524 d="M 239.5625,99.5 C 223.00629,99.741583 209.77569,113.34979 210,129.90625 L 210,350 c -0.15301,10.81908 5.53126,20.88244 14.87619,26.33663 9.34492,5.45419 20.9027,5.45419 30.24762,0 C 264.46874,370.88244 270.15301,360.81908 270,350 l 0,-220.09375 c 0.10978,-8.10283 -3.06279,-15.9055 -8.79582,-21.63265 -5.73304,-5.72715 -13.53896,-8.891699 -21.64168,-8.7736 l 0,0 z"
525 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none"
526 inkscape:connector-curvature="0" />
527 <path
528 transform="translate(0,-10)"
529 d="M 100,40 C 100,56.568542 86.568542,70 70,70 53.431458,70 40,56.568542 40,40 40,23.431458 53.431458,10 70,10 c 16.568542,0 30,13.431458 30,30 z"
530 sodipodi:ry="30"
531 sodipodi:rx="30"
532 sodipodi:cy="40"
533 sodipodi:cx="70"
534 id="path3400"
535 style="fill:#000000;fill-opacity:1;stroke-width:60;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
536 sodipodi:type="arc" />
537 <path
538 sodipodi:type="arc"
539 style="fill:#000000;fill-opacity:1;stroke-width:60;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
540 id="path3402"
541 sodipodi:cx="70"
542 sodipodi:cy="40"
543 sodipodi:rx="30"
544 sodipodi:ry="30"
545 d="M 100,40 C 100,56.568542 86.568542,70 70,70 53.431458,70 40,56.568542 40,40 40,23.431458 53.431458,10 70,10 c 16.568542,0 30,13.431458 30,30 z"
546 transform="translate(170,-10)" />
547 <path
548 transform="translate(345,-10)"
549 d="M 100,40 C 100,56.568542 86.568542,70 70,70 53.431458,70 40,56.568542 40,40 40,23.431458 53.431458,10 70,10 c 16.568542,0 30,13.431458 30,30 z"
550 sodipodi:ry="30"
551 sodipodi:rx="30"
552 sodipodi:cy="40"
553 sodipodi:cx="70"
554 id="path3404"
555 style="fill:#000000;fill-opacity:1;stroke-width:60;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
556 sodipodi:type="arc" />
557 </g>
558 <rect
559 style="fill:none;stroke:#000000;stroke-width:0.47207919;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
560 id="rect3244"
561 width="154.98553"
562 height="143.2533"
563 x="24.140676"
564 y="248.69504" />
565 <rect
566 y="248.69504"
567 x="24.140676"
568 height="143.2533"
569 width="154.98553"
570 id="rect3246"
571 style="fill:none;stroke:#000000;stroke-width:0.47207919;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline" />
572 <path
573 sodipodi:nodetypes="ccc"
574 id="path2929"
575 d="m 91.346794,248.69506 0,143.2533 0,-143.2533 z"
576 style="fill:none;stroke:#000000;stroke-width:0.47207919;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;display:inline"
577 inkscape:connector-curvature="0" />
578 <path
579 style="fill:none;stroke:#000000;stroke-width:0.47207919;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
580 d="m 91.135721,295.48452 -66.783968,0 66.783968,0 z"
581 id="path3254"
582 sodipodi:nodetypes="ccc"
583 inkscape:connector-curvature="0" />
584 <path
585 sodipodi:nodetypes="ccc"
586 id="path3256"
587 d="m 91.135721,344.69467 -66.783968,0 66.783968,0 z"
588 style="fill:none;stroke:#000000;stroke-width:0.47207919;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
589 inkscape:connector-curvature="0" />
590 <path
591 id="path2405"
592 d="m 115.21918,278.33218 c -2.65284,2.65258 -2.58219,6.88205 0.15787,9.45037 0,0 14.24765,13.72146 32.05684,30.87293 3.80597,3.6654 4.4197,8.0675 2.51621,14.44427 -1.90349,6.37677 -6.8302,13.85801 -13.15631,20.0015 -6.3261,6.1435 -14.04129,10.93924 -20.62704,12.80667 -6.58576,1.86742 -11.14017,1.29224 -14.94614,-2.37317 -8.87889,-8.55098 -16.805682,-16.32381 -22.570867,-21.9437 -2.882591,-2.80994 -5.215552,-5.07861 -6.899273,-6.67397 -0.841858,-0.79767 -1.508291,-1.41185 -2.08182,-1.91647 -0.28676,-0.25231 -0.521261,-0.45895 -0.92336,-0.76148 -0.201047,-0.15126 -0.388572,-0.32135 -1.00971,-0.65789 -0.310564,-0.16827 -0.682588,-0.40991 -1.732842,-0.66627 -1.050249,-0.25636 -4.028733,-0.7463 -6.616274,1.76657 -1.539573,1.45705 -2.288993,3.5248 -2.026936,5.59257 0.262055,2.06777 1.505651,3.89928 3.363508,4.95364 0.34191,0.30941 0.732128,0.65576 1.352158,1.24325 1.570361,1.48794 3.890994,3.74311 6.761491,6.54126 5.741001,5.59633 13.69671,13.3973 22.626998,21.99777 7.769995,7.48303 18.899617,8.47839 28.595837,5.72898 9.69621,-2.74941 18.86609,-8.75732 26.53197,-16.20191 7.66587,-7.44459 13.83992,-16.3377 16.64242,-25.72621 2.80251,-9.38852 1.72689,-20.14767 -6.0431,-27.63069 -17.80917,-17.15146 -32.05684,-30.87293 -32.05684,-30.87293 -1.3053,-1.29162 -3.09534,-2.01769 -4.96283,-2.013 -1.8675,0.005 -3.65363,0.73975 -4.95196,2.03791 l 0,0 z"
593 style="opacity:0.87000002;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:60;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
594 inkscape:connector-curvature="0" />
595 <path
596 id="path3179"
597 d="m 87.204209,305.82471 c -2.652845,2.65256 -2.582201,6.88205 0.157868,9.45036 l 35.940193,34.61287 c 1.74182,1.72562 4.30946,2.41055 6.71973,1.79255 2.41027,-0.61802 4.28975,-2.44325 4.91873,-4.77676 0.62899,-2.3335 -0.0899,-4.81377 -1.88154,-6.49106 L 97.119,305.7998 c -1.305296,-1.29163 -3.095344,-2.01769 -4.962836,-2.013 -1.867498,0.005 -3.653612,0.73974 -4.951955,2.03791 l 0,0 z"
598 style="opacity:0.87000002;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline"
599 inkscape:connector-curvature="0" />
600 <path
601 transform="matrix(0.16261542,-0.15792135,0.16329493,0.15726421,30.366855,326.43631)"
602 d="M 100,40 C 100,56.568542 86.568542,70 70,70 53.431458,70 40,56.568542 40,40 40,23.431458 53.431458,10 70,10 c 16.568542,0 30,13.431458 30,30 z"
603 sodipodi:ry="30"
604 sodipodi:rx="30"
605 sodipodi:cy="40"
606 sodipodi:cx="70"
607 id="path3181"
608 style="opacity:0.87000002;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:124.98213196;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
609 sodipodi:type="arc" />
610 <path
611 sodipodi:type="arc"
612 style="opacity:0.87000002;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:124.98213196;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
613 id="path3183"
614 sodipodi:cx="70"
615 sodipodi:cy="40"
616 sodipodi:rx="30"
617 sodipodi:ry="30"
618 d="M 100,40 C 100,56.568542 86.568542,70 70,70 53.431458,70 40,56.568542 40,40 40,23.431458 53.431458,10 70,10 c 16.568542,0 30,13.431458 30,30 z"
619 transform="matrix(0.16261542,-0.15792135,0.16329493,0.15726421,58.011475,299.58968)" />
620 <path
621 transform="matrix(0.16261542,-0.15792135,0.16329493,0.15726421,86.469174,271.95344)"
622 d="M 100,40 C 100,56.568542 86.568542,70 70,70 53.431458,70 40,56.568542 40,40 40,23.431458 53.431458,10 70,10 c 16.568542,0 30,13.431458 30,30 z"
623 sodipodi:ry="30"
624 sodipodi:rx="30"
625 sodipodi:cy="40"
626 sodipodi:cx="70"
627 id="path3185"
628 style="opacity:0.87000002;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:124.98213196;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
629 sodipodi:type="arc" />
630 </g>
631 <text
632 xml:space="preserve"
633 style="font-size:13.28640651999999989px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:center;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:middle;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Trebuchet MS;-inkscape-font-specification:Trebuchet MS"
634 x="215.76903"
635 y="383.70779"
636 id="text3067"
637 sodipodi:linespacing="125%"><tspan
638 sodipodi:role="line"
639 id="tspan3069"
640 x="215.76903"
641 y="383.70779"
642 style="font-size:18px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Georgia;-inkscape-font-specification:Georgia;fill:#ffffff;fill-opacity:1">i3wm.org</tspan></text>
643 </g>
644 </svg>
0 #!/bin/sh
1 # vim:ts=4:sw=4:expandtab
2 # © 2012 Michael Stapelberg, Public Domain
3
4 # This script is a trivial shell script to send your own output to i3bar while
5 # using the JSON protocol.
6 #
7 # It is ugly and that is inherent to using JSON with shell scripts. You
8 # _really_ should not do that. See i3status or i3status’s contrib/ directory
9 # for examples of how to handle the output in higher-level languages.
10 #
11 # This example is purely for illustration of the protocol. DO NOT USE IT IN THE
12 # REAL WORLD.
13
14 # Send the header so that i3bar knows we want to use JSON:
15 echo '{ "version": 1 }'
16
17 # Begin the endless array.
18 echo '['
19
20 # We send an empty first array of blocks to make the loop simpler:
21 echo '[]'
22
23 # Now send blocks with information forever:
24 while :;
25 do
26 echo ",[{\"name\":\"time\",\"full_text\":\"$(date)\"}]"
27 sleep 1
28 done
0 i3-wm (4.18.1-1) unstable; urgency=medium
1
2 * New upstream release.
3
4 -- Michael Stapelberg <[email protected]> Mon, 17 Feb 2020 18:25:47 +0100
5
6 i3-wm (4.18-1) unstable; urgency=medium
7
8 * New upstream release.
9
10 -- Michael Stapelberg <[email protected]> Mon, 17 Feb 2020 18:25:47 +0100
11
12 i3-wm (4.17.1-1) unstable; urgency=medium
13
14 * New upstream release.
15
16 -- Michael Stapelberg <[email protected]> Fri, 30 Aug 2019 23:06:40 +0200
17
18 i3-wm (4.17-1) unstable; urgency=medium
19
20 * New upstream release.
21
22 -- Michael Stapelberg <[email protected]> Sat, 03 Aug 2019 15:14:28 +0200
23
24 i3-wm (4.16.1-1) unstable; urgency=medium
25
26 * New upstream release.
27
28 -- Michael Stapelberg <[email protected]> Sun, 27 Jan 2019 16:45:11 +0100
29
30 i3-wm (4.16-1) unstable; urgency=medium
31
32 * UNRELEASED
33
34 -- Michael Stapelberg <[email protected]> Sun, 04 Nov 2018 14:47:25 +0100
35
36 i3-wm (4.15-1) unstable; urgency=medium
37
38 * New upstream release.
39
40 -- Michael Stapelberg <[email protected]> Sat, 10 Mar 2018 17:27:26 +0100
41
42 i3-wm (4.14.1-1) unstable; urgency=medium
43
44 * New upstream release.
45
46 -- Michael Stapelberg <[email protected]> Sun, 24 Sep 2017 19:21:15 +0200
47
48 i3-wm (4.14-1) unstable; urgency=medium
49
50 * New upstream release.
51
52 -- Michael Stapelberg <[email protected]> Mon, 04 Sep 2017 07:53:16 +0200
53
54 i3-wm (4.13-1) unstable; urgency=medium
55
56 * New upstream release.
57
58 -- Michael Stapelberg <[email protected]> Tue, 08 Nov 2016 19:02:16 +0100
59
60 i3-wm (4.12-2) unstable; urgency=medium
61
62 * Override lintian warning desktop-entry-contains-unknown-key for
63 DesktopNames, gdm needs that key.
64 * Remove i3-wm.menu to conform to the tech-ctte decision on #741573.
65
66 -- Michael Stapelberg <[email protected]> Fri, 01 Apr 2016 15:51:23 +0200
67
68 i3-wm (4.12-1) unstable; urgency=medium
69
70 * New upstream release.
71 * Move to debhelper 9
72 * Bump Standards-Version to 3.9.7 (no changes necessary)
73 * debian/watch: verify signature, use https
74
75 -- Michael Stapelberg <[email protected]> Sun, 06 Mar 2016 14:20:38 +0100
76
77 i3-wm (4.11-1) unstable; urgency=medium
78
79 * New upstream release.
80
81 -- Michael Stapelberg <[email protected]> Wed, 30 Sep 2015 08:50:13 +0200
82
83 i3-wm (4.10.4-1) unstable; urgency=medium
84
85 * New upstream release.
86
87 -- Michael Stapelberg <[email protected]> Tue, 08 Sep 2015 09:15:45 +0200
88
89 i3-wm (4.10.3-1) unstable; urgency=medium
90
91 * New upstream release.
92
93 -- Michael Stapelberg <[email protected]> Thu, 30 Jul 2015 21:51:27 +0200
94
95 i3-wm (4.10.2-2) unstable; urgency=medium
96
97 * New upstream release.
98 * experimental to unstable because i3-wm 4.10.2-1 was only in experimental
99 due to the freeze.
100
101 -- Michael Stapelberg <[email protected]> Fri, 01 May 2015 20:21:18 +0200
102
103 i3-wm (4.10.2-1) experimental; urgency=medium
104
105 * New upstream release.
106
107 -- Michael Stapelberg <[email protected]> Thu, 16 Apr 2015 09:02:53 +0200
108
109 i3-wm (4.10.1-1) experimental; urgency=medium
110
111 * New upstream release.
112
113 -- Michael Stapelberg <[email protected]> Sun, 29 Mar 2015 18:54:07 +0200
114
115 i3-wm (4.10-1) experimental; urgency=medium
116
117 * New upstream release.
118
119 -- Michael Stapelberg <[email protected]> Sun, 29 Mar 2015 17:46:09 +0200
120
121 i3-wm (4.9.1-1) experimental; urgency=medium
122
123 * New upstream release.
124
125 -- Michael Stapelberg <[email protected]> Sat, 07 Mar 2015 20:01:46 +0100
126
127 i3-wm (4.9-1) experimental; urgency=medium
128
129 * New upstream release.
130
131 -- Michael Stapelberg <[email protected]> Sat, 28 Feb 2015 14:53:34 +0100
132
133 i3-wm (4.8-2) unstable; urgency=medium
134
135 * Backport two bugfixes:
136 - backport-dpi-fix.patch (Closes: #778460)
137 - backport-i3bar-tray-fix.patch (Closes: #778461)
138
139 -- Michael Stapelberg <[email protected]> Sun, 15 Feb 2015 13:24:42 +0100
140
141 i3-wm (4.8-1) unstable; urgency=medium
142
143 * New upstream release.
144 * Bump standards-version to 3.9.5 (no changes necessary)
145
146 -- Michael Stapelberg <[email protected]> Sun, 15 Jun 2014 19:15:29 +0200
147
148 i3-wm (4.7.2-1) unstable; urgency=low
149
150 * New upstream release. (Closes: #736396)
151
152 -- Michael Stapelberg <[email protected]> Thu, 23 Jan 2014 23:03:03 +0100
153
154 i3-wm (4.7.1-1) unstable; urgency=low
155
156 * New upstream release.
157
158 -- Michael Stapelberg <[email protected]> Tue, 21 Jan 2014 19:29:34 +0100
159
160 i3-wm (4.7-1) unstable; urgency=low
161
162 * New upstream release.
163
164 -- Michael Stapelberg <[email protected]> Sun, 22 Dec 2013 21:19:02 +0100
165
166 i3-wm (4.6-1) unstable; urgency=low
167
168 * New upstream release.
169
170 -- Michael Stapelberg <[email protected]> Wed, 07 Aug 2013 20:53:26 +0200
171
172 i3-wm (4.5.1-2) unstable; urgency=low
173
174 * experimental to unstable because i3-wm 4.5.1 was only in experimental due
175 to the freeze.
176 * bump standards-version to 3.9.4 (no changes necessary)
177
178 -- Michael Stapelberg <[email protected]> Tue, 14 May 2013 20:48:16 +0200
179
180 i3-wm (4.5.1-1) experimental; urgency=low
181
182 * New upstream release
183
184 -- Michael Stapelberg <[email protected]> Mon, 18 Mar 2013 22:50:12 +0100
185
186 i3-wm (4.5-1) experimental; urgency=low
187
188 * New upstream release
189
190 -- Michael Stapelberg <[email protected]> Tue, 12 Mar 2013 13:51:04 +0100
191
192 i3-wm (4.4-1) experimental; urgency=low
193
194 * New upstream release
195
196 -- Michael Stapelberg <[email protected]> Tue, 11 Dec 2012 22:52:56 +0100
197
198 i3-wm (4.3-1) experimental; urgency=low
199
200 * New upstream release
201
202 -- Michael Stapelberg <[email protected]> Wed, 19 Sep 2012 18:13:40 +0200
203
204 i3-wm (4.2-1) unstable; urgency=low
205
206 * New upstream release
207
208 -- Michael Stapelberg <[email protected]> Wed, 25 Apr 2012 23:19:44 +0200
209
210 i3-wm (4.1.2-3) unstable; urgency=low
211
212 * Disable generation of docs/refcard.pdf (Closes: #666363)
213 * Add debian/i3-wm.menu (Closes: #664697)
214 * Bump standards-version to 3.9.3 (no changes needed)
215 * Fix 'section' field of the i3-wm source package to 'x11'
216 * Email change: Michael Stapelberg -> [email protected]
217
218 -- Michael Stapelberg <[email protected]> Thu, 12 Apr 2012 16:09:58 +0200
219
220 i3-wm (4.1.2-2) unstable; urgency=low
221
222 * Rebuild against libyajl and libxcb from unstable
223
224 -- Michael Stapelberg <[email protected]> Fri, 27 Jan 2012 19:50:29 +0000
225
226 i3-wm (4.1.2-1) unstable; urgency=low
227
228 * Bugfix: Don’t lose focus on fullscreen windows when another window gets
229 moved to that workspace
230 * Bugfix: Open new windows in the correct place when assignments match
231 * Bugfix: Fix assignments of floating windows to (yet) unused workspaces
232 * Bugfix: Either use SetInputFocus *or* send WM_TAKE_FOCUS, not both
233 * Bugfix: Respect WM_HINTS.input for WM_TAKE_FOCUS clients
234 * Bugfix: Setup the _NET_SUPPORTING_WM_CHECK atom in a standards-compliant
235 way
236 * Bugfix: Only ignore EnterNotify events after UnmapNotifies from managed
237 windows
238 * Bugfix: Force a new sequence number after UnmapNotify
239 * Bugfix: Position floating windows exactly where their geometry specified
240 * Bugfix: Fix coordinates when the rect of an output changes
241
242 -- Michael Stapelberg <[email protected]> Fri, 27 Jan 2012 19:04:28 +0000
243
244 i3-wm (4.1.1-1) unstable; urgency=low
245
246 * Re-add build-arch/build-indep targets to debian/rules (Closes: #648613)
247 * Create a secure temp path instead of a predictable one
248 * ipc: set CLOEXEC on client file descriptors
249 * Fix prototype in include/xcursor.h
250 * Bugfix: Skip dock clients when handling FocusIn events
251 * Bugfix: Fix fullscreen with floating windows
252 * Bugfix: Fix startup when RandR is not present
253 * Bugfix: Retain window position and size when changing floating border
254 * Bugfix: Disallow focusing dock clients via criteria
255 * Bugfix: Don’t create a workspace named 'back_and_forth' on startup
256 * Bugfix: Fix wrong focus in complex tabbed/stacked layouts
257 * Bugfix: Fix resizing for (e.g.) v-split containers in h-split containers
258 * Bugfix: Fix 'resize' command in nested containers
259 * Bugfix: Don’t set the _NET_WM_WORKAREA hint at all
260 * Bugfix: Skip leading whitespace in variable assignments
261 * Bugfix: Make resizing of tiling windows with floating_modifier use absolute
262 coordinates
263 * Bugfix: Make resizing work when pressing floating_modifier + right mouse
264 button on window decorations
265 * Bugfix: Fix setting the same mark repeatedly on different windows
266 * Bugfix: Disallow focusing other windows when in fullscreen mode
267 * Bugfix: Ignore ConfigureRequests with out-of-bound coordinates
268 * Bugfix: Correctly check boundaries and reassign floating windows when
269 moving
270 * Bugfix: Don’t close workspace when there are still floating windows on it
271
272 -- Michael Stapelberg <[email protected]> Sat, 24 Dec 2011 16:23:55 +0100
273
274 i3-wm (4.1-1) unstable; urgency=low
275
276 * Switch to dpkg-source 3.0 (quilt) and compat level 7
277 * Implement system tray support in i3bar (for NetworkManager, Skype, …)
278 * i3bar is now configurable in the i3 configfile
279 * Implement support for PCRE regular expressions in criteria
280 * Implement a new assign syntax which uses criteria
281 * Sort named workspaces whose name starts with a number accordingly
282 * Warn on duplicate bindings for the same key
283 * Restrict 'resize' command to left/right for horizontal containers, up/down
284 for vertical containers
285 * Implement support for startup notifications (cursor will change to 'watch',
286 started applications show up on the workspace they have been launched on)
287 * Implement the GET_MARKS IPC request to get all marks
288 * Implement the new_float config option (border style for floating windows)
289 * Implement passing IPC sockets to i3 (systemd-style socket activation)
290 * Implement the 'move output' command to move containers to a specific output
291 * Implement focus switching for floating windows
292 * Implement the window_role criterion (for matching multi-window apps)
293 * Implement a force_xinerama configuration directive
294 * Implement the --get-socketpath, useful for scripts using the IPC interface
295 * Implement the 'move workspace next' and 'move workspace prev' commands
296 * Implement the 'workspace back_and_forth' command and related configuration
297 option
298 * Implement the move command for floating windows
299 * i3 will now handle arbitrary text arguments by sending them as an IPC
300 command, like i3-msg: 'i3 reload' or 'i3 move workspace 3'
301 * Introduce the i3-sensible-{pager,editor,terminal} scripts to execute
302 $PAGER, $EDITOR or an available terminal emulator
303 * i3-input: implement -F (format) option
304 * Bugfix: Preserve marks when restarting
305 * Bugfix: Correctly free old assignments when reloading
306 * Bugfix: Fix flickering when moving floating windows between monitors
307 * Bugfix: Correctly handle ConfigureRequests for floating windows in a
308 multi-monitor environment.
309 * Bugfix: Fix size of floating windows with X11 borders
310 * Bugfix: Always adjust floating window position when moving to another
311 output
312 * Bugfix: Avoid out-of-bounds coordinates when moving floating windows
313 * Bugfix: Don’t steal focus when a window gets destroyed
314 * Bugfix: Correctly split key/value when parsing variables
315 * Bugfix: Correctly revert focus to other floating windows when closing a
316 floating window
317 * Bugfix: Don’t leak the error logfile file descriptor
318 * Bugfix: Don’t steal focus when a window opens on an invisible workspace due
319 to assignments
320 * Bugfix: Fix handling of Mode_switch in i3-input
321 * Bugfix: Close invisible workspaces when they become empty
322 * Bugfix: Don’t invoke interactive resizing when clicking on the decoration
323 of a split container with more than one child (switch focus instead)
324 * Bugfix: Make named workspace assignments work again
325 * Bugfix: RandR: Correctly keep focus on the focused workspace when an output
326 disappears
327 * Bugfix: Insert container at the correct position on workspace level when
328 workspace_layout == default
329
330 -- Michael Stapelberg <[email protected]> Fri, 11 Nov 2011 21:28:15 +0000
331
332 i3-wm (4.0.2-1) unstable; urgency=low
333
334 * i3-config-wizard: handle mouse button clicks on <win> and <alt> texts
335 * i3-config-wizard: check the modifier mapping to decide whether to use Mod1
336 or Mod4
337 * migrate-config: use \s, be a bit more whitespace tolerant
338 * userguide: s/mod+h/mod+s for stacking
339 * userguide: provide the default colors in the colors example
340 * userguide: document force_focus_wrapping directive
341 * userguide: properly document the resize command
342 * userguide: properly document command chaining and criteria
343 * Bugfix: Correctly bind on multiple keycodes if a symbol has more than one
344 * Bugfix: Allow multiple criteria in 'for_window'
345 * Bugfix: Ensure a minimum size when using the 'resize' command
346 * Bugfix: Start on the first named workspace, not always on '1'
347 * Bugfix: Fix resize command with direction != up for floating windows
348 * Bugfix: Correctly set the _NET_CLIENT_LIST_STACKING hint (chromium tabbar)
349 * Bugfix: 'workspace <next|prev>' now takes all outputs into account
350 * Bugfix: i3-wsbar: make workspace names clickable again
351 * Bugfix: i3-wsbar: correctly handle EOF on stdin
352 * Bugfix: i3-wsbar: display a separator between workspaces of each output
353 * Bugfix: Correctly handle the 'instance' criterion (WM_CLASS)
354 * Bugfix: Use correct format string in load_layout (fixes crash in restart)
355 * Bugfix: Fix border rendering (border lines were "cutting" through)
356 * Bugfix: Raise floating windows immediately when dragging/resizing
357 * Bugfix: Make focus switching work across outputs again
358 * Bugfix: migration-script: handle resize top/bottom correctly
359 * Bugfix: Fix focus issue when moving containers to workspaces
360 * Bugfix: Warp cursor when changing outputs again
361 * Bugfix: i3bar: fix switching to workspaces with extremely long names
362 * Bugfix: i3bar: fix switching to workspaces "next" and "prev"
363 * Bugfix: i3bar: Correctly allocate pixmap for statuslines which are longer
364 than the screen
365 * Bugfix: i3bar: set statusline = NULL on EOF / SIGCHLD
366 * Bugfix: Correctly initialize the verbose flag
367 * Bugfix: Don’t start with workspace 'next' when the command 'workspace next'
368 is bound in the config file
369 * Bugfix: Set focus to where the mouse pointer is when starting
370 * Bugfix: Don’t change focus when assigned windows start on invisible
371 workspaces
372 * Bugfix: Don’t use absolute paths for exec in the config file
373 * Bugfix: Fix crash when using 'focus mode_toggle' on an empty workspace
374 * Bugfix: Make the 'resize' command work inside tabbed/stacked cons
375 * Bugfix: Correctly place floating windows on their appropriate output
376 * Bugfix: Fix coordinates when moving a floating window to a different output
377 * Bugfix: Correctly keep focus when moving non-leaf windows
378 * Bugfix: Accept '\t' in the set command
379 * Bugfix: Only consider tiling windows when attaching tiling windows to a
380 workspace
381 * Bugfix: Correctly render containers when a split container is focused
382 * Bugfix: Correctly recognize duplicate workspace assignments
383 * Bugfix: Re-enable X11 Eventmask *after* pushing all the X11 changes
384 * Bugfix: Fix focus stealing with assignments of floating windows
385 * Bugfix: Re-implement reconfiguring height of dock windows
386 * Bugfix: IPC: return name_json if available
387 * Bugfix: Make 'floating enable' check for dock windows
388
389 -- Michael Stapelberg <[email protected]> Sun, 28 Aug 2011 19:07:43 +0200
390
391 i3-wm (4.0.1-1) unstable; urgency=low
392
393 * Fix the build process of i3bar (Closes: #636274)
394 * Fix the build process on Mac OS X
395 * i3-config-wizard: also start i3bar in the keycode config template
396 * userguide: Remove the obsolete bar.* colors
397 * userguide: Use i3bar instead of dzen2 in the 'exec' example
398
399 -- Michael Stapelberg <[email protected]> Mon, 01 Aug 2011 23:31:06 +0200
400
401 i3-wm (4.0-1) unstable; urgency=low
402
403 * In addition to the proper flex/bison based parser for the config file
404 introduced in 3.δ, we now also have a flex/bison parser for commands. What
405 this means is that we can have more human-readable, beautiful command names
406 instead of cryptic commands like 'f' for fullscreen or 'mh' for move left.
407 In fact, the commands for the aforementioned functions *are* 'fullscreen'
408 and 'move left'!
409 * You can now chain commands using ';' (a semicolon). One example for that is
410 'workspace 3 ; exec /usr/bin/urxvt' to switch to a new workspace and open a
411 terminal.
412 * You can specify which windows should be affected by your command by using
413 different criteria. A good example is '[class="Firefox"] kill' to get rid
414 of all Firefox windows.
415 * As the configuration file needs new commands (and a few options are
416 obsolete), you need to change it. To make this process a little bit easier
417 for you, this release comes with the script i3-migrate-config-to-v4. Just
418 run it on your current config file and it will spit out a v4 config file to
419 stdout. To make things even better, i3 automatically detects v3 config files
420 and calls that script, so you never end up with a non-working config :).
421 * Similarly to the criteria when using commands, we now have a 'for_window'
422 configuration directive, which lets you automatically apply certain commands
423 to certain windows. Use it to set border styles per window, for example with
424 'for_window [class="XTerm"] border 1pixel'.
425 * Since dock clients (like dzen2) are now part of the layout tree (as opposed
426 to a custom data structure as before), it was easy to implement top and
427 bottom dock areas. Programs which properly specify the dock hint get placed
428 on the edge of the screen they request. i3bar has the -dtop and -dbottom
429 parameters, for example.
430 * The internal workspace bar is obsolete. Use i3bar instead.
431 * Resizing now works between all windows!
432 * Fullscreen now works for everything!
433 * Floating now works for everything!
434 * Your layout is now preserved when doing an inplace restart.
435 * When you have an error in your config file, a new program called i3-nagbar
436 will tell you so. It offers you two buttons: One to view the error in your
437 $PAGER and one to edit your config in your $EDITOR.
438 * The default config used key symbols (like 'bind Mod1+f fullscreen') instead
439 of key codes. If you use a non-qwerty layout, the program i3-config-wizard
440 can create a key symbol based config file based on your current layout. You
441 can also chose between Windows (Mod4) and Alt (Mod1) as your default
442 modifier. i3-config-wizard will automatically be started as long as you
443 don’t have a configuration file for i3.
444 * Custom X cursor themes are now supported.
445 * The RandR backend now respects the primary output.
446 * A wrong 'font' configuration in your config file will no longer make i3
447 exit. Instead, it will fall back to a different font and tell you about the
448 error in its log.
449 * The default split direction (whether a new window gets placed right next to
450 the current one or below the current one) is now automatically set to
451 horizontal if you have a monitor that is wider than high or vertical if you
452 a monitor which is higher than wide. This works great with rotated monitors.
453 * Sockets and temporary files are now placed in XDG_RUNTIME_DIR, if set (this
454 is used on systemd based systems).
455 * Tools like i3bar, i3-msg etc. use the I3_SOCKET_PATH property which is set
456 to the X11 root window, so you don’t have to configure your socket path
457 anywhere.
458 * The kill command kills single windows by default now. To kill a whole
459 application, use 'kill client'.
460 * IPC: Commands can now have custom replies. When the parser encounters an
461 error, a proper error reply is sent.
462 * There is now an 'exec_always' configuration directive which works like
463 'exec' but will also be run when restarting.
464
465 -- Michael Stapelberg <[email protected]> Sun, 31 Jul 2011 22:34:26 +0200
466
467 i3-wm (3.e-bf1-3) unstable; urgency=low
468
469 * include keyboard-layer{1,2}.png in docs (Closes: #595295)
470
471 -- Michael Stapelberg <[email protected]> Wed, 03 Nov 2010 20:32:42 +0100
472
473 i3-wm (3.e-bf1-2) unstable; urgency=low
474
475 * debian: call dh_installwm to register as alternative for x-window-manager
476
477 -- Michael Stapelberg <[email protected]> Wed, 23 Jun 2010 18:23:10 +0200
478
479 i3-wm (3.e-bf1-1) unstable; urgency=low
480
481 * Bugfix: Correctly initialize workspaces if RandR is not available
482 * Bugfix: Correctly handle asprintf() return value
483 * Bugfix: Update _NET_WM_STATE when clients request changes via ClientMessage
484 * Bugfix: Don’t invert directions when resizing floating clients (top/left)
485 * Bugfix: Don’t leak file descriptors
486
487 -- Michael Stapelberg <[email protected]> Wed, 09 Jun 2010 09:51:10 +0200
488
489 i3-wm (3.e-3) unstable; urgency=low
490
491 * Bump debian policy version
492 * Add Recommends: libanyevent-i3-perl, libanyevent-perl, libipc-run-perl
493 which are necessary to use i3-wsbar (which is not core functionality,
494 thus no Depends:) (Closes: #577287)
495
496 -- Michael Stapelberg <[email protected]> Sat, 24 Apr 2010 11:20:19 +0200
497
498 i3-wm (3.e-2) unstable; urgency=low
499
500 * Use x-terminal-emulator instead of hard-coded urxvt
501
502 -- Michael Stapelberg <[email protected]> Sun, 04 Apr 2010 19:30:46 +0200
503
504 i3-wm (3.e-1) unstable; urgency=low
505
506 * Implement RandR instead of Xinerama
507 * Obey the XDG Base Directory Specification for config file paths
508 * lexer/parser: proper error messages
509 * Add new options -V for verbose mode and -d <loglevel> for debug log levels
510 * Implement resize command for floating clients
511 * Include date of the last commit in version string
512 * Fixed cursor orientation when resizing
513 * Added focus_follows_mouse config option
514 * Feature: Cycle through workspaces
515 * Fix bindings using the cursor keys in default config
516 * added popup for handling SIGSEGV or SIGFPE
517 * Correctly exit when another window manager is already running
518 * Take into account the window’s base_{width,height} when resizing
519 * Disable XKB instead of quitting with an error
520 * Make containers containing exactly one window behave like default containers
521 * Also warp the pointer when moving a window to a another visible workspace
522 * work around clients setting 0xFFFF as resize increments
523 * Move autostart after creating the IPC socket in start process
524 * Restore geometry of all windows before exiting/restarting
525 * When in fullscreen mode, focus whole screens instead of denying to focus
526 * draw consistent borders for each frame in a tabbed/stacked container
527 * Update fullscreen client position/size when an output changes
528 * i3-input: Bugfix: repeatedly grab the keyboard if it does not succeed
529 * put windows with WM_CLIENT_LEADER on the workspace of their leader
530 * use real functions instead of nested functions (enables compilation with
531 llvm-clang)
532 * implement screen-spanning fullscreen mode
533 * floating resize now uses arbitrary corners
534 * floating resize now works proportionally when pressing shift
535 * Don’t use SYNC key bindings for mode_switch but re-grab keys
536 * support PREFIX and SYSCONFDIR in Makefile
537 * make pointer follow the focus when moving to a different screen also for
538 floating clients
539 * start dock clients on the output they request to be started on according
540 to their geometry
541 * handle destroy notify events like unmap notify events
542 * ewmh: correctly set _NET_CURRENT_DESKTOP to the number of the active
543 workspace
544 * ewmh: correctly set _NET_ACTIVE_WINDOW
545 * ewmh: implement support for _NET_WORKAREA (rdesktop can use that)
546 * default ipc-socket path is now ~/.i3/ipc.sock, enabled in the default config
547 * Bugfix: Containers could lose their snap state
548 * Bugfix: Use ev_loop_new to not block SIGCHLD
549 * Bugfix: if a font provides no per-char info for width, fall back to default
550 * Bugfix: lexer: return to INITIAL state after floating_modifier
551 * Bugfix: Don’t leak IPC socket to launched processes
552 * Bugfix: Use both parts of WM_CLASS (it contains instance and class)
553 * Bugfix: Correctly do boundary checking/moving to other workspaces when
554 moving floating clients via keyboard
555 * Bugfix: checked for wrong flag in size hints
556 * Bugfix: Correctly render workspace names containing some non-ascii chars
557 * Bugfix: Correctly position floating windows sending configure requests
558 * Bugfix: Don’t remap stack windows errnously when changing workspaces
559 * Bugfix: configure floating windows above tiling windows when moving them
560 to another workspace
561 * Bugfix: Take window out of fullscreen mode before entering floating mode
562 * Bugfix: Don’t enter BIND_A2WS_COND state too early
563 * Bugfix: only restore focus if the workspace is focused, not if it is visible
564 * Bugfix: numlock state will now be filtered in i3-input and signal handler
565 * Bugfix: Don’t unmap windows when current workspace gets reassigned
566 * Bugfix: correctly translate coordinates for floating windows when outputs
567 change
568 * Bugfix: Correctly switch workspace when using the "jump" command
569 * Bugfix: Fix rendering of workspace names after "reload"
570 * Bugfix: Correctly ignore clicks when in fullscreen mode
571 * Bugfix: Don’t allow fullscreen floating windows to be moved
572 * Bugfix: Don’t render containers which are not visible on hint changes
573 * Some memory leaks/invalid accesses have been fixed
574
575 -- Michael Stapelberg <[email protected]> Tue, 30 Mar 2010 13:11:50 +0200
576
577 i3-wm (3.d-bf1-1) unstable; urgency=low
578
579 * Bugfix: Don’t draw window title when titlebar is disabled
580 * Bugfix: Correctly switch border types for floating windows
581 * Bugfix: Correctly replay pointer if the click handler does not trigger
582 * Bugfix: Also allow WORDs as workspace names
583 * Bugfix: Correctly clear the urgency hint if a window gets unmapped without
584 clearing it
585 * Bugfix: Fix resizing of floating windows in borderless/1-px-border mode
586 * Bugfix: Accept underscores in bindsym
587 * Bugfix: Don’t set the urgency flag if the window is focused
588 * Bugfix: Handle stack-limit cols on tabbed containers
589 * Bugfix: Resize client after updating base_width/base_height
590 * Bugfix: Force render containers after setting the client active
591 * Bugfix: Fix two problems in resizing floating windows with right mouse
592 * Bugfix: Use more precise floating point arithmetics
593 * Bugfix: Correctly place new windows below fullscreen windows
594
595 -- Michael Stapelberg <[email protected]> Mon, 21 Dec 2009 22:33:02 +0100
596
597 i3-wm (3.d-2) unstable; urgency=low
598
599 * debian: register in doc-base
600 * debian: add watchfile
601 * debian: remove unnecessary priority-field from binary packages
602 * debian: add missing images to documentation
603
604 -- Michael Stapelberg <[email protected]> Mon, 23 Nov 2009 21:56:04 +0100
605
606 i3-wm (3.d-1) unstable; urgency=low
607
608 * Implement tabbing (command "T")
609 * Implement horizontal resize of containers (containers! not windows)
610 * Implement the urgency hint for windows/workspaces
611 * Implement vim-like marks (mark/goto command)
612 * Implement stack-limit for further defining how stack windows should look
613 * Implement modes which allow you to use a different set of keybindings
614 when inside a specific mode
615 * Implement changing the default mode of containers
616 * Implement long options (--version, --no-autostart, --help, --config)
617 * Implement 'bt' to toggle between the different border styles
618 * Implement an option to specify the default border style
619 * Use a yacc/lex parser/lexer for the configuration file
620 * The number of workspaces is now dynamic instead of limited to 10
621 * Floating windows (and tiled containers) can now be resized using
622 floating_modifier and right mouse button
623 * Dock windows can now reconfigure their height
624 * Bugfix: Correctly handle multiple messages on the IPC socket
625 * Bugfix: Correctly use base_width, base_height and size increment hints
626 * Bugfix: Correctly send fake configure_notify events
627 * Bugfix: Don’t crash if the numlock symbol cannot be found
628 * Bugfix: Don’t display a colon after unnamed workspaces
629 * Bugfix: If the pointer is outside of the screen when starting, fall back to
630 the first screen.
631 * Bugfix: Initialize screens correctly when not using Xinerama
632 * Bugfix: Correctly handle unmap_notify events when resizing
633 * Bugfix: Correctly warp pointer after rendering the layout
634 * Bugfix: Fix NULL pointer dereference when reconfiguring screens
635 * Explicitly specify -lxcb when linking (Closes: #554860)
636
637 -- Michael Stapelberg <[email protected]> Mon, 09 Nov 2009 20:53:43 +0100
638
639 i3-wm (3.c-2) unstable; urgency=low
640
641 * Fix FTBFS on GNU/kFreeBSD and possibly GNU/Hurd (Closes: #542877)
642 * Add manpage for i3-msg
643
644 -- Michael Stapelberg <[email protected]> Mon, 24 Aug 2009 12:23:18 +0200
645
646 i3-wm (3.c-1) unstable; urgency=low
647
648 * Implement a reload command
649 * Implement keysymbols in configuration file
650 * Implement assignments of workspaces to screens
651 * Implement named workspaces
652 * Implement borderless/1-px-border windows
653 * Implement command to focus screens
654 * Implement IPC via unix sockets
655 * Correctly render decoration of floating windows
656 * Map floating windows requesting (0x0) to center of their leader/workspace
657 * Optimization: Render stack windows on pixmaps to reduce flickering
658 * Optimization: Directly position new windows to their final position
659 * Bugfix: Repeatedly try to find screens if none are available
660 * Bugfix: Correctly redecorate clients when changing focus
661 * Bugfix: Don’t crash when clients reconfigure themselves
662 * Bugfix: Fix screen wrapping
663 * Bugfix: Fix selecting a different screen with your mouse when not having
664 any windows on the current workspace
665 * Bugfix: Correctly unmap stack windows and don’t re-map them too early
666 * Bugfix: Allow switching layout if there are no clients in the this container
667 * Bugfix: Set WM_STATE_WITHDRAWN when unmapping, unmap windows when
668 destroying
669 * Bugfix: Don’t hide assigned clients to inactive but visible workspaces
670
671 -- Michael Stapelberg <[email protected]> Wed, 19 Aug 2009 13:07:58 +0200
672
673 i3-wm (3.b-1) unstable; urgency=low
674
675 * Bugfix: Correctly handle col-/rowspanned containers when setting focus.
676 * Bugfix: Correctly handle col-/rowspanned containers when snapping.
677 * Bugfix: Force reconfiguration of all windows on workspaces which are
678 re-assigned because a screen was detached.
679 * Bugfix: Several bugs in resizing table columns fixed.
680 * Bugfix: Resizing should now work correctly in all cases.
681 * Bugfix: Correctly re-assign dock windows when workspace is destroyed.
682 * Bugfix: Correctly handle Mode_switch modifier.
683 * Bugfix: Don't raise clients in fullscreen mode.
684 * Bugfix: Re-assign dock windows to different workspaces when a workspace
685 is detached.
686 * Bugfix: Fix crash because of workspace-pointer which did not get updated
687 * Bugfix: Correctly initialize screen when Xinerama is disabled.
688 * Bugfix: Fullscreen window movement and focus problems fixed
689 * Implement jumping to other windows by specifying their position or
690 window class/title.
691 * Implement jumping back by using the focus stack.
692 * Implement autostart (exec-command in configuration file).
693 * Implement floating.
694 * Implement automatically assigning clients on specific workspaces.
695 * Implement variables in configfile.
696 * Colors are now configurable.
697
698 -- Michael Stapelberg <[email protected]> Fri, 26 Jun 2009 04:42:23 +0200
699
700 i3-wm (3.a-bf2-1) unstable; urgency=low
701
702 * Bugfix: Don't crash when setting focus
703 * Bugfix: Reconfigure bar window when changing resolutions
704
705 -- Michael Stapelberg <[email protected]> Sun, 03 May 2009 23:02:24 +0200
706
707 i3-wm (3.a-bf1-1) unstable; urgency=low
708
709 * Bugfix: When entering a stack window with the mouse, set focus to the
710 active client in the container the stack window belongs to.
711 * Bugfix: Correctly filter out the numlock bit. This fixes i3 not reacting
712 to any keybindings after pressing numlock once.
713 * Bugfix: Don't crash when Xinerama is disabled.
714 * Bugfix: Correctly remove client from container when moving to another
715 workspace.
716 * Bugfix: Set focus to the client which was previously focused instead of
717 the next client in container when moving windows out of a container.
718 * Bugfix: Correctly set focus when switching between screens.
719 * Bugfix: Don't crash anymore moving focus to another screen under the
720 following conditions: The screen you switch to has a lower number of cells
721 and/or rows than the current one, you switch focus using your mouse, you
722 previously were in a column/row which is not available on the destination
723 screen.
724 * Bugfix: When switching screens, warp the pointer to the correct
725 destination window.
726 * Bugfix: Store dock clients per screen, not per workspace.
727 * Bugfix: Perform bounds checking for snapped containers.
728 * Bugfix: Send clients their absolute position/size (on the root window) in
729 generated configure events. This fixes problems with xfontsel, xmaple,
730 etc.
731 * Bugfix: Correctly update state when moving fullscreen windows across
732 workspaces.
733 * Bugfix: Correctly restart i3 when not using its absolute path
734 * Bugfix: Drag & Drop in GTK applications works now
735 * Bugfix: Don't hide non-managed windows (libnotify-popups for example)
736 when raising clients in stacked containers.
737 * Bugfix: Correctly restore focus when leaving fullscreen mode
738 * Bugfix: Re-distribute free space when closing customly resized containers,
739 re-evaluate for other containers
740 * Bugfix: When moving windows into different containers, insert them at the
741 correct position.
742 * Bugfix: Correctly set focus when moving windows into other containers
743 * Implement scrolling on stack windows and on the bottom bar.
744 * Create i3-wm-dbg with debug symbols
745 * Don't rely on libxcb-wm any longer, as it got removed in libxcb 0.3.4.
746
747 -- Michael Stapelberg <[email protected]> Sat, 02 May 2009 20:55:46 +0200
748
749 i3-wm (3.a-1) unstable; urgency=low
750
751 * First release (Closes: #521709)
752
753 -- Michael Stapelberg <[email protected]> Sun, 29 Mar 2009 18:21:30 +0200
0 Source: i3-wm
1 Section: x11
2 Priority: extra
3 Maintainer: Michael Stapelberg <[email protected]>
4 Build-Depends: debhelper (>= 9),
5 dh-autoreconf,
6 libx11-dev,
7 libxcb-util0-dev (>= 0.3.8),
8 libxcb-keysyms1-dev,
9 libxcb-xinerama0-dev (>= 1.1),
10 libxcb-randr0-dev,
11 libxcb-icccm4-dev,
12 libxcb-cursor-dev,
13 libxcb-xrm-dev,
14 libxcb-xkb-dev,
15 libxcb-shape0-dev,
16 libxkbcommon-dev (>= 0.4.0),
17 libxkbcommon-x11-dev (>= 0.4.0),
18 asciidoc (>= 8.4.4),
19 xmlto,
20 docbook-xml,
21 pkg-config,
22 libev-dev (>= 1:4.04),
23 libyajl-dev (>= 2.0.4),
24 libpcre3-dev (>= 1:8.10),
25 libstartup-notification0-dev (>= 0.10),
26 libcairo2-dev (>= 1.14.4),
27 libpango1.0-dev,
28 libpod-simple-perl
29 Standards-Version: 3.9.8
30 Homepage: https://i3wm.org/
31
32 Package: i3
33 Architecture: any
34 Depends: i3-wm (=${binary:Version}), ${misc:Depends}
35 Recommends: i3lock (>= 2.2), suckless-tools, i3status (>= 2.3), dunst
36 Description: metapackage (i3 window manager, screen locker, menu, statusbar)
37 This metapackage installs the i3 window manager (i3-wm), the i3lock screen
38 locker, i3status (for system information) and suckless-tools (for dmenu).
39 These are all the tools you need to use the i3 window manager efficiently.
40
41 Package: i3-wm
42 Architecture: any
43 Depends: ${shlibs:Depends}, ${misc:Depends}, ${perl:Depends}
44 Provides: x-window-manager
45 Recommends: xfonts-base, fonts-dejavu-core, libanyevent-i3-perl (>= 0.12), libjson-xs-perl, rxvt-unicode | x-terminal-emulator
46 Description: improved dynamic tiling window manager
47 Key features of i3 are good documentation, reasonable defaults (changeable in
48 a simple configuration file) and good multi-monitor support. The user
49 interface is designed for power users and emphasizes keyboard usage. i3 uses
50 XCB for asynchronous communication with X11 and aims to be fast and
51 light-weight.
52 .
53 Please be aware i3 is primarily targeted at advanced users and developers.
54
55 Package: i3-wm-dbg
56 Architecture: any
57 Section: debug
58 Depends: i3-wm (=${binary:Version}), ${misc:Depends}
59 Description: Debugging symbols for the i3 window manager
60 Debugging symbols for the i3 window manager. Please install this to produce
61 useful backtraces before creating new tickets.
0 Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
1 Upstream-Name: i3
2 Upstream-Contact: Michael Stapelberg <[email protected]>
3 Source: https://i3wm.org/
4
5 Files: *
6 Copyright: 2009 Michael Stapelberg
7 License: BSD-3-clause
8
9 Files: debian/*
10 Copyright: 2009 Michael Stapelberg
11 License: BSD-3-clause
12
13 License: BSD-3-clause
14 Copyright: © 2009 Michael Stapelberg <michael at i3wm dot org>
15 All rights reserved.
16 .
17 Redistribution and use in source and binary forms, with or without
18 modification, are permitted provided that the following conditions are met:
19 .
20 * Redistributions of source code must retain the above copyright notice, this
21 list of conditions and the following disclaimer.
22 .
23 * Redistributions in binary form must reproduce the above copyright notice,
24 this list of conditions and the following disclaimer in the documentation
25 and/or other materials provided with the distribution.
26 .
27 * Neither the name of Michael Stapelberg, i3 nor the names of its contributors
28 may be used to endorse or promote products derived from this software
29 without specific prior written permission.
30 .
31 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
35 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
39 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0 Document: i3-wm
1 Title: i3 documentation
2 Author: Michael Stapelberg
3 Abstract: The documentation explains how to use and modify the i3 window
4 manager.
5 Section: Window Managers
6
7 Format: HTML
8 Files: /usr/share/doc/i3-wm/*.html
9 Index: /usr/share/doc/i3-wm/userguide.html
0 docs/debugging.html
1 docs/hacking-howto.html
2 docs/i3bar-protocol.html
3 docs/userguide.html
4 docs/bigpicture.png
5 docs/single_terminal.png
6 docs/snapping.png
7 docs/two_columns.png
8 docs/two_terminals.png
9 docs/modes.png
10 docs/ipc.html
11 docs/multi-monitor.html
12 docs/wsbar.html
13 docs/wsbar.png
14 docs/keyboard-layer1.png
15 docs/keyboard-layer2.png
16 docs/testsuite.html
17 docs/i3-sync-working.png
18 docs/i3-sync.png
19 docs/tree-layout1.png
20 docs/tree-layout2.png
21 docs/tree-shot1.png
22 docs/tree-shot2.png
23 docs/tree-shot3.png
24 docs/tree-shot4.png
25 docs/refcard.html
26 docs/refcard_style.css
27 docs/logo-30.png
28 docs/lib-i3test.html
29 docs/lib-i3test-test.html
30 docs/layout-saving.html
31 docs/layout-saving-1.png
0 debian/tmp/etc
1 debian/tmp/usr
2 contrib/dump-asy.pl usr/share/doc/i3-wm/examples/
3 contrib/gtk-tree-watch.pl usr/share/doc/i3-wm/examples/
4 contrib/i3-wsbar usr/share/doc/i3-wm/examples/
5 contrib/per-workspace-layout.pl usr/share/doc/i3-wm/examples/
6 contrib/trivial-bar-script.sh usr/share/doc/i3-wm/examples/
0 usr/share/man/man1/i3.1.gz usr/share/man/man1/i3-with-shmlog.1.gz
0 man/i3.1
1 man/i3-msg.1
2 man/i3-input.1
3 man/i3-nagbar.1
4 man/i3-config-wizard.1
5 man/i3-dump-log.1
6 man/i3-migrate-config-to-v4.1
7 man/i3-sensible-pager.1
8 man/i3-sensible-editor.1
9 man/i3-sensible-terminal.1
10 man/i3-dmenu-desktop.1
11 man/i3-save-tree.1
12 man/i3bar.1
0 /usr/bin/i3
0 #!/usr/bin/make -f
1 # vi: ts=8 sw=8 noet
2
3 export V:=1
4 export DEB_BUILD_MAINT_OPTIONS = hardening=+all
5
6 override_dh_installchangelogs:
7 dh_installchangelogs RELEASE-NOTES-*
8
9 override_dh_strip:
10 dh_strip --dbg-package=i3-wm-dbg
11
12 override_dh_auto_test:
13 # TODO: enable tests
14
15 override_dh_auto_configure:
16 # The default is /usr/share/doc/i3
17 dh_auto_configure -- --docdir=/usr/share/doc/i3-wm
18
19 override_dh_builddeb:
20 # bintray does not support xz currently.
21 dh_builddeb -- -Zgzip
22
23 %:
24 dh $@ --parallel --builddirectory=build --with=autoreconf
0 -----BEGIN PGP PUBLIC KEY BLOCK-----
1 Version: GnuPG v1
2
3 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
53 VRx/oRxr
54 =1n/p
55 -----END PGP PUBLIC KEY BLOCK-----
0 version=3
1 opts=pgpsigurlmangle=s/$/.asc/ \
2 https://i3wm.org/downloads/ /downloads/i3-(.*)\.tar\.bz2
0 %
1 % © 2009 Michael Stapelberg
2 %
3 % 2009-06-24
4 %
5 \documentclass[mode=print,paper=screen,style=jefka]{powerdot}
6 \usepackage[utf8]{inputenc}
7 \usepackage{graphicx}
8 \usepackage{float}
9 \usepackage{ngerman}
10 \usepackage{url}
11 \usepackage{listings}
12 \newcommand{\bs}{\textbackslash}
13 \pdsetup{palette=white}
14 \definecolor{darkblue}{rgb}{0,0,.6}
15 \definecolor{darkred}{rgb}{.6,0,0}
16 \definecolor{darkgreen}{rgb}{0,.6,0}
17 \definecolor{darkgray}{gray}{.3}
18 \definecolor{lightblue}{rgb}{0.97,0.99,1}
19
20 \lstloadlanguages{C}
21 \lstdefinestyle{colors}{keywordstyle={\bf\color{darkblue}}, commentstyle={\em\color{magenta}}, stringstyle={\color{darkred}},%
22 emphstyle={\color{darkgray}}}
23 \lstnewenvironment{code}{%
24 \lstset{frame=single, basicstyle=\footnotesize\ttfamily, language=C, showstringspaces=false,%
25 style=colors, numbers=left, morekeywords={xcb_get_window_attributes_cookie_t, xcb_map_request_event_t,%
26 xcb_connection_t, xcb_get_window_attributes_reply_t, window_attributes_t, xcb_intern_atom_cookie_t,%
27 xcb_intern_atom_reply_t, xcb_atom_t, uint32_t, uint16_t, foreach, UINT_MAX, NULL},%
28 moreemph={xcb_get_window_attributes_reply, xcb_get_window_attributes_unchecked, manage_window,%
29 add_ignore_event, xcb_intern_atom, xcb_intern_atom_reply, fprintf, printf, free, load_configuration,%
30 XInternAtom, exit, strlen, xcb_change_window_attributes, xcb_event_wait_for_event_loop,%
31 xcb_event_set_key_press_handler, xcb_property_set_handler}}
32 }{}
33
34 \newcommand{\isrc}[1]{\begin{center} \footnotesize\ttfamily Siehe auch: #1 \end{center}}
35
36 \title{Hacking your own window manager}
37 \author{sECuRE auf der GPN 8\\
38 ~\\
39 powered by \LaTeX, of course}
40 \begin{document}
41 \maketitle
42
43 \begin{slide}{Dieser Vortrag}
44 \begin{list}{$\bullet$}{\itemsep=.5em}
45 \item Geschichte/Einführung in Window Manager
46 \item Merkmale von i3
47 \item Window Manager und X11
48 %
49 % zuerst: wie funktioniert ein client?
50 %
51 % WM ist nur ein weiterer Client
52 % Keine Rechteverwaltung, prinzipiell darf jeder Fenster schubsen
53 % Clients können Events abfangen, der WM macht das halt für das root-fenster
54 \item Arbeitsumgebung
55 \item XCB
56 \item Setup
57 \item Reparenting (Window Decorations)
58 %\item fake\_configure\_notify
59 %\item Colorpixel
60 %\item UTF-8
61 % irgendwo da erwähnen: fenster in eine hashtable aufnehmen
62
63 \item Events
64 % (die kriegt man natürlich nur wenn man redirectmask gesetzt hat:)
65 % MapRequest
66 % ConfigureRequest
67 \item Hints (Titel, Klassen, Größen, …)
68 % Atoms
69 % NetWM
70 % - NET_WM_WINDOW_TYPE
71 % - NET_WM_NAME
72 % - in kombination mit NET_SUPPORTING_WM_CHECK auf dem rootfenster
73 % - NET_WM_STRUT_PARTIAL
74 % ICCCM
75 % - Normal hints / size hints (warum zwei namen?)
76 % - Aspect ratio, wichtig z.B. für mplayer
77 % - min/max size, interessant primär für floating
78 % - WM_NAME
79 % - WM_TRANSIENT_FOR
80 % - WM_CLASS
81 \item Gotchas
82 % flush()
83 % WM_STATE_NORMAL und drag&drop in gtk-apps
84 \item Zusammenfassung
85 % TODO
86 \end{list}
87 \end{slide}
88
89 \begin{slide}{Geschichte/Einführung}
90 \begin{list}{$\bullet$}{\itemsep=1em}
91 \item<1-> „All window managers suck, this one just sucks less”?
92 \item<2-> Desktop environment vs. window manager (GNOME, KDE, Xfce, …)
93 \item<3-> Stacking (e17, fluxbox, IceWM, fvwm, …) vs Tiling (dwm, wmii, xmonad, …)
94 \item<4-> dwm, awesome, xmonad, …: statisches Layout
95 % gedanke: man braucht sich nicht mal mehr um das layout kümmern
96 \item<5-> wmii, ion: dynamisches layout
97 \item<6-> Probleme an ion: tuomov (Lizenz, Kommunikation), Config, Look and feel, Code
98 \item<7-> Probleme an wmii: Xinerama-support, Xlib, undokumentierter Code, nur Spalten, keine Reihen, Kleinigkeiten (titellose Fenster)
99 \end{list}
100 \end{slide}
101
102 \begin{slide}{Merkmale von i3}
103 \begin{list}{$\bullet$}{\itemsep=1em}
104 \item<1-> gut lesbarer, dokumentierter Code. Dokumentation.
105 \item<2-> XCB anstelle von Xlib
106 \item<3-> Xinerama done right™
107 \item<4-> Spalten und Zeilen, Tabelle als Basis
108 \item<5-> command-mode, wie in vim
109 \item<6-> UTF-8 clean
110 \item<7-> kein Antialiasing, schlank und schnell bleiben
111 \end{list}
112 \end{slide}
113
114 \begin{slide}{Typische Kommunikation mit X}
115 \begin{list}{$\bullet$}{\itemsep=1em}
116 \item<1-> Verbindung aufbauen
117 \item<2-> Requests über die Leitung schicken (Fenster erzeugen)
118 \begin{list}{$\bullet$}{\itemsep=1em}
119 \item Cookie für jeden Request
120 \item Antwort für spezifisches Cookie abholen
121 \item $\Rightarrow$ Asynchronität nutzbar
122 \end{list}
123 \item<3-> Eventloop starten, reagieren (Fenster zeichnen, Eingaben, …)
124 \end{list}
125 \end{slide}
126
127 \begin{slide}{Was genau macht ein WM?}
128 \begin{list}{$\bullet$}{\itemsep=1em}
129 \item<1-> Events umlenken
130 \item<2-> Neue Fenster anzeigen/positionieren (MapRequest)
131 \item<3-> Titelleisten malen (reparenting)
132 \item<4-> Den Fokus verwalten
133 \item<5-> Mit Hints umgehen (Fenstertitel, Fullscreen, Dock, …)
134 \item<6-> Auf Benutzereingaben reagieren
135 \end{list}
136 \end{slide}
137
138
139 \begin{slide}[method=direct]{Window Manager und X11 (1)}
140 \includegraphics[width=1\textwidth]{xserver_konzept.eps}
141 \end{slide}
142
143 \begin{slide}{Window Manager und X11 (2)}
144 \begin{list}{$\bullet$}{\itemsep=1em}
145 \item<1-> Keine Rechteaufteilung, prinzipiell kann jeder Fenster managen
146 \item<2-> Window Manager verantwortlich für alle Kinder das Root-Fensters
147 \item<3-> RedirectMask, lässt sich Events des Root-Fensters schicken
148 \item<4-> Setzt hints auf dem Root-Fenster
149 \end{list}
150 \end{slide}
151
152 \begin{slide}{Arbeitsumgebung}
153 \begin{list}{$\bullet$}{\itemsep=1em}
154 \item X sinnvoll beim Entwickeln $\Rightarrow$ anderen Computer verwenden oder Xephyr
155 \item xtrace dazwischenschalten (sowohl zwischen WM und X11 als auch zwischen Clients und X11 sinnvoll)\\
156 \texttt{DISPLAY=:1 xtrace -o /tmp/xtrace.log -n :9}
157 \item \texttt{xprop} zeigt Hints an, \texttt{xwininfo} gibt Struktur aus
158 \item als ersten Client ein Terminal starten $\Rightarrow$ wenn der WM crashed lebt
159 die X-Session noch\\
160 \texttt{DISPLAY=:1 urxvt \&}
161 \item Debugger, strace, logfiles, core-dumps aktivieren\\
162 (Siehe auch \url{http://i3wm.org/docs/debugging.html})
163 \end{list}
164 \end{slide}
165
166 \begin{slide}{XCB}
167 \begin{list}{$\bullet$}{\itemsep=1em}
168 \item \url{http://xcb.freedesktop.org/}
169 \item<1-> „X-protocol C-language Binding”
170 \item<2-> Klein, wartbar (aus einer Protokollbeschreibung auto-generiert)
171 \item<3-> Sinnvoll benannte Funktionsnamen und Datentypen
172 \item<4-> Nutzt die Asynchronität von X aus
173 \item<5-> Allerdings: Sehr spärlich dokumentiert, man muss mit Xlib-Doku arbeiten
174 \item<6-> xcb-util: XCB noch mal ein bisschen gekapselt, nützliche Funktionen abstrahiert
175 \end{list}
176 \end{slide}
177
178 \begin{slide}[method=direct]{Xlib-Beispielcode}
179 \begin{code}
180 char *names[10] = {"_NET_SUPPORTED", "_NET_WM_STATE",
181 "_NET_WM_STATE_FULLSCREEN", "_NET_WM_NAME" /* ... */};
182 Atom atoms[10];
183
184 /* Get atoms */
185 for (int i = 0; i < 10; i++) {
186 atoms[i] = XInternAtom(display, names[i], 0);
187 }
188 \end{code}
189 \end{slide}
190
191 \begin{slide}[method=direct]{XCB-Beispielcode}
192 \begin{code}
193 char *names[10] = {"_NET_SUPPORTED", "_NET_WM_STATE",
194 "_NET_WM_STATE_FULLSCREEN", "_NET_WM_NAME" /* ... */};
195 xcb_intern_atom_cookie_t cookies[10];
196
197 /* Place requests for atoms as soon as possible */
198 for (int c = 0; c < 10; c++)
199 cookies[c] = xcb_intern_atom(connection, 0,
200 strlen(names[c]), names[c]);
201
202 /* Do other stuff here */
203 load_configuration();
204
205 /* Get atoms */
206 for (int c = 0; c < 10; c++) {
207 xcb_intern_atom_reply_t *reply =
208 xcb_intern_atom_reply(connection, cookies[c], NULL);
209 if (!reply) {
210 fprintf(stderr, "Could not get atom\n");
211 exit(-1);
212 }
213 printf("atom has ID %d\n", reply->atom);
214 free(reply);
215 }
216 \end{code}
217 \end{slide}
218
219 \begin{slide}[method=direct]{Setup}
220 \begin{code}
221 get_atoms();
222
223 xcb_event_set_key_press_handler(&evenths, handle_key_press, NULL);
224 xcb_property_set_handler(&prophs, WM_TRANSIENT_FOR, UINT_MAX,
225 handle_transient_for, NULL);
226
227 xcb_grab_key(conn, 0, root, modifier, keycode,
228 XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
229 xcb_grab_key(conn, 0, root, modifier | xcb_numlock_mask, keycode,
230 XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
231
232 uint32_t values[] = { XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
233 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
234 XCB_EVENT_MASK_PROPERTY_CHANGE |
235 XCB_EVENT_MASK_ENTER_WINDOW };
236 xcb_change_window_attributes(conn, root, XCB_CW_EVENT_MASK, values);
237
238 manage_existing_windows();
239
240 xcb_event_wait_for_event_loop(&evenths);
241 \end{code}
242
243 \isrc{i3/src/mainx.c:370ff}
244 \end{slide}
245
246 \begin{slide}[method=direct]{Reparenting}
247 \includegraphics[width=1\textwidth]{reparenting.eps}
248 \begin{enumerate}
249 \item (App) Fenster wird konfiguriert (Position, Größe, …)
250 \item (App) MapRequest
251 \item (WM) Window Manager erstellt eigenes Fenster
252 \item (WM) Reparent = neues Fenster kriegt statt root das WM-Fenster als parent
253 \item (WM) Mappen des neuen Fensters
254 \end{enumerate}
255 \end{slide}
256
257 \begin{slide}[method=direct]{fake\_configure\_notify}
258 \begin{list}{$\bullet$}{\itemsep=.5em}
259 \item (Alte) Reparented clients kriegen nichts mit, denken relativ zum root-Fenster
260 \item $\Rightarrow$ Window Manager tut so, als würde das Fenster neu konfiguriert, sendet den Event mit absoluten statt relativen Koordinaten
261 \item Sieht man sehr gut an \texttt{xfontsel} und anderen Anwendungen, die Xaw (X Athena widget set) verwenden
262 \end{list}
263 \begin{code}
264 xcb_configure_notify_event_t generated_event;
265 generated_event.window = window;
266 generated_event.response_type = XCB_CONFIGURE_NOTIFY;
267 generated_event.x = r.x;
268 /* ... */
269 generated_event.override_redirect = false;
270 xcb_send_event(conn, false, window,
271 XCB_EVENT_MASK_STRUCTURE_NOTIFY,
272 (char*)&generated_event);
273 \end{code}
274 \isrc{i3/src/xcb.c:193ff}
275 \end{slide}
276
277
278 \begin{slide}[method=direct]{Events: button\_press}
279 \begin{list}{$\bullet$}{\itemsep=.5em}
280 \item Aktiv grabben, die Anwendung soll keinen Klick bekommen, wenn der Nutzer das Fenster verschiebt
281 \end{list}
282 \begin{code}
283 int handle_button_press(void *ignored, xcb_connection_t *conn,
284 xcb_button_press_event_t *event) {
285 /* ... */
286 if ((event->state & XCB_MOD_MASK_1) != 0)
287 floating_drag_window(conn, client, event);
288
289 /* ... */
290 if (event->detail == XCB_BUTTON_INDEX_4 ||
291 event->detail == XCB_BUTTON_INDEX_5) {
292 LOG("User scrolled\n");
293 return 1;
294 }
295 /* if unhandled, forward the click to the application */
296 xcb_allow_events(conn, XCB_ALLOW_REPLAY_POINTER, event->time);
297 return 1;
298 }
299 \end{code}
300 \isrc{i3/src/handlers.c:148ff}
301 \end{slide}
302
303
304 \begin{slide}[method=direct]{Events: enter\_notify}
305 \begin{list}{$\bullet$}{\itemsep=.5em}
306 \item Der Mauszeiger ist über dem Fenster gelandet
307 \item Auch unabsichtlich: Wenn das Fenster unter den Mauszeiger konfiguriert wird
308 \item $\Rightarrow$ Blacklist an Events, die man ignorieren muss
309 \end{list}
310
311 \begin{code}
312 int handle_enter_notify(void *ignored, xcb_connection_t *conn,
313 xcb_enter_notify_event_t *event) {
314 if (event_is_ignored(event->sequence))
315 return 1;
316
317 Client *client = table_get(&by_parent, event->event);
318 if (client == NULL) {
319 return 1; /* user moved cursor to another screen */
320 }
321
322 set_focus(conn, client, false);
323 return 1;
324 }
325 \end{code}
326 \isrc{i3/src/handlers.c:148ff}
327 \end{slide}
328
329
330 \begin{slide}[method=direct]{Events: key\_press }
331 \begin{list}{$\bullet$}{\itemsep=.5em}
332 \item Aktives key grabbing: WM entscheidet, ob Tastendruck weitergeht, also bei der Anwendung ankommt (kann abfangen)
333 \item Passives key grabbing: WM kriegt einen event
334 \end{list}
335
336 \begin{code}
337 uint16_t state_filtered =
338 event->state & ~(xcb_numlock_mask | XCB_MOD_MASK_LOCK);
339 state_filtered &= 0xFF; /* filter mouse buttons */
340 foreach (binding) {
341 if (binding->keycode == event->detail &&
342 binding->mods == state_filtered) {
343 /* do fancy stuff here */
344 break;
345 }
346 }
347 \end{code}
348 \isrc{i3/src/handlers.c:100ff}
349 \end{slide}
350
351 \begin{slide}[method=direct]{Events: key\_press (2), Mode\_switch }
352 \begin{list}{$\bullet$}{\itemsep=.25em}
353 \item \texttt{event->state} enthält nie das Mode\_switch-Bit, Bug in X
354 \item XKB hilft, den korrekten state zu ermitteln
355 \item $\Rightarrow$ Mode\_switch nicht als modifier in \texttt{xcb\_grab\_key} verwendbar
356 \item $\Rightarrow$ wir grabben alle keys aktiv (!) und filtern selbst nach Mode\_switch
357 \end{list}
358
359 \begin{code}
360 /* ... state_filtered is already cleaned */
361 XkbStateRec state;
362 if (XkbGetState(xkbdpy, XkbUseCoreKbd, &state) == Success &&
363 (state.group+1) == 2)
364 state_filtered |= BIND_MODE_SWITCH;
365 foreach (binding)
366 if (binding->keycode == event->detail &&
367 binding->mods == state_filtered) {
368 xcb_allow_events(conn, SyncKeyboard, event->time);
369 return; /* after doing actual stuff, of course */
370 }
371 xcb_allow_events(conn, ReplayKeyboard, event->time);
372 \end{code}
373 \isrc{i3/src/handlers.c:100ff}
374 \end{slide}
375
376
377 \begin{slide}[method=direct]{Umlaute und Sonderzeichen}
378 \includegraphics[width=.5\textwidth]{xft.eps}
379 \begin{list}{$\bullet$}{\itemsep=.1em}
380 \item Verschiedene APIs fürs Rendern von Text: X Core Fonts und xft
381 \item xft = X FreeType, antialiased fonts, Pango, GTK
382 \item Problem mit X Core Fonts: keine Sonderzeichen
383 \item …oder? \texttt{misc-fixed-*-iso10646}, also X Core Fonts mit Universal Character Set (= Unicode-Zeichen). Nicht 100\% vollständig
384 \item urxvt: benutzt beide APIs, pro Glyph unterschiedlich
385 \item Trend geht leider zu fontconfig/xft :-(
386 \end{list}
387 \end{slide}
388
389 \begin{slide}[method=direct]{Umlaute und Sonderzeichen (2)}
390 \begin{list}{$\bullet$}{\itemsep=.5em}
391 \item X hat eigenes Encoding: Compound Text
392 \item Früher ICCCM (Compound text, z.B. Atom WM\_NAME)\\
393 ICCCM = Inter-Client Communication Conventions Manual
394 \item heute EWMH (UTF-8, z.B. Atom \_NET\_WM\_NAME)\\
395 EWMH = Extended Window Manager Hints (= NetWM)
396 \item XImageText16 (bzw xcb\_image\_text\_16) erwartet UCS-2\\
397 $\Rightarrow$ \texttt{iconv\_open(UCS2\_BE, UTF-8)}
398 \end{list}
399 \isrc{i3/src/util.c:191ff, i3/src/handlers.c:663ff}
400 \end{slide}
401
402
403 \begin{slide}[method=direct]{Colorpixel}
404 \begin{list}{$\bullet$}{\itemsep=.5em}
405 \item Heutzutage: TrueColor. Früher: 8 bit o.ä.
406 \item Colormaps: Geben an welche Farben die Hardware kann
407 \item Colorpixel: Ein Wert aus der Colormap, der der gewünschten Farbe am nähesten kommt
408 \item Bei TrueColor: \texttt{return (red << 16) + (green << 8) + blue;}
409 \item Alles andere: Round-Trip zum X-Server:
410 \end{list}
411 \begin{code}
412 #define RGB_8_TO_16(i) (65535 * ((i) & 0xFF) / 255)
413 xcb_alloc_color_reply_t *reply;
414 reply = xcb_alloc_color_reply(conn, xcb_alloc_color(conn,
415 root_screen->default_colormap, RGB_8_TO_16(red),
416 RGB_8_TO_16(green), RGB_8_TO_16(blue)), NULL);
417 if (!reply)
418 die("Could not allocate color\n");
419 return reply->pixel;
420 \end{code}
421 \isrc{i3/src/xcb.c:76ff}
422 \end{slide}
423
424 \begin{slide}[method=direct]{Hints}
425 \begin{list}{$\bullet$}{\itemsep=.5em}
426 \item NetWM
427 \begin{description}
428 \item[NET\_WM\_WINDOW\_TYPE] dock, dialog, utility, toolbar, splashscreen
429 \item[NET\_WM\_NAME] Fenstertitel (UTF-8), auch auf dem root-Fenster
430 \item[NET\_WM\_STRUT\_PARTIAL] Reservierter Bereich am Bildschirmrand (Docks), z.B. für dzen2
431 \end{description}
432 \item ICCCM
433 \begin{description}
434 \item[WM\_NAME] Fenstertitel (Compound Text)
435 \item[WM\_TRANSIENT\_FOR] Zugehöriges, "`temporäres"' Fenster für Anwendung X ($\Rightarrow$ floating)
436 \item[WM\_CLASS] Fensterklasse (z.B. "`urxvt"'), praktisch zum identifizieren
437 \item[WM\_NORMAL\_HINTS] (Size hints), beinhaltet Aspect Ratio (mplayer!), minimale und maximale Größe
438 \end{description}
439 \end{list}
440 \end{slide}
441
442 \begin{slide}[method=direct]{Hints (2)}
443 \begin{code}
444 int handle_transient_for(void *data, xcb_connection_t *conn,
445 uint8_t state, xcb_window_t window,
446 xcb_atom_t name, xcb_get_property_reply_t *reply)
447 {
448 xcb_window_t transient_for;
449 if (reply != NULL) {
450 if (!xcb_get_wm_transient_for_from_reply(&transient_for, reply)) {
451 LOG("Not transient for any window\n");
452 return 1;
453 }
454 } else {
455 if (!xcb_get_wm_transient_for_reply(conn,
456 xcb_get_wm_transient_for_unchecked(conn, window),
457 &transient_for, NULL)) {
458 LOG("Not transient for any window\n");
459 return 1;
460 }
461 }
462 if (client->floating == FLOATING_AUTO_OFF)
463 toggle_floating_mode(conn, client, true);
464 return 1;
465 }
466 \end{code}
467 \end{slide}
468
469 \begin{slide}[method=direct]{Gotchas}
470 \begin{list}{$\bullet$}{\itemsep=.5em}
471 \item Flushing (\texttt{xcb\_flush(connection);})
472 \item \texttt{WM\_STATE} != \texttt{WM\_STATE\_NORMAL}
473 \item Eventloops / Caching von xcb (GIMP splash screen)
474 \end{list}
475 \end{slide}
476
477
478 \begin{slide}{Zusammenfassung}
479 \begin{list}{$\bullet$}{\itemsep=.5em}
480 \item Bindings aufsetzen, Eventmask konfigurieren
481 \item Events/Hints abarbeiten
482 \item Decorations zeichnen
483 \end{list}
484 \end{slide}
485
486 \begin{slide}{Lust bekommen?}
487 \begin{list}{$\bullet$}{\itemsep=1em}
488 \item git clone \url{git://code.stapelberg.de/i3}
489 \item development branch: \texttt{git checkout --track -b next origin/next}
490 \item Debian: \texttt{apt-get install i3-wm/unstable}
491 \item non-Debian: \texttt{cd i3; cat DEPENDS; make \&\& sudo make install}
492 \item in \~{}/.xsession: \texttt{exec /usr/bin/i3}
493 \item Siehe manpage \texttt{i3(1)}, user’s guide, how to hack
494 \end{list}
495 \end{slide}
496
497 \begin{slide}{exit(0);}
498 \begin{list}{$\bullet$}{\itemsep=1em}
499 \item git-webinterface: \url{http://code.stapelberg.de/git/i3}
500 \item Website: \url{http://i3wm.org}
501 \item IRC: \#i3 auf irc.twice-irc.de
502 \item xcb: \url{http://xcb.freedesktop.org/}
503 \item 50-Zeilen-WM: \url{http://incise.org/tinywm.html}
504 \item „Why X is not our ideal window system”: \url{http://www.std.org/~msm/common/WhyX.pdf}
505 \item …noch Fragen?
506 \end{list}
507 \end{slide}
508
509 \end{document}
0 %!PS-Adobe-2.0 EPSF-2.0
1 %%Title: /home/michael/GPN-2009-06-27/reparenting.dia
2 %%Creator: Dia v0.96.1
3 %%CreationDate: Sat Jun 20 18:53:49 2009
4 %%For: michael
5 %%Orientation: Portrait
6 %%Magnification: 1.0000
7 %%BoundingBox: 0 0 793 295
8 %%BeginSetup
9 %%EndSetup
10 %%EndComments
11 %%BeginProlog
12 [ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
13 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
14 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
15 /.notdef /.notdef /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright
16 /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash /zero /one
17 /two /three /four /five /six /seven /eight /nine /colon /semicolon
18 /less /equal /greater /question /at /A /B /C /D /E
19 /F /G /H /I /J /K /L /M /N /O
20 /P /Q /R /S /T /U /V /W /X /Y
21 /Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c
22 /d /e /f /g /h /i /j /k /l /m
23 /n /o /p /q /r /s /t /u /v /w
24 /x /y /z /braceleft /bar /braceright /asciitilde /.notdef /.notdef /.notdef
25 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
26 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
27 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
28 /space /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright
29 /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron /degree /plusminus /twosuperior /threesuperior
30 /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf
31 /threequarters /questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
32 /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde
33 /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex
34 /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring
35 /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
36 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave
37 /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] /isolatin1encoding exch def
38 /cp {closepath} bind def
39 /c {curveto} bind def
40 /f {fill} bind def
41 /a {arc} bind def
42 /ef {eofill} bind def
43 /ex {exch} bind def
44 /gr {grestore} bind def
45 /gs {gsave} bind def
46 /sa {save} bind def
47 /rs {restore} bind def
48 /l {lineto} bind def
49 /m {moveto} bind def
50 /rm {rmoveto} bind def
51 /n {newpath} bind def
52 /s {stroke} bind def
53 /sh {show} bind def
54 /slc {setlinecap} bind def
55 /slj {setlinejoin} bind def
56 /slw {setlinewidth} bind def
57 /srgb {setrgbcolor} bind def
58 /rot {rotate} bind def
59 /sc {scale} bind def
60 /sd {setdash} bind def
61 /ff {findfont} bind def
62 /sf {setfont} bind def
63 /scf {scalefont} bind def
64 /sw {stringwidth pop} bind def
65 /tr {translate} bind def
66
67 /ellipsedict 8 dict def
68 ellipsedict /mtrx matrix put
69 /ellipse
70 { ellipsedict begin
71 /endangle exch def
72 /startangle exch def
73 /yrad exch def
74 /xrad exch def
75 /y exch def
76 /x exch def /savematrix mtrx currentmatrix def
77 x y tr xrad yrad sc
78 0 0 1 startangle endangle arc
79 savematrix setmatrix
80 end
81 } def
82
83 /mergeprocs {
84 dup length
85 3 -1 roll
86 dup
87 length
88 dup
89 5 1 roll
90 3 -1 roll
91 add
92 array cvx
93 dup
94 3 -1 roll
95 0 exch
96 putinterval
97 dup
98 4 2 roll
99 putinterval
100 } bind def
101 /dpi_x 300 def
102 /dpi_y 300 def
103 /conicto {
104 /to_y exch def
105 /to_x exch def
106 /conic_cntrl_y exch def
107 /conic_cntrl_x exch def
108 currentpoint
109 /p0_y exch def
110 /p0_x exch def
111 /p1_x p0_x conic_cntrl_x p0_x sub 2 3 div mul add def
112 /p1_y p0_y conic_cntrl_y p0_y sub 2 3 div mul add def
113 /p2_x p1_x to_x p0_x sub 1 3 div mul add def
114 /p2_y p1_y to_y p0_y sub 1 3 div mul add def
115 p1_x p1_y p2_x p2_y to_x to_y curveto
116 } bind def
117 /start_ol { gsave 1.1 dpi_x div dup scale} bind def
118 /end_ol { closepath fill grestore } bind def
119 28.346000 -28.346000 scale
120 -15.600000 -20.279125 translate
121 %%EndProlog
122
123
124 0.100000 slw
125 [0.200000] 0 sd
126 [0.200000] 0 sd
127 0 slj
128 1.000000 1.000000 1.000000 srgb
129 n 16.850000 12.250000 m 16.850000 18.000000 l 26.050000 18.000000 l 26.050000 12.250000 l f
130 n 16.850000 12.250000 m 16.850000 12.250000 0.000000 0.000000 180.000000 270.000000 ellipse f
131 n 26.050000 12.250000 m 26.050000 12.250000 0.000000 0.000000 270.000000 360.000000 ellipse f
132 n 16.850000 12.250000 m 16.850000 18.000000 l 26.050000 18.000000 l 26.050000 12.250000 l f
133 n 16.850000 18.000000 m 16.850000 18.000000 0.000000 0.000000 90.000000 180.000000 ellipse f
134 n 26.050000 18.000000 m 26.050000 18.000000 0.000000 0.000000 0.000000 90.000000 ellipse f
135 0.000000 0.000000 0.000000 srgb
136 n 16.850000 12.250000 m 26.050000 12.250000 l s
137 n 16.850000 18.000000 m 26.050000 18.000000 l s
138 n 16.850000 12.250000 0.000000 0.000000 180.000000 270.000000 ellipse s
139 n 26.050000 12.250000 0.000000 0.000000 270.000000 360.000000 ellipse s
140 n 16.850000 12.250000 m 16.850000 18.000000 l s
141 n 26.050000 12.250000 m 26.050000 18.000000 l s
142 n 16.850000 18.000000 0.000000 0.000000 90.000000 180.000000 ellipse s
143 n 26.050000 18.000000 0.000000 0.000000 0.000000 90.000000 ellipse s
144 gsave 18.550000 15.375000 translate 0.035278 -0.035278 scale
145 start_ol
146 640 4800 moveto
147 1524 4800 lineto
148 3648 784 lineto
149 3648 4800 lineto
150 4288 4800 lineto
151 4288 0 lineto
152 3404 0 lineto
153 1280 4016 lineto
154 1280 0 lineto
155 640 0 lineto
156 640 4800 lineto
157 end_ol grestore
158 gsave 19.204381 15.375000 translate 0.035278 -0.035278 scale
159 start_ol
160 3712 1944 moveto
161 3712 1664 lineto
162 1024 1664 lineto
163 1062 1070 1389 759 conicto
164 1716 448 2299 448 conicto
165 2637 448 2954 528 conicto
166 3272 608 3584 768 conicto
167 3584 192 lineto
168 3266 67 2931 1 conicto
169 2597 -64 2253 -64 conicto
170 1391 -64 887 437 conicto
171 384 938 384 1792 conicto
172 384 2675 860 3193 conicto
173 1336 3712 2144 3712 conicto
174 2869 3712 3290 3236 conicto
175 3712 2761 3712 1944 conicto
176 3136 2112 moveto
177 3130 2608 2866 2904 conicto
178 2603 3200 2169 3200 conicto
179 1678 3200 1383 2914 conicto
180 1088 2628 1043 2109 conicto
181 3136 2112 lineto
182 end_ol grestore
183 gsave 19.741377 15.375000 translate 0.035278 -0.035278 scale
184 start_ol
185 576 1433 moveto
186 576 3584 lineto
187 1152 3584 lineto
188 1152 1455 lineto
189 1152 952 1354 700 conicto
190 1556 448 1960 448 conicto
191 2445 448 2726 749 conicto
192 3008 1050 3008 1569 conicto
193 3008 3584 lineto
194 3584 3584 lineto
195 3584 0 lineto
196 3008 0 lineto
197 3008 576 lineto
198 2792 251 2506 93 conicto
199 2221 -64 1844 -64 conicto
200 1221 -64 898 317 conicto
201 576 699 576 1433 conicto
202 end_ol grestore
203 gsave 20.295853 15.375000 translate 0.035278 -0.035278 scale
204 start_ol
205 3712 1944 moveto
206 3712 1664 lineto
207 1024 1664 lineto
208 1062 1070 1389 759 conicto
209 1716 448 2299 448 conicto
210 2637 448 2954 528 conicto
211 3272 608 3584 768 conicto
212 3584 192 lineto
213 3266 67 2931 1 conicto
214 2597 -64 2253 -64 conicto
215 1391 -64 887 437 conicto
216 384 938 384 1792 conicto
217 384 2675 860 3193 conicto
218 1336 3712 2144 3712 conicto
219 2869 3712 3290 3236 conicto
220 3712 2761 3712 1944 conicto
221 3136 2112 moveto
222 3130 2608 2866 2904 conicto
223 2603 3200 2169 3200 conicto
224 1678 3200 1383 2914 conicto
225 1088 2628 1043 2109 conicto
226 3136 2112 lineto
227 end_ol grestore
228 gsave 20.832850 15.375000 translate 0.035278 -0.035278 scale
229 start_ol
230 2944 3520 moveto
231 2944 2944 lineto
232 2690 3072 2417 3136 conicto
233 2144 3200 1851 3200 conicto
234 1406 3200 1183 3066 conicto
235 960 2932 960 2664 conicto
236 960 2459 1123 2342 conicto
237 1286 2226 1778 2121 conicto
238 1988 2076 lineto
239 2611 1942 2873 1697 conicto
240 3136 1453 3136 1016 conicto
241 3136 517 2739 226 conicto
242 2342 -64 1647 -64 conicto
243 1358 -64 1044 -16 conicto
244 731 32 384 128 conicto
245 384 768 lineto
246 717 608 1040 528 conicto
247 1363 448 1679 448 conicto
248 2103 448 2331 588 conicto
249 2560 728 2560 982 conicto
250 2560 1218 2392 1343 conicto
251 2224 1469 1655 1585 conicto
252 1442 1633 lineto
253 882 1749 633 1989 conicto
254 384 2229 384 2648 conicto
255 384 3158 748 3435 conicto
256 1112 3712 1781 3712 conicto
257 2112 3712 2404 3664 conicto
258 2697 3616 2944 3520 conicto
259 end_ol grestore
260 gsave 21.287421 15.375000 translate 0.035278 -0.035278 scale
261 start_ol
262 end_ol grestore
263 gsave 21.564654 15.375000 translate 0.035278 -0.035278 scale
264 start_ol
265 640 4800 moveto
266 3392 4800 lineto
267 3392 4288 lineto
268 1280 4288 lineto
269 1280 2816 lineto
270 3200 2816 lineto
271 3200 2304 lineto
272 1280 2304 lineto
273 1280 0 lineto
274 640 0 lineto
275 640 4800 lineto
276 end_ol grestore
277 gsave 22.019225 15.375000 translate 0.035278 -0.035278 scale
278 start_ol
279 3712 1944 moveto
280 3712 1664 lineto
281 1024 1664 lineto
282 1062 1070 1389 759 conicto
283 1716 448 2299 448 conicto
284 2637 448 2954 528 conicto
285 3272 608 3584 768 conicto
286 3584 192 lineto
287 3266 67 2931 1 conicto
288 2597 -64 2253 -64 conicto
289 1391 -64 887 437 conicto
290 384 938 384 1792 conicto
291 384 2675 860 3193 conicto
292 1336 3712 2144 3712 conicto
293 2869 3712 3290 3236 conicto
294 3712 2761 3712 1944 conicto
295 3136 2112 moveto
296 3130 2608 2866 2904 conicto
297 2603 3200 2169 3200 conicto
298 1678 3200 1383 2914 conicto
299 1088 2628 1043 2109 conicto
300 3136 2112 lineto
301 end_ol grestore
302 gsave 22.556222 15.375000 translate 0.035278 -0.035278 scale
303 start_ol
304 3584 2195 moveto
305 3584 0 lineto
306 3008 0 lineto
307 3008 2176 lineto
308 3008 2690 2806 2945 conicto
309 2604 3200 2199 3200 conicto
310 1713 3200 1432 2893 conicto
311 1152 2586 1152 2056 conicto
312 1152 0 lineto
313 576 0 lineto
314 576 3584 lineto
315 1152 3584 lineto
316 1152 3072 lineto
317 1365 3394 1654 3553 conicto
318 1943 3712 2321 3712 conicto
319 2945 3712 3264 3327 conicto
320 3584 2942 3584 2195 conicto
321 end_ol grestore
322 gsave 23.110697 15.375000 translate 0.035278 -0.035278 scale
323 start_ol
324 2944 3520 moveto
325 2944 2944 lineto
326 2690 3072 2417 3136 conicto
327 2144 3200 1851 3200 conicto
328 1406 3200 1183 3066 conicto
329 960 2932 960 2664 conicto
330 960 2459 1123 2342 conicto
331 1286 2226 1778 2121 conicto
332 1988 2076 lineto
333 2611 1942 2873 1697 conicto
334 3136 1453 3136 1016 conicto
335 3136 517 2739 226 conicto
336 2342 -64 1647 -64 conicto
337 1358 -64 1044 -16 conicto
338 731 32 384 128 conicto
339 384 768 lineto
340 717 608 1040 528 conicto
341 1363 448 1679 448 conicto
342 2103 448 2331 588 conicto
343 2560 728 2560 982 conicto
344 2560 1218 2392 1343 conicto
345 2224 1469 1655 1585 conicto
346 1442 1633 lineto
347 882 1749 633 1989 conicto
348 384 2229 384 2648 conicto
349 384 3158 748 3435 conicto
350 1112 3712 1781 3712 conicto
351 2112 3712 2404 3664 conicto
352 2697 3616 2944 3520 conicto
353 end_ol grestore
354 gsave 23.565268 15.375000 translate 0.035278 -0.035278 scale
355 start_ol
356 1152 4608 moveto
357 1152 3584 lineto
358 2368 3584 lineto
359 2368 3136 lineto
360 1152 3136 lineto
361 1152 1197 lineto
362 1152 761 1272 636 conicto
363 1393 512 1762 512 conicto
364 2368 512 lineto
365 2368 0 lineto
366 1762 0 lineto
367 1088 0 832 258 conicto
368 576 516 576 1197 conicto
369 576 3136 lineto
370 128 3136 lineto
371 128 3584 lineto
372 576 3584 lineto
373 576 4608 lineto
374 1152 4608 lineto
375 end_ol grestore
376 gsave 23.907440 15.375000 translate 0.035278 -0.035278 scale
377 start_ol
378 3712 1944 moveto
379 3712 1664 lineto
380 1024 1664 lineto
381 1062 1070 1389 759 conicto
382 1716 448 2299 448 conicto
383 2637 448 2954 528 conicto
384 3272 608 3584 768 conicto
385 3584 192 lineto
386 3266 67 2931 1 conicto
387 2597 -64 2253 -64 conicto
388 1391 -64 887 437 conicto
389 384 938 384 1792 conicto
390 384 2675 860 3193 conicto
391 1336 3712 2144 3712 conicto
392 2869 3712 3290 3236 conicto
393 3712 2761 3712 1944 conicto
394 3136 2112 moveto
395 3130 2608 2866 2904 conicto
396 2603 3200 2169 3200 conicto
397 1678 3200 1383 2914 conicto
398 1088 2628 1043 2109 conicto
399 3136 2112 lineto
400 end_ol grestore
401 gsave 24.444437 15.375000 translate 0.035278 -0.035278 scale
402 start_ol
403 2688 3008 moveto
404 2587 3107 2468 3153 conicto
405 2349 3200 2205 3200 conicto
406 1697 3200 1424 2868 conicto
407 1152 2537 1152 1916 conicto
408 1152 0 lineto
409 576 0 lineto
410 576 3584 lineto
411 1152 3584 lineto
412 1152 3072 lineto
413 1341 3397 1644 3554 conicto
414 1948 3712 2381 3712 conicto
415 2443 3712 2518 3696 conicto
416 2593 3680 2685 3648 conicto
417 2688 3008 lineto
418 end_ol grestore
419 gsave 15.600000 11.550000 translate 0.035278 -0.035278 scale
420 start_ol
421 1344 3328 moveto
422 1084 2828 958 2338 conicto
423 832 1849 832 1346 conicto
424 832 844 959 351 conicto
425 1086 -142 1344 -640 conicto
426 1034 -640 lineto
427 708 -129 546 365 conicto
428 384 859 384 1346 conicto
429 384 1831 545 2323 conicto
430 706 2815 1034 3328 conicto
431 1344 3328 lineto
432 end_ol grestore
433 gsave 15.827285 11.550000 translate 0.035278 -0.035278 scale
434 start_ol
435 833 320 moveto
436 2385 320 lineto
437 2385 0 lineto
438 320 0 lineto
439 320 320 lineto
440 570 585 1001 1030 conicto
441 1432 1476 1542 1605 conicto
442 1753 1848 1836 2015 conicto
443 1920 2183 1920 2346 conicto
444 1920 2610 1736 2777 conicto
445 1552 2944 1258 2944 conicto
446 1048 2944 816 2864 conicto
447 584 2785 320 2624 conicto
448 320 3072 lineto
449 589 3167 822 3215 conicto
450 1056 3264 1249 3264 conicto
451 1760 3264 2064 3011 conicto
452 2368 2758 2368 2335 conicto
453 2368 2134 2292 1954 conicto
454 2216 1775 2016 1530 conicto
455 1961 1467 1665 1165 conicto
456 1370 863 833 320 conicto
457 end_ol grestore
458 gsave 16.196933 11.550000 translate 0.035278 -0.035278 scale
459 start_ol
460 1439 2944 moveto
461 1105 2944 936 2608 conicto
462 768 2273 768 1599 conicto
463 768 927 936 591 conicto
464 1105 256 1439 256 conicto
465 1775 256 1943 591 conicto
466 2112 927 2112 1599 conicto
467 2112 2273 1943 2608 conicto
468 1775 2944 1439 2944 conicto
469 1440 3264 moveto
470 1985 3264 2272 2837 conicto
471 2560 2411 2560 1599 conicto
472 2560 789 2272 362 conicto
473 1985 -64 1440 -64 conicto
474 895 -64 607 362 conicto
475 320 789 320 1599 conicto
476 320 2411 607 2837 conicto
477 895 3264 1440 3264 conicto
478 end_ol grestore
479 gsave 16.566581 11.550000 translate 0.035278 -0.035278 scale
480 start_ol
481 512 576 moveto
482 960 576 lineto
483 960 196 lineto
484 576 -512 lineto
485 320 -512 lineto
486 512 196 lineto
487 512 576 lineto
488 end_ol grestore
489 gsave 16.751401 11.550000 translate 0.035278 -0.035278 scale
490 start_ol
491 end_ol grestore
492 gsave 16.936220 11.550000 translate 0.035278 -0.035278 scale
493 start_ol
494 833 320 moveto
495 2385 320 lineto
496 2385 0 lineto
497 320 0 lineto
498 320 320 lineto
499 570 585 1001 1030 conicto
500 1432 1476 1542 1605 conicto
501 1753 1848 1836 2015 conicto
502 1920 2183 1920 2346 conicto
503 1920 2610 1736 2777 conicto
504 1552 2944 1258 2944 conicto
505 1048 2944 816 2864 conicto
506 584 2785 320 2624 conicto
507 320 3072 lineto
508 589 3167 822 3215 conicto
509 1056 3264 1249 3264 conicto
510 1760 3264 2064 3011 conicto
511 2368 2758 2368 2335 conicto
512 2368 2134 2292 1954 conicto
513 2216 1775 2016 1530 conicto
514 1961 1467 1665 1165 conicto
515 1370 863 833 320 conicto
516 end_ol grestore
517 gsave 17.305868 11.550000 translate 0.035278 -0.035278 scale
518 start_ol
519 1439 2944 moveto
520 1105 2944 936 2608 conicto
521 768 2273 768 1599 conicto
522 768 927 936 591 conicto
523 1105 256 1439 256 conicto
524 1775 256 1943 591 conicto
525 2112 927 2112 1599 conicto
526 2112 2273 1943 2608 conicto
527 1775 2944 1439 2944 conicto
528 1440 3264 moveto
529 1985 3264 2272 2837 conicto
530 2560 2411 2560 1599 conicto
531 2560 789 2272 362 conicto
532 1985 -64 1440 -64 conicto
533 895 -64 607 362 conicto
534 320 789 320 1599 conicto
535 320 2411 607 2837 conicto
536 895 3264 1440 3264 conicto
537 end_ol grestore
538 gsave 17.675516 11.550000 translate 0.035278 -0.035278 scale
539 start_ol
540 384 3328 moveto
541 694 3328 lineto
542 1020 2815 1182 2323 conicto
543 1344 1831 1344 1346 conicto
544 1344 859 1182 365 conicto
545 1020 -129 694 -640 conicto
546 384 -640 lineto
547 642 -142 769 351 conicto
548 896 844 896 1346 conicto
549 896 1849 769 2338 conicto
550 642 2828 384 3328 conicto
551 end_ol grestore
552 gsave 20.350000 19.000000 translate 0.035278 -0.035278 scale
553 start_ol
554 833 320 moveto
555 2385 320 lineto
556 2385 0 lineto
557 320 0 lineto
558 320 320 lineto
559 570 585 1001 1030 conicto
560 1432 1476 1542 1605 conicto
561 1753 1848 1836 2015 conicto
562 1920 2183 1920 2346 conicto
563 1920 2610 1736 2777 conicto
564 1552 2944 1258 2944 conicto
565 1048 2944 816 2864 conicto
566 584 2785 320 2624 conicto
567 320 3072 lineto
568 589 3167 822 3215 conicto
569 1056 3264 1249 3264 conicto
570 1760 3264 2064 3011 conicto
571 2368 2758 2368 2335 conicto
572 2368 2134 2292 1954 conicto
573 2216 1775 2016 1530 conicto
574 1961 1467 1665 1165 conicto
575 1370 863 833 320 conicto
576 end_ol grestore
577 gsave 20.719648 19.000000 translate 0.035278 -0.035278 scale
578 start_ol
579 1439 2944 moveto
580 1105 2944 936 2608 conicto
581 768 2273 768 1599 conicto
582 768 927 936 591 conicto
583 1105 256 1439 256 conicto
584 1775 256 1943 591 conicto
585 2112 927 2112 1599 conicto
586 2112 2273 1943 2608 conicto
587 1775 2944 1439 2944 conicto
588 1440 3264 moveto
589 1985 3264 2272 2837 conicto
590 2560 2411 2560 1599 conicto
591 2560 789 2272 362 conicto
592 1985 -64 1440 -64 conicto
593 895 -64 607 362 conicto
594 320 789 320 1599 conicto
595 320 2411 607 2837 conicto
596 895 3264 1440 3264 conicto
597 end_ol grestore
598 gsave 21.089295 19.000000 translate 0.035278 -0.035278 scale
599 start_ol
600 1439 2944 moveto
601 1105 2944 936 2608 conicto
602 768 2273 768 1599 conicto
603 768 927 936 591 conicto
604 1105 256 1439 256 conicto
605 1775 256 1943 591 conicto
606 2112 927 2112 1599 conicto
607 2112 2273 1943 2608 conicto
608 1775 2944 1439 2944 conicto
609 1440 3264 moveto
610 1985 3264 2272 2837 conicto
611 2560 2411 2560 1599 conicto
612 2560 789 2272 362 conicto
613 1985 -64 1440 -64 conicto
614 895 -64 607 362 conicto
615 320 789 320 1599 conicto
616 320 2411 607 2837 conicto
617 895 3264 1440 3264 conicto
618 end_ol grestore
619 gsave 21.458943 19.000000 translate 0.035278 -0.035278 scale
620 start_ol
621 768 384 moveto
622 768 -896 lineto
623 384 -896 lineto
624 384 2432 lineto
625 768 2432 lineto
626 768 2048 lineto
627 895 2275 1089 2385 conicto
628 1283 2496 1553 2496 conicto
629 2001 2496 2280 2143 conicto
630 2560 1791 2560 1216 conicto
631 2560 641 2280 288 conicto
632 2001 -64 1553 -64 conicto
633 1283 -64 1089 46 conicto
634 895 157 768 384 conicto
635 2112 1216 moveto
636 2112 1665 1932 1920 conicto
637 1753 2176 1440 2176 conicto
638 1127 2176 947 1920 conicto
639 768 1665 768 1216 conicto
640 768 767 947 511 conicto
641 1127 256 1440 256 conicto
642 1753 256 1932 511 conicto
643 2112 767 2112 1216 conicto
644 end_ol grestore
645 gsave 21.828591 19.000000 translate 0.035278 -0.035278 scale
646 start_ol
647 2432 2432 moveto
648 1550 1249 lineto
649 2496 0 lineto
650 2016 0 lineto
651 1295 955 lineto
652 594 0 lineto
653 128 0 lineto
654 1059 1272 lineto
655 192 2432 lineto
656 665 2432 lineto
657 1312 1566 lineto
658 1959 2432 lineto
659 2432 2432 lineto
660 end_ol grestore
661 gsave 26.500000 15.850000 translate 0.035278 -0.035278 scale
662 start_ol
663 576 320 moveto
664 1280 320 lineto
665 1280 2880 lineto
666 512 2752 lineto
667 512 3072 lineto
668 1289 3200 lineto
669 1728 3200 lineto
670 1728 320 lineto
671 2432 320 lineto
672 2432 0 lineto
673 576 0 lineto
674 576 320 lineto
675 end_ol grestore
676 gsave 26.869648 15.850000 translate 0.035278 -0.035278 scale
677 start_ol
678 448 3200 moveto
679 2176 3200 lineto
680 2176 2880 lineto
681 896 2880 lineto
682 896 2056 lineto
683 990 2084 1084 2098 conicto
684 1178 2112 1273 2112 conicto
685 1807 2112 2119 1818 conicto
686 2432 1525 2432 1024 conicto
687 2432 508 2104 222 conicto
688 1776 -64 1179 -64 conicto
689 974 -64 760 -32 conicto
690 547 0 320 64 conicto
691 320 512 lineto
692 516 383 725 319 conicto
693 934 256 1167 256 conicto
694 1544 256 1764 463 conicto
695 1984 670 1984 1024 conicto
696 1984 1378 1762 1585 conicto
697 1541 1792 1162 1792 conicto
698 985 1792 808 1745 conicto
699 632 1699 448 1600 conicto
700 448 3200 lineto
701 end_ol grestore
702 gsave 27.239295 15.850000 translate 0.035278 -0.035278 scale
703 start_ol
704 1439 2944 moveto
705 1105 2944 936 2608 conicto
706 768 2273 768 1599 conicto
707 768 927 936 591 conicto
708 1105 256 1439 256 conicto
709 1775 256 1943 591 conicto
710 2112 927 2112 1599 conicto
711 2112 2273 1943 2608 conicto
712 1775 2944 1439 2944 conicto
713 1440 3264 moveto
714 1985 3264 2272 2837 conicto
715 2560 2411 2560 1599 conicto
716 2560 789 2272 362 conicto
717 1985 -64 1440 -64 conicto
718 895 -64 607 362 conicto
719 320 789 320 1599 conicto
720 320 2411 607 2837 conicto
721 895 3264 1440 3264 conicto
722 end_ol grestore
723 gsave 27.608943 15.850000 translate 0.035278 -0.035278 scale
724 start_ol
725 768 384 moveto
726 768 -896 lineto
727 384 -896 lineto
728 384 2432 lineto
729 768 2432 lineto
730 768 2048 lineto
731 895 2275 1089 2385 conicto
732 1283 2496 1553 2496 conicto
733 2001 2496 2280 2143 conicto
734 2560 1791 2560 1216 conicto
735 2560 641 2280 288 conicto
736 2001 -64 1553 -64 conicto
737 1283 -64 1089 46 conicto
738 895 157 768 384 conicto
739 2112 1216 moveto
740 2112 1665 1932 1920 conicto
741 1753 2176 1440 2176 conicto
742 1127 2176 947 1920 conicto
743 768 1665 768 1216 conicto
744 768 767 947 511 conicto
745 1127 256 1440 256 conicto
746 1753 256 1932 511 conicto
747 2112 767 2112 1216 conicto
748 end_ol grestore
749 gsave 27.978591 15.850000 translate 0.035278 -0.035278 scale
750 start_ol
751 2432 2432 moveto
752 1550 1249 lineto
753 2496 0 lineto
754 2016 0 lineto
755 1295 955 lineto
756 594 0 lineto
757 128 0 lineto
758 1059 1272 lineto
759 192 2432 lineto
760 665 2432 lineto
761 1312 1566 lineto
762 1959 2432 lineto
763 2432 2432 lineto
764 end_ol grestore
765 0.100000 slw
766 [] 0 sd
767 [] 0 sd
768 0 slj
769 0.678431 0.847059 0.901961 srgb
770 n 30.955000 11.147500 m 30.955000 18.450000 l 41.200000 18.450000 l 41.200000 11.147500 l f
771 n 30.955000 11.147500 m 30.955000 11.147500 0.000000 0.000000 180.000000 270.000000 ellipse f
772 n 41.200000 11.147500 m 41.200000 11.147500 0.000000 0.000000 270.000000 360.000000 ellipse f
773 n 30.955000 11.147500 m 30.955000 18.450000 l 41.200000 18.450000 l 41.200000 11.147500 l f
774 n 30.955000 18.450000 m 30.955000 18.450000 0.000000 0.000000 90.000000 180.000000 ellipse f
775 n 41.200000 18.450000 m 41.200000 18.450000 0.000000 0.000000 0.000000 90.000000 ellipse f
776 0.000000 0.000000 0.000000 srgb
777 n 30.955000 11.147500 m 41.200000 11.147500 l s
778 n 30.955000 18.450000 m 41.200000 18.450000 l s
779 n 30.955000 11.147500 0.000000 0.000000 180.000000 270.000000 ellipse s
780 n 41.200000 11.147500 0.000000 0.000000 270.000000 360.000000 ellipse s
781 n 30.955000 11.147500 m 30.955000 18.450000 l s
782 n 41.200000 11.147500 m 41.200000 18.450000 l s
783 n 30.955000 18.450000 0.000000 0.000000 90.000000 180.000000 ellipse s
784 n 41.200000 18.450000 0.000000 0.000000 0.000000 90.000000 ellipse s
785 gsave 29.705000 10.447500 translate 0.035278 -0.035278 scale
786 start_ol
787 1344 3328 moveto
788 1084 2828 958 2338 conicto
789 832 1849 832 1346 conicto
790 832 844 959 351 conicto
791 1086 -142 1344 -640 conicto
792 1034 -640 lineto
793 708 -129 546 365 conicto
794 384 859 384 1346 conicto
795 384 1831 545 2323 conicto
796 706 2815 1034 3328 conicto
797 1344 3328 lineto
798 end_ol grestore
799 gsave 29.932285 10.447500 translate 0.035278 -0.035278 scale
800 start_ol
801 833 320 moveto
802 2385 320 lineto
803 2385 0 lineto
804 320 0 lineto
805 320 320 lineto
806 570 585 1001 1030 conicto
807 1432 1476 1542 1605 conicto
808 1753 1848 1836 2015 conicto
809 1920 2183 1920 2346 conicto
810 1920 2610 1736 2777 conicto
811 1552 2944 1258 2944 conicto
812 1048 2944 816 2864 conicto
813 584 2785 320 2624 conicto
814 320 3072 lineto
815 589 3167 822 3215 conicto
816 1056 3264 1249 3264 conicto
817 1760 3264 2064 3011 conicto
818 2368 2758 2368 2335 conicto
819 2368 2134 2292 1954 conicto
820 2216 1775 2016 1530 conicto
821 1961 1467 1665 1165 conicto
822 1370 863 833 320 conicto
823 end_ol grestore
824 gsave 30.301933 10.447500 translate 0.035278 -0.035278 scale
825 start_ol
826 1439 2944 moveto
827 1105 2944 936 2608 conicto
828 768 2273 768 1599 conicto
829 768 927 936 591 conicto
830 1105 256 1439 256 conicto
831 1775 256 1943 591 conicto
832 2112 927 2112 1599 conicto
833 2112 2273 1943 2608 conicto
834 1775 2944 1439 2944 conicto
835 1440 3264 moveto
836 1985 3264 2272 2837 conicto
837 2560 2411 2560 1599 conicto
838 2560 789 2272 362 conicto
839 1985 -64 1440 -64 conicto
840 895 -64 607 362 conicto
841 320 789 320 1599 conicto
842 320 2411 607 2837 conicto
843 895 3264 1440 3264 conicto
844 end_ol grestore
845 gsave 30.671581 10.447500 translate 0.035278 -0.035278 scale
846 start_ol
847 512 576 moveto
848 960 576 lineto
849 960 196 lineto
850 576 -512 lineto
851 320 -512 lineto
852 512 196 lineto
853 512 576 lineto
854 end_ol grestore
855 gsave 30.856401 10.447500 translate 0.035278 -0.035278 scale
856 start_ol
857 end_ol grestore
858 gsave 31.041220 10.447500 translate 0.035278 -0.035278 scale
859 start_ol
860 833 320 moveto
861 2385 320 lineto
862 2385 0 lineto
863 320 0 lineto
864 320 320 lineto
865 570 585 1001 1030 conicto
866 1432 1476 1542 1605 conicto
867 1753 1848 1836 2015 conicto
868 1920 2183 1920 2346 conicto
869 1920 2610 1736 2777 conicto
870 1552 2944 1258 2944 conicto
871 1048 2944 816 2864 conicto
872 584 2785 320 2624 conicto
873 320 3072 lineto
874 589 3167 822 3215 conicto
875 1056 3264 1249 3264 conicto
876 1760 3264 2064 3011 conicto
877 2368 2758 2368 2335 conicto
878 2368 2134 2292 1954 conicto
879 2216 1775 2016 1530 conicto
880 1961 1467 1665 1165 conicto
881 1370 863 833 320 conicto
882 end_ol grestore
883 gsave 31.410868 10.447500 translate 0.035278 -0.035278 scale
884 start_ol
885 1439 2944 moveto
886 1105 2944 936 2608 conicto
887 768 2273 768 1599 conicto
888 768 927 936 591 conicto
889 1105 256 1439 256 conicto
890 1775 256 1943 591 conicto
891 2112 927 2112 1599 conicto
892 2112 2273 1943 2608 conicto
893 1775 2944 1439 2944 conicto
894 1440 3264 moveto
895 1985 3264 2272 2837 conicto
896 2560 2411 2560 1599 conicto
897 2560 789 2272 362 conicto
898 1985 -64 1440 -64 conicto
899 895 -64 607 362 conicto
900 320 789 320 1599 conicto
901 320 2411 607 2837 conicto
902 895 3264 1440 3264 conicto
903 end_ol grestore
904 gsave 31.780516 10.447500 translate 0.035278 -0.035278 scale
905 start_ol
906 384 3328 moveto
907 694 3328 lineto
908 1020 2815 1182 2323 conicto
909 1344 1831 1344 1346 conicto
910 1344 859 1182 365 conicto
911 1020 -129 694 -640 conicto
912 384 -640 lineto
913 642 -142 769 351 conicto
914 896 844 896 1346 conicto
915 896 1849 769 2338 conicto
916 642 2828 384 3328 conicto
917 end_ol grestore
918 gsave 34.505000 19.847500 translate 0.035278 -0.035278 scale
919 start_ol
920 833 320 moveto
921 2385 320 lineto
922 2385 0 lineto
923 320 0 lineto
924 320 320 lineto
925 570 585 1001 1030 conicto
926 1432 1476 1542 1605 conicto
927 1753 1848 1836 2015 conicto
928 1920 2183 1920 2346 conicto
929 1920 2610 1736 2777 conicto
930 1552 2944 1258 2944 conicto
931 1048 2944 816 2864 conicto
932 584 2785 320 2624 conicto
933 320 3072 lineto
934 589 3167 822 3215 conicto
935 1056 3264 1249 3264 conicto
936 1760 3264 2064 3011 conicto
937 2368 2758 2368 2335 conicto
938 2368 2134 2292 1954 conicto
939 2216 1775 2016 1530 conicto
940 1961 1467 1665 1165 conicto
941 1370 863 833 320 conicto
942 end_ol grestore
943 gsave 34.874648 19.847500 translate 0.035278 -0.035278 scale
944 start_ol
945 576 320 moveto
946 1280 320 lineto
947 1280 2880 lineto
948 512 2752 lineto
949 512 3072 lineto
950 1289 3200 lineto
951 1728 3200 lineto
952 1728 320 lineto
953 2432 320 lineto
954 2432 0 lineto
955 576 0 lineto
956 576 320 lineto
957 end_ol grestore
958 gsave 35.244295 19.847500 translate 0.035278 -0.035278 scale
959 start_ol
960 448 3200 moveto
961 2176 3200 lineto
962 2176 2880 lineto
963 896 2880 lineto
964 896 2056 lineto
965 990 2084 1084 2098 conicto
966 1178 2112 1273 2112 conicto
967 1807 2112 2119 1818 conicto
968 2432 1525 2432 1024 conicto
969 2432 508 2104 222 conicto
970 1776 -64 1179 -64 conicto
971 974 -64 760 -32 conicto
972 547 0 320 64 conicto
973 320 512 lineto
974 516 383 725 319 conicto
975 934 256 1167 256 conicto
976 1544 256 1764 463 conicto
977 1984 670 1984 1024 conicto
978 1984 1378 1762 1585 conicto
979 1541 1792 1162 1792 conicto
980 985 1792 808 1745 conicto
981 632 1699 448 1600 conicto
982 448 3200 lineto
983 end_ol grestore
984 gsave 35.613943 19.847500 translate 0.035278 -0.035278 scale
985 start_ol
986 768 384 moveto
987 768 -896 lineto
988 384 -896 lineto
989 384 2432 lineto
990 768 2432 lineto
991 768 2048 lineto
992 895 2275 1089 2385 conicto
993 1283 2496 1553 2496 conicto
994 2001 2496 2280 2143 conicto
995 2560 1791 2560 1216 conicto
996 2560 641 2280 288 conicto
997 2001 -64 1553 -64 conicto
998 1283 -64 1089 46 conicto
999 895 157 768 384 conicto
1000 2112 1216 moveto
1001 2112 1665 1932 1920 conicto
1002 1753 2176 1440 2176 conicto
1003 1127 2176 947 1920 conicto
1004 768 1665 768 1216 conicto
1005 768 767 947 511 conicto
1006 1127 256 1440 256 conicto
1007 1753 256 1932 511 conicto
1008 2112 767 2112 1216 conicto
1009 end_ol grestore
1010 gsave 35.983591 19.847500 translate 0.035278 -0.035278 scale
1011 start_ol
1012 2432 2432 moveto
1013 1550 1249 lineto
1014 2496 0 lineto
1015 2016 0 lineto
1016 1295 955 lineto
1017 594 0 lineto
1018 128 0 lineto
1019 1059 1272 lineto
1020 192 2432 lineto
1021 665 2432 lineto
1022 1312 1566 lineto
1023 1959 2432 lineto
1024 2432 2432 lineto
1025 end_ol grestore
1026 gsave 41.705000 15.497500 translate 0.035278 -0.035278 scale
1027 start_ol
1028 576 320 moveto
1029 1280 320 lineto
1030 1280 2880 lineto
1031 512 2752 lineto
1032 512 3072 lineto
1033 1289 3200 lineto
1034 1728 3200 lineto
1035 1728 320 lineto
1036 2432 320 lineto
1037 2432 0 lineto
1038 576 0 lineto
1039 576 320 lineto
1040 end_ol grestore
1041 gsave 42.074648 15.497500 translate 0.035278 -0.035278 scale
1042 start_ol
1043 1472 1856 moveto
1044 1177 1856 1004 1642 conicto
1045 832 1428 832 1056 conicto
1046 832 686 1004 471 conicto
1047 1177 256 1472 256 conicto
1048 1767 256 1939 471 conicto
1049 2112 686 2112 1056 conicto
1050 2112 1428 1939 1642 conicto
1051 1767 1856 1472 1856 conicto
1052 2368 3136 moveto
1053 2368 2752 lineto
1054 2202 2845 2033 2894 conicto
1055 1864 2944 1698 2944 conicto
1056 1261 2944 1031 2662 conicto
1057 801 2380 768 1810 conicto
1058 895 1987 1087 2081 conicto
1059 1280 2176 1511 2176 conicto
1060 1996 2176 2278 1875 conicto
1061 2560 1574 2560 1056 conicto
1062 2560 549 2264 242 conicto
1063 1969 -64 1478 -64 conicto
1064 915 -64 617 362 conicto
1065 320 789 320 1599 conicto
1066 320 2359 688 2811 conicto
1067 1057 3264 1677 3264 conicto
1068 1844 3264 2014 3232 conicto
1069 2184 3200 2368 3136 conicto
1070 end_ol grestore
1071 gsave 42.444295 15.497500 translate 0.035278 -0.035278 scale
1072 start_ol
1073 1439 2944 moveto
1074 1105 2944 936 2608 conicto
1075 768 2273 768 1599 conicto
1076 768 927 936 591 conicto
1077 1105 256 1439 256 conicto
1078 1775 256 1943 591 conicto
1079 2112 927 2112 1599 conicto
1080 2112 2273 1943 2608 conicto
1081 1775 2944 1439 2944 conicto
1082 1440 3264 moveto
1083 1985 3264 2272 2837 conicto
1084 2560 2411 2560 1599 conicto
1085 2560 789 2272 362 conicto
1086 1985 -64 1440 -64 conicto
1087 895 -64 607 362 conicto
1088 320 789 320 1599 conicto
1089 320 2411 607 2837 conicto
1090 895 3264 1440 3264 conicto
1091 end_ol grestore
1092 gsave 42.813943 15.497500 translate 0.035278 -0.035278 scale
1093 start_ol
1094 768 384 moveto
1095 768 -896 lineto
1096 384 -896 lineto
1097 384 2432 lineto
1098 768 2432 lineto
1099 768 2048 lineto
1100 895 2275 1089 2385 conicto
1101 1283 2496 1553 2496 conicto
1102 2001 2496 2280 2143 conicto
1103 2560 1791 2560 1216 conicto
1104 2560 641 2280 288 conicto
1105 2001 -64 1553 -64 conicto
1106 1283 -64 1089 46 conicto
1107 895 157 768 384 conicto
1108 2112 1216 moveto
1109 2112 1665 1932 1920 conicto
1110 1753 2176 1440 2176 conicto
1111 1127 2176 947 1920 conicto
1112 768 1665 768 1216 conicto
1113 768 767 947 511 conicto
1114 1127 256 1440 256 conicto
1115 1753 256 1932 511 conicto
1116 2112 767 2112 1216 conicto
1117 end_ol grestore
1118 gsave 43.183591 15.497500 translate 0.035278 -0.035278 scale
1119 start_ol
1120 2432 2432 moveto
1121 1550 1249 lineto
1122 2496 0 lineto
1123 2016 0 lineto
1124 1295 955 lineto
1125 594 0 lineto
1126 128 0 lineto
1127 1059 1272 lineto
1128 192 2432 lineto
1129 665 2432 lineto
1130 1312 1566 lineto
1131 1959 2432 lineto
1132 2432 2432 lineto
1133 end_ol grestore
1134 0.100000 slw
1135 [0.200000] 0 sd
1136 [0.200000] 0 sd
1137 0 slj
1138 1.000000 1.000000 1.000000 srgb
1139 n 31.450000 12.300000 m 31.450000 17.900000 l 40.700000 17.900000 l 40.700000 12.300000 l f
1140 n 31.450000 12.300000 m 31.450000 12.300000 0.000000 0.000000 180.000000 270.000000 ellipse f
1141 n 40.700000 12.300000 m 40.700000 12.300000 0.000000 0.000000 270.000000 360.000000 ellipse f
1142 n 31.450000 12.300000 m 31.450000 17.900000 l 40.700000 17.900000 l 40.700000 12.300000 l f
1143 n 31.450000 17.900000 m 31.450000 17.900000 0.000000 0.000000 90.000000 180.000000 ellipse f
1144 n 40.700000 17.900000 m 40.700000 17.900000 0.000000 0.000000 0.000000 90.000000 ellipse f
1145 0.000000 0.000000 0.000000 srgb
1146 n 31.450000 12.300000 m 40.700000 12.300000 l s
1147 n 31.450000 17.900000 m 40.700000 17.900000 l s
1148 n 31.450000 12.300000 0.000000 0.000000 180.000000 270.000000 ellipse s
1149 n 40.700000 12.300000 0.000000 0.000000 270.000000 360.000000 ellipse s
1150 n 31.450000 12.300000 m 31.450000 17.900000 l s
1151 n 40.700000 12.300000 m 40.700000 17.900000 l s
1152 n 31.450000 17.900000 0.000000 0.000000 90.000000 180.000000 ellipse s
1153 n 40.700000 17.900000 0.000000 0.000000 0.000000 90.000000 ellipse s
1154 gsave 32.355000 14.722500 translate 0.035278 -0.035278 scale
1155 start_ol
1156 640 4800 moveto
1157 1524 4800 lineto
1158 3648 784 lineto
1159 3648 4800 lineto
1160 4288 4800 lineto
1161 4288 0 lineto
1162 3404 0 lineto
1163 1280 4016 lineto
1164 1280 0 lineto
1165 640 0 lineto
1166 640 4800 lineto
1167 end_ol grestore
1168 gsave 33.009381 14.722500 translate 0.035278 -0.035278 scale
1169 start_ol
1170 3712 1944 moveto
1171 3712 1664 lineto
1172 1024 1664 lineto
1173 1062 1070 1389 759 conicto
1174 1716 448 2299 448 conicto
1175 2637 448 2954 528 conicto
1176 3272 608 3584 768 conicto
1177 3584 192 lineto
1178 3266 67 2931 1 conicto
1179 2597 -64 2253 -64 conicto
1180 1391 -64 887 437 conicto
1181 384 938 384 1792 conicto
1182 384 2675 860 3193 conicto
1183 1336 3712 2144 3712 conicto
1184 2869 3712 3290 3236 conicto
1185 3712 2761 3712 1944 conicto
1186 3136 2112 moveto
1187 3130 2608 2866 2904 conicto
1188 2603 3200 2169 3200 conicto
1189 1678 3200 1383 2914 conicto
1190 1088 2628 1043 2109 conicto
1191 3136 2112 lineto
1192 end_ol grestore
1193 gsave 33.546377 14.722500 translate 0.035278 -0.035278 scale
1194 start_ol
1195 576 1433 moveto
1196 576 3584 lineto
1197 1152 3584 lineto
1198 1152 1455 lineto
1199 1152 952 1354 700 conicto
1200 1556 448 1960 448 conicto
1201 2445 448 2726 749 conicto
1202 3008 1050 3008 1569 conicto
1203 3008 3584 lineto
1204 3584 3584 lineto
1205 3584 0 lineto
1206 3008 0 lineto
1207 3008 576 lineto
1208 2792 251 2506 93 conicto
1209 2221 -64 1844 -64 conicto
1210 1221 -64 898 317 conicto
1211 576 699 576 1433 conicto
1212 end_ol grestore
1213 gsave 34.100853 14.722500 translate 0.035278 -0.035278 scale
1214 start_ol
1215 3712 1944 moveto
1216 3712 1664 lineto
1217 1024 1664 lineto
1218 1062 1070 1389 759 conicto
1219 1716 448 2299 448 conicto
1220 2637 448 2954 528 conicto
1221 3272 608 3584 768 conicto
1222 3584 192 lineto
1223 3266 67 2931 1 conicto
1224 2597 -64 2253 -64 conicto
1225 1391 -64 887 437 conicto
1226 384 938 384 1792 conicto
1227 384 2675 860 3193 conicto
1228 1336 3712 2144 3712 conicto
1229 2869 3712 3290 3236 conicto
1230 3712 2761 3712 1944 conicto
1231 3136 2112 moveto
1232 3130 2608 2866 2904 conicto
1233 2603 3200 2169 3200 conicto
1234 1678 3200 1383 2914 conicto
1235 1088 2628 1043 2109 conicto
1236 3136 2112 lineto
1237 end_ol grestore
1238 gsave 34.637850 14.722500 translate 0.035278 -0.035278 scale
1239 start_ol
1240 2944 3520 moveto
1241 2944 2944 lineto
1242 2690 3072 2417 3136 conicto
1243 2144 3200 1851 3200 conicto
1244 1406 3200 1183 3066 conicto
1245 960 2932 960 2664 conicto
1246 960 2459 1123 2342 conicto
1247 1286 2226 1778 2121 conicto
1248 1988 2076 lineto
1249 2611 1942 2873 1697 conicto
1250 3136 1453 3136 1016 conicto
1251 3136 517 2739 226 conicto
1252 2342 -64 1647 -64 conicto
1253 1358 -64 1044 -16 conicto
1254 731 32 384 128 conicto
1255 384 768 lineto
1256 717 608 1040 528 conicto
1257 1363 448 1679 448 conicto
1258 2103 448 2331 588 conicto
1259 2560 728 2560 982 conicto
1260 2560 1218 2392 1343 conicto
1261 2224 1469 1655 1585 conicto
1262 1442 1633 lineto
1263 882 1749 633 1989 conicto
1264 384 2229 384 2648 conicto
1265 384 3158 748 3435 conicto
1266 1112 3712 1781 3712 conicto
1267 2112 3712 2404 3664 conicto
1268 2697 3616 2944 3520 conicto
1269 end_ol grestore
1270 gsave 35.092421 14.722500 translate 0.035278 -0.035278 scale
1271 start_ol
1272 end_ol grestore
1273 gsave 35.369654 14.722500 translate 0.035278 -0.035278 scale
1274 start_ol
1275 640 4800 moveto
1276 3392 4800 lineto
1277 3392 4288 lineto
1278 1280 4288 lineto
1279 1280 2816 lineto
1280 3200 2816 lineto
1281 3200 2304 lineto
1282 1280 2304 lineto
1283 1280 0 lineto
1284 640 0 lineto
1285 640 4800 lineto
1286 end_ol grestore
1287 gsave 35.824225 14.722500 translate 0.035278 -0.035278 scale
1288 start_ol
1289 3712 1944 moveto
1290 3712 1664 lineto
1291 1024 1664 lineto
1292 1062 1070 1389 759 conicto
1293 1716 448 2299 448 conicto
1294 2637 448 2954 528 conicto
1295 3272 608 3584 768 conicto
1296 3584 192 lineto
1297 3266 67 2931 1 conicto
1298 2597 -64 2253 -64 conicto
1299 1391 -64 887 437 conicto
1300 384 938 384 1792 conicto
1301 384 2675 860 3193 conicto
1302 1336 3712 2144 3712 conicto
1303 2869 3712 3290 3236 conicto
1304 3712 2761 3712 1944 conicto
1305 3136 2112 moveto
1306 3130 2608 2866 2904 conicto
1307 2603 3200 2169 3200 conicto
1308 1678 3200 1383 2914 conicto
1309 1088 2628 1043 2109 conicto
1310 3136 2112 lineto
1311 end_ol grestore
1312 gsave 36.361222 14.722500 translate 0.035278 -0.035278 scale
1313 start_ol
1314 3584 2195 moveto
1315 3584 0 lineto
1316 3008 0 lineto
1317 3008 2176 lineto
1318 3008 2690 2806 2945 conicto
1319 2604 3200 2199 3200 conicto
1320 1713 3200 1432 2893 conicto
1321 1152 2586 1152 2056 conicto
1322 1152 0 lineto
1323 576 0 lineto
1324 576 3584 lineto
1325 1152 3584 lineto
1326 1152 3072 lineto
1327 1365 3394 1654 3553 conicto
1328 1943 3712 2321 3712 conicto
1329 2945 3712 3264 3327 conicto
1330 3584 2942 3584 2195 conicto
1331 end_ol grestore
1332 gsave 36.915697 14.722500 translate 0.035278 -0.035278 scale
1333 start_ol
1334 2944 3520 moveto
1335 2944 2944 lineto
1336 2690 3072 2417 3136 conicto
1337 2144 3200 1851 3200 conicto
1338 1406 3200 1183 3066 conicto
1339 960 2932 960 2664 conicto
1340 960 2459 1123 2342 conicto
1341 1286 2226 1778 2121 conicto
1342 1988 2076 lineto
1343 2611 1942 2873 1697 conicto
1344 3136 1453 3136 1016 conicto
1345 3136 517 2739 226 conicto
1346 2342 -64 1647 -64 conicto
1347 1358 -64 1044 -16 conicto
1348 731 32 384 128 conicto
1349 384 768 lineto
1350 717 608 1040 528 conicto
1351 1363 448 1679 448 conicto
1352 2103 448 2331 588 conicto
1353 2560 728 2560 982 conicto
1354 2560 1218 2392 1343 conicto
1355 2224 1469 1655 1585 conicto
1356 1442 1633 lineto
1357 882 1749 633 1989 conicto
1358 384 2229 384 2648 conicto
1359 384 3158 748 3435 conicto
1360 1112 3712 1781 3712 conicto
1361 2112 3712 2404 3664 conicto
1362 2697 3616 2944 3520 conicto
1363 end_ol grestore
1364 gsave 37.370268 14.722500 translate 0.035278 -0.035278 scale
1365 start_ol
1366 1152 4608 moveto
1367 1152 3584 lineto
1368 2368 3584 lineto
1369 2368 3136 lineto
1370 1152 3136 lineto
1371 1152 1197 lineto
1372 1152 761 1272 636 conicto
1373 1393 512 1762 512 conicto
1374 2368 512 lineto
1375 2368 0 lineto
1376 1762 0 lineto
1377 1088 0 832 258 conicto
1378 576 516 576 1197 conicto
1379 576 3136 lineto
1380 128 3136 lineto
1381 128 3584 lineto
1382 576 3584 lineto
1383 576 4608 lineto
1384 1152 4608 lineto
1385 end_ol grestore
1386 gsave 37.712440 14.722500 translate 0.035278 -0.035278 scale
1387 start_ol
1388 3712 1944 moveto
1389 3712 1664 lineto
1390 1024 1664 lineto
1391 1062 1070 1389 759 conicto
1392 1716 448 2299 448 conicto
1393 2637 448 2954 528 conicto
1394 3272 608 3584 768 conicto
1395 3584 192 lineto
1396 3266 67 2931 1 conicto
1397 2597 -64 2253 -64 conicto
1398 1391 -64 887 437 conicto
1399 384 938 384 1792 conicto
1400 384 2675 860 3193 conicto
1401 1336 3712 2144 3712 conicto
1402 2869 3712 3290 3236 conicto
1403 3712 2761 3712 1944 conicto
1404 3136 2112 moveto
1405 3130 2608 2866 2904 conicto
1406 2603 3200 2169 3200 conicto
1407 1678 3200 1383 2914 conicto
1408 1088 2628 1043 2109 conicto
1409 3136 2112 lineto
1410 end_ol grestore
1411 gsave 38.249437 14.722500 translate 0.035278 -0.035278 scale
1412 start_ol
1413 2688 3008 moveto
1414 2587 3107 2468 3153 conicto
1415 2349 3200 2205 3200 conicto
1416 1697 3200 1424 2868 conicto
1417 1152 2537 1152 1916 conicto
1418 1152 0 lineto
1419 576 0 lineto
1420 576 3584 lineto
1421 1152 3584 lineto
1422 1152 3072 lineto
1423 1341 3397 1644 3554 conicto
1424 1948 3712 2381 3712 conicto
1425 2443 3712 2518 3696 conicto
1426 2593 3680 2685 3648 conicto
1427 2688 3008 lineto
1428 end_ol grestore
1429 gsave 31.305000 12.072500 translate 0.035278 -0.035278 scale
1430 start_ol
1431 1344 3328 moveto
1432 1084 2828 958 2338 conicto
1433 832 1849 832 1346 conicto
1434 832 844 959 351 conicto
1435 1086 -142 1344 -640 conicto
1436 1034 -640 lineto
1437 708 -129 546 365 conicto
1438 384 859 384 1346 conicto
1439 384 1831 545 2323 conicto
1440 706 2815 1034 3328 conicto
1441 1344 3328 lineto
1442 end_ol grestore
1443 gsave 31.532285 12.072500 translate 0.035278 -0.035278 scale
1444 start_ol
1445 448 3200 moveto
1446 2176 3200 lineto
1447 2176 2880 lineto
1448 896 2880 lineto
1449 896 2056 lineto
1450 990 2084 1084 2098 conicto
1451 1178 2112 1273 2112 conicto
1452 1807 2112 2119 1818 conicto
1453 2432 1525 2432 1024 conicto
1454 2432 508 2104 222 conicto
1455 1776 -64 1179 -64 conicto
1456 974 -64 760 -32 conicto
1457 547 0 320 64 conicto
1458 320 512 lineto
1459 516 383 725 319 conicto
1460 934 256 1167 256 conicto
1461 1544 256 1764 463 conicto
1462 1984 670 1984 1024 conicto
1463 1984 1378 1762 1585 conicto
1464 1541 1792 1162 1792 conicto
1465 985 1792 808 1745 conicto
1466 632 1699 448 1600 conicto
1467 448 3200 lineto
1468 end_ol grestore
1469 gsave 31.901933 12.072500 translate 0.035278 -0.035278 scale
1470 start_ol
1471 512 576 moveto
1472 960 576 lineto
1473 960 196 lineto
1474 576 -512 lineto
1475 320 -512 lineto
1476 512 196 lineto
1477 512 576 lineto
1478 end_ol grestore
1479 gsave 32.086753 12.072500 translate 0.035278 -0.035278 scale
1480 start_ol
1481 end_ol grestore
1482 gsave 32.271573 12.072500 translate 0.035278 -0.035278 scale
1483 start_ol
1484 576 320 moveto
1485 1280 320 lineto
1486 1280 2880 lineto
1487 512 2752 lineto
1488 512 3072 lineto
1489 1289 3200 lineto
1490 1728 3200 lineto
1491 1728 320 lineto
1492 2432 320 lineto
1493 2432 0 lineto
1494 576 0 lineto
1495 576 320 lineto
1496 end_ol grestore
1497 gsave 32.641220 12.072500 translate 0.035278 -0.035278 scale
1498 start_ol
1499 1439 2944 moveto
1500 1105 2944 936 2608 conicto
1501 768 2273 768 1599 conicto
1502 768 927 936 591 conicto
1503 1105 256 1439 256 conicto
1504 1775 256 1943 591 conicto
1505 2112 927 2112 1599 conicto
1506 2112 2273 1943 2608 conicto
1507 1775 2944 1439 2944 conicto
1508 1440 3264 moveto
1509 1985 3264 2272 2837 conicto
1510 2560 2411 2560 1599 conicto
1511 2560 789 2272 362 conicto
1512 1985 -64 1440 -64 conicto
1513 895 -64 607 362 conicto
1514 320 789 320 1599 conicto
1515 320 2411 607 2837 conicto
1516 895 3264 1440 3264 conicto
1517 end_ol grestore
1518 gsave 33.010868 12.072500 translate 0.035278 -0.035278 scale
1519 start_ol
1520 384 3328 moveto
1521 694 3328 lineto
1522 1020 2815 1182 2323 conicto
1523 1344 1831 1344 1346 conicto
1524 1344 859 1182 365 conicto
1525 1020 -129 694 -640 conicto
1526 384 -640 lineto
1527 642 -142 769 351 conicto
1528 896 844 896 1346 conicto
1529 896 1849 769 2338 conicto
1530 642 2828 384 3328 conicto
1531 end_ol grestore
1532 gsave 33.650000 10.600000 translate 0.035278 -0.035278 scale
1533 start_ol
1534 896 2816 moveto
1535 896 384 lineto
1536 1417 384 lineto
1537 2076 384 2382 677 conicto
1538 2688 971 2688 1603 conicto
1539 2688 2232 2382 2524 conicto
1540 2076 2816 1417 2816 conicto
1541 896 2816 lineto
1542 448 3200 moveto
1543 1350 3200 lineto
1544 2273 3200 2704 2813 conicto
1545 3136 2426 3136 1603 conicto
1546 3136 776 2702 388 conicto
1547 2269 0 1350 0 conicto
1548 448 0 lineto
1549 448 3200 lineto
1550 end_ol grestore
1551 gsave 34.097080 10.600000 translate 0.035278 -0.035278 scale
1552 start_ol
1553 2496 1352 moveto
1554 2496 1152 lineto
1555 704 1152 lineto
1556 730 714 950 485 conicto
1557 1171 256 1565 256 conicto
1558 1793 256 2007 320 conicto
1559 2221 384 2432 512 conicto
1560 2432 128 lineto
1561 2215 34 1988 -15 conicto
1562 1761 -64 1527 -64 conicto
1563 941 -64 598 275 conicto
1564 256 615 256 1194 conicto
1565 256 1793 576 2144 conicto
1566 897 2496 1441 2496 conicto
1567 1928 2496 2212 2188 conicto
1568 2496 1881 2496 1352 conicto
1569 2112 1472 moveto
1570 2108 1793 1932 1984 conicto
1571 1757 2176 1468 2176 conicto
1572 1140 2176 943 1991 conicto
1573 747 1806 717 1470 conicto
1574 2112 1472 lineto
1575 end_ol grestore
1576 gsave 34.454242 10.600000 translate 0.035278 -0.035278 scale
1577 start_ol
1578 2176 2368 moveto
1579 2176 1984 lineto
1580 2010 2080 1843 2128 conicto
1581 1676 2176 1506 2176 conicto
1582 1125 2176 914 1924 conicto
1583 704 1672 704 1216 conicto
1584 704 760 914 508 conicto
1585 1125 256 1506 256 conicto
1586 1676 256 1843 304 conicto
1587 2010 352 2176 448 conicto
1588 2176 64 lineto
1589 2009 0 1830 -32 conicto
1590 1652 -64 1450 -64 conicto
1591 902 -64 579 282 conicto
1592 256 628 256 1216 conicto
1593 256 1812 582 2154 conicto
1594 908 2496 1476 2496 conicto
1595 1660 2496 1835 2464 conicto
1596 2011 2432 2176 2368 conicto
1597 end_ol grestore
1598 gsave 34.773942 10.600000 translate 0.035278 -0.035278 scale
1599 start_ol
1600 1377 2176 moveto
1601 1066 2176 885 1919 conicto
1602 704 1663 704 1216 conicto
1603 704 769 884 512 conicto
1604 1064 256 1377 256 conicto
1605 1686 256 1867 514 conicto
1606 2048 772 2048 1216 conicto
1607 2048 1658 1867 1917 conicto
1608 1686 2176 1377 2176 conicto
1609 1376 2496 moveto
1610 1899 2496 2197 2156 conicto
1611 2496 1817 2496 1216 conicto
1612 2496 617 2197 276 conicto
1613 1899 -64 1376 -64 conicto
1614 851 -64 553 276 conicto
1615 256 617 256 1216 conicto
1616 256 1817 553 2156 conicto
1617 851 2496 1376 2496 conicto
1618 end_ol grestore
1619 gsave 35.131104 10.600000 translate 0.035278 -0.035278 scale
1620 start_ol
1621 1792 2112 moveto
1622 1725 2145 1645 2160 conicto
1623 1566 2176 1470 2176 conicto
1624 1131 2176 949 1944 conicto
1625 768 1712 768 1277 conicto
1626 768 0 lineto
1627 384 0 lineto
1628 384 2432 lineto
1629 768 2432 lineto
1630 768 2048 lineto
1631 894 2275 1096 2385 conicto
1632 1298 2496 1588 2496 conicto
1633 1629 2496 1679 2496 conicto
1634 1729 2496 1790 2496 conicto
1635 1792 2112 lineto
1636 end_ol grestore
1637 gsave 35.370875 10.600000 translate 0.035278 -0.035278 scale
1638 start_ol
1639 1515 1216 moveto
1640 1021 1216 830 1104 conicto
1641 640 992 640 723 conicto
1642 640 508 783 382 conicto
1643 926 256 1171 256 conicto
1644 1510 256 1715 494 conicto
1645 1920 733 1920 1129 conicto
1646 1920 1216 lineto
1647 1515 1216 lineto
1648 2304 1385 moveto
1649 2304 0 lineto
1650 1920 0 lineto
1651 1920 384 lineto
1652 1782 154 1577 45 conicto
1653 1372 -64 1075 -64 conicto
1654 699 -64 477 146 conicto
1655 256 356 256 708 conicto
1656 256 1119 530 1327 conicto
1657 805 1536 1349 1536 conicto
1658 1920 1536 lineto
1659 1920 1578 lineto
1660 1920 1864 1739 2020 conicto
1661 1558 2176 1232 2176 conicto
1662 1024 2176 827 2128 conicto
1663 630 2080 448 1984 conicto
1664 448 2368 lineto
1665 665 2432 869 2464 conicto
1666 1073 2496 1266 2496 conicto
1667 1788 2496 2046 2220 conicto
1668 2304 1945 2304 1385 conicto
1669 end_ol grestore
1670 gsave 35.728038 10.600000 translate 0.035278 -0.035278 scale
1671 start_ol
1672 768 3136 moveto
1673 768 2432 lineto
1674 1600 2432 lineto
1675 1600 2112 lineto
1676 768 2112 lineto
1677 768 788 lineto
1678 768 490 850 405 conicto
1679 933 320 1185 320 conicto
1680 1600 320 lineto
1681 1600 0 lineto
1682 1185 0 lineto
1683 730 0 557 170 conicto
1684 384 340 384 788 conicto
1685 384 2112 lineto
1686 64 2112 lineto
1687 64 2432 lineto
1688 384 2432 lineto
1689 384 3136 lineto
1690 768 3136 lineto
1691 end_ol grestore
1692 gsave 35.955323 10.600000 translate 0.035278 -0.035278 scale
1693 start_ol
1694 384 2432 moveto
1695 768 2432 lineto
1696 768 0 lineto
1697 384 0 lineto
1698 384 2432 lineto
1699 384 3328 moveto
1700 768 3328 lineto
1701 768 2816 lineto
1702 384 2816 lineto
1703 384 3328 lineto
1704 end_ol grestore
1705 gsave 36.117670 10.600000 translate 0.035278 -0.035278 scale
1706 start_ol
1707 1377 2176 moveto
1708 1066 2176 885 1919 conicto
1709 704 1663 704 1216 conicto
1710 704 769 884 512 conicto
1711 1064 256 1377 256 conicto
1712 1686 256 1867 514 conicto
1713 2048 772 2048 1216 conicto
1714 2048 1658 1867 1917 conicto
1715 1686 2176 1377 2176 conicto
1716 1376 2496 moveto
1717 1899 2496 2197 2156 conicto
1718 2496 1817 2496 1216 conicto
1719 2496 617 2197 276 conicto
1720 1899 -64 1376 -64 conicto
1721 851 -64 553 276 conicto
1722 256 617 256 1216 conicto
1723 256 1817 553 2156 conicto
1724 851 2496 1376 2496 conicto
1725 end_ol grestore
1726 gsave 36.474832 10.600000 translate 0.035278 -0.035278 scale
1727 start_ol
1728 2432 1463 moveto
1729 2432 0 lineto
1730 2048 0 lineto
1731 2048 1450 lineto
1732 2048 1814 1908 1995 conicto
1733 1769 2176 1490 2176 conicto
1734 1155 2176 961 1959 conicto
1735 768 1743 768 1370 conicto
1736 768 0 lineto
1737 384 0 lineto
1738 384 2432 lineto
1739 768 2432 lineto
1740 768 2048 lineto
1741 914 2273 1111 2384 conicto
1742 1309 2496 1568 2496 conicto
1743 1994 2496 2213 2234 conicto
1744 2432 1972 2432 1463 conicto
1745 end_ol grestore
1746 gsave 36.844480 10.600000 translate 0.035278 -0.035278 scale
1747 start_ol
1748 1984 2368 moveto
1749 1984 1984 lineto
1750 1812 2080 1627 2128 conicto
1751 1442 2176 1244 2176 conicto
1752 942 2176 791 2083 conicto
1753 640 1990 640 1804 conicto
1754 640 1662 750 1581 conicto
1755 861 1500 1196 1427 conicto
1756 1339 1397 lineto
1757 1759 1305 1935 1138 conicto
1758 2112 972 2112 673 conicto
1759 2112 333 1844 134 conicto
1760 1576 -64 1108 -64 conicto
1761 913 -64 701 -16 conicto
1762 490 32 256 128 conicto
1763 256 512 lineto
1764 481 384 699 320 conicto
1765 918 256 1132 256 conicto
1766 1419 256 1573 355 conicto
1767 1728 455 1728 636 conicto
1768 1728 804 1614 893 conicto
1769 1500 982 1113 1065 conicto
1770 968 1097 lineto
1771 591 1175 423 1336 conicto
1772 256 1498 256 1780 conicto
1773 256 2123 501 2309 conicto
1774 747 2496 1199 2496 conicto
1775 1423 2496 1620 2464 conicto
1776 1817 2432 1984 2368 conicto
1777 end_ol grestore
1778 0.100000 slw
1779 [] 0 sd
1780 [] 0 sd
1781 0 slc
1782 n 35.300000 10.700000 m 36.251889 11.369848 l s
1783 [] 0 sd
1784 0 slj
1785 0 slc
1786 n 36.558566 11.585658 m 36.005790 11.502363 l 36.251889 11.369848 l 36.293537 11.093460 l ef
1787 n 36.558566 11.585658 m 36.005790 11.502363 l 36.251889 11.369848 l 36.293537 11.093460 l cp s
1788 0.100000 slw
1789 [] 0 sd
1790 [] 0 sd
1791 0 slc
1792 n 27.350000 14.950000 m 29.413197 14.950000 l s
1793 [] 0 sd
1794 0 slj
1795 0 slc
1796 n 29.788197 14.950000 m 29.288197 15.200000 l 29.413197 14.950000 l 29.288197 14.700000 l ef
1797 n 29.788197 14.950000 m 29.288197 15.200000 l 29.413197 14.950000 l 29.288197 14.700000 l cp s
1798 showpage
0 %!PS-Adobe-3.0
1 %%Creator: GIMP PostScript file plugin V 1.17 by Peter Kirchgessner
2 %%Title: screenshot.ps
3 %%CreationDate: Thu Mar 12 03:26:16 2009
4 %%DocumentData: Clean7Bit
5 %%LanguageLevel: 2
6 %%Pages: 1
7 %%BoundingBox: 14 14 1295 815
8 %%EndComments
9 %%BeginProlog
10 % Use own dictionary to avoid conflicts
11 10 dict begin
12 %%EndProlog
13 %%Page: 1 1
14 % Translate for offset
15 14.173228346456694 14.173228346456694 translate
16 % Translate to begin of first scanline
17 0 799.99999999999989 translate
18 1279.9999999999998 -799.99999999999989 scale
19 % Image geometry
20 1280 800 8
21 % Transformation matrix
22 [ 1280 0 0 800 0 0 ]
23 % Strings to hold RGB-samples per scanline
24 /rstr 1280 string def
25 /gstr 1280 string def
26 /bstr 1280 string def
27 {currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
28 {currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
29 {currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
30 true 3
31 %%BeginData: 542919 ASCII Bytes
32 colorimage
33 s!!"MJMVj5JMVp7s&FVDJP:VgJP:\iJ,~>
34 s!!"MJMVj5JMVp7s&FVpJTu`jJTuflJ,~>
35 s!!"MJMVj5JMVp7s&FW<JXM(WJXM.YJ,~>
36 JKfXhJKfXhJKfYFJQ78$JQ78$J,~>
37 JKfXhJKfXhJKfYFJQ78$JQ78$J,~>
38 JKfXhJKfXhJKfYFJQ78$JQ78$J,~>
39 JKfXhJKfXhJKfYFJQ78$JQ78$J,~>
40 JKfXhJKfXhJKfYFJQ78$JQ78$J,~>
41 JKfXhJKfXhJKfYFJQ78$JQ78$J,~>
42 JKfXhJKfXhJKfYFJQ78$JQ78$J,~>
43 JKfXhJKfXhJKfYFJQ78$JQ78$J,~>
44 JKfXhJKfXhJKfYFJQ78$JQ78$J,~>
45 kop+`lQZ@br?D2rpEKQlr?D8tr$)/smNMah+sMho,(Uqh,(Us),55+7s63P`s7]Lns1q_8s3F[F
46 s7B:ks0Yi,s.r]qs8>pts++1$<TmG5~>
47 kop+`lQZ@br?D2rpEKQlr?D8tr$)/smNMah+sMho,(Uqh,(Us),55+7s63P`s7]Lns1q_8s3F[F
48 s7B:ks0Yi,s.r]qs8>pts++1$<TmG5~>
49 kop+`lQZ@br?D2rpEKQlr?D8tr$)/smNMah+sMho,(Uqh,(Us),55+7s63P`s7]Lns1q_8s3F[F
50 s7B:ks0Yi,s.r]qs8>pts++1$<TmG5~>
51 oHF9kpEBTnl664arZV>ur?;5tq'#fpr?;H%+sMge,)H4B",J-FM!uSkLa%X!Lk-b$,(Uqh,4$NN
52 <<3'p<<3'a<<N8$<WDho!<;Xj!<;pr!<;1]!<;jp!<;pr!<;pr!<:VM!<;[k!<;"X!<;1]!<;Ui
53 !<8lq!<<!t!<<!t!<:bQ!<7UMPuW>~>
54 oHF9kpEBTnl664arZV>ur?;5tq'#fpr?;H%+sMge,)H4B",J-FM!uSkLa%X!Lk-b$,(Uqh,4$NN
55 <<3'p<<3'a<<N8$<WDho!<;Xj!<;pr!<;1]!<;jp!<;pr!<;pr!<:VM!<;[k!<;"X!<;1]!<;Ui
56 !<8lq!<<!t!<<!t!<:bQ!<7UMPuW>~>
57 oHF9kpEBTnl664arZV>ur?;5tq'#fpr?;H%+sMge,)H4B",J-FM!uSkLa%X!Lk-b$,(Uqh,4$NN
58 <<3'p<<3'a<<N8$<WDho!<;Xj!<;pr!<;1]!<;jp!<;pr!<;pr!<:VM!<;[k!<;"X!<;1]!<;Ui
59 !<8lq!<<!t!<<!t!<:bQ!<7UMPuW>~>
60 kop+`l664arZV>ur?;5tq'#fpr?;<!,)H1A!f/%Vr?;5tr?;5tp*'Tp+sMho,(Uqh,(Us(,4ee7
61 s6<Sas8>pts7oXps794js8,drs5m;]s70.is3F[Fs7B:ks0Yi,s.r]qs8>pts4(*Ls++18<Ib~>
62 kop+`l664arZV>ur?;5tq'#fpr?;<!,)H1A!f/%Vr?;5tr?;5tp*'Tp+sMho,(Uqh,(Us(,4ee7
63 s6<Sas8>pts7oXps794js8,drs5m;]s70.is3F[Fs7B:ks0Yi,s.r]qs8>pts4(*Ls++18<Ib~>
64 kop+`l664arZV>ur?;5tq'#fpr?;<!,)H1A!f/%Vr?;5tr?;5tp*'Tp+sMho,(Uqh,(Us(,4ee7
65 s6<Sas8>pts7oXps794js8,drs5m;]s70.is3F[Fs7B:ks0Yi,s.r]qs8>pts4(*Ls++18<Ib~>
66 r?D8t!@!?u,6*Jt,5m>t+p!KDreUOtrJ:FsrJ:@q!/UUu!f/$EreLS!M#ALtM#/@tLa%ZR+p*QE
67 M#ALtM#JUtLk-b$,(Uqh,2FI@<WE*r<<3'`<<3't<<3'p<<<,"rr;strVumtrVujsrVugrrVumt
68 !WQ1!s7fUms85mss8,drs85mss8H"!s&K'ur`/st!EK0p<W2st<<<,"rr;strr3"!s7fUnrrZ:$
69 <WE"t"92C$<W<$t<W2ss<WE("<WE"ts8W$trVuUl!<<$u!<<$us8W'u!WQ1!s8H$trrZ:$<E9"t
70 r`&sur`&supf7@o!EK1!<W2st<<<,"rr;strVujsrr3(#s&E(ts8Q("s&K'uku@ic<E9(t<WE*t
71 <WE(&<W?'!s&K'ur`/pss&B+"<W<$t<W2st<W2sr<W2st<<<,"rr7OLVH&-~>
72 r?D8t!@!?u,6*Jt,5m>t+p!KDreUOtrJ:FsrJ:@q!/UUu!f/$EreLS!M#ALtM#/@tLa%ZR+p*QE
73 M#ALtM#JUtLk-b$,(Uqh,2FI@<WE*r<<3'`<<3't<<3'p<<<,"rr;strVumtrVujsrVugrrVumt
74 !WQ1!s7fUms85mss8,drs85mss8H"!s&K'ur`/st!EK0p<W2st<<<,"rr;strr3"!s7fUnrrZ:$
75 <WE"t"92C$<W<$t<W2ss<WE("<WE"ts8W$trVuUl!<<$u!<<$us8W'u!WQ1!s8H$trrZ:$<E9"t
76 r`&sur`&supf7@o!EK1!<W2st<<<,"rr;strVujsrr3(#s&E(ts8Q("s&K'uku@ic<E9(t<WE*t
77 <WE(&<W?'!s&K'ur`/pss&B+"<W<$t<W2st<W2sr<W2st<<<,"rr7OLVH&-~>
78 r?D8t!@!?u,6*Jt,5m>t+p!KDreUOtrJ:FsrJ:@q!/UUu!f/$EreLS!M#ALtM#/@tLa%ZR+p*QE
79 M#ALtM#JUtLk-b$,(Uqh,2FI@<WE*r<<3'`<<3't<<3'p<<<,"rr;strVumtrVujsrVugrrVumt
80 !WQ1!s7fUms85mss8,drs85mss8H"!s&K'ur`/st!EK0p<W2st<<<,"rr;strr3"!s7fUnrrZ:$
81 <WE"t"92C$<W<$t<W2ss<WE("<WE"ts8W$trVuUl!<<$u!<<$us8W'u!WQ1!s8H$trrZ:$<E9"t
82 r`&sur`&supf7@o!EK1!<W2st<<<,"rr;strVujsrr3(#s&E(ts8Q("s&K'uku@ic<E9(t<WE*t
83 <WE(&<W?'!s&K'ur`/pss&B+"<W<$t<W2st<W2sr<W2st<<<,"rr7OLVH&-~>
84 r?;B#,)@G!r?;5trZV>ur?;?",)D'S+omGr+p*QEM#ALtM#ALtM#JS+La%X!,)@EeLa"%!q]Z,u
85 +sMjA+p*QEM#ALtM#ALtLk-b$,(Uqh,2=C><<3's<W<$m<W)mm<<3't<<3'p<WE*u<<E2#s8>q"
86 s&E)!qc*Xrr)EasrD`t"<E9(u<<3'o<<3'p<<3'r<<3'r<<3'u<WE*u<<E2#s8H!us794ms&K+!
87 r`'%"<WE%us8Vmp!<<$us8N+"s8>q"s&K+!r`&suqc*n$<E9'!s&K*t<<3'u<<3't<<3'o<<3'u
88 <<3't<<3'u<WE*u<<E2#s8H$urrH."rD`t"<E9(u<<3'o<<W>%s&K*r<<N8$s8W'u!<;pr!rl:#
89 r`'(#<E9(t<<N8$<WE%u!<;gor;ZOl"92A$s85jss8>q&s&K)!s&K+!r`'%"<WE"t"92A$s8H!u
90 s8,dus&E)!r)EasrD`t"<E9(u<<3&M<MriI~>
91 r?;B#,)@G!r?;5trZV>ur?;?",)D'S+omGr+p*QEM#ALtM#ALtM#JS+La%X!,)@EeLa"%!q]Z,u
92 +sMjA+p*QEM#ALtM#ALtLk-b$,(Uqh,2=C><<3's<W<$m<W)mm<<3't<<3'p<WE*u<<E2#s8>q"
93 s&E)!qc*Xrr)EasrD`t"<E9(u<<3'o<<3'p<<3'r<<3'r<<3'u<WE*u<<E2#s8H!us794ms&K+!
94 r`'%"<WE%us8Vmp!<<$us8N+"s8>q"s&K+!r`&suqc*n$<E9'!s&K*t<<3'u<<3't<<3'o<<3'u
95 <<3't<<3'u<WE*u<<E2#s8H$urrH."rD`t"<E9(u<<3'o<<W>%s&K*r<<N8$s8W'u!<;pr!rl:#
96 r`'(#<E9(t<<N8$<WE%u!<;gor;ZOl"92A$s85jss8>q&s&K)!s&K+!r`'%"<WE"t"92A$s8H!u
97 s8,dus&E)!r)EasrD`t"<E9(u<<3&M<MriI~>
98 r?;B#,)@G!r?;5trZV>ur?;?",)D'S+omGr+p*QEM#ALtM#ALtM#JS+La%X!,)@EeLa"%!q]Z,u
99 +sMjA+p*QEM#ALtM#ALtLk-b$,(Uqh,2=C><<3's<W<$m<W)mm<<3't<<3'p<WE*u<<E2#s8>q"
100 s&E)!qc*Xrr)EasrD`t"<E9(u<<3'o<<3'p<<3'r<<3'r<<3'u<WE*u<<E2#s8H!us794ms&K+!
101 r`'%"<WE%us8Vmp!<<$us8N+"s8>q"s&K+!r`&suqc*n$<E9'!s&K*t<<3'u<<3't<<3'o<<3'u
102 <<3't<<3'u<WE*u<<E2#s8H$urrH."rD`t"<E9(u<<3'o<<W>%s&K*r<<N8$s8W'u!<;pr!rl:#
103 r`'(#<E9(t<<N8$<WE%u!<;gor;ZOl"92A$s85jss8>q&s&K)!s&K+!r`'%"<WE"t"92A$s8H!u
104 s8,dus&E)!r)EasrD`t"<E9(u<<3&M<MriI~>
105 r?;B#,)@G!r?;5trZV>uq]Z#rr?;<!+sQr@!$_;rr?;5trZVN%,)@G!M#JUuM#8IsM#JRuM#AM!
106 La%ZR+omFM,(Uqh,(Uri,5Y@?s7oXps6E\^s7oXps8>pus&Jsrs&B(!qc*Xrr)NXos&B(!oMknk
107 q,IFpqc*Xrqc*Xrr`&surD`q!<WE%u!<;dnr;Qdts8>q!s&K*t<<3'p<<3't<<E2#s8>q!s&K*t
108 <<E2#<W)ms<<W>%s&K*t<<3'u<<3'j<<W>%s&K*t<<3'u<<3't<<E2#s8>q!s&K*t<<rP(<W?)!
109 <WDho#6.^'<W?'!r;Qdts8>q!s&E(srrH."r`'%"<E8qrs&B(!k#DN`<E9(s<<3't<<iJ's&K)!
110 s8>pus&Jsrs&B(!qc3Ros&B(!r)EasrD`t"<E9'M<MNQE~>
111 r?;B#,)@G!r?;5trZV>uq]Z#rr?;<!+sQr@!$_;rr?;5trZVN%,)@G!M#JUuM#8IsM#JRuM#AM!
112 La%ZR+omFM,(Uqh,(Uri,5Y@?s7oXps6E\^s7oXps8>pus&Jsrs&B(!qc*Xrr)NXos&B(!oMknk
113 q,IFpqc*Xrqc*Xrr`&surD`q!<WE%u!<;dnr;Qdts8>q!s&K*t<<3'p<<3't<<E2#s8>q!s&K*t
114 <<E2#<W)ms<<W>%s&K*t<<3'u<<3'j<<W>%s&K*t<<3'u<<3't<<E2#s8>q!s&K*t<<rP(<W?)!
115 <WDho#6.^'<W?'!r;Qdts8>q!s&E(srrH."r`'%"<E8qrs&B(!k#DN`<E9(s<<3't<<iJ's&K)!
116 s8>pus&Jsrs&B(!qc3Ros&B(!r)EasrD`t"<E9'M<MNQE~>
117 r?;B#,)@G!r?;5trZV>uq]Z#rr?;<!+sQr@!$_;rr?;5trZVN%,)@G!M#JUuM#8IsM#JRuM#AM!
118 La%ZR+omFM,(Uqh,(Uri,5Y@?s7oXps6E\^s7oXps8>pus&Jsrs&B(!qc*Xrr)NXos&B(!oMknk
119 q,IFpqc*Xrqc*Xrr`&surD`q!<WE%u!<;dnr;Qdts8>q!s&K*t<<3'p<<3't<<E2#s8>q!s&K*t
120 <<E2#<W)ms<<W>%s&K*t<<3'u<<3'j<<W>%s&K*t<<3'u<<3't<<E2#s8>q!s&K*t<<rP(<W?)!
121 <WDho#6.^'<W?'!r;Qdts8>q!s&E(srrH."r`'%"<E8qrs&B(!k#DN`<E9(s<<3't<<iJ's&K)!
122 s8>pus&Jsrs&B(!qc3Ros&B(!r)EasrD`t"<E9'M<MNQE~>
123 r?;B#,)@G!r?;5trZV>uq]Z#rr?;<!,)H1A!f/%Vp`]]orZVN%+sMgeM#JUuM#ALtM#8FsM#AM!
124 La%ZR+omFM,(Uqh,(Uri,5Y@?s7oXps6EYbs8>pts7oXps8>q!s&K*q<<3'r<<3's<<3'q<<3'k
125 <<3'p<<3'r<<3'r<<3'u<<3't<<E2#<W<$m<<3't<<E2#s8>q!s&K*t<<3'p<<3't<<E2#s8H$u
126 rrH."rD`q!<WE"t#QIe(s&K)!s8>pts8H!us794ns&K)!s8>pts8H!us8>q!s&K*t<<E2#s8>q&
127 s&E)!<W?)!pf.Ou<W?)!<WE"t!rl:#rD`q!<WE"t!rl8#rr;st!<;mq!<;.\s8Vsr!<<!t#QIg(
128 <W?)!s8H""s&K*q<<3's<<3't<<N8$<WDts!<<!t"92A$s++1F<Ib~>
129 r?;B#,)@G!r?;5trZV>uq]Z#rr?;<!,)H1A!f/%Vp`]]orZVN%+sMgeM#JUuM#ALtM#8FsM#AM!
130 La%ZR+omFM,(Uqh,(Uri,5Y@?s7oXps6EYbs8>pts7oXps8>q!s&K*q<<3'r<<3's<<3'q<<3'k
131 <<3'p<<3'r<<3'r<<3'u<<3't<<E2#<W<$m<<3't<<E2#s8>q!s&K*t<<3'p<<3't<<E2#s8H$u
132 rrH."rD`q!<WE"t#QIe(s&K)!s8>pts8H!us794ns&K)!s8>pts8H!us8>q!s&K*t<<E2#s8>q&
133 s&E)!<W?)!pf.Ou<W?)!<WE"t!rl:#rD`q!<WE"t!rl8#rr;st!<;mq!<;.\s8Vsr!<<!t#QIg(
134 <W?)!s8H""s&K*q<<3's<<3't<<N8$<WDts!<<!t"92A$s++1F<Ib~>
135 r?;B#,)@G!r?;5trZV>uq]Z#rr?;<!,)H1A!f/%Vp`]]orZVN%+sMgeM#JUuM#ALtM#8FsM#AM!
136 La%ZR+omFM,(Uqh,(Uri,5Y@?s7oXps6EYbs8>pts7oXps8>q!s&K*q<<3'r<<3's<<3'q<<3'k
137 <<3'p<<3'r<<3'r<<3'u<<3't<<E2#<W<$m<<3't<<E2#s8>q!s&K*t<<3'p<<3't<<E2#s8H$u
138 rrH."rD`q!<WE"t#QIe(s&K)!s8>pts8H!us794ns&K)!s8>pts8H!us8>q!s&K*t<<E2#s8>q&
139 s&E)!<W?)!pf.Ou<W?)!<WE"t!rl:#rD`q!<WE"t!rl8#rr;st!<;mq!<;.\s8Vsr!<<!t#QIg(
140 <W?)!s8H""s&K*q<<3's<<3't<<N8$<WDts!<<!t"92A$s++1F<Ib~>
141 r?;B#,)@G!r?;5trZV>ur?;<!,)H1A!f/%VrZ_Au!@!?u+omGt+omGu+omGq+pNiI,)@EeM#&:t
142 La"%!rZVH#+sMj@+omFM,(Uqh,(Urn,5Y@?s8H!us8>pts6EYbs8>pts7o[ps8H""s&K*t<<N8$
143 <WE%u"92A$s8H""s&K*t<<N8$<WD\k!<<$u!<<!t!<;pr!<;pr!<<$u!<<!t!rl:#oMknkr`0!u
144 !EK0u<<E2#s8H$us7oXps8H$us8Q*urrZ:$<WE"t!rl:#r`0!us&B4%<W?)!rD`jtr`&surD`jt
145 pf.Is<W?)!rD`jtr`&surD`q!<WE%us8N+"s8>q&s&E)!<W?)!pf.Ou<W?)!<WE%us8N+"s8>q!
146 s&K*u<WE("<WDqr!<<!t"92A$s5d8\s8,drs8>q&s&K)!s&K)!rr<!u!<<!t"92A$s85jss8H$u
147 s8Q(!s8H""s&K*t<<N8$<W@VMUK)g~>
148 r?;B#,)@G!r?;5trZV>ur?;<!,)H1A!f/%VrZ_Au!@!?u+omGt+omGu+omGq+pNiI,)@EeM#&:t
149 La"%!rZVH#+sMj@+omFM,(Uqh,(Urn,5Y@?s8H!us8>pts6EYbs8>pts7o[ps8H""s&K*t<<N8$
150 <WE%u"92A$s8H""s&K*t<<N8$<WD\k!<<$u!<<!t!<;pr!<;pr!<<$u!<<!t!rl:#oMknkr`0!u
151 !EK0u<<E2#s8H$us7oXps8H$us8Q*urrZ:$<WE"t!rl:#r`0!us&B4%<W?)!rD`jtr`&surD`jt
152 pf.Is<W?)!rD`jtr`&surD`q!<WE%us8N+"s8>q&s&E)!<W?)!pf.Ou<W?)!<WE%us8N+"s8>q!
153 s&K*u<WE("<WDqr!<<!t"92A$s5d8\s8,drs8>q&s&K)!s&K)!rr<!u!<<!t"92A$s85jss8H$u
154 s8Q(!s8H""s&K*t<<N8$<W@VMUK)g~>
155 r?;B#,)@G!r?;5trZV>ur?;<!,)H1A!f/%VrZ_Au!@!?u+omGt+omGu+omGq+pNiI,)@EeM#&:t
156 La"%!rZVH#+sMj@+omFM,(Uqh,(Urn,5Y@?s8H!us8>pts6EYbs8>pts7o[ps8H""s&K*t<<N8$
157 <WE%u"92A$s8H""s&K*t<<N8$<WD\k!<<$u!<<!t!<;pr!<;pr!<<$u!<<!t!rl:#oMknkr`0!u
158 !EK0u<<E2#s8H$us7oXps8H$us8Q*urrZ:$<WE"t!rl:#r`0!us&B4%<W?)!rD`jtr`&surD`jt
159 pf.Is<W?)!rD`jtr`&surD`q!<WE%us8N+"s8>q&s&E)!<W?)!pf.Ou<W?)!<WE%us8N+"s8>q!
160 s&K*u<WE("<WDqr!<<!t"92A$s5d8\s8,drs8>q&s&K)!s&K)!rr<!u!<<!t"92A$s85jss8H$u
161 s8Q(!s8H""s&K*t<<N8$<W@VMUK)g~>
162 r?;5trZVE"+sQr@s!%DtruqH!r?;<!+sR#B"!WOF,5m>s,5d8s,5m>t+omGt+p!KDqhY4qs+pRs
163 s+pRsreQ+LJKfXhJKinorDidqs&K$tl;[iarD`jtq,IIq<W<$t<W2sr<W<$s<W<$t<W2ss<<3'j
164 <W<$t<W)ms<W)ms<W)jt<WE"t!rl8#rVuUlrr3(#s&K*t<<E2#<W<"!<WDhorr3"!s8,dts&K*t
165 <<E2#<W<"$<W?'!s8H""s&E(ss8Q*ts7TFos&K*u<W)jt<WE"t!rl8#rr3(#s&E(ts8>q!s&K*n
166 <<3'u<<E2#<W<"#<W?)!rD`q!<E9%u"',A$<W2ss<W2ss<<3'\<WE*t<W)ms<<3'u<<E2#s8#ao
167 s8H!us8,gqrrH."r`/str`/psr`&suJQ8IFJ,~>
168 r?;5trZVE"+sQr@s!%DtruqH!r?;<!+sR#B"!WOF,5m>s,5d8s,5m>t+omGt+p!KDqhY4qs+pRs
169 s+pRsreQ+LJKfXhJKinorDidqs&K$tl;[iarD`jtq,IIq<W<$t<W2sr<W<$s<W<$t<W2ss<<3'j
170 <W<$t<W)ms<W)ms<W)jt<WE"t!rl8#rVuUlrr3(#s&K*t<<E2#<W<"!<WDhorr3"!s8,dts&K*t
171 <<E2#<W<"$<W?'!s8H""s&E(ss8Q*ts7TFos&K*u<W)jt<WE"t!rl8#rr3(#s&E(ts8>q!s&K*n
172 <<3'u<<E2#<W<"#<W?)!rD`q!<E9%u"',A$<W2ss<W2ss<<3'\<WE*t<W)ms<<3'u<<E2#s8#ao
173 s8H!us8,gqrrH."r`/str`/psr`&suJQ8IFJ,~>
174 r?;5trZVE"+sQr@s!%DtruqH!r?;<!+sR#B"!WOF,5m>s,5d8s,5m>t+omGt+p!KDqhY4qs+pRs
175 s+pRsreQ+LJKfXhJKinorDidqs&K$tl;[iarD`jtq,IIq<W<$t<W2sr<W<$s<W<$t<W2ss<<3'j
176 <W<$t<W)ms<W)ms<W)jt<WE"t!rl8#rVuUlrr3(#s&K*t<<E2#<W<"!<WDhorr3"!s8,dts&K*t
177 <<E2#<W<"$<W?'!s8H""s&E(ss8Q*ts7TFos&K*u<W)jt<WE"t!rl8#rr3(#s&E(ts8>q!s&K*n
178 <<3'u<<E2#<W<"#<W?)!rD`q!<E9%u"',A$<W2ss<W2ss<<3'\<WE*t<W)ms<<3'u<<E2#s8#ao
179 s8H!us8,gqrrH."r`/str`/psr`&suJQ8IFJ,~>
180 V]l+sJKfXhJKfXhg`h;Lq,IFprD`jtel;_MrD`jtM,aQUrD`jtaAi6?JQ78$pf2h~>
181 V]l+sJKfXhJKfXhg`h;Lq,IFprD`jtel;_MrD`jtM,aQUrD`jtaAi6?JQ78$pf2h~>
182 V]l+sJKfXhJKfXhg`h;Lq,IFprD`jtel;_MrD`jtM,aQUrD`jtaAi6?JQ78$pf2h~>
183 JKfXhJKfXhJKfYFpf7:me5cJILK4<Qa&N->JQ78$pf2h~>
184 JKfXhJKfXhJKfYFpf7:me5cJILK4<Qa&N->JQ78$pf2h~>
185 JKfXhJKfXhJKfYFpf7:me5cJILK4<Qa&N->JQ78$pf2h~>
186 JKfXhJKfXhJKfYFJQ78$JQ78$J,~>
187 JKfXhJKfXhJKfYFJQ78$JQ78$J,~>
188 JKfXhJKfXhJKfYFJQ78$JQ78$J,~>
189 s!!"MJMVj5JMVp7s&FVDJP:VgJP:\iJ,~>
190 s!!"MJMVj5JMVp7s&FVpJTu`jJTuflJ,~>
191 s!!"MJMVj5JMVp7s&FW<JXM(WJXM.YJ,~>
192 s!!!oJH16$JH1B(s!%JCJ_Yh3fA*"uJ_ZCCs&FR~>
193 s!!!oJH16$JH1B(s!%JCJ_G\/f@lksJ_H7?s&FR~>
194 s!!!oJH16$JH1B(s!%JCJ^o>%f@?MnJ^on5s&FR~>
195 s!!!oJH16$JH1B(s!%JCJ_Yh3f\?K,TA0DHJ_ZFDs&FR~>
196 s!!!oJH16$JH1B(s!%JCJ_G\/f\-?*T@s8FJ_H:@s&FR~>
197 s!!!oJH16$JH1B(s!%JCJ^o>%f[U!%T@EoAJ^oq6s&FR~>
198 s!!!oJH16$JH1B(s!%JCrS4(C!8O7E!8O7E!<8_I!M0:BglgIm<Ib~>
199 s!!!oJH16$JH1B(s!%JCrS!qA!8=+C!8=+C!<8_G!La">g611i<Ib~>
200 s!!!oJH16$JH1B(s!%JCrRIS;!7db=!7db=!<8_B!KdA5eWSJ_<Ib~>
201 s!%CA!7UiGs3pfE!7TEtrR:]Fs3prIqpYQFrR:WD!7UE;rR:]Fs3p-2s3pB9s3pW@s3pB9s3pT?
202 !7UK=!7U'1!7U`D!7U-3!n..unc8^=q#CEDJH16$c2dkgs&K'R!;iG-!;iG-!;iG-!<8_I!M0:B
203 glgIm<Ib~>
204 s!%CA!7UiGs3pfE!7TEtrR:]Fs3prIqpYQFrR:WD!7UE;rR:]Fs3p-2s3pB9s3pW@s3pB9s3pT?
205 !7UK=!7U'1!7U`D!7U-3!n..unc8^=q#CEDJH16$c2dkgs&K'P!;iG+!;iG+!;iG+!<8_G!La">
206 g611i<Ib~>
207 s!%CA!7UiGs3pfE!7TEtrR:]Fs3prIqpYQFrR:WD!7UE;rR:]Fs3p-2s3pB9s3pW@s3pB9s3pT?
208 !7UK=!7U'1!7U`D!7U-3!n..unc8^=q#CEDJH16$c2dkgs&K'K!;`A%!;`A%!;`A%!<8_B!KdA5
209 eWSJ_<Ib~>
210 s!%FBs3poH"4I5Me,04Ge("Eue,97Ndf9Bs!!(LE!!:ULe,97He,9:He+!D<e,97Ndf9Bs!!(L4
211 !!C[M!7UE;"4I5Me+WhEdf9Bsn,NR>!!(LA!<:O=!!(L1!!(LD!!(LC!!(L=!!:ULe+!D<e+itD
212 dt%LM!6tTE,6([Bg]75E_uT\-_uT\-_uTh1g]<uHJ_ZFDs&FR~>
213 s!%FBs3poH"4I5Me,04Ge("Eue,97Ndf9Bs!!(LE!!:ULe,97He,9:He+!D<e,97Ndf9Bs!!(L4
214 !!C[M!7UE;"4I5Me+WhEdf9Bsn,NR>!!(LA!<:O=!!(L1!!(LD!!(LC!!(L=!!:ULe+!D<e+itD
215 dt%LM!6tTE,6([Bg&V#C_>sJ+_>sJ+_>sV/g&[WBJ_H:@s&FR~>
216 s!%FBs3poH"4I5Me,04Ge("Eue,97Ndf9Bs!!(LE!!:ULe,97He,9:He+!D<e,97Ndf9Bs!!(L4
217 !!C[M!7UE;"4I5Me+WhEdf9Bsn,NR>!!(LA!<:O=!!(L1!!(LD!!(LC!!(L=!!:ULe+!D<e+itD
218 dt%LM!6tTE,6([BeH#H=]`@o%]`@o%]`A)*eH(d4J^oq6s&FR~>
219 s!%IC!n..urVurIr;ZiHrW!#K!7THu!7UlH!n..ur;ZiHqu?iJ!!(LH!!(LI!!:ULe+!D<e,97J
220 df@kq!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LC!!:ULe+3P>e)gW1e+`nCe*-i7
221 df9BsnGiR<q#CEDJH16$c2dkgs&K'R!;iG-!;iG-!;iG-!<8_I!M0:BglgIm<Ib~>
222 s!%IC!n..urVurIr;ZiHrW!#K!7THu!7UlH!n..ur;ZiHqu?iJ!!(LH!!(LI!!:ULe+!D<e,97J
223 df@kq!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LC!!:ULe+3P>e)gW1e+`nCe*-i7
224 df9BsnGiR<q#CEDJH16$c2dkgs&K'P!;iG+!;iG+!;iG+!<8_G!La">g611i<Ib~>
225 s!%IC!n..urVurIr;ZiHrW!#K!7THu!7UlH!n..ur;ZiHqu?iJ!!(LH!!(LI!!:ULe+!D<e,97J
226 df@kq!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LC!!:ULe+3P>e)gW1e+`nCe*-i7
227 df9BsnGiR<q#CEDJH16$c2dkgs&K'K!;`A%!;`A%!;`A%!<8_B!KdA5eWSJ_<Ib~>
228 s!%CA!7UoI!7UlH#1EPPdf9Bsci=-r!7UlH!7UlH!7UoI!7UoIs3puJ"4I5Me*I&9df@kq!!(L6
229 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LA!!(L>!!C[M!7UlH!n.,LrR:cH!Rh&Je,'+F
230 e,B@Ge,KCKdfBBrr;clHrVuuJ!<1IE!!LaN!7LrIe,B@Ge,01Ge,9:GdfBHtJH16$c2dkgs&K'R
231 !;lZ3!O@mcL]`NnS$]K>!;lZ3!O@mcL]`NnS$]K>!;lZ3!O@mcL]`NnS$]K>!<;rO!Q10!L]`No
232 TuOCn!M0:BglgIm<Ib~>
233 s!%CA!7UoI!7UlH#1EPPdf9Bsci=-r!7UlH!7UlH!7UoI!7UoIs3puJ"4I5Me*I&9df@kq!!(L6
234 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LA!!(L>!!C[M!7UlH!n.,LrR:cH!Rh&Je,'+F
235 e,B@Ge,KCKdfBBrr;clHrVuuJ!<1IE!!LaN!7LrIe,B@Ge,01Ge,9:GdfBHtJH16$c2dkgs&K'P
236 !;lZ1!O@pdM?AftS@#T=!;lZ1!O@pdM?AftS@#T=!;lZ1!O@pdM?AftS@#T=!<;rM!Q13"M?Afu
237 U;aFl!La">g611i<Ib~>
238 s!%CA!7UoI!7UlH#1EPPdf9Bsci=-r!7UlH!7UlH!7UoI!7UoIs3puJ"4I5Me*I&9df@kq!!(L6
239 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LA!!(L>!!C[M!7UlH!n.,LrR:cH!Rh&Je,'+F
240 e,B@Ge,KCKdfBBrr;clHrVuuJ!<1IE!!LaN!7LrIe,B@Ge,01Ge,9:GdfBHtJH16$c2dkgs&K'K
241 !;cT+!N_=YK`d*eQ`dX-!;cT+!N_=YK`d*eQ`dX-!;cT+!N_=YK`d*eQ`dX-!<;rH!POWmK`d*f
242 S\VP]!KdA5eWSJ_<Ib~>
243 s!%CA!7UoI!7UlH!n..urVurId/X9t!!(LH!!(LH!!(LH!<1FL!7LqsrVurIm/R7;!!(LH!!(L6
244 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LA!!(L?!!(LI!!(LH!!:ULe,97Kdf9BsrVurI
245 r;ZiHrVurIr;ZrK!7TEr!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LF!!(LH!!(LI!!(LI!<:N!
246 !.b-q!<48C<W:bRqtn;4OQu]B"5VFhV6e)?qtn;4OQu]B"5VFhV6e)?qtn;4OQu]B"5VFhV6e)?
247 s81RPPNr#E"5VFiYPR#S!5%"eScF>sP2-(;J,~>
248 s!%CA!7UoI!7UlH!n..urVurId/X9t!!(LH!!(LH!!(LH!<1FL!7LqsrVurIm/R7;!!(LH!!(L6
249 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LA!!(L?!!(LI!!(LH!!:ULe,97Kdf9BsrVurI
250 r;ZiHrVurIr;ZrK!7TEr!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LF!!(LH!!(LI!!(LI!<:N!
251 !.b-q!<48C<W:\Pqtn52P3_uE"5_OlVR+,>qtn52P3_uE"5_OlVR+,>qtn52P3_uE"5_OlVR+,>
252 s81LNQ0\;H"5_OmYkm&R!5$qcRK.omP1oq9J,~>
253 s!%CA!7UoI!7UlH!n..urVurId/X9t!!(LH!!(LH!!(LH!<1FL!7LqsrVurIm/R7;!!(LH!!(L6
254 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LA!!(L?!!(LI!!(LH!!:ULe,97Kdf9BsrVurI
255 r;ZiHrVurIr;ZrK!7TEr!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LF!!(LH!!(LI!!(LI!<:N!
256 !.b-q!<48C<W:MKqYRr,Np6E?"5M:bTX2<3qYRr,Np6E?"5M:bTX2<3qYRr,Np6E?"5M:bTX2<3
257 s81=IOQlWA"5M:cX8:?H!5$b^OT9s_P1BS4J,~>
258 s!%CA!7UoI!7UlH!n..urVurIdfBEsrVurIr;ZiHrVurIp](BE!7UoI!7UB:s3prI!7UlH!7U66
259 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7UT@!7UlH!7UlH"Od>Ne'n3p!7UcE!7UiG
260 s3poH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH!n.,Lr6tTE!7UoI!7UlH!7QK!JH3sqs!%JC
261 rnIMNqnrMks8CULf`\GDn;ss!`!!tt2JL&,_umhf2K\]3!;lZ3!JpdSf`'P,XmGP=ZMMK>bi-J?
262 bk/gV_f7SK_YqCT_.GTIpV[(/qnrMks8CULf`\GDn;ss!`!!tt2JL&,_umhf2K\]3!<;rO!JpdS
263 f`'P,XmGP>`;A<r!8QAB=;M#Q9Y]?;"P\;_F4pNI"5.QNJ+q_!ScF>sP2-(;J,~>
264 s!%CA!7UoI!7UlH!n..urVurIdfBEsrVurIr;ZiHrVurIp](BE!7UoI!7UB:s3prI!7UlH!7U66
265 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7UT@!7UlH!7UlH"Od>Ne'n3p!7UcE!7UiG
266 s3poH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH!n.,Lr6tTE!7UoI!7UlH!7QK!JH3sqs!%JC
267 rn7ALqn`Gms4lB,g]XeJn<1*#_?@\r3c2\2_?7Pe4*LA8!;lZ1",d-6g\fh0Y3teBZMVK>\d7<4
268 !OrI._?@\r3c2\2_?7Pe4*LA8!;lZ1",d-6g\fh0Y3teBZHL)f_/hYS_#;+P^M,cQpVHq1qq;.0
269 s4lB,g]XeJn<:ceg'Ic5g8%1K!ukOpgY)e`IQM`)rRqA*E]epIg&[WBJ_H:@s&FR~>
270 s!%CA!7UoI!7UlH!n..urVurIdfBEsrVurIr;ZiHrVurIp](BE!7UoI!7UB:s3prI!7UlH!7U66
271 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7UT@!7UlH!7UlH"Od>Ne'n3p!7UcE!7UiG
272 s3poH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH!n.,Lr6tTE!7UoI!7UlH!7QK!JH3sqs!%JC
273 rm_#Fqn3)cs4,WseHDl;muFNn]`bug4)DP-]`YiZ4*C;2!;cT+",6d*eGRi"WU'#5Xo#d4R3(A$
274 !L"f$]`bug4)DP-]`YiZ4*C;2!;cT+",6d*eGRi"WU'#5XinB\]Q-)M]D]DF\nF0JpUpS,qpbe&
275 s4,WseHDl;muP6\eHl6+eVc<l"se3:gXQGVI6;Z#rRD"uEBJdGeH(d4J^oq6s&FR~>
276 s!%CA!7UoI!7UlH!Rh&Ge("Eue,01Ge,97He,B=Ie+`nDdfB9onGiR<qu?`Gr;ZiHlMpq6r;ZiH
277 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*Ao`,!@r;ZiHr;ZiHr;clHrVurIq>^NEq>gQErr<&J
278 r;ZiHr;ZiHrVurIr;ZiHrVurIr;ZiHr;ZoJ!7UlH!7UlH!7UoI!7UlH!7QK!JH3sqs!%JCrnIMN
279 qnrMks8LdOg]Xe@nB73o_udRh!<'h=U+-9ZAc9OKVa1=G`!p]^P?M>1`5KJs?(4W4pr!10qnrMk
280 s8LdOg]Xe@nB73r_u[j#qSWESb3QtH`QRnl%<51->$o.b`5,\aRnn2%_uT]3_uY\ornID,"KphT
281 bF&.E!6k/T!QN:?`!p]^P?M>1`5KJs?(4W4pr!14qqM4.s8LdOg]Xe@nB7Btg]egH]@kG]&_l(M
282 Hr-#2B%btpfje?X:k8>r!M0:BglgIm<Ib~>
283 s!%CA!7UoI!7UlH!Rh&Ge("Eue,01Ge,97He,B=Ie+`nDdfB9onGiR<qu?`Gr;ZiHlMpq6r;ZiH
284 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*Ao`,!@r;ZiHr;ZiHr;clHrVurIq>^NEq>gQErr<&J
285 r;ZiHr;ZiHrVurIr;ZiHrVurIr;ZiHr;ZoJ!7UlH!7UlH!7UoI!7UlH!7QK!JH3sqs!%JCrn7AL
286 qn`Aks8LmRhZU4Gn][Er_?-tS!<'b;J/eV1Jc3FeO=L=o_@:QbQ!Rq8_SX&p@@U8?pqd%.qn`Ak
287 s8LmRhZU4Gn][Eu_?$PPqSE7oJEt&QU`8sC%<GI5?=L^e_S9GdS5XY,_>sK1_?#PorndV2"L7(Y
288 baJ@F!P&I/_>u]Ji5,qE;jCZu^r!t'?X]I'GPK#Ts81LNMZ<\4rSIa_jmgQdpt>p.MT"/cALQ<e%
289 =V9A?Y\3Hg=KqGS5b+8g&[WBJ_H:@s&FR~>
290 s!%CA!7UoI!7UlH!Rh&Ge("Eue,01Ge,97He,B=Ie+`nDdfB9onGiR<qu?`Gr;ZiHlMpq6r;ZiH
291 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*Ao`,!@r;ZiHr;ZiHr;clHrVurIq>^NEq>gQErr<&J
292 r;ZiHr;ZiHrVurIr;ZiHrVurIr;ZiHr;ZoJ!7UlH!7UlH!7UoI!7UlH!7QK!JH3sqs!%JCrm_#F
293 qn3&bs4@8&rn.FSipXsPpq6``0*(sa"CMlG.%U=M!dGI\kIh=F<0LTs]=knh?t#L&FniWMqYRr-
294 L&]d(f`'P,WoEKgPP`#o;e>g=!>hNs]`CfBoXt]S<0LTs]=knh?t#L&FniWMqYRr-L&]d(f`'P,
295 WoEKgPP`#oQ5oV3!>hNh]a]!]P?hY0]tM!b@@C,;pq6\-qpbb%s4@8&rn.FSipXsUpsfR<QH.F\
296 2e:[n%=M6??>7j<e^A)>RT+k5eH(d4J^oq6s&FR~>
297 s!%CA!7UlH"4I5Me,'+Fe("Eue+s%Hdf9BsrVurIp](<CqZ$WFnGiR<q>^WH!!(L4!!C[M!7UE;
298 "4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LF!!(LA!!(LG!!(LI!<:LK!7UlH"4I5Me,'+Fe,01G
299 e,97Kdf@kGrVurIr;ZiHrVurIr;ZrK!!(LG!!(LH!!:ULe,B@Ie,97He,B=Ie,B@Idt%LM!6tTE
300 ,6([Bg]76K_uY\orndV2"NR[Fb)?)6"2dWM!<0n@\-RT!W$H<\_u^p.!9_9022mWi=^Ak[>[F7l
301 N]?gP!;lZ3!JpdThYl=7a0)GbMu1En`QS+r!QiFK_u[j"oY_1rN0']8?,=?^?DWpI3;CDlqtn;4
302 M#[J2rSIauY,]X&qSWBWp;@!RaPauG22mWi=^Ak[>[F7lN]?gP!<;rO!JpdThYl=7a0)GbMu290
303 !;bIOgB--b%5s0,TNYmZfjeBcQ&[m"g]<uHJ_ZFDs&FR~>
304 s!%CA!7UlH"4I5Me,'+Fe("Eue+s%Hdf9BsrVurIp](<CqZ$WFnGiR<q>^WH!!(L4!!C[M!7UE;
305 "4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LF!!(LA!!(LG!!(LI!<:LK!7UlH"4I5Me,'+Fe,01G
306 e,97Kdf@kGrVurIr;ZiHrVurIr;ZrK!!(LG!!(LH!!:ULe,B@Ie,97He,B=Ie,B@Idt%LM!6tTE
307 ,6([Bg&V$I_?#Poro*h8"Nn!ObDl>7"2GkL!<0h>U^EC%PmX>d_?)ER!9_3.3fT8r?=L[a?Xfn!
308 O?WHV!;lZ1!K-pViVha=b-A(lNVgQnF%Q5F!>;I!_?"FKoYM%uNKKrA@_]Zb@]#KR55;tpqtn52
309 MZ<\7rSdt&Z)u3/qn`B.)tq,L'!'s-%6BK2U0_<D^L(HIQ]OE+_>sW5g&[*2ro*h8"Nn!ObDlDQ
310 !!)lL!S7G.g'p-'OeQ2sf@OVEVO*B/pt>b;!.ijegAb0'~>
311 s!%CA!7UlH"4I5Me,'+Fe("Eue+s%Hdf9BsrVurIp](<CqZ$WFnGiR<q>^WH!!(L4!!C[M!7UE;
312 "4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LF!!(LA!!(LG!!(LI!<:LK!7UlH"4I5Me,'+Fe,01G
313 e,97Kdf@kGrVurIr;ZiHrVurIr;ZrK!!(LG!!(LH!!:ULe,B@Ie,97He,B=Ie,B@Idt%LM!6tTE
314 ,6([BeH#IC]`WuggY;\^"l7+sW5sej]`YPPYQ4[9#&5BW\9\Cbrk/A#U&aAi%6KK-TNu!;\mT!B
315 PE%j%]`@p+]`WuggY;\^"l7+sW5sel]`BUFqRln8Zg5:*.$O;:%6KK-TNu!;\mT!BPE%j%]`@p+
316 ]`WuggY;\^"l7+sW5sel]`C`>p:UJ4Zf&M+4,])k?"(=U?t,mpN^!6O!<;rH",6d0g\on2h8H=l
317 aGB`D!!)lG!QGK$eI=X!NM'TkdaDc<UQ^^'psfD-!.i[`ec/X"~>
318 s!%ICr6tWFs3pfE!7THuqpYNEs3poH!7UfFrmU]D!7UH<qpYNEs3p-2s3pB9s3plGrmUfGs3pB9
319 s3plGrmUiHr6tE@!7UfFrmLrLdf9CHe,B=Ie,'+Fe,'.De,KCKdfBBrrW)lF!<CUI!!C[M!7UiG
320 !7UlH!n.,LrmLrLdf9CGe,KFIdfBHtJH16$c2dkgs&K'R!;lZ3%>b&CiQGCU/7-ZNaS1Vg_uk`Q
321 _uTeT!I[!-_uZnPr58R8kJRgD>FUDB=^><>VN%6MD>;$Lqtn;@M#ZGmb??GJ?I.'@pP\pe#KP!.
322 bfn2I`;IjL`!+6*bfRlHoY_2Q>FUDB=^><>VN%6MD>;$Lqtn;@M#ZGmb??GJ?I.'@pP\pe$cU<-
323 `6?3Bbfe,H`;IjZ`!"0)bfe#j`!pEbRtm_@?!Ud6NM'?ipr!14qqMX:s5Dq[=tD42cdKo/Mu290
324 !;kOQd"rOmg^S=0Rtm_AARo/FNM'BtptPnA!.ipgh#CB)~>
325 s!%ICr6tWFs3pfE!7THuqpYNEs3poH!7UfFrmU]D!7UH<qpYNEs3p-2s3pB9s3plGrmUfGs3pB9
326 s3plGrmUiHr6tE@!7UfFrmLrLdf9CHe,B=Ie,'+Fe,'.De,KCKdfBBrrW)lF!<CUI!!C[M!7UiG
327 !7UlH!n.,LrmLrLdf9CGe,KFIdfBHtJH16$c2dkgs&K'P!;lZ1%>t2GjO/<Q<I<<Hb4ptl_?3VK
328 _>sSP!@rd$_?#6>r5&F6kJ@[E?CcnI>@CoKW/mZWDtq0Lqtn5>MZ;_tdWnelHe-]hpl50f#VUcu
329 $O_0q]E/!3!#P4C#/*J4%VI8ToYM&R?CcnI>@CoKW/mZWDtq0Lqtn5>MZ;_tdWnelHe-]hpl50f
330 $t3/Q]EOEP#S;F$]E/!3#8b7j<"]?fZ0B+7CgNZgUK_/7@]5?^>As;R!<;rM%>t2GjO/<Q<I<<H
331 b4ptng&M-Mg&f9.38<-rF^L\qUKhJFA#PH_>^?+u!La">g611i<Ib~>
332 s!%ICr6tWFs3pfE!7THuqpYNEs3poH!7UfFrmU]D!7UH<qpYNEs3p-2s3pB9s3plGrmUfGs3pB9
333 s3plGrmUiHr6tE@!7UfFrmLrLdf9CHe,B=Ie,'+Fe,'.De,KCKdfBBrrW)lF!<CUI!!C[M!7UiG
334 !7UlH!n.,LrmLrLdf9CGe,KFIdfBHtJH16$c2dkgs&K'K!;cT+%>Fi=hpnK]NMP1P`qP;b]`TIE
335 ]`A&F!>;7.]`C'<r4N(1kIh=@?^ZV?>[UrKUl:mKDYUmFqYRr8L&^#eeYA+`Ut<r4pPA^[#S_tL
336 #8NfCV#gPq!*o*.#,O'X(P`X'oXt]M?^ZV?>[UrKUl:mKDYUmFqYRr8L&^#eeYA+`Ut<r4pPA^[
337 $m_+OV%e"r"<4&JV#gPq#@+sB5Rdra[ctI7CgWTaT3Pc3@\esS>&O,K!<;rH%>Fi=hpnK]NMP1P
338 `qP;deGoUIeH=:23d09.%<Z'HKqDX`B4I`rSm-I7eH(d4J^oq6s&FR~>
339 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCrnIMNqnru#s5_BXEM9Ic0@Aq^Lr9,."KrNV_uTeT!A'E5
340 _u[UVr58R8kJRhH?<`qXU0(a"Oe>`__YD%Lqtn;AM#ZP[0QEefJhPO6s+nSj`!OQ/`l,j?`5KX=
341 n&57J"NA=$bK'7n%DlFUS;X+D?DipY<a`f>_uT]3`"%V'jNK;tTr`i!dH:Ib_u.F^a2u9=bfe#E
342 `QZ9=`Q\;!"j+p+`5^!b`!sRi>F^VG=C.nfTN5I;pr!14qqM[;s5_BXEM9Ic0@Aq^Lthj_!!)uQ
343 rVus*\(f[Ifk"EYMkX?]VidWRB\E19!M0:BglgIm<Ib~>
344 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCrn7ALqn`i#s5qg3Ogi3!=P)d:MS]2,"H5%O_>sSP!=QC9
345 _?%+Rr5&F6kJ@\D@:,RaUg%<,P+l,i_"bbHqtn5?MZ;hg<fsl.SljV.s,+Yj_?gejPe`Uk_SWJd
346 nA5FG,\4Ei/HrEO_@=:h?_*.O>@OOoU0;'Bpqd%.qn`i#s5qg3Ogi3!=P)d:MS]5-%3_4XYQHVV
347 ^m>>D_QOIK_?Re(@C3[X*pLNN^gUT@N20ZeW03lYA&.lV!<;rM%Z:;Ke5h^@_Oal]kl6Onr7V,N
348 rS%5N!>j/<g'uYJ@%E7P>[s^qU0DEbpt>b;!.ijegAb0'~>
349 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCrm_#Fqn3Jns5DRfP_R):NnWRoKtR;r"BSpC]`A&F!<p"4
350 ]`F*Dr4N(1kIh>:@UGU\TNbj$Nh0B`]D0&>qYRr9L&^,`Mj/t6O,hrTs+S,`]a4rsT=Sn]]tJ;D
351 n@](8%XbgY&d#N6]a_S_?^lkE>@F@gSloR8pq6\(qn3Jns5DRfP_R):NnWRoKtR>s%1]MRF::sH
352 \o&\)]l#k0]`tnWG."P5=m<U/]4,-:LnIs\V2h-MA%VNL!<;rH%YarAf8GlJ_iKi3jSsq`r7(cI
353 rRLlI!B&<[eIBr@@%2tF>[jOiSm#mWpsfD-!.i[`ec/X"~>
354 s!!!oJH16$JH1B(s!%JCrnIMNqnru#s6!O7W/%=^L0j-EM8T80"hu7W`5DZT_uU(TrkniT!W9k9
355 !9V3-_Hg<7N1lu-T2f:9pV[(/qnru#s6!O7W/%=^L0j-EM8T80!R&O_`!"<&`5Tsi_u[j#rknlW
356 bf01l$c61PS;a/9OIoN\_Y:tKqtn;AM#ZX@J#J.$\V=GTs,"Yk`!+?(`5Km=rknr``5KX=rkniW
357 bPf?ZbiltQ_Hg<7N1lu-T2f:9pV[(3qqM[;s6!O7W/%=^L0j-EM;.s`!!)oO!lnslg>!(hA6PL^
358 Tq[X@<bU1\g]<uHJ_ZFDs&FR~>
359 s!!!oJH16$JH1B(s!%JCrn7ALqn`i#s64fs]Vr`lTR?)*Mo#>."h#&T_SQ<P_>s_Rrk\]O!rTn8
360 !9V-+^gUQ?NM<53TNPd?pVHq-qn`i#s64fs]Vr`lTR?)*Mo#A/$GZ_>_SX"h_SV9]nA53R3<$br
361 XTH<0_@+.f?Cd(MUlqBRA&.iU!;lZ1%Z:;NH'u=D_p"d$li2mZr5&mM[_eaF]u%Y#"2_p7.K70b
362 H;4CU!Ped#_@+.f?Cd(MUlqBRA&.iU!<;rM%Z:;NH'u=D_p"d$li2mrr7V,Nr7V8+]0nj:g'cMG
363 ?_*1NUlqBSCY/=7!La">g611i<Ib~>
364 s!!!oJH16$JH1B(s!%JCrm_#Fqn3Gms5g%hERC^\F/J.#LASXfOY")W]`A&F!<Kk4]`GMGr4N(1
365 k.M/7?sT7ZT:h18>%>2=]`@p+]a]\qjeQO/dATi^VW[u6r4NHF!O9>OXpi"W21P,/!B>6$]`MjR
366 ]^rfE]3np6MP$Q$Sm#X9pUpS'qn3Gms5g%hERC^\F/J.#LASXn"Lu-5,eLb'Xpi"W21PV=!B>f4
367 ]`GGEke.A9?sT7ZT:h18>%>2=]`A*0eII<5jeQO/dATi^VW[u6eGRhs!;t@Ld]"4>g=6SZB3q'b
368 T:h18>ADU\eH(d4J^oq6s&FR~>
369 s!!!oJH16$JH1B(s!%JCrnIMNqnru#s6;)$E,`1dUFYa3M8T80!E<t9_uKf:_uU(TrkniT!W9k9
370 !9M-*_-C*1Mi4**@)DWU!;lZ3%Z(/M.[Y0o[&p)RmJi$\r58TZrknuZbJ_?=b4*@LaSj$WbONLW
371 _-C*1Mi4**@)DWU!;lZ3%Z(/M.[Y0o[&p)RmJi$\r58`^`5KX<rknuZbJ_?=b5T<Zans<F`!O7b
372 =IG)*S5it6p;?t2qqM[;s6;)$E,`1dUFYa3M;%m_!!)lN!SISPh#.65g^2YE=db2+S5s=Vp=o\?
373 !.ipgh#CB)~>
374 s!!!oJH16$JH1B(s!%JCrn7ALqn`i#s6NXeQ']\4\5_nrMo#>.!@=<9_>jT8_>s_Rrk\]O!rTn8
375 !9M'(^L1<9NK'N4AAIoU!;lZ1%Z:;Q;Ql@PbJ^nimf/3]rPAT?%fX<KY7\Xg7rIh5!>_^7_?$bO
376 n\PUI?sK1\NLj9`_"PVFqtn5?MZ<$@YEbHt`4/e7s,4_l_?IIT_SUU^rk\iB&]2CTDZ7KQ(&e79
377 !<<>e_?mtb>ap_4SloU>p;-h0qq;O;s6NXeQ']\4\5_nrMqIs]!!)lL!R_,JgAM$3g'QAD?(6h5
378 Sm#p]p=]P9!.ijegAb0'~>
379 s!!!oJH16$JH1B(s!%JCrm_#Fqn3Jns6,Gb_9$:p?&n7NL:mGt!>DX8]`8'3]`A/Hrk/??#Q278
380 !9Lm#\mSa1M27U'@_;?I!;cT+%YarHNHN(ZAmJ]&li2^PrOi5T3<$SpDFV=Q)kHK3!=H14]`D\8
381 n\#7??sB%ULmhIU]Cro<qYRr9L&^@rFhu13?!WKVs+\2b]`j]A]tGtTrk/JQ7_QJSSc6;,$3C80
382 !<=##]a;8X>FC>(RTX+3p:UJ+qpc11s6,Gb_9$:p?&n7NL=?(N!!)lG!OWR;eboL.eHsZ:>a^G)
383 RTaISp=02+!.i[`ec/X"~>
384 s!!!oJH16$JH1B(s!%JCrnIMNqnru#s6M4sNb"?ZR4Ie,MSoA1q>gQ6!A'E5_u[UVr58R8jhqJA
385 >ZI#DL6YhI_Y1nJqtn;AM#ZfkOH*k8ZC*64s,+_m_u[j#rPSi^`5Ka<nAG=MrPS`VbONLW_-C!)
386 LPD'q?c)NT!;lZ3%Z(/O.Zf[$PHpT,nGeB`r58`]`5K[<rPSi^`5Ka<rkni\`T"fB_-C!)LPD'q
387 ?c)NT!<;rO%Z(/O.Zf[$PHpT,nGeC"r7h8PqV2,("52H9fje'ILPD'rBA*"6!M0:BglgIm<Ib~>
388 s!!!oJH16$JH1B(s!%JCrn7ALqn`i#s6`dbVi7k!YZ1/mN5>G/q>gQ4!=QC9_?%+Rr5&F6jh_>=
389 ?WrbPLmM=T_"PVFqtn5?MZ<*BWi(f[`NW>3s,=em_?#iLrk\i!0>bRCVsqP("Mk#R!G!kR_?mta
390 >*b#$QWmq7p;-h,qn`i#s6`dbVi7k!YZ1/mN5>J0"elsQ_F\qM_?GrQ_SR.frk\[=^uE3;^L(01
391 M27L&@_h]S!<;rM%Z:;S;Q?XRYf3hGnc+R#r7V,NqUttt#hdo<f4J6QM27L'C"N(4!La">g611i
392 <Ib~>
393 s!!!oJH16$JH1B(s!%JCrm_#Fqn3Jns6GZL?*nf9PE,)2LV3Puq>gQ/!<p"4]`F*Cr4N(1jh1u3
394 ?s/\IK9KMK]Cro<qYRr9L&^IuZ!F_\3KoKks+e8c]`C-Crk/ImKY>&,Z1,F-!keNG!@ENj]a;8X
395 =d+PlP?VM.p:UJ&qn3Jns6GZL?*nf9PE,)2LV3T!"\NLB]c<^E]`g9H]tFfYrk/=6]]-U2\mS[)
396 KnGRn@_;?I!<;rH%YarKNNlcrG<(kImf/'kr7(cIqUGVJ*8/jKdUuaIKnGRoC=;h+!KdA5eWSJ_
397 <Ib~>
398 s!#5YrR:]Fs3prIqpYQFrR:cHqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pE:!7U?9!7UK=
399 s3pcD!7QK!JH2JGs!%JCrnIMNqnru#s6j,jRsn_A>@-q$Mo5;-!!*#:!I[!-_uZnPr58R8k/7YD
400 >Z6W3OHG*S;dR?8_uT]3`"%V'moi\[IUAsV?M"2T_u7LS`lnA""ie^'`66-h_u\'#rkni[bOWRZ
401 _-BouIuoeDN`09$pV[(/qnru#s6j,jRsn_A>@-q$Mo5M3"i\['`5g"!`!+0'`5Kj<rkni\`T+lE
402 _-BouIuoeDN`09$pV[(3qqM[;s6j,jRsn_A>@-q$Mqe0b#lrc9.@SW<^KiA[g].?Qg].?Qg].?I
403 g^DeF</lBhOb&NlA_Hh5!M0:BglgIm<Ib~>
404 s!#5YrR:]Fs3prIqpYQFrR:cHqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pE:!7U?9!7UK=
405 s3pcD!7QK!JH2JGs!%JCrn7ALqn`i#s6t8YYapT]IspthNPYA+!!*#8!@rd$_?#6>r5&F6k/%M@
406 ?W`>>Ock?Y=CK#>_>sK1_@DJ'n9B5_SVXk,IJ!Q!_>V4O:M]sH"\<[N_?daB_?L+S_SWtoFRm9V
407 ^L(*'JWZ+JOB>r,pVHq-qn`i#s6t8YYapT]IspthNPYS1"^tEJ_BGWP_?EJN_SQSirk\[<\)Y=5
408 ^L(*'JWZ+JOB>r,pVHq1qq;O;s6t8YYapT]IspthNS46`#lr]57]=beZ8c.[g&M-Og&M-Og&M-G
409 g'cME=cS&qP(Sj!C"N+5!La">g611i<Ib~>
410 s!#5YrR:]Fs3prIqpYQFrR:cHqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pE:!7U?9!7UK=
411 s3pcD!7QK!JH2JGs!%JCrm_#Fqn3Jns6ZVX5^^13Su;/ZLV3Ap!!*#3!>;7.]`C'<r4N(1k.M/6
412 ?WW/7NK/II=CSo:]`@p+]afbrmA-OCI(Me<Vt0kC]`#ME*h<5C"WX/J]`bq9]`nMK]tLELTCTZ'
413 \mJNsIZ9A:NEBZ%pUpS'qn3Jns6ZVX5^^13Su;/ZLV3T!"XKAH]aq=G]`fCJ]tFQ[rk/=5\`:@2
414 \mJNsIZ9A:NEBZ%pUpS,qpc11s6ZVX5^^13Su;/ZLt)@Q#lrN+?*DZ#T,*seeGoUJeGoUJeGoUB
415 eI0f;=GqWfNdcsjC!ub+!KdA5eWSJ_<Ib~>
416 s!$_.!7TU$!7UlH#1EPPdf9Bsq>^TG!7UlH!n..um/R.8r;[&N!!(IJ!7U04"4I5Me*m>>df9Bs
417 pAb<E!!(L;!!C[M!7UZB"4I5Me*m>;e*[29e+!D<e+itDdt%LM!2KVp,6([Bg]76K`"%V'n^T./
418 LkoRnh=gl,_Y:tK!<0n@[g7N!W$H<Z_uKf3_uKf9_uKf9_uKf8`!sOf:kX(L:/HjpLJV<npr!10
419 qnru#s7+ViE/9<\/`$.#Mo,G2!Q`C^`;dpY_u\'$rPS][rPS][rPT#d`5Ka?`PopAaRd=Z_-Bfi
420 G_f*kMgC.T?GZET!;lZ3%Z(/TeLPTpLh&*npA^&frPSl[ai)->a8X$WaT'0ZbJsP"#04p,`5Ka:
421 rknf\rPS][rPS][pV[NW>Yp)uLe^d)HA>='_>(qKs81R]M#["q.r^<#A1cX2s,5V/g^*u9gpT`^
422 "!(n)n_=*ErS.AQrS.AQp=p,1@o7o(Legm+HA>@/g%a>'ScF>sP2-(;J,~>
423 s!$_.!7TU$!7UlH#1EPPdf9Bsq>^TG!7UlH!n..um/R.8r;[&N!!(IJ!7U04"4I5Me*m>>df9Bs
424 pAb<E!!(L;!!C[M!7UZB"4I5Me*m>;e*[29e+!D<e+itDdt%LM!2KVp,6([Bg&V$I_@DJ'o%[0(
425 USNQCj7iS5_"Y\G!<0h>U^<@%Q3sGc_>jT1_>jT7_>jT7_>jT6_@=7e<JGgW;H&O%Lf@cspqd%.
426 qn`i#s74rDNh`D'<TEiRNPPM0!?7j6_?CgT_SQGRrPAO7rPAO7rPAj@_SR?r]r*OdVt7b7^L'uq
427 HAYU!N-pF\@))KR!;lZ1%Z:;Wgf'6.UkDb.p]$5grPA^]S&3#TYl;KC)5k?g"K279"t_p>^S=l>
428 rk\X8rPAO7rPAO7pVIBS?WDi,MGdB3I#(a0^\GYGs81L[MZ<8&;i[WKKN7(,s,G\/g'Ic5g6so)
429 "X\KIn_*sCrRq5OrRq5Op=]u-AlaY4MGmK5I#(d9fD+&#RK.omP1oq9J,~>
430 s!$_.!7TU$!7UlH#1EPPdf9Bsq>^TG!7UlH!n..um/R.8r;[&N!!(IJ!7U04"4I5Me*m>>df9Bs
431 pAb<E!!(L;!!C[M!7UZB"4I5Me*m>;e*[29e+!D<e+itDdt%LM!2KVp,6([BeH#IC]afbrnDfIL
432 _T@Rnl1P(3]D&u=!<0Y9Bd9@_HO$hR]`8',]`8'2]`8'2]`8'1]a_P[<J,IM;Gr<qKiDHkpq6\(
433 qn3Jns7#'-FMc.TNp66:LV*Mu!=c:4]`eeK]tFKOrOi12rOi12rOiL;]tFl$\s*j/Z1GX<\mJHi
434 G)&snLj4VQ@(Q-H!;cT+%YarPj,A)sabPo@p&BfZrOi@EXhDCR[JmiC$aICY!jM[;"qk4J\<K4g
435 rk/:3rOi12rOi12pUq$I?WD`%LJh$+G_K+)](ir=s81=VL&^Z&N-)qYLQ:Wls+o/%eHc0*eUJqK
436 #r7S2eGoUJeGoUJeGoUCeIBr=<eGRN;cAKsKiMd6psfD-!.i[`ec/X"~>
437 s!$_.!7TU$!7UlH!n..ur;ZiHqu?iJ!!(LH!!:ULe*R,8e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH
438 !!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L;!!(L:!!(L<!!(LD!!(K!!.b-G!<48C<W:bRqtn;A
439 M#[)=f3BgV?/PMTs,=hh_uKf9_uub_!to/C`;BW2_uKf9_uKf9_uKf8`!p?SHuFO.>[0sSFF[&"
440 pr!10qnru#s7>m7>Uq=1htm3LN5GP3!R&L^`!X],`5K[>bfdrCbl,H[bl,Hdbf%H=b08)NbJs.l%
441 ;/F`Dh(Jc>YK`kJ4s_Q_uT]3`"%V'oCUX>.k=o_qYL5N_YqCVbJqK=bJjJ!%a2i0`5^$FbJ_?@b
442 KS/NrPS][rPS][rPS][pV[MR:4-u193b^qJolN:CA>^Is81R]M#[)=f3BgV?/PMTs,GaVg^S3uH
443 uFO/A7J>cFF[),ptPnA!.ipgh#CB)~>
444 s!$_.!7TU$!7UlH!n..ur;ZiHqu?iJ!!(LH!!:ULe*R,8e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH
445 !!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L;!!(L:!!(L<!!(LD!!(K!!.b-G!<48C<W:\Pqtn5?
446 MZ<>AhKi+!IHC>%s,Onh_>jT7_?><,!ZQXf_YaE0_>jT7_>jT7_>jT6_@:3WIW:!:?scc`G(EM-
447 pqd%.qn`i#s7H!@H;dajjneiRNkkV1!=?:8_?pR[_STmo!*-nQ!<'b7!<'b@!5cUS+T`d7#eKWE%
448 ;A^hEJ%(q?VuH!JPg:Z_>sK1_@DJ'o_%'e;cA,+qYL5P_#;+R$F[gg#/'rP%LBY__Ia5W<Pl=5$
449 3_l0rPAO7rPAO7rPAO7pVIAR;LWV<:gdX-K6DfCD>:sJs81L[MZ<>AhKi+!IHC>%s,YgVg'r($I
450 W:!;B4b%oG(EP7pt>b;!.ijegAb0'~>
451 s!$_.!7TU$!7UlH!n..ur;ZiHqu?iJ!!(LH!!:ULe*R,8e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH
452 !!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L;!!(L:!!(L<!!(LD!!(K!!.b-G!<48C<W:MKqYRr9
453 L&^`8k,+0!WU'BUs,"D_]`8'2]`_^T""0W;^&.m+]`8'2]`8'2]`8'1]a\[RH>S..?XHZ\EIL`#
454 pq6\(qn3Jns75dDVN-\9lhUAVM7if#!<ft4]a=nQ]tHl?!0t72!<'S2!<'S;!56'u'*KkP"M+-;%
455 ;A^dD1>Ah?Vu>nISakU]`@p+]afbro(2"@NfL+)q>(&I]`#MI"Lu.Y"2"QG%Ks>U]g`5,Q+`_A"
456 UHuOrOi12rOi12rOi12pUq#M;L320:g[R,J8p$7D"t[Ds81=VL&^`8k,+0!WU'BUs,,:LeI?OtH
457 >S./AnFqkEILc-psfD-!.i[`ec/X"~>
458 ruqLEdfBBrrW)oGrW)oGrrE#Hec5d#!7UlH!7UlH!7UoI!7UoIs3h#LdfBBrli7+9!7UlH!7U66
459 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UE;!7UB:!Rh&Je,B@Ge,01Ge,9:G
460 dfBHtq#CHE!<1II!!(LH!!C[MdfBBrrr<)K!<1IH!<(CH!!1OKrmQDuJH41"s!%JCrnIMNqnru#
461 s7H!Xp\F[_r;HToNP`oX%5_g<G">cF[T?"DEb@<*_uT]3`"%V'o_%qPq>1!drVcbU_T]q-1hprP
462 86NF1=%IOUB/]P'!;lZ3%Z(/Wp%J.UqYU3hrVqkobesrIC2\8d=gth@89])e2Yb2js81R]M#[,?
463 p@nCZqu$Eks,PdVg^Q,UDg"][c-0HbGB.=TptPnA!.ipgh#CB)~>
464 ruqLEdfBBrrW)oGrW)oGrrE#Hec5d#!7UlH!7UlH!7UoI!7UoIs3h#LdfBBrli7+9!7UlH!7U66
465 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UE;!7UB:!Rh&Je,B@Ge,01Ge,9:G
466 dfBHtq#CHE!<1II!!(LH!!C[MdfBBrrr<)K!<1IH!<(CH!!1OKrmQDuJH41"s!%JCrn7ALqn`i#
467 s7Q*[q"ad`r;HToO2/uV%6A?GGYDAMZs$.JF(mc3_>sK1_@DJ'p%J.Tq>1!drVcbW^s'Y)3c/k]
468 9O,!4>"j0^Bfu1-!;lZ1%Z:;Zp@n@XqYU3hrVqqobeafMD/jeo>d^qB9R(Vm4SZbns81L[MZ<AC
469 p\=R\qu$Eks,bjVg'p,\EHk2fbKF<gG]RR^pt>b;!.ijegAb0'~>
470 ruqLEdfBBrrW)oGrW)oGrrE#Hec5d#!7UlH!7UlH!7UoI!7UoIs3h#LdfBBrli7+9!7UlH!7U66
471 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UE;!7UB:!Rh&Je,B@Ge,01Ge,9:G
472 dfBHtq#CHE!<1II!!(LH!!C[MdfBBrrr<)K!<1IH!<(CH!!1OKrmQDuJH41"s!%JCrm_#Fqn3Jn
473 s7>mUp\=R]r;HToMS%*G%6SBBF\H&EYZXVADeD9/]`@p+]afbroCV_Mq"agbrVcbR]?Iqt4DJ_U
474 9O+g+=\EmUB0Q+(!;cT+%YarSo_%tRq>:*grVqbebe4HJC2J)e>d1G896G/c55;eks81=VL&^c:
475 p%S7Wqu$Eks,5=LeI=ZVD08Q_a2VI[F`1nWpsfD-!.i[`ec/X"~>
476 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me("F#df9Bsr;ZiHr;ZiHr;ciG"9?mNe'n9r!7U?9"4I5M
477 e,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He*d8:e*mA;e,B=Ie,'+F
478 e,97He,B=Ie,B@Ie,KFGe,KCJe,B=Kdf@kq!!C[Me'n9r"4I8!e,B=Kdf@kq!!C[M!7UoI!7QK!
479 JH44#s!%JCrnIMNqnrMunFuqaoT6u7`"$iS@7!ngTq@oN5@6Tr_th4Nqtn;4P485G!q_Slbet!4
480 6"*)YUnOEP9g;uKFMmpm!;lZ3!KusHrrVhS_p$%/F$X5$;l$+ZSkVFV5'4^<_uTi7g]<]0p\t<e
481 P2"49%Xp`Q6Wpt-Za!Cn?U'(qq:l"B!.ipgh#CB)~>
482 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me("F#df9Bsr;ZiHr;ZiHr;ciG"9?mNe'n9r!7U?9"4I5M
483 e,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He*d8:e*mA;e,B=Ie,'+F
484 e,97He,B=Ie,B@Ie,KFGe,KCJe,B=Kdf@kq!!C[Me'n9r"4I8!e,B=Kdf@kq!!C[M!7UoI!7QK!
485 JH44#s!%JCrn7ALqn`Atnb<%bood/8_@C`YA4K[qTUhTK6XW9)_>1qJqtn52PO\DI!qh_mbeaj5
486 7V#"iUS+0J:IAMWG/=!k!;lZ1!L*'JrrVkV_9Bb+G"-"4<hl=YS52L[6[$<A_>sW5g&[K/p\t<f
487 PhF:7%Y7,\86r^3Z*..q?poV"q:Yk<!.ijegAb0'~>
488 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me("F#df9Bsr;ZiHr;ZiHr;ciG"9?mNe'n9r!7U?9"4I5M
489 e,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He*d8:e*mA;e,B=Ie,'+F
490 e,97He,B=Ie,B@Ie,KFGe,KCJe,B=Kdf@kq!!C[Me'n9r"4I8!e,B=Kdf@kq!!C[M!7UoI!7QK!
491 JH44#s!%JCrm_#Fqn3#knFuqaoT$T.]af0S@7F:iS=,a?6XN6(]_T5@qYRr,O7;oD!q_Mcbe4L/
492 7U\beT:D=::IAJWFhIO`!;cT+!KZaErrVhQ]Ze&!F[fe/<hGnMQqp(V7!60<]`A*0eH(g%p\t<e
493 OOVM)%Y.&X7pNC(XfGGi?U]Lpq:,M.!.i[`ec/X"~>
494 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L"!<:OI!!(LH!!(LI!!(LC!!(LF!!(L;!<:OI!!(LH!!(L6
495 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L9!!(L<!!(LH!!:UL!;t=E!!(LI
496 !!(LH!!(LC!!(LG!!(LH!!:ULe,97Jdf@kq!!1OKqpYQF!7QK!JH4'ts!%JCrnIMNqnrNAPP9k6
497 PHrBM%`<6A@AolgQ^F:E0lOnGq8<:1qnrNAPP9k6PHrBM%`<6A@AolgQ^F:E0lOnGq8<:1qnrNA
498 PP9k6PHrBM%`<6A@AolgQ^F:E0lOnGq8<:5qqM4kQM619Q,Cf#%bl=eC:ppUWN34013qR-q:l"B
499 !.ipgh#CB)~>
500 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L"!<:OI!!(LH!!(LI!!(LC!!(LF!!(L;!<:OI!!(LH!!(L6
501 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L9!!(L<!!(LH!!:UL!;t=E!!(LI
502 !!(LH!!(LC!!(LG!!(LH!!:ULe,97Jdf@kq!!1OKqpYQF!7QK!JH4'ts!%JCrn7ALqn`B>Q1p.:
503 Q*JNL%`*0GA#>lcQ'[qC2K?LJq8*./qn`B>Q1p.:Q*JNL%`*0GA#>lcQ'[qC2K?LJq8*./qn`B>
504 Q1p.:Q*JNL%`*0GA#>lcQ'[qC2K?LJq8*.3qq;(gR.lI=Qbpr"%bZ7kCq?sRW2Zq.2gj61q:Yk<
505 !.ijegAb0'~>
506 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L"!<:OI!!(LH!!(LI!!(LC!!(LF!!(L;!<:OI!!(LH!!(L6
507 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L9!!(L<!!(LH!!:UL!;t=E!!(LI
508 !!(LH!!(LC!!(LG!!(LH!!:ULe,97Jdf@kq!!1OKqpYQF!7QK!JH4'ts!%JCrm_#Fqn3$4OS=G0
509 O0-U=%_QaB@A96UOcu)63,lIAq7Qe)qn3$4OS=G0O0-U=%_QaB@A96UOcu)63,lIAq7Qe)qn3$4
510 OS=G0O0-U=%_QaB@A96UOcu)63,lIAq7Qe.qpb_^PP9b3P.o,i%b,hfC::=DUnt)"3I9-'q:,M.
511 !.i[`ec/X"~>
512 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L#!!(LG!!(LH!!(LI!!(LC!!(LF!!(L<!!(LG!!(LH!!(L6
513 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L9!!(L<!!(LH!!:ULe,97He,97H
514 e,B=Ie,97He+`nCe,01Ge,97Jdf@kq!!:ULe,97Jdf@kn!!(K!!.b-t!<48C<W:bRqmOEO_nj'u
515 [Bd$B[CNue_YD%LqmOEO_nj'u[Bd$B[CNue_YD%LqmOEO_nj'u[Bd$B[CNue_YD%Ls0g\kgY(-)
516 bf@`Dbg=kmgA'G(ScF>sP2-(;J,~>
517 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L#!!(LG!!(LH!!(LI!!(LC!!(LF!!(L<!!(LG!!(LH!!(L6
518 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L9!!(L<!!(LH!!:ULe,97He,97H
519 e,B=Ie,97He+`nCe,01Ge,97Jdf@kq!!:ULe,97Jdf@kn!!(K!!.b-t!<48C<W:\PqmO?M_8!Xm
520 ['6^;[(!Z^_"bbHqmO?M_8!Xm['6^;[(!Z^_"bbHqmO?M_8!Xm['6^;[(!Z^_"bbHs0gVig"4^!
521 b/M<<b0JGef_F/$RK.omP1oq9J,~>
522 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L#!!(LG!!(LH!!(LI!!(LC!!(LF!!(L<!!(LG!!(LH!!(L6
523 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L9!!(L<!!(LH!!:ULe,97He,97H
524 e,B=Ie,97He+`nCe,01Ge,97Jdf@kq!!:ULe,97Jdf@kn!!(K!!.b-t!<48C<W:MKqR4'G]XkSY
525 YH+\(YHt[K]_K/?qR4'G]XkSYYH+\(YHt[K]_K/?qR4'G]XkSYYH+\(YHt[K]_K/?s0gGdeC)Xb
526 `PK=*`Q?BQe+hGoOT9s_P1BS4J,~>
527 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LE!!C[M!7UoI!7U]C"4I5Me,97He+*J=e+s%H
528 df9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L7!!(L=!!(LH!!:UL
529 e,B@Ie,97He,B=Ie,B@Ie+`nCe,01Ge,B@IdfBHtr;ZoJ!7UlH!n..ur;ZrK!!(K!!.b-t!<48C
530 <W:bRqk1k-qk1k-qk1k-s.J-JScF>sP2-(;J,~>
531 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LE!!C[M!7UoI!7U]C"4I5Me,97He+*J=e+s%H
532 df9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L7!!(L=!!(LH!!:UL
533 e,B@Ie,97He,B=Ie,B@Ie+`nCe,01Ge,B@IdfBHtr;ZoJ!7UlH!n..ur;ZrK!!(K!!.b-t!<48C
534 <W:\Pqk1e+qk1e+qk1e+s.J'HRK.omP1oq9J,~>
535 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LE!!C[M!7UoI!7U]C"4I5Me,97He+*J=e+s%H
536 df9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L7!!(L=!!(LH!!:UL
537 e,B@Ie,97He,B=Ie,B@Ie+`nCe,01Ge,B@IdfBHtr;ZoJ!7UlH!n..ur;ZrK!!(K!!.b-t!<48C
538 <W:MKqOkM%qOkM%qOkM%s.ImCOT9s_P1BS4J,~>
539 s!%IC!7UfFrR:`GrR:]FrmTX&qpYNEs3poH!7UfFrmUfGrR:9:qpYNEs3p-2s3pB9s3plGrmUfG
540 s3pB9s3plGrmUfGs3p96!7UK=!7UlH!n.,LrmLrLdf9CGe,KFIdfBHtp](<CqZ-WE!s$dMe,97J
541 df@kq!!:UL!<(CG!!(K!!.b-t!<48C<Ip`mT%KV7s.J-JScF>5P+M\RJ,~>
542 s!%IC!7UfFrR:`GrR:]FrmTX&qpYNEs3poH!7UfFrmUfGrR:9:qpYNEs3p-2s3pB9s3plGrmUfG
543 s3pB9s3plGrmUfGs3p96!7UK=!7UlH!n.,LrmLrLdf9CGe,KFIdfBHtp](<CqZ-WE!s$dMe,97J
544 df@kq!!:UL!<(CG!!(K!!.b-t!<48C<IpTiRb4&/s.J'HRK.o-P+)DNJ,~>
545 s!%IC!7UfFrR:`GrR:]FrmTX&qpYNEs3poH!7UfFrmUfGrR:9:qpYNEs3p-2s3pB9s3plGrmUfG
546 s3pB9s3plGrmUfGs3p96!7UK=!7UlH!n.,LrmLrLdf9CGe,KFIdfBHtp](<CqZ-WE!s$dMe,97J
547 df@kq!!:UL!<(CG!!(K!!.b-t!<48C<Ip9`Ok>crs.ImCOT9rpP*,cEJ,~>
548 s!!!oc2[jnhZ*Z*iW/l)JH16$JH5]os&FXMJcC<$JcD#8nr*YI<E4P~>
549 s!!!oc2[jnhZ*Z*iW/l)JH16$JH5]os&FXMJcC<$JcD#8nqdGF<E4P~>
550 s!!!oc2[jnhZ*Z*iW/l)JH16$JH5]os&FXMJcC<$JcD#8nq$r><E4P~>
551 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^iCo`#!nqc-XH~>
552 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^i@o`#!nqc-XH~>
553 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^i9o`#!nqGgOG~>
554 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
555 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
556 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
557 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
558 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
559 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
560 s!#5YrR:]Fs3poHrR:`GrR:`GrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3oEs!7U?9!7UK=
561 s3pcD!7U<8!7UfF!7SLZ!7RYB!7UfF!7U<8!7TR#!7T[&s3pN=s!%JCJcC<$JcC<$Q2^lDs7Y4N
562 ScJXf<Ib~>
563 s!#5YrR:]Fs3poHrR:`GrR:`GrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3oEs!7U?9!7UK=
564 s3pcD!7U<8!7UfF!7SLZ!7RYB!7UfF!7U<8!7TR#!7T[&s3pN=s!%JCJcC<$JcC<$Q2^lAs7Y.L
565 RK34b<Ib~>
566 s!#5YrR:]Fs3poHrR:`GrR:`GrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3oEs!7U?9!7UK=
567 s3pcD!7U<8!7UfF!7SLZ!7RYB!7UfF!7U<8!7TR#!7T[&s3pN=s!%JCJcC<$JcC<$Q2^l:s7XtG
568 OT>5X<Ib~>
569 s!$_.!7TU$!7UlH$.AkSdf9Bs!!(LH!!:ULe,97Jdf@kq!!(L=!!(LH!!^mP!7LoJe*-i7df9Bs
570 n,NR>!!(LB!!C[M!7UE;"4I5Me+WhEdf9Bse,TKtmJm79nGiR<q#CEDm/R.8qZ$WFkPtV3kPtV3
571 mJm79p](<Cp&G*AlMpq6cN!soqZ$WFm/R.8r;ZiHkPtV3pAb3BirB).qZ$`I!!(L>!<48C<It1$
572 s+13$s-<TbN;rk3!n<C_rS.OI!;fbrJ,~>
573 s!$_.!7TU$!7UlH$.AkSdf9Bs!!(LH!!:ULe,97Jdf@kq!!(L=!!(LH!!^mP!7LoJe*-i7df9Bs
574 n,NR>!!(LB!!C[M!7UE;"4I5Me+WhEdf9Bse,TKtmJm79nGiR<q#CEDm/R.8qZ$WFkPtV3kPtV3
575 mJm79p](<Cp&G*AlMpq6cN!soqZ$WFm/R.8r;ZiHkPtV3pAb3BirB).qZ$`I!!(L>!<48C<It1$
576 s+13$s-<TbM?!P.!n*7[rRqCC!;fbrJ,~>
577 s!$_.!7TU$!7UlH$.AkSdf9Bs!!(LH!!:ULe,97Jdf@kq!!(L=!!(LH!!^mP!7LoJe*-i7df9Bs
578 n,NR>!!(LB!!C[M!7UE;"4I5Me+WhEdf9Bse,TKtmJm79nGiR<q#CEDm/R.8qZ$WFkPtV3kPtV3
579 mJm79p](<Cp&G*AlMpq6cN!soqZ$WFm/R.8r;ZiHkPtV3pAb3BirB).qZ$`I!!(L>!<48C<It1$
580 s+13$s-<TbK)bf"!mQhOrRD%5!;]\qJ,~>
581 s!$_.!7TU$!7UlH!n..ur;ZoJ!7UlH!n..ur;ZoJ!7UlH!7UK=!7UlH!n..ur;ZiHlMpq6r;ZiH
582 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHe,TKtmf3@:nGiR<q#CEDm/R.8qZ$WFc2[jn
583 q#CEDpAb3Bli7%7\GuWYq>^NEmJm79iW&u-p](<CiW&u-qu?`Gr;ZiHoDnn8s&FXMJcC<$JcD#8
584 !K@'Xg]Z8fFckGXg]X2Kqc-XH~>
585 s!$_.!7TU$!7UlH!n..ur;ZoJ!7UlH!n..ur;ZoJ!7UlH!7UK=!7UlH!n..ur;ZiHlMpq6r;ZiH
586 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHe,TKtmf3@:nGiR<q#CEDm/R.8qZ$WFc2[jn
587 q#CEDpAb3Bli7%7\GuWYq>^NEmJm79iW&u-p](<CiW&u-qu?`Gr;ZiHoDnn8s&FXMJcC<$JcD#8
588 !K$jUg'#ubFckAVg'!iEqc-XH~>
589 s!$_.!7TU$!7UlH!n..ur;ZoJ!7UlH!n..ur;ZoJ!7UlH!7UK=!7UlH!n..ur;ZiHlMpq6r;ZiH
590 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHe,TKtmf3@:nGiR<q#CEDm/R.8qZ$WFc2[jn
591 q#CEDpAb3Bli7%7\GuWYq>^NEmJm79iW&u-p](<CiW&u-qu?`Gr;ZiHoDnn8s&FXMJcC<$JcD#8
592 !J:@NeH=6WFccRP"H`]\<E4P~>
593 ruqLEdfBBrrW)oGrW)oGrrE#Hec5d#!7UlH!n..ur;ZiHqZ$]H!7UoIs3p?8!n..ur;ZiHlMpq6
594 r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHe,TKtmf3C;!<1IH!<(CE!!(LH!<1FJ
595 !7U]CrR:`GrmLrLdf9CIdfTU!!!)uHrr<)K!<1I@!<:OI!!1OKrmUlI!Rh&Je,KCJe,97IdfB?q
596 quH`Fp](<Cq#LHDr;cfFrrE#Hr;cfFrr<)K!<1IG!<:OI!!1OKrmUiHrmLlJe+`qAe,KCKdfBBr
597 oDem?rW)rH!s$dM!<(CG!!(LI!!(LG!!(LH!<:OI!!1OKrmUlI!Rh&Je,KCJe,97IdfB?qq>^NE
598 rW)oGrVurIrW!#K!!)uHrr<)K!<1II!<(CG!!(LH!!(L?!<48C<It1$s+13$s-<TfN;q\gg6DSZ
599 #bB`*gn"NC<E4P~>
600 ruqLEdfBBrrW)oGrW)oGrrE#Hec5d#!7UlH!n..ur;ZiHqZ$]H!7UoIs3p?8!n..ur;ZiHlMpq6
601 r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHe,TKtmf3C;!<1IH!<(CE!!(LH!<1FJ
602 !7U]CrR:`GrmLrLdf9CIdfTU!!!)uHrr<)K!<1I@!<:OI!!1OKrmUlI!Rh&Je,KCJe,97IdfB?q
603 quH`Fp](<Cq#LHDr;cfFrrE#Hr;cfFrr<)K!<1IG!<:OI!!1OKrmUiHrmLlJe+`qAe,KCKdfBBr
604 oDem?rW)rH!s$dM!<(CG!!(LI!!(LG!!(LH!<:OI!!1OKrmUlI!Rh&Je,KCJe,97IdfB?qq>^NE
605 rW)oGrVurIrW!#K!!)uHrr<)K!<1II!<(CG!!(LH!!(L?!<48C<It1$s+13$s-<TfM>u;`fTcAX
606 #bBZ&g6r$=<E4P~>
607 ruqLEdfBBrrW)oGrW)oGrrE#Hec5d#!7UlH!n..ur;ZiHqZ$]H!7UoIs3p?8!n..ur;ZiHlMpq6
608 r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHe,TKtmf3C;!<1IH!<(CE!!(LH!<1FJ
609 !7U]CrR:`GrmLrLdf9CIdfTU!!!)uHrr<)K!<1I@!<:OI!!1OKrmUlI!Rh&Je,KCJe,97IdfB?q
610 quH`Fp](<Cq#LHDr;cfFrrE#Hr;cfFrr<)K!<1IG!<:OI!!1OKrmUiHrmLlJe+`qAe,KCKdfBBr
611 oDem?rW)rH!s$dM!<(CG!!(LI!!(LG!!(LH!<:OI!!1OKrmUlI!Rh&Je,KCJe,97IdfB?qq>^NE
612 rW)oGrVurIrW!#K!!)uHrr<)K!<1II!<(CG!!(LH!!(L?!<48C<It1$s+13$s-<TfK)aBOdus]Q
613 !1a&="H`]\<E4P~>
614 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me("F#df9Bsr;ZoJ!!)uHqZ$WFrW)rH!<CU:!!C[M!7UlH
615 !7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TBs!7UE;s3prI!7UfF!7UlH
616 !7UoI!7UoIs3puJr6tNC!n..urW)uI!<CUJ!<:LK!7UlH"4I8!e,B=Kdf9CGe,97He,B@Ie,B=L
617 df@kGrW!#K!7UlH"4I5Me+itDe+WhBe+`nCe,B=Ie,97Kdf9Bsqu?`Gr;ZrK!7TEr!!(LH!!(LI
618 !<:OI!!:ULe,B=Ie+`nCe,97Kdf@kGrVurIp&G*ArVurIrW)uI!<CUI!!C[M!7UoI!7UlH!7UfF
619 !7UoIs3prI"4I8!e,B=Kdf@kq!!C[M!7U`D!7UoI!7UlH"4I5Me,B=Kdf@kq!!C[Me'n9r"4I5M
620 e,01Ge,97He+<Y?,6(Yos+13$s+138rre;\gt\S#FU+o$gn"NC<E4P~>
621 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me("F#df9Bsr;ZoJ!!)uHqZ$WFrW)rH!<CU:!!C[M!7UlH
622 !7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TBs!7UE;s3prI!7UfF!7UlH
623 !7UoI!7UoIs3puJr6tNC!n..urW)uI!<CUJ!<:LK!7UlH"4I8!e,B=Kdf9CGe,97He,B@Ie,B=L
624 df@kGrW!#K!7UlH"4I5Me+itDe+WhBe+`nCe,B=Ie,97Kdf9Bsqu?`Gr;ZrK!7TEr!!(LH!!(LI
625 !<:OI!!:ULe,B=Ie+`nCe,97Kdf@kGrVurIp&G*ArVurIrW)uI!<CUI!!C[M!7UoI!7UlH!7UfF
626 !7UoIs3prI"4I8!e,B=Kdf@kq!!C[M!7U`D!7UoI!7UlH"4I5Me,B=Kdf@kq!!C[Me'n9r"4I5M
627 e,01Ge,97He+<Y?,6(Yos+13$s+138rre2Yg=i1sFU+o"g6r$=<E4P~>
628 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me("F#df9Bsr;ZoJ!!)uHqZ$WFrW)rH!<CU:!!C[M!7UlH
629 !7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TBs!7UE;s3prI!7UfF!7UlH
630 !7UoI!7UoIs3puJr6tNC!n..urW)uI!<CUJ!<:LK!7UlH"4I8!e,B=Kdf9CGe,97He,B@Ie,B=L
631 df@kGrW!#K!7UlH"4I5Me+itDe+WhBe+`nCe,B=Ie,97Kdf9Bsqu?`Gr;ZrK!7TEr!!(LH!!(LI
632 !<:OI!!:ULe,B=Ie+`nCe,97Kdf@kGrVurIp&G*ArVurIrW)uI!<CUI!!C[M!7UoI!7UlH!7UfF
633 !7UoIs3prI"4I8!e,B=Kdf@kq!!C[M!7U`D!7UoI!7UlH"4I5Me,B=Kdf@kq!!C[Me'n9r"4I5M
634 e,01Ge,97He+<Y?,6(Yos+13$s+138rrdrRe^^5gFU+nreWBk.<E4P~>
635 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L"!<:OI!!(LH!!:ULe,97He,B@Ie+itDe*mA;e,B=Ie,97H
636 e*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He'\3re+!D<e,97Jdf9CGe,97H
637 e,B=Ie,97He+`q@dfBHtr;ZoJ!7UlH!n..ur;ZoJ!7UlH!7UWA!7UoI!7UlH!n..ur;ZoJ!7UlH
638 "4I5Me*[29e+`nCe,9:He,01Ge,04CdfBHtr;ZiHr;ZiHrVurIr;ZoJ!7UoI!7U]C!7UlH!n..u
639 r;ZiHpAb3Br;ZiHr;ZlI!;k7F!!(LI!!(LI!!(LE!!(LI!!(LH!!:ULe,97Jdf@kq!!C[M!7UcE
640 !7UlHqpYQF!7UoI!Rh&GdfBHtr;ZrK!!(LG!!(LH!!(L?!<48C<It1$s+13$s-<TbN;rn4!:g!e
641 #4^K?!;fbrJ,~>
642 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L"!<:OI!!(LH!!:ULe,97He,B@Ie+itDe*mA;e,B=Ie,97H
643 e*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He'\3re+!D<e,97Jdf9CGe,97H
644 e,B=Ie,97He+`q@dfBHtr;ZoJ!7UlH!n..ur;ZoJ!7UlH!7UWA!7UoI!7UlH!n..ur;ZoJ!7UlH
645 "4I5Me*[29e+`nCe,9:He,01Ge,04CdfBHtr;ZiHr;ZiHrVurIr;ZoJ!7UoI!7U]C!7UlH!n..u
646 r;ZiHpAb3Br;ZiHr;ZlI!;k7F!!(LI!!(LI!!(LE!!(LI!!(LH!!:ULe,97Jdf@kq!!C[M!7UcE
647 !7UlHqpYQF!7UoI!Rh&GdfBHtr;ZrK!!(LG!!(LH!!(L?!<48C<It1$s+13$s-<TbM?!S/!:]pd
648 #4U?8!;fbrJ,~>
649 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L"!<:OI!!(LH!!:ULe,97He,B@Ie+itDe*mA;e,B=Ie,97H
650 e*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He'\3re+!D<e,97Jdf9CGe,97H
651 e,B=Ie,97He+`q@dfBHtr;ZoJ!7UlH!n..ur;ZoJ!7UlH!7UWA!7UoI!7UlH!n..ur;ZoJ!7UlH
652 "4I5Me*[29e+`nCe,9:He,01Ge,04CdfBHtr;ZiHr;ZiHrVurIr;ZoJ!7UoI!7U]C!7UlH!n..u
653 r;ZiHpAb3Br;ZiHr;ZlI!;k7F!!(LI!!(LI!!(LE!!(LI!!(LH!!:ULe,97Jdf@kq!!C[M!7UcE
654 !7UlHqpYQF!7UoI!Rh&GdfBHtr;ZrK!!(LG!!(LH!!(L?!<48C<It1$s+13$s-<TbK)bi#!:Kdb
655 #4C$(!;]\qJ,~>
656 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L#!!(LG!!(LH!!:ULe,97Kdf9BspAb3BnGiR<qu?`Gr;ZiH
657 lMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHdJs9rnGiR<r;ZoJ!7UlH!7UlH
658 !7UoI!7UlH!7U`D!7UlH!n..ur;ZoJ!7UlH!n..ur;ZoJ!7UlH!7UWA!7UoI!7UlH"4I8!e,B=K
659 df@kq!!C[M!7U?9!7U]C!7UfFs3prI!7UiG!7UfF!7UlH!7UlH!7UoI!7UlH!n.,LrmUTA!7UlH
660 !n..ur;ZiHpAb3Br;ZiHr;ZoJ!7U`D!n..ur;ZiHq>^NErVurIr;ZrK!7TEr!!:ULe,97Kdf9Bs
661 q>^NEr;ZiHq#CTI!7LoJe,'+Fe,97Kdf9Bsqu?`Gr;ZiHoDnn8s&FXMJcC<$JcD#8!K@'Pg]X2K
662 qc-XH~>
663 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L#!!(LG!!(LH!!:ULe,97Kdf9BspAb3BnGiR<qu?`Gr;ZiH
664 lMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHdJs9rnGiR<r;ZoJ!7UlH!7UlH
665 !7UoI!7UlH!7U`D!7UlH!n..ur;ZoJ!7UlH!n..ur;ZoJ!7UlH!7UWA!7UoI!7UlH"4I8!e,B=K
666 df@kq!!C[M!7U?9!7U]C!7UfFs3prI!7UiG!7UfF!7UlH!7UlH!7UoI!7UlH!n.,LrmUTA!7UlH
667 !n..ur;ZiHpAb3Br;ZiHr;ZoJ!7U`D!n..ur;ZiHq>^NErVurIr;ZrK!7TEr!!:ULe,97Kdf9Bs
668 q>^NEr;ZiHq#CTI!7LoJe,'+Fe,97Kdf9Bsqu?`Gr;ZiHoDnn8s&FXMJcC<$JcD#8!K$jMg'!iE
669 qc-XH~>
670 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L#!!(LG!!(LH!!:ULe,97Kdf9BspAb3BnGiR<qu?`Gr;ZiH
671 lMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHdJs9rnGiR<r;ZoJ!7UlH!7UlH
672 !7UoI!7UlH!7U`D!7UlH!n..ur;ZoJ!7UlH!n..ur;ZoJ!7UlH!7UWA!7UoI!7UlH"4I8!e,B=K
673 df@kq!!C[M!7U?9!7U]C!7UfFs3prI!7UiG!7UfF!7UlH!7UlH!7UoI!7UlH!n.,LrmUTA!7UlH
674 !n..ur;ZiHpAb3Br;ZiHr;ZoJ!7U`D!n..ur;ZiHq>^NErVurIr;ZrK!7TEr!!:ULe,97Kdf9Bs
675 q>^NEr;ZiHq#CTI!7LoJe,'+Fe,97Kdf9Bsqu?`Gr;ZiHoDnn8s&FXMJcC<$JcD#8!J:@FeHD!7
676 qGgOG~>
677 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LE!!^mP!7LoJe,97Jdf@kk!!(L<!!(LE!!C[M
678 !7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5Me'J'pe+*J=e,97Jdf@kr
679 !<:OH!!(LI!!(LI!<:OD!!(LI!<:LK!7UoIs3guKe,B@IdfBHtr;ZoJ!7UlH!7UWA!7UoI!7UlH
680 "4I8!!<1II!!(LI!<:OJ!!(LI!!(LH!!(LB!!(LC!!(LI!!(LH!!C[M!7UoI!n..ur;ZoJ!7UlH
681 !7UlH!7UoI!7UlH!n..uoDem?r;ZoJ!7UlH!7U]C!7UiG!7UoIs3guKe,97He,B=Kdf@kr!!(LD
682 !!(LI!!(LH!!C[MdfBBrrr<&JrW)uIrr<&JrW!&L!!(LG!!(LH!!(LI!!UgOdf9Bsr;ZoJ!7UlH
683 "4I5Me,B=Odf9Bs!!(L>!<48C<It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
684 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LE!!^mP!7LoJe,97Jdf@kk!!(L<!!(LE!!C[M
685 !7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5Me'J'pe+*J=e,97Jdf@kr
686 !<:OH!!(LI!!(LI!<:OD!!(LI!<:LK!7UoIs3guKe,B@IdfBHtr;ZoJ!7UlH!7UWA!7UoI!7UlH
687 "4I8!!<1II!!(LI!<:OJ!!(LI!!(LH!!(LB!!(LC!!(LI!!(LH!!C[M!7UoI!n..ur;ZoJ!7UlH
688 !7UlH!7UoI!7UlH!n..uoDem?r;ZoJ!7UlH!7U]C!7UiG!7UoIs3guKe,97He,B=Kdf@kr!!(LD
689 !!(LI!!(LH!!C[MdfBBrrr<&JrW)uIrr<&JrW!&L!!(LG!!(LH!!(LI!!UgOdf9Bsr;ZoJ!7UlH
690 "4I5Me,B=Odf9Bs!!(L>!<48C<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
691 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LE!!^mP!7LoJe,97Jdf@kk!!(L<!!(LE!!C[M
692 !7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5Me'J'pe+*J=e,97Jdf@kr
693 !<:OH!!(LI!!(LI!<:OD!!(LI!<:LK!7UoIs3guKe,B@IdfBHtr;ZoJ!7UlH!7UWA!7UoI!7UlH
694 "4I8!!<1II!!(LI!<:OJ!!(LI!!(LH!!(LB!!(LC!!(LI!!(LH!!C[M!7UoI!n..ur;ZoJ!7UlH
695 !7UlH!7UoI!7UlH!n..uoDem?r;ZoJ!7UlH!7U]C!7UiG!7UoIs3guKe,97He,B=Kdf@kr!!(LD
696 !!(LI!!(LH!!C[MdfBBrrr<&JrW)uIrr<&JrW!&L!!(LG!!(LH!!(LI!!UgOdf9Bsr;ZoJ!7UlH
697 "4I5Me,B=Odf9Bs!!(L>!<48C<It1$s+13$s-<TbK)bPp"H`]\<E4P~>
698 s!%IC!7UfFrR:`GrR:]FrmTX&qpYNEs3poHrR:cHqpYQFrmU?:qpYNEs3p-2s3pB9s3plGrmUfG
699 s3pB9s3plGrmUfGs3o9o!7UK=!7UlH!n.,LrmLrLdf9CGe,KFIdfBHtp]1<B!s$dM!<1FL!7LoJ
700 rmLrLdf9CHe,KCJe,97He+`q@dfBHtr;ZoJ!7UcErmLlJe,B@He,9:Ge+`q?e,KFGe,KFHe,9:G
701 e,B@Ge,KCJe,97Jdf9CGdfBHtr;ZoJ!!)uHpAk0@rr<&Jr;ZiHp](<CqZ-WE!s$dM!<(CE!!(LH
702 !!(LF!;t:H!7UlH!n..uq>gND!<CUJ!<1IH!!(LF!<(CE!!(LH!<(CH!!(LH!!(LI!<1IG!<:O=
703 !<48C<It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
704 s!%IC!7UfFrR:`GrR:]FrmTX&qpYNEs3poHrR:cHqpYQFrmU?:qpYNEs3p-2s3pB9s3plGrmUfG
705 s3pB9s3plGrmUfGs3o9o!7UK=!7UlH!n.,LrmLrLdf9CGe,KFIdfBHtp]1<B!s$dM!<1FL!7LoJ
706 rmLrLdf9CHe,KCJe,97He+`q@dfBHtr;ZoJ!7UcErmLlJe,B@He,9:Ge+`q?e,KFGe,KFHe,9:G
707 e,B@Ge,KCJe,97Jdf9CGdfBHtr;ZoJ!!)uHpAk0@rr<&Jr;ZiHp](<CqZ-WE!s$dM!<(CE!!(LH
708 !!(LF!;t:H!7UlH!n..uq>gND!<CUJ!<1IH!!(LF!<(CE!!(LH!<(CH!!(LH!!(LI!<1IG!<:O=
709 !<48C<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
710 s!%IC!7UfFrR:`GrR:]FrmTX&qpYNEs3poHrR:cHqpYQFrmU?:qpYNEs3p-2s3pB9s3plGrmUfG
711 s3pB9s3plGrmUfGs3o9o!7UK=!7UlH!n.,LrmLrLdf9CGe,KFIdfBHtp]1<B!s$dM!<1FL!7LoJ
712 rmLrLdf9CHe,KCJe,97He+`q@dfBHtr;ZoJ!7UcErmLlJe,B@He,9:Ge+`q?e,KFGe,KFHe,9:G
713 e,B@Ge,KCJe,97Jdf9CGdfBHtr;ZoJ!!)uHpAk0@rr<&Jr;ZiHp](<CqZ-WE!s$dM!<(CE!!(LH
714 !!(LF!;t:H!7UlH!n..uq>gND!<CUJ!<1IH!!(LF!<(CE!!(LH!<(CH!!(LH!!(LI!<1IG!<:O=
715 !<48C<It1$s+13$s-<TbK)bPp"H`]\<E4P~>
716 s!!!oc2[jnhZ*Z*`W5nbScAc>l2Uh5^An8_r;ZiHZN(!SYQ4\Is&G'Yr;b1Dr;`Dgr;_EKJcDeN
717 !K@'OSc\ui<E4P~>
718 s!!!oc2[jnhZ*Z*`W5nbScAc>l2Uh5^An8_r;ZiHZN(!SYQ4\Is&G'Yr;b1Dr;`Dgr;_EKJcDeN
719 !K$jLRKEQe<E4P~>
720 s!!!oc2[jnhZ*Z*`W5nbScAc>l2Uh5^An8_r;ZiHZN(!SYQ4\Is&G'Yr;b1Dr;`Dgr;_EKJcDeN
721 !J:@EOTPU[<E4P~>
722 s!!!oJH1E)!7ReFrR8%P!7S.Ps!%JCNW8qWci<qDScAWgq>Urq_NSk//f4ot"rB11XSdYLJcEUe
723 !0$LL!rGttJ,~>
724 s!!!oJH1E)!7ReFrR8%P!7S.Ps!%JCNW8qWci<qDScAWgq>Uof\;Orc.2*!g#TGsK^4H<8s2"^8
725 M=U]Kqc-XH~>
726 s!!!oJH1E)!7ReFrR8%P!7S.Ps!%JCNW8qWci<qDScAWgq>Uo]YCg.E,nL:_$Qqric[l+Is2"^8
727 K(AsDqGgOG~>
728 s!!!oJH16$JH1B(s!%JCNW8qWci<qDScAWgq>^$d!>(3@s+13frrA#MrrW8u<E4P~>
729 s!!!oJH16$JH1B(s!%JCNW8qWci<qDScAWgq>^$d!@+Xrs+13frr@oJrrW8u<E4P~>
730 s!!!oJH16$JH1B(s!%JCNW8qWci<qDScAWgq>^$d!BeSWs+13frr@ZCrrW8t<E4P~>
731 s!!!oJH16$JH1B(s!%JCNW8qWci<qDScAWgq>]sb!B0_(s+13hrrJ)Yp=oeB!;fbrJ,~>
732 s!!!oJH16$JH1B(s!%JCNW8qWci<qDScAWgq>]sb!FbtYs+13hrrIuVp=]Y<!;fbrJ,~>
733 s!!!oJH16$JH1B(s!%JCNW8qWci<qDScAWgq>]sb!02X1JcE[g!J:@FeHD!7qGgOG~>
734 s!%CA!7UiGs3pfE!7TEtrR:]Fs3poHrR:cHqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@
735 s3oEs!7U?9!7UK=s3pcD!7U<8!7UfF!7S[_s3lf)!7U!/!7Tm,!7U'1!7UQ?s!%JCNW8qWci<qD
736 ScAWgq>^Hp$3EAC[c6rXm`ghKr;ZgLJcC<$`W#sts7Y4NScJXf<Ib~>
737 s!%CA!7UiGs3pfE!7TEtrR:]Fs3poHrR:cHqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@
738 s3oEs!7U?9!7UK=s3pcD!7U<8!7UfF!7S[_s3lf)!7U!/!7Tm,!7U'1!7UQ?s!%JCNW8qWci<qD
739 ScAWgq>^Hp$3a+`^ukCglGA&hr;Zh-JcC<$`W#sqs7Y.LRK34b<Ib~>
740 s!%CA!7UiGs3pfE!7TEtrR:]Fs3poHrR:cHqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@
741 s3oEs!7U?9!7UK=s3pcD!7U<8!7UfF!7S[_s3lf)!7U!/!7Tm,!7U'1!7UQ?s!%JCNW8qWci<qD
742 ScAWgq>^Hp$4pC.b3Ag"j1&t6r;ZhpJcC<$`W#sjs7XtGOT>5X<Ib~>
743 s!%FBs3poH"4I5Me,04Ge("Eue,97Qdf9Bs!!(IJ!7UlH!7UfF!7UfF!7UK=!7UlH#1EPPdf9Bs
744 kl:h7!!(L;!!C[M!7UZB"4I5Me*m>>df9BspAb<E!!(Kt!!(L9!!(L<!!(LD!!(L8!!(LF!!(Ks
745 !!(L8!!(LF!!(LA!!(L6!!(K\!!(LD!!(L/!!(L>!!(L;!!(L1!!(L?!<48C<It2%s8;q[rrO:!
746 kP5&XrfmB^!<J(/s+13irrJ)Yp=oeB!;fbrJ,~>
747 s!%FBs3poH"4I5Me,04Ge("Eue,97Qdf9Bs!!(IJ!7UlH!7UfF!7UfF!7UK=!7UlH#1EPPdf9Bs
748 kl:h7!!(L;!!C[M!7UZB"4I5Me*m>>df9BspAb<E!!(Kt!!(L9!!(L<!!(LD!!(L8!!(LF!!(Ks
749 !!(L8!!(LF!!(LA!!(L6!!(K\!!(LD!!(L/!!(L>!!(L;!!(L1!!(L?!<48C<It2%s8;q[rrP'K
750 pA"Xgqe?$0!<Ll)s+13irrIuVp=]Y<!;fbrJ,~>
751 s!%FBs3poH"4I5Me,04Ge("Eue,97Qdf9Bs!!(IJ!7UlH!7UfF!7UfF!7UK=!7UlH#1EPPdf9Bs
752 kl:h7!!(L;!!C[M!7UZB"4I5Me*m>>df9BspAb<E!!(Kt!!(L9!!(L<!!(LD!!(L8!!(LF!!(Ks
753 !!(L8!!(LF!!(LA!!(L6!!(K\!!(LD!!(L/!!(L>!!(L;!!(L1!!(L?!<48C<It2%s8;q[rrPiu
754 r:p9mmQ(7H!<MY?s+13irrI`Op=0;.!;]\qJ,~>
755 s!%IC!n..urVurIr;ZiHrW!#K!7THu!7UlH!n..ur;ZoJ!7UlH!7UiG!7UfF!7UH<!7UlH!n..u
756 r;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHe,TKtmf3@:nGiR<q#CED
757 m/R.8qZ$WFbQ%XloDem?mf3@:S,`Q<j8]2/o)Jd>nGiR<jo>D1o)Se7s&FXMfDkdLKDtq*rVup;
758 JcC<$`r?'us7Y4NScJXf<Ib~>
759 s!%IC!n..urVurIr;ZiHrW!#K!7THu!7UlH!n..ur;ZoJ!7UlH!7UiG!7UfF!7UH<!7UlH!n..u
760 r;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHe,TKtmf3@:nGiR<q#CED
761 m/R.8qZ$WFbQ%XloDem?mf3@:S,`Q<j8]2/o)Jd>nGiR<jo>D1o)Se7s&FXMfDkdLKDtp5rVup_
762 JcC<$`r?'rs7Y.LRK34b<Ib~>
763 s!%IC!n..urVurIr;ZiHrW!#K!7THu!7UlH!n..ur;ZoJ!7UlH!7UiG!7UfF!7UH<!7UlH!n..u
764 r;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHe,TKtmf3@:nGiR<q#CED
765 m/R.8qZ$WFbQ%XloDem?mf3@:S,`Q<j8]2/o)Jd>nGiR<jo>D1o)Se7s&FXMfDkdLK`;)P)#aL8
766 WIb)#s2P'>K)bPp"H`]\<E4P~>
767 s!%CA!7UoI!7UlH#1EPPdf9Bsci=-r!7UlH!n..ur;ZiHr;ZiHqZ$WFlMq"8!7UlH!7U66!7UlH
768 !7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7UB:!Rh&Je,B@Ge,01Ge,9:GdfBHt
769 p]19ArW)rH!s$dM!<1FL!7LoJrR:cH!Rh&Je+Wk@e,B@Ge,KCKdfBBrr;clHquH`Fo`,!@quHcG
770 r;cfFrrE#Hr;cfFrr<)K!<1IG!<:OI!!1OKrmUiHrmLlJe+`qAe,KCKdfBBrpAk0@rW)oGrr<)K
771 !<1IG!<:OH!<1FJ!7U]CrR:`GrR:`GrR:cH!7UoI!7UoIrR:cHrR:?<!7UoI!7UoI!n.,LrR:cH
772 !Rh&Je,'+Jdf9Bs!<1ID!<48C<It2%s8;qMrrDQf!!!7Ts+13irrJ)Yp=oeB!;fbrJ,~>
773 s!%CA!7UoI!7UlH#1EPPdf9Bsci=-r!7UlH!n..ur;ZiHr;ZiHqZ$WFlMq"8!7UlH!7U66!7UlH
774 !7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7UB:!Rh&Je,B@Ge,01Ge,9:GdfBHt
775 p]19ArW)rH!s$dM!<1FL!7LoJrR:cH!Rh&Je+Wk@e,B@Ge,KCKdfBBrr;clHquH`Fo`,!@quHcG
776 r;cfFrrE#Hr;cfFrr<)K!<1IG!<:OI!!1OKrmUiHrmLlJe+`qAe,KCKdfBBrpAk0@rW)oGrr<)K
777 !<1IG!<:OH!<1FJ!7U]CrR:`GrR:`GrR:cH!7UoI!7UoIrR:cHrR:?<!7UoI!7UoI!n.,LrR:cH
778 !Rh&Je,'+Jdf9Bs!<1ID!<48C<It2%s8;qMrrCmS!!!O\s+13irrIuVp=]Y<!;fbrJ,~>
779 s!%CA!7UoI!7UlH#1EPPdf9Bsci=-r!7UlH!n..ur;ZiHr;ZiHqZ$WFlMq"8!7UlH!7U66!7UlH
780 !7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7UB:!Rh&Je,B@Ge,01Ge,9:GdfBHt
781 p]19ArW)rH!s$dM!<1FL!7LoJrR:cH!Rh&Je+Wk@e,B@Ge,KCKdfBBrr;clHquH`Fo`,!@quHcG
782 r;cfFrrE#Hr;cfFrr<)K!<1IG!<:OI!!1OKrmUiHrmLlJe+`qAe,KCKdfBBrpAk0@rW)oGrr<)K
783 !<1IG!<:OH!<1FJ!7U]CrR:`GrR:`GrR:cH!7UoI!7UoIrR:cHrR:?<!7UoI!7UoI!n.,LrR:cH
784 !Rh&Je,'+Jdf9Bs!<1ID!<48C<It2%s8;qMrr@]N!!#*3s+13irrI`Op=0;.!;]\qJ,~>
785 s!%CA!7UoI!7UlH!n..urVurId/X9t!!(LH!!:UL!<(CF!<1IG!<1I7!!C[M!7UlH!7U66!7UlH
786 !7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TBs!7UE;s3prI!7UfF!7UlH!7UoI!7UoI
787 s3puJr6tNC!n..urW)uI!<CUJ!<:LK!7UlH"4I8!e,B=Kdf9CGe,'+Hdf@kq!!C[Me'n9r!7UlH
788 !7UfF!7UQ?!7UfF!7UoI!7UlH"4I5Me,01Ge,97Kdf@kGrVurIr;ZiHrW)uIrW!#K!7UoI!7U]C
789 !7UlH"4I8!e,B=Ie+<VAdf@kq!!C[Me'n9r!7UlH!7UoI!7UoIs3pcD!7UlH!n..ur;ZoJ!7UlH
790 "k*J#!!(LI!!(LH!!C[M!7UK=!7UlH!7UoI!7UfF"4I5Me,B=Ie,97He,97He,B=Ie,'.F,6(Yo
791 s8)a$p6.ua"pZ5JVt9ooqOU:r":?J[Z2Xe%!;6@!rO$8m&d/F[7uHJurrE#s!!!%Ns+13irrJ)Y
792 p=oeB!;fbrJ,~>
793 s!%CA!7UoI!7UlH!n..urVurId/X9t!!(LH!!:UL!<(CF!<1IG!<1I7!!C[M!7UlH!7U66!7UlH
794 !7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TBs!7UE;s3prI!7UfF!7UlH!7UoI!7UoI
795 s3puJr6tNC!n..urW)uI!<CUJ!<:LK!7UlH"4I8!e,B=Kdf9CGe,'+Hdf@kq!!C[Me'n9r!7UlH
796 !7UfF!7UQ?!7UfF!7UoI!7UlH"4I5Me,01Ge,97Kdf@kGrVurIr;ZiHrW)uIrW!#K!7UoI!7U]C
797 !7UlH"4I8!e,B=Ie+<VAdf@kq!!C[Me'n9r!7UlH!7UoI!7UoIs3pcD!7UlH!n..ur;ZoJ!7UlH
798 "k*J#!!(LI!!(LH!!C[M!7UK=!7UlH!7UoI!7UfF"4I5Me,B=Ie,97He,97He,B=Ie,'.F,6(Yo
799 s8)a$kCG]-!t$A_^%;70nqfI@!t?ktaSu5<!;6@!q4h.D%0?h\;OmNNrrDop!!!(Os+13irrIuV
800 p=]Y<!;fbrJ,~>
801 s!%CA!7UoI!7UlH!n..urVurId/X9t!!(LH!!:UL!<(CF!<1IG!<1I7!!C[M!7UlH!7U66!7UlH
802 !7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TBs!7UE;s3prI!7UfF!7UlH!7UoI!7UoI
803 s3puJr6tNC!n..urW)uI!<CUJ!<:LK!7UlH"4I8!e,B=Kdf9CGe,'+Hdf@kq!!C[Me'n9r!7UlH
804 !7UfF!7UQ?!7UfF!7UoI!7UlH"4I5Me,01Ge,97Kdf@kGrVurIr;ZiHrW)uIrW!#K!7UoI!7U]C
805 !7UlH"4I8!e,B=Ie+<VAdf@kq!!C[Me'n9r!7UlH!7UoI!7UoIs3pcD!7UlH!n..ur;ZoJ!7UlH
806 "k*J#!!(LI!!(LH!!C[M!7UK=!7UlH!7UoI!7UfF"4I5Me,B=Ie,97He,97He,B=Ie,'.F,6(Yo
807 s8)a$d;^lN!Y-o'fCT"JgikI]";*P<i;WcT!;6@!k`JXd$3CVc?EO-orrD?`!!!=Vs+13irrI`O
808 p=0;.!;]\qJ,~>
809 s!%CA!7UoI!7UlH!n..urVurIdfBEsrVurIr;ZoJ!7UlH!7UfF!7UfF!7UE;s3prI!7UlH!7U66
810 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7UH<!7UlH!n.,Lr6tTE!7UoI
811 !7UlH!7U]Cr6kZHe,97Jdf@kq!!:ULe,97Jdf@kq!!(LC!;t:H!7UfF!7UlH!7UlH!7U<8!7UfF
812 !7UlHs3plG!7UiGqpPQGe,97He,97He,B=Ie,97Jdf@kr!!(LC!!(LH!!:ULe,97He+`q@dfBHt
813 qZ$WFr;ZiHr;ZiHrVurIr;ZiHp]1?Cr;ZiHr;ZoJ!7UfFrmUfGqpYQF!7UN>!7UiG!7UoI!n.,L
814 r6tZG!7UcE!7UiG!7UZBs!%JCNW8qWq>^Bns8N+q&,?2+.c0n!!QlS]!!4t9s8;rlrrW2#+nu$=
815 #'BkArrAVg!!$a-rrCpS!!":ms8;r`rrE&t!!!+Ps+13irrJ)Yp=oeB!;fbrJ,~>
816 s!%CA!7UoI!7UlH!n..urVurIdfBEsrVurIr;ZoJ!7UlH!7UfF!7UfF!7UE;s3prI!7UlH!7U66
817 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7UH<!7UlH!n.,Lr6tTE!7UoI
818 !7UlH!7U]Cr6kZHe,97Jdf@kq!!:ULe,97Jdf@kq!!(LC!;t:H!7UfF!7UlH!7UlH!7U<8!7UfF
819 !7UlHs3plG!7UiGqpPQGe,97He,97He,B=Ie,97Jdf@kr!!(LC!!(LH!!:ULe,97He+`q@dfBHt
820 qZ$WFr;ZiHr;ZiHrVurIr;ZiHp]1?Cr;ZiHr;ZoJ!7UfFrmUfGqpYQF!7UN>!7UiG!7UoI!n.,L
821 r6tZG!7UcE!7UiG!7UZBs!%JCNW8qWq>^Bn"98@M"Si#u9_\8\!MTtt!!60qs8;rlrrW.W%JTo(%
822 @$_h!*T7#!3Gqp!3?%u!*RbMr;c0`!;ufr!!\#SJcEai!K$jMg'!iEqc-XH~>
823 s!%CA!7UoI!7UlH!n..urVurIdfBEsrVurIr;ZoJ!7UlH!7UfF!7UfF!7UE;s3prI!7UlH!7U66
824 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7UH<!7UlH!n.,Lr6tTE!7UoI
825 !7UlH!7U]Cr6kZHe,97Jdf@kq!!:ULe,97Jdf@kq!!(LC!;t:H!7UfF!7UlH!7UlH!7U<8!7UfF
826 !7UlHs3plG!7UiGqpPQGe,97He,97He,B=Ie,97Jdf@kr!!(LC!!(LH!!:ULe,97He+`q@dfBHt
827 qZ$WFr;ZiHr;ZiHrVurIr;ZiHp]1?Cr;ZiHr;ZoJ!7UfFrmUfGqpYQF!7UN>!7UiG!7UoI!n.,L
828 r6tZG!7UcE!7UiG!7UZBs!%JCNW8qWq>^Bn"984(!r2fsEW#P1!I=qF!!7ECs8;rlrrVn0#5A0!
829 +h.=J!$qLC!8dJM!,2<2!1hR<r;c0`!:p*h!#L4dJcEai!J:@FeHD!7qGgOG~>
830 s!%CA!7UoI!7UlH!Rh&Ge("Eue,01Ge,97Jdf@kq!!(LF!!(LF!!(L<!!(LG!!(LH!!(L6!!(LH
831 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(Kr!!(L<!!(LH!!:ULe,97He,97He,B=I
832 e,97He+itDe,97Jdf@kq!!:ULe,97Jdf@kq!!:ULe,97He+itDe,97Jdf@ko!<:OI!!(LH!!(L8
833 !!(LF!!(LF!<:OI!!(LG!!(LF!!(LH!!(LH!!(LI!!(LH!!:UL!<1IA!!(LH!!:ULe,97He+itD
834 e,97Jdf@ko!<:OI!!(LH!!(LI!!(LH!!(LA!<:OJ!!(LH!!:ULe,'+Idf9BsrVurIq>^NEo)Jd>
835 qZ$fK!7LoJe,97Kdf9Bsq>^NEqu?`GpAk4;s&G'Yr;cZnr;ZltIeEaB'(,Jo!4__&!>+8h!;QQp
836 qI9's!A!j@rrN'orVus$[JBh'oc*l1!=S,>s8;r`rrD]j!!!IZs+13irrJ)Yp=oeB!;fbrJ,~>
837 s!%CA!7UoI!7UlH!Rh&Ge("Eue,01Ge,97Jdf@kq!!(LF!!(LF!!(L<!!(LG!!(LH!!(L6!!(LH
838 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(Kr!!(L<!!(LH!!:ULe,97He,97He,B=I
839 e,97He+itDe,97Jdf@kq!!:ULe,97Jdf@kq!!:ULe,97He+itDe,97Jdf@ko!<:OI!!(LH!!(L8
840 !!(LF!!(LF!<:OI!!(LG!!(LF!!(LH!!(LH!!(LI!!(LH!!:UL!<1IA!!(LH!!:ULe,97He+itD
841 e,97Jdf@ko!<:OI!!(LH!!(LI!!(LH!!(LA!<:OJ!!(LH!!:ULe,'+Idf9BsrVurIq>^NEo)Jd>
842 qZ$fK!7LoJe,97Kdf9Bsq>^NEqu?`GpAk4;s&G'Yr;cZnr;Zls9D/>d/,T,A!.jhD!@R[@!;QQp
843 oK)UE!EK*rrrMs8rVus(kkY5ZkQh(e!?1g_s8;r`rrD0[!!!shs+13irrIuVp=]Y<!;fbrJ,~>
844 s!%CA!7UoI!7UlH!Rh&Ge("Eue,01Ge,97Jdf@kq!!(LF!!(LF!!(L<!!(LG!!(LH!!(L6!!(LH
845 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(Kr!!(L<!!(LH!!:ULe,97He,97He,B=I
846 e,97He+itDe,97Jdf@kq!!:ULe,97Jdf@kq!!:ULe,97He+itDe,97Jdf@ko!<:OI!!(LH!!(L8
847 !!(LF!!(LF!<:OI!!(LG!!(LF!!(LH!!(LH!!(LI!!(LH!!:UL!<1IA!!(LH!!:ULe,97He+itD
848 e,97Jdf@ko!<:OI!!(LH!!(LI!!(LH!!(LA!<:OJ!!(LH!!:ULe,'+Idf9BsrVurIq>^NEo)Jd>
849 qZ$fK!7LoJe,97Kdf9Bsq>^NEqu?`GpAk4;s&G'Yr;cZnr;Zlj,5)!;?N0a"!)E4f!E]3t!;QQp
850 eJ[uZ!JUONrrM<lrVus<p%eUg[0-C.!D`UAs8;r`rrA>`!!$nfs+13irrI`Op=0;.!;]\qJ,~>
851 s!%CA!7UlH"4I5Me,'+Fe("Eue+s%Kdf9Bs!!(LH!!:ULe,97Jdf@kq!!(L=!!(LE!!C[M!7U04
852 "4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5Me'J'pe+*J=e,97Jdf@kr!<:OH
853 !!(LI!!(LI!<:OD!!(LI!<:LK!7UoIs3guKe,B@IdfBHtr;ZoJ!7UlH!7U`D!7UoIs3guKe,97K
854 df@hsrmUcF!7UfF!7UQ?!7UfF!7UoI!7UlH"4I5Me,B=Kdf@kq!!:ULe,97He,97He,B=Ie,97J
855 df@kh!!(LH!!:ULe,97He+itDe,B@IdfBHtr;ZrK!7LrIe,01Ge,B=Ie,B@Ie+itDe,97Jdf@kq
856 !!:ULe,97Jdf@kr!!C[M!7UlH"4I5Me,B=Ie+`nCe+s%Jdf@hs!7UoIs3puJ!7UfF!7UfF!7UZB
857 s!%JCNW8qWq>^Bn$)%>!(m*DAo#bYE!!"\JrrCmR!!s6sh>$3>8H8`3r;cZn!W5go!!i^4ZKCrN
858 aE%I_!!"JFrrM^)rVus0nGE4dr`f@%!<]=fs8=b=s8;r`rrA_k!!#05s+13irrJ)Yp=oeB!;fbr
859 J,~>
860 s!%CA!7UlH"4I5Me,'+Fe("Eue+s%Kdf9Bs!!(LH!!:ULe,97Jdf@kq!!(L=!!(LE!!C[M!7U04
861 "4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5Me'J'pe+*J=e,97Jdf@kr!<:OH
862 !!(LI!!(LI!<:OD!!(LI!<:LK!7UoIs3guKe,B@IdfBHtr;ZoJ!7UlH!7U`D!7UoIs3guKe,97K
863 df@hsrmUcF!7UfF!7UQ?!7UfF!7UoI!7UlH"4I5Me,B=Kdf@kq!!:ULe,97He,97He,B=Ie,97J
864 df@kh!!(LH!!:ULe,97He+itDe,B@IdfBHtr;ZrK!7LrIe,01Ge,B=Ie,B@Ie+itDe,97Jdf@kq
865 !!:ULe,97Jdf@kr!!C[M!7UlH"4I5Me,B=Ie+`nCe+s%Jdf@hs!7UoIs3puJ!7UfF!7UfF!7UZB
866 s!%JCNW8qWq>^Bn$"*`51SE\$m^bsf!!$s5rrB"r!!t0Lj87i..0'?Ar;cZn!Vdo=!!imR^Zta_
867 \6&e2!!$=%rrM'^rVusDr;6Kpr$)+?!<qHKs8=b=s8;r`rr>sr!!&+3s+13irrIuVp=]Y<!;fbr
868 J,~>
869 s!%CA!7UlH"4I5Me,'+Fe("Eue+s%Kdf9Bs!!(LH!!:ULe,97Jdf@kq!!(L=!!(LE!!C[M!7U04
870 "4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5Me'J'pe+*J=e,97Jdf@kr!<:OH
871 !!(LI!!(LI!<:OD!!(LI!<:LK!7UoIs3guKe,B@IdfBHtr;ZoJ!7UlH!7U`D!7UoIs3guKe,97K
872 df@hsrmUcF!7UfF!7UQ?!7UfF!7UoI!7UlH"4I5Me,B=Kdf@kq!!:ULe,97He,97He,B=Ie,97J
873 df@kh!!(LH!!:ULe,97He+itDe,B@IdfBHtr;ZrK!7LrIe,01Ge,B=Ie,B@Ie+itDe,97Jdf@kq
874 !!:ULe,97Jdf@kr!!C[M!7UlH"4I5Me,B=Ie+`nCe+s%Jdf@hs!7UoIs3puJ!7UfF!7UfF!7UZB
875 s!%JCNW8qWq>^Bn#q5iS;R#<\l)H01!!'_.rr?^1!!u?+l1`tk&-)]qr;cZn!T4Lf!!jO"bjP>i
876 WB1.[!!&McrrK)$rVut(rql]rn.,Et!>G(ks8=b=s8;r`rr=5A!!(N"s+13irrI`Op=0;.!;]\q
877 J,~>
878 s!%ICr6tWFs3pfE!7THuqpYNEs3poHrR:`GrR:`GrR:9:qpYNEs3p-2s3pB9s3plGrmUfGs3pB9
879 s3plGrmUfGs3o9o!7UK=!7UlH!n.,LrmLrLdf9CGe,KFIdfBHtp]1<B!s$dM!<1FL!7LoJrmLrL
880 df9CHe,KCJe,97He+`qBdfTU!!!)uHrr<&Jq>gHBrW)rHpAk-?rrDuGrrE#Hr;ciGrW)oGrr<&J
881 r;ZoJ!!)rG!<CUI!!:UL!<(C@!<(CH!!(LH!!(LC!<1FL!7LoJrR:cH!7UcEr6tZGrmLlJe+`qA
882 e,B@Ge,B@Ge,KCJe,97Jdf9CHe,9:Ge+WhBe+itDe,9:Gdf]["!!(LF!!(LF!!(LB!<48C<K7%W
883 !;ZZl!!,poqu6YkrVus#ebf@IqAoP8!@dR:rrN+XqZ-Hl!/^[T!?BSbrrLplrVuq6qu6ZJr;ZgK
884 qu6Yrr;Zh$li6o>lMpe_m/I'crVus+l%/kcs2P'>N;rV,"J,Vj<E4P~>
885 s!%ICr6tWFs3pfE!7THuqpYNEs3poHrR:`GrR:`GrR:9:qpYNEs3p-2s3pB9s3plGrmUfGs3pB9
886 s3plGrmUfGs3o9o!7UK=!7UlH!n.,LrmLrLdf9CGe,KFIdfBHtp]1<B!s$dM!<1FL!7LoJrmLrL
887 df9CHe,KCJe,97He+`qBdfTU!!!)uHrr<&Jq>gHBrW)rHpAk-?rrDuGrrE#Hr;ciGrW)oGrr<&J
888 r;ZoJ!!)rG!<CUI!!:UL!<(C@!<(CH!!(LH!!(LC!<1FL!7LoJrR:cH!7UcEr6tZGrmLlJe+`qA
889 e,B@Ge,B@Ge,KCJe,97Jdf9CHe,9:Ge+WhBe+itDe,9:Gdf]["!!(LF!!(LF!!(LB!<48C<K7%W
890 !;ZZl!!%THrr?j6!!*8rqu6]g#Q=](>l=O"!W6*t!;ZWp7/d/e5k+XM!OW.2!!'M*rrA\i!!$[/
891 rr?[0!!&VVs8=b=s8;rbrrN+MrVus7qLSZts2P'>M?!;'"I]>f<E4P~>
892 s!%ICr6tWFs3pfE!7THuqpYNEs3poHrR:`GrR:`GrR:9:qpYNEs3p-2s3pB9s3plGrmUfGs3pB9
893 s3plGrmUfGs3o9o!7UK=!7UlH!n.,LrmLrLdf9CGe,KFIdfBHtp]1<B!s$dM!<1FL!7LoJrmLrL
894 df9CHe,KCJe,97He+`qBdfTU!!!)uHrr<&Jq>gHBrW)rHpAk-?rrDuGrrE#Hr;ciGrW)oGrr<&J
895 r;ZoJ!!)rG!<CUI!!:UL!<(C@!<(CH!!(LH!!(LC!<1FL!7LoJrR:cH!7UcEr6tZGrmLlJe+`qA
896 e,B@Ge,B@Ge,KCJe,97Jdf9CHe,9:Ge+WhBe+itDe,9:Gdf]["!!(LF!!(LF!!(LB!<48C<K7%W
897 !;ZZl!!'8"rr=kS!!*`0qu6]?"TAB%O8f(W!UqK6!;ZWp)u]g<B_hN)!JgjW!!)'Vrr?:%!!'(s
898 rr=VK!!(X:s8=b=s8;rbrrMpmrVushrIP!"s2P'>K)bPp"H`]\<E4P~>
899 s!!!oc2[jnhZ*Z*`W5nbScAc>nGiR<^An8_r;ZiHec5^!L&h5ts&IGGrMfk$_uKZ8q>^?m!&OHN
900 !WGLd!!#IbrrBP-!!*c*qYpTqCA\).rrD0[!!*f)q#:?QrVus*qtpBnQ2L[_EW,n;ir&iW+R9"*
901 1[>#=!:^!jo[TO!rVus+]Rg*6s2G!=N;rV,"J,Vj<E4P~>
902 s!!!oc2[jnhZ*Z*`W5nbScAc>nGiR<^An8_r;ZiHec5^!L&h5ts&IGGr;Zg._uKZ8q>^?m!-@u9
903 !W3Q/!!'%rrr?@(!!+\MqYpTo.f9;CrrBb3!!+eOq#:?#rVus3rql]q;Z-Rq[/L")Zi'k(;<n2[
904 1[>#=!:g'lrU8!k.K0;J)!6DLJcE^h!K$jMg'!iEqc-XH~>
905 s!!!oc2[jnhZ*Z*`W5nbScAc>nGiR<^An8_r;ZiHec5^!L&h5ts&IGGr;Zg._uKZ8q>^?m!4DY&
906 !UpBo!!(jPrr=AE!!.!:qYpTf')Vb+rr?d4!!-p8q#:>3rVupiqYpO=r;ZiWrVlk;r;Zh^lMpf=
907 lMpe_nc&ailG@r_rVus\on!-os2G!=K)bPp"H`]\<E4P~>
908 s!!!oJH1E)!7S%MrR99s!7QZ&s!%JCd/X'E!3a<?r;cZnr;Zj&mJ-\]ci*nE)#XC;r=o;4!MT;g
909 !V6Bk!;c]u>Q=a*[eB_$If9<IEr5k;rCQtg"U)O=s7[Z8!!*GelMpf=lMpe_p&Fad!Wl9WJcC<$
910 `;]jss7Y4NScJXf<Ib~>
911 s!!!oJH1E)!7S%MrR99s!7QZ&s!%JCd/X%E!"[!Ir;cZnr;Zj-qtU0kK)P`M2Z3RYq#p`u!Ta%U
912 !TF.Y!;c]u)#sX=m.UGZ.fKDJeGK7Hq%s#1"UOJps6L$j!!*l2lMpf=lMpe_p&Fad!X3B5JcC<$
913 `;]jps7Y.LRK34b<Ib~>
914 s!!!oJH1E)!7S%MrR99s!7QZ&s!%JCd/X%E!"[!Ir;cZnr;ZjVrqQKn1B%7RWVlc"j9#A^"7u<f
915 !M'8i!;c]u$NL/6p\+Ue')hk2mJHnaj9kkd"X*R>s1AL6!!,XglMpf=lMpe_p&Fad!YU:dJcC<$
916 `;]jis7XtGOT>5X<Ib~>
917 s!!!oJH16$JH1B(s!%JCd/X'E!3a<?r;cZnr;ZgNp\t6`rVup*r;QcZrVup0pAY,>r;c`p!;$0i
918 !#bJ0!9F+Z!$qF@!V$a#!!<i*raYp-!<StZs8=b=s8;rjs7cQq$AJ&%s+13frrJ)Yp=oeB!;fbr
919 J,~>
920 s!!!oJH16$JH1B(s!%JCd/X%E!"[!Ir;cZnr;ZhBp\t6OrVup6r;Qc7rVupCpAY+:r;c`p!9F+Z
921 !'BlR!5/:2!*T0u!SmnX!!=YJr$VID!<h0As8=b=s8;rjs7cQq(Spt[s+13frrIuVp=]Y<!;fbr
922 J,~>
923 s!!!oJH16$JH1B(s!%JCd/X%E!"[!Ir;cZnr;ZiAp\t5CrVuq#r;QaurVuqHpAY+'r;c`p!0I0[
924 !2&ra!)`^q!5\O3!Mfer!!?a1o+Cs%!=nYas8=b=s8;rjs7cQq1;!O:s+13frrI`Op=0;.!;]\q
925 J,~>
926 s!!!oJH16$JH1B(s!%JCd/X'E!3a<?r;cZnr;ZhHp\t6irVup$r;Qc1rVupZpAY-Dr;c`p!6tKC
927 !)3(c!;HHm!"Jc(!7UlH!A^tZ!!#m@s8;rjs7QEn$%%7'JcE[g!K@'Pg]X2Kqc-XH~>
928 s!!!oJH16$JH1B(s!%JCd/X%E!"[!Ir;cZnr;ZiUp\t6crVup(r;QanrVuqcpAY,Yr;c`p!.FhH
929 !5/")!:Kgd!$(h7!1<]b!H2lS!!&;/s8;rjs7QEn'q9dSJcE[g!K$jMg'!iEqc-XH~>
930 s!!!oJH16$JH1B(s!%JCd/X%E!"[!Ir;cZnr;Zifp\t6>rVupAr;Qa?rVurMpAY+Qr;c`p!&4BP
931 !9EhQ!4Mk,!-@u9!*&ms!OFQ[!!(Eks8;rjs7QEn/A6W7JcE[g!J:@FeHD!7qGgOG~>
932 s!#5YrR:ZE!7UlHrR:cHqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1!7U`D
933 !7U-3!7U'1!7Tg*!7U'1!7U'1!7U'1!7U'1!7Tm,!7UiGs3prIqpY6=!7UiGs3prIqpV\Js!%JC
934 d/X'E!3a<?r;cZnr;ZiGp\t6mrVup!r;Qb?rVuqJpAY-_r;c`p!0mH_!1WZ]!<2rt!!`5u!07$Y
935 !<E9$!!"%`s8;rfrri8fb`b*d!!+bKJcC<$`r?'us7Y4NScJXf<Ib~>
936 s!#5YrR:ZE!7UlHrR:cHqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1!7U`D
937 !7U-3!7U'1!7Tg*!7U'1!7U'1!7U'1!7U'1!7Tm,!7UiGs3prIqpY6=!7UiGs3prIqpV\Js!%JC
938 d/X%E!"[!Ir;cZnr;Zijp\t6jrVup"r;Qa;rVurWpAY-Nr;c`p!%.[F!9a%T!;ufr!"8T%!)3@l
939 rrN*!!(b?6r;cBf"T.H$K-U<p!F5VTs+13irrIuVp=]Y<!;fbrJ,~>
940 s!#5YrR:ZE!7UlHrR:cHqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1!7U`D
941 !7U-3!7U'1!7Tg*!7U'1!7U'1!7U'1!7U'1!7Tm,!7UiGs3prIqpY6=!7UiGs3prIqpV\Js!%JC
942 d/X%E!"[!Ir;cZnr;Zipp\t6^rVup'r;Qa,rVurgpAY,Ar;c`p!"o21!;,sa!:p*h!&"'H!$;+>
943 !<N<$!!%o#s8;rfrri/Y\8`&X!!%t/s+13hrrI`Op=0;.!;]\qJ,~>
944 s!%4<!7T*k!7UlH!7UoIs3prI!7UlH!n..uqZ$WFm/R.8r;[&N!!(IJ!7U04"4I5Me*m>>df9Bs
945 pAb<E!!(L;!!C[M!7UZB"4I5Me+3P>e)gW1e+itDe+`nCe+*J=e+`nCe*m>;e)(-*e)gW1e)gW1
946 e+`nCe*m>;e*d8:e+itDe)CB-e,97Kdf9Bsq>^NEpAk6Br;[&N!!(IJ!7RnIs!%JCNW8qWq>^Bn
947 !;Z?gr;ccq!&a`U!6Fm6!;ZQnqu6XerW)m!r;us!qZ$Ttq#:Bm7/Hrb#i3`)r;c3a!OE15!!"m-
948 s+13irrJ)Yp=oeB!;fbrJ,~>
949 s!%4<!7T*k!7UlH!7UoIs3prI!7UlH!n..uqZ$WFm/R.8r;[&N!!(IJ!7U04"4I5Me*m>>df9Bs
950 pAb<E!!(L;!!C[M!7UZB"4I5Me+3P>e)gW1e+itDe+`nCe+*J=e+`nCe*m>;e)(-*e)gW1e)gW1
951 e+`nCe*m>;e*d8:e+itDe)CB-e,97Kdf9Bsq>^NEpAk6Br;[&N!!(IJ!7RnIs!%JCNW8qWq>^Bn
952 !<2]lr;ccq!"Jo-!:oj`!:p'gqu6X/rW)m!r;us!qZ$Tuq#:Bi'`.k2')0WMr;c6b!re8`rVuq=
953 JcC<$`r?'rs7Y.LRK34b<Ib~>
954 s!%4<!7T*k!7UlH!7UoIs3prI!7UlH!n..uqZ$WFm/R.8r;[&N!!(IJ!7U04"4I5Me*m>>df9Bs
955 pAb<E!!(L;!!C[M!7UZB"4I5Me+3P>e)gW1e+itDe+`nCe+*J=e+`nCe*m>;e)(-*e)gW1e)gW1
956 e+`nCe*m>;e*d8:e+itDe)CB-e,97Kdf9Bsq>^NEpAk6Br;[&N!!(IJ!7RnIs!%JCNW8qWq>^Bn
957 p&Fsjr;Qa$rVuropAY-5r;c`p!!rQ(r<*!"rW2lr!"AZ&!T4:]!!,@_bl@VAmJd7`CBFJ8!4[U[
958 JcEai!J:@FeHD!7qGgOG~>
959 s!%4<!7T*k!7UlH"k*GOdf@kr!!(LH!!:ULe,'+Fe*R,8e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH
960 !!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L@!!(L1!!(LC!!(L4!!(LB!!(L;!!(L+!!(L1!!(L1
961 !!(LB!!(L;!!(L1!!(L.!!:ULe,B=Ie,97He,01Ge,01Ge,97Jdf@kr!!(LH!!:ULe#<?I,6(ZY
962 s8AqtYLEOM!;ZZn!;6Bj!;uis&H2Y0nFlk^rquiorr<l%!;HKomg]3q!<S\4s8;r`rrq9]!!!%t
963 JcDPG!!'Y2!!)Bc!K@'Pg]X2Kqc-XH~>
964 s!%4<!7T*k!7UlH"k*GOdf@kr!!(LH!!:ULe,'+Fe*R,8e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH
965 !!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L@!!(L1!!(LC!!(L4!!(LB!!(L;!!(L+!!(L1!!(L1
966 !!(LB!!(L;!!(L1!!(L.!!:ULe,B=Ie,97He,01Ge,01Ge,97Jdf@kr!!(LH!!:ULe#<?I,6(ZY
967 s8;ot&(CRW!;ZZn!;6Bj!;uis"TAB$r:^-jr;?Wmrr<8i!;HKofE;'P!<^ors8;r`rro\/!!!)a
968 JcDPG!!'Y2!!)Bc!K$jMg'!iEqc-XH~>
969 s!%4<!7T*k!7UlH"k*GOdf@kr!!(LH!!:ULe,'+Fe*R,8e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH
970 !!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L@!!(L1!!(LC!!(L4!!(LB!!(L;!!(L+!!(L1!!(L1
971 !!(LB!!(L;!!(L1!!(L.!!:ULe,B=Ie,97He,01Ge,01Ge,97Jdf@kr!!(LH!!:ULe#<?I,6(ZY
972 s8;ot&(CRW!;ZZn!;6Bj!;uis!r`0"rq??lnGN@arr</f!;HKoSHA`i!=S>=s8;r`rrmTI!!!2q
973 JcDPG!!'Y2!!)Bc!J:@FeHD!7qGgOG~>
974 ruqLEdfBBrrrE#HrVuuJ!<1Ho!!(LH!!(LD!!C[MdfBBrrr<)K!<1I6!!:ULe,97He*?u6e,97H
975 e+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+E\Cdf9Bsr;ZoJ!!)uHrr<)K!<1IE!!(LI
976 !<(CH!!1OKrmUfGs3prI!Rh&Je,'+Jdf9Bs!<1II!<(CG!!1OKrmUiHrmLlJe+*J>dfBBroDem?
977 rVurIrW!#K!!)uHrr<)K!<1IE!!LaN!7LrIe,KCJe,97Kdf@hsrmU`E"Od>NdfBBrrrE#HrVuuJ
978 !<1IH!<1FJ!7U`D!Rh&Je,9:He,9:GdfBHtnc/[=r;ZiHp&G*ArVurIr;ZiHr;ZiHquH`Fqu?`G
979 rVurIr;ZrK!7LrIe*mA:dfBHt_Z9]\s&Hl7rMfk$e,T@Hq>^Bnp&Fsjr;Qa"rVursp&Fsjqu6X"
980 li?bZ!1j&g!%l@nr;c-_!20;k!%!3rn,KlP!M0;gs2*OlScJ-W!K@'Pg]X2Kqc-XH~>
981 ruqLEdfBBrrrE#HrVuuJ!<1Ho!!(LH!!(LD!!C[MdfBBrrr<)K!<1I6!!:ULe,97He*?u6e,97H
982 e+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+E\Cdf9Bsr;ZoJ!!)uHrr<)K!<1IE!!(LI
983 !<(CH!!1OKrmUfGs3prI!Rh&Je,'+Jdf9Bs!<1II!<(CG!!1OKrmUiHrmLlJe+*J>dfBBroDem?
984 rVurIrW!#K!!)uHrr<)K!<1IE!!LaN!7LrIe,KCJe,97Kdf@hsrmU`E"Od>NdfBBrrrE#HrVuuJ
985 !<1IH!<1FJ!7U`D!Rh&Je,9:He,9:GdfBHtnc/[=r;ZiHp&G*ArVurIr;ZiHr;ZiHquH`Fqu?`G
986 rVurIr;ZrK!7LrIe*mA:dfBHt_Z9]\s&Hl7r;Zg.e,T@Hq>^Bnp&Fsjr;Q`trW)Tjr;c`p!!;Ke
987 pAY+Rr;Zh?b5_D?lMgiUrVuq&JcG3=\(UkO!;lf5g&[WBm/I*Cs7Y.LRK34b<Ib~>
988 ruqLEdfBBrrrE#HrVuuJ!<1Ho!!(LH!!(LD!!C[MdfBBrrr<)K!<1I6!!:ULe,97He*?u6e,97H
989 e+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+E\Cdf9Bsr;ZoJ!!)uHrr<)K!<1IE!!(LI
990 !<(CH!!1OKrmUfGs3prI!Rh&Je,'+Jdf9Bs!<1II!<(CG!!1OKrmUiHrmLlJe+*J>dfBBroDem?
991 rVurIrW!#K!!)uHrr<)K!<1IE!!LaN!7LrIe,KCJe,97Kdf@hsrmU`E"Od>NdfBBrrrE#HrVuuJ
992 !<1IH!<1FJ!7U`D!Rh&Je,9:He,9:GdfBHtnc/[=r;ZiHp&G*ArVurIr;ZiHr;ZiHquH`Fqu?`G
993 rVurIr;ZrK!7LrIe*mA:dfBHt_Z9]\s&Hl7r;Zg.e,T@Hq>^Bnp&Fsjr;Q`trW)Wk!;ucqqu6Ws
994 li?bZ!#b_8!5cnYr;c-_!$;+>!5F*bn,KlI!KdBZs2*:eOT=bJ!J:@FeHD!7qGgOG~>
995 ruqLEe'n9r"4I5Me,04Ge,B=Ie'\3re,01Ge+s%Idf9Bse,B=Ldf@kGrVurImJm@<!!(LH!!(L6
996 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LA!!(LI!!(LH!!:ULe,97Kdf9Bs
997 rVurIr;ZiHrVurIr;ZrK!7TEr!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!C[M!7UiGs3prI!n..u
998 rW)uIp]16@!W^]urVurIp&G*Ar;ZiHrVurIqZ$`I!!(LI!!(LH!!(LH!!(LI!!:ULe,97Kdf@kG
999 rVurIr;ZiHrW)uIrW!&L!!(LG!<:OI!!:ULe,B@Ie+j"De,B=Ie,97He,B=Ie,B@Ie+`q@dfBHt
1000 r;ZiHp&G*ArVurIr;ZiHrW)rHqu?`GqZ$WFrVurIr;ZrK!7TEr!!(LC!;t:H!7UoI!7Sdbs!%JC
1001 _#OA5!3alOr;cZnr;cNjr;ccq!"f,0!:]^^!<2osqu6X,rVur_k5PJE"8r3#$KfP3r;c-_!:Tme
1002 !"+;Wn,KlP!M0;gs2*OlScJ-W!K@'Pg]X2Kqc-XH~>
1003 ruqLEe'n9r"4I5Me,04Ge,B=Ie'\3re,01Ge+s%Idf9Bse,B=Ldf@kGrVurImJm@<!!(LH!!(L6
1004 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LA!!(LI!!(LH!!:ULe,97Kdf9Bs
1005 rVurIr;ZiHrVurIr;ZrK!7TEr!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!C[M!7UiGs3prI!n..u
1006 rW)uIp]16@!W^]urVurIp&G*Ar;ZiHrVurIqZ$`I!!(LI!!(LH!!(LH!!(LI!!:ULe,97Kdf@kG
1007 rVurIr;ZiHrW)uIrW!&L!!(LG!<:OI!!:ULe,B@Ie+j"De,B=Ie,97He,B=Ie,B@Ie+`q@dfBHt
1008 r;ZiHp&G*ArVurIr;ZiHrW)rHqu?`GqZ$WFrVurIr;ZrK!7TEr!!(LC!;t:H!7UoI!7Sdbs!%JC
1009 _#O?5!"[QYr;cZnr;cNjr;ccq!!N9$!;uQj!;ucqqu6X!rVurpk5PIr!W<!!(&?&Qr;c-_!8IJQ
1010 !#:(bn,KlN!La#cs2*IjRK2^S!K$jMg'!iEqc-XH~>
1011 ruqLEe'n9r"4I5Me,04Ge,B=Ie'\3re,01Ge+s%Idf9Bse,B=Ldf@kGrVurImJm@<!!(LH!!(L6
1012 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LA!!(LI!!(LH!!:ULe,97Kdf9Bs
1013 rVurIr;ZiHrVurIr;ZrK!7TEr!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!C[M!7UiGs3prI!n..u
1014 rW)uIp]16@!W^]urVurIp&G*Ar;ZiHrVurIqZ$`I!!(LI!!(LH!!(LH!!(LI!!:ULe,97Kdf@kG
1015 rVurIr;ZiHrW)uIrW!&L!!(LG!<:OI!!:ULe,B@Ie+j"De,B=Ie,97He,B=Ie,B@Ie+`q@dfBHt
1016 r;ZiHp&G*ArVurIr;ZiHrW)rHqu?`GqZ$WFrVurIr;ZrK!7TEr!!(LC!;t:H!7UoI!7Sdbs!%JC
1017 _#O?5!"[QYr;cZnr;cNjr;ccq!!<-"!<2]l!:]pequ6WtrVursk5PI2!W<!!8,^X2r;c-_!.4\F
1018 !*=aOn,KlI!KdBZs2*:eOT=bJ!J:@FeHD!7qGgOG~>
1019 ruqIDe,97Kdf9Bsqu?`Gr;ZiHe,]NtqZ$WFquHcGq#CEDqZ$WFn,WL;rVurIr;ZiHlMpq6r;ZiH
1020 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHpAb3Br;ZiHr;ZuL!!(Ksqu?`Gq>^NEquHcG
1021 r;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurIr;ZiHr;ZrK!!(LG!!(LH!!:ULe,97He+*J=e,97He+WhB
1022 e,01Ge,B=Kdf9CGe,KCJe+s%Ee,01Ge,01Ge,97Jdf@kq!!(LI!!(LH!!(LH!!C[M!7UiG!7UlH
1023 !n..ur;ZiHq#CEDr;ZiHr;ZiHrVurIr;ZiHnc/[=r;ZiHp&G*ArVurIr;ZiHqZ$WFp&G*ArVurI
1024 r;ZiHqZ$WFnc/[=rVurI_>sT[s&Hl7rMfk$e,T@Hq>^Bnp&Fsjr;QaSrVur>pAY-gr;c`p!&XZT
1025 !3GA`!Ve&>!!"@hs8;r_rrDur!!!+Ps6p!0h#Eu9g]<uHqu=Og!M0;XrrJ)Yp=oeB!;fbrJ,~>
1026 ruqIDe,97Kdf9Bsqu?`Gr;ZiHe,]NtqZ$WFquHcGq#CEDqZ$WFn,WL;rVurIr;ZiHlMpq6r;ZiH
1027 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHpAb3Br;ZiHr;ZuL!!(Ksqu?`Gq>^NEquHcG
1028 r;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurIr;ZiHr;ZrK!!(LG!!(LH!!:ULe,97He+*J=e,97He+WhB
1029 e,01Ge,B=Kdf9CGe,KCJe+s%Ee,01Ge,01Ge,97Jdf@kq!!(LI!!(LH!!(LH!!C[M!7UiG!7UlH
1030 !n..ur;ZiHq#CEDr;ZiHr;ZiHrVurIr;ZiHnc/[=r;ZiHp&G*ArVurIr;ZiHqZ$WFp&G*ArVurI
1031 r;ZiHqZ$WFnc/[=rVurI_>sT[s&Hl7r;Zg.e,T@Hq>^Bnp&Fsjr;Qa+rVurhpAY-`r;c`p!"Jo-
1032 !:/hJ!U^<l!!$<Js8;r_rrDin!!!1Rs6p!0gAdW3g&[WBqu=Oe!La#TrrIuVp=]Y<!;fbrJ,~>
1033 ruqIDe,97Kdf9Bsqu?`Gr;ZiHe,]NtqZ$WFquHcGq#CEDqZ$WFn,WL;rVurIr;ZiHlMpq6r;ZiH
1034 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHpAb3Br;ZiHr;ZuL!!(Ksqu?`Gq>^NEquHcG
1035 r;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurIr;ZiHr;ZrK!!(LG!!(LH!!:ULe,97He+*J=e,97He+WhB
1036 e,01Ge,B=Kdf9CGe,KCJe+s%Ee,01Ge,01Ge,97Jdf@kq!!(LI!!(LH!!(LH!!C[M!7UiG!7UlH
1037 !n..ur;ZiHq#CEDr;ZiHr;ZiHrVurIr;ZiHnc/[=r;ZiHp&G*ArVurIr;ZiHqZ$WFp&G*ArVurI
1038 r;ZiHqZ$WFnc/[=rVurI_>sT[s&Hl7r;Zg.e,T@Hq>^Bnp&Fsjr;Qa$rVuropAY-5r;c`p!!`E&
1039 !;>UU!Q#$;!!&h<s8;r_rrD!V!!![`s6p!0ec1d%eH(d4qu=O`!KdBKrrI`Op=0;.!;]\qJ,~>
1040 ruqIDe,97Kdf9BsquHcGrVurIeGoTuq#CEDr;ZiHpAb3BqZ$WFnGiR<qu?`Gr;ZiHlMpq6r;ZiH
1041 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHpAb3Br;ZiHr;ZiHr;clHrVurIq>^NEq>gQE
1042 rr<&Jr;ZiHr;ZiHrVurIr;ZiHrVurIr;ZiHr;ZrK!!(LG!<:OI!!:ULe,97He+*M=e,B=Ie+WhB
1043 e,'+Kdf@hs!7UlH"4I5Me+s%Ee,01Ge,01Ge,97Jdf@kq!!(LI!!(LH!!(LH!!C[M!7UiGs3prI
1044 !n..ur;ZiHq#LHDrVurIr;ZiHrVurIr;ZiHnc/[=r;ZiHp&G*ArVurIr;ZiHqZ$WFp&G*ArVurI
1045 r;ZiHqZ$WFnGrR;_#XKZs&Hl7rMfk$e,T@Hq>^Bnp&Fsjr;Qb>rVuqJpAY-_r;c`p!.=bG!*8=`
1046 !WH^,!!%,bs8;r^s8Duu!J1:>s2j$sT)\?9!M0;gs2*OlScJ-W!K@'Pg]X2Kqc-XH~>
1047 ruqIDe,97Kdf9BsquHcGrVurIeGoTuq#CEDr;ZiHpAb3BqZ$WFnGiR<qu?`Gr;ZiHlMpq6r;ZiH
1048 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHpAb3Br;ZiHr;ZiHr;clHrVurIq>^NEq>gQE
1049 rr<&Jr;ZiHr;ZiHrVurIr;ZiHrVurIr;ZiHr;ZrK!!(LG!<:OI!!:ULe,97He+*M=e,B=Ie+WhB
1050 e,'+Kdf@hs!7UlH"4I5Me+s%Ee,01Ge,01Ge,97Jdf@kq!!(LI!!(LH!!(LH!!C[M!7UiGs3prI
1051 !n..ur;ZiHq#LHDrVurIr;ZiHrVurIr;ZiHnc/[=r;ZiHp&G*ArVurIr;ZiHqZ$WFp&G*ArVurI
1052 r;ZiHqZ$WFnGrR;_#XKZs&Hl7r;Zg.e,T@Hq>^Bnp&Fsjr;Qa;rVurWpAY-Nr;c`p!$;+>!6=='
1053 !W=PE!!'RRs8;r_rrE&t!!!(Os6p!0g&[ZBn_+#4!;lf5g&[WBm/I*Cs7Y.LRK34b<Ib~>
1054 ruqIDe,97Kdf9BsquHcGrVurIeGoTuq#CEDr;ZiHpAb3BqZ$WFnGiR<qu?`Gr;ZiHlMpq6r;ZiH
1055 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHpAb3Br;ZiHr;ZiHr;clHrVurIq>^NEq>gQE
1056 rr<&Jr;ZiHr;ZiHrVurIr;ZiHrVurIr;ZiHr;ZrK!!(LG!<:OI!!:ULe,97He+*M=e,B=Ie+WhB
1057 e,'+Kdf@hs!7UlH"4I5Me+s%Ee,01Ge,01Ge,97Jdf@kq!!(LI!!(LH!!(LH!!C[M!7UiGs3prI
1058 !n..ur;ZiHq#LHDrVurIr;ZiHrVurIr;ZiHnc/[=r;ZiHp&G*ArVurIr;ZiHqZ$WFp&G*ArVurI
1059 r;ZiHqZ$WFnGrR;_#XKZs&Hl7r;Zg.e,T@Hq>^Bnp&Fsjr;Qa+rVurgpAY,Ar;c`p!"Su.!9iYH
1060 !V@$#!!)*(s8;r_rrDlo!!!:Us6p!0eH(g4n^RZ&!;lf5eH(d4m/I*<s7XtGOT>5X<Ib~>
1061 ruqIDe,97Kdf9BsrW!&L!7LrIe("Eue+`nCe,B=Ie,'+Fe,97Jdf@kq!!(L=!!(LE!!C[M!7U04
1062 "4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5Me+WhBe,01Ge,B@IdfBHtr;ZrK
1063 !!(LF!!(LG!!(LH!!C[Me'n9r!7UlH!7UoI!7UlH"4I5Me,01Ge,97Kdf9BsrW!&L!7LrIe,KCJ
1064 e,B@Ie+*J>dfBBrpAb3Bq>^]J!7LoJe,B@Ie,KCJe,'+Fe,'+Fe,01Ge,B@IdfBHtr;ZrK!!(LG
1065 !!(LH!!C[M!7UoI"4I8!!<1II!!(LI!<:OH!!(LI!!1OKrmUcF!7UoI!7UoIs3pN=!7UoIs3pZA
1066 !7UlH#1EPPdf9Bsr;ZiHr;ZiHqZ$WFr;[&N!!(IJ!7UlH!7UK=!7SX^s!%JC_#OA5!3alOr;cZn
1067 r;cNjr;ccq!5/:2!'9iR!7q)Kqu6Z7rVup@kl1Xfr;Zjh<;lju"jG6kr;c-_!;l`q!!RrRn,LMb
1068 !M9>]g]<uHqu=Og!M0;XrrJ)Yp=oeB!;fbrJ,~>
1069 ruqIDe,97Kdf9BsrW!&L!7LrIe("Eue+`nCe,B=Ie,'+Fe,97Jdf@kq!!(L=!!(LE!!C[M!7U04
1070 "4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5Me+WhBe,01Ge,B@IdfBHtr;ZrK
1071 !!(LF!!(LG!!(LH!!C[Me'n9r!7UlH!7UoI!7UlH"4I5Me,01Ge,97Kdf9BsrW!&L!7LrIe,KCJ
1072 e,B@Ie+*J>dfBBrpAb3Bq>^]J!7LoJe,B@Ie,KCJe,'+Fe,'+Fe,01Ge,B@IdfBHtr;ZrK!!(LG
1073 !!(LH!!C[M!7UoI"4I8!!<1II!!(LI!<:OH!!(LI!!1OKrmUcF!7UoI!7UoIs3pN=!7UoIs3pZA
1074 !7UlH#1EPPdf9Bsr;ZiHr;ZiHqZ$WFr;[&N!!(IJ!7UlH!7UK=!7SX^s!%JC_#O?5!"[QYr;cZn
1075 r;cNjr;ccq!)NRo!1<K[!1*Q`qu6Y*rVupmkl1X#r;ZkS*W?$>$M2OBr;c-_!;6<k!"+;Wn,LM`
1076 !Lj&Yg&[WBqu=Oe!La#TrrIuVp=]Y<!;fbrJ,~>
1077 ruqIDe,97Kdf9BsrW!&L!7LrIe("Eue+`nCe,B=Ie,'+Fe,97Jdf@kq!!(L=!!(LE!!C[M!7U04
1078 "4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5Me+WhBe,01Ge,B@IdfBHtr;ZrK
1079 !!(LF!!(LG!!(LH!!C[Me'n9r!7UlH!7UoI!7UlH"4I5Me,01Ge,97Kdf9BsrW!&L!7LrIe,KCJ
1080 e,B@Ie+*J>dfBBrpAb3Bq>^]J!7LoJe,B@Ie,KCJe,'+Fe,'+Fe,01Ge,B@IdfBHtr;ZrK!!(LG
1081 !!(LH!!C[M!7UoI"4I8!!<1II!!(LI!<:OH!!(LI!!1OKrmUcF!7UoI!7UoIs3pN=!7UoIs3pZA
1082 !7UlH#1EPPdf9Bsr;ZiHr;ZiHqZ$WFr;[&N!!(IJ!7UlH!7UK=!7SX^s!%JC_#O?5!"[QYr;cZn
1083 r;cNjr;ccq!$V=A!8$rE!'0uXqu6XDrVur*kl1W<r;Zl0%/p5-.f.Eir;c-_!7UoI!%EL!n,LM[
1084 !KmEPeH(d4qu=O`!KdBKrrI`Op=0;.!;]\qJ,~>
1085 ruqIDe,97He,B@He,KCJe'S0me,KFGdf9CFe,KFHe,B@Ge+!G8e,B@Ie)p`2e*[59e,04Fe,9:H
1086 e*[59e,04Fe,9:He+NbAe,'.EdfTU!!!)uHrVurIqZ$WFqZ-TDrr<)K!<1IH!;t:H!7UlH"4I5M
1087 e,01Ge,97He,B@He,KCJe+s(DdfBHtnc/[=o)Jd>q#CEDr;ciG"9?mN!7UfF!7UfF!7UfFrmLrL
1088 df@kq!!C[M!7UiG!7UlH!7UoIrmUlI!7UcErmLlJe,B@He,KCJe+s(Be,KFIdfBHtnGrR;!<CUD
1089 !;t=F!<:OH!<(CF!<1IH!;t=F!<:OH!<(C9!<(B`!<48C<P\Y5WW96Os8;rns8;rjs8;rqrrD3\
1090 !!!T(rr@HF!;lcrn,<:f"Q\kJ!TO4[!!=5>ndbX!!>td\s8;r_rrDEb!!!L[s6p!0g]=#Hn_=/:
1091 !;lfVg].?Fg].?Eg]<uHm/I*Fs7Y4NScJXf<Ib~>
1092 ruqIDe,97He,B@He,KCJe'S0me,KFGdf9CFe,KFHe,B@Ge+!G8e,B@Ie)p`2e*[59e,04Fe,9:H
1093 e*[59e,04Fe,9:He+NbAe,'.EdfTU!!!)uHrVurIqZ$WFqZ-TDrr<)K!<1IH!;t:H!7UlH"4I5M
1094 e,01Ge,97He,B@He,KCJe+s(DdfBHtnc/[=o)Jd>q#CEDr;ciG"9?mN!7UfF!7UfF!7UfFrmLrL
1095 df@kq!!C[M!7UiG!7UlH!7UoIrmUlI!7UcErmLlJe,B@He,KCJe+s(Be,KFIdfBHtnGrR;!<CUD
1096 !;t=F!<:OH!<(CF!<1IH!;t=F!<:OH!<(C9!<(B`!<48C<P\Y5!!!PYs8;rns8;rjs8;rqrrBt9
1097 !!";<rr=8A!;lcrg&:sP#l3cc!O`%.!!>[ihus#Z!'JO+r;c-_!7LiH!$6^kn,LM`!Lj&Yg&[WB
1098 qu>^1!!)TD!!)QC!La#TrrIuVp=]Y<!;fbrJ,~>
1099 ruqIDe,97He,B@He,KCJe'S0me,KFGdf9CFe,KFHe,B@Ge+!G8e,B@Ie)p`2e*[59e,04Fe,9:H
1100 e*[59e,04Fe,9:He+NbAe,'.EdfTU!!!)uHrVurIqZ$WFqZ-TDrr<)K!<1IH!;t:H!7UlH"4I5M
1101 e,01Ge,97He,B@He,KCJe+s(DdfBHtnc/[=o)Jd>q#CEDr;ciG"9?mN!7UfF!7UfF!7UfFrmLrL
1102 df@kq!!C[M!7UiG!7UlH!7UoIrmUlI!7UcErmLlJe,B@He,KCJe+s(Be,KFIdfBHtnGrR;!<CUD
1103 !;t=F!<:OH!<(CF!<1IH!;t=F!<:OH!<(C9!<(B`!<48C<P\Y5!!!PYs8;rns8;rjs8;rqrr?."
1104 !!%KArr<W/!;lcrGl@[D+8tL)!H\AA!!@rTV#pVr!.`>or;c-_!,DK5!.0:sn,LM[!KmEPeH(d4
1105 qu>^,!!)T?!!)Q>!KdBKrrI`Op=0;.!;]\qJ,~>
1106 s!%"6!7QK!h>dQ)hZ*Z*S,`Q<jo>D1VZ6_GnGiR<rVurI\GuWYgAh6&r;ZiH_Z9]\s&JRg&+A/k
1107 ]!AH=WiE,'Zb+B4naZYXWW97!s6-KCs8;rns8;rjs8;rqrrr<7!!!%oq#:Bd!rW,qrr>Xi!!"h@
1108 rrMg9rW!'-g].;ur;ZgocN!hClMgjJrVupQJcG3=hV8)2mG%`6s7+kFScJZfj4j_:gtVo&g].?E
1109 g]<uHm/I*Fs7Y4NScJXf<Ib~>
1110 s!%"6!7QK!h>dQ)hZ*Z*S,`Q<jo>D1VZ6_GnGiR<rVurI\GuWYgAh6&r;ZiH_Z9]\s&JRg&(-><
1111 1)^K%!!!-6*Aq5`fCAn>!!!Q+s6'ICs8;rns8;rjs8;rqrrr3%!!!&]q#:BT!W<#qrrN*3rVuqE
1112 li."O#lXf,'DMP,NVrhWQd5X0!:'Ra4T5<\IY%Ofs5)H0!:AJ@RfDp3!La#cs5Vf8!8?-,p"BBG
1113 n_+#4!:9^dM?!;'"I]>f<E4P~>
1114 s!%"6!7QK!h>dQ)hZ*Z*S,`Q<jo>D1VZ6_GnGiR<rVurI\GuWYgAh6&r;ZiH_Z9]\s&JRg&(-><
1115 1)^K%!!!-6*Aq5`fCAn>!!!Q+s6'ICs8;rns8;rjs8;rqrrqEb!!!,nq#:Ae!W<#qrrN!'rVur7
1116 li.!t"TAB(5lCZ^8GrMge'A!l!:'Ra)?'U9c@Q#as5)9+!:A;;OoOt%!KdBZs5VW3!7fU"p!j$B
1117 n^RZ&!:9^dK)bPp"H`]\<E4P~>
1118 s!%"6!7QK!JH44#!7U'1!7RhG!7U<8!7R&1rR8U`s!%JCo)AaM\ac[#\`<;]rMfk$qZ#cZj8]&X
1119 q>^Bnp&Fsjqu6Z(rVus4p%n[hrbME3qYpQRrVus"M!b3Cra#L'!<Shjrr@3@!!*/(ci<qDqYpRU
1120 jRiHPgAV'Q!ka*an,M8"!!)EA!M9>]g]<uHqu>U0!!)]I!!)QE!M0;XrrJ)Yp=oeB!;fbrJ,~>
1121 s!%"6!7QK!JH44#!7U'1!7RhG!7U<8!7R&1rR8U`s!%JCo)A`h/b&fA0!+[Er;Zg.qZ#aZj8]&X
1122 q>^Bnp&Fsjqu6Y#rVusOrVHNpr@@dGqYpQ#rVus#_!V.&r$;7A!<h'Rrr=nT!!*8aci<qDqYpS'
1123 q"4RdWr;u!"7Lg@n,M7u!!)E?!Lj&Yg&[WBqu>U.!!)]G!!)QC!La#TrrIuVp=]Y<!;fbrJ,~>
1124 s!%"6!7QK!JH44#!7U'1!7RhG!7U<8!7R&1rR8U`s!%JCo)A`h/b&fA0!+[Er;Zg.qZ#aZj8]&X
1125 q>^Bnp&Fsjqu6XArVut;rqcWqoFh'%qYpP%rVus*k3`0Ln.5Ku!=nStrrN$4rVus3o[!R9!;c]r
1126 L]$fE!,hc9!=S[Rs6p!EeGoU:eH(g4n^RZ&!;lfSeGoUBeGoU>eH(d4m/I*<s7XtGOT>5X<Ib~>
1127 s!!!oJH16$JH1B(s!%JCo`"sh`U0Z+_u03-rMfk$qZ#cZj8]&Xq>^Bnp&Fsjqu6]m)u]g<.e<N;
1128 !WJ)U!;ZWpL&M&R!dO_>rrW//9`+hiW;Q\r;uHXrp`f\;!=n_es8=b=s8;rorrW6-JFWF7!rf;.
1129 rVupRJcG0<qqN+jUaZHbLp&B7*1u$Acrgk\.C.aacqb5U*d-99!<:g^\2FO#:=S(S!1Y26rnIXJ
1130 s4lCCq>^M/r7h=E!;lfig^MP*&Ha(sgt)_`gtZ'3g]T"'g]6.-!<:g`[lFa+B\_ACW\k%d1:-`1
1131 !M0;XrrJ)Yp=oeB!;fbrJ,~>
1132 s!!!oJH16$JH1B(s!%JCo`"sb;=+>a9DA,Zr;Zg.qZ#aZj8]&Xq>^Bnp&Fsjqu6]f#Q=](?2XX#
1133 !W6-u!;ZWp6iI&d"eYPh!r8NIqu6Y-r;Zh`r;Qfe$2so*,5gd,rA3a=r;c]o!rs(*r:p9nrJC[U
1134 !!%"is6fpag)C$@*!7OjL`Z^K`S0%^57%HQce@*c4UVECO4sL3s4RjE-Nb&of\5$ZF;4iUg'!lE
1135 g=g39!!$[0g&[WBqu?BD#eW;."Y,Sec3jR)!%7d"":<B-!8@>Ns4RpH.KgWBg=cO`-NaZCchH,o
1136 RK2^S!K$jMg'!iEqc-XH~>
1137 s!!!oJH16$JH1B(s!%JCo`"sb;=+>a9DA,Zr;Zg.qZ#aZj8]&Xq>^Bnp&Fsjqu6]<"9&9$OT,1X
1138 !UqK6!;c]rrYth:!><6CrrVSG+8c'</H#PKdJX"F_Z]r=!F>]js8=b=s8;rorrW6U[f6(%!qg+*
1139 rVur0JcG0<qpcVc?P3T$`+Kbf5L%a/W%8)Y:XR_CQ7W=I2lbF+!<:RWEuG-$JCN-"!*'I/rm_.6
1140 s4,Y1q>^M+r7(h1!;lfieHhHm#7*8geY=PleHf@/e^=TIeH".t!<:RYF<(H1UXdlpC`EKf=jcuo
1141 !KdBKrrI`Op=0;.!;]\qJ,~>
1142 s!!!oJH16$JH1B(s!%JCo`"p0l`(!%rV$9iWW97!s6-KCs8;rns8;rjs8;rorrCgP!!s:!hYHHD
1143 8cSi4r;cZn!W6."!"9d!amf<&ji*Tl&c_q0rrCsT!!",;rrD!U!!"kAs8=b=s8;ros8E!*#?-l5
1144 k5+u>`JQDK!!*u.JcG0<qqN1l(9uP]!uJ5qRLn90&<bJpNYpR,7U+$g]40RN!<([\a:Oomc=nc`
1145 g]//&rS.RJs4lDa:](1n:YYg&!M0;gs7Y4`7U+$g]40RN8rMKU!Nk/*$/F;9gtVo.g^_=1NRQ$g
1146 gtVl>R+'N5'_gA`ScJ-W!K@'Pg]X2Kqc-XH~>
1147 s!!!oJH16$JH1B(s!%JCo`"ndlMprUq=aje!!!Q+s6'ICs8;rns8;rjs8;rorrAno!!t3NjSS#2
1148 .0'?Ar;cZn!Ve2D!":WJeFih2ik(4E#64c%rrB2"!!#djrrB5#!!%-,s8=b=s8;ros8E!*&R_<`
1149 lM^S?]QtRr!!,:]JcG0<qq<%j28@[_#<'?IF!]Po+K!];BK=f#&r"Z^X[q1"!<(UZW$AIs_EhVa
1150 g&O1TrRqFDs4Z2[:Ab(m:>,R!!La#cs7Y.^&r"Z^X[q1"'$&_L!RKK<'&)%>g=cQ*g('hfU=HnS
1151 g=cNNW7K*m0_a9%RK2^S!K$jMg'!iEqc-XH~>
1152 s!!!oJH16$JH1B(s!%JCo`"ndlMprUq=aje!!!Q+s6'ICs8;rns8;rjs8;rorr?O,!!u?-lhK=r
1153 &-)]pr;cZn!TF^i!";Jrh>$s:h6M_s!rr?!rr?j5!!&)Vrr?a2!!'Rqs8=b=s8;ros8E!*,As[<
1154 n,E%:Y\FRE!!.0?JcG0<qpc\e?,k#I**pS,3H*Hu3O.#O1PaN2#b0/bROZk<!<(FUBLoV\Y8X+b
1155 eGs4)rRD(6s4,ZL9`+kk9[s!j!KdBZs7XtY#b0/bROZk<#gLng!moJC8_)>ke^XZueIH(AYL9F)
1156 e^XXgZdZH3H2#hiOT=bJ!J:@FeHD!7qGgOG~>
1157 s!#5YrR:ZE!7UoIqpYQFrR:WD!7UE;rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1!7U`D
1158 !7U-3!7UE;rmU36!7QK!JH4I*s!%JCp&>$Mql1%._pd;qi8EMIe]P>tWW:`Gs8AqtYPS:ti;KYU
1159 Xmt?0s8;rns8;rjs8;rnrrBG"!!*Yjr;cWm!W7!.!<)ouoc!f0!=Ii^rrAGc!!*+[m/R#?lMpe_
1160 qZ$$b!B]e%s6]j`g^4%Rgt^Q_T\S>U"8gjWg'$3d&$c#e!!)uQ!GI>hg]c=6gtVmor7h=Es8LdS
1161 f/`g1!BJd/g]<uHqu?BF!=uI4g^^8>gq!PPgp83[g]6-b!<(^Q@f+p]!1!Q=!SISLg]<uHm/I*F
1162 s7Y4NScJXf<Ib~>
1163 s!#5YrR:ZE!7UoIqpYQFrR:WD!7UE;rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1!7U`D
1164 !7U-3!7UE;rmU36!7QK!JH4I*s!%JCp&>#dqZ%!<9RMnmUSFKIK4#u%!!&&Qs8;ot&,Q>)U\t/m
1165 $LsnOs8;rns8;rjs8;rnrr@K@!!+JBr;cWm!Vf=X!<)oujp1kc!>kP,rr>sr!!*,Gm/R#?lMpe_
1166 qZ$$b!FPbUs6]j`g'Ri'g=k'WbM(\#"T-mVed:'a"46r!!!)uO!?9#Wg',k2g=cPKr7V1?s8L^Q
1167 eN!O.!BAX,g&[WBqu?BD!<^^Gg(%&9g4f`ug2L!Eg&Tj\!<(UP)Qrtk!<C4?g&]Y*pY#Y:!:9^d
1168 M?!;'"I]>f<E4P~>
1169 s!#5YrR:ZE!7UoIqpYQFrR:WD!7UE;rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1!7U`D
1170 !7U-3!7UE;rmU36!7QK!JH4I*s!%JCp&>#dqZ%!<9RMnmUSFKIK4#u%!!&&Qs8;ot&,Q>)U\t/m
1171 $LsnOs8;rns8;rjs8;rnrr>[b!!-1!r;cWm!TGKs!<)ouZNL1,!D*.arr=2@!!*8hm/R#?lMpe_
1172 qZ$$b!JgZ*s6]j`eHu<&e^_A6cdgR[')U2__]dR\!n$nq!!)uJ!=d9PeHN')e^XZEr7(h1s8LOL
1173 co:q(!B8C&eH(d4qu?B?!<U[GeIEb1eM@9=eLREFeH".M!<(FK%)_tm!<CCDeH*,kpXK;,!:9^d
1174 K)bPp"H`]\<E4P~>
1175 s!$_.!7TU$!7UlH!7UoIs3pcD!n..ur;ZiHr;clHnGiR<r;[&N!!(IJ!7U04"4I5Me*m>>df9Bs
1176 pAb<E!!(L;!!C[M!7UZB"4I5Me+3P>e)gW1e+itDe+`nCe+*J=e+!D<e,B=Ldf9Bsn,NI;JH16$
1177 g]7?us&Jal!4Mj+!jCJZpAY0[\,E<-Ykn+orMfk$pAb)k!3alOr;cZnr;cNjr;cWm!QH2V!!4q6
1178 s8;rkrrKqqo)Sdi!W?$t!!*.uq#:Bm4T5<]#iG%LrA3a=r;c]o!oeVKo`,"=Sq6q-s81RP!8IM.
1179 !<CmRg^aD?gs]+3!!!&Tgm/1@K!kU5!!)uQ$4m:A!W`9%gtVn^r7h=Es8C^UcS#8OchcDtScJZf
1180 p=oe:#>]rZrnJ"-&_q@r'\m;,gtVnbg]7<.!=m?Ng].?Pg].?Kg]<uHm/I*Fs7Y4NScJXf<Ib~>
1181 s!$_.!7TU$!7UlH!7UoIs3pcD!n..ur;ZiHr;clHnGiR<r;[&N!!(IJ!7U04"4I5Me*m>>df9Bs
1182 pAb<E!!(L;!!C[M!7UZB"4I5Me+3P>e)gW1e+itDe+`nCe+*J=e+!D<e,B=Ldf9Bsn,NI;JH16$
1183 g]7?us&Jal!%.XE!YCt!pAY05.K'5I'(P_rr;Zg.pAb'k!"[QYr;cZnr;cNjr;cWm!M0Vn!!6-p
1184 s8;rkrrJl<o)Sdi!W*u<!!*8[q#:Bi&H2Y1&btbnrA3a=r;c]o!mPEho`,"T]7L"Js81LM!<(UO
1185 !<(U^!8?/F4UD)g!SZ72&6jt-rn7>PrRqS]!s8T*!!1g-!87;(!Lj&eg'#YR!&)Ung&[WBqu?BD
1186 "Bl@@Lr0/F%^m_<*f;T()7J8Q!8?-,rRq8SfDF8%!;tON!;G1JRK2^S!K$jMg'!iEqc-XH~>
1187 s!$_.!7TU$!7UlH!7UoIs3pcD!n..ur;ZiHr;clHnGiR<r;[&N!!(IJ!7U04"4I5Me*m>>df9Bs
1188 pAb<E!!(L;!!C[M!7UZB"4I5Me+3P>e)gW1e+itDe+`nCe+*J=e+!D<e,B=Ldf9Bsn,NI;JH16$
1189 g]7?us&Jal!%.XE!YCt!pAY05.K'5I'(P_rr;Zg.pAb'k!"[QYr;cZnr;cNjr;cWm!I"\B!!7?A
1190 s8;rlrrW1R%eB]"rrMEprVus3o(`4ch['2]!C$GKs8=b=s8;rorrT]0#5%rs;V6R#li6k4!!)uJ
1191 !!)uJ%fk/1SLasF!!:^$0Ht"ebPp#l!<(FS!WrN+!<<2OeH#Ks!KmE\eHErG!%u@heH(d4qu?B?
1192 ">D$0Nm%FP%U4D4%7Gs$%*$iJ!7fU"rRCoMe,.Yq!;t@I!;G"EOT=bJ!J:@FeHD!7qGgOG~>
1193 s!$_.!7TU$!7UlH"k*GOdf@kn!!C[M!7UlH!7UoI!n..unGiR<r;ZoJ!7UlH!7U66!7UlH!7UK=
1194 !7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UT@!7U'1!7U]C!7U04!7UE;!7UfF!7UE;!7QK!
1195 JH4I*s!%JCpAY-[rMfn!mdpGZp9=Lq!93bQrMfk$pAb)k!3alOr;cZnr;cNjr;cTl#l:#\('=gf
1196 >-Ir*r;cKi%F';h*s_lP%NmZ0H`,WtrrA\i!!$9trrMEhrVupAmJm,@lMpe_p\tWJLfPu="9]8a
1197 :4gT=s69R\g].?Qg].?Qg^!o8gg*Cbg"ZT,g]tZG<>e<^g]7<.!=cg?g].?Og]=#Hr7h@r50E]V
1198 !M0;gs7P.^_15N'8)2nR&C:a'&C:[*gtVnbg]7<.!=m?Ng].?Pg].?Kg]<uHm/I*Fs7Y4NScJXf
1199 <Ib~>
1200 s!$_.!7TU$!7UlH"k*GOdf@kn!!C[M!7UlH!7UoI!n..unGiR<r;ZoJ!7UlH!7U66!7UlH!7UK=
1201 !7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UT@!7U'1!7U]C!7U04!7UE;!7UfF!7UE;!7QK!
1202 JH4I*s!%JCpAY-8r;Zj$cL_&:jq@Um!3,_mr;Zg.pAb'k!"[QYr;cZnr;cNjr;cTl#k<X1%fm%i
1203 Bug5Qr;cNj%fX+[3Z&&%#SA@E?%]EDrr2t'r;ZhhpAY0<!WE'!;XOM_1[>#=!;QR&rP<hS+qF\Y
1204 'eWOJg4B:gs81LM!<(UO!<(UW!8?-GFN<(e!<1[WY'*DED;*\DrRq8Se,%bu!;kINRfE<>!m!RH
1205 q:Yk<!;lfhg(gc68d]Fhg=?SX"jmY("P2;\!8?-,rRq8SfDF8%!;tON!;G1JRK2^S!K$jMg'!iE
1206 qc-XH~>
1207 s!$_.!7TU$!7UlH"k*GOdf@kn!!C[M!7UlH!7UoI!n..unGiR<r;ZoJ!7UlH!7U66!7UlH!7UK=
1208 !7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UT@!7U'1!7U]C!7U04!7UE;!7UfF!7UE;!7QK!
1209 JH4I*s!%JCpAY-8r;Zj$cL_&:jq@Um!3,_mr;Zg.pAb'k!"[QYr;cZnr;cNjr;cTl#hsGS$3C_r
1210 Gi/N#r;cNj%f<;;1(j`m$5=sUAW+4jrr2sGr;ZiLpAY/O!WE'!RI1%Q1[>#=!;QR&p9J^+*=MuS
1211 ))blml[f*#s81=H!<(FJ!<(FR!7fU.Nl]bq!<1LRRqt7oT@MHlrRCoMde_Jo!;k:IOoP@0!lI.<
1212 q:,M.!;lfheJ4Qi4p[e2e\i93%DNjh%F`kX!7fU"rRCoMeGIbr!;t@I!;G"EOT=bJ!J:@FeHD!7
1213 qGgOG~>
1214 ruqLEdfBBrrW)oGrW)oGrrE#Hec5^!r;ZiHqZ$WFq#CWJ!!(IJ!7U97!n..ur;ZiHlMpq6r;ZiH
1215 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,*C!!(LH!!:UL!<(CH!!1OKrmU`E!7UoI
1216 rR:cH!Rh&Je,9:He,B=JdfBBrqZ$WFrVurIrW!#K!!)uHrVurIquH]ErVuuJ!<1IH!<1FJ!7QK!
1217 JH4I*s!%JCpAY-DrMfk<nc&U=rMfk@p](2l!3c+rrMfk$JcC<$KE(i(!!)uQ!!)uQ#QWZ8#ghA^
1218 d/a(!"kEe2g]Q7/g]:tZqV2&NqqM4Ds7+kFScJZfo%X8s"9.'[G?PR5GZG@Sg]RW4g]Q7/g]:ho
1219 qqM/Or7h8PpY5e@!:9^dN;rV,"J,Vj<E4P~>
1220 ruqLEdfBBrrW)oGrW)oGrrE#Hec5^!r;ZiHqZ$WFq#CWJ!!(IJ!7U97!n..ur;ZiHlMpq6r;ZiH
1221 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,*C!!(LH!!:UL!<(CH!!1OKrmU`E!7UoI
1222 rR:cH!Rh&Je,9:He,B=JdfBBrqZ$WFrVurIrW!#K!!)uHrVurIquH]ErVuuJ!<1IH!<1FJ!7QK!
1223 JH4I*s!%JCpAY,Hr;Zh#nc&T=r;Zh/p](0l!"\f'r;Zg.JcC<$KE(i&!!)uO!!)uO#QWT4!nZ/[
1224 ^B"/b"Npr%g&_0+!?7F&g&M-Mg&[ZBn_+#4!;lfeg&]A"rn7Q!LEY@pMBMoP!s%'/!WC^Q)6`qk
1225 !!)rN!!)cI!La#TrrIuVp=]Y<!;fbrJ,~>
1226 ruqLEdfBBrrW)oGrW)oGrrE#Hec5^!r;ZiHqZ$WFq#CWJ!!(IJ!7U97!n..ur;ZiHlMpq6r;ZiH
1227 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,*C!!(LH!!:UL!<(CH!!1OKrmU`E!7UoI
1228 rR:cH!Rh&Je,9:He,B=JdfBBrqZ$WFrVurIrW!#K!!)uHrVurIquH]ErVuuJ!<1IH!<1FJ!7QK!
1229 JH4I*s!%JCpAY,Hr;Zh#nc&T=r;Zh/p](0l!"\f'r;Zg.JcC<$KE(i!!!)uJ!!)uJ#QWE*!S#ZM
1230 GQ@Wk"Jc[\eH,X!!=ZU:eGoUHeH(g4n^RZ&!;lfeeH)HYrm_2_3HWd]4*1DO!s$m%!WCOL$cDkl
1231 !!)rI!!)cD!KdBKrrI`Op=0;.!;]\qJ,~>
1232 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me("Eue,01Ge,04Fe,'+Idf9BsrVurIm/R7;!!(LH!!(L6
1233 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LA!!(LI!!(LH!!:ULe,97Kdf9Bs
1234 rVurIr;ZiHrVurIr;ZrK!7TEr!!(LH!!(LI!<:OI!!(LH!!(LH!!(LI!!:ULe,97IdfB?qr;ZiH
1235 quHcGrW!#K!7UoIs3lN!JH4I*s!%JCpAY-3rMfkSnc&UVrMfk/p](2l!3c+rrMfk$JcC<$KE(i(
1236 !!)uQ!!)uQ+TU<Q9N0H^8H@Q$-'?I*V[;/621XE9grTkKc.K:)gtVo,g]=#Hn_=/:!;lfig]]!d
1237 c.T!$rnI^g"#SfE"#9f1&-1M@21XE9gr9Y]e]Vmdg]79-!!)cK!M0;XrrJ)Yp=oeB!;fbrJ,~>
1238 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me("Eue,01Ge,04Fe,'+Idf9BsrVurIm/R7;!!(LH!!(L6
1239 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LA!!(LI!!(LH!!:ULe,97Kdf9Bs
1240 rVurIr;ZiHrVurIr;ZrK!7TEr!!(LH!!(LI!<:OI!!(LH!!(LH!!(LI!!:ULe,97IdfB?qr;ZiH
1241 quHcGrW!#K!7UoIs3lN!JH4I*s!%JCpAY+ir;Zhhnc&U2r;ZgQp](0l!"\f'r;Zg.JcC<$KE(i&
1242 !!)uO!!)uO'EHk@'8>&K*WXpJ5G?KSN>1+#%B]W`$*";pda=dTg=cQ(g&[ZBn_+#4!;lfig''^7
1243 dF=-irn7R+"bkZa"b6O*"9@00%B]W`#b_g+f"Fu8g&V')!!)cI!La#TrrIuVp=]Y<!;fbrJ,~>
1244 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me("Eue,01Ge,04Fe,'+Idf9BsrVurIm/R7;!!(LH!!(L6
1245 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LA!!(LI!!(LH!!:ULe,97Kdf9Bs
1246 rVurIr;ZiHrVurIr;ZrK!7TEr!!(LH!!(LI!<:OI!!(LH!!(LH!!(LI!!:ULe,97IdfB?qr;ZiH
1247 quHcGrW!#K!7UoIs3lN!JH4I*s!%JCpAY+ir;Zhhnc&U2r;ZgQp](0l!"\f'r;Zg.JcC<$KE(i!
1248 !!)uJ!!)uJ'EH\6#b]V=%04r/<N=Hg@7A_s#/1#d$#UfZd`@Ire^XZseH(g4n^RZ&!;lfieHJsQ
1249 dE,fcrm_3,"16T6"1/!W"9@!&#/1#d#\#Kmd],"OeH#Nt!!)cD!KdBKrrI`Op=0;.!;]\qJ,~>
1250 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L"!<:OF!!(LD!!(LI!<:OI!!(LI!!(L:!<:OI!!(LH!!(L6
1251 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LB!!(LH!!(LH!!LaN!7TEp!!(LE
1252 !!(LG!<:OH!!(LH!!(LH!!(LI!!(LH!!(LI!!(LG!!(LI!!LaN!7TEp!!(LF!!(LG!!(LH!!:UL
1253 e,97Hdt%LM!8ISS,6([:rrBV.WW;JWrrDuqWW9C"s8AqtYP/"pWW95Rs+13&s81RO!<([Q!<([r
1254 !8QAR2?OLp!8QA<7LBARTA855+9DPugqcGh""8`Ug]76,!M9>]g]<uHqu?BF"h$l-#;;_Kg]l4-
1255 PhaagM#Q0@!8QA@+9DPugpApB&89kS!;tUP!;G7LScJ-W!K@'Pg]X2Kqc-XH~>
1256 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L"!<:OF!!(LD!!(LI!<:OI!!(LI!!(L:!<:OI!!(LH!!(L6
1257 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LB!!(LH!!(LH!!LaN!7TEp!!(LE
1258 !!(LG!<:OH!!(LH!!(LH!!(LI!!(LH!!(LI!!(LG!!(LI!!LaN!7TEp!!(LF!!(LG!!(LH!!:UL
1259 e,97Hdt%LM!8ISS,6([:rr=YL!!(=7rrDck!!"&6s8;ot&,-&%!!!O\s+13&s81LM!<(UO!<(Up
1260 !8?/5,68U)!8?.q1^+7N^Y7Cu'`e<gg7^A/#W8%(g&V$(!Lj&Yg&[WBqu?BD"e%7O$U2?)g'5Os
1261 akFi:`r=['!8?.`'`e<gg5mW`)MHhu!;tON!;G1JRK2^S!K$jMg'!iEqc-XH~>
1262 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L"!<:OF!!(LD!!(LI!<:OI!!(LI!!(L:!<:OI!!(LH!!(L6
1263 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LB!!(LH!!(LH!!LaN!7TEp!!(LE
1264 !!(LG!<:OH!!(LH!!(LH!!(LI!!(LH!!(LI!!(LG!!(LI!!LaN!7TEp!!(LF!!(LG!!(LH!!:UL
1265 e,97Hdt%LM!8ISS,6([:rr=YL!!(=7rrDck!!"&6s8;ot&,-&%!!!O\s+13&s81=H!<(FJ!<(Fk
1266 !7fVS'`oPH!7fVK-3FlWbLP-L%06IZeU]%L$q.;LeH#Ks!KmEPeH(d4qu?B?"b%d#&l?dNeHUX+
1267 c..jTc2Q6)!7fV+%06IZeSlB.-DT,A!;t@I!;G"EOT=bJ!J:@FeHD!7qGgOG~>
1268 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L#!!(LD!!(LD!!C[M!7UiGqpY'8!7UiG!7UlH!7U66!7UlH
1269 !7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH!7UlH!7UlHs3prI!7UcE!7UcE
1270 s3puJ!7UlH!7UlH!7UoI!7UlH!7UoI!7UfF!n..uquHcGrVurIqZ$WFquHcGrW!#K!7UlH!7QK!
1271 JH4I*s!%JCpAY,trMfkmnG`Kiri,t#p](2l!3c+rrMfk$JcC<$KE''K!M9>]g]<uHqu=Og!M0;X
1272 rrJ)Yp=oeB!;fbrJ,~>
1273 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L#!!(LD!!(LD!!C[M!7UiGqpY'8!7UiG!7UlH!7U66!7UlH
1274 !7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH!7UlH!7UlHs3prI!7UcE!7UcE
1275 s3puJ!7UlH!7UlH!7UoI!7UlH!7UoI!7UfF!n..uquHcGrVurIqZ$WFquHcGrW!#K!7UlH!7QK!
1276 JH4I*s!%JCpAY+-r;Zi_nG`InrVup)p](0l!"\f'r;Zg.JcC<$KE''I!Lj&Yg&[WBqu=Oe!La#T
1277 rrIuVp=]Y<!;fbrJ,~>
1278 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L#!!(LD!!(LD!!C[M!7UiGqpY'8!7UiG!7UlH!7U66!7UlH
1279 !7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH!7UlH!7UlHs3prI!7UcE!7UcE
1280 s3puJ!7UlH!7UlH!7UoI!7UlH!7UoI!7UfF!n..uquHcGrVurIqZ$WFquHcGrW!#K!7UlH!7QK!
1281 JH4I*s!%JCpAY+-r;Zi_nG`InrVup)p](0l!"\f'r;Zg.JcC<$KE''D!KmEPeH(d4qu=O`!KdBK
1282 rrI`Op=0;.!;]\qJ,~>
1283 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LC!!(LI!!(LH!!:ULe+WhBe+!D<e+s%Hdf9Bs
1284 kl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(LB!!(LG!!(LI!<:LK!7UlH
1285 "4I5Me,'+Fe,01Ge,97Kdf@kGrVurIr;ZiHrVurIr;ZrK!!(LE!!UgOdf9Bsr;ZrK!!(LF!!(LI
1286 !!C[MdfBBrrr<&JrW)uIJH16$g]7?us&Jdm!3H.!!<1sWrMfk$pAb)k!3^tRJcCB&akQogs7+kF
1287 ScJZf_V>0`!:9^dN;rV,"J,Vj<E4P~>
1288 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LC!!(LI!!(LH!!:ULe+WhBe+!D<e+s%Hdf9Bs
1289 kl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(LB!!(LG!!(LI!<:LK!7UlH
1290 "4I5Me,'+Fe,01Ge,97Kdf@kGrVurIr;ZiHrVurIr;ZrK!!(LE!!UgOdf9Bsr;ZrK!!(LF!!(LI
1291 !!C[MdfBBrrr<&JrW)uIJH16$g]7?us&Jdm!!`B%!<1sWr;Zg.pAb'k!"XY\JcCB&ak?cas7+eD
1292 RK36b_V,$Z!:9^dM?!;'"I]>f<E4P~>
1293 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LC!!(LI!!(LH!!:ULe+WhBe+!D<e+s%Hdf9Bs
1294 kl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(LB!!(LG!!(LI!<:LK!7UlH
1295 "4I5Me,'+Fe,01Ge,97Kdf@kGrVurIr;ZiHrVurIr;ZrK!!(LE!!UgOdf9Bsr;ZrK!!(LF!!(LI
1296 !!C[MdfBBrrr<&JrW)uIJH16$g]7?us&Jdm!!`B%!<1sWr;Zg.pAb'k!"XY\JcCB&ajgESs7+V?
1297 OT>:Y_US[L!:9^dK)bPp"H`]\<E4P~>
1298 s!%IC!7UfFrR:`GrR:]FrmTX&qpYQFr6tZGrR:cHqpYHC!7UH<qpYNEs3p-2s3pB9s3plGrmUfG
1299 s3pB9s3plGrmUfGs3pZA!7UfFrmLrLdf9CHe,B=Ie,'+Fe,'.De,KCKdfBBrrW)lF!<CUI!!C[M
1300 !7U`D!7UlHrR:`G!7UcErmUlI!7UcErmLlJdt%LM!8ISS,6([:s8AqtXPj-WWW96rs8AqtYCZ_)
1301 s+C?ng]=#Hn_=/:!;lf5g]<uHm/I*Fs7Y4NScJXf<Ib~>
1302 s!%IC!7UfFrR:`GrR:]FrmTX&qpYQFr6tZGrR:cHqpYHC!7UH<qpYNEs3p-2s3pB9s3plGrmUfG
1303 s3pB9s3plGrmUfGs3pZA!7UfFrmLrLdf9CHe,B=Ie,'+Fe,'.De,KCKdfBBrrW)lF!<CUI!!C[M
1304 !7U`D!7UlHrR:`G!7UcErmUlI!7UcErmLlJdt%LM!8ISS,6([:rr<*!!!!8^s8;ot&,-&%!!!O\
1305 s+13&s2isqRfDp3!La#cs2*IjRK2^S!K$jMg'!iEqc-XH~>
1306 s!%IC!7UfFrR:`GrR:]FrmTX&qpYQFr6tZGrR:cHqpYHC!7UH<qpYNEs3p-2s3pB9s3plGrmUfG
1307 s3pB9s3plGrmUfGs3pZA!7UfFrmLrLdf9CHe,B=Ie,'+Fe,'.De,KCKdfBBrrW)lF!<CUI!!C[M
1308 !7U`D!7UlHrR:`G!7UcErmUlI!7UcErmLlJdt%LM!8ISS,6([:rr<*!!!!8^s8;ot&,-&%!!!O\
1309 s+13&s2idlOoOt%!KdBZs2*:eOT=bJ!J:@FeHD!7qGgOG~>
1310 s!!!oc2[jnhZ*Z*NW9(.JH16$ciF(is&JdmrMfk#i;`bU!3c+rrMfk$JcC<$KE''K!M9>]g]<uH
1311 qu=Og!M0;XrrJ)Yp=oeB!;fbrJ,~>
1312 s!!!oc2[jnhZ*Z*NW9(.JH16$ciF(is&Jdmr;Zg-i;``U!"\f'r;Zg.JcC<$KE''I!Lj&Yg&[WB
1313 qu=Oe!La#TrrIuVp=]Y<!;fbrJ,~>
1314 s!!!oc2[jnhZ*Z*NW9(.JH16$ciF(is&Jdmr;Zg-i;``U!"\f'r;Zg.JcC<$KE''D!KmEPeH(d4
1315 qu=O`!KdBKrrI`Op=0;.!;]\qJ,~>
1316 s!!!oJH3.Z!7QK!JH4$ss!%JCpAb)k!3b>\rMfk$pAb)k!3^tRJcCB&akZprn_=/:!;lf5g]<uH
1317 m/I*Fs7Y4NScJXf<Ib~>
1318 s!!!oJH3.Z!7QK!JH4$ss!%JCpAb'k!"\#fr;Zg.pAb'k!"XY\JcCB&akHdpn_+#4!;lf5g&[WB
1319 m/I*Cs7Y.LRK34b<Ib~>
1320 s!!!oJH3.Z!7QK!JH4$ss!%JCpAb'k!"\#fr;Zg.pAb'k!"XY\JcCB&ajpFkn^RZ&!;lf5eH(d4
1321 m/I*<s7XtGOT>5X<Ib~>
1322 s!!!oJH16$JH1B(s!%JCpAb)k!3b>\rMfk$pAb)k!3^tRJcCB&[[mI!qu=L(!!)Bc!K@'Pg]X2K
1323 qc-XH~>
1324 s!!!oJH16$JH1B(s!%JCpAb'k!"\#fr;Zg.pAb'k!"XY\JcCB&[[I0rqu=L$!!)Bc!K$jMg'!iE
1325 qc-XH~>
1326 s!!!oJH16$JH1B(s!%JCpAb'k!"\#fr;Zg.pAb'k!"XY\JcCB&[ZLOiqu=Kp!!)Bc!J:@FeHD!7
1327 qGgOG~>
1328 s!!!oJH16$JH1B(s!%JCpAb)k!3b>\rMfk$pAb)k!3^tRJcCE'ZiL%(^B!X#!K@'Pg]X2Kqc-XH~>
1329 s!!!oJH16$JH1B(s!%JCpAb'k!"\#fr;Zg.pAb'k!"XY\JcCE'ZiL%(^B!X#!K$jMg'!iEqc-XH~>
1330 s!!!oJH16$JH1B(s!%JCpAb'k!"\#fr;Zg.pAb'k!"XY\JcCE'ZiL%(^B!X#!J:@FeHD!7qGgOG~>
1331 s!#5YrR:`GrR:]FrmUlIqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1!n..u
1332 kPtV3JH16$WrW/Ds&JdmrMfk$i;`bU!3c+rrMfk$JcC<$JcC<$g]%;5s7Y4NScJXf<Ib~>
1333 s!#5YrR:`GrR:]FrmUlIqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1!n..u
1334 kPtV3JH16$WrW/Ds&Jdmr;Zg.i;``U!"\f'r;Zg.JcC<$JcC<$g]%;2s7Y.LRK34b<Ib~>
1335 s!#5YrR:`GrR:]FrmUlIqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1!n..u
1336 kPtV3JH16$WrW/Ds&Jdmr;Zg.i;``U!"\f'r;Zg.JcC<$JcC<$g]%;+s7XtGOT>5X<Ib~>
1337 s!$_.!7TU$!7UlH!n..ur;ZrK!!(LB!!(LF!!(L=!!(LH!!^mP!7LoJe*-i7df9Bsn,NR>!!(LB
1338 !!C[M!7UE;"4I5Me+WhEdf9Bso)Jd>jo>J3!7U]C!7UK=!7UB:!7UfF!7UWA!7UQ?!7QK!JH4R-
1339 s!%JCpAb)k!3b>\rMfk$pAb)k!3^tRJcC<$JcFL)!K@'Pg]X2Kqc-XH~>
1340 s!$_.!7TU$!7UlH!n..ur;ZrK!!(LB!!(LF!!(L=!!(LH!!^mP!7LoJe*-i7df9Bsn,NR>!!(LB
1341 !!C[M!7UE;"4I5Me+WhEdf9Bso)Jd>jo>J3!7U]C!7UK=!7UB:!7UfF!7UWA!7UQ?!7QK!JH4R-
1342 s!%JCpAb'k!"\#fr;Zg.pAb'k!"XY\JcC<$JcFL)!K$jMg'!iEqc-XH~>
1343 s!$_.!7TU$!7UlH!n..ur;ZrK!!(LB!!(LF!!(L=!!(LH!!^mP!7LoJe*-i7df9Bsn,NR>!!(LB
1344 !!C[M!7UE;"4I5Me+WhEdf9Bso)Jd>jo>J3!7U]C!7UK=!7UB:!7UfF!7UWA!7UQ?!7QK!JH4R-
1345 s!%JCpAb'k!"\#fr;Zg.pAb'k!"XY\JcC<$JcFL)!J:@FeHD!7qGgOG~>
1346 s!$_.!7TU$!7UlH!n..ur;ZoJ!7UZB!7UfF!7UH<!7UlH!n..ur;ZiHlMpq6r;ZiHnc/[=r;ZiH
1347 q#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,!@jo>M4!!(L4!!(L&!!(L?!!(K!!.b.-!<48C<VHIk
1348 WW93[s8AqtYP/"pWW96]s+/CFb^muhbl>ocrrJ)Yp=oeB!;fbrJ,~>
1349 s!$_.!7TU$!7UlH!n..ur;ZoJ!7UZB!7UfF!7UH<!7UlH!n..ur;ZiHlMpq6r;ZiHnc/[=r;ZiH
1350 q#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,!@jo>M4!!(L4!!(L&!!(L?!!(K!!.b.-!<48C<VHIk
1351 !!!Mes8;ot&,-&%!!!Pgs+/CFb^muhbl>ocrrIuVp=]Y<!;fbrJ,~>
1352 s!$_.!7TU$!7UlH!n..ur;ZoJ!7UZB!7UfF!7UH<!7UlH!n..ur;ZiHlMpq6r;ZiHnc/[=r;ZiH
1353 q#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,!@jo>M4!!(L4!!(L&!!(L?!!(K!!.b.-!<48C<VHIk
1354 !!!Mes8;ot&,-&%!!!Pgs+/CFb^muhbl>ocrrI`Op=0;.!;]\qJ,~>
1355 ruqLEdfBBrrW)oGrW)oGrrE#Hec5d#!7UoIs3guKe+`nCe,'+Fe*?u8df@kq!!(L6!!(LH!!(L=
1356 !!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L@!!C[M!7UlH!n.,LrR:cH!Rh&Je,'+Jdf9Bs
1357 !<1IG!<:OI!!1OKrmU`E!7UoI!7UoI#1EPPe'e<Gr;clHquHcGr;cfFrrE#Hr;cfFrrE#HrVurI
1358 r;ZoJ!!)uHJH16$n,WJ4s&JdmrMfk!i;`bU!3c+rrMfk$JcC<$JcC<$g]%;5s7Y4NScJXf<Ib~>
1359 ruqLEdfBBrrW)oGrW)oGrrE#Hec5d#!7UoIs3guKe+`nCe,'+Fe*?u8df@kq!!(L6!!(LH!!(L=
1360 !!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L@!!C[M!7UlH!n.,LrR:cH!Rh&Je,'+Jdf9Bs
1361 !<1IG!<:OI!!1OKrmU`E!7UoI!7UoI#1EPPe'e<Gr;clHquHcGr;cfFrrE#Hr;cfFrrE#HrVurI
1362 r;ZoJ!!)uHJH16$n,WJ4s&Jdm!!3'!!!_B]r;Zg.pAb'k!"XY\JcC<$JcFL)!K$jMg'!iEqc-XH~>
1363 ruqLEdfBBrrW)oGrW)oGrrE#Hec5d#!7UoIs3guKe+`nCe,'+Fe*?u8df@kq!!(L6!!(LH!!(L=
1364 !!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L@!!C[M!7UlH!n.,LrR:cH!Rh&Je,'+Jdf9Bs
1365 !<1IG!<:OI!!1OKrmU`E!7UoI!7UoI#1EPPe'e<Gr;clHquHcGr;cfFrrE#Hr;cfFrrE#HrVurI
1366 r;ZoJ!!)uHJH16$n,WJ4s&Jdm!!3'!!!_B]r;Zg.pAb'k!"XY\JcC<$JcFL)!J:@FeHD!7qGgOG~>
1367 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me("Eue,B@Hdf]["!7LrIe,01Ge,04Fe*R,;df9Bsr;ZiH
1368 lMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHp&G*ArVurIr;ZoJ!7UlH"4I5M
1369 e,B=Ie,97He,B@Ie,B=Ie,97He,B@Ie,B=Ie,97He,97He,B=Pdf9Bs!7Lqsr;ZiHqZ$WFrVurI
1370 r;ZrK!!(LB!!C[M!7UiG!7UlH!n..ur;ZiHJH16$nGrS5s&Jdm!3H.!!<2Kf!3Z:#p](2l!3c+r
1371 rMfk$pAY-+rjVs=JcC<$JcC<$li.!Es7Y4NScJXf<Ib~>
1372 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me("Eue,B@Hdf]["!7LrIe,01Ge,04Fe*R,;df9Bsr;ZiH
1373 lMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHp&G*ArVurIr;ZoJ!7UlH"4I5M
1374 e,B=Ie,97He,B@Ie,B=Ie,97He,B@Ie,B=Ie,97He,97He,B=Pdf9Bs!7Lqsr;ZiHqZ$WFrVurI
1375 r;ZrK!!(LB!!C[M!7UiG!7UlH!n..ur;ZiHJH16$nGrS5s&Jdm!!`B%!<2Kf!"Su.!!2ior;Zg.
1376 pAY*nrVup/pAY+Qr[Rt#JcC<$JcC<$li.!Bs7Y.LRK34b<Ib~>
1377 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me("Eue,B@Hdf]["!7LrIe,01Ge,04Fe*R,;df9Bsr;ZiH
1378 lMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHp&G*ArVurIr;ZoJ!7UlH"4I5M
1379 e,B=Ie,97He,B@Ie,B=Ie,97He,B@Ie,B=Ie,97He,97He,B=Pdf9Bs!7Lqsr;ZiHqZ$WFrVurI
1380 r;ZrK!!(LB!!C[M!7UiG!7UlH!n..ur;ZiHJH16$nGrS5s&Jdm!!`B%!<2Kf!"Su.!!2ior;Zg.
1381 pAY*nrVup/pAY+Qr[Rt#JcC<$JcC<$li.!;s7XtGOT>5X<Ib~>
1382 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L"!<:OD!!C[Me'n9r!7UoI!7U]C!7UE;s3prI!7UlH!7U66
1383 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH!7UlH"Od>Ne'n3p!7UcE
1384 !7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UiG$e#+)!7LoJdf@hse,97He,'+Fe,9:He,01Ge,'.C
1385 e,KCJe,01Ge,97Ldf9Bsdt%LM!:Bje,6([:rrB>&WW;e`rrE&sWW93rs8AqtYP.trXo>=#Y4hkq
1386 Xo>=#XF^D&s+13$s6K[cN;rV,"J,Vj<E4P~>
1387 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L"!<:OD!!C[Me'n9r!7UoI!7U]C!7UE;s3prI!7UlH!7U66
1388 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH!7UlH"Od>Ne'n3p!7UcE
1389 !7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UiG$e#+)!7LoJdf@hse,97He,'+Fe,9:He,01Ge,'.C
1390 e,KCJe,01Ge,97Ldf9Bsdt%LM!:Bje,6([:rr<f4!!)6QrrN*#rVup-p](0l!"\f'!"&W)!"AT$
1391 !"8c+!!\#SJcC<$JcG'9!K$jMg'!iEqc-XH~>
1392 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L"!<:OD!!C[Me'n9r!7UoI!7U]C!7UE;s3prI!7UlH!7U66
1393 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH!7UlH"Od>Ne'n3p!7UcE
1394 !7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UiG$e#+)!7LoJdf@hse,97He,'+Fe,9:He,01Ge,'.C
1395 e,KCJe,01Ge,97Ldf9Bsdt%LM!:Bje,6([:rr<f4!!)6QrrN*#rVup-p](0l!"\f'!"&W)!"AT$
1396 !"8c+!!\#SJcC<$JcG'9!J:@FeHD!7qGgOG~>
1397 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L#!!(LB!!:ULe,97He,B=Ie+`nCe+!D<e,01Ge,97He*?u6
1398 e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+WhBe,97He,97He,9:He,B=Ie+s%E
1399 e,97He,97He,97He,B=Ie,97He,B=Ie,01Rdf@hsdf9Bs!7Lqsr;ZiHqZ$WFqZ-ZFrVurIqu?`G
1400 r;ZrK!!(LG!!(LH!!(LH!<:N!!.b.>!<48C<VHFm\G`E-md^;Wq#.2mXS;bnWW96rrrB;%WqQJk
1401 WW95Rs+13$s+149rrJ)Yp=oeB!;fbrJ,~>
1402 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L#!!(LB!!:ULe,97He,B=Ie+`nCe+!D<e,01Ge,97He*?u6
1403 e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+WhBe,97He,97He,9:He,B=Ie+s%E
1404 e,97He,97He,97He,B=Ie,97He,B=Ie,01Rdf@hsdf9Bs!7Lqsr;ZiHqZ$WFqZ-ZFrVurIqu?`G
1405 r;ZrK!!(LG!!(LH!!(LH!<:N!!.b.>!<48C<VHFm/H#PKbjk]5lhpe`#5A/r!!!Q'rr<`3!!!)o
1406 rr<-"!!!U^s+13$s+149rrIuVp=]Y<!;fbrJ,~>
1407 s!%IC!7UiG!7UlH!n..ur;ZrK!!(L#!!(LB!!:ULe,97He,B=Ie+`nCe+!D<e,01Ge,97He*?u6
1408 e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+WhBe,97He,97He,9:He,B=Ie+s%E
1409 e,97He,97He,97He,B=Ie,97He,B=Ie,01Rdf@hsdf9Bs!7Lqsr;ZiHqZ$WFqZ-ZFrVurIqu?`G
1410 r;ZrK!!(LG!!(LH!!(LH!<:N!!.b.>!<48C<VHFm/H#PKbjk]5lhpe`#5A/r!!!Q'rr<`3!!!)o
1411 rr<-"!!!U^s+13$s+149rrI`Op=0;.!;]\qJ,~>
1412 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LB!!C[M!7UlH"4I5Me,01Ge,97He+*J=e+s%H
1413 df9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(LB!!(LG!!(LI!<:LK
1414 !7UlH"4I5Me,'+Fe,04Ge,B=Ie,97He,B=Ie,97Kdf9BsqZ%#Q!7Lqs!!(IJdf@kq!!(LF!!(LI
1415 !!(LH!!C[M!7UoI!n..urW)uIrr<&JrW!#K!7UoIs3guKe,97Hdt%LM!:^'h,6([:rrC%:WW:lF
1416 rrD6[WqZPlWW96rrrBM+WW;bfrrDckWW9JYs+13$s+149rrJ)Yp=oeB!;fbrJ,~>
1417 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LB!!C[M!7UlH"4I5Me,01Ge,97He+*J=e+s%H
1418 df9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(LB!!(LG!!(LI!<:LK
1419 !7UlH"4I5Me,'+Fe,04Ge,B=Ie,97He,B=Ie,97Kdf9BsqZ%#Q!7Lqs!!(IJdf@kq!!(LF!!(LI
1420 !!(LH!!C[M!7UoI!n..urW)uIrr<&JrW!#K!7UoIs3guKe,97Hdt%LM!:^'h,6([:rr>pp!!&MY
1421 rrBS,!;HNl!!!Q'rr=AD!!)0VrrD3[!!"9qs+13$s+149rrIuVp=]Y<!;fbrJ,~>
1422 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LB!!C[M!7UlH"4I5Me,01Ge,97He+*J=e+s%H
1423 df9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(LB!!(LG!!(LI!<:LK
1424 !7UlH"4I5Me,'+Fe,04Ge,B=Ie,97He,B=Ie,97Kdf9BsqZ%#Q!7Lqs!!(IJdf@kq!!(LF!!(LI
1425 !!(LH!!C[M!7UoI!n..urW)uIrr<&JrW!#K!7UoIs3guKe,97Hdt%LM!:^'h,6([:rr>pp!!&MY
1426 rrBS,!;HNl!!!Q'rr=AD!!)0VrrD3[!!"9qs+13$s+149rrI`Op=0;.!;]\qJ,~>
1427 s!%IC!7UfFrR:`GrR:]FrmTX&qpYQFrmUfGrR:`G!7UfFrR:9:qpYNEs3p-2s3pB9s3plGrmUfG
1428 s3pB9s3plGrmUfGs3pZA!7UfFrmLrLdf9CHe,B=Ie,'+Fe,01HdfBBrrW)lF!<CUI!!C[M!7UcE
1429 !n..urVurIrW!#K!!)rGrrDuGrrE#Hr;ciGrW)rH!<CUJ!<1IH!<1FL!7LoJrR6;tJH50>s!%JC
1430 pAY-DrMfk:nc&U5r2TMkrMfk$pAY-0rMfk[q#:?WrMfk5ec5Yn`;fj]rr<"Brr<"Bb5_Kco`+r8
1431 cN!ogJcC<$hu<_9s7Y4NScJXf<Ib~>
1432 s!%IC!7UfFrR:`GrR:]FrmTX&qpYQFrmUfGrR:`G!7UfFrR:9:qpYNEs3p-2s3pB9s3plGrmUfG
1433 s3pB9s3plGrmUfGs3pZA!7UfFrmLrLdf9CHe,B=Ie,'+Fe,01HdfBBrrW)lF!<CUI!!C[M!7UcE
1434 !n..urVurIrW!#K!!)rGrrDuGrrE#Hr;ciGrW)rH!<CUJ!<1IH!<1FL!7LoJrR6;tJH50>s!%JC
1435 pAY,Gr;Zgrnc&T$quHKkr;Zg.pAY+`r;Zi*q#:?)r;Zgaec5Yn`;fj]rr<"Brr<"Bb5_Kco`+r8
1436 cN!ogJcC<$hu<_6s7Y.LRK34b<Ib~>
1437 s!%IC!7UfFrR:`GrR:]FrmTX&qpYQFrmUfGrR:`G!7UfFrR:9:qpYNEs3p-2s3pB9s3plGrmUfG
1438 s3pB9s3plGrmUfGs3pZA!7UfFrmLrLdf9CHe,B=Ie,'+Fe,01HdfBBrrW)lF!<CUI!!C[M!7UcE
1439 !n..urVurIrW!#K!!)rGrrDuGrrE#Hr;ciGrW)rH!<CUJ!<1IH!<1FL!7LoJrR6;tJH50>s!%JC
1440 pAY,Gr;Zgrnc&T$quHKkr;Zg.pAY+`r;Zi*q#:?)r;Zgaec5Yn`;fj]rr<"Brr<"Bb5_Kco`+r8
1441 cN!ogJcC<$hu<_/s7XtGOT>5X<Ib~>
1442 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCpAY-[r2Kb`oD\j[XSf*ms8AqtYP.trci'jDa8#Z7b5J=?
1443 cK"p+eouuEs8R<3s8R<@s8R<*s8R<@s8R<Bs8R<Bs8R;cs8R<8s8R;gs8R:os+14-rrJ)Yp=oeB
1444 !;fbrJ,~>
1445 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCpAY-7r;Zj"a7K<3cj9OLp](0l!"\f'!,qf9!*T*s!+Gg+
1446 !,^cr!hsn5pAb/:n,NE3r;Ze@k5YI*r;Ze@rr<"Brr<"Bb5_Kco`+r8cN!ogJcC<$hu<_6s7Y.L
1447 RK34b<Ib~>
1448 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCpAY-7r;Zj"a7K<3cj9OLp](0l!"\f'!,qf9!*T*s!+Gg+
1449 !,^cr!f;-PpAb/:n,NE3r;Ze@k5YI*r;Ze@rr<"Brr<"Bb5_Kco`+r8cN!ogJcC<$hu<_/s7XtG
1450 OT>5X<Ib~>
1451 s!!!oJH16$JH1B(s!%JCp&>$#rMfq%hYm3K!rh5cql9DjrMfk$pAY-Rr2KeOrql]rhlH^U!93)>
1452 "TF+!H1Ue1s**r3s*+D@s**W*s*+5;s*)H^s*+,8s*'%oJcDbM!K@'Pg]X2Kqc-XH~>
1453 s!!!oJH16$JH1B(s!%JCp&>"=r;Zm/SGDpZ!r]2;qZ-Bjr;Zg.pAY,sr;Zm"P5b@Y!M9Jm!!'"Z
1454 rri7HGC08^s8R<3s8R<@s8R<*s8R<;s8R;^s8R<8s8R:os+13MrrIuVp=]Y<!;fbrJ,~>
1455 s!!!oJH16$JH1B(s!%JCp&>"=r;Zm/SGDpZ!r]2;qZ-Bjr;Zg.pAY,sr;Zm"P5b@Y!M9Jm!!'"Z
1456 rrhq=GD6%js8R<3s8R<@s8R<*s8R<;s8R;^s8R<8s8R:os+13MrrI`Op=0;.!;]\qJ,~>
1457 s!!!oJH16$JH1B(s!%JCp&>$Lql1%._pmDsi8EMIeAniiWqZPlWW96rrrN#"r2Kt1ceI@3d(0(S
1458 !Nl4Zrrhe7I<VI\s8R<3s8R<@s8R<*s8R<;s8R;^s8R<8s8R:os+13MrrJ)Yp=oeB!;fbrJ,~>
1459 s!!!oJH16$JH1B(s!%JCp&>#cqZ%!<9n&1qUSFHHIodH^!;HNl!!!Q'rrMa#qu?pKDj-iZF>!Ik
1460 !=SGYrrgtuMKd_Is8R<3s8R<@s8R<*s8R<;s8R;^s8R<8s8R:os+13MrrIuVp=]Y<!;fbrJ,~>
1461 s!!!oJH16$JH1B(s!%JCp&>#cqZ%!<9n&1qUSFHHIodH^!;HNl!!!Q'rrMa#qu?pKDj-iZF>!Ik
1462 !=SGYrrf*@I<Y/Ss8R<3s8R<@s8R<*s8R<;s8R;^s8R<8s8R:os+13MrrI`Op=0;.!;]\qJ,~>
1463 s!!!oJH3+YrR9a+rR6;tJH5EEs!%JCo`"p/kc4CWrMfk$p&>$@n>ZK8j8T7nGKY2\p](8;"T59H
1464 KY[Te#lVW&I!qF:s8Vt?!<;q?s8N<%_NB4oRG.Z?s*"P@T6^>6qfi)?s*+JBs*+JBs*+JBs*"YG
1465 \Uf.$q>UBul'$FRj`bqErs&;7KR&9Tqu6WqG6RuVJUF-drr32gP^8ANGB`l_$gX%'NoYD.s8.+f
1466 mJd+orHrkRs*&\d\Uf.$q>UBuq7qZ/Ks1CQs8R9NrjdZ2Y5eI-K7'Hlrr<"Brr3/uZ\Ng]^OcE9
1467 s60I`N;rV,"J,Vj<E4P~>
1468 s!!!oJH3+YrR9a+rR6;tJH5EEs!%JCo`"nckQ(AWr;Zg.p&>#?n,NH0j8T7>GNj=/p](8;"SeF2
1469 Mq%b+#lD#eH@VaWs8Vt?!<;q?s8N<#[>K9\U@%s[s*"P9Oa-d'qfi)?s*+JBs*+JBs*+JBs*"YE
1470 W-j)urr2p%d>E4<pigrXrs&%sIX6pcrr2rtG6RoCI"/@!rr32PMKtZcGB`l_$e1&ZReV)Ns7LV_
1471 qu6U(qg!J`s*&\bW-j)urr2p%nudFfMnT,hs8R9Nr2G1!^]4/-J:P!*rr<"Brr3/lVh02Td"24J
1472 s60I`M?!;'"I]>f<E4P~>
1473 s!!!oJH3+YrR9a+rR6;tJH5EEs!%JCo`"nckQ(AWr;Zg.p&>#?n,NH0j8T74GKP-@p](8;"QYSh
1474 PjA>K#k"[FH%`?qs8Vt?!<;q?s8N;kWJ#PMY5&"rs*"P!LNr^rqfi)?s*+JBs*+JBs*+JBs*"Y;
1475 RX0Y(rr2p%]RtU3r-*A\rrqY[H[Cq#rVunA"nJ+.KYm`frs$8lI&d*gGPV7H^k@*8r-*AbeTccG
1476 rr3DnG^]PjGB`VHHA'07rr3/dTR2$Kc2I\BG7*o2I#6DRlC!$S`r5r;GQ.UGi15=DRH&kuJcFs6
1477 !J:@FeHD!7qGgOG~>
1478 s!#8ZqpYKD!7UlHrR:WD!n.,LqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3p34!7UWA!7Ta(
1479 !7U66s3pZA!7T^'!7QK!JH5EEs!%JCo`"sh_s+2qs8AqtYP%nrr4qm'!PA6irs&@FIK-BnfD,CG
1480 G8%dQpnW/Rs8AL6`;/tpH.W)rGB`ubs*+GA&,i&E`;/tpH.W)rGB^[ZnG<[email protected]
1481 GQ.XBG7VdLr5!TBs8Vb<J*-O3GB`o`#Q'/$r:e$OPQ(U^G7VdLr5!TBs8Ve>IcU:,GB`o`%/,$s
1482 jS5m%GQ7]bGF&7.(@ZO$s8R:eaP6X/GEr4.qh*;opVD';rr<"B$cq$!`HSGeg&/g5RK!6dGQ7[I
1483 qi,m@q=M=Ns+146rrJ)Yp=oeB!;fbrJ,~>
1484 s!#8ZqpYKD!7UlHrR:WD!n.,LqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3p34!7UWA!7Ta(
1485 !7U66s3pZA!7T^'!7QK!JH5EEs!%JCo`"sb:$DZPs8;ot&,#r'p-S<M!AsH0rs&.@K`?^Mp%\Re
1486 G8$\?nVDGTs8%IsebnZbHh7:;GB`ubs*+GA&,M$-ebnZbHh7:;GB]SHh>[email protected]
1487 GQ.XBG7U\;q4`)Gs8V8,M=U55GB`o`#PX29rUR"5[Jp4+G7U\;q4`)Gs8VA/M"1#.GB`o`%-i(n
1488 naW8rGQ7]2GJjF[(>F%us8R:eWTj5QGJ*tUpPe)0nuHuBrr<"B$`E1aVK^a[kPD'"_Z'T8GQ7[I
1489 p3h>?qs:>6s+146rrIuVp=]Y<!;fbrJ,~>
1490 s!#8ZqpYKD!7UlHrR:WD!n.,LqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3p34!7UWA!7Ta(
1491 !7U66s3pZA!7T^'!7QK!JH5EEs!%JCo`"sb:$DZPs8;ot&,#r'p-S<M!AsH0rs%)"XT*]nqtU3k
1492 G8%4UjF2ILs6G)gj8I\[M#./OGB`ubs*+GA&*nY!j8I\[M#./OGB^1`]))I,[email protected]
1493 GQ.XBG7UbFo8%VPs8To[VtfDjGB`o`#Mbj8rT]Gfi;WcVG7UbFo8%VPs8U&_V>0,eGB`o`%)mIf
1494 puK57GQ7\sGNf&+(8H)rs8R:eX7Gk<GNJl)gmm^/lAp/Irr<"B$`W[hMKeE]nb%c`kl1V^GQ7[I
1495 gj4h;rSs/os+146rrI`Op=0;.!;]\qJ,~>
1496 s!$_.!7TEt!7UoIs3prI!7UlH!7UlHs3pfE!7UK=!7UlH#1EPPdf9Bskl:h7!!(L;!!C[M!7UZB
1497 "4I5Me*m>>df9BspAb<E!!(L5!!(LA!!(L3!!(LB!!(L5!!(LA!!(L6!!(L>!!(K!!.b.E!<48C
1498 <V$.jiOA?W!P#91WqZPlWW96prrW,DXS/XqXj?n)rs%M-QN-2nOSJkUG6tMRs7CMfs4_afrr32p
1499 GD6(sGB`ubs*+GA!o%phrr35qGD6(sGB^7cs8R<@s8R<Bs8R<Bs8R<Bs8R9RYQ+Y!GC9Gj`cn`g
1500 s7CMZp&>*mGC'8gs*#!Ws8Vq>I/j5fGHh,Io65ETruB+(YlFapGBa)epih)\s8U8dYQ+WHGH_&H
1501 qKI>`rrW1DHN*sEG71PQs8$qcXoJFtGC9Dis*+MC!n):dJcC<$jSo7>s7Y4NScJXf<Ib~>
1502 s!$_.!7TEt!7UoIs3prI!7UlH!7UlHs3pfE!7UK=!7UlH#1EPPdf9Bskl:h7!!(L;!!C[M!7UZB
1503 "4I5Me*m>>df9BspAb<E!!(L5!!(LA!!(L3!!(LB!!(L5!!(LA!!(L6!!(L>!!(K!!.b.E!<48C
1504 <V$.jV^_-9!@eES!;HNl!!!Q%rrVn1#5/#u$#oOsrs#oU`rF&&[eTn&G7!C2s5\Bes/^Fgrr32b
1505 GFAL2GB`ubs*+GA!j$Uirr35cGFAL2GB`-Cs8R<@s8R<Bs8R<Bs8R<Bs8R9RirB&MGCokpOE]je
1506 s5nNLp&>*kGCKPks*#"5s8V\7K)bk6GNJl)j*,_Dru@2Gjo>A@GBa)emWX-Zs8S:,j8].'GN/Z&
1507 o65f_rrW+BIfBBIG73C0s7CM`iW&rMGD#nps*+MC!hFP`JcC<$jSo7;s7Y.LRK34b<Ib~>
1508 s!$_.!7TEt!7UoIs3prI!7UlH!7UlHs3pfE!7UK=!7UlH#1EPPdf9Bskl:h7!!(L;!!C[M!7UZB
1509 "4I5Me*m>>df9BspAb<E!!(L5!!(LA!!(L3!!(LB!!(L5!!(LA!!(L6!!(L>!!(K!!.b.E!<48C
1510 <V$.jV^_-9!@eES!;HNl!!!Q%rrVn1#5/#u$#oOsrs"R/l2R&nj7rZSG7!pAs0-^gs,;0frr320
1511 GKp0fGB`ubs*+GA!fV?hrr351GKp0fGB`]Ss8R<@s8R<Bs8R<Bs8R<Bs8R9RoDej9GGG3<Jp6nf
1512 s0?imp&>*`GEi+,s*#"Fs8UAgU]:@HGP(q8YBP3eru?Z8o`+rpGBa)ea*3gJs8R^qo`+r8GOtk7
1513 c?H&[rrV_7PlC^_G74$Bs3Z%AoDej<GGkH?s*+MC!f)!eJcC<$jSo74s7XtGOT>5X<Ib~>
1514 s!$_.!7THu!7UoI!n..urVurIr;ZiHrW!#K!7UfF!7UH<!7UlH!n..ur;ZiHlMpq6r;ZiHnc/[=
1515 r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHlMpq6p&G*Ar;ZiHiW&u-l2Uh5p&G*Ag].?'JH16$
1516 pAk4;s&JRg"n1$_]!AI;WX,Z/Z+8!/n,KTiWqZPlWW96nrs\PQ_mZeMX0/hDbi&<Urs+j7iW&h%
1517 Hi3^>s*"e9s8W%AHN0CWh#@<Xrc`\gs*&\bs8R<ArrSU4h#@<Yrc`\gs*&\Pq#CA<r;Ze@rr<"B
1518 rr<"Brr<"B&+0Dsrc`Ves,2*fs8W%AGPV7?c^'%ZG5umes8R9RmJm4cGBj/[email protected]
1519 GO5A0rHEJbrt2nfVZ6XIHM[[AGB`HSs8I4err3&GQ@AgW!-nMCs*"k<s8W(BGO>G1rc`Vds8R<C
1520 rrS:+kCNYas5a1\N;rV,"J,Vj<E4P~>
1521 s!$_.!7THu!7UoI!n..urVurIr;ZiHrW!#K!7UfF!7UH<!7UlH!n..ur;ZiHlMpq6r;ZiHnc/[=
1522 r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHlMpq6p&G*Ar;ZiHiW&u-l2Uh5p&G*Ag].?'JH16$
1523 pAk4;s&JRg&^Z861)UB"!!!-4(G9!NdJjaV!!!)ps8;ot&+]`/i/UMX'*A=G+?aD6n)F?QrdK+e
1524 s7ghfrqZToG7"0Hs8$qes*o7err33#GCBMkGB`ubs*+GA!e5Fgrr36$GCBMkGB`oYs8R<@s8R<B
1525 s8R<Bs8R<Bs8R9Rqu?]pGBs5gI!>Jfs8."aqYpZs^lNmBG5umes8R9Rqu?]pGBs5gI!>Jfs8$q`
1526 qYpeJGPhF?qKI/_rtg]>f`1kqIK'9HGB`[email protected])6O*pqN!-nMCs*"kJs8W%AGPhF?rHEPd
1527 s8R<CrrRUmq18Qss5a1\M?!;'"I]>f<E4P~>
1528 s!$_.!7THu!7UoI!n..urVurIr;ZiHrW!#K!7UfF!7UH<!7UlH!n..ur;ZiHlMpq6r;ZiHnc/[=
1529 r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHlMpq6p&G*Ar;ZiHiW&u-l2Uh5p&G*Ag].?'JH16$
1530 pAk4;s&JRg&^Z861)UB"!!!-4(G9!NdJjaV!!!)ps8;ot&+]`/i/UMX'*A=G+?aD6n)F?Pr-Nbf
1531 s5A3gq#CA<$2so(lZ\<fH[#Adrs&(=NrT-'GPqL@GQ%OCH[#Adrs/.>NrT-'GQ%=:s*+D@s*+JB
1532 s*+JBs*+JBs*#"Ps8Vk<IK0=nGQ%RAm!![Mrr`/)ML,8G!."SDs*#"Ps8Vk<IK0=nGQ%RAlZ[RL
1533 rs*jorVuo`GBa&d#(_!fs7CT!rr<"B$iU,*pih/ds80-[HN&*gH2djDG74BLs7ge^rVuomGC]\m
1534 s*+MC!d](gJcC<$jSo74s7XtGOT>5X<Ib~>
1535 ruqLEdfBBrrW)oGrW)oGrrE#HfDkp#qZ$WFq#CWJ!!(IJ!7UiG!7U66!n..ur;ZiHlMpq6r;ZiH
1536 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHp]19ArW)oGrr<)K!<1IH!<1FJ!7UoIrmUTA
1537 s3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gp&G*Aqu?cH!<1II!!1OKrmUfGs3poH!7UoI
1538 !7UiG!7QK!JH5EEs!%JChu<\[ri,t#\,QI$qKDqHq>^J=!;uir%sN9uI!9j]G^+FVGlRefGPqL@
1539 GQ%ONI!9j]G^+FVGlRefGQ%=:s*+D@s*+JBs*+JBs*+JBs*+GAs*+MC!dT"grr<"BqYpfQGED+g
1540 s*&\ds8R<As8R<CrrRIir;Q`rGP_=@H$B2cs8R<Brs&.?IfK"`NW/tXGQ%RAGQ7[JfQWGBrVq(c
1541 rr<"BrVunArVunArr<"Bs8N.HGQ!*mJcFg2!K@'Pg]X2Kqc-XH~>
1542 ruqLEdfBBrrW)oGrW)oGrrE#HfDkp#qZ$WFq#CWJ!!(IJ!7UiG!7U66!n..ur;ZiHlMpq6r;ZiH
1543 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHp]19ArW)oGrr<)K!<1IH!<1FJ!7UoIrmUTA
1544 s3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gp&G*Aqu?cH!<1II!!1OKrmUfGs3poH!7UoI
1545 !7UiG!7QK!JH5EEs!%JChu<ZerVup)\,QHkqKDr&q>^J='E8%3rc`VeG^"FYG^+FVGlRefGPqL@
1546 GQ%ONG^"FYG^+FVGlRefGQ.C;s*+D@s*+JBs*+JBs*+JBs*+GAs*+MC#C(Ils8W(BGP_=EX`pr<
1547 rr.+crr<"BrVunAs8N=KGQ.XBrc`S_rs*dmrr<#tGBa&d#3L,`s5S=,rr<"BrVunAs8N>+GHUK8
1548 rc`Scs8R<As8R<As8R<Bs8R<CrrI@gJcC<$j8T.:s7Y.LRK34b<Ib~>
1549 ruqLEdfBBrrW)oGrW)oGrrE#HfDkp#qZ$WFq#CWJ!!(IJ!7UiG!7U66!n..ur;ZiHlMpq6r;ZiH
1550 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHp]19ArW)oGrr<)K!<1IH!<1FJ!7UoIrmUTA
1551 s3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gp&G*Aqu?cH!<1II!!1OKrmUfGs3poH!7UoI
1552 !7UiG!7QK!JH5EEs!%JChu<ZerVup)\,QH8qKDr4q>^J=rr3Q-GC':6GBnIYG^"@Ws8R:er;Ze@
1553 rVm:NGBnIYG^"@Ws8R:ep](8;r;Ze@rr<"Brr<"Brr<"BrVunAs8N+EGQ.UDr-*A]rs+R.`V'9/
1554 GBa&ds*+GAs*+MC!I/hfrrW+BGP_=?G^'/e!rR7drr325GHChGGMrK#s*+GAs*+MC#EF#Ip&Fr6
1555 GQ.XBGQ%RAGQ%RAGQ.XBGQ7[DG^"`=JcFd1!J:@FeHD!7qGgOG~>
1556 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me(4U!e,01Ge+s%Hdf9BsrVurIr;ciGm/R7;!!(LH!!(L6
1557 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LD!!(LH!!:ULe,97Kdf@kGrW!#K
1558 !7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(LA!!(LG!<:OI
1559 !!C[M!7UoI!7UlH!7UlH!7UoI!7UiG!7QK!JH5EEs!%JChu<\Zri,t(\,QNSGE`%+!p4]\q>^J=
1560 $1.]lrHESfP'?-cs8R<@s8R<ArrS@-kkY8YGPD.;[email protected]%RAGQ7[JMg+Rg
1561 [email protected]*Aas8R<As8R<Crs+L,m/R+aGB`o`#E3lns8W%AGQ%OFX`qG-GL$3fs*+GA
1562 s*+MC#DmZks8W"@GQ.XBGQ%RAGQ%RAGQ.XBGQ7[EOE]l=s+142rrJ)Yp=oeB!;fbrJ,~>
1563 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me(4U!e,01Ge+s%Hdf9BsrVurIr;ciGm/R7;!!(LH!!(L6
1564 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LD!!(LH!!:ULe,97Kdf@kGrW!#K
1565 !7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(LA!!(LG!<:OI
1566 !!C[M!7UoI!7UlH!7UlH!7UoI!7UiG!7QK!JH5EEs!%JChu<ZdrVup9\,QMsGJO4X!l0#Iq>^J=
1567 $2ac&qfdGfI<YP`s8R<@s8R<ArrRUmqYC0kGPD.;[email protected]%RAGQ7[JI!>Jf
1568 s8."aqYpeIGPhF?pigr]s8R<As8R<Crs*pqqu?]mGB`o`#CLams8Vq>GQ%OFLNi!QGOth6s*+GA
1569 s*+MC#CC[ls8Vk<GQ.XBGQ%RAGQ%RAGQ.XBGQ7[EI<YL<s+142rrIuVp=]Y<!;fbrJ,~>
1570 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me(4U!e,01Ge+s%Hdf9BsrVurIr;ciGm/R7;!!(LH!!(L6
1571 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LD!!(LH!!:ULe,97Kdf@kGrW!#K
1572 !7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(LA!!(LG!<:OI
1573 !!C[M!7UoI!7UlH!7UlH!7UoI!7UiG!7QK!JH5EEs!%JChu<ZdrVup9\,QM`GNSo)!g@iQq>^J=
1574 $2so(m!"EgH?]>`s8R<@s8R<ArrRLjrV?KnGPD.;[email protected]%RAGQ7[JH?]>f
1575 s6OrRqYpeGGQ%RAiHKMFs8R<As8R<Crs*jorVuo`GB`o`#C:Ums8VD/GQ%OFIWtL?GP_==s*+GA
1576 s*+MC#C1Ols8V&%GQ.XBGQ%RAGQ%RAGQ.XBGQ7[EH?]:<s+142rrI`Op=0;.!;]\qJ,~>
1577 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!(LH!!(LG!<:OI!!(LI!!(LE!!(L;!<:OI!!(LH!!(L6
1578 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LC!<:OG!<:OH!!(LH!!:ULe,97H
1579 e+!D@df@hse,97He,B=Ie,'+Fe,97Jdf9CGdf9CFe,97He+NbAe,01Ge,97Kdf9Bsq#CEDr;ZiH
1580 rVurIqu?`GJH16$pAk4;s&Jal!3uO*!O)ImrrE#rWW9W?rr`4LGi8T$"8mIilh^Y]G6tPSs7CMe
1581 s4MUdq>UMDGPh@=!do4hrr3&QGF\L/s*+5;!do4hrVunArr<"Brr<"Brr<"BrVunAs8N>CGI.>L
1582 olkWVrs+'unc/XVGBa&ds*+GAs*+MC#KM%ns8V_8GP_=Ea*4fgs7CMZrVm#jGCtd%rVunArVunA
1583 s8N=SGOb_5m<<dRs8R<As8R<As8R<Bs8R<CrrUVmU4N>qs5a1\N;rV,"J,Vj<E4P~>
1584 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!(LH!!(LG!<:OI!!(LI!!(LE!!(L;!<:OI!!(LH!!(L6
1585 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LC!<:OG!<:OH!!(LH!!:ULe,97H
1586 e+!D@df@hse,97He,B=Ie,'+Fe,97Jdf9CGdf9CFe,97He+NbAe,01Ge,97Kdf9Bsq#CEDr;ZiH
1587 rVurIqu?`GJH16$pAk4;s&Jal!#>J@!>#"srrMutrVupP\Gl[-H$K,`rr`%@H2@C;s*"e2s8V2)
1588 OoMD)aSGi;H$B8drrRIirr2p!WHZGZs8R<;rrRIirr)lsGQ.XBGQ.XBGQ.XBGQ%RAGQ7[JOE]pg
1589 s5nNLqYpeGGPqL@d<Bg6s8R<As8R<Crs+[1jo>AAGB`o`#Ea5ls8V/(GQ%OEginp/LAh/PGQ%RA
1590 GQ7[JH$B2ds3Z%7rr<"BrVunArVunArr<"Bs8N.lGLM-CJcFg2!K$jMg'!iEqc-XH~>
1591 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!(LH!!(LG!<:OI!!(LI!!(LE!!(L;!<:OI!!(LH!!(L6
1592 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LC!<:OG!<:OH!!(LH!!:ULe,97H
1593 e+!D@df@hse,97He,B=Ie,'+Fe,97Jdf9CGdf9CFe,97He+NbAe,01Ge,97Kdf9Bsq#CEDr;ZiH
1594 rVurIqu?`GJH16$pAk4;s&Jal!#>J@!>#"srrMutrVupP\GlZsG^B;err_2(J,T6Ds*"eAs8T?J
1595 aT%0BkkY5ZG^')c!I/herrS+&kkY8YGPD+<G^')cs*+JBs*+JBs*+JBs*+GAs*+MC#D.0ms8TBK
1596 GP_=EG^'/es.4FYrr<"BrVunAs8N=UGP(q8Y]k<frs+."o`+rqGBa#c"KZg^H*I8Is*+GAs*+MC
1597 #C(Ils8S[7GQ.XBGQ%RAGQ%RAGQ.XBGQ7[ELNi-:s+142rrI`Op=0;.!;]\qJ,~>
1598 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!(LH!!(LH!!(LG!;k7B!!(L<!!(LG!!(LH!!(L6!!(LH
1599 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LA!<:OG!<:OJ!!(LH!!:ULe,97He+!D@
1600 df@hse,97He,B=Ie,'+Fe,97Jdf@kq!!:ULe+`nCe+NbAe,04Ge,B=Ldf9Bsq#CEDqu?fI!7UfF
1601 !7QK!JH5EEs!%JCp&>#urMfkco)A^\rMfk;\GlWrGCobm!lK5NqZ$S>'u8r+VKg#YrM+VBm/?\5
1602 W;ln#GJ=(Urt;JY^Ae04rM+VBm/?\5W;lmAGPD+>Y'7VZrr<"Brr<"Brr<"Brr<"BrVunAs8N>s
1603 H@P)QZZgWirs-MeRJH6>GBa&ds*+GAs*+MC#PNLnjnQ'(GP_=Ep3V8Mponsdr;QklGB]SUs8R<A
1604 s8R<Crs-MeRJH6>GBa&ds*+GAs*+GAs*+JBs*+MC#5aC*a85G@]DqnTpAb/:jT#7(nGiN4[K$8N
1605 rr<"BeGoPmnc&WKs7Y4NScJXf<Ib~>
1606 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!(LH!!(LH!!(LG!;k7B!!(L<!!(LG!!(LH!!(L6!!(LH
1607 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LA!<:OG!<:OJ!!(LH!!:ULe,97He+!D@
1608 df@hse,97He,B=Ie,'+Fe,97Jdf@kq!!:ULe+`nCe+NbAe,04Ge,B=Ldf9Bsq#CEDqu?fI!7UfF
1609 !7QK!JH5EEs!%JCp&>"3r;ZiCo)A^Dr;Zgt\GlWSGEDb&!g%WMqZ$S>'Vb0hM0S:bqi#g<o)A7/
1610 RfEDBGM`;u!etpUrr3E(N-W>3rq"R,s8R:ep\t;LGM`;us*+JBs*+JBs*+JBs*+GAs*+MC#Np>i
1611 o(&T#GP_=EQZp(>igt@<rr<"BrVunAs8N>gG_u"]Tm(_Wrs.e5M=U21GBa#c"TEsrGL-6fs*+GA
1612 s*+MC#FBYHr8O;lGQ.XBGQ%RAGQ%RAGQ.XBGQ7[Ip3h>@r9^Mrs8R<:s8R<(s8R<4s8R;Ns8R<B
1613 s8R;ms8R<5rrIuVp=]Y<!;fbrJ,~>
1614 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!(LH!!(LH!!(LG!;k7B!!(L<!!(LG!!(LH!!(L6!!(LH
1615 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LA!<:OG!<:OJ!!(LH!!:ULe,97He+!D@
1616 df@hse,97He,B=Ie,'+Fe,97Jdf@kq!!:ULe+`nCe+NbAe,04Ge,B=Ldf9Bsq#CEDqu?fI!7UfF
1617 !7QK!JH5EEs!%JCp&>"3r;ZiCo)A^Dr;Zgt\GlW!GJj@Y!ePX^qZ$S>'X@GpIXCegm!sQ3p\jL#
1618 MuWg+GO>A/!e,@\rr3DnJ:>l>rU%[as8R:ep\t;DGO>A/s*+JBs*+JBs*+JBs*+GAs*+MC#JkYa
1619 q<#P<GP_=EKQkrDdDC*Orr<"BrVunAs8N>AGc(8t^it#!rs-GdVYK8gGBa#c"T3XkGO5;.s*+GA
1620 s*+MC#D@<Nr6`B*GQ.XBGQ%RAGQ%RAGQ.XBGQ7[Igj4k=rT'6Us8R<:s8R<(s8R<4s8R;Ns8R<B
1621 s8R;ms8R<5rrI`Op=0;.!;]\qJ,~>
1622 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LH!!(LH!!(LI!!(LB!!C[M!7UlH!7UK=!7UcE
1623 "4I5Me*-i7df9Bsn,NR>!!(LG!!(LH!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsp](<Cr;ZoJ!7UlH
1624 !n..ur;ZoJ!7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97H
1625 e+NbAe,01HdfBBrrVurIq#CEDqu?fI!7UfF!7QK!JH5EEs!%JCp&>$(rMfkGo)A^ArMfkL\GlW4
1626 GH1T@!qLP`qZ$S>"T53FK>.?b,Q>rUJ9Z[=df9@@UOdZ6s8VefJTuD=s8L92J9Z[=df9>kGPD+C
1627 p7m1`GQ7\eGQ.XBGQ.XBGQ.XBGQ%RAGQ.UHk`^:PjEGkFrs/J,J9m[PGBa&ds*+GAs*+JB#3qCt
1628 NoP>-q>UZaPBi2KGB`ub"6t)Tm/?taGQ%RAGQ7[Jr3:cuRdPBDrr<"BrVunArVunArr<"Brr3/t
1629 Z%[FY^q9XHGP;(:GNAf(GPV:=GP_@>GQ7[Im^8(%H]Yu;rs.JbMLBr5ZK1WWs**?"s*+JBs*)um
1630 s*+#5!K@'Pg]X2Kqc-XH~>
1631 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LH!!(LH!!(LI!!(LB!!C[M!7UlH!7UK=!7UcE
1632 "4I5Me*-i7df9Bsn,NR>!!(LG!!(LH!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsp](<Cr;ZoJ!7UlH
1633 !n..ur;ZoJ!7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97H
1634 e+NbAe,01HdfBBrrVurIq#CEDqu?fI!7UfF!7QK!JH5EEs!%JCp&>"Kr;ZhDo)A]Gr;ZhR\GlVa
1635 GMi>u!oJ3UqZ$S>"S\:/MUMM(,Q5EAI<gUIhuE`AR!j4's8VAOI<]u9s8B`sI<gUIhuE_#GPD+C
1636 lBm!EGQ7\eGQ.XBGQ.XBGQ.XBGQ%RAGQ.UHd#!%:pNLlYrs/@oI!qmhGBa&ds*+GAs*+JB#1ABS
1637 RJ1oLq>UZIMKtWaGB`ub"3>\3qu-QpGQ%RAGQ7[Jq4`7bVYbR]rr<"BrVunArVunArr<"Brr3/l
1638 V1<iQd(B>XGP;(:GNAf(GPV:=GP_@>GQ7[IiN.i\I[84Srs8VQVMBMLOh:/Ts8R<"s8R<Bs8R;m
1639 s8R<5rrIuVp=]Y<!;fbrJ,~>
1640 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LH!!(LH!!(LI!!(LB!!C[M!7UlH!7UK=!7UcE
1641 "4I5Me*-i7df9Bsn,NR>!!(LG!!(LH!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsp](<Cr;ZoJ!7UlH
1642 !n..ur;ZoJ!7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97H
1643 e+NbAe,01HdfBBrrVurIq#CEDqu?fI!7UfF!7QK!JH5EEs!%JCp&>"Kr;ZhDo)A]Gr;ZhR\GlVY
1644 GOk\3!igIHqZ$S>"QPJePNr/I,PJL(I!^gXm/R+6OaD=ss8UN0H['c7s7WgZI!^gXm/R*0GPD+C
1645 dZJm$GQ7\eGQ.XBGQ.XBGQ.XBGQ%RAGQ.UH]RkL1q0.2^rs.eSH@iX)GBa&ds*+GAs*+JB#/5_:
1646 W;Lj`q>UZ5K6sQpGB`ub".".]rVccrGQ%RAGQ7[Jl'?XI\,CMprr<"BrVunArVunArr<"Brr3/Y
1647 Rs]RNj1G?kGP;(:GNAf(GPV:=GP_@>GQ7[IeY@bBJtCcors8SESqMBBRDo$os8R<"s8R<Bs8R;m
1648 s8R<5rrI`Op=0;.!;]\qJ,~>
1649 s!%IC!7UfFrR:`GrR:]FrmTU%rR:`Gr6kWGqpYHC!7UoIrR:9:qpYNEs3p-2s3pB9s3plGrmUfG
1650 s3pB9s3plGrmUfGs3pZArR:`GrR:cH!7UlH!n.,LrmLlJe,B@He+WhBe,B=Kdf9CGe,KFHe,KCJ
1651 e,97Jdf9CIdfTU!!!)uHrW)lFp](<Cqu?`Gq>^NEqZ-QCr;ZiHq>^NEJH16$pAk4;s&Jal!71VD
1652 !O)1grrMerrMfkbJcEjl!rR7hao;G.GD1VJq#CA<jT#7(q>^J=pAYAT_s@9m[s+2:rsJV!H*-*&
1653 p>)HfY4VboGM`B"GQ.XBGLZZmGOb\6N;rV,"J,Vj<E4P~>
1654 s!%IC!7UfFrR:`GrR:]FrmTU%rR:`Gr6kWGqpYHC!7UoIrR:9:qpYNEs3p-2s3pB9s3plGrmUfG
1655 s3pB9s3plGrmUfGs3pZArR:`GrR:cH!7UlH!n.,LrmLlJe,B@He+WhBe,B=Kdf9CGe,KFHe,KCJ
1656 e,97Jdf9CIdfTU!!!)uHrW)lFp](<Cqu?`Gq>^NEqZ-QCr;ZiHq>^NEJH16$pAk4;s&Jal!-.r;
1657 !>"5_rrM'ir;Zi@JcEjl!r7%hao;FdGF=$^q#CA<jT#7(q>^J=pAYAac11f"Tm*sCrsJ:[HFiA=
1658 o?rbH_Y!m.GM`B"GQ.XBGLZZmGOb\6M?!;'"I]>f<E4P~>
1659 s!%IC!7UfFrR:`GrR:]FrmTU%rR:`Gr6kWGqpYHC!7UoIrR:9:qpYNEs3p-2s3pB9s3plGrmUfG
1660 s3pB9s3plGrmUfGs3pZArR:`GrR:cH!7UlH!n.,LrmLlJe,B@He+WhBe,B=Kdf9CGe,KFHe,KCJ
1661 e,97Jdf9CIdfTU!!!)uHrW)lFp](<Cqu?`Gq>^NEqZ-QCr;ZiHq>^NEJH16$pAk4;s&Jal!-.r;
1662 !>"5_rrM'ir;Zi@JcEjl!p"Qjao;F/GKtd>q#CA<jT#7(q>^J=pAYAnf(T(&Lj.\QrsIS8K?!EZ
1663 nAg-2g%>=EGM`B"GQ.XBGLZZmGOb\6K)bPp"H`]\<E4P~>
1664 s!!!oc2[jnhZ*Z*d/X0q^&\,\rr<&JjT,8.JH16$pAk4;s&Jal!9j?\!OhFirrM8frMfk,JcEgk
1665 !q:Dfao;G#GIiA*q#CA<jT#7(q>^J=nc&[hGBs/e"8\(*g&1jPrl')Pp&G&9hZ*V"rr<"BeGoPm
1666 nc&WKs7Y4NScJXf<Ib~>
1667 s!!!oc2[jnhZ*Z*d/X0q^&\,\rr<&JjT,8.JH16$pAk4;s&Jal!5&./!@?%brrKPHr;ZgFJcEgk
1668 !nhdbao;FDGNj\Yq#CA<jT#7(q>^J=nc&[eGC0;g"7ptmmem(erht%Rp&G&9hZ*V"rr<"BeGoPm
1669 nc&WHs7Y.LRK34b<Ib~>
1670 s!!!oc2[jnhZ*Z*d/X0q^&\,\rr<&JjT,8.JH16$pAk4;s&Jal!5&./!@?%brrKPHr;ZgFJcEgk
1671 !i1%eao;F$GP-Oeq#CA<jT#7(q>^J=nc&[TGDH.s"5/!dq>C6pqMf^Sp&G&9hZ*V"rr<"BeGoPm
1672 nc&WAs7XtGOT>5X<Ib~>
1673 s!!!oJH2nS!7QK!JH4:%s!%JCp&>'l]_e]2]?]*drnmn7f?1JtWW:q-s31KIQ/qo0P^(EprrW"h
1674 LR%o>G74D\K7C'(rNq3)U\t,ks*+JB&,NVfH&'07s*&\d\Uf.$q>UBuq7qZ/Ks1CQrs&G=OaMSF
1675 gA_-PGPV:=GP_@>GP_=@rHESdrrT0Ebkh>KriC@bs8W&1N-]l8a8c$\s8N<!^k?ueYP\>!s*"VD
1676 WdBE7rr33$_NB4oRG.Z?s*+JBs*"VDWdBE7rr33$_NB4oRG.Z?s*"kIT6^J:l'$FRj`bqErs%eR
1677 HB.'1GQ.UHrPF\EI@8gdrrJ)Yp=oeB!;fbrJ,~>
1678 s!!!oJH2nS!7QK!JH4:%s!%JCp&>'l2Z!I]1i85BUSFQOLLD>&!!&[Cs31KIWpK`CIX1A(rrVeC
1679 T9]HVG74>JItYT:qPJdnZi9t(s*+JB&+QQLH&p>Ps*&\bW-j)urr2p%nudFfMnT,hrs&A.ML'fI
1680 mJd.cGPV:=GP_@>GP_=@qKIAerr`7VGjP;,%K;3/mJm4_Y(h4NRb%N9GQ7[InudFfMnT,hs8R9G
1681 pmQJdeGfIPqmD<-J>2H1s8R<Bs8R9GpmQJdeGfIPqmD<-J>2H1s8R9No9":ts3Z^LReV)Nq>UZK
1682 MKtZcGBa&d#5bfcH@VaWqu6\Rs7Y.LRK34b<Ib~>
1683 s!!!oJH2nS!7QK!JH4:%s!%JCp&>'l2Z!I]1i85BUSFQOLLD>&!!&[Cs31KI]Cc$KH[bb4rrVG4
1684 `KgK'G7*o2I#6DRlC!$S`r5r;GQ.UQi15=DRH+>IGB`VHHA'07rr3/dTR2$Kc2IYHm\tkbKWb+L
1685 s8R<=s8R<>s8R<>rrVJ0OT,7^qgNneqYq$$IX:ehs6QP5G_2aSs8.$?rrqY[H[Cq#rVunA"QYSh
1686 PjA>K#4AIDH%`?qrr<"Brr<"B"QYShPjA>K#4AIDH%`?qrr<"B$epG]s8T`aI&d*gGPV7C^k@*8
1687 r-*Aars%njKR&6Rq"t'lK)bPp"H`]\<E4P~>
1688 s!!!oJH16$JH1B(s!%JCo`"sZXR)qf_>]#cbl7k-S:,^Fbf]qfGBoDAQ2gl.$cq$!`HSGeg&/g5
1689 RK!6dGQ7[lqi,m@q=M?"s*&\.g\em3Q2gm]K@0Vk_0;+Cs8AL6`;/tpH.W)rGB`l_s*+>>s*+A?
1690 "8'6N[/U(En99]gs7V>:GBa)enooces1EQPo)7m]s8R:erVm-"K@0Vk_0;+Bs8R9V^uY9dGfB^]
1691 SU&0Lnst'Xs8R:err<"B+2Ht4Uj0lYrLJ5Pq=:)%fDkkpGIuo)s7L\fk4l6+GP_=Pp3V8Lpo\gb
1692 s8W%gH,TOLSU&ibrrJ)Yp=oeB!;fbrJ,~>
1693 s!!!oJH16$JH1B(s!%JCo`"s7#ODEk8,e)>bl7jpPBqVEhTGj#GC#qZQ2gl.$`E1aVK^a[kPD'"
1694 _Z'T8GQ7[lp3h>?qs:?_s*&[dl1q&t]`8$+N8aa+X*:uOs8%IsebnZbHh7:;GB`l_s*+>>s*+A?
1695 "7E"2d/O%afQX"gs6>0:GBa)ehfkFes,qTCp\a'Is8R:erVm,sN8aa+X*:uNs8R9VU%.Z/Gj>>*
1696 L3qJKl%FETs8R:err<"B+//5pLj84bqM'@Ir98l]oDei7GF\0Ys6"W`o(&T#GP_=Pl?J-TnXt)M
1697 s8VqMHe&&YKR<=grrIuVp=]Y<!;fbrJ,~>
1698 s!!!oJH16$JH1B(s!%JCo`"s7#ODEk8,e)>bl7j`Mg9iJo#gt7GC?apQ2gl.$`W[hMKeE]nb%c`
1699 kl1V^GQ7[lgj4h;rSs1Cs*&[fo(.Z]jo>A9SEp.=O*BO^s6G)gj8I\[M#./OGB`l_s*+>>s*+D@
1700 "TIP@IdI(6)l@i-s8U5ib]e:2s/C4es8R[peGB$pP5kQ+GQ%OHgmm^/lAp/Irr<"B'<q8mIXCeg
1701 l[=QKrRu[UqZ$S>GQ.XBG9='ajF2ILs6G)gj8I\[M#./OGB^1`])TTkVtfDjGB`o`'#f*lpuK57
1702 GQ7^/I>?k]g3neRr;QeLs7XtGOT>5X<Ib~>
1703 s!!!oJH16$JH1B(s!%JCoD\jUY3r:j_>8`_JcD>As*"jQs8Vq>HEI5IqKI>ds8R<CrrUVmU&4li
1704 G6P2Ms8$qeqYpg"GC';hgNT1ers&+>L&_0sGQ.X8GQ7^CGQ%R@G6*'/rVmPLGI7DM_KWb=GQ7^@
1705 GC';hI!=!8s8R<<rrW1DHN*sEG6tMRs7CMfs4_afrr32pGD6(sGBa&ds*"dRs8V_8KE'\MSGrNn
1706 oQQ#hs*&[jrr35CGI%8KoQPNUrsZtmYlFapGBa)egNT1errVh:L&CrON;rV,"J,Vj<E4P~>
1707 s!!!oJH16$JH1B(s!%JCoD\j)%.4)r7Ibs/JcD>As*"k0s8V_8IGt5+oQPres8R<CrrSa8dej(E
1708 G6R"+s7:GdqYpfuGCKSlXEVnfrs%V0RK*;2GQ.X8GQ7^CGQ%R@G6*9MrVmOjGO,;/Nd'?(GQ7^=
1709 GC9GjH$A<Gs8R<<rrW+BIfBBIG7!C2s5\Bes/^Fgrr32bGFAL2GBa&ds*"e2s8V/(P5hV-bl7VI
1710 k'*6ns*&\Jrr34bGNSr*k')%GrsY'7jo>A@GBa)eXEVnfrrV>,RJd'cM?!;'"I]>f<E4P~>
1711 s!!!oJH16$JH1B(s!%JCoD\j)%.4)r7Ibs/JcD>As*"kBs8UJjJb/pAd<DMfs8R<CrrRt"mJHq`
1712 G6RU<s3>h`qYpfjGEi.-N-FUers#iSc2[ffGQ.X8GQ7^CGQ%R@G6*`orVmO^GP;(:JTnhPGQ7^+
1713 GE)Y&G^&]Ts8R<<rrV_7PlC^_G7!pAs0-^gs,;0frr320GKp0fGBa&ds*"eAs8T<IaT%3Cli-nh
1714 [!0dps*&\Zrr34TGP2"9Z?LNhrsXO(o`+rpGBa)eN-FUerrTQOc2@SBK)bPp"H`]\<E4P~>
1715 s!$b/!7U66s3pH;qpYKD!7UlHrR:WD!7UlHrmU?:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pE:
1716 !7Tj+!7UWA!7Ta(!7U66s3poHrR9j.!Rh&Gdt%LY!<48C<V$.koZ=0)WWKTardk*#s.02iG73g<
1717 s8I4dmJm4cGBj,es*+MC!g%Whqu?\?"mu?irc`VdrrUN4If=NpGlRf3GMN2t#6&gms8R:err;Y8
1718 s8W+Cqu6cdVg,`Nrs=[/li7!BGOfs%rr3:KGlRfKGBf7hmJd.cGPqIBc^'%ZG5umes8R9Lm/R+a
1719 GC':WGMN2t#6&gms8R:err<"B$1.]lrHESfR<RHcrs/OIHN4"hGO#2-#E*fms8W%AGP_=JN-FXg
1720 [email protected]#@<Trc`\drrJ)Yp=oeB!;fbrJ,~>
1721 s!$b/!7U66s3pH;qpYKD!7UlHrR:WD!7UlHrmU?:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pE:
1722 !7Tj+!7UWA!7Ta(!7U66s3poHrR9j.!Rh&Gdt%LY!<48C<V$.ki*HTX!!4=4rdk*#s.02iG74<J
1723 [email protected]?]pGBs2fs*+MC!e#:gqu?\?$iBu(rHEPes8KfpI/\<nGlRenGPD+:#5i[ns8R:err;Y8
1724 s8W+Cr;Qp!k)O`<rr3a]GP_@>I!>F2GQ7^BGBj/fMKa<<bP2#9s*+GA"9-)sI/\<iGlIaCG7"0H
1725 s8$qes*o7err33#GCBMkGBa&ds*"eHs8Vq>I/e\?p\t0tr-*Shs*&\`rr34NGPhF?qfd8\rsX:!
1726 qu?]mGBa)eIs:YdrrW+BIJj*GM?!;'"I]>f<E4P~>
1727 s!$b/!7U66s3pH;qpYKD!7UlHrR:WD!7UlHrmU?:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pE:
1728 !7Tj+!7UWA!7Ta(!7U66s3poHrR9j.!Rh&Gdt%LY!<48C<V$.ki*HTX!!4=4rdk*#s.02iG74BL
1729 s7ge^rVuomGC]\ms*+MC!d](gqu?\?$iU,*pih/ds80-[HN&*lH2mnkGPhC>#4m&!s8R:err;Y8
1730 s8W+Cr;QotgOXeBrr3a[GQ%RAH$Ah'GQ7^>GC9GjJ9Q7>e,94Fs*+GA"8fE^HN&*gH2djDG7"6J
1731 s6Flfs*Jterr32oGE2_'GBa&ds*"eJs8VD/N;n6Kqu6U#o665ps*&\crr34LGQ%RAm!![MrsX3t
1732 rVuo`GBa)eH[#AdrrVe9Nr8nXK)bPp"H`]\<E4P~>
1733 s!%.:!7UZB!7U35!7U66!7UoIs3prI!7UlH!7UlHs3prI!7U?9!7UlH#1EPPdf9Bskl:h7!!(L;
1734 !!C[M!7UZB"4I5Me*m>>df9BspAb<E!!(L;!!(L+!!(LA!!(L3!!(LB!!(L5!!(LI!!(LH!!(LC
1735 !!(L;!!:ULdt%LT!<48C<Ug"mq;KT6['6Y2WWoQ/\AZq`rdk*#s-s&gGQ%RAGQ%RAGQ.XBGQ7[E
1736 H?]>bs8R<As8R<Crta72OQufEGBa)eI!9j]G^+FVGlRefGPV:=GP_@>GP_=@qKI;cru69.r;ZeC
1737 GPu`0s8Vt?I/j6E\;5?QH+EtTGBa#c#M=6^lM^a,GQ.XBG6%R?rss<us*T$9H$FRXGBj/fGBa&d
1738 s*"J@rr3ORGlN/8H$OXZGB\<3s*&\crr3%FGQ%O@s*+>>!dT"frr<"Bs8N@PGBnIYG^"@Vr;QeV
1739 s7Y4NScJXf<Ib~>
1740 s!%.:!7UZB!7U35!7U66!7UoIs3prI!7UlH!7UlHs3prI!7U?9!7UlH#1EPPdf9Bskl:h7!!(L;
1741 !!C[M!7UZB"4I5Me*m>>df9BspAb<E!!(L;!!(L+!!(LA!!(L3!!(LB!!(L5!!(LI!!(LH!!(LC
1742 !!(L;!!:ULdt%LT!<48C<Ug#"n"jbc+;+kY!!*9<.o(Z6rdk*#s-s&gGQ%RAGQ%RAGQ.XBGQ7[D
1743 G^'#as*+GAs*+MC(9Me`nc&N3GQ7\fGBnIYG^"@Vs8R:eq>^J=qZ$S>qYpWgGCfbn)gHT+s8R=f
1744 rc`Sds7UYhs8VenJTl<aeGoPmGQ%OHX`pr<rr.+crr<"B'E8%3rc`VeG^"FYG^+FVGlRefGQ.XB
1745 G81&Vs8I4es*/a5H$FRXGBj/fGBa&crs*dmrr<#tGB`o`&pSX"s8W(BGQ7\fGBnIYG^"@Vr;QeS
1746 s7Y.LRK34b<Ib~>
1747 s!%.:!7UZB!7U35!7U66!7UoIs3prI!7UlH!7UlHs3prI!7U?9!7UlH#1EPPdf9Bskl:h7!!(L;
1748 !!C[M!7UZB"4I5Me*m>>df9BspAb<E!!(L;!!(L+!!(LA!!(L3!!(LB!!(L5!!(LI!!(LH!!(LC
1749 !!(L;!!:ULdt%LT!<48C<Ug#"n"jbc+;+kY!!*9<.o(Z6rdk*#s-s&gGQ%RAGQ%RAGQ.XBGQ7[D
1750 G^'#as*+GAs*+MC(63UXp&Fr6GQ7\fGBnIYG^"@Ws8R:eq>^J=qZ$S>qYpWDGFea5!I/hfrt]j'
1751 rHEJcs4MUos8V2RHZs[dmf3<2GQ%OHNd&J8s87(brr<"Brr3Q-GC':6GBnIYG^"@Ws8R:err<"B
1752 rr3Q-GC':6GBnIYG^"@Ws8R:erVlnCGQ.UDr-*A]rrI@grr3H*GBa)eG^"FYG^+FVH2R[CK)bPp
1753 "H`]\<E4P~>
1754 s!$b/!7U35!7U97!7UoI!n..urVurIr;ZiHrW!,N!7LoJe*R,8e,97Jdf@kq!!(L6!!(LH!!(L=
1755 !!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L;!!(L,!!(LA!!(LH!!(L-!!(L5!!(LI!!(LH
1756 !!(LC!!(L<!!C[M!7QK!L]IH!s&FXMJcC<$q>^J=rVunArVunArr<"Bs8N.^GN\l's*+GAs*+MC%
1757 #K2ps8W"@GQ7]+GNel&s*+;=s*+>>s*+;=!I&efrsjm0mJm3CGOp$&s8UbrX8Mu&m^m[hs8R:er
1758 Vm+ZGO5A0r-*Aas8R9Lm/R+aGC':PGNel&s*+JBs*"e9s8W%AHN0.PkkY8YGQ%[email protected]
1759 Ypt_GO5A0rHEJcs,qTipAY/Ps7Y4NScJXf<Ib~>
1760 s!$b/!7U35!7U97!7UoI!n..urVurIr;ZiHrW!,N!7LoJe*R,8e,97Jdf@kq!!(L6!!(LH!!(L=
1761 !!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L;!!(L,!!(LA!!(LH!!(L-!!(L5!!(LI!!(LH
1762 !!(LC!!(L<!!C[M!7QK!L]IH!s&FXMJcC<$q>^J=rVunArVunArr<"Bs8N.KGPV.9s*+GAs*+MC%
1763 "!3qs8Vk<GQ7\kGP_.8s*+;=s*+>>s*+>>!rdCgrr3IUGPhF?I!>F2GQ7]KGLHEh#N`"1IfKFlG
1764 Q%OHH[#Aes7ge^rr<"B$2ac&qfdGfI<YP`s8R<Bs8R9Lqu?]nGC9F=GP_.8s*+GA#CLams8Vt?G
1765 P_=JI!>Jfs8$q`s8RLkqY'piM?!;'"I]>f<E4P~>
1766 s!$b/!7U35!7U97!7UoI!n..urVurIr;ZiHrW!,N!7LoJe*R,8e,97Jdf@kq!!(L6!!(LH!!(L=
1767 !!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L;!!(L,!!(LA!!(LH!!(L-!!(L5!!(LI!!(LH
1768 !!(LC!!(L<!!C[M!7QK!L]IH!s&FXMJcC<$q>^J=rVunArVunArr<"Bs8N.HGPq@<s*+GAs*+MC%
1769 !d'qs8V&%GQ7\hGQ%@;s*+;=s*+>>s*+>>!rI1grr3IRGQ%RAH$Ah'GQ7]'GO>A/#l`YDGE`(,G
1770 Ba#c#C1Ols8V&%GQ.XBG7"6Js6Orgs*Anfq>^J=rr<"B$2so(m!"EgH?]>`s8R<Ars*jorVuoaG
1771 B`o`%!m-rs8VD/GQ7\hGQ%78!J:@FeHD!7qGgOG~>
1772 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8qZ$WFq#C`M!!(IJ!7LoJe*$c5
1773 df@kq!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L;!!(L9!<(CG!<(CH
1774 !!1OKrmUiHrmLlJe,B@He+WkBdfBHtr;clHr;cfFrr<)K!<1IH!<(CG!<(CE!!(LI!!:UL!<1FK
1775 !7LrIe,KFHe,9:Fe,'+Jdf9Bs!<1Gu!/ppX,6(Yos+13$s7u]pGQ%RAGQ%RAGQ.XBGQ7[EdW_G_
1776 s8R<As8R<CrsXF%nc/XVGBa)eflrt^s8R<=s8R<>s8R<>rrW"?IK'6U\p(dds1ropGB`c#H*7#D
1777 #QAplrr7@iqu6U#J9UP`s6Y#Srr<"B$*jO1oQPoeflrt^s8R<Bs8R9LZ2ajrGCokJGF\L/s*+GA
1778 #K:nns8Vb9GP_=Ja*4fgs7CMZs8UbrSG)s`N;rV,"J,Vj<E4P~>
1779 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8qZ$WFq#C`M!!(IJ!7LoJe*$c5
1780 df@kq!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L;!!(L9!<(CG!<(CH
1781 !!1OKrmUiHrmLlJe,B@He+WkBdfBHtr;clHr;cfFrr<)K!<1IH!<(CG!<(CE!!(LI!!:UL!<1FK
1782 !7LrIe,KFHe,9:Fe,'+Jdf9Bs!<1Gu!/ppX,6(Yos+13$s7u]pGQ%RAGQ%RAGQ.XBGQ7[ESp/Z\
1783 s8R<As8R<CrsX0sr;ZfEGBa)eWHZGZs8R<=s8R<>s8R<>rrV\6KDtl[Lj/:es,D6ZGB`PaHGfUZ
1784 #Q8jks8R@grr2p&H$B2ds3Z%7rr<"B$0D3ej`cjeWHZGZs8R<Bs8R9Ljo>ABGEMp)GKBU[s*+GA
1785 #EX/ns8V5*GP_=JOa#pes5\BJs8T'BaS,W7M?!;'"I]>f<E4P~>
1786 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8qZ$WFq#C`M!!(IJ!7LoJe*$c5
1787 df@kq!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L;!!(L9!<(CG!<(CH
1788 !!1OKrmUiHrmLlJe,B@He+WkBdfBHtr;clHr;cfFrr<)K!<1IH!<(CG!<(CE!!(LI!!:UL!<1FK
1789 !7LrIe,KFHe,9:Fe,'+Jdf9Bs!<1Gu!/ppX,6(Yos+13$s7u]pGQ%RAGQ%RAGQ.XBGQ7[ELNi._
1790 s8R<As8R<CrsX-rrr<"iGBa)eMg+C\s8R<=s8R<>s8R<>rrU;dWW)o,Is:\fs+,C.GB`8FJD9r#
1791 #5*1ds8R=frVm+IGQ.XBSp,DXs8R9Lo`+rrGKBfBGNel&s*+JBs*"eAs8T?JaT%0BkkY8YGQ%OH
1792 Jp6nfs0?imqYptUGP(q8Y]k<ks,2*bpAY/Fs7XtGOT>5X<Ib~>
1793 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IF!!(LE!!C[M!7UoI
1794 "Od>NdfBBrm/R7;!!(LH!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L:
1795 !!(L;!!(LH!!:ULe,97Kdf@kGrW!#K!7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH"4I8!e,B=I
1796 e,'+Hdf@kq!!(LH!!(LI!!q$Rdf9Bs!7TEr!!C[M!7UiG!7UlH!7UlH!7UoIs3prI!7QK!N<&u&
1797 s&FXM!rmIgmf3<2JcCl4s*+GAs*+GAs*+JBs*+MC$N#g.a85G@s8R:erVunAs8NkRGFA9oRs0)V
1798 s8A^;Z0_G`gSk/PGB`l_s*+>>s*+MC#EdU4rofu!\c2U;l?A3es7V;8G_)*dk5G;qNm[S!g382L
1799 s/pR[rr<#;GFA9oRs0)Us8R9V^ub?gGf0R[UNj'1rV,'Fs8R:err<"B'>W`)VKg#YrM+VBm/?\5
1800 W;lmAGQ%OHom2,Mq6P9hrr<"Bs8N`*H[b)OY]k<ks8A^;Z0_G`gSk&M!K@'Pg]X2Kqc-XH~>
1801 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IF!!(LE!!C[M!7UoI
1802 "Od>NdfBBrm/R7;!!(LH!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L:
1803 !!(L;!!(LH!!:ULe,97Kdf@kGrW!#K!7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH"4I8!e,B=I
1804 e,'+Hdf@kq!!(LH!!(LI!!q$Rdf9Bs!7TEr!!C[M!7UiG!7UlH!7UlH!7UoIs3prI!7QK!N<&u&
1805 s&FXM!rmIgmf3<2JcCl4s*+GAs*+GAs*+JBs*+MC$MJmqf_k-:s8R:erVunAs8Nk$GJ!e4Sp,DY
1806 s8.b#_t*fud[L49GB`l_s*+>>s*+MC#G^5Rr8*6Sg]%3]aEO]bs65'7H%_Tuo)8RrT%j,=aENjJ
1807 s+YaSrr34iGJ!e4Sp,DXs8R9VU@Rl3Gj58*N-W>3rq"R,s8R:err<"B';G'gM0S:bqi#g<o)A7/
1808 RfED3GQ%OHkBMpUnt^JRrr<"Bs8N_rG_u"]Tm(_\s8.b#_t*fud[L+6!K$jMg'!iEqc-XH~>
1809 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IF!!(LE!!C[M!7UoI
1810 "Od>NdfBBrm/R7;!!(LH!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L:
1811 !!(L;!!(LH!!:ULe,97Kdf@kGrW!#K!7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH"4I8!e,B=I
1812 e,'+Hdf@kq!!(LH!!(LI!!q$Rdf9Bs!7TEr!!C[M!7UiG!7UlH!7UlH!7UoIs3prI!7QK!N<&u&
1813 s&FXM!rmIgmf3<2JcCl4s*+GAs*+GAs*+JBs*+MC$J]rbjSe/)s8R:erVunAs8NjfGLZQ<_KU5(
1814 s6P8bd.dM+aG^)uGB`l_s*+>>s*+MC#I<Ojq9j_=nc&OsR!7<bs2]W4HAA-4qYgF%XlTERX*;5V
1815 s*f1Zrr34VGLZQ<_KU5's8R9VZ2!F0HhRL+J:>l>rU%[as8R:err<"B'=%>oIXCegm!sQ3p\jL#
1816 MuWg$GQ%OH_0DsTk/)=drr<"Bs8N_LGc(8t^it#&s6P8bd.dM+aG]ur!J:@FeHD!7qGgOG~>
1817 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UlH!7UiGs3prI!7UoI"Od>N
1818 e'n9r!7UE;s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7U?9
1819 !7UE;s3plGs3poH!7UlH!n..ur;ZiHnGi^@!7Lqsr;ZiHrVurIqZ$WFr;ZoJ!!)rG!!)oFr;ZiH
1820 rW!2P!7Lqsdf@kq!!C[M!7UfFs3piF!7U]C!7QK!N<&u&s&FXM!rmIgmf3<2JcCl4s*+GAs*+GA
1821 s*+JBs*+JB$2Li[G_j08s*&\cs8R<Crs/J,J9m[PGBa&d$i\D=J9Z[=df9>kGPV:=GP_@>GQ7[I
1822 lE#_bJ==j`rr`4^H//&l(@/)WG_)[Xs8VefJTuD=r3:cuRdPBDrr<"B"T53FK>.?b$i\D=J9Z[=
1823 df9>kGQ.XBG6IiBH\9'3rsShNR=KO6T[Nl?GB`ub#3_7rNoYD/rr<"Brr32fPBi2KGBa&d#QDu9
1824 J9Z[=des+GN;rV,"J,Vj<E4P~>
1825 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UlH!7UiGs3prI!7UoI"Od>N
1826 e'n9r!7UE;s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7U?9
1827 !7UE;s3plGs3poH!7UlH!n..ur;ZiHnGi^@!7Lqsr;ZiHrVurIqZ$WFr;ZoJ!!)rG!!)oFr;ZiH
1828 rW!2P!7Lqsdf@kq!!C[M!7UfFs3piF!7U]C!7QK!N<&u&s&FXM!rmIgmf3<2JcCl4s*+GAs*+GA
1829 s*+JBs*+JB$1XjBH'$DQs*&\cs8R<Crs/@oI!qmhGBa&d$iRl)I<gUIhuE_#GPV:=GP_@>GQ7[I
1830 gnK@EK;.?'rr`.HHM-q1(>Ya:G_N?us8VAOI<]u9q4`7bVYbR]rr<"B"S\:/MUMM($iRl)I<gUI
1831 huE_#GQ.XBG6IZ-H&C&LrsSe@PC7_3WSdaUGB`ub#1/3PReM#Nrr<"Brr32NMKtWaGBa&d#Q;H%
1832 I<gUIhu*KTM?!;'"I]>f<E4P~>
1833 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UlH!7UiGs3prI!7UoI"Od>N
1834 e'n9r!7UE;s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7U?9
1835 !7UE;s3plGs3poH!7UlH!n..ur;ZiHnGi^@!7Lqsr;ZiHrVurIqZ$WFr;ZoJ!!)rG!!)oFr;ZiH
1836 rW!2P!7Lqsdf@kq!!C[M!7UfFs3piF!7U]C!7QK!N<&u&s&FXM!rmIgmf3<2JcCl4s*+GAs*+GA
1837 s*+JBs*+JB$/V/!H^Wpos*&\cs8R<Crs.eSH@iX)GBa&d$hgreI!^gXm/R*0GPV:=GP_@>GQ7[I
1838 cC00,LTL%Err_b:K)>3?(=/FtH&TH8s8UN0H['c7l'?XI\,CMprr<"B"QPJePNr/I$hgreI!^gX
1839 m/R*0GQ.XBG6HrcH'@OmrsSP-NI6)3ZL%VkGB`ub#/#P7Wqgjcrr<"Brr32:K6sQpGBa&d#PPNa
1840 I!^gXm/6kaK)bPp"H`]\<E4P~>
1841 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66!7UlH!7UlH!7UiGqpPQGe,97H
1842 e+!D<e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He*[29e*[59
1843 e,04Ge,KCJe,97Jdf@kq!!(L<!!LaNdf@kq!!(LI!!(LF!!(LH!!:ULe,97Jdf@kl!!(LI!!q$R
1844 !7Lqs!7TEr!!C[M!7U`Ds3poH!7U]C!7QK!N<&u&s&FXMli7!/JcC<$Z2XpsI"1G9s8R;drrW+B
1845 HfG&+N;rV,"J,Vj<E4P~>
1846 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66!7UlH!7UlH!7UiGqpPQGe,97H
1847 e+!D<e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He*[29e*[59
1848 e,04Ge,KCJe,97Jdf@kq!!(L<!!LaNdf@kq!!(LI!!(LF!!(LH!!:ULe,97Jdf@kl!!(LI!!q$R
1849 !7Lqs!7TEr!!C[M!7U`Ds3poH!7U]C!7QK!N<&u&s&FXMli7!/JcC<$Z2Xp_H&MORs8R;drrW"?
1850 IcCA.M?!;'"I]>f<E4P~>
1851 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66!7UlH!7UlH!7UiGqpPQGe,97H
1852 e+!D<e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He*[29e*[59
1853 e,04Ge,KCJe,97Jdf@kq!!(L<!!LaNdf@kq!!(LI!!(LF!!(LH!!:ULe,97Jdf@kl!!(LI!!q$R
1854 !7Lqs!7TEr!!C[M!7U`Ds3poH!7U]C!7QK!N<&u&s&FXMli7!/JcC<$Z2Xp?Gbk;ms8R;drrV8*
1855 Q/_fEK)bPp"H`]\<E4P~>
1856 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97He,97He,B=I
1857 e+WhEdf9Bsr;ZiHnc/[=q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LH
1858 !!C[M!7U97!7UK=!7UlH!n..ur;ZoJ!7UlH!n..urW)uIr;ZiHp&G6E!7Lqsr;ZiHrVurIr;ZoJ
1859 !7UlH!n..urW)uI!<CUI!!(LH!!(LI!!(LF!!1OKrmUiH!7UoI!n..ur;ZrK!!(LG!!(LH!!(K!
1860 !0%!Y,6(Yos6K^bGCfdFs02M0n;;V.meue+Qdk$ps*)Zd!q:Dfir9%<s7Y4NScJXf<Ib~>
1861 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97He,97He,B=I
1862 e+WhEdf9Bsr;ZiHnc/[=q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LH
1863 !!C[M!7U97!7UK=!7UlH!n..ur;ZoJ!7UlH!n..urW)uIr;ZiHp&G6E!7Lqsr;ZiHrVurIr;ZoJ
1864 !7UlH!n..urW)uI!<CUI!!(LH!!(LI!!(LF!!1OKrmUiH!7UoI!n..ur;ZrK!!(LG!!(LH!!(K!
1865 !0%!Y,6(Yos6K^bGCfdFs02M0gjXn!oDS*uMsfU)s*)Zd!nhdbir9%9s7Y.LRK34b<Ib~>
1866 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97He,97He,B=I
1867 e+WhEdf9Bsr;ZiHnc/[=q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LH
1868 !!C[M!7U97!7UK=!7UlH!n..ur;ZoJ!7UlH!n..urW)uIr;ZiHp&G6E!7Lqsr;ZiHrVurIr;ZoJ
1869 !7UlH!n..urW)uI!<CUI!!(LH!!(LI!!(LF!!1OKrmUiH!7UoI!n..ur;ZrK!!(LG!!(LH!!(K!
1870 !0%!Y,6(Yos6K^bGCfdFs02M0`-RTspA=*eNqq]7s*)Zd!i1%eir9%2s7XtGOT>5X<Ib~>
1871 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,B@Fdf9CFe,01Ge,B@G
1872 e+!G8e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He*?u6e+!G:e,B@Ge,KCJe,97Jdf9CI
1873 dfBHtrW)rHpAb3BrW!#K!!)rGrrE#Hrr<&Jr;ZoJ!!*#I!s$dM!<(CG!;t=G!<(CH!!(LD!<1IH
1874 !<(CG!!(LF!<(At!/ppX,6(Z(rsP?@bl@^WJH,ZGGC0>hs*+JBs*"YG\Uf.$q>UBul]c^UjEGhI
1875 rs&>.ML'iHj8T&dS9N3Ws1X$`s8$qdq>^J=$i[\hJ$/hM["Eb$r;Q^#q7qZ/Ks1CQs8R9HrjdT-
1876 T_\Te#5Q&fH%iI!rr32ePBr8NGBa&d#5uE$I!qF:rr<"B!rAO7JcD/<#lVf3JU)g5]^Ok[s*)fh
1877 #*n9Jl]cY<ir9%<s7Y4NScJXf<Ib~>
1878 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,B@Fdf9CFe,01Ge,B@G
1879 e+!G8e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He*?u6e+!G:e,B@Ge,KCJe,97Jdf9CI
1880 dfBHtrW)rHpAb3BrW!#K!!)rGrrE#Hrr<&Jr;ZoJ!!*#I!s$dM!<(CG!;t=G!<(CH!!(LD!<1IH
1881 !<(CG!!(LF!<(At!/ppX,6(Z(rsO@$oDeiJM?!VIGC]\ms*+JBs*"YEW-j)urr2p%e;AO?pigr]
1882 rs&(oKR&6No`"juJ9UVbs,)[5s7:Gbq>^J=$iHuRKYRQ`VLX3'rr2p%nudFfMnT,hs8R9Hr2>!m
1883 YQ"P$#4epGHAfK9rr32MMKtZcGBa&d#5bfcH@VaWrr<"B!qVP!JcD/<#l;/qIX6^=`VJNns*)fh
1884 #-.%hi-ot>ir9%9s7Y.LRK34b<Ib~>
1885 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,B@Fdf9CFe,01Ge,B@G
1886 e+!G8e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He*?u6e+!G:e,B@Ge,KCJe,97Jdf9CI
1887 dfBHtrW)rHpAb3BrW!#K!!)rGrrE#Hrr<&Jr;ZoJ!!*#I!s$dM!<(CG!;t=G!<(CH!!(LD!<1IH
1888 !<(CG!!(LF!<(At!/ppX,6(Z(rsO0tqZ$SG^&S,VGF\[4s*+JBs*"Y;RX0Y(rr2p%^k@*8r-*Aa
1889 rs%JUJU33_qu6U'H[#>ds+%f_s3,\Wq>^J=$M'^7M:MXkR='b/rVm&cTR2$Kc2I\BG6RQ+HA'07
1890 rr3/dTR2$Kc2IYH]RtU3r-*Aars%njKR&6Rq#:<nG66NSG_,m_rs8%uMgKf-V9o2#s8R;hrs$+-
1891 r6]k?pu;;SK)bPp"H`]\<E4P~>
1892 s!!!oc2[jnhZ*Z*iW/l)g&M-%^An8_JH16$li@&0s&G-[$e]`ls8IIqnc.s"M#RGSGQ.XBG::Pe
1893 r5!TBs8Ve>IcU:,GBa)eqiH-Kqrs)dhuE`0GFAL1IXUbdm!"9]s8R9XaP$L1GHJ%$r5ElJs8VtK
1894 dJWaTGE`%+s*$!7g\em3Q2gm]K@0Vk_0;+Cs7L\fk4l6+GQ7^ASU&0Lnst'Xs8R:e]ArC3s+14?
1895 s8R;hrrqJRI<q"!iVrq;s7Y4NScJXf<Ib~>
1896 s!!!oc2[jnhZ*Z*iW/l)g&M-%^An8_JH16$li@&0s&G-[$_V^ks871hr;Y,fT`4ukGQ.XBG:9HT
1897 q4`)Gs8VA/M"1#.GBa)ep3qGHrS;jMp](8dGL?HgH@#Mhd!)/Ys8R9XVs!oRGM8AGqPJJRs8VhP
1898 iVi>JGI@GMs*#uml1q&t]`8$+N8aa+X*:uOs6"W`o(&T#GQ7^>L3qJKl%FETs8R:eSFG?cs+14?
1899 s8R;hrrpi7H@2.;iVrq8s7Y.LRK34b<Ib~>
1900 s!!!oc2[jnhZ*Z*iW/l)g&M-%^An8_JH16$li@&0s&G-[$]'#os7:YfrVr:0g&D$OGQ.XBG:9N_
1901 o8%VPs8U&_V>0,eGBa)ehKk4IqojAJqu?\PGO>G%I=D.pR<R?[s8R9XWU]Y=GO2'oonmtWs8UlE
1902 li$+0GMrK#s*#uoo(.Z]jo>A9SEp.=O*BO^s1rrXpu]D:GQ7^/I>?k]g3neRs8R:eXnTDXs+14?
1903 s8R;hrrp8tH%;[\iVrq1s7XtGOT>5X<Ib~>
1904 s!!!oJH2/>!7QK!JH5$:s!%JCO8fUYGD-"hI^cEYd<DDcs8R<Bs8R9WYQ+Y!GC9GjaEOlgs7:GY
1905 s8UPlUAk0(m<=Bds71Aes7LiMXT-[lV"t&jG71PQs8$qcXoJFtGC98e!rdCirr<"B"g@t+qKI>`
1906 rt56SHN4#bGI%8KoQPNZs4_afrr35qGD6(sGB^6As+138rrJ)Yp=oeB!;fbrJ,~>
1907 s!!!oJH2/>!7QK!JH5$:s!%JCO8fUFGEr3lL5+giP]u$as8R<Bs8R9WirB&MGCokpP'?$fs5S<I
1908 s8Sa9ec,R[ds%Mcs5/$cs6,2ljo:Qhhtd<PG73C0s7CM`iW&rMGD#bl!rR7krr<"B"lfR^o65f_
1909 rt50QIfKG0GNSr*k')%Ls/^Fgrr35cGFAL2GB`,!s+138rrIuVp=]Y<!;fbrJ,~>
1910 s!!!oJH2/>!7QK!JH5$:s!%JCO8fT`GLHMq\:4)MKQm"ds8R<Bs8R9WoDej9GGG3<K6Qtfs0$Wj
1911 s8Rn!mf*4tTm,#ds.jkes00"^o`'Sgo(i=cG74$Bs3Z%AoDej<GGk<;!qCK!rr<"B"nVcoc?H&[
1912 rt4dFPlLc8GP2"9Z?LNms,;0frr351GKp0fGB`\1s+138rrI`Op=0;.!;]\qJ,~>
1913 s!!!oJH16$JH1B(s!%JCO8fUcG^KJIOlVB!PBc3gs8R<Bs8R9WmJm4cGBj/[email protected]:,
1914 k5PAlr-*Jes87+gs5&n!M>rcajn\rVG73g<s8I4dmJm4cGBj,e!md0]rc\?err<"B"mu?irc`Vd
1915 rrUN4If=O%GlRf%GO5A0rHEJcs-\)drr36&GC';hGB`>'s+138rrJ)Yp=oeB!;fbrJ,~>
1916 s!!!oJH16$JH1B(s!%JCO8fU`G^f[l\@A=6IX(\fs8R<Bs8R9Wqu?]pGBs5gI!>Jfs8$q`s8ROl
1917 q>UC*q0.;fs7pngs/EN<U]5dfq>('jG7j`[email protected]?]pGBs5grkOSBrc\?err<"B$iBu(rHEPe
1918 s8KfpI/\=#GlRekGPhF?qfd8as*o7err36$GCBMkGB`n7s+138rrIuVp=]Y<!;fbrJ,~>
1919 s!!!oJH16$JH1B(s!%JCO8fULGa8;ejH/-rH?fAes8R<Bs8R9WrVuomGCBMkH?]>fs6FlQs8RCh
1920 r;Q^-j`cpgs5eKjs,5s"g])SEr;$BmG7jfRs7ge^rVuomGC]_nqm20+rc\?frr<"B$iU,*pih/d
1921 s80-[HN&+!H2mnjGQ%RAm!![Rs*Jterr35pGE2_'GBa":s+138rrI`Op=0;.!;]\qJ,~>
1922 s!!!oJH16$JH1B(s!%JCNrKEaGM8k'pNud]IJs3GGQ.XBGQ%RAGQ7[EH$B2cs8R<CrrRRlr;HWr
1923 GBj,e$)i(%Uq-5HqfdJ`s8R<As8R<As8R<Crs.2#OQufEGBa&ds*+GAs*+MC%+occlM^a,GQ7\g
1924 GQ%O@s*+MC%=EAFH$FRXGBj/fGBa":s+138rrJ)Yp=oeB!;fbrJ,~>
1925 s!!!oJH16$JH1B(s!%JCNrKE<GP6XUm==kRKDkiMGQ.XBGQ%RAGQ7[OG^'/es8I4ds8R@grr2p!
1926 rc`Yers==%p4D]!JG",=q#CA<rVunArVunAs8N>+GHUK8rc`Scs8R<As8R<CrunLgY4;MjGBa)e
1927 G^'/es8I4ds8R=fH$OXZGB\<3s*&\dJcC<$Q2^lAs7Y.LRK34b<Ib~>
1928 s!!!oJH16$JH1B(s!%JCNrKE6GPcd^\XM)nW;ZbrGQ.XBGQ%RAGQ7[DG^'/e#5i[hs8R=frVlrr
1929 GC9Di$%7$pI.t1?ep"(fs8R<As8R<As8R<Crs+R.`V'9/GBa&ds*+GAs*+MC$]]GMp&Fr6GQ7\f
1930 GQ.USr-*Abs*/a5H$FRXGBs5gGB\W<JcCu7!J:@FeHD!7qGgOG~>
1931 s!$b/!7U66s3pH;qpYKD!7UlHrR:WD!n.,LqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pT?!7TBs
1932 !7TU$!7QK!JH3:^s!%JCNrKFBGFWsRrdr"2MuE\UGQ.XBGQ%RAGQ7[[email protected]+k5PA^
1933 r-*Jdrs@P+S9ao/K#2_iq#CA<rVunArVunAs8N=\GO5A0r-*Aas8R<As8R<Crt^H8m/R+`GBa)e
1934 [email protected]+kkY8YGCfdFs-3NaN;rV,"J,Vj<E4P~>
1935 s!$b/!7U66s3pH;qpYKD!7UlHrR:WD!n.,LqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pT?!7TBs
1936 !7TU$!7QK!JH3:^s!%JCNrKEbGLUs;rHcb5WVuksGQ.XBGQ%RAGQ7[OI!>Jfs8$q`s8ROlq>UBq
1937 q0.;ers>ZKe9_)lHHp`6q#CA<rVunArVunAs8N=NGPhF?pigr]s8R<As8R<Crt]s*qu?]kGBa)e
1938 I!>Jfs8."as8RLkqYC0kGCfdFs-3NaM?!;'"I]>f<E4P~>
1939 s!$b/!7U66s3pH;qpYKD!7UlHrR:WD!n.,LqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pT?!7TBs
1940 !7TU$!7QK!JH3:^s!%JCNrKEDGL(m?pj&9OhYmKSGQ.XBGQ%RAGQ7[OH?]>fs6FlQs8RChr;Q]t
1941 k'*$grs=U-c[u/kH'rm5q#CA<rVunArVunAs8N=LGQ%RAiHKMFs8R<As8R<Crt]m(rVuoVGBa)e
1942 H?]>fs6OrRs8RChrV?KnGCfdFs-3NaK)bPp"H`]\<E4P~>
1943 s!%.:!7UZB!7U35!7U66!7UoIs3prI!7UlH!7UlHs3pfE!7UK=!7UlH#1EPPdf9Bskl:h7!!(L;
1944 !!C[M!7UZB"4I5Me*m>>df9Bsp&P-Adf9Bsf`2$$JH16$])_jTs&G*Z$1rFhJH,YdHZuRis8R<B
1945 s8R<As8R<CrsZqlZ2ajrGBa)eds%PcrrVV4M#RD\oQP\5s8Tr_GHCT>s*+GAs*+GAs*+MC#Cq$g
1946 s8VJ1GQ.XBGQ%RAGQ7[YJ9UP`s6Y#Ss8U&^ZiC'uGBa)eflrt^s8R:os+137rrJ)Yp=oeB!;fbr
1947 J,~>
1948 s!%.:!7UZB!7U35!7U66!7UoIs3prI!7UlH!7UlHs3pfE!7UK=!7UlH#1EPPdf9Bskl:h7!!(L;
1949 !!C[M!7UZB"4I5Me*m>>df9Bsp&P-Adf9Bsf`2$$JH16$])_jTs&G*Z$0HGdMuWg8JTp8Ts8R<B
1950 s8R<As8R<CrsY$6jo>AAGBa)eT6JibrrU_pT`4rtk')Q<s8S".GNS]#s*+GAs*+GAs*+MC#C1Ok
1951 s8UJjGQ.XBGQ%RAGQ7[YH$B2ds3Z%7s8S1)kl:\FGBa)eWHZGZs8R:os+137rrIuVp=]Y<!;fbr
1952 J,~>
1953 s!%.:!7UZB!7U35!7U66!7UoIs3prI!7UlH!7UlHs3pfE!7UK=!7UlH#1EPPdf9Bskl:h7!!(L;
1954 !!C[M!7UZB"4I5Me*m>>df9Bsp&P-Adf9Bsf`2$$JH16$])_jTs&G*Z$*8?#_Z0XdH[#,\s8R<B
1955 s8R<As8R<CrsXL'o`+rqGBa)eLj/:drrSp=e,K@RXET02s8RUrGP(\1s*+GAs*+GAs*+MC#C(Il
1956 s8S[7GQ.XBGQ%RAGQ7[YG^'/es.4FYs8R[pp&G&tGBa)eMg+C\s8R:os+137rrI`Op=0;.!;]\q
1957 J,~>
1958 s!$b/!7U35!7U97!7UoI!n..urVurIr;ZiHrW!#K!7UfF!7UH<!7UlH!n..ur;ZiHlMpq6r;ZiH
1959 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp](BE!7T?r!7TX%!7QK!JH3:^s!%JCNrKFaHZt_Ss6+ZO
1960 mf!1cGQ.XBGQ%RAGQ7[Up3V8Mponsds8VtUHHuHRNdBO\rsAXNGEi.-k]_:>q#CA<rVunArVunA
1961 s8N>CGFA9oRs0)Us8R<As8R<Cruf:)RJH6>GBa)eom2,Mq6P9hs8W%mGd6W6pY2YHs*&[<s+137
1962 rrJ)Yp=oeB!;fbrJ,~>
1963 s!$b/!7U35!7U97!7UoI!n..urVurIr;ZiHrW!#K!7UfF!7UH<!7UlH!n..ur;ZiHlMpq6r;ZiH
1964 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp](BE!7T?r!7TX%!7QK!JH3:^s!%JCNrKF_G^%++s20&*
1965 qu-QpGQ.XBGQ%RAGQ7[Ul$/'UnY(/Ns8Vb?IGXqZI=CnhrsARIGJsO]_fpA&q#CA<rVunArVunA
1966 s8N=jGJ!e4Sp,DXs8R<As8R<CrudYP]DUZ[GBa)ekBMpUnt^JRs8VtTH,K4Po?s*-s*&[<s+137
1967 rrIuVp=]Y<!;fbrJ,~>
1968 s!$b/!7U35!7U97!7UoI!n..urVurIr;ZiHrW!#K!7UfF!7UH<!7UlH!n..ur;ZiHlMpq6r;ZiH
1969 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp](BE!7T?r!7TX%!7QK!JH3:^s!%JCNrKFRG^&BOs-._S
1970 rVccrGQ.XBGQ%RAGQ7[U_g&'RjhQ(as8Uo$Np?PfHB.n%rsA+<GNf),P]qKQq#CA<rVunArVunA
1971 s8N=WGLZQ<_KU5's8R<As8R<Crucu=eGR_2GBa)e_0DsTk/)=ds8VG9IaIifmDt4cs*&[<s+137
1972 rrI`Op=0;.!;]\qJ,~>
1973 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8qZ$WFq#CWJ!!(IJ!7UiG!7U66
1974 !n..ur;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*AdJs9rkQ(M/rrE#Hrr<)K
1975 !<1Gu!.b-b!<48C<K7"`ZZj@fs7pkfr;Ze@rr<"BrVunArr32fPBi2KGBa&d#5Y`aH@VUGr;R#.
1976 GJsO]q0.;^s8R<As8R<As8R<Crs/J,J9m[PGBa&ds*+GAs*+MC#Q1iWHCF8GGQ.UHk`^:PjEGkJ
1977 rsShNR=KO6T[Nl?GB\W<JcCu7!K@'Pg]X2Kqc-XH~>
1978 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8qZ$WFq#CWJ!!(IJ!7UiG!7U66
1979 !n..ur;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*AdJs9rkQ(M/rrE#Hrr<)K
1980 !<1Gu!.b-b!<48C<K7"`L3N1fs7(;fr;Ze@rr<"BrVunArr32NMKtWaGBa&d#4e^FH%W*fr;R"V
1981 GOb_5nTT`^s8R<As8R<As8R<Crs/@oI!qmhGBa&ds*+GAs*+MC#Pk*AIAZmcGQ.UHd#!%:pNLl]
1982 rsSe@PC7_3WSdaUGB\W<JcCu7!K$jMg'!iEqc-XH~>
1983 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8qZ$WFq#CWJ!!(IJ!7UiG!7U66
1984 !n..ur;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*AdJs9rkQ(M/rrE#Hrr<)K
1985 !<1Gu!.b-b!<48C<K7"`IWtVfs29,fr;Ze@rr<"BrVunArr32:K6sQpGBa&d#2l)'HAT*,r;R"N
1986 GPV:=`-8Q^s8R<As8R<As8R<Crs.eSH@iX)GBa&ds*+GAs*+MC#O.P#K"(]&GQ.UH]RkL1q0.2b
1987 rsSP-NI6)3ZL%VkGB\W<JcCu7!J:@FeHD!7qGgOG~>
1988 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IF!!(LE!!C[M!7UoI
1989 !7UiG!7U97"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+NbAe'S-qe*d;7
1990 e,01Jdf9Bsr;ZrK!7TEr!!(K!!.b-c!<48C<It17rrW+BH\)3Js+UIRN;rV,"J,Vj<E4P~>
1991 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IF!!(LE!!C[M!7UoI
1992 !7UiG!7U97"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+NbAe'S-qe*d;7
1993 e,01Jdf9Bsr;ZrK!7TEr!!(K!!.b-c!<48C<It17rrW"?IY%NMs+UIRM?!;'"I]>f<E4P~>
1994 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IF!!(LE!!C[M!7UoI
1995 !7UiG!7U97"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+NbAe'S-qe*d;7
1996 e,01Jdf9Bsr;ZrK!7TEr!!(K!!.b-c!<48C<It17rrV8*Q%Asds+UIRK)bPp"H`]\<E4P~>
1997 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UlH!7UiGs3prI!7UoI!7UlH
1998 !7U<8s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7T9p!7U*2!7UlH
1999 s3poH!7UlH!7QK!JH3Ics!%JCJcCu7!q:DfJcC<$L&V14s7Y4NScJXf<Ib~>
2000 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UlH!7UiGs3prI!7UoI!7UlH
2001 !7U<8s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7T9p!7U*2!7UlH
2002 s3poH!7UlH!7QK!JH3Ics!%JCJcCu7!nhdbJcC<$L&V11s7Y.LRK34b<Ib~>
2003 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UlH!7UiGs3prI!7UoI!7UlH
2004 !7U<8s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7T9p!7U*2!7UlH
2005 s3poH!7UlH!7QK!JH3Ics!%JCJcCu7!i1%eJcC<$L&V1*s7XtGOT>5X<Ib~>
2006 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66!7UlH!7UlH!7UiGqpYNE!7U?9
2007 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7T9p!7U-3!7UcEs3puJ
2008 !7UlH!7QK!JH3Ics!%JCJcD,;#*n9Jl]cY<JcC<$L&V14s7Y4NScJXf<Ib~>
2009 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66!7UlH!7UlH!7UiGqpYNE!7U?9
2010 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7T9p!7U-3!7UcEs3puJ
2011 !7UlH!7QK!JH3Ics!%JCJcD,;#-.%hi-ot>JcC<$L&V11s7Y.LRK34b<Ib~>
2012 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66!7UlH!7UlH!7UiGqpYNE!7U?9
2013 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7T9p!7U-3!7UcEs3puJ
2014 !7UlH!7QK!JH3Ics!%JCJcD,;#.sO*d<g?;JcC<$L&V1*s7XtGOT>5X<Ib~>
2015 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97He,97He,B=I
2016 e+WhBe,B=Ie*[29e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`GqZ$WF
2017 cN!sol2Uh5qu?`Gr;ZoJ!7UlH!7QK!JH3Ics!%JCJcD,;"lu2%HB?@%s+13'rrJ)Yp=oeB!;fbr
2018 J,~>
2019 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97He,97He,B=I
2020 e+WhBe,B=Ie*[29e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`GqZ$WF
2021 cN!sol2Uh5qu?`Gr;ZoJ!7UlH!7QK!JH3Ics!%JCJcD,;"k&T\I$riBs+13'rrIuVp=]Y<!;fbr
2022 J,~>
2023 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97He,97He,B=I
2024 e+WhBe,B=Ie*[29e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`GqZ$WF
2025 cN!sol2Uh5qu?`Gr;ZoJ!7UlH!7QK!JH3Ics!%JCJcD,;"i?1CJ>;[ds+13'rrI`Op=0;.!;]\q
2026 J,~>
2027 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,B@Fdf9CFe,01Ge,B=I
2028 e*[55e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,B@Fe'S-qe*@#2e,KFHe,KCJe,97Hdt%LM
2029 !5JU7,6(Yos+13$s+138rrJ)Yp=oeB!;fbrJ,~>
2030 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,B@Fdf9CFe,01Ge,B=I
2031 e*[55e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,B@Fe'S-qe*@#2e,KFHe,KCJe,97Hdt%LM
2032 !5JU7,6(Yos+13$s+138rrIuVp=]Y<!;fbrJ,~>
2033 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,B@Fdf9CFe,01Ge,B=I
2034 e*[55e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,B@Fe'S-qe*@#2e,KFHe,KCJe,97Hdt%LM
2035 !5JU7,6(Yos+13$s+138rrI`Op=0;.!;]\qJ,~>
2036 s!!!oc2[jnhZ*Z*`W5nbJH16$SH/[6s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
2037 s!!!oc2[jnhZ*Z*`W5nbJH16$SH/[6s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
2038 s!!!oc2[jnhZ*Z*`W5nbJH16$SH/[6s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
2039 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2040 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2041 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2042 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2043 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2044 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2045 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2046 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2047 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2048 s!#8ZqpYQFrR:]FrmUlIqpYKD!7UB:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pZArR:?<!7U'1!n..u
2049 kPtV3pAk6Bh#IH(JH16$g]7?us&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
2050 s!#8ZqpYQFrR:]FrmUlIqpYKD!7UB:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pZArR:?<!7U'1!n..u
2051 kPtV3pAk6Bh#IH(JH16$g]7?us&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
2052 s!#8ZqpYQFrR:]FrmUlIqpYKD!7UB:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pZArR:?<!7U'1!n..u
2053 kPtV3pAk6Bh#IH(JH16$g]7?us&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
2054 s!$_.!7TEt!n..ur;ZrK!!(LB!!(LI!<:O;!!(LH!!^mP!7LoJe*-i7df9Bsn,NR>!!(LB!!C[M
2055 !7UE;"4I5Me+`nCe,97He+<V?e)gW3df@kl!!(L=!!(LA!!(LF!!(L/!!(K!!.b.*!<48C<It1$
2056 s+13$s-<TbN;rV,"J,Vj<E4P~>
2057 s!$_.!7TEt!n..ur;ZrK!!(LB!!(LI!<:O;!!(LH!!^mP!7LoJe*-i7df9Bsn,NR>!!(LB!!C[M
2058 !7UE;"4I5Me+`nCe,97He+<V?e)gW3df@kl!!(L=!!(LA!!(LF!!(L/!!(K!!.b.*!<48C<It1$
2059 s+13$s-<TbM?!;'"I]>f<E4P~>
2060 s!$_.!7TEt!n..ur;ZrK!!(LB!!(LI!<:O;!!(LH!!^mP!7LoJe*-i7df9Bsn,NR>!!(LB!!C[M
2061 !7UE;"4I5Me+`nCe,97He+<V?e)gW3df@kl!!(L=!!(LA!!(LF!!(L/!!(K!!.b.*!<48C<It1$
2062 s+13$s-<TbK)bPp"H`]\<E4P~>
2063 s!$_.!7THu"4I5Me,97Jdf@kk!!(LI!!:ULe*m>;e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH!!(LD
2064 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L@!!(L1!!C[M!7U04!7UT@!7Ta(!7QK!JH4I*s!%JCJcC<$
2065 JcC<$Q2^lDs7Y4NScJXf<Ib~>
2066 s!$_.!7THu"4I5Me,97Jdf@kk!!(LI!!:ULe*m>;e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH!!(LD
2067 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L@!!(L1!!C[M!7U04!7UT@!7Ta(!7QK!JH4I*s!%JCJcC<$
2068 JcC<$Q2^lAs7Y.LRK34b<Ib~>
2069 s!$_.!7THu"4I5Me,97Jdf@kk!!(LI!!:ULe*m>;e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH!!(LD
2070 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L@!!(L1!!C[M!7U04!7UT@!7Ta(!7QK!JH4I*s!%JCJcC<$
2071 JcC<$Q2^l:s7XtGOT>5X<Ib~>
2072 ruqLEdfBBrrW)oGrW)oGrrE#HfDkp#q#CKF!7U]C!7UfF!7U66!n..ur;ZiHlMpq6r;ZiHnc/[=
2073 r;ZiHq#CEDr;ZiHnc/[=r;ZiHoDem?o`,*C!!(LH!!:UL!<(CH!!1OKrmU`E"Od>NdfBBrr;clH
2074 rVuuJ!<1IE!!(LI!<(CE!!(LG!<:OH!<:LK!7UE;rmLlJdt%LM!8ISS,6(Yos+13$s+138rrJ)Y
2075 p=oeB!;fbrJ,~>
2076 ruqLEdfBBrrW)oGrW)oGrrE#HfDkp#q#CKF!7U]C!7UfF!7U66!n..ur;ZiHlMpq6r;ZiHnc/[=
2077 r;ZiHq#CEDr;ZiHnc/[=r;ZiHoDem?o`,*C!!(LH!!:UL!<(CH!!1OKrmU`E"Od>NdfBBrr;clH
2078 rVuuJ!<1IE!!(LI!<(CE!!(LG!<:OH!<:LK!7UE;rmLlJdt%LM!8ISS,6(Yos+13$s+138rrIuV
2079 p=]Y<!;fbrJ,~>
2080 ruqLEdfBBrrW)oGrW)oGrrE#HfDkp#q#CKF!7U]C!7UfF!7U66!n..ur;ZiHlMpq6r;ZiHnc/[=
2081 r;ZiHq#CEDr;ZiHnc/[=r;ZiHoDem?o`,*C!!(LH!!:UL!<(CH!!1OKrmU`E"Od>NdfBBrr;clH
2082 rVuuJ!<1IE!!(LI!<(CE!!(LG!<:OH!<:LK!7UE;rmLlJdt%LM!8ISS,6(Yos+13$s+138rrI`O
2083 p=0;.!;]\qJ,~>
2084 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me(4U!e,'+Jdf9Bs!<1IG!<1IF!!(L7!!C[M!7UlH!7U66
2085 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UT@!7UT@!7UoI!7UlH!n..ur;ZrK!!(LI!!(LH
2086 !!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LH!!(LH!!(LF!!(LH!!LaNdf@kl!;t:H!7UoI
2087 s3lN!JH4I*s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2088 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me(4U!e,'+Jdf9Bs!<1IG!<1IF!!(L7!!C[M!7UlH!7U66
2089 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UT@!7UT@!7UoI!7UlH!n..ur;ZrK!!(LI!!(LH
2090 !!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LH!!(LH!!(LF!!(LH!!LaNdf@kl!;t:H!7UoI
2091 s3lN!JH4I*s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2092 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me(4U!e,'+Jdf9Bs!<1IG!<1IF!!(L7!!C[M!7UlH!7U66
2093 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UT@!7UT@!7UoI!7UlH!n..ur;ZrK!!(LI!!(LH
2094 !!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LH!!(LH!!(LF!!(LH!!LaNdf@kl!;t:H!7UoI
2095 s3lN!JH4I*s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2096 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!(LI!<:OI!<:OI!!(LF!!(LH!!(L9!<:OI!!(LH!!(L6
2097 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LB!<:O@!!(LH!!(LH!!LaN!7TEp!!(LE!!(LH
2098 !!(LH!!(LH!!(LI!!(LH!!(LI!!(LG!<:OE!!(LF!!(LH!!LaNdf@kf!!(LH!!(K!!.b.*!<48C
2099 <It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
2100 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!(LI!<:OI!<:OI!!(LF!!(LH!!(L9!<:OI!!(LH!!(L6
2101 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LB!<:O@!!(LH!!(LH!!LaN!7TEp!!(LE!!(LH
2102 !!(LH!!(LH!!(LI!!(LH!!(LI!!(LG!<:OE!!(LF!!(LH!!LaNdf@kf!!(LH!!(K!!.b.*!<48C
2103 <It1$s+13$s-<TbM?!;'"I]>f<E4P~>
2104 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!(LI!<:OI!<:OI!!(LF!!(LH!!(L9!<:OI!!(LH!!(L6
2105 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LB!<:O@!!(LH!!(LH!!LaN!7TEp!!(LE!!(LH
2106 !!(LH!!(LH!!(LI!!(LH!!(LI!!(LG!<:OE!!(LF!!(LH!!LaNdf@kf!!(LH!!(K!!.b.*!<48C
2107 <It1$s+13$s-<TbK)bPp"H`]\<E4P~>
2108 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!C[M!7UiG!7UlH!7UfF!7UlH!7UB:!7UiG!7UlH!7U66
2109 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U]C!7UN>!7UlH!7UlH!7UlHs3prI!7UcE!7UlH
2110 !7UlH!7UlH!7UoI!7UlH!7UoI!7UcEs3plG!7UfF!7UlH"OdA"!7UK=!7UlH!7QK!JH4I*s!%JC
2111 JcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2112 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!C[M!7UiG!7UlH!7UfF!7UlH!7UB:!7UiG!7UlH!7U66
2113 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U]C!7UN>!7UlH!7UlH!7UlHs3prI!7UcE!7UlH
2114 !7UlH!7UlH!7UoI!7UlH!7UoI!7UcEs3plG!7UfF!7UlH"OdA"!7UK=!7UlH!7QK!JH4I*s!%JC
2115 JcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2116 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!C[M!7UiG!7UlH!7UfF!7UlH!7UB:!7UiG!7UlH!7U66
2117 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U]C!7UN>!7UlH!7UlH!7UlHs3prI!7UcE!7UlH
2118 !7UlH!7UlH!7UoI!7UlH!7UoI!7UcEs3plG!7UfF!7UlH"OdA"!7UK=!7UlH!7QK!JH4I*s!%JC
2119 JcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2120 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LH!!:ULe,'+Fe,97Jdf@kq!!(LH!!(L;!!(LE
2121 !!C[M!7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UoI!7UN>!7UiG!7UoIs3guK
2122 e,97Kdf9BsqZ$WFquHcGrVurIr;ZiHrVurIr;ZrK!!(LG!!(LH!!(LH!!(LF!!(LH!!LaNdf@kf
2123 !!(LI!<:N!!.b.*!<48C<It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
2124 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LH!!:ULe,'+Fe,97Jdf@kq!!(LH!!(L;!!(LE
2125 !!C[M!7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UoI!7UN>!7UiG!7UoIs3guK
2126 e,97Kdf9BsqZ$WFquHcGrVurIr;ZiHrVurIr;ZrK!!(LG!!(LH!!(LH!!(LF!!(LH!!LaNdf@kf
2127 !!(LI!<:N!!.b.*!<48C<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
2128 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LH!!:ULe,'+Fe,97Jdf@kq!!(LH!!(L;!!(LE
2129 !!C[M!7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UoI!7UN>!7UiG!7UoIs3guK
2130 e,97Kdf9BsqZ$WFquHcGrVurIr;ZiHrVurIr;ZrK!!(LG!!(LH!!(LH!!(LF!!(LH!!LaNdf@kf
2131 !!(LI!<:N!!.b.*!<48C<It1$s+13$s-<TbK)bPp"H`]\<E4P~>
2132 s!%IC!7UfFrR:`GrR:]FrmTU%rR:cHqpYQFrR:`GrR:`Gr6t3:qpYNEs3p-2s3pB9s3plGrmUfG
2133 s3pB9s3plGrmUlIqpY<?!7UfFrmLrLdf9CHe,B=Ie,'+Fe,01HdfBBrrW)lF!<CUI!!C[M!7UfF
2134 rR:`Gr6tZGr6tZG!7UoI!7UH<rmLlJdt%LM!8ISS,6(Yos+13$s+138rrJ)Yp=oeB!;fbrJ,~>
2135 s!%IC!7UfFrR:`GrR:]FrmTU%rR:cHqpYQFrR:`GrR:`Gr6t3:qpYNEs3p-2s3pB9s3plGrmUfG
2136 s3pB9s3plGrmUlIqpY<?!7UfFrmLrLdf9CHe,B=Ie,'+Fe,01HdfBBrrW)lF!<CUI!!C[M!7UfF
2137 rR:`Gr6tZGr6tZG!7UoI!7UH<rmLlJdt%LM!8ISS,6(Yos+13$s+138rrIuVp=]Y<!;fbrJ,~>
2138 s!%IC!7UfFrR:`GrR:]FrmTU%rR:cHqpYQFrR:`GrR:`Gr6t3:qpYNEs3p-2s3pB9s3plGrmUfG
2139 s3pB9s3plGrmUlIqpY<?!7UfFrmLrLdf9CHe,B=Ie,'+Fe,01HdfBBrrW)lF!<CUI!!C[M!7UfF
2140 rR:`Gr6tZGr6tZG!7UoI!7UH<rmLlJdt%LM!8ISS,6(Yos+13$s+138rrI`Op=0;.!;]\qJ,~>
2141 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2142 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2143 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2144 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2145 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2146 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2147 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2148 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2149 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2150 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2151 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2152 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2153 s!#8ZqpYQFrR:]FrmUlIqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3p]BqpY'8!7U04!7U'1
2154 !n..ur;ZiHr;ZiHqZ$WFrW)lFr;ciGq>^TG!7U-3!n..ur;ZiHiW0#-S,`Q<mf3@:jo>D1jo>D1
2155 pAk6Bec>^os&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
2156 s!#8ZqpYQFrR:]FrmUlIqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3p]BqpY'8!7U04!7U'1
2157 !n..ur;ZiHr;ZiHqZ$WFrW)lFr;ciGq>^TG!7U-3!n..ur;ZiHiW0#-S,`Q<mf3@:jo>D1jo>D1
2158 pAk6Bec>^os&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
2159 s!#8ZqpYQFrR:]FrmUlIqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3p]BqpY'8!7U04!7U'1
2160 !n..ur;ZiHr;ZiHqZ$WFrW)lFr;ciGq>^TG!7U-3!n..ur;ZiHiW0#-S,`Q<mf3@:jo>D1jo>D1
2161 pAk6Bec>^os&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
2162 s!$_.!7TEt!n..ur;ZrK!!(LB!!(LF!!(L=!!(LH!!^mP!7LoJe*-i7df9Bsn,NR>!!(LB!!C[M
2163 !7UE;"4I5Me+`nCe*I&7e*-i4e)gW3df@kq!!(LI!<:OG!<:OI!!(LH!!C[M!7UZB!n..up](<C
2164 nc/a?!7UlH!7Tm,!7UfF!7UWA!7U'1!7T<q!7UiG!7UB:!7U'1!7U'1!7UWA!7UfF!7Ta(s!%JC
2165 JcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2166 s!$_.!7TEt!n..ur;ZrK!!(LB!!(LF!!(L=!!(LH!!^mP!7LoJe*-i7df9Bsn,NR>!!(LB!!C[M
2167 !7UE;"4I5Me+`nCe*I&7e*-i4e)gW3df@kq!!(LI!<:OG!<:OI!!(LH!!C[M!7UZB!n..up](<C
2168 nc/a?!7UlH!7Tm,!7UfF!7UWA!7U'1!7T<q!7UiG!7UB:!7U'1!7U'1!7UWA!7UfF!7Ta(s!%JC
2169 JcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2170 s!$_.!7TEt!n..ur;ZrK!!(LB!!(LF!!(L=!!(LH!!^mP!7LoJe*-i7df9Bsn,NR>!!(LB!!C[M
2171 !7UE;"4I5Me+`nCe*I&7e*-i4e)gW3df@kq!!(LI!<:OG!<:OI!!(LH!!C[M!7UZB!n..up](<C
2172 nc/a?!7UlH!7Tm,!7UfF!7UWA!7U'1!7T<q!7UiG!7UB:!7U'1!7U'1!7UWA!7UfF!7Ta(s!%JC
2173 JcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2174 s!$_.!7THu"4I5Me,97Jdf@kk!!(LF!!(L<!!(LH!!:ULe,97He*?u6e,97He+*J=e,97He+itD
2175 e,97He+*J=e,97He+itDe*?u6e*?u6e)gW1e,B=Ldf9BsrW!#K!7UlH!n..urVurIr;ZoJ!7UZB
2176 "4I5Me*-i4e,B=Ldf9BshuEc+mf3@:jo>D1d/X0qqu?`Gn,NI;jo>D1jo>D1o`,!@ec>^os&FXM
2177 JcC<$JcD#8!K@'Pg]X2Kqc-XH~>
2178 s!$_.!7THu"4I5Me,97Jdf@kk!!(LF!!(L<!!(LH!!:ULe,97He*?u6e,97He+*J=e,97He+itD
2179 e,97He+*J=e,97He+itDe*?u6e*?u6e)gW1e,B=Ldf9BsrW!#K!7UlH!n..urVurIr;ZoJ!7UZB
2180 "4I5Me*-i4e,B=Ldf9BshuEc+mf3@:jo>D1d/X0qqu?`Gn,NI;jo>D1jo>D1o`,!@ec>^os&FXM
2181 JcC<$JcD#8!K$jMg'!iEqc-XH~>
2182 s!$_.!7THu"4I5Me,97Jdf@kk!!(LF!!(L<!!(LH!!:ULe,97He*?u6e,97He+*J=e,97He+itD
2183 e,97He+*J=e,97He+itDe*?u6e*?u6e)gW1e,B=Ldf9BsrW!#K!7UlH!n..urVurIr;ZoJ!7UZB
2184 "4I5Me*-i4e,B=Ldf9BshuEc+mf3@:jo>D1d/X0qqu?`Gn,NI;jo>D1jo>D1o`,!@ec>^os&FXM
2185 JcC<$JcD#8!J:@FeHD!7qGgOG~>
2186 ruqLEdfBBrrW)oGrW)oGrrE#HfDkp#q#CKF!7U]C!7UfF!7U66!n..ur;ZiHlMpq6r;ZiHnc/[=
2187 r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CHE!<1I9!!(L6!!C[M!7UlH!n.,LrR:cH!Rh&Je,'+Fe,B=L
2188 df9Bsqu?`GqZ$WFrVurIr;ZoJ!7UZB"Od>NdfBBrr;clHrVuuJ!<1IE!!(LI!!C[M!7UH<!Rh&J
2189 e,B@Ge,01Ge,04Ge,9:Fe,KFHe,9:Fe,KCKdfBBrp]19Ar;cfFrr<)K!<1I:!<(CH!!(LH!!1OK
2190 rR:`G!Rh&Je+<V?e,B=Ie,B=Kdf9CHe,KCKdfBBrqZ$cJ!!(IJrmUlI!7UlH"4I8!!<1IE!!(LI
2191 !<(CE!!(LG!<:OH!<:LK!7UZBrR:cH!7UlH!7UfFs!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2192 ruqLEdfBBrrW)oGrW)oGrrE#HfDkp#q#CKF!7U]C!7UfF!7U66!n..ur;ZiHlMpq6r;ZiHnc/[=
2193 r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CHE!<1I9!!(L6!!C[M!7UlH!n.,LrR:cH!Rh&Je,'+Fe,B=L
2194 df9Bsqu?`GqZ$WFrVurIr;ZoJ!7UZB"Od>NdfBBrr;clHrVuuJ!<1IE!!(LI!!C[M!7UH<!Rh&J
2195 e,B@Ge,01Ge,04Ge,9:Fe,KFHe,9:Fe,KCKdfBBrp]19Ar;cfFrr<)K!<1I:!<(CH!!(LH!!1OK
2196 rR:`G!Rh&Je+<V?e,B=Ie,B=Kdf9CHe,KCKdfBBrqZ$cJ!!(IJrmUlI!7UlH"4I8!!<1IE!!(LI
2197 !<(CE!!(LG!<:OH!<:LK!7UZBrR:cH!7UlH!7UfFs!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2198 ruqLEdfBBrrW)oGrW)oGrrE#HfDkp#q#CKF!7U]C!7UfF!7U66!n..ur;ZiHlMpq6r;ZiHnc/[=
2199 r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CHE!<1I9!!(L6!!C[M!7UlH!n.,LrR:cH!Rh&Je,'+Fe,B=L
2200 df9Bsqu?`GqZ$WFrVurIr;ZoJ!7UZB"Od>NdfBBrr;clHrVuuJ!<1IE!!(LI!!C[M!7UH<!Rh&J
2201 e,B@Ge,01Ge,04Ge,9:Fe,KFHe,9:Fe,KCKdfBBrp]19Ar;cfFrr<)K!<1I:!<(CH!!(LH!!1OK
2202 rR:`G!Rh&Je+<V?e,B=Ie,B=Kdf9CHe,KCKdfBBrqZ$cJ!!(IJrmUlI!7UlH"4I8!!<1IE!!(LI
2203 !<(CE!!(LG!<:OH!<:LK!7UZBrR:cH!7UlH!7UfFs!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2204 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me(4U!e,'+Jdf9Bs!<1IG!<1IG!<1I7!!C[M!7UlH!7U66
2205 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`Ds3prI!7UB:!7U<8!7UoI!7UlH!n..ur;ZrK
2206 !!(LI!!(LH!!(LG!<:OF!!(LF!!(LI!;t=G!!1OKrmUcF!7UoIs3prI!7UlH!7UoIs3prI!7UlH
2207 !7UiGs3pZAr6k]Ie'n9r!n..ur;ZiHr;ZiHqZ$WFrVurIr;ZrK!!(LG!!(LH!!C[Me'n9r!7U]C
2208 !7UiG!7UlH"4I8!e,B=Ie+`q@e,'+Hdf@kq!!C[M!7UiGs3prI!7UWA!7UlH!7UoI!7UfF"4I5M
2209 e,B=Ie,97He,97He,B=Kdf@kq!!C[Me'n9r!7UlH!7UoI!7UlH!7UlH!7UfF!7UlH"OdA"!7UQ?
2210 !n..ur;ZiHqZ-X?s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
2211 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me(4U!e,'+Jdf9Bs!<1IG!<1IG!<1I7!!C[M!7UlH!7U66
2212 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`Ds3prI!7UB:!7U<8!7UoI!7UlH!n..ur;ZrK
2213 !!(LI!!(LH!!(LG!<:OF!!(LF!!(LI!;t=G!!1OKrmUcF!7UoIs3prI!7UlH!7UoIs3prI!7UlH
2214 !7UiGs3pZAr6k]Ie'n9r!n..ur;ZiHr;ZiHqZ$WFrVurIr;ZrK!!(LG!!(LH!!C[Me'n9r!7U]C
2215 !7UiG!7UlH"4I8!e,B=Ie+`q@e,'+Hdf@kq!!C[M!7UiGs3prI!7UWA!7UlH!7UoI!7UfF"4I5M
2216 e,B=Ie,97He,97He,B=Kdf@kq!!C[Me'n9r!7UlH!7UoI!7UlH!7UlH!7UfF!7UlH"OdA"!7UQ?
2217 !n..ur;ZiHqZ-X?s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
2218 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me(4U!e,'+Jdf9Bs!<1IG!<1IG!<1I7!!C[M!7UlH!7U66
2219 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`Ds3prI!7UB:!7U<8!7UoI!7UlH!n..ur;ZrK
2220 !!(LI!!(LH!!(LG!<:OF!!(LF!!(LI!;t=G!!1OKrmUcF!7UoIs3prI!7UlH!7UoIs3prI!7UlH
2221 !7UiGs3pZAr6k]Ie'n9r!n..ur;ZiHr;ZiHqZ$WFrVurIr;ZrK!!(LG!!(LH!!C[Me'n9r!7U]C
2222 !7UiG!7UlH"4I8!e,B=Ie+`q@e,'+Hdf@kq!!C[M!7UiGs3prI!7UWA!7UlH!7UoI!7UfF"4I5M
2223 e,B=Ie,97He,97He,B=Kdf@kq!!C[Me'n9r!7UlH!7UoI!7UlH!7UlH!7UfF!7UlH"OdA"!7UQ?
2224 !n..ur;ZiHqZ-X?s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
2225 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!(LI!<:OI!<:OI!!(LF!!(LF!!(L;!<:OI!!(LH!!(L6
2226 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(L?!!(L9!!(L:!!(LH!!(LH!!LaN!7TEp!!(LE
2227 !!(LG!!C[M!7UiG!7UfF!7UoI!n..ur;clHrVurIrVurIr;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurI
2228 qu?iJ!!(L<!!(LH!!:ULe,97He,97He,'+Fe,9:He,01Ge,04CdfBHtr;ZiHp](<Cqu?`GqZ$WF
2229 r;ZiHnGrL9!<CUI!!C[M!7UiG!7UlH!7UZB!7UiG!7UoI!n.,Lr6tZG!7UcE!7UiG!7UiG!7UlH
2230 !n..ur;ZiHrVurIquHcGq>^NEqZ$WFr;ZuL!7Lqsp]16@!<CUI!!(LF!<48C<It1$s+13$s-<Tb
2231 N;rV,"J,Vj<E4P~>
2232 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!(LI!<:OI!<:OI!!(LF!!(LF!!(L;!<:OI!!(LH!!(L6
2233 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(L?!!(L9!!(L:!!(LH!!(LH!!LaN!7TEp!!(LE
2234 !!(LG!!C[M!7UiG!7UfF!7UoI!n..ur;clHrVurIrVurIr;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurI
2235 qu?iJ!!(L<!!(LH!!:ULe,97He,97He,'+Fe,9:He,01Ge,04CdfBHtr;ZiHp](<Cqu?`GqZ$WF
2236 r;ZiHnGrL9!<CUI!!C[M!7UiG!7UlH!7UZB!7UiG!7UoI!n.,Lr6tZG!7UcE!7UiG!7UiG!7UlH
2237 !n..ur;ZiHrVurIquHcGq>^NEqZ$WFr;ZuL!7Lqsp]16@!<CUI!!(LF!<48C<It1$s+13$s-<Tb
2238 M?!;'"I]>f<E4P~>
2239 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!(LI!<:OI!<:OI!!(LF!!(LF!!(L;!<:OI!!(LH!!(L6
2240 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(L?!!(L9!!(L:!!(LH!!(LH!!LaN!7TEp!!(LE
2241 !!(LG!!C[M!7UiG!7UfF!7UoI!n..ur;clHrVurIrVurIr;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurI
2242 qu?iJ!!(L<!!(LH!!:ULe,97He,97He,'+Fe,9:He,01Ge,04CdfBHtr;ZiHp](<Cqu?`GqZ$WF
2243 r;ZiHnGrL9!<CUI!!C[M!7UiG!7UlH!7UZB!7UiG!7UoI!n.,Lr6tZG!7UcE!7UiG!7UiG!7UlH
2244 !n..ur;ZiHrVurIquHcGq>^NEqZ$WFr;ZuL!7Lqsp]16@!<CUI!!(LF!<48C<It1$s+13$s-<Tb
2245 K)bPp"H`]\<E4P~>
2246 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!C[M!7UiG!7UlH!7UfF!7UfF!7UH<!7UiG!7UlH!7U66
2247 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UQ?!7U?9!7UB:!7UlH!7UlH!7UlHs3prI!7UcE
2248 !7UiG"4I5Me,01Ge,'+Fe,B=Ldf9BsrVurIr;ZiHrVurIr;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurI
2249 qu?iJ!!(L<!!(LH!!:ULe,97He,97He,'+Fe,'.Fe,B=Ie,01Ge,'+Fe,97He+`nCe,01Ge,'.F
2250 e,B=Ie+*J=e,97Jdf@kq!!C[M!7UiG!7UlH!7UZB!7UfF"k*J#!!(LH!!C[M!7UcE!7UiG!7UiG
2251 !7UlH!n..ur;ZiHrVurIq>gQEqu?`GqZ$WFr;ZuL!7Lqsq#CEDr;ZoJ!7UlH!7UfFs!%JCJcC<$
2252 JcC<$Q2^lDs7Y4NScJXf<Ib~>
2253 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!C[M!7UiG!7UlH!7UfF!7UfF!7UH<!7UiG!7UlH!7U66
2254 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UQ?!7U?9!7UB:!7UlH!7UlH!7UlHs3prI!7UcE
2255 !7UiG"4I5Me,01Ge,'+Fe,B=Ldf9BsrVurIr;ZiHrVurIr;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurI
2256 qu?iJ!!(L<!!(LH!!:ULe,97He,97He,'+Fe,'.Fe,B=Ie,01Ge,'+Fe,97He+`nCe,01Ge,'.F
2257 e,B=Ie+*J=e,97Jdf@kq!!C[M!7UiG!7UlH!7UZB!7UfF"k*J#!!(LH!!C[M!7UcE!7UiG!7UiG
2258 !7UlH!n..ur;ZiHrVurIq>gQEqu?`GqZ$WFr;ZuL!7Lqsq#CEDr;ZoJ!7UlH!7UfFs!%JCJcC<$
2259 JcC<$Q2^lAs7Y.LRK34b<Ib~>
2260 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kt!!C[M!7UiG!7UlH!7UfF!7UfF!7UH<!7UiG!7UlH!7U66
2261 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UQ?!7U?9!7UB:!7UlH!7UlH!7UlHs3prI!7UcE
2262 !7UiG"4I5Me,01Ge,'+Fe,B=Ldf9BsrVurIr;ZiHrVurIr;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurI
2263 qu?iJ!!(L<!!(LH!!:ULe,97He,97He,'+Fe,'.Fe,B=Ie,01Ge,'+Fe,97He+`nCe,01Ge,'.F
2264 e,B=Ie+*J=e,97Jdf@kq!!C[M!7UiG!7UlH!7UZB!7UfF"k*J#!!(LH!!C[M!7UcE!7UiG!7UiG
2265 !7UlH!n..ur;ZiHrVurIq>gQEqu?`GqZ$WFr;ZuL!7Lqsq#CEDr;ZoJ!7UlH!7UfFs!%JCJcC<$
2266 JcC<$Q2^l:s7XtGOT>5X<Ib~>
2267 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LH!!:ULe,'+Fe,97Jdf@kq!!:ULe,97He+*J=
2268 e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`GrVurIr;ZiHm/R.8nGiR<
2269 qu?`GrW)uI!<CUI!!C[M!7UfF!7UiG!7UlH!7UlH!7UfF!7UoI!7UoI"4I5Me,97Kdf9BsquHcG
2270 rVurIr;ZiHrVurIr;ZrK!!(LG!!(LH!!(L=!!(LH!!:ULe,97He,97He,'+Fe,B=Ie,97Kdf9Bs
2271 rW!#K!7UlH!n..ur;ZiHp](<CrW!#K!7UlH"4I8!!<1I;!!(LI!<:LK!7UoIs3puJ!7UoI!n..u
2272 r;ZiHp](<Cq>^]J!7LoJe,B@Ie,KCJe,'+Fe,'+Fe,01Ge,B@IdfBHtr;ZrK!!(LG!!(LH!!(LH
2273 !!(LF!!(LH!!LaNdf@kq!!(LI!!(LI!<:LK!7UoIs3piFs!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf
2274 <Ib~>
2275 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LH!!:ULe,'+Fe,97Jdf@kq!!:ULe,97He+*J=
2276 e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`GrVurIr;ZiHm/R.8nGiR<
2277 qu?`GrW)uI!<CUI!!C[M!7UfF!7UiG!7UlH!7UlH!7UfF!7UoI!7UoI"4I5Me,97Kdf9BsquHcG
2278 rVurIr;ZiHrVurIr;ZrK!!(LG!!(LH!!(L=!!(LH!!:ULe,97He,97He,'+Fe,B=Ie,97Kdf9Bs
2279 rW!#K!7UlH!n..ur;ZiHp](<CrW!#K!7UlH"4I8!!<1I;!!(LI!<:LK!7UoIs3puJ!7UoI!n..u
2280 r;ZiHp](<Cq>^]J!7LoJe,B@Ie,KCJe,'+Fe,'+Fe,01Ge,B@IdfBHtr;ZrK!!(LG!!(LH!!(LH
2281 !!(LF!!(LH!!LaNdf@kq!!(LI!!(LI!<:LK!7UoIs3piFs!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b
2282 <Ib~>
2283 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(L(!!(LH!!:ULe,'+Fe,97Jdf@kq!!:ULe,97He+*J=
2284 e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`GrVurIr;ZiHm/R.8nGiR<
2285 qu?`GrW)uI!<CUI!!C[M!7UfF!7UiG!7UlH!7UlH!7UfF!7UoI!7UoI"4I5Me,97Kdf9BsquHcG
2286 rVurIr;ZiHrVurIr;ZrK!!(LG!!(LH!!(L=!!(LH!!:ULe,97He,97He,'+Fe,B=Ie,97Kdf9Bs
2287 rW!#K!7UlH!n..ur;ZiHp](<CrW!#K!7UlH"4I8!!<1I;!!(LI!<:LK!7UoIs3puJ!7UoI!n..u
2288 r;ZiHp](<Cq>^]J!7LoJe,B@Ie,KCJe,'+Fe,'+Fe,01Ge,B@IdfBHtr;ZrK!!(LG!!(LH!!(LH
2289 !!(LF!!(LH!!LaNdf@kq!!(LI!!(LI!<:LK!7UoIs3piFs!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X
2290 <Ib~>
2291 s!%IC!7UfFrR:`GrR:]FrmTU%rR:cHqpYQFrR:`GrR:`GrR:9:qpYNEs3p-2s3pB9s3plGrmUfG
2292 s3pB9s3plGrmUiHrR:*5!7UH<!7UfFrmLrLdf9CHe,B=Ie,'+Fe,01Ge,97Jdf9CGe,KFGdfBHt
2293 r;ZoJ!!)uHrVurIqu?cH!<1IH!;t:H!7UlH"4I5Me,01Ge,97He+*J=e,97Jdf9CHe,B@Fe,KFG
2294 e,KFHe,9:Ge,B@Ge,KCJe,97He+WkAe,B@Ge,KCJe*I)6dfTU!!!*#I!<CUJ!<1II!!(LH!!(LC
2295 !!(LD!!(LH!<1FM!7LoJe,'+Fe,'+Fe,'.EdfTU!!7UlH"4I5Me,'.De,B@Fe,KFGe,KCJe,B=I
2296 e,B@He,B@HdfTU!!!*#I!<CUG!<48C<It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
2297 s!%IC!7UfFrR:`GrR:]FrmTU%rR:cHqpYQFrR:`GrR:`GrR:9:qpYNEs3p-2s3pB9s3plGrmUfG
2298 s3pB9s3plGrmUiHrR:*5!7UH<!7UfFrmLrLdf9CHe,B=Ie,'+Fe,01Ge,97Jdf9CGe,KFGdfBHt
2299 r;ZoJ!!)uHrVurIqu?cH!<1IH!;t:H!7UlH"4I5Me,01Ge,97He+*J=e,97Jdf9CHe,B@Fe,KFG
2300 e,KFHe,9:Ge,B@Ge,KCJe,97He+WkAe,B@Ge,KCJe*I)6dfTU!!!*#I!<CUJ!<1II!!(LH!!(LC
2301 !!(LD!!(LH!<1FM!7LoJe,'+Fe,'+Fe,'.EdfTU!!7UlH"4I5Me,'.De,B@Fe,KFGe,KCJe,B=I
2302 e,B@He,B@HdfTU!!!*#I!<CUG!<48C<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
2303 s!%IC!7UfFrR:`GrR:]FrmTU%rR:cHqpYQFrR:`GrR:`GrR:9:qpYNEs3p-2s3pB9s3plGrmUfG
2304 s3pB9s3plGrmUiHrR:*5!7UH<!7UfFrmLrLdf9CHe,B=Ie,'+Fe,01Ge,97Jdf9CGe,KFGdfBHt
2305 r;ZoJ!!)uHrVurIqu?cH!<1IH!;t:H!7UlH"4I5Me,01Ge,97He+*J=e,97Jdf9CHe,B@Fe,KFG
2306 e,KFHe,9:Ge,B@Ge,KCJe,97He+WkAe,B@Ge,KCJe*I)6dfTU!!!*#I!<CUJ!<1II!!(LH!!(LC
2307 !!(LD!!(LH!<1FM!7LoJe,'+Fe,'+Fe,'.EdfTU!!7UlH"4I5Me,'.De,B@Fe,KFGe,KCJe,B=I
2308 e,B@He,B@HdfTU!!!*#I!<CUG!<48C<It1$s+13$s-<TbK)bPp"H`]\<E4P~>
2309 s!!!oc2[jnhZ*Z*iW/l)JH2hQ!7QK!li7%7lN$r/s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
2310 s!!!oc2[jnhZ*Z*iW/l)JH2hQ!7QK!li7%7lN$r/s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
2311 s!!!oc2[jnhZ*Z*iW/l)JH2hQ!7QK!li7%7lN$r/s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
2312 s!!!oJH16$Z2amRJH44#s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2313 s!!!oJH16$Z2amRJH44#s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2314 s!!!oJH16$Z2amRJH44#s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2315 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2316 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2317 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2318 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2319 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2320 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2321 s!$b/!7U66s3pH;qpYQFrR:cHqpYKD!7UcE!7UE;rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pE:
2322 !7U04!7U'1!n..ukPtV3q#L<@JH16$eH#Uns&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
2323 s!$b/!7U66s3pH;qpYQFrR:cHqpYKD!7UcE!7UE;rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pE:
2324 !7U04!7U'1!n..ukPtV3q#L<@JH16$eH#Uns&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
2325 s!$b/!7U66s3pH;qpYQFrR:cHqpYKD!7UcE!7UE;rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pE:
2326 !7U04!7U'1!n..ukPtV3q#L<@JH16$eH#Uns&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
2327 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFrW)uIqZ-ZFnGiR<r;[&N!!(IJ!7U04"4I5Me*m>>
2328 df9BspAb<E!!(L;!!C[M!7UZB"4I5Me*m>;e*-i4e)gW3df@kl!!(L=!!(LH!!(LD!!(K!!.b.#
2329 !<48C<It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
2330 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFrW)uIqZ-ZFnGiR<r;[&N!!(IJ!7U04"4I5Me*m>>
2331 df9BspAb<E!!(L;!!C[M!7UZB"4I5Me*m>;e*-i4e)gW3df@kl!!(L=!!(LH!!(LD!!(K!!.b.#
2332 !<48C<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
2333 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFrW)uIqZ-ZFnGiR<r;[&N!!(IJ!7U04"4I5Me*m>>
2334 df9BspAb<E!!(L;!!C[M!7UZB"4I5Me*m>;e*-i4e)gW3df@kl!!(L=!!(LH!!(LD!!(K!!.b.#
2335 !<48C<It1$s+13$s-<TbK)bPp"H`]\<E4P~>
2336 s!$b/!7U35!7U97"4I5Me,97He,01Ge,B=Kdf@kp!!:ULe+!D<e,97Jdf@kq!!(L6!!(LH!!(L=
2337 !!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L;!!(L6!!(L1!!C[M!7U04!7UQ?!7QK!JH41"
2338 s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2339 s!$b/!7U35!7U97"4I5Me,97He,01Ge,B=Kdf@kp!!:ULe+!D<e,97Jdf@kq!!(L6!!(LH!!(L=
2340 !!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L;!!(L6!!(L1!!C[M!7U04!7UQ?!7QK!JH41"
2341 s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2342 s!$b/!7U35!7U97"4I5Me,97He,01Ge,B=Kdf@kp!!:ULe+!D<e,97Jdf@kq!!(L6!!(LH!!(L=
2343 !!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L;!!(L6!!(L1!!C[M!7U04!7UQ?!7QK!JH41"
2344 s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2345 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHqZ$WFr;ZrK!!(L7
2346 !!:ULe,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He*m>;e*?u9df9Bs
2347 r;ZoJ!!)uHrr<)K!<1IE!!LaN!7LrIe,9:He,B=JdfBBrqZ$WFr;clHqZ$WFJH16$dfBCls&FXM
2348 JcC<$JcD#8!K@'Pg]X2Kqc-XH~>
2349 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHqZ$WFr;ZrK!!(L7
2350 !!:ULe,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He*m>;e*?u9df9Bs
2351 r;ZoJ!!)uHrr<)K!<1IE!!LaN!7LrIe,9:He,B=JdfBBrqZ$WFr;clHqZ$WFJH16$dfBCls&FXM
2352 JcC<$JcD#8!K$jMg'!iEqc-XH~>
2353 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHqZ$WFr;ZrK!!(L7
2354 !!:ULe,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He*m>;e*?u9df9Bs
2355 r;ZoJ!!)uHrr<)K!<1IE!!LaN!7LrIe,9:He,B=JdfBBrqZ$WFr;clHqZ$WFJH16$dfBCls&FXM
2356 JcC<$JcD#8!J:@FeHD!7qGgOG~>
2357 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LF!!(LI
2358 !!(LI!!(L8!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UB:
2359 !7U<8!7UoI!7UlH!n..ur;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LF!!(LG
2360 !<1Gu!.b."!<48C<It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
2361 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LF!!(LI
2362 !!(LI!!(L8!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UB:
2363 !7U<8!7UoI!7UlH!n..ur;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LF!!(LG
2364 !<1Gu!.b."!<48C<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
2365 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LF!!(LI
2366 !!(LI!!(L8!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UB:
2367 !7U<8!7UoI!7UlH!n..ur;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LF!!(LG
2368 !<1Gu!.b."!<48C<It1$s+13$s-<TbK)bPp"H`]\<E4P~>
2369 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7UcE!7UoI!7UoI
2370 !7UB:s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7U?9!7UB:
2371 !7UlH!7UlH"Od>Ne'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UcE!7U`D!7QK!JH44#
2372 s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2373 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7UcE!7UoI!7UoI
2374 !7UB:s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7U?9!7UB:
2375 !7UlH!7UlH"Od>Ne'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UcE!7U`D!7QK!JH44#
2376 s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2377 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7UcE!7UoI!7UoI
2378 !7UB:s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7U?9!7UB:
2379 !7UlH!7UlH"Od>Ne'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UcE!7U`D!7QK!JH44#
2380 s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2381 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee+s%Ee,B@Ee+!D<
2382 e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He*[29e*d8:e,97H
2383 e,97He,9:He,B=Ie+s%Ee,97He,97He,97He,B=Ie,97He,B=Ie+s%Ee+itDdt%LM!7_)L,6(Yo
2384 s+13$s+138rrJ)Yp=oeB!;fbrJ,~>
2385 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee+s%Ee,B@Ee+!D<
2386 e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He*[29e*d8:e,97H
2387 e,97He,9:He,B=Ie+s%Ee,97He,97He,97He,B=Ie,97He,B=Ie+s%Ee+itDdt%LM!7_)L,6(Yo
2388 s+13$s+138rrIuVp=]Y<!;fbrJ,~>
2389 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee+s%Ee,B@Ee+!D<
2390 e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He*[29e*d8:e,97H
2391 e,97He,9:He,B=Ie+s%Ee,97He,97He,97He,B=Ie,97He,B=Ie+s%Ee+itDdt%LM!7_)L,6(Yo
2392 s+13$s+138rrI`Op=0;.!;]\qJ,~>
2393 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LD
2394 !!(LE!!(L<!!(LE!!C[M!7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5M
2395 e*I&7e+!D<e,01Ge,B@IdfBHtr;ZrK!!(LF!!(LG!<:OI!!(LH!!(LI!!(LH!!C[M!7U`D!7UoI
2396 !7UlH!7QK!JH44#s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2397 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LD
2398 !!(LE!!(L<!!(LE!!C[M!7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5M
2399 e*I&7e+!D<e,01Ge,B@IdfBHtr;ZrK!!(LF!!(LG!<:OI!!(LH!!(LI!!(LH!!C[M!7U`D!7UoI
2400 !7UlH!7QK!JH44#s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2401 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LD
2402 !!(LE!!(L<!!(LE!!C[M!7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5M
2403 e*I&7e+!D<e,01Ge,B@IdfBHtr;ZrK!!(LF!!(LG!<:OI!!(LH!!(LI!!(LH!!C[M!7U`D!7UoI
2404 !7UlH!7QK!JH44#s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2405 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe,'.Ce,01G
2406 e+!G8e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He*?u6e+!D<e,'.EdfTU!!!)uHrVurI
2407 qZ$WFqu?cH!<1IH!;t:H!7UlH"4I5Me,'.Ce,KFHdt%LM!7V#K,6(Yos+13$s+138rrJ)Yp=oeB
2408 !;fbrJ,~>
2409 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe,'.Ce,01G
2410 e+!G8e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He*?u6e+!D<e,'.EdfTU!!!)uHrVurI
2411 qZ$WFqu?cH!<1IH!;t:H!7UlH"4I5Me,'.Ce,KFHdt%LM!7V#K,6(Yos+13$s+138rrIuVp=]Y<
2412 !;fbrJ,~>
2413 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe,'.Ce,01G
2414 e+!G8e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He*?u6e+!D<e,'.EdfTU!!!)uHrVurI
2415 qZ$WFqu?cH!<1IH!;t:H!7UlH"4I5Me,'.Ce,KFHdt%LM!7V#K,6(Yos+13$s+138rrI`Op=0;.
2416 !;]\qJ,~>
2417 s!!!oc2[jnhZ*Z*iW/l)JH16$JH5]os&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
2418 s!!!oc2[jnhZ*Z*iW/l)JH16$JH5]os&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
2419 s!!!oc2[jnhZ*Z*iW/l)JH16$JH5]os&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
2420 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2421 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2422 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2423 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2424 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2425 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2426 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2427 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2428 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2429 s!$b/!7U66s3pH;qpYQFrR:cHqpPNFqpYQFrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3oEs
2430 !7U04!7U'1!n..ukPtV3nc/[=`;fnejo>J3!7U-3!7UfF!n..uj8f5/iW&u-YQ4\Is&FXMJcC<$
2431 JcD#8!K@'Pg]X2Kqc-XH~>
2432 s!$b/!7U66s3pH;qpYQFrR:cHqpPNFqpYQFrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3oEs
2433 !7U04!7U'1!n..ukPtV3nc/[=`;fnejo>J3!7U-3!7UfF!n..uj8f5/iW&u-YQ4\Is&FXMJcC<$
2434 JcD#8!K$jMg'!iEqc-XH~>
2435 s!$b/!7U66s3pH;qpYQFrR:cHqpPNFqpYQFrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3oEs
2436 !7U04!7U'1!n..ukPtV3nc/[=`;fnejo>J3!7U-3!7UfF!n..uj8f5/iW&u-YQ4\Is&FXMJcC<$
2437 JcD#8!J:@FeHD!7qGgOG~>
2438 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFqZ$]H!7UlH!7UK=!7UlH#1EPPdf9Bskl:h7!!(L;
2439 !!C[M!7UZB"4I5Me*m>>df9BspAb<E!!(Kt!!(L4!!(L1!!:ULe+`nCe+*J=e+*J=e(4R"e*m>;
2440 e)gW3df@kl!!(L=!!(LF!!:ULe)LE.e)C?-e("Eue,97He*?u6e+j"D,6(Yos+13$s+138rrJ)Y
2441 p=oeB!;fbrJ,~>
2442 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFqZ$]H!7UlH!7UK=!7UlH#1EPPdf9Bskl:h7!!(L;
2443 !!C[M!7UZB"4I5Me*m>>df9BspAb<E!!(Kt!!(L4!!(L1!!:ULe+`nCe+*J=e+*J=e(4R"e*m>;
2444 e)gW3df@kl!!(L=!!(LF!!:ULe)LE.e)C?-e("Eue,97He*?u6e+j"D,6(Yos+13$s+138rrIuV
2445 p=]Y<!;fbrJ,~>
2446 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFqZ$]H!7UlH!7UK=!7UlH#1EPPdf9Bskl:h7!!(L;
2447 !!C[M!7UZB"4I5Me*m>>df9BspAb<E!!(Kt!!(L4!!(L1!!:ULe+`nCe+*J=e+*J=e(4R"e*m>;
2448 e)gW3df@kl!!(L=!!(LF!!:ULe)LE.e)C?-e("Eue,97He*?u6e+j"D,6(Yos+13$s+138rrI`O
2449 p=0;.!;]\qJ,~>
2450 s!$b/!7U35!7U97"4I5Me,97He,01Ge,'+Idf9Bsr;ZiHnc/[=r;ZoJ!7UlH!7U66!7UlH!7UK=
2451 !7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7U66!7U'1"4I5Me*-i4e+!D<e(4R"e+!D<
2452 e)gW4df9Bskl:_4q>^TG!7Ts.!7Tp-!7T9p!7Tp-s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2453 s!$b/!7U35!7U97"4I5Me,97He,01Ge,'+Idf9Bsr;ZiHnc/[=r;ZoJ!7UlH!7U66!7UlH!7UK=
2454 !7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7U66!7U'1"4I5Me*-i4e+!D<e(4R"e+!D<
2455 e)gW4df9Bskl:_4q>^TG!7Ts.!7Tp-!7T9p!7Tp-s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2456 s!$b/!7U35!7U97"4I5Me,97He,01Ge,'+Idf9Bsr;ZiHnc/[=r;ZoJ!7UlH!7U66!7UlH!7UK=
2457 !7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7U66!7U'1"4I5Me*-i4e+!D<e(4R"e+!D<
2458 e)gW4df9Bskl:_4q>^TG!7Ts.!7Tp-!7T9p!7Tp-s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2459 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHqZ$WFrVurIr;ZiH
2460 m/R4:!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7U66"4I5M
2461 e,97Jdf9CHe,KCKdfBBrqZ$cJ!!(IJrmUfGs3prI!Rh&Je,'+Fe,B@Ge,B@Ge,KCKdfBBrpAk0@
2462 rW)rH!s$dM!<(CH!!1OKrmUlIrR:?<"4I5Me,97Jdf9CHe,KCKdfBBrqZ$cJ!!(IJrmUfGs3prI
2463 !Rh&Je,'+Fe,B@Hdf]["!7LrIe,KCJe,97Jdf9CHe+E\@e,9:Fe,KCJe,97Kdf@hsrmUiHrR:cH
2464 !Rh&Je*-l2e,KCJe,97He,B@Ie,B@Ge+NbAe,B=Ie,B@Ie+j"D,6(Yos+13$s+138rrJ)Yp=oeB
2465 !;fbrJ,~>
2466 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHqZ$WFrVurIr;ZiH
2467 m/R4:!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7U66"4I5M
2468 e,97Jdf9CHe,KCKdfBBrqZ$cJ!!(IJrmUfGs3prI!Rh&Je,'+Fe,B@Ge,B@Ge,KCKdfBBrpAk0@
2469 rW)rH!s$dM!<(CH!!1OKrmUlIrR:?<"4I5Me,97Jdf9CHe,KCKdfBBrqZ$cJ!!(IJrmUfGs3prI
2470 !Rh&Je,'+Fe,B@Hdf]["!7LrIe,KCJe,97Jdf9CHe+E\@e,9:Fe,KCJe,97Kdf@hsrmUiHrR:cH
2471 !Rh&Je*-l2e,KCJe,97He,B@Ie,B@Ge+NbAe,B=Ie,B@Ie+j"D,6(Yos+13$s+138rrIuVp=]Y<
2472 !;fbrJ,~>
2473 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHqZ$WFrVurIr;ZiH
2474 m/R4:!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7U66"4I5M
2475 e,97Jdf9CHe,KCKdfBBrqZ$cJ!!(IJrmUfGs3prI!Rh&Je,'+Fe,B@Ge,B@Ge,KCKdfBBrpAk0@
2476 rW)rH!s$dM!<(CH!!1OKrmUlIrR:?<"4I5Me,97Jdf9CHe,KCKdfBBrqZ$cJ!!(IJrmUfGs3prI
2477 !Rh&Je,'+Fe,B@Hdf]["!7LrIe,KCJe,97Jdf9CHe+E\@e,9:Fe,KCJe,97Kdf@hsrmUiHrR:cH
2478 !Rh&Je*-l2e,KCJe,97He,B@Ie,B@Ge+NbAe,B=Ie,B@Ie+j"D,6(Yos+13$s+138rrI`Op=0;.
2479 !;]\qJ,~>
2480 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LG!<1IH
2481 !<(C6!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TBs!7U<8
2482 !7UoI!7UlH!n..ur;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LH!!:UL
2483 e,97Kdf@kGrW!#K!!)rGqZ$]H!7UoI"4I5Me,97Kdf@kGrW!&L!!(L=!!(LI!!(LH!!:ULe,97K
2484 df9BsrVurIr;ZiHrW)uIrVurIr;ZiHrW)uIrVurIr;ZiHrVurIrW)uI!W^]urW!#K!7UlH!n..u
2485 r;ZoJ!!)rGr;ZiHq#CKF!7UlH"4I8!e,B=Kdf@kq!!C[Me'n9r!7U]Cr6tZGr6kZHe,97Ndf9Bs
2486 !!(LG!!(LH!!(LF!;t=G!!(LI!!(LH!!(LD!<48C<It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
2487 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LG!<1IH
2488 !<(C6!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TBs!7U<8
2489 !7UoI!7UlH!n..ur;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LH!!:UL
2490 e,97Kdf@kGrW!#K!!)rGqZ$]H!7UoI"4I5Me,97Kdf@kGrW!&L!!(L=!!(LI!!(LH!!:ULe,97K
2491 df9BsrVurIr;ZiHrW)uIrVurIr;ZiHrW)uIrVurIr;ZiHrVurIrW)uI!W^]urW!#K!7UlH!n..u
2492 r;ZoJ!!)rGr;ZiHq#CKF!7UlH"4I8!e,B=Kdf@kq!!C[Me'n9r!7U]Cr6tZGr6kZHe,97Ndf9Bs
2493 !!(LG!!(LH!!(LF!;t=G!!(LI!!(LH!!(LD!<48C<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
2494 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LG!<1IH
2495 !<(C6!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TBs!7U<8
2496 !7UoI!7UlH!n..ur;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LH!!:UL
2497 e,97Kdf@kGrW!#K!!)rGqZ$]H!7UoI"4I5Me,97Kdf@kGrW!&L!!(L=!!(LI!!(LH!!:ULe,97K
2498 df9BsrVurIr;ZiHrW)uIrVurIr;ZiHrW)uIrVurIr;ZiHrVurIrW)uI!W^]urW!#K!7UlH!n..u
2499 r;ZoJ!!)rGr;ZiHq#CKF!7UlH"4I8!e,B=Kdf@kq!!C[Me'n9r!7U]Cr6tZGr6kZHe,97Ndf9Bs
2500 !!(LG!!(LH!!(LF!;t=G!!(LI!!(LH!!(LD!<48C<It1$s+13$s-<TbK)bPp"H`]\<E4P~>
2501 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7U]C!n..ur;ZiH
2502 n,WL;rVurIr;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHdJs9rmf3@:
2503 r;ZiHr;ZuL!!(Ksqu?`Gq>^NEr;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurIquHcGquHcGr;ZiHr;ZiH
2504 p]16@!<CUJ!!:UL!;k4G!7UlH"4I5Me+3P>e,97He,97Ldf9Bse,01Ge+s%Ee,97He,97He,97H
2505 e,B=Ie,97He,B=Ie,97He,97Jdf@kq!!:ULe,97Ldf9Bse+3P>e,9:EdfBHtr;ZoJ!7UlH!n..u
2506 qZ$WFr;ZiHlN$h2rW)uIqZ$WFr;ZiHoDf$C!7Lqsr;ZiHq#LF=s&FXMJcC<$JcD#8!K@'Pg]X2K
2507 qc-XH~>
2508 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7U]C!n..ur;ZiH
2509 n,WL;rVurIr;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHdJs9rmf3@:
2510 r;ZiHr;ZuL!!(Ksqu?`Gq>^NEr;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurIquHcGquHcGr;ZiHr;ZiH
2511 p]16@!<CUJ!!:UL!;k4G!7UlH"4I5Me+3P>e,97He,97Ldf9Bse,01Ge+s%Ee,97He,97He,97H
2512 e,B=Ie,97He,B=Ie,97He,97Jdf@kq!!:ULe,97Ldf9Bse+3P>e,9:EdfBHtr;ZoJ!7UlH!n..u
2513 qZ$WFr;ZiHlN$h2rW)uIqZ$WFr;ZiHoDf$C!7Lqsr;ZiHq#LF=s&FXMJcC<$JcD#8!K$jMg'!iE
2514 qc-XH~>
2515 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7U]C!n..ur;ZiH
2516 n,WL;rVurIr;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHdJs9rmf3@:
2517 r;ZiHr;ZuL!!(Ksqu?`Gq>^NEr;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurIquHcGquHcGr;ZiHr;ZiH
2518 p]16@!<CUJ!!:UL!;k4G!7UlH"4I5Me+3P>e,97He,97Ldf9Bse,01Ge+s%Ee,97He,97He,97H
2519 e,B=Ie,97He,B=Ie,97He,97Jdf@kq!!:ULe,97Ldf9Bse+3P>e,9:EdfBHtr;ZoJ!7UlH!n..u
2520 qZ$WFr;ZiHlN$h2rW)uIqZ$WFr;ZiHoDf$C!7Lqsr;ZiHq#LF=s&FXMJcC<$JcD#8!J:@FeHD!7
2521 qGgOG~>
2522 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee+`nEdf@kq!!(L<
2523 !!(LG!!(LH!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(Kr!!(L:!!(LH
2524 !!(LH!!(LH!<:OI!!(LE!!(LH!!(LH!!(LH!!(LI!!(LH!!(LI!!(LE!<:OG!<:OJ!!(LH!!(LD
2525 !!(LH!!:UL!<1IH!!(LF!!(LH!!C[M!7UN>!7UlH!7UlH!7UlHs3prI!7UcE!7UlH!7UlH!7UlH
2526 !7UoI!7UlH!7UoI!7UlH!7UlH!n..ur;ZoJ!7UlH!7UlHs3pW@!7UoI!7UlH!n..ur;ZoJ!7UlH
2527 !n..uqZ$WFr;ZiHlMpq6q#LHDqZ$WFr;ZiHoDf$C!7Lqsr;ZiHq#LF=s&FXMJcC<$JcD#8!K@'P
2528 g]X2Kqc-XH~>
2529 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee+`nEdf@kq!!(L<
2530 !!(LG!!(LH!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(Kr!!(L:!!(LH
2531 !!(LH!!(LH!<:OI!!(LE!!(LH!!(LH!!(LH!!(LI!!(LH!!(LI!!(LE!<:OG!<:OJ!!(LH!!(LD
2532 !!(LH!!:UL!<1IH!!(LF!!(LH!!C[M!7UN>!7UlH!7UlH!7UlHs3prI!7UcE!7UlH!7UlH!7UlH
2533 !7UoI!7UlH!7UoI!7UlH!7UlH!n..ur;ZoJ!7UlH!7UlHs3pW@!7UoI!7UlH!n..ur;ZoJ!7UlH
2534 !n..uqZ$WFr;ZiHlMpq6q#LHDqZ$WFr;ZiHoDf$C!7Lqsr;ZiHq#LF=s&FXMJcC<$JcD#8!K$jM
2535 g'!iEqc-XH~>
2536 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee+`nEdf@kq!!(L<
2537 !!(LG!!(LH!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(Kr!!(L:!!(LH
2538 !!(LH!!(LH!<:OI!!(LE!!(LH!!(LH!!(LH!!(LI!!(LH!!(LI!!(LE!<:OG!<:OJ!!(LH!!(LD
2539 !!(LH!!:UL!<1IH!!(LF!!(LH!!C[M!7UN>!7UlH!7UlH!7UlHs3prI!7UcE!7UlH!7UlH!7UlH
2540 !7UoI!7UlH!7UoI!7UlH!7UlH!n..ur;ZoJ!7UlH!7UlHs3pW@!7UoI!7UlH!n..ur;ZoJ!7UlH
2541 !n..uqZ$WFr;ZiHlMpq6q#LHDqZ$WFr;ZiHoDf$C!7Lqsr;ZiHq#LF=s&FXMJcC<$JcD#8!J:@F
2542 eHD!7qGgOG~>
2543 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LG
2544 !!(LH!!:ULe,97He+*J=e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`G
2545 r;ZrK!!(Kp!!(L<!!(LG!!(LI!<:LK!7UlH"4I5Me,'+Fe,04Ge,B=Ie,97He,B=Ie,97Kdf9Bs
2546 qu?`Gr;ZoJ!7UlH!n..ur;ZiHq#CEDrW)uI!<CUG!!(LH!!:ULe,97Kdf9BsrVurIp](<Cqu?`G
2547 rW)uI!<CUI!!C[M!7UfF!7UiGs3prI!7UlH!7UoI!7UlH"4I5Me,01Ge,B@IdfKNue,B=Kdf@kr
2548 !<:LK!7UlH!7UWA!7UoI!7UoIs3guKe,B@IdfBHtr;ZoJ!7UlH!n..ur;ZiHlMpq6r;[&N!!(IJ
2549 !7UiG!7UlH!7UoI!7U]C"OdA"!7UlH!7U`Ds!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2550 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LG
2551 !!(LH!!:ULe,97He+*J=e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`G
2552 r;ZrK!!(Kp!!(L<!!(LG!!(LI!<:LK!7UlH"4I5Me,'+Fe,04Ge,B=Ie,97He,B=Ie,97Kdf9Bs
2553 qu?`Gr;ZoJ!7UlH!n..ur;ZiHq#CEDrW)uI!<CUG!!(LH!!:ULe,97Kdf9BsrVurIp](<Cqu?`G
2554 rW)uI!<CUI!!C[M!7UfF!7UiGs3prI!7UlH!7UoI!7UlH"4I5Me,01Ge,B@IdfKNue,B=Kdf@kr
2555 !<:LK!7UlH!7UWA!7UoI!7UoIs3guKe,B@IdfBHtr;ZoJ!7UlH!n..ur;ZiHlMpq6r;[&N!!(IJ
2556 !7UiG!7UlH!7UoI!7U]C"OdA"!7UlH!7U`Ds!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2557 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LG
2558 !!(LH!!:ULe,97He+*J=e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`G
2559 r;ZrK!!(Kp!!(L<!!(LG!!(LI!<:LK!7UlH"4I5Me,'+Fe,04Ge,B=Ie,97He,B=Ie,97Kdf9Bs
2560 qu?`Gr;ZoJ!7UlH!n..ur;ZiHq#CEDrW)uI!<CUG!!(LH!!:ULe,97Kdf9BsrVurIp](<Cqu?`G
2561 rW)uI!<CUI!!C[M!7UfF!7UiGs3prI!7UlH!7UoI!7UlH"4I5Me,01Ge,B@IdfKNue,B=Kdf@kr
2562 !<:LK!7UlH!7UWA!7UoI!7UoIs3guKe,B@IdfBHtr;ZoJ!7UlH!n..ur;ZiHlMpq6r;[&N!!(IJ
2563 !7UiG!7UlH!7UoI!7U]C"OdA"!7UlH!7U`Ds!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2564 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe,'.De,B@G
2565 e+!G8e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He'A!oe+!D<e,'.EdfTU!!!)uHrVurI
2566 qZ$WFqu?cH!<1IH!;t:H!7UlH"4I5Me,'.De,B@Ge,KCJe,97He+`qBdfTU!!!)uHrW)oGrr<&J
2567 r;ZiHrW)rHpAb3BqZ-WE!s$dM!<(CG!!(LF!!(LG!!1OKrmUiHr6kZHe,97Kdf9BsqZ-WE"9?mN
2568 dfBBrrW)rH!s$dM!<(C@!;t=G!<1FL!7LoJrmLrLdf@kq!!:UL!<(CH!!(LH!!(L5!<(CH!!(LH
2569 !!:UL!;t=F!<1I@!!:ULe,B@Fe,'.F,6(Yos+13$s+138rrJ)Yp=oeB!;fbrJ,~>
2570 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe,'.De,B@G
2571 e+!G8e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He'A!oe+!D<e,'.EdfTU!!!)uHrVurI
2572 qZ$WFqu?cH!<1IH!;t:H!7UlH"4I5Me,'.De,B@Ge,KCJe,97He+`qBdfTU!!!)uHrW)oGrr<&J
2573 r;ZiHrW)rHpAb3BqZ-WE!s$dM!<(CG!!(LF!!(LG!!1OKrmUiHr6kZHe,97Kdf9BsqZ-WE"9?mN
2574 dfBBrrW)rH!s$dM!<(C@!;t=G!<1FL!7LoJrmLrLdf@kq!!:UL!<(CH!!(LH!!(L5!<(CH!!(LH
2575 !!:UL!;t=F!<1I@!!:ULe,B@Fe,'.F,6(Yos+13$s+138rrIuVp=]Y<!;fbrJ,~>
2576 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe,'.De,B@G
2577 e+!G8e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He'A!oe+!D<e,'.EdfTU!!!)uHrVurI
2578 qZ$WFqu?cH!<1IH!;t:H!7UlH"4I5Me,'.De,B@Ge,KCJe,97He+`qBdfTU!!!)uHrW)oGrr<&J
2579 r;ZiHrW)rHpAb3BqZ-WE!s$dM!<(CG!!(LF!!(LG!!1OKrmUiHr6kZHe,97Kdf9BsqZ-WE"9?mN
2580 dfBBrrW)rH!s$dM!<(C@!;t=G!<1FL!7LoJrmLrLdf@kq!!:UL!<(CH!!(LH!!(L5!<(CH!!(LH
2581 !!:UL!;t=F!<1I@!!:ULe,B@Fe,'.F,6(Yos+13$s+138rrI`Op=0;.!;]\qJ,~>
2582 s!!!oc2[jnhZ*Z*`W5nbQN.$7r;ZiHJH1Z0s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
2583 s!!!oc2[jnhZ*Z*`W5nbQN.$7r;ZiHJH1Z0s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
2584 s!!!oc2[jnhZ*Z*`W5nbQN.$7r;ZiHJH1Z0s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
2585 s!!!oJH16$rW)oGJH1W/s!%JCJcC<$JcC<$V#LDpr;ZP`!K@'Pg]X2Kqc-XH~>
2586 s!!!oJH16$rW)oGJH1W/s!%JCJcC<$JcC<$V#LDpr;ZP\!K$jMg'!iEqc-XH~>
2587 s!!!oJH16$rW)oGJH1W/s!%JCJcC<$JcC<$V#LDpr;ZPS!J:@FeHD!7qGgOG~>
2588 s!!!oJH16$JH1B(s!%JCm/N-jJcC<$N;oU,!M0;hrrAYd!!/&Yp=oeB!;fbrJ,~>
2589 s!!!oJH16$JH1B(s!%JCm/N-jJcC<$N;oU*!La#drrAM`!!.rVp=]Y<!;fbrJ,~>
2590 s!!!oJH16$JH1B(s!%JCm/N-jJcC<$N;oU%!KdB[rrA2W!!.]Op=0;.!;]\qJ,~>
2591 s!!!oJH16$JH1B(s!%JCm/N-jJcC<$N;oU,!M0;hrrJ\kqYpSTs7Y4NScJXf<Ib~>
2592 s!!!oJH16$JH1B(s!%JCm/N-jJcC<$N;oU*!La#drrJPgqYpSQs7Y.LRK34b<Ib~>
2593 s!!!oJH16$JH1B(s!%JCm/N-jJcC<$N;oU%!KdB[rrJ5^qYpSJs7XtGOT>5X<Ib~>
2594 s!$b/!7U66s3pH;qpYQFrR:cHqpYHC!7UiG!7UB:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=
2595 !7U'1!n..ukPtV3qZ$]H!7Tm,!7SpfrmUB;!7RnI!7U`DqpVqQ!7UfF!7Tg*s!%JCm/N-jJcC<$
2596 N;p6>s.8c9!M0;hrrJ\kqYpSTs7Y4NScJXf<Ib~>
2597 s!$b/!7U66s3pH;qpYQFrR:cHqpYHC!7UiG!7UB:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=
2598 !7U'1!n..ukPtV3qZ$]H!7Tm,!7SpfrmUB;!7RnI!7U`DqpVqQ!7UfF!7Tg*s!%JCm/N-jJcC<$
2599 N;p6<s-iK3!La#drrJPgqYpSQs7Y.LRK34b<Ib~>
2600 s!$b/!7U66s3pH;qpYQFrR:cHqpYHC!7UiG!7UB:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=
2601 !7U'1!n..ukPtV3qZ$]H!7Tm,!7SpfrmUB;!7RnI!7U`DqpVqQ!7UfF!7Tg*s!%JCm/N-jJcC<$
2602 N;p67s,lj%!KdB[rrJ5^qYpSJs7XtGOT>5X<Ib~>
2603 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFr;clHr;clHn,NI;r;[&N!!(IJ!7U04"4I5Me*m>>
2604 df9BspAb<E!!(L;!!C[M!7UZB"4I5Me+3P>e)gW3df@kl!!(L=!!(LF!!:ULe):9,e&MFge,B=I
2605 e+*J=e("Eue+NbAe*?u6e+itDe+itDe("Eue+NbAe*-i4e,'+Fe)(0*,6([0s,YBTs+13/s0LJ]
2606 T)\?9!M0;hrrJ\kqYpSTs7Y4NScJXf<Ib~>
2607 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFr;clHr;clHn,NI;r;[&N!!(IJ!7U04"4I5Me*m>>
2608 df9BspAb<E!!(L;!!C[M!7UZB"4I5Me+3P>e)gW3df@kl!!(L=!!(LF!!:ULe):9,e&MFge,B=I
2609 e+*J=e("Eue+NbAe*?u6e+itDe+itDe("Eue+NbAe*-i4e,'+Fe)(0*,6([0s,YBTs+13/s0LD[
2610 RfDp3!La#drrJPgqYpSQs7Y.LRK34b<Ib~>
2611 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFr;clHr;clHn,NI;r;[&N!!(IJ!7U04"4I5Me*m>>
2612 df9BspAb<E!!(L;!!C[M!7UZB"4I5Me+3P>e)gW3df@kl!!(L=!!(LF!!:ULe):9,e&MFge,B=I
2613 e+*J=e("Eue+NbAe*?u6e+itDe+itDe("Eue+NbAe*-i4e,'+Fe)(0*,6([0s,YBTs+13/s0L5V
2614 OoOt%!KdB[rrJ5^qYpSJs7XtGOT>5X<Ib~>
2615 s!$b/!7U35!7U97"4I5Me,97He,01Ge,97Jdf@kr!!:ULe*m>;e,97Jdf@kq!!(L6!!(LH!!(L=
2616 !!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L@!!(L1!!C[M!7U04!7UcE!n..ui;`l,`rH+g
2617 mJm79aT)=iiW&u-q#CEDaT)=ikl:_4qZ$WFhZ3[#s&JFcO3E1TJcC]/ZePSQs7+kFScJ]g!M0;f
2618 rrJ)Yp=oeB!;fbrJ,~>
2619 s!$b/!7U35!7U97"4I5Me,97He,01Ge,97Jdf@kr!!:ULe*m>;e,97Jdf@kq!!(L6!!(LH!!(L=
2620 !!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L@!!(L1!!C[M!7U04!7UcE!n..ui;`l,`rH+g
2621 mJm79aT)=iiW&u-q#CEDaT)=ikl:_4qZ$WFhZ3[#s&JFcO3E1TJcC]/Ze>GKs7+eDRK39c!La#b
2622 rrIuVp=]Y<!;fbrJ,~>
2623 s!$b/!7U35!7U97"4I5Me,97He,01Ge,97Jdf@kr!!:ULe*m>;e,97Jdf@kq!!(L6!!(LH!!(L=
2624 !!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L@!!(L1!!C[M!7U04!7UcE!n..ui;`l,`rH+g
2625 mJm79aT)=iiW&u-q#CEDaT)=ikl:_4qZ$WFhZ3[#s&JFcO3E1TJcC]/Zdf)=s7+V?OT>=Z!KdBY
2626 rrI`Op=0;.!;]\qJ,~>
2627 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHr;ZrK!!(LG!!(L6
2628 !!:ULe,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+E\Cdf9Bsr;ZoJ
2629 !!)uHrr<)K!<1IE!!LaN!7LrIe,9:He,B=JdfBBrqZ$WFrW)rH"9?mNdfBBrrr<&Jr;ZoJ!!)uH
2630 pAk3A!s$dM!<(CG!<(CG!<:LK!7UoIrR:cH!Rh&Je*-i4e,'.De,KCKdfBBrrr<&JrVurIl2Uk6
2631 !<1II!!1OKrmUfGs3prI!Rh&Je,KFHe+WhCdfBBrr;clHr;ciG!<CUE!!1OKrmU-4!Rh&Je,KCK
2632 dfBBrr;clHrVuuJ!<1II!<(C?!<(CG!<1FL!7LoJrmLuMdf@hsrmUiHrR:`GrR:`GrR:TCs!%JC
2633 m/N-jJcC<$N;re1!!'Uc!M9>]g]<uHr;Qeh!;c]rN;rV,"J,Vj<E4P~>
2634 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHr;ZrK!!(LG!!(L6
2635 !!:ULe,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+E\Cdf9Bsr;ZoJ
2636 !!)uHrr<)K!<1IE!!LaN!7LrIe,9:He,B=JdfBBrqZ$WFrW)rH"9?mNdfBBrrr<&Jr;ZoJ!!)uH
2637 pAk3A!s$dM!<(CG!<(CG!<:LK!7UoIrR:cH!Rh&Je*-i4e,'.De,KCKdfBBrrr<&JrVurIl2Uk6
2638 !<1II!!1OKrmUfGs3prI!Rh&Je,KFHe+WhCdfBBrr;clHr;ciG!<CUE!!1OKrmU-4!Rh&Je,KCK
2639 dfBBrr;clHrVuuJ!<1II!<(C?!<(CG!<1FL!7LoJrmLuMdf@hsrmUiHrR:`GrR:`GrR:TCs!%JC
2640 m/N-jJcC<$N;re/!!'Ua!Lj&Yg&[WBr;Qed!;c]rM?!;'"I]>f<E4P~>
2641 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHr;ZrK!!(LG!!(L6
2642 !!:ULe,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+E\Cdf9Bsr;ZoJ
2643 !!)uHrr<)K!<1IE!!LaN!7LrIe,9:He,B=JdfBBrqZ$WFrW)rH"9?mNdfBBrrr<&Jr;ZoJ!!)uH
2644 pAk3A!s$dM!<(CG!<(CG!<:LK!7UoIrR:cH!Rh&Je*-i4e,'.De,KCKdfBBrrr<&JrVurIl2Uk6
2645 !<1II!!1OKrmUfGs3prI!Rh&Je,KFHe+WhCdfBBrr;clHr;ciG!<CUE!!1OKrmU-4!Rh&Je,KCK
2646 dfBBrr;clHrVuuJ!<1II!<(C?!<(CG!<1FL!7LoJrmLuMdf@hsrmUiHrR:`GrR:`GrR:TCs!%JC
2647 m/N-jJcC<$N;re*!!'U\!KmEPeH(d4r;Qe[!;c]rK)bPp"H`]\<E4P~>
2648 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LI!!(LI
2649 !!(LG!!(L7!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UWA
2650 !7UoI!7UlH!n..ur;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LI!<:LL
2651 !7TEr!!:ULe,97Jdf@kq!!:UL!;t:H!7UoIs3piF!n..ur;[/Q!!(IJdf@hse,97Kdf@kGrVurI
2652 p]16@rrDuG!!)uHrVurIr;ZrK!!(LI!!UgOdf9Bsp&P$>rrDuG!W^]urW!&L!!(LI!!(LH!!(LI
2653 !<:OI!!C[M!7UfFr6k]Ie'n9r!7UlH!7UoI!7UoIs3pcDs3prI!7U]Cr6tZGr6k]Ie'n9r"4I5M
2654 e,B=Ie,97He,B@Ie,B=Ldf9BsqZ-QCqZ$]H!7UoIs3guKe,B@Ie,KCJe,B=Kdf@kq!!:ULe,97J
2655 df@kq!!(LF!<48C<UBaHbhi@&rkseBGM<)sGCfeCs8R;ls8R<Bs8R<BrsJbDNI#gKrkseBGL6Be
2656 g].>cg]=#Hn_=/:!;uitScJWe!K@'Pg]X2Kqc-XH~>
2657 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LI!!(LI
2658 !!(LG!!(L7!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UWA
2659 !7UoI!7UlH!n..ur;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LI!<:LL
2660 !7TEr!!:ULe,97Jdf@kq!!:UL!;t:H!7UoIs3piF!n..ur;[/Q!!(IJdf@hse,97Kdf@kGrVurI
2661 p]16@rrDuG!!)uHrVurIr;ZrK!!(LI!!UgOdf9Bsp&P$>rrDuG!W^]urW!&L!!(LI!!(LH!!(LI
2662 !<:OI!!C[M!7UfFr6k]Ie'n9r!7UlH!7UoI!7UoIs3pcDs3prI!7U]Cr6tZGr6k]Ie'n9r"4I5M
2663 e,B=Ie,97He,B@Ie,B=Ldf9BsqZ-QCqZ$]H!7UoIs3guKe,B@Ie,KCJe,B=Kdf@kq!!:ULe,97J
2664 df@kq!!(LF!<48C<UBaHbhi@&rNq?*GM<)sGCfeCs8R;ls8R<Bs8R<BrsJ_3LO"+DrNq?*GL6Be
2665 g&M,ag&[ZBn_+#4!;uitRK33a!K$jMg'!iEqc-XH~>
2666 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LI!!(LI
2667 !!(LG!!(L7!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UWA
2668 !7UoI!7UlH!n..ur;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LI!<:LL
2669 !7TEr!!:ULe,97Jdf@kq!!:UL!;t:H!7UoIs3piF!n..ur;[/Q!!(IJdf@hse,97Kdf@kGrVurI
2670 p]16@rrDuG!!)uHrVurIr;ZrK!!(LI!!UgOdf9Bsp&P$>rrDuG!W^]urW!&L!!(LI!!(LH!!(LI
2671 !<:OI!!C[M!7UfFr6k]Ie'n9r!7UlH!7UoI!7UoIs3pcDs3prI!7U]Cr6tZGr6k]Ie'n9r"4I5M
2672 e,B=Ie,97He,B@Ie,B=Ldf9BsqZ-QCqZ$]H!7UoIs3guKe,B@Ie,KCJe,B=Kdf@kq!!:ULe,97J
2673 df@kq!!(LF!<48C<UBaHbhi@&p8<LeGM<)sGCfeCs8R;ls8R<Bs8R<BrsJItJp;M>p8<LeGL6Be
2674 eGoT\eH(g4n^RZ&!;uitOT>7X!J:@FeHD!7qGgOG~>
2675 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7UlH!7UoI!7UiG
2676 !7U?9s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH
2677 !7UlH"Od>Ne'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH!n..ur;ZoJ!7UlH
2678 "Od>Ne'n!j!7UlH!n.,Lr6kWGqpYQF#1ES$!7Lqsr;ZoJ!7UlH!7U35!7UiG!7UlH"4I5Me,04F
2679 e*$c3e,97Kdf9Bsq#CEDrVurIr;ZrK!!(L@!!(LH!!(LH!!(LI!!(LH!!(L?!!(L6!!(LH!!C[M
2680 !7U`D!7UoI!7UlH"4I5Me+<Y<dfBHtr;ZoJ!7UlH"4I5Me,04Ce,KFJe,04Ge+`qC,6([0s,YC\
2681 rrCaNGM<)sGK^$dGDlM$GQ.XBGM)rqGQ.XBGQ.UBg&6*qs4R?pd/X!u!!'Uc!M9>]g]<uHr;Qeh
2682 !;c]rN;rV,"J,Vj<E4P~>
2683 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7UlH!7UoI!7UiG
2684 !7U?9s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH
2685 !7UlH"Od>Ne'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH!n..ur;ZoJ!7UlH
2686 "Od>Ne'n!j!7UlH!n.,Lr6kWGqpYQF#1ES$!7Lqsr;ZoJ!7UlH!7U35!7UiG!7UlH"4I5Me,04F
2687 e*$c3e,97Kdf9Bsq#CEDrVurIr;ZrK!!(L@!!(LH!!(LH!!(LI!!(LH!!(L?!!(L6!!(LH!!C[M
2688 !7U`D!7UoI!7UlH"4I5Me+<Y<dfBHtr;ZoJ!7UlH"4I5Me,04Ce,KFJe,04Ge+`qC,6([0s,YC\
2689 rrB+uGM<)sGK^$dGDlM$GQ.XBGM)rqGQ.XBGQ.UBX8R5Cs/Z*Bd/X!s!!'Ua!Lj&Yg&[WBr;Qed
2690 !;c]rM?!;'"I]>f<E4P~>
2691 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7UlH!7UoI!7UiG
2692 !7U?9s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH
2693 !7UlH"Od>Ne'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH!n..ur;ZoJ!7UlH
2694 "Od>Ne'n!j!7UlH!n.,Lr6kWGqpYQF#1ES$!7Lqsr;ZoJ!7UlH!7U35!7UiG!7UlH"4I5Me,04F
2695 e*$c3e,97Kdf9Bsq#CEDrVurIr;ZrK!!(L@!!(LH!!(LH!!(LI!!(LH!!(L?!!(L6!!(LH!!C[M
2696 !7U`D!7UoI!7UlH"4I5Me+<Y<dfBHtr;ZoJ!7UlH"4I5Me,04Ce,KFJe,04Ge+`qC,6([0s,YC\
2697 rrA#VGM<)sGK^$dGDlM$GQ.XBGM)rqGQ.XBGQ.UBN;[r$s,?o#d/X!n!!'U\!KmEPeH(d4r;Qe[
2698 !;c]rK)bPp"H`]\<E4P~>
2699 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee,9:De,97He*d8:
2700 e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+WhBe,97He,97H
2701 e,9:He,B=Ie+s%Ee,97He,97He,97He,B=Ie,97He,B=Ie,97He,97Jdf@kq!!:ULe,97He,9:H
2702 e+`nCe,97Jdf@kq!!:ULe+s%Kdf@hsdf@kq!!:ULe,97He*6o5e,01Ge,97Kdf9Bsqu?iJ!!(L4
2703 !<:OI!!C[M!7U`D!7UoI!7UlH"4I5Me+E_@e,B=Ie,97He,B=Ie,97He+<V?e*@#6e,B=Ldf9Bs
2704 q#CEDrVurIr;ZrK!!(L@!!(LH!!:ULe,97Jdf@kq!!C[M!7UiG!7U]Cs3plGs3pfEs!%JCm/N-j
2705 hZ!\>GJO.0s8R;ds8R:ts8R;qs8R<=rs=d2_#464OE\M<ci<mt!!*#R"JI7H'4_!r"fEdO'4Cn<
2706 g_'U_.0UTFY:TquTA85K:D![MFoL/"V^V]]@0#`N"J5YKgh?Na!,2;c!M0;hrrJ\kqYpSTs7Y4N
2707 ScJXf<Ib~>
2708 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee,9:De,97He*d8:
2709 e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+WhBe,97He,97H
2710 e,9:He,B=Ie+s%Ee,97He,97He,97He,B=Ie,97He,B=Ie,97He,97Jdf@kq!!:ULe,97He,9:H
2711 e+`nCe,97Jdf@kq!!:ULe+s%Kdf@hsdf@kq!!:ULe,97He*6o5e,01Ge,97Kdf9Bsqu?iJ!!(L4
2712 !<:OI!!C[M!7U`D!7UoI!7UlH"4I5Me+E_@e,B=Ie,97He,B=Ie,97He+<V?e*@#6e,B=Ldf9Bs
2713 q#CEDrVurIr;ZrK!!(L@!!(LH!!:ULe,97Jdf@kq!!C[M!7UiG!7U]Cs3plGs3pfEs!%JCm/N-j
2714 hZ!\+GMN/Ms8R;ds8R:ts8R;qs8R<=rs=*th#79QI<XKFci<mr!!*#P"F_<l*.Rq@"b7No*.7ha
2715 g(FC7*!7OjL`Z^K`S0%Y4UVECO8di:J/\S1I/r]h"IfAEg1U6^!,)5`!La#drrJPgqYpSQs7Y.L
2716 RK34b<Ib~>
2717 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee,9:De,97He*d8:
2718 e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+WhBe,97He,97H
2719 e,9:He,B=Ie+s%Ee,97He,97He,97He,B=Ie,97He,B=Ie,97He,97Jdf@kq!!:ULe,97He,9:H
2720 e+`nCe,97Jdf@kq!!:ULe+s%Kdf@hsdf@kq!!:ULe,97He*6o5e,01Ge,97Kdf9Bsqu?iJ!!(L4
2721 !<:OI!!C[M!7U`D!7UoI!7UlH"4I5Me+E_@e,B=Ie,97He,B=Ie,97He+<V?e*@#6e,B=Ldf9Bs
2722 q#CEDrVurIr;ZrK!!(L@!!(LH!!:ULe,97Jdf@kq!!C[M!7UiG!7U]Cs3plGs3pfEs!%JCm/N-j
2723 hZ!\(GNo+[s8R;ds8R:ts8R;qs8R<=rs=!ql2L__H?\WQci<mm!!*#K"CDcD.%U=e"^quF.%C;7
2724 eIhjh&dL;4B+tM6c.1@1/I)P?WrCNP@1`SiS,i!-"Hi`7eR\LV!+c#X!KdB[rrJ5^qYpSJs7XtG
2725 OT>5X<Ib~>
2726 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LC
2727 !!(LG!!(L;!!(LE!!C[M!7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5M
2728 e+WhBe,01Ge,B@IdfBHtr;ZrK!!(LF!!(LG!<:OI!!(LH!!(LI!!(LH!!C[M!7UiG!7UoIs3h#L
2729 e'n9r!n..urW)uI!<CUI!!(LD!!(LI!<:LK!7UoIs3guKe,97Qdf9Bs!7Lqs!7UlH!n..ur;ZiH
2730 l2Uh5qu?`Gr;ZrK!!(LG!!(LI!!(L5!!1OKrmUiH!7U`D!7UoI!7UlH"4I5Me,B=Ie+itEdfBBr
2731 qu?`GrVurIrW)uIq#CEDr;ZiHlMpt7!<1IH!!(LD!!(LI!!(LH!!C[M!7UoI!7U`D!7UoIs3guK
2732 e,B@IdfBHtrW)uIrr<&Jqu?`Gr;ZoJ!7UlH!n..ur;ZiHqZ-X?s&JFcO3HJ\!dJqgf`1tqbQ%Td
2733 LB%9tf`1tqq>[email protected]!dJqgcN!ds&cg_B^^-7X^G]$GgqjAdf>'HJqqN+j(9uP]!uJ5qRLn90
2734 7U+$g]40RN_?l[_^cMPag]a;Lgt^X[qu?ang\fh-ScJ]g!M0;frrJ)Yp=oeB!;fbrJ,~>
2735 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LC
2736 !!(LG!!(L;!!(LE!!C[M!7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5M
2737 e+WhBe,01Ge,B@IdfBHtr;ZrK!!(LF!!(LG!<:OI!!(LH!!(LI!!(LH!!C[M!7UiG!7UoIs3h#L
2738 e'n9r!n..urW)uI!<CUI!!(LD!!(LI!<:LK!7UoIs3guKe,97Qdf9Bs!7Lqs!7UlH!n..ur;ZiH
2739 l2Uh5qu?`Gr;ZrK!!(LG!!(LI!!(L5!!1OKrmUiH!7U`D!7UoI!7UlH"4I5Me,B=Ie+itEdfBBr
2740 qu?`GrVurIrW)uIq#CEDr;ZiHlMpt7!<1IH!!(LD!!(LI!!(LH!!C[M!7UoI!7U`D!7UoIs3guK
2741 e,B@IdfBHtrW)uIrr<&Jqu?`Gr;ZoJ!7UlH!n..ur;ZiHqZ-X?s&JFcO3HJ\!I/h?s8R;ds8R:t
2742 s8R;qs8R<=rrI@grVlnCGKp0bg(FD>g6*)Mf;oRJg=hl.YLfrm!;kIh!&_OAEsFV<eT3%jg(K+c
2743 eZDBrg6WPXf<5nhmb.i5s4Z2[:Ab(m:>,R!!La#drrJPgqYpSQs7Y.LRK34b<Ib~>
2744 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LC
2745 !!(LG!!(L;!!(LE!!C[M!7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5M
2746 e+WhBe,01Ge,B@IdfBHtr;ZrK!!(LF!!(LG!<:OI!!(LH!!(LI!!(LH!!C[M!7UiG!7UoIs3h#L
2747 e'n9r!n..urW)uI!<CUI!!(LD!!(LI!<:LK!7UoIs3guKe,97Qdf9Bs!7Lqs!7UlH!n..ur;ZiH
2748 l2Uh5qu?`Gr;ZrK!!(LG!!(LI!!(L5!!1OKrmUiH!7U`D!7UoI!7UlH"4I5Me,B=Ie+itEdfBBr
2749 qu?`GrVurIrW)uIq#CEDr;ZiHlMpt7!<1IH!!(LD!!(LI!!(LH!!C[M!7UoI!7U`D!7UoIs3guK
2750 e,B@IdfBHtrW)uIrr<&Jqu?`Gr;ZoJ!7UlH!n..ur;ZiHqZ-X?s&JFcO3HJ\!I/h?s8R;ds8R:t
2751 s8R;qs8R<=rrI@grVlnCGKp0beIhl4ePA'5d#eUFe^[VZ]$Q`K!;k:c!+!Ue3?2>EauOCjeHhYj
2752 c'g-4ePnQ?d$=q;maVK's4,ZL9`+kk9[s!j!KdB[rrJ5^qYpSJs7XtGOT>5X<Ib~>
2753 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe+`nCe,B@F
2754 e+*M9e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He+NbAe,'.EdfTU!!!)uHrVurIqZ$WF
2755 qu?cH!<1IH!;t:H!7UlH"4I5Me,'.Edf]["!7LrIe,B@HdfTU!!!)uHpAk3A!s$dM!<1FL!7LoJ
2756 rR:`G!7UoI!n.,LrR:cH!7UlH!7U35!7UfFrR:`G!7UiG!7UlH!7U66!7UcE!7UfFr6kZHe,97H
2757 e,B@He+`nCe+s(Be,KFIdfBHtp]19Al2Uh5q>^NEqZ-QC!<CUI!!(LI!<1IA!<1FL!7LoJrmLrL
2758 df9CIdf]["!!(LF!<(CG!<(CG!<(CC!<48C<UBbTbR0(]%K[+tJBZ4;!;t(@!<14B!"6qZ&e%da
2759 a^,Ve7`t_Srr<GL@hK2MbfO0)#tE):bQb:S*Wug$HMu(f!!gY]('2,L"hjlY"3W:sAb=4:s8R9F
2760 rk=)2rr35YTRqHBW:']^G6e/pRXf[7R`sdks*+JB#QDu7IX6mXq>UC!q5f*qT_!AOirAk!s8W+C
2761 "9-#gGlI^Ign97EKW+>;rs%8OJpE$Jmc+6Xrm@*^HB?/Hs8L90IX6mXq>UEoG74D\K7C-*rO.B-
2762 V>gJos*"kM\V#C9s8BBZIAQrBs8R<Cs8$s!rs/D'JUX<bGBa&ds*"JCoQS[^qqM;SgtZ(FrnI\#
2763 $JaEBB`?cfbQ.Oq%KN-Vgt;\#gt^QbgtWFFqqM3XB`?cfbQ.(d!M9>jg]?"erVusZfDF>(ScJ]g
2764 !M0;frrJ)Yp=oeB!;fbrJ,~>
2765 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe+`nCe,B@F
2766 e+*M9e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He+NbAe,'.EdfTU!!!)uHrVurIqZ$WF
2767 qu?cH!<1IH!;t:H!7UlH"4I5Me,'.Edf]["!7LrIe,B@HdfTU!!!)uHpAk3A!s$dM!<1FL!7LoJ
2768 rR:`G!7UoI!n.,LrR:cH!7UlH!7U35!7UfFrR:`G!7UiG!7UlH!7U66!7UcE!7UfFr6kZHe,97H
2769 e,B@He+`nCe+s(Be,KFIdfBHtp]19Al2Uh5q>^NEqZ-QC!<CUI!!(LI!<1IA!<1FL!7LoJrmLrL
2770 df9CIdf]["!!(LF!<(CG!<(CG!<(CC!<48C<UBbUbR;R4-j]qg6C,j>!!)r@rrE&Brr<DH9+2JP
2771 bf36a%Uf7Zrr<DH9+2JPbf36a%Uf7Z#+S:$!Y.,PrQP9A#KK^P!ic5-ao0EcapS3KoZZk*s*"SC
2772 XakZqrs-i;J9m'[qu?M:#QDT'I<gL@gZ&85GQ.UIrP4MBI$)8Drr35nTRDBnr-*AEs8$s>s8R9F
2773 r2kKorr32JR=KU?[JTq&#0rWeHAT',ir9Sh_NB1mR+;6:rP4MBI$)8Drr<"B$N-lQKYd]cW.9E-
2774 rVunA$N-lQKYd]cW.9E-rVunAs8Vq>ir98STRDBnr-*Aas8R9Cs7CN^s81LQ!8?-AZMrP]Ync!H
2775 (UX1q!OMk(g(",+g=k'WbM(\#"PVQ3d/2Mt(UX1q!OMjpg&[ZBrn7D'3;rmY37[o[!La#drrJPg
2776 qYpSQs7Y.LRK34b<Ib~>
2777 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe+`nCe,B@F
2778 e+*M9e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He+NbAe,'.EdfTU!!!)uHrVurIqZ$WF
2779 qu?cH!<1IH!;t:H!7UlH"4I5Me,'.Edf]["!7LrIe,B@HdfTU!!!)uHpAk3A!s$dM!<1FL!7LoJ
2780 rR:`G!7UoI!n.,LrR:cH!7UlH!7U35!7UfFrR:`G!7UiG!7UlH!7U66!7UcE!7UfFr6kZHe,97H
2781 e,B@He+`nCe+s(Be,KFIdfBHtp]19Al2Uh5q>^NEqZ-QC!<CUI!!(LI!<1IA!<1FL!7LoJrmLrL
2782 df9CIdf]["!!(LF!<(CG!<(CG!<(CC!<48C<UBbUbR;Bq+9hug:oqmb!!)r@rrE&Brr<D:2[::a
2783 bc`l/(P)J.rr<D:2[::abc`l/(P)J.#)PGQ";F;.rQP9A#J!#("_Rfbb5KNd^]jeQoZZk*s*"tD
2784 TR;(cs8KitI=.-orVu_<#PtieH[:OMlJhjDGQ.UIpp,d'I[JF[rr35ZQ$\4trc`SGs8$s>s8R9P
2785 nt:AVs8W)7P'q_>_u9T7#QDQ&I=.-orSmhgqR)6-I\Q$*s7imWH@D7,rr2rtG7*o2I#6MUm$`<V
2786 bl.SAG7*o2I#6MUm$`<Vbl.SAGQ7^>GN/W-hj/VC^&E5"rr<"B!<;\8d/X!n"9@!&$H2qo"^tK_
2787 eI0@qeH'1\qpc/VcdgR[!703G^(SuH!n$nq!=QmGeH'1\maV?#s8LOLco:q(!B8C&eH(d4r;Qe[
2788 !;c]rK)bPp"H`]\<E4P~>
2789 s!!!oc2[jnhZ*Z*JH28A!7TR#!7T'j!7RYBs!%JCm/QV"!/C=Ms31KCr650@rlkBB!-A)=!EN(r
2790 !!#:`bl7YCF8Z(><`/eq!'pP-qZ$Wt?N/1K!!dEB!!1;K!&XYu!j2M2o??b)s*"[`GB\<3s1nMU
2791 !IjM6G6$"dGN/Z&GQ7[Dril9D"GHRMrKI2(!etoCirAk!s8W+C#/PM-GlRfZqf`0ln,NF'qf`'i
2792 n)XKLrj2KG!rr8(qf`6tq#CA<GJsH(!O8d*G6"B:s8R9C`;Ol\Z*!tK!2BJms*+MCqKM!"!WA;^
2793 G63MCGQ.XBG6%[8GL6Beg]RW4g^MF+g]cC5gtW@^rnIP.!;kOP!8IM.!<CmRg]mi7gm/1@K!kU5
2794 !=d6Og]?+/mb@i7s8C^UcS#8OchcDtScJ]g!M0;frrJ)Yp=oeB!;fbrJ,~>
2795 s!!!oc2[jnhZ*Z*JH28A!7TR#!7T'j!7RYBs!%JCm/QV"!(Zkcs31KCr650@rlkBB!&siV!Lb52
2796 !!%WMbl7YC2uN^WRNh\1!.t3oqZ$WtQN#,.!!bC^!!1:b!-\=b!e(+fo??b)s*"[:GB\<3s/#U:
2797 !K$^MG6"N:GN/Z&GQ7[DrKR2'"I8rcqLAHf!h=IYirAk!s8W+C#+Kg\GlRf?qf`1"qu?\mqf`'t
2798 qrIbXrg<S,!rr4`qf`70rVunAGF\VU!Sre7G6#nes8R9CSGdX4h2_GX!6tNCs*+MCqKM!"!W%?F
2799 G64=ZGQ.XBG6%[8GL6Beg&qE0g&ot+g'-(1g=cY\rn7D(!;kIM!<(UO!<(UV!8?.1&6jt-rn7AT
2800 fDaJ)ec>-l!Lj&eg'#YR!&)Ung&[WBr;Qed!;c]rM?!;'"I]>f<E4P~>
2801 s!!!oc2[jnhZ*Z*JH28A!7TR#!7T'j!7RYBs!%JCm/QV"!$:t:s31KCr650@rlkBB!#GM5!ON@8
2802 !!'5%bl7YC(B"46Zk!$7!3cCGqZ$Wu[f4MN!!a8>!!:@R!36"A!]g<^o??b)s*"[$GB\<3rJpc!
2803 !MTJgG6!QtGN/Z&GQ7[Dpk/Hf"Kqb(l$NAQ!lT;,irAk!s8W+C#).8FGlR`&qf`1:rVuhVqf`(7
2804 rT*tZq1\]i!rr%Jqf`7Irr<"BGD?'?!UkU<G6%"/s8R9CLAc;smt(F]!:9^bs*+MCqKM!"!UG+2
2805 G65^,GQ.XBG6%[8GL6BeeH>m&eH48"eHNr%e^X`Mrm_%f!;k:H!<(FJ!<(FQ!7fUR,%HYVrm_#N
2806 e,Iku_uT5U!KmE\eHErG!%u@heH(d4r;Qe[!;c]rK)bPp"H`]\<E4P~>
2807 s!!!oJH16$`rH+gfDkp#aoDFjU&b3;s&JFcn]V@Q!)'W?_OXHGbQ%Y@bl7\Bbl7YN%\Car!!Nk(
2808 aG'[%rlkBB$P&cLL&_AeT#cWd$NA6S,)!PN^5i7$rlkBB%L7[*bfm[!"hMq%b:Wcoo??b)s*#*'
2809 chd\Am!!j!oD\*WGE;e(GBa&d#D.0!meut>X5a0ZGQ7[Vk]_<gp&*['GF&9eGC8!>m[JEEiW&q%
2810 qu?\?)19d,s8VG0I*)!Zm&P>ks6OrWan,MuX*9Wcs!$ZNH+ibHlE^HRGBq$tr8*9SQN-u/GCe]M
2811 d<Bnfi;CuHIfBBIG7/u[r6]_7J`-IRGCKPks*+JBs**B##iTuTebng'GBa&ds*+JBs*+GAs*)`f
2812 qqM;SgtW=^rnI\2!o2Q?bPp8tg&V$*!!)uQ!!)uQ!!*#R#f2$k)+WK;%Enb+!SRPAg]=#Hr7h@r
2813 50E]V!M0;hrrJ\kqYpSTs7Y4NScJXf<Ib~>
2814 s!!!oJH16$`rH+gfDkp#aoDFjU&b3;s&JFcn]V@D!-5Zn^QCM"bQ%Y@bl7\Bbl7YN,-]'p!"1!T
2815 `aAc^rlkBB$R2gp?iUQYYf:&N(B2M_3g@J'\U4AmrlkBB%M5)Mbflj_$-:?7apS3>o??b)s*#*-
2816 h>I<Qc?Frmq#09=GI.>LGBa&d#C:U3oD\I9SDsSKGQ7[V_KUCTq>&EcGJO6_GD,&UjFh`$iW&q%
2817 qu?\?)1p]Bs8UAgK\#qsjHXqqs3>hAf(f4)Q$9Rqs!#=(Hd)3]ihHIiGC7g6q9aS6_#OFYGE2%e
2818 [s*:]m/+89L&V,PG70GtqmUcuNpQYPGD6%rs*+JBs**B##d\`-j8J"iGBa&ds*+JBs*+GAs*)`f
2819 qq;/Qg=cY\rn7P-"5;H2fDaJ)f)Y^%!!)uO!!)uO!!*#P#d/>C$>nMN"5!P+!S7>>g&[ZBr7V4n
2820 503QR!La#drrJPgqYpSQs7Y.LRK34b<Ib~>
2821 s!!!oJH16$`rH+gfDkp#aoDFjU&b3;s&JFcn]V@B!/\M6\:GgIbQ%Y@bl7\Bbl7YN9"_nh!"qo:
2822 ^FK:frlkBB$VJ(H.f^2S]Y>rs>5l_N;P1qMZ<dN5rlkBB%PXj(bfjDo--FHU^]jeLo??b)s*#*B
2823 kPkM]U3E!_qYT!!GMrN$GBa&d#C1OAp\sa.NT1!<GQ7[VQZn>Dr:RmOGN]!cGFS$uepM[ciW&q%
2824 qu?\?)40Ocs8Sg;R,Ii<g4OV-s.X_)i;3?)K6Q87s!!hSLY;P#fTH3#GDb8TotbotkPtR+GH(6.
2825 P]qbZo_+MnZi:")G71DBp69cRWV#nKGI.;Ks*+JBs**B##`a+umJPL^GBa&ds*+JBs*+GAs*)`f
2826 qpbfLe^X`Nrm_1l%+Wl0e,Iku_uT\b!!)uJ!!)uJ!!*#K#b,Wo#bTYt!n7/!!Q5!+eH(g4r7(kd
2827 4N%!F!KdB[rrJ5^qYpSJs7XtGOT>5X<Ib~>
2828 s!!!oJH16$JH1B(s!%JCm/QV""ZQK<;g+r7bl7\@bl7\Bbl7YNHHaUT!!%>hbfKhdrlkBB$[U%@
2829 aT)<ebfn0/!rgCGYtGu>rVup"rlkBB!+,TI#ZLdYbfm3i#g2b_nc/W5!4De*!jQsgrVm*"GC9Gj
2830 GBa&d"e9e)Y/TJ[s8R<CrrT6FX8W&&n99<\UNa3HrrVk;GN&T%GPhF?G6#&LrrTHL`Vof@r-*Pg
2831 Z$41crrW+BI,t;/WHYB>rrT6FX8W&2n99<\s*&\/s8W%AGKKmbrHEPds8R9NaoDD>GB_1/[email protected]
2832 rr<"Brr<"Bhu<bRGIIMN!q^\\rr<"Brr<"BrVunAc2[[r"9@64=_Rfi"j@>/gg+Xng]>V!qqM/O
2833 rS.AQrS.AQqqMA+"5M[;C&ZlgbQ.(d!M9>]g]<uHr;Qeh!;c]rN;rV,"J,Vj<E4P~>
2834 s!!!oJH16$JH1B(s!%JCm/QV""V(Mn>(*UQbl7\@bl7\Bbl7YN[`lt6!!'IObesJbrlkBB$b":'
2835 _uKeGbfn!*"oc^JQp),brVup$rlkBB!2f\<#9!S^bfkJ8'(X9:s8R9Cjo,2\Km2t`rs&7BJcGao
2836 GQ.UGJ9RQjb3\'ds*+MC!ebdOrVm)TGD#pIGNf&+!p=cOiW&q%qu?\?!9O1Z!ekjdrVm)sGCfdJ
2837 GOGG0!r-tjjSo:6GM2ln!ebdOrVmM`GD#qqGB`TWs8$q`nc/XcGC'8gs*"k@s8Vq>GOb_5qKI8b
2838 s8R<Bs8R<#rrRdrk5PA^j`bqJs8R<Bs8R<As8R;fs81LQ!8?-AZi8Y^ZPD3J(:F.q!OMk(g&M-O
2839 g&M-Og&M-Mg',Y&g=d=Mrn7C[!:JPARfDp3!La#drrJPgqYpSQs7Y.LRK34b<Ib~>
2840 s!!!oJH16$JH1B(s!%JCm/QV""U4rl@YDGnbl7\@bl7\Bbl7YN_T^6(!!'m[bc1XWrlkBB$c:-3
2841 WW3%9bfm'e'`Q;YIkhK8rVup.rlkBB!5/6R#7CO1bfi'I6h8Iks8R9Co_ndkIWtScrs%G+T`>%9
2842 GQ.UGHZu3och65rs*+MC!e#:^rVm)%GH(UiGP1t8!k3AtiW&q%qu?\?!;-6i!e,@grVm)\GG+tb
2843 GPM.:!o\?rjSo:0GOYM0!e#:^rVmM1GH(WBGB`l_s6+ZNq>^KYGD,tqs*"kHs8V;,GPV:=k]_^Z
2844 s8R<Bs8R<#rrRRlp&=sm[<Hios8R<Bs8R<As8R;fs81=L!7fU,`W"Bk@oq42$HE(q!G)9.eGoUJ
2845 eGoUJeGoUHeHM`]e^Y#Hrm_$\!:JA<OoOt%!KdB[rrJ5^qYpSJs7XtGOT>5X<Ib~>
2846 s!!!oJH16$JH1B(s!%JCm/QV"!P0WW!!WHKWQ`Qd!;t(@!<14B!!((=bl7YCa8X9`!!3)Crr<&>
2847 rlkBB!6>)_"TSSIbd7HJ!<14B!!'b2bQk]Z"LlQ*!(HJ&nc/W5!;6<j"+bZAH2`'gG6E0js*&\d
2848 rrM_Qrc\EgNp,L&s*+MC!eGRdrVm*$GBj.<GP(n7!rdCfiW&q%qu?\?!;6<j"+bZAH2`'gG6N6k
2849 JTlBbrcnHe!-mT)!e,@bqu6_KGOk_4#QApls8R:er;Q`rG6%R?rrI=grr<"B!;uirs*"J@rr3"C
2850 GlIaCGQ.XBGMiE%J9UYbrrW1DGQ.XBGQ.XBGQ%RAGKp0bg_'VBgqX5aft]UHgt]^PSCt_B!;kOO
2851 !<([Q!<([b!8Q?UOj2RW$/F=P$(T\b4ok$+!M9>]g]<uHr;Qeh!;c]rN;rV,"J,Vj<E4P~>
2852 s!!!oJH16$JH1B(s!%JCm/QV"!M'l&!!WHa_T^4(!;t(@!<14B!!(4Abl7YCbPo]d!!3)Crr<&B
2853 rlkBB!6bAc"TSSIb`2`#!<14B!!(.=bQj^>#fk$p!06Wonc/W5!<)lr"+#0:H2`'gG6E3ks*&\d
2854 rrM&1rc\EgSb_:Fs*+MC!d](grVm*"GBs46GQ%O@!rR7diW&q%qu?\?!<)lr"+#0:H2`'gG6N9l
2855 H?XX[rcnHe!.!Z*!dT"fqu6_DGPqF>#Q/dks8R:err2rtG6%XArrI=grr<"B!<2uts*"JBrr3"C
2856 GlIaCGQ.XBGMiE%H$B5drrW+BGQ.XBGQ.XBGQ%RAGKp0bg(FD>g6!)PfWGpPg=hl/Z.Q8r!;kIM
2857 !<(UO!<(U`!8?-kU!_AL'\_9-(9uMr('*dV!Lj&Yg&[WBr;Qed!;c]rM?!;'"I]>f<E4P~>
2858 s!!!oJH16$JH1B(s!%JCm/QV"!HnbJ!!WI%aNVj.!;t(@!<14B!<11Db5_PAbQ>rf!WL=C!<11D
2859 b5_PAbQc5j!R/bj!Vufqbl7YCb5BHg<raDd^BO\Eo$$Y(s*"JBrVltEGBnK5GlMsjIK0=kGQ.UC
2860 `dIc0!dLjFirB%&s8N.GGQ.R@#4Znds*/berr3&lGB`$Gs*+A?s*"JBrVltEGBnK5GlMskIK+P9
2861 H$TC6s*"HkjSo:+GQ.L>!dT"hrVm)lGCKSlGBa&d!rdCfrr3'!GBj,es*+JB!rdCfrr3'!GBj,e
2862 s*+JBs**B#!dJqgrr3&lGBa&ds*+JBs*+GAs*)`fqpc;Ze^[GS\^H]J]%,>14M9+/#lskQ!!)uJ
2863 !!)uJ&HLA3<N=Hg@7A_s<'7hAQO*Z[eH(g4n^RZ&!;uitOT>7X!J:@FeHD!7qGgOG~>
2864 s!$b/!7U66s3pH;qpYQFrR:cHqpYHC!7UoIrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=
2865 !7U'1!n..ukPtV3qZ$]H!7U!/s3os-!7S(N!7S=U!7UB:!n..ui;`l,lMpq6lN$t6q#LF=s&JFc
2866 nB;9`UioKK!#*T#!<C=Abl7\Bbl7\Abl7\Abl7\Bbl7\Abl7\Abl7\CbQpZ<25\76b5_PAbl7\>
2867 bQ^]?0!,*X`:D.Bs8R<@rr@NCGQ7^CGQ%OGroD)"L3J=1s8R<CrrRaqo)8Rmrc`VeJ9UYbrrW1D
2868 GN&T%GPhF?GPqI@Ie\*fs*j`ejSo:1GOt_3!eGRdrVm*$GBj/fGBa#cs*+GAs*+JBs*+GAs*+GA
2869 s*+JBs*+JBs**B#!e>Lerr3'!GBa&ds*+JBs*+GAs*)`fqqM/OrnIXL.0C2lrS.RS-j(,j!W1XP
2870 !<([Q!<([Y!8QA<7LBARTDmULV^MW\?if]N!M9>]g]<uHr;Qeh!;c]rN;rV,"J,Vj<E4P~>
2871 s!$b/!7U66s3pH;qpYQFrR:cHqpYHC!7UoIrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=
2872 !7U'1!n..ukPtV3qZ$]H!7U!/s3os-!7S(N!7S=U!7UB:!n..ui;`l,lMpq6lN$t6q#LF=s&JFc
2873 nB;6^R;PJ#!%uL>!<E)B!m1KCrlkBBrQP9ArQP9ArlkBBrQP9ArQP9As3(`]!+)hJbfTncrlkBB
2874 qTK-Z!,R#_%*J.bnc/W5r;QbBpilc<s*+GA#6*GpV1!QRirB%&s8N.HGPqF>#5i[js*8herr3&u
2875 GB`$Gs*+A?s*+D@!."?`!WRH?GNAc*H$B2`rrRLjr;HX"r-*Gds*&\cs8R<As8R<Bs8R<As8R<A
2876 s8R<Bs8R<Bs8R<#rrRIirVlfur-*Aas8R<Bs8R<As8R;fs81LM!<1[TI2`2+If7t(Ii8A.H3=&u
2877 !!)uO!!)uO#QWT4RPY0U5/7*N"b.El*-q_Tg&[ZBn_+#4!;uitRK33a!K$jMg'!iEqc-XH~>
2878 s!$b/!7U66s3pH;qpYQFrR:cHqpYHC!7UoIrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=
2879 !7U'1!n..ukPtV3qZ$]H!7U!/s3os-!7S(N!7S=U!7UB:!n..ui;`l,lMpq6lN$t6q#LF=s&JFc
2880 nB;6YO(UNW!-ZT1!<E)B!lY->rlkBBrQP9ArQP9ArlkBBrQP9ArQP9As3(`S!-krnbejD\rlkBB
2881 qof;f$36q_!&Dagbjk`5GPqI@GkcL_s8R<Ars&>N]UjFn`T$ptGQ7[EH$B8drs&%<IfFY:rr2p!
2882 oQPN<s8R<?s8R<@rr@<=G6._gpikg!!dJqgqu6_CGQ.R@#4ctes8R:erVunArVunArr<"BrVunA
2883 rVunArr<"Brr<"Bhu<b&GQ.UA!q^\\rr<"Brr<"BrVunAc2[[k!!*#K"C;]C-_:4d"^hlD-^=u7
2884 eGoUJeGoUJeHc0*eUAhI&l?dNeHK=l""0?>maV?#s7+V?OT>=Z!KdBYrrI`Op=0;.!;]\qJ,~>
2885 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFr;clHrr<&Jr;ZiHnc/[=r;[&N!!(IJ!7U04"4I5M
2886 e*m>>df9BspAb<E!!(L;!!C[M!7UZB"4I5Me+3P>e)gW3df@kl!!(L=!!(LF!!:ULe)LE.e)C?-
2887 e("Eue,97He*?u6e,97He,01Ge("Eue)C?-e*d8<df@kU!!(LA!!(LB!!(L5!!(LD!<48C<UBbP
2888 bQl,f!mJk(!1s26!l"^8rlkBBrQP9ArQP9ArlkBBrQP9ArQP9As3(NO!5AHV!keR6rlkBBqTK,P
2889 !!=_O2t>,^s8R<@rrT<Hd.mY@GPV7?qfd>Fs8R<CrrT6FXSr/'nTTE]UNa6IrrVk;GN&Q'H$B5b
2890 s8R<@rrT<Hd/!\CX`r.JrrT3EX8DnuX*:ZDrs&";IK0=kGQ%RAGQ%RAGQ.XBGQ%RAGQ%RAGQ.XB
2891 GQ.UDH$B5FrrT!?[f6:.oQPNYs8R<Bs8R<As8R;fs6AA?dg4pf!Rh>Bg]=#Hn_=/:!;uitScJWe
2892 !K@'Pg]X2Kqc-XH~>
2893 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFr;clHrr<&Jr;ZiHnc/[=r;[&N!!(IJ!7U04"4I5M
2894 e*m>>df9BspAb<E!!(L;!!C[M!7UZB"4I5Me+3P>e)gW3df@kl!!(L=!!(LF!!:ULe)LE.e)C?-
2895 e("Eue,97He*?u6e,97He,01Ge("Eue)C?-e*d8<df@kU!!(LA!!(LB!!(L5!!(LD!<48C<UBbP
2896 bQki^"O,'o!5\ZY!j2M'rlkBBrQP9ArQP9ArlkBBrQP9ArQP9As3(NG!6P5a!i>qtrlkBBqTK,0
2897 !!`i2IIYPOs8R<@rrRjtnbE.aGPV7?p31iBs8R<CrrRjtg\q-Vg382LJp6GXrrVD.GN&Q'G^'/b
2898 s8R<@rrRjtnbN1dKQltBrrRgsgACmOKQl2Lrs%2$KE(sqGQ%RAGQ%RAGQ.XBGQ%RAGQ%RAGQ.XB
2899 GQ.UDG^'/FrrRdrkPkJ_k')%Ks8R<Bs8R<As8R;fs6A;=`"Ct^!Q5T<g&[ZBn_+#4!;uitRK33a
2900 !K$jMg'!iEqc-XH~>
2901 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFr;clHrr<&Jr;ZiHnc/[=r;[&N!!(IJ!7U04"4I5M
2902 e*m>>df9BspAb<E!!(L;!!C[M!7UZB"4I5Me+3P>e)gW3df@kl!!(L=!!(LF!!:ULe)LE.e)C?-
2903 e("Eue,97He*?u6e,97He,01Ge("Eue)C?-e*d8<df@kU!!(LA!!(LB!!(L5!!(LD!<48C<UBbP
2904 bQj[=&Br?"!6>)_!c.i:rlkBBrQP9ArQP9ArlkBBrQP9ArQP9As3(NG!6bAc!b)-0rlkBBqTK+>
2905 !$)4CY49a+s8R<@rrRUmq=t!iGPV7?i-0e4s8R<CrrRUmnbrIlX*:NBI!>8_rrT]SGN&Q&G^'&b
2906 s*+D@!e#:gq>UMEGPU(p!e#:^qu6_GGObY3#-2sHs8R:erVunArVunArr<"BrVunArVunArr<"B
2907 rr3"DGMiE%I!>8_rrTTPGQ.XBGQ.XBGQ%RAGKp0QeH(1fiRIsZ6giJ*OoOt%!KdB[rrJ5^qYpSJ
2908 s7XtGOT>5X<Ib~>
2909 s!$b/!7U35!7U97"4I5Me,97He,01Ge,97Mdf@hs!7UlH!7UK=!7UlH!n..ur;ZiHlMpq6r;ZiH
2910 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,!@jo>M4!!(L4!!(LE!!:ULe)LE.e)C?-
2911 e'J'pe)gW1e,01Ge$T/Ue*m>>df9BsiW&u-l2Uh5l2Uh5q#LF=s&JFcn]VUdFfrg)O8o@+b[UVn
2912 Yf`n#!!*#BrrE#ArrE#ArrE&BrrE#ArrE#ArrE)C#VH*B]#p`r!!*#BrrDl="@E.h"MF9Knc/W5
2913 r;R5mGC7<or;H-5UAt7;GQ.UIMT+oZqU]q:irB%&s8NbrGC%1"r83EVQN,idIG"MdSTf;:rr\:*
2914 ]DMR,s*+D@'^U$k_s@7!nC"'2m!!iplhp_Nd\>h&(?fsf^@M9gZiB65HGfFRhhu]Es8R:erVunA
2915 rVunArr<"BrVunArVunArr<"Brr3(\GJ!b2rs7P,I+J8`RWiuTs8R<Bs8R<As8R;fs6eYG0X06L
2916 :c7@i"Yd16`DAG[g]=#Hn_=/:!;uitScJWe!K@'Pg]X2Kqc-XH~>
2917 s!$b/!7U35!7U97"4I5Me,97He,01Ge,97Mdf@hs!7UlH!7UK=!7UlH!n..ur;ZiHlMpq6r;ZiH
2918 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,!@jo>M4!!(L4!!(LE!!:ULe)LE.e)C?-
2919 e'J'pe)gW1e,01Ge$T/Ue*m>>df9BsiW&u-l2Uh5l2Uh5q#LF=s&JFcn]VV#K=B"<GlRukbSgIN
2920 ]?$BQ!!*#BrrE#ArrE#ArrE&BrrE#ArrE#ArrE)C#R^WL_T%]H!!*#BrrDo>"j7MY!"$d;bjk`5
2921 GPqIMcZb#enbr@Nad)o+GBa&d#FNg,rq=EWHK+u)GQ7[V_KUCVqYJWfGJO6^GD5/Xjb7o&iVs".
2922 GM<#os8R<@rtNe'K?j#cqs2@hs3GnAcLLl1lcGFQrt`LrHd;EaihQOjGC7m9qU0b8_#OFYGQ%RA
2923 GQ%RAGQ.XBGQ%RAGQ%RAGQ.XBGQ.UEI<XEDiVs1hGD"uUj+DQ"rr<"Brr<"BrVunAc2[4c"];qc
2924 [3fqUg'(?dfsN/Imb.]1s7+eDRK39c!La#brrIuVp=]Y<!;fbrJ,~>
2925 s!$b/!7U35!7U97"4I5Me,97He,01Ge,97Mdf@hs!7UlH!7UK=!7UlH!n..ur;ZiHlMpq6r;ZiH
2926 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,!@jo>M4!!(L4!!(LE!!:ULe)LE.e)C?-
2927 e'J'pe)gW1e,01Ge$T/Ue*m>>df9BsiW&u-l2Uh5l2Uh5q#LF=s&JFcn]VV7P.o,L;ZI?PbR=Jg
2928 _o.67!!*#BrrE#ArrE#ArrE&BrrE#ArrE#ArrE)C#R19da2**,!!*#BrrDo>"j%#M!$o_Wbjk`5
2929 GPqIMUj&-Wo`"^L_283lGBa&d#Gp)Grpm49J`?_0GQ7[VQ?S;Fr:RsRGNSpbGFe4$fR7sfiVs"+
2930 GNf&)s8R<@rtM8QQItj/qW>VNs.jk)f_#1>k.uo8rt^uGM;%k'fTH3"GDtGWotu*"k5YI*GQ%RA
2931 GQ%RAGQ.XBGQ%RAGQ%RAGQ.XBGQ.UEH?\TPiVs1DGFS%!eU2Rbrr<"Brr<"BrVunAc2[4^"`)$(
2932 TF\0deHKa+d\%,QmaV?#s7+V?OT>=Z!KdBYrrI`Op=0;.!;]\qJ,~>
2933 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHr;ZrK!!(LE!!(L8
2934 !!:ULe,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+E\Cdf9Bsr;ZoJ
2935 !!)uHrr<)K!<1IE!!LaN!7LrIe,9:He,B=JdfBBrqZ$WFrW)rH"9?mNdfBBrrr<&Jr;ZoJ!!)uH
2936 o`,!@r;cfFrr<&Jr;ZrK!7LrIe,B@Ge,KCKdfBBrklC\2rr<&Jr;ZiHrW)uIrW)oGp&G*ArVurI
2937 rW)uIrW)oGrVuuJ!<1IA!<(CG!<(CG!<(CG!<(CF!<:OH!<(CH!!1OKrmUTArR:cH!Rh&Je+<VC
2938 df9Bs!<1IH!<(CG!<:LK!7UoIrR:WD!7UoIs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`G
2939 q#LF=s&JFcn]^h0"!Gh3[ep+,+92E@bl7\Abl7\Abl7\Bbl7\Abl7\Abl7\CbQ+=6!!42A!<14B
2940 !;Xh@[/^1XnBCG&s*+A?!6P%\s8W+Crr;h=!0#q;s*+MC!WK;"G6ETns8A)YG63MCGiAZ&dJS4g
2941 s8R<?rrC1:GQ7[Can^/ArrN,(qf`,Aric3C"bcXMs*&\cs8R<As8R<Bs8R<As8R<As8R<Bs8R<B
2942 rrCIEGN8](rK[>*!etoCrr<"Brr<"BrVunAc2[4e"fa-V&6%3Bg]a]0!t\D_mb@i7s7+kFScJ]g
2943 !M0;frrJ)Yp=oeB!;fbrJ,~>
2944 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHr;ZrK!!(LE!!(L8
2945 !!:ULe,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+E\Cdf9Bsr;ZoJ
2946 !!)uHrr<)K!<1IE!!LaN!7LrIe,9:He,B=JdfBBrqZ$WFrW)rH"9?mNdfBBrrr<&Jr;ZoJ!!)uH
2947 o`,!@r;cfFrr<&Jr;ZrK!7LrIe,B@Ge,KCKdfBBrklC\2rr<&Jr;ZiHrW)uIrW)oGp&G*ArVurI
2948 rW)uIrW)oGrVuuJ!<1IA!<(CG!<(CG!<(CG!<(CF!<:OH!<(CH!!1OKrmUTArR:cH!Rh&Je+<VC
2949 df9Bs!<1IH!<(CG!<:LK!7UoIrR:WD!7UoIs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`G
2950 q#LF=s&JFcn]^h0"%pe]PPbC^8cSkjbl7\Abl7\Abl7\Bbl7\Abl7\Abl7\CbQ)/N!!5Rh!<14B
2951 !;Xh@OT5AsnBCG&s*+A?!3Z-As8W+Crr;h=!3+uXs*+MC!WA8[G6F30s8%3CG64:YH/\c'T_s$6
2952 s8R<?rrB4tGQ7[CY5*;&rrN(aqf`,ArKR2'"dT&ds*&\cs8R<As8R<Bs8R<As8R<As8R<Bs8R<B
2953 rrA_iGN8](qLJNg!h=IYrr<"Brr<"BrVunAc2[4c"c"0$(hq[bg'*6R!Z5Y)mb.]1s7+eDRK39c
2954 !La#brrIuVp=]Y<!;fbrJ,~>
2955 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHr;ZrK!!(LE!!(L8
2956 !!:ULe,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+E\Cdf9Bsr;ZoJ
2957 !!)uHrr<)K!<1IE!!LaN!7LrIe,9:He,B=JdfBBrqZ$WFrW)rH"9?mNdfBBrrr<&Jr;ZoJ!!)uH
2958 o`,!@r;cfFrr<&Jr;ZrK!7LrIe,B@Ge,KCKdfBBrklC\2rr<&Jr;ZiHrW)uIrW)oGp&G*ArVurI
2959 rW)uIrW)oGrVuuJ!<1IA!<(CG!<(CG!<(CG!<(CF!<:OH!<(CH!!1OKrmUTArR:cH!Rh&Je+<VC
2960 df9Bs!<1IH!<(CG!<:LK!7UoIrR:WD!7UoIs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`G
2961 q#LF=s&JFcn]^h0",P1F<r;q!IfKKJbl7\Abl7\Abl7\Bbl7\Abl7\Abl7\CbQ'9n!!7NJ!<14B
2962 !;Xh@8H8afnBCG&s*+D@!WJM_GQ7^CGQ.X=G6$(Ns8R<CrrMnIqf`1Grr;/-rHA=\GC8BL!/UPs
2963 s8W+Cr;QfsRJD%.s8JG^GNAc)pk8Ng!rr%Jqf`4Hrr<"BGQ%RAGQ%RAGQ.XBGQ%RAGQ%RAGQ.XB
2964 GQ.UBM#;JWrrMD3rHA=]GBa&ds*+JBs*+GAs*)`fmaVGR'*BD1jOFBH'*BD1mF;6"s7+V?OT>=Z
2965 !KdBYrrI`Op=0;.!;]\qJ,~>
2966 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LI!!(LI
2967 !!(LF!!(L8!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UWA
2968 !7UoI!7UlH!n..ur;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LI!<:LL
2969 !7TEr!!:ULe,97Jdf@kq!!:UL!;t=E!!(LD!!:ULe,97Kdf@kGrW!#K!7UlH"4I8!e,B=Ie+`q@
2970 e,KFGdfBHtr;[&N!!(IJ!7UiG!7UlH!7UfFr6tZG!7UoI!7UlH!7UlH!7UiGs3prI!n.,Lr6kZH
2971 e,97Jdf@kq!!:ULe,97Jdf@kq!!(LH!!(LI!!(LH!!C[Me'n9r!7U`D!7UlH"4I8!e,B=Ie+NbA
2972 e,B@Ie,B=Kdf@kq!"%*S!7Lqs!7Lqsr;ZiHr;ZiHr;ZuL!7Lqsr;ZiHrVurIr;ZrK!7TEr!!(LF
2973 !!:ULe,97He,97He+j"D,6([0s7+;<Z<e^Z"sI<nrlbV=.g?M[`rH,=bl7\Abl7\Abl7\Bbl7\A
2974 bl7\Abl7\BbQi\A!Y.oC!!*#BrrDl="2Y$?ZLH*.s8R<>rsS+oML0Z+Vq1nJGBa&d#OSpZH[Ca\
2975 r8RbVGQ.UIrlpaWHAT!'rr36!X+5VknTT<<rsAY8MgBSks8R:eqYpfcXbqIOM5Sr(rs.hkML0Z+
2976 Vq0o.&H9q>I!Upps8W)CQ@4(9ZhXP"s*+GAs*+GAs*+JBs*+GAs*+GAs*+JBs*+JB"oZ#jH?XSm
2977 rs/D&J:4']GBa&ds*+JBs*+GAs*)`fZePSQs7+kFScJ]g!M0;frrJ)Yp=oeB!;fbrJ,~>
2978 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LI!!(LI
2979 !!(LF!!(L8!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UWA
2980 !7UoI!7UlH!n..ur;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LI!<:LL
2981 !7TEr!!:ULe,97Jdf@kq!!:UL!;t=E!!(LD!!:ULe,97Kdf@kGrW!#K!7UlH"4I8!e,B=Ie+`q@
2982 e,KFGdfBHtr;[&N!!(IJ!7UiG!7UlH!7UfFr6tZG!7UoI!7UlH!7UlH!7UiGs3prI!n.,Lr6kZH
2983 e,97Jdf@kq!!:ULe,97Jdf@kq!!(LH!!(LI!!(LH!!C[Me'n9r!7U`D!7UlH"4I8!e,B=Ie+NbA
2984 e,B@Ie,B=Kdf@kq!"%*S!7Lqs!7Lqsr;ZiHr;ZiHr;ZuL!7Lqsr;ZiHrVurIr;ZrK!7TEr!!(LF
2985 !!:ULe,97He,97He+j"D,6([0s7+;<T2-@,#V'l<rlbUp*s39gb5_PAbl7\Abl7\Abl7\Bbl7\A
2986 bl7\Abl7\CbQuC'('57\aoDG@bl7\=bQG3P#0-/Vnc/W5qYprWUP4#ANj.OCs*&\drs.MaLj=B3
2987 _uAZqs*+JB#Q;H"H[LpjrVlg%n=G#YXS6peiVs5]XG2"EGQ7\eGP_=Eg7s@JI#bGjrr35WUP4#A
2988 Nj.O'rt,.CNI#u>ec5[J^lWnjOMLhos8R<As8R<As8R<Bs8R<As8R<As8R<Bs8R<Brrr;$L3[ue
2989 ir98STRDBmr-*Aas8R<Bs8R<As8R;fs0LD[RfDp3!La#drrJPgqYpSQs7Y.LRK34b<Ib~>
2990 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LI!!(LI
2991 !!(LF!!(L8!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UWA
2992 !7UoI!7UlH!n..ur;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LI!<:LL
2993 !7TEr!!:ULe,97Jdf@kq!!:UL!;t=E!!(LD!!:ULe,97Kdf@kGrW!#K!7UlH"4I8!e,B=Ie+`q@
2994 e,KFGdfBHtr;[&N!!(IJ!7UiG!7UlH!7UfFr6tZG!7UoI!7UlH!7UlH!7UiGs3prI!n.,Lr6kZH
2995 e,97Jdf@kq!!:ULe,97Jdf@kq!!(LH!!(LI!!(LH!!C[Me'n9r!7U`D!7UlH"4I8!e,B=Ie+NbA
2996 e,B@Ie,B=Kdf@kq!"%*S!7Lqs!7Lqsr;ZiHr;ZiHr;ZuL!7Lqsr;ZiHrVurIr;ZrK!7TEr!!(LF
2997 !!:ULe,97He,97He+j"D,6([0s7+;;NC"6Z$oNn?bQhSm"!E-<!!*#BrrE#ArrE#ArrE&BrrE#A
2998 rrE#ArrE)C#ff[M![3$:!!*#BrrDl="*=MZb4*XFs8R<>rsR)AJp;a.\aKLtGBa&d#1]K$G^l11
2999 iW&q%rr35uZAEmVQHfF.rs.>DHA0#qGE:__$14I=G^"B3s*&\`rs-f=Jp;a.\aKIs#L/cjG^bje
3000 mc4<Ypp,^#J>23+s7imVH@D1)rr2rtGQ%RAGQ%RAGQ.XBGQ%RAGQ%RAGQ.XBGQ.UGm@o2WGB`'H
3001 #Mt_lKY.5-GQ.XBGQ.XBGQ%RAGKp/oeH(g4n^RZ&!;uitOT>7X!J:@FeHD!7qGgOG~>
3002 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7UlH!7UoI!7UlH
3003 s3pB9s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH
3004 !7UlH"Od>Ne'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH!n..ur;ZoJ!7UlH
3005 "Od>Ne'mmg!7UlHr6kZHe,97Jdf@kq!!:ULe,'+Fe,97He*@#2e,B@Ie,'+Fe,97He+<VCdf@hs
3006 e,97He,97He,01Ge,97He+`qCe,9:De,KFJe,04Ge+s%Ee,B=Ie,97Jdf@kq!!(LC!<:OH!!(LH
3007 !!(LB!!(LH!!(LH!!:ULe,97Pdf9Bs!7Lqs!;k7E!!(LG!!LaNdf@kq!!(LI!!(LF!!(LH!!:UL
3008 !;t:G!;k7D!!(LD!<48C<UBa]bQ<k+,4EaHrrVV4J:[`Os7?8sh#IEEg]<uHr;Qeh!;c]rN;rV,
3009 "J,Vj<E4P~>
3010 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7UlH!7UoI!7UlH
3011 s3pB9s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH
3012 !7UlH"Od>Ne'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH!n..ur;ZoJ!7UlH
3013 "Od>Ne'mmg!7UlHr6kZHe,97Jdf@kq!!:ULe,'+Fe,97He*@#2e,B@Ie,'+Fe,97He+<VCdf@hs
3014 e,97He,97He,01Ge,97He+`qCe,9:De,KFJe,04Ge+s%Ee,B=Ie,97Jdf@kq!!(LC!<:OH!!(LH
3015 !!(LB!!(LH!!(LH!!:ULe,97Pdf9Bs!7Lqs!;k7E!!(LG!!LaNdf@kq!!(LI!!(LF!!(LH!!:UL
3016 !;t:G!;k7D!!(LD!<48C<UBa]bQ9j+<q"8'rrU_pM1P\Xs7?8sgAh3Cg&[WBr;Qed!;c]rM?!;'
3017 "I]>f<E4P~>
3018 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7UlH!7UoI!7UlH
3019 s3pB9s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH
3020 !7UlH"Od>Ne'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH!n..ur;ZoJ!7UlH
3021 "Od>Ne'mmg!7UlHr6kZHe,97Jdf@kq!!:ULe,'+Fe,97He*@#2e,B@Ie,'+Fe,97He+<VCdf@hs
3022 e,97He,97He,01Ge,97He+`qCe,9:De,KFJe,04Ge+s%Ee,B=Ie,97Jdf@kq!!(LC!<:OH!!(LH
3023 !!(LB!!(LH!!(LH!!:ULe,97Pdf9Bs!7Lqs!;k7E!!(LG!!LaNdf@kq!!(LI!!(LF!!(LH!!:UL
3024 !;t:G!;k7D!!(LD!<48C<UBa]bQ8X^S+"RlrrT!?^4H<8s7?8sec5[>eH(d4r;Qe[!;c]rK)bPp
3025 "H`]\<E4P~>
3026 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee,9:De,KCJe*R,8
3027 e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+WhBe,97He,97H
3028 e,9:He,B=Ie+s%Ee,97He,97He,97He,B=Ie,97He,B=Ie,97He,97Jdf@kq!!:ULe,97He,9:H
3029 e+E\@e,B=Ie,97Jdf@kq!!:ULe,97Jdf@ko!!(LH!!(L6!!(LD!<:OF!!(LH!!(L?!!LaNdf@kq
3030 !!(LH!!(LG!!(LH!!(LA!<:OJ!!(LC!<:OG!<:OG!!(LI!!(LH!!:ULe,97He+NeAe,KCJe,97H
3031 e+WhBe,97He,97Jdf@kq!"%*S!7Lqs!7Lqsq#CEDqu?lK!7Lqsr;ZiHrVurIqZ$WFr;ZoJ!7UlH
3032 !n..up](<Cq#LF=s&JFcV9B%X-38kibbG+BOOs=*h2-?GJcC<$oDbJT!!)rs!M0;fg]<B6p=oeB
3033 !;fbrJ,~>
3034 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee,9:De,KCJe*R,8
3035 e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+WhBe,97He,97H
3036 e,9:He,B=Ie+s%Ee,97He,97He,97He,B=Ie,97He,B=Ie,97He,97Jdf@kq!!:ULe,97He,9:H
3037 e+E\@e,B=Ie,97Jdf@kq!!:ULe,97Jdf@ko!!(LH!!(L6!!(LD!<:OF!!(LH!!(L?!!LaNdf@kq
3038 !!(LH!!(LG!!(LH!!(LA!<:OJ!!(LC!<:OG!<:OG!!(LI!!(LH!!:ULe,97He+NeAe,KCJe,97H
3039 e+WhBe,97He,97Jdf@kq!"%*S!7Lqs!7Lqsq#CEDqu?lK!7Lqsr;ZiHrVurIqZ$WFr;ZoJ!7UlH
3040 !n..up](<Cq#LF=s&JFcV9B%M$3@d-bbG+BU>c%Gd!U&]JcC<$oDbJP!!)rs!La#bg&['1p=]Y<
3041 !;fbrJ,~>
3042 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee,9:De,KCJe*R,8
3043 e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+WhBe,97He,97H
3044 e,9:He,B=Ie+s%Ee,97He,97He,97He,B=Ie,97He,B=Ie,97He,97Jdf@kq!!:ULe,97He,9:H
3045 e+E\@e,B=Ie,97Jdf@kq!!:ULe,97Jdf@ko!!(LH!!(L6!!(LD!<:OF!!(LH!!(L?!!LaNdf@kq
3046 !!(LH!!(LG!!(LH!!(LA!<:OJ!!(LC!<:OG!<:OG!!(LI!!(LH!!:ULe,97He+NeAe,KCJe,97H
3047 e+WhBe,97He,97Jdf@kq!"%*S!7Lqs!7Lqsq#CEDqu?lK!7Lqsr;ZiHrVurIqZ$WFr;ZoJ!7UlH
3048 !n..up](<Cq#LF=s&JFcV9B%9"TcU2bbG+BZK_>Z_0L7jJcC<$oDbJG!!)rs!KdBYeH(:%p=0;.
3049 !;]\qJ,~>
3050 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LC
3051 !!C[M!7U<8!7UcE"4I5Me*-i7df9Bsn,NR>!!(LG!!(LH!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bs
3052 pAb3Bqu?`GrW)uI!<CUI!!C[M!7UfF!7UiGs3prI!7UlH!7UoI!7UlH"4I5Me,01Ge,B@IdfKNu
3053 e,B=Kdf@kr!<:LK!7UlH!7UWA!7UoI!7UoIs3guKe,B@IdfBHtr;ZoJ!7UlH!n..ur;ZiHlMpq6
3054 r;[&N!!(IJ!7UiG!7UlH!7UoI!7U]C"OdA"!7UlH!7UlH!7UoI!n..ur;ZiHq#CEDr;ZoJ!7UlH
3055 !n..ur;ZoJ!7UlH!7UlH!7UoI!7UlH!n..ur;ZiHq#CEDr;ZoJ!7UlH!7U]C!7UiG!7UlH!n..u
3056 r;[/Q!!(IJdf@hse,97Kdf9BsqZ$cJ!7Lqsr;ZiHrVurIr;ZoJ!7UlH!n..urW)uI!<CUI!!(LH
3057 !!(LD!<48C<UBa_bl.SB'(3u<s8.!@JG=]qJcGBBScJ]g!1s#d!K@'Pg]X2Kqc-XH~>
3058 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LC
3059 !!C[M!7U<8!7UcE"4I5Me*-i7df9Bsn,NR>!!(LG!!(LH!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bs
3060 pAb3Bqu?`GrW)uI!<CUI!!C[M!7UfF!7UiGs3prI!7UlH!7UoI!7UlH"4I5Me,01Ge,B@IdfKNu
3061 e,B=Kdf@kr!<:LK!7UlH!7UWA!7UoI!7UoIs3guKe,B@IdfBHtr;ZoJ!7UlH!n..ur;ZiHlMpq6
3062 r;[&N!!(IJ!7UiG!7UlH!7UoI!7U]C"OdA"!7UlH!7UlH!7UoI!n..ur;ZiHq#CEDr;ZoJ!7UlH
3063 !n..ur;ZoJ!7UlH!7UlH!7UoI!7UlH!n..ur;ZiHq#CEDr;ZoJ!7UlH!7U]C!7UiG!7UlH!n..u
3064 r;[/Q!!(IJdf@hse,97Kdf9BsqZ$cJ!7Lqsr;ZiHrVurIr;ZoJ!7UlH!n..urW)uI!<CUI!!(LH
3065 !!(LD!<48C<UBa_bl.SB/FL`Vs8.!@NW"G.JcGBBScJ]g!1N``!K$jMg'!iEqc-XH~>
3066 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LC
3067 !!C[M!7U<8!7UcE"4I5Me*-i7df9Bsn,NR>!!(LG!!(LH!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bs
3068 pAb3Bqu?`GrW)uI!<CUI!!C[M!7UfF!7UiGs3prI!7UlH!7UoI!7UlH"4I5Me,01Ge,B@IdfKNu
3069 e,B=Kdf@kr!<:LK!7UlH!7UWA!7UoI!7UoIs3guKe,B@IdfBHtr;ZoJ!7UlH!n..ur;ZiHlMpq6
3070 r;[&N!!(IJ!7UiG!7UlH!7UoI!7U]C"OdA"!7UlH!7UlH!7UoI!n..ur;ZiHq#CEDr;ZoJ!7UlH
3071 !n..ur;ZoJ!7UlH!7UlH!7UoI!7UlH!n..ur;ZiHq#CEDr;ZoJ!7UlH!7U]C!7UiG!7UlH!n..u
3072 r;[/Q!!(IJdf@hse,97Kdf9BsqZ$cJ!7Lqsr;ZiHrVurIr;ZoJ!7UlH!n..urW)uI!<CUI!!(LH
3073 !!(LD!<48C<UBa_bl.SBDXP`Cs8.!@W;_AJJcGBBScJ]g!0R*W!J:@FeHD!7qGgOG~>
3074 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe+`nEdf9CF
3075 e+*M9e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He+NbAe,'.EdfTU!!!)uHrVurIqZ$WF
3076 qu?cH!<1IH!;t:H!7UlH"4I5Me,'.Edf]["!7LrIe,B@HdfTU!!!)uHpAk-?rrE&I!s$dM!<1FL
3077 !7Lqsr;ZoJ!!)uHrr<&Jr;ZiHl2^e3rr<&Jr;ZoJ!!)rGrW)rHp&G0C!7UoIr6tWFrmUlI!7UlH
3078 !7U]CrR:`GrR:`GrR:`GrR:`Gr6tZGrR:cH!7UlH!7U]CrR:cH!7UlH!7U]C!7UiG!7UlH!n.,L
3079 rR:`G!7UoI!n.,LrR:`G!7UfF!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe,'.F
3080 ,6([0s/+!B!!4@=m`_F*#3_n8H%`0cJcC<$K)Yk1s7Y4NScJXf<Ib~>
3081 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe+`nEdf9CF
3082 e+*M9e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He+NbAe,'.EdfTU!!!)uHrVurIqZ$WF
3083 qu?cH!<1IH!;t:H!7UlH"4I5Me,'.Edf]["!7LrIe,B@HdfTU!!!)uHpAk-?rrE&I!s$dM!<1FL
3084 !7Lqsr;ZoJ!!)uHrr<&Jr;ZiHl2^e3rr<&Jr;ZoJ!!)rGrW)rHp&G0C!7UoIr6tWFrmUlI!7UlH
3085 !7U]CrR:`GrR:`GrR:`GrR:`Gr6tZGrR:cH!7UlH!7U]CrR:cH!7UlH!7U]C!7UiG!7UlH!n.,L
3086 rR:`G!7UoI!n.,LrR:`G!7UfF!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe,'.F
3087 ,6([0s/+!B!!4plm`_F*#1o>nHAT$+JcC<$K)Yk.s7Y.LRK34b<Ib~>
3088 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe+`nEdf9CF
3089 e+*M9e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He+NbAe,'.EdfTU!!!)uHrVurIqZ$WF
3090 qu?cH!<1IH!;t:H!7UlH"4I5Me,'.Edf]["!7LrIe,B@HdfTU!!!)uHpAk-?rrE&I!s$dM!<1FL
3091 !7Lqsr;ZoJ!!)uHrr<&Jr;ZiHl2^e3rr<&Jr;ZoJ!!)rGrW)rHp&G0C!7UoIr6tWFrmUlI!7UlH
3092 !7U]CrR:`GrR:`GrR:`GrR:`Gr6tZGrR:cH!7UlH!7U]CrR:cH!7UlH!7U]C!7UiG!7UlH!n.,L
3093 rR:`G!7UoI!n.,LrR:`G!7UfF!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe,'.F
3094 ,6([0s/+!B!!Z!7m`_F*#0<!UI#u8EJcC<$K)Yk's7XtGOT>5X<Ib~>
3095 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCm/N-jJcC<$JcD8?!K@'Pg]X2Kqc-XH~>
3096 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCm/N-jJcC<$JcD8?!K$jMg'!iEqc-XH~>
3097 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCm/N-jJcC<$JcD8?!J:@FeHD!7qGgOG~>
3098 s!!!oJH16$JH1B(s!%JCrVqGmJ]r\hJ]s\/rVlnWs7Y4NScJXf<Ib~>
3099 s!!!oJH16$JH1B(s!%JCrVqGmJ]r\hJ]s\/rVlnTs7Y.LRK34b<Ib~>
3100 s!!!oJH16$JH1B(s!%JCrVqGmJ]r\hJ]s\/rVlnMs7XtGOT>5X<Ib~>
3101 s!!!oJH16$JH1B(s!%JCrVqGmJ]r\hJ]s\/rVlnWs7Y4NScJXf<Ib~>
3102 s!!!oJH16$JH1B(s!%JCrVqGmJ]r\hJ]s\/rVlnTs7Y.LRK34b<Ib~>
3103 s!!!oJH16$JH1B(s!%JCrVqGmJ]r\hJ]s\/rVlnMs7XtGOT>5X<Ib~>
3104 s!!!oJH16$JH1B(s!%JCrVqGmJ]r\hJ]s\/rVlnWs7Y4NScJXf<Ib~>
3105 s!!!oJH16$JH1B(s!%JCrVqGmJ]r\hJ]s\/rVlnTs7Y.LRK34b<Ib~>
3106 s!!!oJH16$JH1B(s!%JCrVqGmJ]r\hJ]s\/rVlnMs7XtGOT>5X<Ib~>
3107 s!$b/!7U66s3pH;qpYQFrR:cHqpYHC!7UoIrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pZArR:?<
3108 !7U'1!n..ukPtV3JH16$WrW/Ds&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
3109 s!$b/!7U66s3pH;qpYQFrR:cHqpYHC!7UoIrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pZArR:?<
3110 !7U'1!n..ukPtV3JH16$WrW/Ds&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
3111 s!$b/!7U66s3pH;qpYQFrR:cHqpYHC!7UoIrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pZArR:?<
3112 !7U'1!n..ukPtV3JH16$WrW/Ds&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
3113 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFr;clHrr<&Jr;ZiHnc/[=r;[&N!!(IJ!7U04"4I5M
3114 e*m>>df9BspAb<E!!(L;!!C[M!7U]C!7UlH!7UQ?!7U'1!n..up](<Cnc/[=irB).JH16$aoMGc
3115 s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
3116 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFr;clHrr<&Jr;ZiHnc/[=r;[&N!!(IJ!7U04"4I5M
3117 e*m>>df9BspAb<E!!(L;!!C[M!7U]C!7UlH!7UQ?!7U'1!n..up](<Cnc/[=irB).JH16$aoMGc
3118 s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
3119 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$WFr;clHrr<&Jr;ZiHnc/[=r;[&N!!(IJ!7U04"4I5M
3120 e*m>>df9BspAb<E!!(L;!!C[M!7U]C!7UlH!7UQ?!7U'1!n..up](<Cnc/[=irB).JH16$aoMGc
3121 s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
3122 s!$b/!7U35!7U97"4I5Me,97He,01Ge,97Mdf@hs!7UlH!7UK=!7UlH!n..ur;ZiHlMpq6r;ZiH
3123 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,!@jo>M4!!(L4!!(L-!!(K!!.b-m!<48C
3124 <It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
3125 s!$b/!7U35!7U97"4I5Me,97He,01Ge,97Mdf@hs!7UlH!7UK=!7UlH!n..ur;ZiHlMpq6r;ZiH
3126 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,!@jo>M4!!(L4!!(L-!!(K!!.b-m!<48C
3127 <It1$s+13$s-<TbM?!;'"I]>f<E4P~>
3128 s!$b/!7U35!7U97"4I5Me,97He,01Ge,97Mdf@hs!7UlH!7UK=!7UlH!n..ur;ZiHlMpq6r;ZiH
3129 nc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,!@jo>M4!!(L4!!(L-!!(K!!.b-m!<48C
3130 <It1$s+13$s-<TbK)bPp"H`]\<E4P~>
3131 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHr;[&N!!(IJ!7UoI
3132 s3p?8!n..ur;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHoDem?o`,*C!!(LH!!:UL
3133 !<(CH!!1OKrmU`E"Od>NdfBBrr;clHrVuuJ!<1IE!!C[M!7UlH"4I8!!<1II!!(LH!!C[M!7UoI
3134 !Rh&Idt%LM!6bHC,6(Yos+13$s+138rrJ)Yp=oeB!;fbrJ,~>
3135 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHr;[&N!!(IJ!7UoI
3136 s3p?8!n..ur;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHoDem?o`,*C!!(LH!!:UL
3137 !<(CH!!1OKrmU`E"Od>NdfBBrr;clHrVuuJ!<1IE!!C[M!7UlH"4I8!!<1II!!(LH!!C[M!7UoI
3138 !Rh&Idt%LM!6bHC,6(Yos+13$s+138rrIuVp=]Y<!;fbrJ,~>
3139 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHr;[&N!!(IJ!7UoI
3140 s3p?8!n..ur;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHoDem?o`,*C!!(LH!!:UL
3141 !<(CH!!1OKrmU`E"Od>NdfBBrr;clHrVuuJ!<1IE!!C[M!7UlH"4I8!!<1II!!(LH!!C[M!7UoI
3142 !Rh&Idt%LM!6bHC,6(Yos+13$s+138rrI`Op=0;.!;]\qJ,~>
3143 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LI!!(LI
3144 !!(LI!<1FJ!7U?9"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+E\@e+E\@
3145 e,B=Ie,97Jdf@kq!!C[M!7UoI!7UlH!7UoIs3prI!7UlH!7UoIs3prI!7UlH!7UoI!7UlH"4I5M
3146 e,B=Odf9Bs!!(LI!!(LI!!C[M!7QK!JH3gms!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3147 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LI!!(LI
3148 !!(LI!<1FJ!7U?9"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+E\@e+E\@
3149 e,B=Ie,97Jdf@kq!!C[M!7UoI!7UlH!7UoIs3prI!7UlH!7UoIs3prI!7UlH!7UoI!7UlH"4I5M
3150 e,B=Odf9Bs!!(LI!!(LI!!C[M!7QK!JH3gms!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3151 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LI!!(LI
3152 !!(LI!<1FJ!7U?9"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+E\@e+E\@
3153 e,B=Ie,97Jdf@kq!!C[M!7UoI!7UlH!7UoIs3prI!7UlH!7UoIs3prI!7UlH!7UoI!7UlH"4I5M
3154 e,B=Odf9Bs!!(LI!!(LI!!C[M!7QK!JH3gms!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3155 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7UlH!7UoI!7UcE
3156 !7UE;s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UZBs3pW@!7UlH!7UlH
3157 "Od>Ne'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH"4I5Me+s(Ee,97He,B=L
3158 df9BsJH16$aoMGcs&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
3159 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7UlH!7UoI!7UcE
3160 !7UE;s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UZBs3pW@!7UlH!7UlH
3161 "Od>Ne'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH"4I5Me+s(Ee,97He,B=L
3162 df9BsJH16$aoMGcs&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
3163 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7UlH!7UoI!7UcE
3164 !7UE;s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UZBs3pW@!7UlH!7UlH
3165 "Od>Ne'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH"4I5Me+s(Ee,97He,B=L
3166 df9BsJH16$aoMGcs&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
3167 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee,9:De,'+Fe+!D<
3168 e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+`nCe+3P>e,97He,97He,9:H
3169 e,B=Ie+s%Ee,97He,97He,97He,B=Ie,97He,B=Ie,97He,97Kdf9Bsq>gQEqu?fI!7UoI!7QK!
3170 JH3gms!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3171 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee,9:De,'+Fe+!D<
3172 e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+`nCe+3P>e,97He,97He,9:H
3173 e,B=Ie+s%Ee,97He,97He,97He,B=Ie,97He,B=Ie,97He,97Kdf9Bsq>gQEqu?fI!7UoI!7QK!
3174 JH3gms!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3175 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee,9:De,'+Fe+!D<
3176 e,01Ge,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+`nCe+3P>e,97He,97He,9:H
3177 e,B=Ie+s%Ee,97He,97He,97He,B=Ie,97He,B=Ie,97He,97Kdf9Bsq>gQEqu?fI!7UoI!7QK!
3178 JH3gms!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3179 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LC
3180 !!(LF!!(L<!!(LE!!C[M!7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UoI!7UN>
3181 !7UiG!7UoIs3guKe,97Kdf9BsqZ$WFquHcGrVurIr;ZiHrVurIr;ZrK!!(LG!!(LI!<:OJ!!(LF
3182 !!C[M!7UlH!n..urVurIrVurIJH16$c2dkgs&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
3183 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LC
3184 !!(LF!!(L<!!(LE!!C[M!7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UoI!7UN>
3185 !7UiG!7UoIs3guKe,97Kdf9BsqZ$WFquHcGrVurIr;ZiHrVurIr;ZrK!!(LG!!(LI!<:OJ!!(LF
3186 !!C[M!7UlH!n..urVurIrVurIJH16$c2dkgs&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
3187 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LC
3188 !!(LF!!(L<!!(LE!!C[M!7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UoI!7UN>
3189 !7UiG!7UoIs3guKe,97Kdf9BsqZ$WFquHcGrVurIr;ZiHrVurIr;ZrK!!(LG!!(LI!<:OJ!!(LF
3190 !!C[M!7UlH!n..urVurIrVurIJH16$c2dkgs&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
3191 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe+`nCe,B@H
3192 e*mA7e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,KFFe+`nCe,'.EdfTU!!!)uHrVurIqZ$WF
3193 qu?cH!<1IH!;t:H!7UlH"4I5Me,'.Edf]["!!(LG!!(LH!!(LH!!(LG!<1Gu!.b-p!<48C<It1$
3194 s+13$s-<TbN;rV,"J,Vj<E4P~>
3195 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe+`nCe,B@H
3196 e*mA7e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,KFFe+`nCe,'.EdfTU!!!)uHrVurIqZ$WF
3197 qu?cH!<1IH!;t:H!7UlH"4I5Me,'.Edf]["!!(LG!!(LH!!(LH!!(LG!<1Gu!.b-p!<48C<It1$
3198 s+13$s-<TbM?!;'"I]>f<E4P~>
3199 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe+`nCe,B@H
3200 e*mA7e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,KFFe+`nCe,'.EdfTU!!!)uHrVurIqZ$WF
3201 qu?cH!<1IH!;t:H!7UlH"4I5Me,'.Edf]["!!(LG!!(LH!!(LH!!(LG!<1Gu!.b-p!<48C<It1$
3202 s+13$s-<TbK)bPp"H`]\<E4P~>
3203 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3204 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3205 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3206 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3207 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3208 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3209 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3210 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3211 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3212 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3213 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3214 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3215 s!$b/!7U66s3pH;qpYQFrR:cHqpPNFqpYNEs3pE:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pT?!7UB:
3216 !7Tj+!7QK!JH2&;s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3217 s!$b/!7U66s3pH;qpYQFrR:cHqpPNFqpYNEs3pE:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pT?!7UB:
3218 !7Tj+!7QK!JH2&;s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3219 s!$b/!7U66s3pH;qpYQFrR:cHqpPNFqpYNEs3pE:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pT?!7UB:
3220 !7Tj+!7QK!JH2&;s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3221 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$]H!7UcE"4I5Me+!D<e,97Ndf9Bs!!(L4!!C[M!7UE;
3222 "4I5Me+WhEdf9Bsn,NR>!!(LA!<:O:!!(L+!!(K!!.b-;!<48C<It1$s+13$s-<TbN;rV,"J,Vj
3223 <E4P~>
3224 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$]H!7UcE"4I5Me+!D<e,97Ndf9Bs!!(L4!!C[M!7UE;
3225 "4I5Me+WhEdf9Bsn,NR>!!(LA!<:O:!!(L+!!(K!!.b-;!<48C<It1$s+13$s-<TbM?!;'"I]>f
3226 <E4P~>
3227 s!%.:!7UZB!7U35!7U66!n..ur;ZiHqZ$]H!7UcE"4I5Me+!D<e,97Ndf9Bs!!(L4!!C[M!7UE;
3228 "4I5Me+WhEdf9Bsn,NR>!!(LA!<:O:!!(L+!!(K!!.b-;!<48C<It1$s+13$s-<TbK)bPp"H`]\
3229 <E4P~>
3230 s!$b/!7U35!7U97"4I5Me,97He,01Jdf9BsqZ$WFr;ZiHnc/[=r;ZoJ!7UlH!7U66!7UlH!7UK=
3231 !7UlH!7U`D!7UlH!7UK=!7UlH!7U]C!n..umJm79i;`l,JH16$QiR.1s&FXMJcC<$JcD#8!K@'P
3232 g]X2Kqc-XH~>
3233 s!$b/!7U35!7U97"4I5Me,97He,01Jdf9BsqZ$WFr;ZiHnc/[=r;ZoJ!7UlH!7U66!7UlH!7UK=
3234 !7UlH!7U`D!7UlH!7UK=!7UlH!7U]C!n..umJm79i;`l,JH16$QiR.1s&FXMJcC<$JcD#8!K$jM
3235 g'!iEqc-XH~>
3236 s!$b/!7U35!7U97"4I5Me,97He,01Jdf9BsqZ$WFr;ZiHnc/[=r;ZoJ!7UlH!7U66!7UlH!7UK=
3237 !7UlH!7U`D!7UlH!7UK=!7UlH!7U]C!n..umJm79i;`l,JH16$QiR.1s&FXMJcC<$JcD#8!J:@F
3238 eHD!7qGgOG~>
3239 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHrVuuJ!<1II!!(LH
3240 !!(L8!!:ULe,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+NbAe*[29e*d;6e,KFH
3241 e,KCKdfBBrJH16$S,iR5s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
3242 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHrVuuJ!<1II!!(LH
3243 !!(L8!!:ULe,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+NbAe*[29e*d;6e,KFH
3244 e,KCKdfBBrJH16$S,iR5s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
3245 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gm/R.8q#CEDr;ZiHrVuuJ!<1II!!(LH
3246 !!(L8!!:ULe,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+NbAe*[29e*d;6e,KFH
3247 e,KCKdfBBrJH16$S,iR5s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
3248 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LI!<:OI
3249 !!:ULe,97He*[2<df9Bsr;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*Am/R.8
3250 li7.:!!(LH!!C[Me'n9r!7QK!JH25@s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3251 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LI!<:OI
3252 !!:ULe,97He*[2<df9Bsr;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*Am/R.8
3253 li7.:!!(LH!!C[Me'n9r!7QK!JH25@s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3254 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L9!<1IE!!(LG!!(LI!<:OI
3255 !!:ULe,97He*[2<df9Bsr;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*Am/R.8
3256 li7.:!!(LH!!C[Me'n9r!7QK!JH25@s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3257 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7U]C!n..ur;ZiH
3258 n,WL;rVurIr;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*Ali7%7mJm79r;clH
3259 r;ZiHr;ZiHJH16$SH/[6s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
3260 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7U]C!n..ur;ZiH
3261 n,WL;rVurIr;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*Ali7%7mJm79r;clH
3262 r;ZiHr;ZiHJH16$SH/[6s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
3263 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U66!7UoIs3plG!7U]C!n..ur;ZiH
3264 n,WL;rVurIr;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*Ali7%7mJm79r;clH
3265 r;ZiHr;ZiHJH16$SH/[6s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
3266 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee+`nEdf@kq!!(L<
3267 !!(LG!!(LH!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LA!!(L7!!(L:!!(LE!<:OJ
3268 !!(LH!!(K!!.b-@!<48C<It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
3269 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee+`nEdf@kq!!(L<
3270 !!(LG!!(LH!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LA!!(L7!!(L:!!(LE!<:OJ
3271 !!(LH!!(K!!.b-@!<48C<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
3272 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U66"4I5Me+s%Ee+`nEdf@kq!!(L<
3273 !!(LG!!(LH!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LA!!(L7!!(L:!!(LE!<:OJ
3274 !!(LH!!(K!!.b-@!<48C<It1$s+13$s-<TbK)bPp"H`]\<E4P~>
3275 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LG
3276 !!(LH!!^mP!7LoJe+!D<e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`G
3277 qZ$WFlMpq6nGiR<qu?`Gr;ZoJ!7UlH!7QK!JH25@s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3278 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LG
3279 !!(LH!!^mP!7LoJe+!D<e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`G
3280 qZ$WFlMpq6nGiR<qu?`Gr;ZoJ!7UlH!7QK!JH25@s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3281 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*m>;e,97Jdf@kn!!(LG
3282 !!(LH!!^mP!7LoJe+!D<e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`G
3283 qZ$WFlMpq6nGiR<qu?`Gr;ZoJ!7UlH!7QK!JH25@s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3284 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe,'.De,9:H
3285 e*mA7e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,B@Fe*R,8e+*M9e,KFHe,KCJe,97Hdt%LM
3286 !1a,i,6(Yos+13$s+138rrJ)Yp=oeB!;fbrJ,~>
3287 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe,'.De,9:H
3288 e*mA7e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,B@Fe*R,8e+*M9e,KFHe,KCJe,97Hdt%LM
3289 !1a,i,6(Yos+13$s+138rrIuVp=]Y<!;fbrJ,~>
3290 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe+!G:e,KFFe,KCJe,'.De,9:H
3291 e*mA7e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,B@Fe*R,8e+*M9e,KFHe,KCJe,97Hdt%LM
3292 !1a,i,6(Yos+13$s+138rrI`Op=0;.!;]\qJ,~>
3293 s!!!oc2[jnhZ*Z*iW/l)JH16$JH5]os&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
3294 s!!!oc2[jnhZ*Z*iW/l)JH16$JH5]os&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
3295 s!!!oc2[jnhZ*Z*iW/l)JH16$JH5]os&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
3296 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3297 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3298 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3299 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3300 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3301 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3302 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3303 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3304 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3305 s!$b/!7U66s3p34qpYQFrR:cHqpYQFrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3oEs!7T9p
3306 s3pW@rmRtL!7QK!W;urBs&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
3307 s!$b/!7U66s3p34qpYQFrR:cHqpYQFrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3oEs!7T9p
3308 s3pW@rmRtL!7QK!W;urBs&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
3309 s!$b/!7U66s3p34qpYQFrR:cHqpYQFrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3oEs!7T9p
3310 s3pW@rmRtL!7QK!W;urBs&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
3311 s!%.:!7UZB!7U35!7U!/!n..ur;ZiHqZ$]H!7UlH!7UK=!7UlH#1EPPdf9Bskl:h7!!(L;!!C[M
3312 !7UZB"4I5Me*m>>df9BspAb<E!!(Kt!!(Kq!!C[M!7UZB!7UoI!7SCW!7U`D!7U-3!7U<8!7UlH
3313 !7U!/!7QK!qZ-X?s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
3314 s!%.:!7UZB!7U35!7U!/!n..ur;ZiHqZ$]H!7UlH!7UK=!7UlH#1EPPdf9Bskl:h7!!(L;!!C[M
3315 !7UZB"4I5Me*m>>df9BspAb<E!!(Kt!!(Kq!!C[M!7UZB!7UoI!7SCW!7U`D!7U-3!7U<8!7UlH
3316 !7U!/!7QK!qZ-X?s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
3317 s!%.:!7UZB!7U35!7U!/!n..ur;ZiHqZ$]H!7UlH!7UK=!7UlH#1EPPdf9Bskl:h7!!(L;!!C[M
3318 !7UZB"4I5Me*m>>df9BspAb<E!!(Kt!!(Kq!!C[M!7UZB!7UoI!7SCW!7U`D!7U-3!7U<8!7UlH
3319 !7U!/!7QK!qZ-X?s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
3320 s!$b/!7U35!7U$0"4I5Me,97He,01Jdf9Bsr;ZiHnc/[=r;ZoJ!7UlH!7U66!7UlH!7UK=!7UlH
3321 !7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7TBs!7UlH!7U]C!7RqJ!7T3n!7QK!h#RI!s&FXM
3322 JcC<$JcD#8!K@'Pg]X2Kqc-XH~>
3323 s!$b/!7U35!7U$0"4I5Me,97He,01Jdf9Bsr;ZiHnc/[=r;ZoJ!7UlH!7U66!7UlH!7UK=!7UlH
3324 !7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7TBs!7UlH!7U]C!7RqJ!7T3n!7QK!h#RI!s&FXM
3325 JcC<$JcD#8!K$jMg'!iEqc-XH~>
3326 s!$b/!7U35!7U$0"4I5Me,97He,01Jdf9Bsr;ZiHnc/[=r;ZoJ!7UlH!7U66!7UlH!7UK=!7UlH
3327 !7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7TBs!7UlH!7U]C!7RqJ!7T3n!7QK!h#RI!s&FXM
3328 JcC<$JcD#8!J:@FeHD!7qGgOG~>
3329 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZiHr;ZiHrVurIrW)uI
3330 m/R4:!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7UB:!Rh&J
3331 e,B@Ge+!D<e,97He+`nCe*R/6e+`nCe,97Jdf9CHe,B@Ge,KCKdfBBrp](?D!<1IG!<:OH!<1FJ
3332 !7U`D!Rh&Je,KCKdfBBrr;clHr;cfFrr<)K!<1IG!<:OI!<(CG!!(LH!!(LD!!1OKrmUfGs3p]B
3333 !Rh&Je,B@Ge,KCKdfBBrrr<&Jr;ZiHq#CHE!<1IH!<:LK!7UoIrR:`Gs3guKe+Wk@e,KCKdfBBr
3334 rW)rH!s$dM!<(C.!<48C<It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
3335 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZiHr;ZiHrVurIrW)uI
3336 m/R4:!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7UB:!Rh&J
3337 e,B@Ge+!D<e,97He+`nCe*R/6e+`nCe,97Jdf9CHe,B@Ge,KCKdfBBrp](?D!<1IG!<:OH!<1FJ
3338 !7U`D!Rh&Je,KCKdfBBrr;clHr;cfFrr<)K!<1IG!<:OI!<(CG!!(LH!!(LD!!1OKrmUfGs3p]B
3339 !Rh&Je,B@Ge,KCKdfBBrrr<&Jr;ZiHq#CHE!<1IH!<:LK!7UoIrR:`Gs3guKe+Wk@e,KCKdfBBr
3340 rW)rH!s$dM!<(C.!<48C<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
3341 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZiHr;ZiHrVurIrW)uI
3342 m/R4:!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7TEt!7UB:!Rh&J
3343 e,B@Ge+!D<e,97He+`nCe*R/6e+`nCe,97Jdf9CHe,B@Ge,KCKdfBBrp](?D!<1IG!<:OH!<1FJ
3344 !7U`D!Rh&Je,KCKdfBBrr;clHr;cfFrr<)K!<1IG!<:OI!<(CG!!(LH!!(LD!!1OKrmUfGs3p]B
3345 !Rh&Je,B@Ge,KCKdfBBrrr<&Jr;ZiHq#CHE!<1IH!<:LK!7UoIrR:`Gs3guKe+Wk@e,KCKdfBBr
3346 rW)rH!s$dM!<(C.!<48C<It1$s+13$s-<TbK)bPp"H`]\<E4P~>
3347 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CE!!(LH!<1FJ
3348 !7U?9"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He'e9se*mA;
3349 e,B=Kdf@kq!!(LC!;t:H!7UlH!7U`DrR:H?r6kZHe,97He+itDe,97Jdf@kq!!:ULe,97Kdf9Bs
3350 rVurIq#LHDrVurIr;ZiHrVurIrW)uIq#LHDrW!&L!!(LI!!(LH!!(LI!!(LH!!C[M!7UoI!7UlH
3351 !7UlH!7UiG!7UlH!7U`Ds3prI!7UlH!7UZBs3prI!n..ur;ZrK!7TEr!!:ULe,97He+j"De,B=R
3352 df9Bs!7Lqs!7UlH#L`YQdf@hse+<VBdf9BsrW!#K!7UoI"4I5Me,97He)gZ1,6(Yos+13$s+138
3353 rrJ)Yp=oeB!;fbrJ,~>
3354 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CE!!(LH!<1FJ
3355 !7U?9"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He'e9se*mA;
3356 e,B=Kdf@kq!!(LC!;t:H!7UlH!7U`DrR:H?r6kZHe,97He+itDe,97Jdf@kq!!:ULe,97Kdf9Bs
3357 rVurIq#LHDrVurIr;ZiHrVurIrW)uIq#LHDrW!&L!!(LI!!(LH!!(LI!!(LH!!C[M!7UoI!7UlH
3358 !7UlH!7UiG!7UlH!7U`Ds3prI!7UlH!7UZBs3prI!n..ur;ZrK!7TEr!!:ULe,97He+j"De,B=R
3359 df9Bs!7Lqs!7UlH#L`YQdf@hse+<VBdf9BsrW!#K!7UoI"4I5Me,97He)gZ1,6(Yos+13$s+138
3360 rrIuVp=]Y<!;fbrJ,~>
3361 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CE!!(LH!<1FJ
3362 !7U?9"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He'e9se*mA;
3363 e,B=Kdf@kq!!(LC!;t:H!7UlH!7U`DrR:H?r6kZHe,97He+itDe,97Jdf@kq!!:ULe,97Kdf9Bs
3364 rVurIq#LHDrVurIr;ZiHrVurIrW)uIq#LHDrW!&L!!(LI!!(LH!!(LI!!(LH!!C[M!7UoI!7UlH
3365 !7UlH!7UiG!7UlH!7U`Ds3prI!7UlH!7UZBs3prI!n..ur;ZrK!7TEr!!:ULe,97He+j"De,B=R
3366 df9Bs!7Lqs!7UlH#L`YQdf@hse+<VBdf9BsrW!#K!7UoI"4I5Me,97He)gZ1,6(Yos+13$s+138
3367 rrI`Op=0;.!;]\qJ,~>
3368 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH!7UoI!7U]C!7UE;
3369 s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7UH<!7UlH
3370 "Od>Ne'macqpY<?!7U?9!7UlH!7U`D!7UlH"Od>Ne'n6qqpYQF!7UT@!7UlH!7UlH!7UoI!7UlH
3371 !7U`D!7UlH"4I5Me+itDe,B=Ie,97Kdf9Bsq#CEDr;ZiHqu?`Gr;ZiHq#CEDr;ZiHr;ZiHpAb3B
3372 r;ZoJ!7UfF!7UlH!n..ur;ZiHq#CEDr;[,P!!(IJdf@hsqpYQF"OdA"!7U]Cr6tZG!7UiG!7UoI
3373 !7UoIs3p!.s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3374 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH!7UoI!7U]C!7UE;
3375 s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7UH<!7UlH
3376 "Od>Ne'macqpY<?!7U?9!7UlH!7U`D!7UlH"Od>Ne'n6qqpYQF!7UT@!7UlH!7UlH!7UoI!7UlH
3377 !7U`D!7UlH"4I5Me+itDe,B=Ie,97Kdf9Bsq#CEDr;ZiHqu?`Gr;ZiHq#CEDr;ZiHr;ZiHpAb3B
3378 r;ZoJ!7UfF!7UlH!n..ur;ZiHq#CEDr;[,P!!(IJdf@hsqpYQF"OdA"!7U]Cr6tZG!7UiG!7UoI
3379 !7UoIs3p!.s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3380 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH!7UoI!7U]C!7UE;
3381 s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7UH<!7UlH
3382 "Od>Ne'macqpY<?!7U?9!7UlH!7U`D!7UlH"Od>Ne'n6qqpYQF!7UT@!7UlH!7UlH!7UoI!7UlH
3383 !7U`D!7UlH"4I5Me+itDe,B=Ie,97Kdf9Bsq#CEDr;ZiHqu?`Gr;ZiHq#CEDr;ZiHr;ZiHpAb3B
3384 r;ZoJ!7UfF!7UlH!n..ur;ZiHq#CEDr;[,P!!(IJdf@hsqpYQF"OdA"!7U]Cr6tZG!7UiG!7UoI
3385 !7UoIs3p!.s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3386 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7U]C!7UH<
3387 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7UH<s3prI
3388 !7UlHs3pK<!7UlH!7U]C!7U?9!7UlH!7U`D!7UlH!7UlHs3puJ!7UcE!7UT@s3prI!7UlH!7UoI
3389 !7UlH!7U`Ds3prI"4I5Me+itDe,B=Ie,97Kdf9Bsq#CEDr;ZiHqu?`GrW)uIq#CEDr;ZiHr;ZiH
3390 pAk6BrW!#K!7UfFs3prI!n..ur;ZiHq#LHDrW!8R!!(IJdf@hse+s%Idf@hse+itDe,97Kdf9Bs
3391 qZ-WEqZ-ZFjT,<)s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
3392 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7U]C!7UH<
3393 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7UH<s3prI
3394 !7UlHs3pK<!7UlH!7U]C!7U?9!7UlH!7U`D!7UlH!7UlHs3puJ!7UcE!7UT@s3prI!7UlH!7UoI
3395 !7UlH!7U`Ds3prI"4I5Me+itDe,B=Ie,97Kdf9Bsq#CEDr;ZiHqu?`GrW)uIq#CEDr;ZiHr;ZiH
3396 pAk6BrW!#K!7UfFs3prI!n..ur;ZiHq#LHDrW!8R!!(IJdf@hse+s%Idf@hse+itDe,97Kdf9Bs
3397 qZ-WEqZ-ZFjT,<)s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
3398 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7U]C!7UH<
3399 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7UH<s3prI
3400 !7UlHs3pK<!7UlH!7U]C!7U?9!7UlH!7U`D!7UlH!7UlHs3puJ!7UcE!7UT@s3prI!7UlH!7UoI
3401 !7UlH!7U`Ds3prI"4I5Me+itDe,B=Ie,97Kdf9Bsq#CEDr;ZiHqu?`GrW)uIq#CEDr;ZiHr;ZiH
3402 pAk6BrW!#K!7UfFs3prI!n..ur;ZiHq#LHDrW!8R!!(IJdf@hse+s%Idf@hse+itDe,97Kdf9Bs
3403 qZ-WEqZ-ZFjT,<)s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
3404 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
3405 p](<CnGiR<q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LH!!C[M!7T9p
3406 !7UK=!Rh&Je,KCJe,97He+*J=e,97He+`nCe*[29e,97He+itDe,B@IdfBHtr;ZoJ!7UlH"4I5M
3407 e+s(De,KCKdfBBrqu?`GrVurIrW)uIrW)rHrr<)K!<1IH!!(LD!!(LI!!(LH!!C[M!7U`D!7UlH
3408 !7UoI!n.,LrmLlJe,B@He,KCJe,97He,97He,04Fe,KCKdfBBrrr<&Jr;ZrK!7LrIe,KCJe,B@I
3409 e,B@He,KCKdfBBrrW!/O!7Lqs!7UlH#L`YQdf@hse,B@He,KCJe,B@Ie,KCJe,01Ge,'+Fe,97H
3410 e)gZ1,6(Yos+13$s+138rrJ)Yp=oeB!;fbrJ,~>
3411 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
3412 p](<CnGiR<q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LH!!C[M!7T9p
3413 !7UK=!Rh&Je,KCJe,97He+*J=e,97He+`nCe*[29e,97He+itDe,B@IdfBHtr;ZoJ!7UlH"4I5M
3414 e+s(De,KCKdfBBrqu?`GrVurIrW)uIrW)rHrr<)K!<1IH!!(LD!!(LI!!(LH!!C[M!7U`D!7UlH
3415 !7UoI!n.,LrmLlJe,B@He,KCJe,97He,97He,04Fe,KCKdfBBrrr<&Jr;ZrK!7LrIe,KCJe,B@I
3416 e,B@He,KCKdfBBrrW!/O!7Lqs!7UlH#L`YQdf@hse,B@He,KCJe,B@Ie,KCJe,01Ge,'+Fe,97H
3417 e)gZ1,6(Yos+13$s+138rrIuVp=]Y<!;fbrJ,~>
3418 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
3419 p](<CnGiR<q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LH!!C[M!7T9p
3420 !7UK=!Rh&Je,KCJe,97He+*J=e,97He+`nCe*[29e,97He+itDe,B@IdfBHtr;ZoJ!7UlH"4I5M
3421 e+s(De,KCKdfBBrqu?`GrVurIrW)uIrW)rHrr<)K!<1IH!!(LD!!(LI!!(LH!!C[M!7U`D!7UlH
3422 !7UoI!n.,LrmLlJe,B@He,KCJe,97He,97He,04Fe,KCKdfBBrrr<&Jr;ZrK!7LrIe,KCJe,B@I
3423 e,B@He,KCKdfBBrrW!/O!7Lqs!7UlH#L`YQdf@hse,B@He,KCJe,B@Ie,KCJe,01Ge,'+Fe,97H
3424 e)gZ1,6(Yos+13$s+138rrI`Op=0;.!;]\qJ,~>
3425 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie,'.Ee*mA7
3426 e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He'A!oe+*J=e+s(Ce+!D<e,97He+`nCe*R/6
3427 e+WkAdfTU!!!)uHrW)oGrVurIq>gQErVurIq>gHBrrE&I!<CUJ!<:OI!!(LE!!(LF!;t=G!<(CG
3428 !!(LF!;t=F!<1ID!!(LI!<:OI!!(LH!!:UL!;t=F!<:OI!!(LE!<(CH!!(LE!<1FJ!7UoIs3prI
3429 !7UcE!7UoI!n.,LrR:`G!7UoI!7UoIs3poHrmLuMdf9BsqZ-TDrW)oGjT,<)s&FXMJcC<$JcD#8
3430 !K@'Pg]X2Kqc-XH~>
3431 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie,'.Ee*mA7
3432 e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He'A!oe+*J=e+s(Ce+!D<e,97He+`nCe*R/6
3433 e+WkAdfTU!!!)uHrW)oGrVurIq>gQErVurIq>gHBrrE&I!<CUJ!<:OI!!(LE!!(LF!;t=G!<(CG
3434 !!(LF!;t=F!<1ID!!(LI!<:OI!!(LH!!:UL!;t=F!<:OI!!(LE!<(CH!!(LE!<1FJ!7UoIs3prI
3435 !7UcE!7UoI!n.,LrR:`G!7UoI!7UoIs3poHrmLuMdf9BsqZ-TDrW)oGjT,<)s&FXMJcC<$JcD#8
3436 !K$jMg'!iEqc-XH~>
3437 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie,'.Ee*mA7
3438 e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He'A!oe+*J=e+s(Ce+!D<e,97He+`nCe*R/6
3439 e+WkAdfTU!!!)uHrW)oGrVurIq>gQErVurIq>gHBrrE&I!<CUJ!<:OI!!(LE!!(LF!;t=G!<(CG
3440 !!(LF!;t=F!<1ID!!(LI!<:OI!!(LH!!:UL!;t=F!<:OI!!(LE!<(CH!!(LE!<1FJ!7UoIs3prI
3441 !7UcE!7UoI!n.,LrR:`G!7UoI!7UoIs3poHrmLuMdf9BsqZ-TDrW)oGjT,<)s&FXMJcC<$JcD#8
3442 !J:@FeHD!7qGgOG~>
3443 s!!!oc2[jnhZ*Z*`W5nbq#CEDQiI-8qu?`Gli7%7qu?`Gd/X0qr;ZrK!!(L8!!(LG!!(L?!!(L>
3444 !!(LG!!(L0!!(L9!!(LH!!(L*!<48C<It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
3445 s!!!oc2[jnhZ*Z*`W5nbq#CEDQiI-8qu?`Gli7%7qu?`Gd/X0qr;ZrK!!(L8!!(LG!!(L?!!(L>
3446 !!(LG!!(L0!!(L9!!(LH!!(L*!<48C<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
3447 s!!!oc2[jnhZ*Z*`W5nbq#CEDQiI-8qu?`Gli7%7qu?`Gd/X0qr;ZrK!!(L8!!(LG!!(L?!!(L>
3448 !!(LG!!(L0!!(L9!!(LH!!(L*!<48C<It1$s+13$s-<TbK)bPp"H`]\<E4P~>
3449 s!!!oJH4X/!7R)2!7U'1!7T9prR9d,!7UQ?!7U<8!7T9prR9U's!%JCJcC<$JcC<$Q2^lDs7Y4N
3450 ScJXf<Ib~>
3451 s!!!oJH4X/!7R)2!7U'1!7T9prR9d,!7UQ?!7U<8!7T9prR9U's!%JCJcC<$JcC<$Q2^lAs7Y.L
3452 RK34b<Ib~>
3453 s!!!oJH4X/!7R)2!7U'1!7T9prR9d,!7UQ?!7U<8!7T9prR9U's!%JCJcC<$JcC<$Q2^l:s7XtG
3454 OT>5X<Ib~>
3455 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3456 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3457 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3458 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3459 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3460 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3461 s!##SqpYNErmUfGrmUiHrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1!7U`D!7U-3
3462 !7UK=!7UWA!7QK!JH3sqs!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3463 s!##SqpYNErmUfGrmUiHrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1!7U`D!7U-3
3464 !7UK=!7UWA!7QK!JH3sqs!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3465 s!##SqpYNErmUfGrmUiHrR:69rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1!7U`D!7U-3
3466 !7UK=!7UWA!7QK!JH3sqs!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3467 s!$_.!7T0m"4I5Me,'+Fe,01Ge,97He+*J=e,97Ndf9Bs!!(L4!!C[M!7UE;"4I5Me+WhEdf9Bs
3468 n,NR>!!(LB!!C[M!7UN>!7U'1!7U`D!7U]C!7UK=!7UK=!7UWA!7QK!JH3sqs!%JCJcC<$JcC<$
3469 Q2^lDs7Y4NScJXf<Ib~>
3470 s!$_.!7T0m"4I5Me,'+Fe,01Ge,97He+*J=e,97Ndf9Bs!!(L4!!C[M!7UE;"4I5Me+WhEdf9Bs
3471 n,NR>!!(LB!!C[M!7UN>!7U'1!7U`D!7U]C!7UK=!7UK=!7UWA!7QK!JH3sqs!%JCJcC<$JcC<$
3472 Q2^lAs7Y.LRK34b<Ib~>
3473 s!$_.!7T0m"4I5Me,'+Fe,01Ge,97He+*J=e,97Ndf9Bs!!(L4!!C[M!7UE;"4I5Me+WhEdf9Bs
3474 n,NR>!!(LB!!C[M!7UN>!7U'1!7U`D!7U]C!7UK=!7UK=!7UWA!7QK!JH3sqs!%JCJcC<$JcC<$
3475 Q2^l:s7XtGOT>5X<Ib~>
3476 s!$_.!7T3n"4I5Me,'+Fe,'+Fe,97He+*J=e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH
3477 !!(L=!!(LH!!(LD!!(LH!!(L@!!(L1!!(LC!!(L4!!(L<!!(LA!!(K!!.b-q!<48C<Lj*g1Sb!L
3478 1P,RWs+14,rrJ)Yp=oeB!;fbrJ,~>
3479 s!$_.!7T3n"4I5Me,'+Fe,'+Fe,97He+*J=e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH
3480 !!(L=!!(LH!!(LD!!(LH!!(L@!!(L1!!(LC!!(L4!!(L<!!(LA!!(K!!.b-q!<48C<Lj*g1Sb!L
3481 1P,RWs+14,rrIuVp=]Y<!;fbrJ,~>
3482 s!$_.!7T3n"4I5Me,'+Fe,'+Fe,97He+*J=e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH
3483 !!(L=!!(LH!!(LD!!(LH!!(L@!!(L1!!(LC!!(L4!!(L<!!(LA!!(K!!.b-q!<48C<Lj*g1Sb!L
3484 1P,RWs+14,rrI`Op=0;.!;]\qJ,~>
3485 ruqLEdfBBrrW)oGrW)oGrrE#Hd/X0qrVurIqZ$WFqZ$WFr;ZiHm/R4:!7UlH!7U66!7UlH!7UK=
3486 !7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UT@"4I5Me,97Jdf9CHe,KCKdfBBrqZ$WFrW)oG
3487 rr<)K!<1IG!<:OI!!1OKrmU`E!7UoIrR:`GrR:cH!Rh&Je,B@HdfBHtJH16$c2dkgs&IGGrA+R5
3488 4B@[Df)P_*gA_E&Io/?e7;/CCs8FhRs8Fg*s+13$s5a1\N;rV,"J,Vj<E4P~>
3489 ruqLEdfBBrrW)oGrW)oGrrE#Hd/X0qrVurIqZ$WFqZ$WFr;ZiHm/R4:!7UlH!7U66!7UlH!7UK=
3490 !7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UT@"4I5Me,97Jdf9CHe,KCKdfBBrqZ$WFrW)oG
3491 rr<)K!<1IG!<:OI!!1OKrmU`E!7UoIrR:`GrR:cH!Rh&Je,B@HdfBHtJH16$c2dkgs&IGGrA+R5
3492 5$k/df)P_*g]%QY]QHe+3(n:sdf9;&rr;sRJcC<$JcFg2!K$jMg'!iEqc-XH~>
3493 ruqLEdfBBrrW)oGrW)oGrrE#Hd/X0qrVurIqZ$WFqZ$WFr;ZiHm/R4:!7UlH!7U66!7UlH!7UK=
3494 !7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UT@"4I5Me,97Jdf9CHe,KCKdfBBrqZ$WFrW)oG
3495 rr<)K!<1IG!<:OI!!1OKrmU`E!7UoIrR:`GrR:cH!Rh&Je,B@HdfBHtJH16$c2dkgs&IGGrA+O5
3496 6u'Hds8Fh/rs8J#Cdp?E;16:/s8FhRs8Fg*s+13$s5a1\K)bPp"H`]\<E4P~>
3497 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me'A!oe,B=JdfBBrrr<)K!<1IH!<(C6!!C[M!7UlH!7U66
3498 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UWA!7UoI!7UlH!n..ur;ZrK!!(LI
3499 !!(LH!!(LI!!(LH!!C[Me'n9r!7UlH!7UoIs3prI!7UlH!7UoI!7UlH!n..ur;ZrK!7TEr!!:UL
3500 e,B@Idt%LM!6tTE,6(Zis7nGN@+PAW1Yi!2q0Vondf9;&rr;sRJcC<$JcFg2!K@'Pg]X2Kqc-XH~>
3501 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me'A!oe,B=JdfBBrrr<)K!<1IH!<(C6!!C[M!7UlH!7U66
3502 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UWA!7UoI!7UlH!n..ur;ZrK!!(LI
3503 !!(LH!!(LI!!(LH!!C[Me'n9r!7UlH!7UoIs3prI!7UlH!7UoI!7UlH!n..ur;ZrK!7TEr!!:UL
3504 e,B@Idt%LM!6tTE,6(Zis7nGNP1K[41Yi!2mp>fGdf9;&rr;sRJcC<$JcFg2!K$jMg'!iEqc-XH~>
3505 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me'A!oe,B=JdfBBrrr<)K!<1IH!<(C6!!C[M!7UlH!7U66
3506 !7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UWA!7UoI!7UlH!n..ur;ZrK!!(LI
3507 !!(LH!!(LI!!(LH!!C[Me'n9r!7UlH!7UoIs3prI!7UlH!7UoI!7UlH!n..ur;ZrK!7TEr!!:UL
3508 e,B@Idt%LM!6tTE,6(Zis7nGNcdr-q1Yi!2d73pfdf9;&rr;sRJcC<$JcFg2!J:@FeHD!7qGgOG~>
3509 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kp!!(LH!<:OI!!C[Me'n9r!n..ur;ZiHn,WL;rVurIr;ZiH
3510 lMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHpAb3Br;ZiHr;ZuL!!(Ksqu?`G
3511 q>^NEquHcGr;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurIquHcGquHcGr;ZiHr;ZoJ!7UlH!7QK!JH3sq
3512 s!%JCd/X)$s8N2U1G_#As8Fh1rsJ^@1G__=o)7jeFNjda1P,RWs+142rrJ)Yp=oeB!;fbrJ,~>
3513 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kp!!(LH!<:OI!!C[Me'n9r!n..ur;ZiHn,WL;rVurIr;ZiH
3514 lMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHpAb3Br;ZiHr;ZuL!!(Ksqu?`G
3515 q>^NEquHcGr;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurIquHcGquHcGr;ZiHr;ZoJ!7UlH!7QK!JH3sq
3516 s!%JCd/X)$s8N291G_2Fs8Fh1rsJTk1G`^hpA*^P@EecN1P,RWs+142rrIuVp=]Y<!;fbrJ,~>
3517 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kp!!(LH!<:OI!!C[Me'n9r!n..ur;ZiHn,WL;rVurIr;ZiH
3518 lMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHpAb3Br;ZiHr;ZuL!!(Ksqu?`G
3519 q>^NEquHcGr;ZiHr;ZiHr;ZiHrVurIr;ZiHrVurIquHcGquHcGr;ZiHr;ZoJ!7UlH!7QK!JH3sq
3520 s!%JCd/X)$"onO\1G`@gs8Fh1rsJ!P1Ga[:q=iU;:!EY:1P,RWs+142rrI`Op=0;.!;]\qJ,~>
3521 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kp!!(LH!!(LH!!:ULe,97Jdf@kq!!(L<!!(LG!!(LH!!(L6
3522 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LB!!(LH!!(LH!!(LH!<:OI!!(LE
3523 !!(LE!<:OJ!!(LH!!(LH!!(LI!!(LH!!(LI!!(LE!<:OG!<:OJ!!(LH!!:ULe,97Hdt%LM!6tTE
3524 ,6(Zis8FhSrr`6V1H#13r\Fu]TL^m=s4]=c1ce^,rr;sR"obDi3c"0_rs8S*@Ql\MW;lns1BmcU
3525 7lkGRj8T861G_Jrq>U]uWF%eI9S;R.s8Fe`rL?;BM?!=#5X'Aas8W'S%K2ec6&GX9J3Z;Ap&G'k
3526 1]RLO1]%.N1CO/O76ue1pOGLmG4kk7#Q:o<5;brWh>[Edr17%S2+`/3s8W"g=ZnW6Hc#d^#2:pi
3527 1ce^,rVm&oJO)GCp&6cHrs/M-A3VqAHJO/PJcELb!K@'Pg]X2Kqc-XH~>
3528 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kp!!(LH!!(LH!!:ULe,97Jdf@kq!!(L<!!(LG!!(LH!!(L6
3529 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LB!!(LH!!(LH!!(LH!<:OI!!(LE
3530 !!(LE!<:OJ!!(LH!!(LH!!(LI!!(LH!!(LI!!(LE!<:OG!<:OJ!!(LH!!:ULe,97Hdt%LM!6tTE
3531 ,6(Zis8FhSrr`3U1H#13r\Fu\L-RQps.M5)1d5?Prr;sR"oX<E5(NP0rs8Ii=?8HN_#OH61Bm`7
3532 5sBhrj8T7M1G`A:q>U]rQ;ot+<L*CZs8Fe`r..%'U&XFq3^\l)s8W'S%K(c@8YQ1MD)t%CrVuos
3533 1]RLO1]%.N1CO,35"VIJlYS[MN;`bU#Q1/t4?-,poD\b%pkr!13)YR^s8VkP;*$[7Lt)G(#,*h/
3534 1d5?PrVm&`DEU@GrVeVPrs/In><Fl@Mt;N"JcELb!K$jMg'!iEqc-XH~>
3535 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kp!!(LH!!(LH!!:ULe,97Jdf@kq!!(L<!!(LG!!(LH!!(L6
3536 !!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LB!!(LH!!(LH!!(LH!<:OI!!(LE
3537 !!(LE!<:OJ!!(LH!!(LH!!(LI!!(LH!!(LI!!(LE!<:OG!<:OJ!!(LH!!:ULe,97Hdt%LM!6tTE
3538 ,6(Zis8FhSrr`!O1Hka;r\FuOEB>uVs'7E:2+)3%rr;sR"nm("7[a5Srs7tJ:cLUXg&M*O1BmJp
3539 3_#P9j8T3d1Gb9jrs.eA9fP:BW;Z_qr\G#RD)kP1s34b,9rJ!js8Fe`nSL9b_#MY`2bg4Ls8W'S
3540 s8VpOqZ$ON$h8'o;o&FX>;o9Srr2p&mu1+(3`qsLrr3SkHqQF[>F"@Ns5\Q#3'(9/k5PAb>r+8o
3541 6YsmCrrpMP3D$.Jr\OQR#OdUK3BC95qLSZts1eR7K)bPp"H`]\<E4P~>
3542 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(Ku!!(LG!!(LH!!:ULe,97Jdf@kq!!(L=!!(LE!!C[M
3543 !7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5Me+WhBe,01Ge,B@IdfBHt
3544 r;ZrK!!(LF!!(LG!!(LH!!C[Me'n9r!7UlH!7UoI!7UlH"4I5Me,01Ge,97Jdf@kq!!:ULe,97J
3545 df@kr!<:N!!.b-q!<48C<RCdF1]RIWgbU`Krr;sR!2ofPs8N)*q_J:os8W'S!3lDX"B>F$r,DNh
3546 s8W'S!3lDX!*&"Y"+)g[Sb`9dr,)<e"$PN@s8FeSWr4^SF^G#&!a>X(r\FPSrA+Is?MuY]>6"X%
3547 1]RLO1]%.N1B=HR1BDW)rA+R[s8W%<q_J@8b5_L3qD80O!1`mArr2u)q_J@qs8VmorA+FMr\OTS
3548 !W@'91BBMYJcC<$_#FFos7Y4NScJXf<Ib~>
3549 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(Ku!!(LG!!(LH!!:ULe,97Jdf@kq!!(L=!!(LE!!C[M
3550 !7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5Me+WhBe,01Ge,B@IdfBHt
3551 r;ZrK!!(LF!!(LG!!(LH!!C[Me'n9r!7UlH!7UoI!7UlH"4I5Me,01Ge,97Jdf@kq!!:ULe,97J
3552 df@kr!<:N!!.b-q!<48C<RCdF1]RIW_)!l9rr;sR!,qims8N($q_J;Rs8W'S!."N!"GQmUpeL]B
3553 s8W'S!."N!!/9J5"%>"%jn\oWpItH?"&&Cgs8FeSEW%ZoY!;k@!g!B]r\FOorA+JW5Q*A>O8o7Z
3554 1]RLO1]%.N1B;Fn1BFXCrA+S;s8Vmlq_J@?nGiMoqD80O!+#FWrr2t#q_JATs8VXPrA+Fur\OTS
3555 !VoUi1BBc1JcC<$_#FFls7Y.LRK34b<Ib~>
3556 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(Ku!!(LG!!(LH!!:ULe,97Jdf@kq!!(L=!!(LE!!C[M
3557 !7U04"4I5Me*m>>df9Bsqu?`Gr;ZrK!!(L;!!C[M!7UiG!7UlH"4I5Me+WhBe,01Ge,B@IdfBHt
3558 r;ZrK!!(LF!!(LG!!(LH!!C[Me'n9r!7UlH!7UoI!7UlH"4I5Me,01Ge,97Jdf@kq!!:ULe,97J
3559 df@kr!<:N!!.b-q!<48C<RCdF1BmgWO#&S@rr;sR!)3AJs8N'eq_J<1s8W'S!)`\N"Ng]Di'.#o
3560 s8W'S!)`\N!6O:$"$8:poD/CehEC`l")[u9s8FeS9`6aJ_)_HM!mpuIr\FOJrA+Jj3W1`8d/X.F
3561 1]RLO1]%.N1B:,I1BG<PrA+T's8V(Cq_J@Zq>^I`qD80O!(H`?rr2sdq_JB3s8UA'rA+GVr\OTS
3562 !TH?@1BC_UJcC<$_#FFes7XtGOT>5X<Ib~>
3563 s!%IC!7UfFrR:`GrR:]FrmT?s!7UfFrR:`GrR:`GrR:9:qpYNEs3p-2s3pB9s3plGrmUfGs3pB9
3564 s3plGrmUfGs3pZA!7UfFrmLrLdf9CHe,B=Ie,'+Fe,'.De,KCKdfBBrrW)lF!<CUI!!C[M!7UfF
3565 rR:`GrR:cH!7UlH!n.,LrmLlJdt%LM!6tTE,6(Zis8"MP251$Lr\FUCd/EtD$'!=+rT#aj3rf6Z
3566 1D*@Kh(piIs8U%o1I9.Zl^%SNr\F^PmG0QS3TL,A4u5"`q>UiB1G_beq49Au;?-[q1BL;<jSgq?
3567 :@7$s1HGL8r\FUMmH"7&#>X[G1G_&ks8FhRs8FhKs8FeU:$q$@1F5f`i\NANs8U.r1P"ijd5*RK
3568 s8P8=1VNeZ`HhL`4u5".rq"*Srr3Ohd.dM"1G_)ls1^?G9BGr:r\OTS$-4nYJF*6^1G_OPs+13c
3569 rrJ)Yp=oeB!;fbrJ,~>
3570 s!%IC!7UfFrR:`GrR:]FrmT?s!7UfFrR:`GrR:`GrR:9:qpYNEs3p-2s3pB9s3plGrmUfGs3pB9
3571 s3plGrmUfGs3pZA!7UfFrmLrLdf9CHe,B=Ie,'+Fe,'.De,KCKdfBBrrW)lF!<CUI!!C[M!7UfF
3572 rR:`GrR:cH!7UlH!n.,LrmLlJdt%LM!6tTE,6(Zis8"MP2UDC&r\FRYiVic_N8==-eh]*Ls8W'S
3573 &U!f^1G_5ps*QUY<ndN0IK0?H1Bhpp^G@Z0j8T3>1Geq(rsO621N`0XFYbh%s8W'S!dOI^r\Fe)
3574 pW,-H5QCc_1BMgqb5O1%H2#B91I(p>r\OQRr\O<Kr\FV#pWEIk-$f7+1G_8qs*lg\W:]o!1G`P@
3575 s#)Yhi;W,QAH2Zf1GdtgmC-X*rt(.Fq>Af"1IM3BEAKCjnaUPs1]RI]IkrmZo_H0V1Ll"9JcEOc
3576 !K$jMg'!iEqc-XH~>
3577 s!%IC!7UfFrR:`GrR:]FrmT?s!7UfFrR:`GrR:`GrR:9:qpYNEs3p-2s3pB9s3plGrmUfGs3pB9
3578 s3plGrmUfGs3pZA!7UfFrmLrLdf9CHe,B=Ie,'+Fe,'.De,KCKdfBBrrW)lF!<CUI!!C[M!7UfF
3579 rR:`GrR:cH!7UlH!n.,LrmLlJdt%LM!6tTE,6(Zis8"MP5jeRNr\FS,mJ[%kT]Q.J^G@Zes8W'S
3580 &Yf,Y1G`G=s%tR.Hfk4Q?iU0*1BjNLM)-qqj8T3=1Gf"*rsM[[1S+:&9f"TFs8W'S!i5^Ur\FeU
3581 qiETiAH2]/1BOBLOo@-AV>H?11M$Ocr\OQRr\O<Kr\FVOqiUk6-)LL#1G`SAs%tR._>3bp1Gc98
3582 s"uSgmeu1F;#gPQ1GeItj/GlSrt(jbrV=2a1NWTr9f"SopuG'H1]RI];):#Eq=U:71U)H1JcEOc
3583 !J:@FeHD!7qGgOG~>
3584 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCd/Wnt"%LW:s8FeS[Jg+.rjHB(2?#B52?3^U1CM)"rA-5d
3585 s8Q@\1Um8]r\F_ps8=`01unT<4u5"`q>Uh21Gd,Ps7nH,3WK-Y1BPPqrVeSX_Z0Tm1Go.3r\FVp
3586 s8DpQ#K$N?2)@)hs8FhRs8FhKs8FeU`W,o91C1ktr\ZJgs8QF$1C5u>s*HOX6ueI6rr31L1G_F=
3587 Pfj"*"TGi@5rJWt#rVb_>r+:Us8Voo1]RIT?MQAW2M(mZs1nX8N;rV,"J,Vj<E4P~>
3588 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCd/Wnt"'Y3os8FeSmJ[%frLd=W2#]942?3^U1CNaQr%g,d
3589 s8P5<1[Y)>r\F`Js84Z/2<4]=2D[/dq>Ugd1GeV%s7.s%56(Z^1BR+Hr;JJWnc/PE1H#44r\FWG
3590 s8;jP#P%im1c%#hs8FhRs8FhKs8FeUnc/Od1C3ONrA6;fs8P7X1C6)As$ee#<-Xtfrr30l1G`!T
3591 S_F)C"T=us4Z*-o#rVb_4Ynnas8VWg1]RIT4o$l63J%3]s1nX8M?!;'"I]>f<E4P~>
3592 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCd/Wnt"*=;<s8FeSp\k*ppl/352#]944TGH\1CO$YnM;s[
3593 s8P&71\^eHr\F`Rs7%m$2rjo?2)@&eq>Ug_1Gek,s2ZuP@K6B,1BRCPnGY3Kq>^4H1H>F7r\FWO
3594 s7$"D#PnDp1c%,ks8FhRs8FhKs8FeUq>]s`1C3gVpbXcds8P(S1C6eUs#`(n?%/^=rr30b1G`<c
3595 VsXK`"SdsT3]-gl#sA7f3&<Ads8U%:1]RIT3;G?19nE=qs1nX8K)bPp"H`]\<E4P~>
3596 s!!!oJH16$JH1B(s!%JCd/X)$s8N;u]/)61s8W'S!;l`p!5\Ies8W'S!rW)ur\OTS"#i"lqYU<l
3597 1BRLSs8Fh7rr[U(1S+@A"$A@qqYpNp1BKH6s8FeUr;Zfr1C*gWs"uSgs8W'S!rW)ur\FfVs8Or4
3598 1]RLS1]IFR1\^qK1BRLSs8Fe[qu?[R1Gf(22u#3/rrVe72Z>K:1j&cto5utj1B]OVs8Tq21]RIW
3599 3\rSgrr;sRs8N'XpbRL$JcEOc!K@'Pg]X2Kqc-XH~>
3600 s!!!oJH16$JH1B(s!%JCd/X)$s8N;nT//9+s8W'S!<2rs!.jr%s8W'S!ri6"r\OTS"#Vkjrql`p
3601 1BRRUs8Fh7rrY\G1ZeH4$T0^rrr<#t1G^ogs8FeUrr<#t1C*pZs"lMfs8W'S!ri6"r\FfYs8Oo3
3602 1]RLS1]IFR1\^qK1BRRUs8Fe[rr<!T1Gf(22>B!-rrV.h2#]981njsLiF=_D1B]P.s8RZG1]RIZ
3603 2)@&fs8W&s1]RIT2>AtYs+13crrIuVp=]Y<!;fbrJ,~>
3604 s!!!oJH16$JH1B(s!%JCd/X)$s8N;gF#,VCs8W'Sr;Qarq(r'Nr\OTS!<)mQs8N-W1Gen-r\OTS
3605 !<)mQj8T3C1GeXurrP&61]ICXq(jfis8W'Srr;sRrr3*X1Gf(2r\OQRr\OQR">hnjs8W'Srr;sR
3606 p](4Krr;sRrr3-Y1Gf(22#&m,rrTo62#]982:hg-^/Qrg1B]Sds8Q'o1]RIV1c$rerrDlo1]RIT
3607 2#&kXs+13crrI`Op=0;.!;]\qJ,~>
3608 s!!!oJH16$JH1B(s!%JCd/X)$rr30$1G^ogs8FhPrrl.R1TC6Lr\OTSr\OQRr\OTS"'m]=\,64)
3609 1]IFR1ZSK<f/#3OqYL4"@5B^\s8VmN1HGL8r\OQRr\OQRr\OTSr\OQRr\OQRr\OTSr\OQRr\O<K
3610 r\OQRr\OQRr\OTS"(!c>anPf=qq8A51H>@5%K"hd1G_#js%Y@+WVZSm1]RIZ>r+:Zs8Voo1]RIW
3611 ?8FCZJcC<$])Meis7Y4NScJXf<Ib~>
3612 s!!!oJH16$JH1B(s!%JCd/X)$rr30"1G^rhs8FhPrrkD=1X,gqr\OTSr\OQRr\OTS"$JFrmJHq_
3613 1]IFR1ZSK<QSUF)rqcX&4u5"cs8VXG1Htj=r\OQRr\OQRr\OTSr\OQRr\OQRr\OTSr\OQRr\O<K
3614 r\OQRr\OQRr\OTS"$JFro(W.fo[Kcp1Hk^:%J8/J1G_2os#Dkkbl.J=1]RIZ4Ynnbs8VWg1]RIW
3615 4YnnbJcC<$])Mefs7Y.LRK34b<Ib~>
3616 s!!!oJH16$JH1B(s!%JCd/X)$rr3/m1G_8qs8FhPrrk;:1Z/3%r\OTSr\OQRr\OTS"#r(mp\Y!i
3617 1]IFR1ZSK;>;J("q>Ug_1Gek,s2ZuP@K6B,1]IFR1]IFR1]RLS1]IFR1]IFR1]RLS1]IFR1\^qK
3618 1]IFR1]IFR1]RIW3&<Adp\tE`cAOJ7=oJ@0m*:MF1KjbX2D[/HrpftDs8N9_1Gek,s2=mms8N0\
3619 1GeiXs+13]rrI`Op=0;.!;]\qJ,~>
3620 s!!!oJH2,=rR9a+rR6;tP5tV,s&IGGr\OTS#5Ged1HGL8r\OKP"\1@)[/.0/1]RLS1]IFR1]RI]
3621 `A9;9b5:Rrs8W'Srr;sRj8TqoBeqP=^[qEk_0,dt1G_bfq4BH!;#gRp1]IFR1]IFR1]RLS1]IFR
3622 1]IFR1]RLS1]ICV68LF5q#C=Lrr;sRrr;sRs8OCe1G_JCq>'!SD?'W7Yiu&J1G^ogs&6/crT5ml
3623 2?3\H1GcE7[/Ml]rs$4o1Jd30Rf5,Crs?e'1I]L_q;JSqJcC<$_#FFos7Y4NScJXf<Ib~>
3624 s!!!oJH2,=rR9a+rR6;tP5tV,s&IGGr\OTS#4e?A1Htj=r\OKP"ZS:ofCkF-1]RLS1]IFR1]RI]
3625 Ho!Q[g\p,`s8W'Srr;sRj8Tqk6o-W5cM.4tZ=<i^1Ga.Do5uiFI/j6G1]IFR1]IFR1]RLS1]IFR
3626 1]IFR1]RLS1]ICV2`!8Kq#C=Lrr;sRrr;sRs8OBs1G`FmrV"p@>lXh<^[V6Q1G^ogs(T7;rm`e\
3627 2?3\91GdYVPQ!B<rs!I!1O8T^E;hZnrs=951LSr8p=Z9IJcC<$_#FFls7Y.LRK34b<Ib~>
3628 s!!!oJH2,=rR9a+rR6;tP5tV,s&IGGr\OTS#3p1a1LgCar\OKP"Z8(ll0i0^1]RLS1]IFR1]RI]
3629 :bsnTkkrt?s8W'Srr;sRj8TqZ4#8[Gg%tO#V,.+g1GbTtk=m`g`W,u;1]IFR1]IFR1]RLS1]IFR
3630 1]IFR1]RLS1]ICV2)@&Xq#C=Lrr;sRrr;sRs8OBC1Ga^GrU\F)9`P-Bbk:qB1G_2os*r8crO"F;
3631 4obO>1Ge:aAH"Cbrru1R1SOX+9E$aIrs;RZ1PFlgo?it"JcC<$_#FFes7XtGOT>5X<Ib~>
3632 s!##SqpYNErmUlIqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pE:!7Tj+!7UWA!7Ta(
3633 !7U66s3pZA!7T^'!7QK!P5tV,s&IGGpbMtos8W'Sr;Qc)rA+FGr\OTSr\OQRr\OTS!W6m51]RLS
3634 1]IFR1ZJE8pilNi!rr16q_J=;h#IER1]IFR1]IFR1]RLS1]IFR1]IFR1]RLS1]ICSSGY2>s8FhR
3635 s8FhRs8FhSrrN(Eq(r'NqD/1Bs8VpO"%N=j[J_l]9)^XHrrMporA+FLr\OTS!W@??1P,RWs1nX8
3636 N;rV,"J,Vj<E4P~>
3637 s!##SqpYNErmUlIqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pE:!7Tj+!7UWA!7Ta(
3638 !7U66s3pZA!7T^'!7QK!P5tV,s&IGGpbMuLs8W'Sr;Qb:rA+Fjr\OTSr\OQRr\OTS!VfCd1]RLS
3639 1]IFR1ZJE8m9KHC!rr!dq_J=Gp](9m1]IFR1]IFR1]RLS1]IFR1]IFR1]RLS1]ICS<W"ZLs8FhR
3640 s8FhRs8FhSrrMptq(r'NqD/1]s8VpO"(D60EW%ZnD>l?krrM[QrA+Ftr\OTS!Vojn1P,RWs1nX8
3641 M?!;'"I]>f<E4P~>
3642 s!##SqpYNErmUlIqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pE:!7Tj+!7UWA!7Ta(
3643 !7U66s3pZA!7T^'!7QK!P5tV,s&IGGpbN!*s8W'Sr;QajrA+GPr\OTSr\OQRr\OTS!T60=1]RLS
3644 1]IFR1ZJE8c:.Ob!rq(>q_J=hr;Zfr1]IFR1]IFR1]RLS1]IFR1]IFR1]RLS1]ICS62WP8s8FhR
3645 s8FhRs8FhSrrM7Kq(r'NqD/2Hs8VpO"/5bp9`6aIW;\UQrrLA'rA+GUr\OTS!Tl`E1P,RWs1nX8
3646 K)bPp"H`]\<E4P~>
3647 s!$_.!7T0m"4I5Me+WhBe,'+Fe+*J=e,97Ndf9Bs!!(L4!!C[M!7UE;"4I5Me+WhEdf9Bsn,NR>
3648 !!(LB!!C[M!7UE;!7Tj+!7UWA!7U-3!7UZB!7U35!7UWA!7U66!7UN>!7QK!P5tV,s&IGGr%eF4
3649 6=m7ts8FhPrrr@e76,)Lr\OTSr\OQRr\OQR#lUl64Z-6;s8W'Srr;sRi;XD4I8E$`6ti:os8Ag#
3650 4>of_jo5;Z1]IFR1]IFR1]RLS1]IFR1]IFR1]RLS1]ICUpO#:+1]%.N1]IFR1]IFR1]ID"rk*,;
3651 2EOok`rH)#O]XV&97?%(s5fAF3B'TZkl:\]Q:3fJmJ\p@rs8:K5Ws;^1G^ofrs8V:DFHHF<J/;B
3652 s+13crrJ)Yp=oeB!;fbrJ,~>
3653 s!$_.!7T0m"4I5Me+WhBe,'+Fe+*J=e,97Ndf9Bs!!(L4!!C[M!7UE;"4I5Me+WhEdf9Bsn,NR>
3654 !!(LB!!C[M!7UE;!7Tj+!7UWA!7U-3!7UZB!7U35!7UWA!7U66!7UN>!7QK!P5tV,s&IGGr%eF6
3655 8TDTGs8FhPrrr7I4[4Dmr\OTSr\OQRr\OQR#l9rj3B1H^s8W'Srr;sRiVsPh\TCD'2bJ+ps8Vn[
3656 <B3'=PPP4Xr\OQRr\OQRr\OTSr\OQRr\OQRr\OTSr\OQR!pjYar\OENr\OQRr\OQRr\OQR,lO]Q
3657 5W(]0O4O@2dY(FU3Dkh4s8UN#:cCC3Nqr_TqL(LkIf'+#rr38cDEC1CpbO]brr39&WFS7O4^='!
3658 JcC<$_#FFls7Y.LRK34b<Ib~>
3659 s!$_.!7T0m"4I5Me+WhBe,'+Fe+*J=e,97Ndf9Bs!!(L4!!C[M!7UE;"4I5Me+WhEdf9Bsn,NR>
3660 !!(LB!!C[M!7UE;!7Tj+!7UWA!7U-3!7UZB!7U35!7UWA!7U66!7UN>!7QK!P5tV,s&IGGr%eF8
3661 :OUsrs8FhPrrqY$3CK23r\OTSr\OQRr\OQR#j[=C2EYs3s8W'Srr;sRiVsPdW+naZ3Dk4?s8V55
3662 9/\n<V>^Dnr\OQRr\OQRr\OTSr\OQRr\OQRr\OTSr\OQR!m4b-r\OENr\OQRr\OQRr\OQR,kdU0
3663 4Z,Q:S*0hO^ii7+4'JBWs8TlX82WJ4UAb,ll"N.GQMpe=rr38F?T1QRkVG"_rr38tQs2^26=cSK
3664 JcC<$_#FFes7XtGOT>5X<Ib~>
3665 s!$_.!7T3n"4I5Me+WhBe,'+Fe+!D<e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=
3666 !!(LH!!(LD!!(LH!!(L;!!(L,!!(LA!!(LH!!(L-!!(L5!!(LA!!(L'!!(K!!0[E_,6(Yos+144
3667 rr_^G1Hg<hJcE+W!K@'Pg]X2Kqc-XH~>
3668 s!$_.!7T3n"4I5Me+WhBe,'+Fe+!D<e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=
3669 !!(LH!!(LD!!(LH!!(L;!!(L,!!(LA!!(LH!!(L-!!(L5!!(LA!!(L'!!(K!!0[E_,6(Yos+144
3670 rr^q11J*/tJcE+W!K$jMg'!iEqc-XH~>
3671 s!$_.!7T3n"4I5Me+WhBe,'+Fe+!D<e,97Jdf@kq!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=
3672 !!(LH!!(LD!!(LH!!(L;!!(L,!!(LA!!(LH!!(L-!!(L5!!(LA!!(L'!!(K!!0[E_,6(Yos+144
3673 rr\9;1Q$b`JcE+W!J:@FeHD!7qGgOG~>
3674 ruqLEdfBBrrW)oGrW)oGrrE#Hd/X0qrVurIp](<CqZ$WFlMq"8!7UlH!7U66!7UlH!7UK=!7UlH
3675 !7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UE;!7U?9rR:`GrR:cH!Rh&Je,B@HdfBHtrW)rHpAk6B
3676 !<CUI!<:OH!<(CH!!1OKrmUiHrR:`GrR:ZE!7UWA!7UiG!Rh&Je,KCKdfBBrr;clHr;ZiHrVurI
3677 qu?`GJH1l6s!%JCJcC<$li.5j[dX1MAhu5[JcC<$[/U/cs7Y4NScJXf<Ib~>
3678 ruqLEdfBBrrW)oGrW)oGrrE#Hd/X0qrVurIp](<CqZ$WFlMq"8!7UlH!7U66!7UlH!7UK=!7UlH
3679 !7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UE;!7U?9rR:`GrR:cH!Rh&Je,B@HdfBHtrW)rHpAk6B
3680 !<CUI!<:OH!<(CH!!1OKrmUiHrR:`GrR:ZE!7UWA!7UiG!Rh&Je,KCKdfBBrr;clHr;ZiHrVurI
3681 qu?`GJH1l6s!%JCJcC<$li.6,`qB2Q6o-X'JcC<$[/U/`s7Y.LRK34b<Ib~>
3682 ruqLEdfBBrrW)oGrW)oGrrE#Hd/X0qrVurIp](<CqZ$WFlMq"8!7UlH!7U66!7UlH!7UK=!7UlH
3683 !7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UE;!7U?9rR:`GrR:cH!Rh&Je,B@HdfBHtrW)rHpAk6B
3684 !<CUI!<:OH!<(CH!!1OKrmUiHrR:`GrR:ZE!7UWA!7UiG!Rh&Je,KCKdfBBrr;clHr;ZiHrVurI
3685 qu?`GJH1l6s!%JCJcC<$li.6AdeWUI3\rSNJcC<$[/U/Ys7XtGOT>5X<Ib~>
3686 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me'A!oe,B=JdfBBrqu?`GquH`Fm/R7;!!(LH!!(L6!!(LH
3687 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L:!!(L;!!(LH!!:ULe,97Kdf@kGrW!#K
3688 !7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(LA!!(LG!<:OI
3689 !!C[M!7UoI!7UlH!7UlH!7UoI!7UiG!7QK!P5tV,s&FXMJcG'9qD/.LqLSZts0Ve,N;rV,"J,Vj
3690 <E4P~>
3691 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me'A!oe,B=JdfBBrqu?`GquH`Fm/R7;!!(LH!!(L6!!(LH
3692 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L:!!(L;!!(LH!!:ULe,97Kdf@kGrW!#K
3693 !7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(LA!!(LG!<:OI
3694 !!C[M!7UoI!7UlH!7UlH!7UoI!7UiG!7QK!P5tV,s&FXMJcG'9qD/.lrdk*#s0Ve,M?!;'"I]>f
3695 <E4P~>
3696 s!%IC!7UoI!n..ur;ZoJ!7UlH"4I5Me'A!oe,B=JdfBBrqu?`GquH`Fm/R7;!!(LH!!(L6!!(LH
3697 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L:!!(L;!!(LH!!:ULe,97Kdf@kGrW!#K
3698 !7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(LA!!(LG!<:OI
3699 !!C[M!7UoI!7UlH!7UlH!7UoI!7UiG!7QK!P5tV,s&FXMJcG'9qD/,=JcC<$Zi:&Xs7XtGOT>5X
3700 <Ib~>
3701 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kp!!(LH!<:OI!!(LI!!(LC!!(L;!<:OI!!(LH!!(L6!!(LH
3702 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L9!!(L;!<:OG!<:OH!!(LH!!:ULe,97H
3703 e+!D@df@hse,97He,B=Ie,'+Fe,97Jdf9CGdf9CFe,97He+NbAe,01Ge,97Kdf9Bsq#CEDr;ZiH
3704 rVurIqu?`GJH1l6s!%JCJcC<$li.4JK1\!c@&!UNs+13VrrJ)Yp=oeB!;fbrJ,~>
3705 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kp!!(LH!<:OI!!(LI!!(LC!!(L;!<:OI!!(LH!!(L6!!(LH
3706 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L9!!(L;!<:OG!<:OH!!(LH!!:ULe,97H
3707 e+!D@df@hse,97He,B=Ie,'+Fe,97Jdf9CGdf9CFe,97He+NbAe,01Ge,97Kdf9Bsq#CEDr;ZiH
3708 rVurIqu?`GJH1l6s!%JCJcC<$li.13F@%iOBsiNlJcE%U!K$jMg'!iEqc-XH~>
3709 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kp!!(LH!<:OI!!(LI!!(LC!!(L;!<:OI!!(LH!!(L6!!(LH
3710 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L9!!(L;!<:OG!<:OH!!(LH!!:ULe,97H
3711 e+!D@df@hse,97He,B=Ie,'+Fe,97Jdf9CGdf9CFe,97He+NbAe,01Ge,97Kdf9Bsq#CEDr;ZiH
3712 rVurIqu?`GJH1l6s!%JCJcC<$li.0sB0A1DFio:8JcE%U!J:@FeHD!7qGgOG~>
3713 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kp!!(LH!!(LH!!(LI!!(LC!!(L<!!(LG!!(LH!!(L6!!(LH
3714 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L9!!(L9!<:OG!<:OJ!!(LH!!:ULe,97H
3715 e+!D@df@hse,97He,B=Ie,'+Fe,97Jdf@kq!!:ULe+`nCe+NbAe,04Ge,B=Ldf9Bsq#CEDqu?fI
3716 !7UfF!7QK!P5tV,s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
3717 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kp!!(LH!!(LH!!(LI!!(LC!!(L<!!(LG!!(LH!!(L6!!(LH
3718 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L9!!(L9!<:OG!<:OJ!!(LH!!:ULe,97H
3719 e+!D@df@hse,97He,B=Ie,'+Fe,97Jdf@kq!!:ULe+`nCe+NbAe,04Ge,B=Ldf9Bsq#CEDqu?fI
3720 !7UfF!7QK!P5tV,s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
3721 s!%IC!7UiG!7UlH!n..ur;ZrK!!(Kp!!(LH!!(LH!!(LI!!(LC!!(L<!!(LG!!(LH!!(L6!!(LH
3722 !!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(L9!!(L9!<:OG!<:OJ!!(LH!!:ULe,97H
3723 e+!D@df@hse,97He,B=Ie,'+Fe,97Jdf@kq!!:ULe+`nCe+NbAe,04Ge,B=Ldf9Bsq#CEDqu?fI
3724 !7UfF!7QK!P5tV,s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
3725 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(Ku!!(LG!!(LH!!C[M!7UiG!7UlH!7UK=!7UcE"4I5M
3726 e*-i7df9Bsn,NR>!!(LG!!(LH!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsli7%7nc/[=r;ZoJ!7UlH
3727 !n..ur;ZoJ!7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97H
3728 e+NbAe,01HdfBBrrVurIq#CEDqu?fI!7UfF!7QK!P5tV,s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
3729 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(Ku!!(LG!!(LH!!C[M!7UiG!7UlH!7UK=!7UcE"4I5M
3730 e*-i7df9Bsn,NR>!!(LG!!(LH!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsli7%7nc/[=r;ZoJ!7UlH
3731 !n..ur;ZoJ!7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97H
3732 e+NbAe,01HdfBBrrVurIq#CEDqu?fI!7UfF!7QK!P5tV,s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
3733 s!%IC!7UiG!7UlH!n..ur;ZrK!!(LI!!(Ku!!(LG!!(LH!!C[M!7UiG!7UlH!7UK=!7UcE"4I5M
3734 e*-i7df9Bsn,NR>!!(LG!!(LH!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsli7%7nc/[=r;ZoJ!7UlH
3735 !n..ur;ZoJ!7UoIs3poH!7UWA"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97H
3736 e+NbAe,01HdfBBrrVurIq#CEDqu?fI!7UfF!7QK!P5tV,s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
3737 s!%IC!7UfFrR:`GrR:]FrmT?s!7UfFrR:`G!7UfFrR:9:qpYNEs3p-2s3pB9s3plGrmUfGs3pB9
3738 s3plGrmUfGs3p96!7UH<rR:`GrR:cH!7UlH!n.,LrmLlJe,B@He+WhBe,B=Kdf9CGe,KFHe,KCJ
3739 e,97Jdf9CIdfTU!!!)uHrW)lFp](<Cqu?`Gq>^NEqZ-QCr;ZiHq>^NEJH1l6s!%JCJcC<$JcC<$
3740 Q2^lDs7Y4NScJXf<Ib~>
3741 s!%IC!7UfFrR:`GrR:]FrmT?s!7UfFrR:`G!7UfFrR:9:qpYNEs3p-2s3pB9s3plGrmUfGs3pB9
3742 s3plGrmUfGs3p96!7UH<rR:`GrR:cH!7UlH!n.,LrmLlJe,B@He+WhBe,B=Kdf9CGe,KFHe,KCJ
3743 e,97Jdf9CIdfTU!!!)uHrW)lFp](<Cqu?`Gq>^NEqZ-QCr;ZiHq>^NEJH1l6s!%JCJcC<$JcC<$
3744 Q2^lAs7Y.LRK34b<Ib~>
3745 s!%IC!7UfFrR:`GrR:]FrmT?s!7UfFrR:`G!7UfFrR:9:qpYNEs3p-2s3pB9s3plGrmUfGs3pB9
3746 s3plGrmUfGs3p96!7UH<rR:`GrR:cH!7UlH!n.,LrmLlJe,B@He+WhBe,B=Kdf9CGe,KFHe,KCJ
3747 e,97Jdf9CIdfTU!!!)uHrW)lFp](<Cqu?`Gq>^NEqZ-QCr;ZiHq>^NEJH1l6s!%JCJcC<$JcC<$
3748 Q2^l:s7XtGOT>5X<Ib~>
3749 s!!!oc2[jnhZ*Z*iW/l)g&M-%^&\,\rr<&JjT,8.JH1l6s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf
3750 <Ib~>
3751 s!!!oc2[jnhZ*Z*iW/l)g&M-%^&\,\rr<&JjT,8.JH1l6s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b
3752 <Ib~>
3753 s!!!oc2[jnhZ*Z*iW/l)g&M-%^&\,\rr<&JjT,8.JH1l6s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X
3754 <Ib~>
3755 s!!!oJH1o7!7QK!JH59As!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3756 s!!!oJH1o7!7QK!JH59As!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3757 s!!!oJH1o7!7QK!JH59As!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3758 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3759 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3760 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3761 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3762 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3763 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3764 s!$b/!7U66s3p34qpYNErmUlIqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3oEs!7Tj+
3765 !7UWA!7Ta(!7U66s3poHrR9j.!n.,LrR6;tVuZiAs&FXMjT#5[q>^Hpi;`fWnc/Uhkl1e`KdI!(
3766 lMpkaoDegjm/R(cJcC<$dJj6+s7Y4NScJXf<Ib~>
3767 s!$b/!7U66s3p34qpYNErmUlIqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3oEs!7Tj+
3768 !7UWA!7Ta(!7U66s3poHrR9j.!n.,LrR6;tVuZiAs&FXMjT#5[q>^Hpi;`fWnc/Uhkl1e]C)[6T
3769 lMpkaoDegjm/R(cJcC<$dJj6(s7Y.LRK34b<Ib~>
3770 s!$b/!7U66s3p34qpYNErmUlIqpPNFqpY'8rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3oEs!7Tj+
3771 !7UWA!7Ta(!7U66s3poHrR9j.!n.,LrR6;tVuZiAs&FXMjT#5[q>^Hpi;`fWnc/Uhkl1eG<"o?5
3772 lMpkaoDegjm/R(cJcC<$dJj6!s7XtGOT>5X<Ib~>
3773 s!%.:!7UZB!7U35!7U!/"4I5Me+WhDdf@ka!!(LH!!^mP!7LoJe*-i7df9Bsn,NR>!!(LB!!C[M
3774 !7UE;"4I5Me+WhEdf9Bse,TKthuEc+p&G*AkPtV3pAb3Bl2Uh5rVurIr;ZiHp](<Cn,NO=!7UlH
3775 !7QK!W;urBs&H3$rrC.?!jVeLpAb-mq>^Hpi;`fWnc/Uhrr;uumJd9`!+#9^s8N*!rs%A'.gH>4
3776 L&CuN!:9ac!.k0$s3^iIN;rV,"J,Vj<E4P~>
3777 s!%.:!7UZB!7U35!7U!/"4I5Me+WhDdf@ka!!(LH!!^mP!7LoJe*-i7df9Bsn,NR>!!(LB!!C[M
3778 !7UE;"4I5Me+WhEdf9Bse,TKthuEc+p&G*AkPtV3pAb3Bl2Uh5rVurIr;ZiHp](<Cn,NO=!7UlH
3779 !7QK!W;urBs&H3$rrC.?!`/knpAb-mq>^Hpi;`fWnc/Uhrr;uumJd8]!202Qs8N*!rs$MR+9N'7
3780 TD\`h!:9ac!.k0$s3^iIM?!;'"I]>f<E4P~>
3781 s!%.:!7UZB!7U35!7U!/"4I5Me+WhDdf@ka!!(LH!!^mP!7LoJe*-i7df9Bsn,NR>!!(LB!!C[M
3782 !7UE;"4I5Me+WhEdf9Bse,TKthuEc+p&G*AkPtV3pAb3Bl2Uh5rVurIr;ZiHp](<Cn,NO=!7UlH
3783 !7QK!W;urBs&H3$rrC.?![.QLpAb-mq>^Hpi;`fWnc/Uhrr;uumJd80!6"m$s8N*!rs#]*('>7C
3784 ^AS$2!:9ac!.k0$s3^iIK)bPp"H`]\<E4P~>
3785 s!$b/!7U35!7U$0"4I5Me+WhEdf9Bsm/R.8r;ZoJ!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH
3786 !7UK=!7UlH!7U`D!7UlH!7TEt!7Tm,!7UWA!7UlH!7Tp-!7U35!7UoI!7UlH!7U]C!7UH<"4I5M
3787 e,97Hdt%Lu!<48C<NZ<$!6P6Dr>P_=kkG,W!;ZZp!9!nW!:9ac!:Bdf*<>Ngrs'd0g&'uX!'L5[
3788 rrDEcrr@WMJcF-t!K@'Pg]X2Kqc-XH~>
3789 s!$b/!7U35!7U$0"4I5Me+WhEdf9Bsm/R.8r;ZoJ!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH
3790 !7UK=!7UlH!7U`D!7UlH!7TEt!7Tm,!7UWA!7UlH!7Tp-!7U35!7UoI!7UlH!7U]C!7UH<"4I5M
3791 e,97Hdt%Lu!<48C<NZ<$!6P6Dq?I!*qY1$i!;ZZp!9!nW!:9ac!:Bdf#6=Y^rs(Z\jo*q/!-eDA
3792 rrDEcrr@WMJcF-t!K$jMg'!iEqc-XH~>
3793 s!$b/!7U35!7U$0"4I5Me+WhEdf9Bsm/R.8r;ZoJ!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH
3794 !7UK=!7UlH!7U`D!7UlH!7TEt!7Tm,!7UWA!7UlH!7Tp-!7U35!7UoI!7UlH!7U]C!7UH<"4I5M
3795 e,97Hdt%Lu!<48C<NZ<$!6P6DkQ:f(rV-?l!;ZZp!9!nW!:9ac!:Bdf"9AG^rs)N0meb-L!5JL4
3796 rrDEcrr@WMJcF-t!J:@FeHD!7qGgOG~>
3797 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIp](<CrVuuJ!<1I6!!:UL
3798 e,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He'n?te*[57e,B@Ge,KCK
3799 dfBBrrW)rH!<CUJ!<1IA!<:LK!7UlHs3poHrR:cH!Rh&Je,B@Ge,B@Ge,01Ge,B=Kdf9CIdfKNu
3800 !<1II!<(CF!<(CD!!(LE!!(K!!3#tu,6(ZFs8N)@rrh9\$ij3"s8N)ps8N)Ws8N)cs8N)ds8N)U
3801 rrW&t"TAB#!:9ac!.k0$s3^iIN;rV,"J,Vj<E4P~>
3802 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIp](<CrVuuJ!<1I6!!:UL
3803 e,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He'n?te*[57e,B@Ge,KCK
3804 dfBBrrW)rH!<CUJ!<1IA!<:LK!7UlHs3poHrR:cH!Rh&Je,B@Ge,B@Ge,01Ge,B=Kdf9CIdfKNu
3805 !<1II!<(CF!<(CD!!(LE!!(K!!3#tu,6(ZFs8N)@rrf_0,65.Gs8N)ps8N)Ws8N)cs8N)ds8N)U
3806 rrVin#lXf'!:9ac!.k0$s3^iIM?!;'"I]>f<E4P~>
3807 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIp](<CrVuuJ!<1I6!!:UL
3808 e,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He'n?te*[57e,B@Ge,KCK
3809 dfBBrrW)rH!<CUJ!<1IA!<:LK!7UlHs3poHrR:cH!Rh&Je,B@Ge,B@Ge,01Ge,B=Kdf9CIdfKNu
3810 !<1II!<(CF!<(CD!!(LE!!(K!!3#tu,6(ZFs8N)@rrc4"$io8\s8N)ps8N)Ws8N)cs8N)ds8N)U
3811 rrU^N*rZ-=!:9ac!.k0$s3^iIK)bPp"H`]\<E4P~>
3812 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LI!!1OKrmUcF!7UoI
3813 s3prI!7U?9"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He'e9s
3814 e*m>;e,97Jdf@kq!!C[Me'n9r!n..urW)uIr;ZiHp&G6E!7Lqsr;ZiHrVurIr;ZrK!7TEr!!(LF
3815 !!:ULe,97He,97He,B=Qdf@hs!7Lqse,B=Ldf9Bsqu?`Gr;ZiHr;ZiHq>^NEJH2VKs!%JCd/X+G
3816 $iPGg%qkq>Eu,0]q>UC*o8"4c)eo*Is8.Br"pm,Ps8)frrs&C\0F8.P\c2X/!!;je"5Wt[I/of<
3817 &H)P4fes!bbl@bCrs%.7"Y@mu!;ZX&70&t[s+M$as7H?trr33#NA(YI5Ipdnrr<`.?O.L)s8VtJ
3818 -jBu7QN-sb!<<)r!<<''r/EB:$pV<!s8)d$s7UX]"qjVPrr;uu!qo7hqZ$QqqYpWo!!`E%rrE&u
3819 #536c"qjVPrr3N%E?56(L]@AS!<<)e)$Hdes+14%rrJ)Yp=oeB!;fbrJ,~>
3820 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LI!!1OKrmUcF!7UoI
3821 s3prI!7U?9"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He'e9s
3822 e*m>;e,97Jdf@kq!!C[Me'n9r!n..urW)uIr;ZiHp&G6E!7Lqsr;ZiHrVurIr;ZrK!7TEr!!(LF
3823 !!:ULe,97He,97He,B=Qdf@hs!7Lqse,B=Ldf9Bsqu?`Gr;ZiHr;ZiHq>^NEJH2VKs!%JCd/X+G
3824 $i+*>(l/.a=V)-`rr2p/[email protected]%l3ss7U+H!t@T&s8)frrs&4?,6e`Vh>[HS!!;@=!T!bY,QQ?p
3825 ,lIZHXs=-:nGiRgrs#VO"@DVY!;ZX&&HM%ps!&`fs6'Fprr32sFX%)&:u2-Nrr<`&63JU;s8Ve+
3826 *<Qa;ZN'q)!<<)r!<<''pN7\b&Q%<[s8)d$s63i,!uPD2rr;uu!pD?>qZ$QqqYpWj!"8c*rrE&u
3827 #3fG2!uPD2rr3Mj=qh)kVZ6Yr!<<)J"prk3s+14%rrIuVp=]Y<!;fbrJ,~>
3828 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LI!!1OKrmUcF!7UoI
3829 s3prI!7U?9"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He'e9s
3830 e*m>;e,97Jdf@kq!!C[Me'n9r!n..urW)uIr;ZiHp&G6E!7Lqsr;ZiHrVurIr;ZrK!7TEr!!(LF
3831 !!:ULe,97He,97He,B=Qdf@hs!7Lqse,B=Ldf9Bsqu?`Gr;ZiHr;ZiHq>^NEJH2VKs!%JCd/X+G
3832 $Kjha+gD!u5RAEqrVm&O9F(nZUAk/tgJemh'NNT]qZ-Zr#2`](";tkCrr;uu!kTKSh>[Th!1X%;
3833 r;QtW(^XUG!!*#u#)F*&@/0d&q>Ug.!;6Bl&;1#_T)_=Zrs%@d)$Cgio)A[h!#*R-"uk68s4^Kf
3834 !YeY_s8N'!s8Vrrs8N;\>o<b_BCbp!qZ$m$a@m3N,^B(_s8N'#],h"Ls8N)qrrUgQ0)bhM!<3!&
3835 a@m3N,^B(_rt!%<%0o,@s8N'!s8S_o,O^3`JcF@%!J:@FeHD!7qGgOG~>
3836 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlHs3prI!7UoI!7U]C!7UE;
3837 s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7UE;s3plG
3838 s3poH!7UlH!n..ur;ZiHnGi^@!7Lqsr;ZiHrVurIqZ$WFr;ZoJ!!)rG!!)oFr;ZiHrW!2P!7Lqs
3839 df@kq!!C[M!7UfFs3piF!7UfFs3lN!VZ?`@s&IGGrr=71\,)9gAn\[MP5mlJs7dA/q=':B2#mT,
3840 !*A@]flI,m!!)ut&,Sm#On@g-"LS4/!!%Pminj\>pAtd'A-'(:rt4]*%F+EU!!*'!mg'BInRhh%
3841 q>W"U!'pS_%L_@tg]/Grs8,=iOn@g-"LS4/!!%l#nPoUQs+(/OkPX"Rs8N'!rr;uurVm0#8-G(I
3842 k=>`_qZ$Qqrr3N(/d8!EegUg@s8N'!JBQsKs8N)rrr_S<!d">?rrE*!)>GffUA3:g#/gK9.Kl%.
3843 l@K!8!!*&j.0QGts+14$rrJ)Yp=oeB!;fbrJ,~>
3844 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlHs3prI!7UoI!7U]C!7UE;
3845 s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7UE;s3plG
3846 s3poH!7UlH!n..ur;ZiHnGi^@!7Lqsr;ZiHrVurIqZ$WFr;ZoJ!!)rG!!)oFr;ZiHrW!2P!7Lqs
3847 df@kq!!C[M!7UfFs3piF!7UfFs3lN!VZ?`@s&IGGrr=6Hde6fD\NA75=TFH]s6qGVr8qDfFoVIt
3848 !0-LDb#JE@!!)ut&,%"KZ2)of#jD<g!!#LK^u#(qm/\+))$0.(rt3ia+6;KW!!*'!f)d&Tj@oUS
3849 q>W!>!3#qo"pOi&V>s<is7RH<Z2)of#jD<g!!#gUj<"HTs"aY7nG14+s8N'!rr;uurVm/s*=&kF
3850 eJSYVqZ$Qqrr3Mt%L^,M^^:S@s8N'!7cV;\s8N)rrr_1["K24urrE*!)=J%C_>D"T%e0Md$jj<9
3851 ggL0^!!*&Y$4,.4s+14$rrIuVp=]Y<!;fbrJ,~>
3852 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlHs3prI!7UoI!7U]C!7UE;
3853 s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7UE;s3plG
3854 s3poH!7UlH!n..ur;ZiHnGi^@!7Lqsr;ZiHrVurIqZ$WFr;ZoJ!!)rG!!)oFr;ZiHrW!2P!7Lqs
3855 df@kq!!C[M!7UfFs3piF!7UfFs3lN!VZ?`@s&IGGrr=6Kjm42lgem2",663ms1UtVr7<M#`;fiP
3856 !3c+h\2+*a!!)ut&(q@4b58aX+SPj8!!$U"Ibt)/ZiO_;$j-2&rt1Cp<q4Fj!!*'!Oo\VRc%l?"
3857 q>Vuf!8[\=$k<.756/4ns4If%b58aX+SPj8!!$d(bmasIrtPO;p@YpNs8N'!rr;uurVm/V$m*Rg
3858 \dKYSqZ$Qqrr3MG"tS="TER"Ds8N'!Aak0Fs8N)srri;I,S&T-s8N*!ru&ZX/(aNg"Y]ZN^'5e)
3859 qo_#"rr<'!ZNVQ@JcC<$f)Gc&s7XtGOT>5X<Ib~>
3860 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7U]C!7UH<
3861 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7U?9s3plG
3862 s3puJ!7UlH!n..ur;ZiHnGi^@!7Lqsr;ZiHrVurIqZ$WFr;ZoJ!7UlH!n..up](<CrW!5Q!!(IJ
3863 df@kGrW!&L!!(LD!<:OH!!(LG!!(K!!2T\q,6(Zis8N',B)ho)!!R!7s7QF"qYpg!!!`K'#lpt%
3864 s8N)trrTh57K3;llMqn(rr<%5h#@T%!'C53!&"9N&XNK5s8V<`!<<(c!,MW7kl:_Zrt+;m)?9%5
3865 G[pcP!*0(!]DtD"rt+Jr)uop<!,MW7l2VV"#lpt%s8N)us8N)trrTh57K3;glMqn#s8N)urrT;&
3866 ;?$S#h>e\urr<%5q#C?orVuis!=4ebs8N*!rrT;&;?$S"h>e\uWW5ils8N'$pc/JOJcC<$ec,Z/
3867 s7Y4NScJXf<Ib~>
3868 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7U]C!7UH<
3869 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7U?9s3plG
3870 s3puJ!7UlH!n..ur;ZiHnGi^@!7Lqsr;ZiHrVurIqZ$WFr;ZoJ!7UlH!n..up](<CrW!5Q!!(IJ
3871 df@kGrW!&L!!(LD!<:OH!!(LG!!(K!!2T\q,6(Zis8N',`rH))!"6gHs69S"qYpfr!"Ju.!s$OA
3872 s8N)trrQ[1TDniqci??2rr<&Ch#@S&!1!SL!-eGB&Ma@3s8U7B!<<'S!7(WEb5_P<rt*'J3WIPK
3873 *R=[D!5nj:@fW/#rt*NW5l^ia!7(WEblBO!!s$OAs8N)us8N)trrQ[1TDnilci??-s8N)urrPjo
3874 Yl=Y-XT2,rrr<&Cq#C?orVuis!>E0Es8N*!rrPjoYl=Y,XT2,r8-#^fs8N'$m1K]RJcC<$ec,Z,
3875 s7Y.LRK34b<Ib~>
3876 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7U]C!7UH<
3877 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7T?r!7U?9s3plG
3878 s3puJ!7UlH!n..ur;ZiHnGi^@!7Lqsr;ZiHrVurIqZ$WFr;ZoJ!7UlH!n..up](<CrW!5Q!!(IJ
3879 df@kGrW!&L!!(LD!<:OH!!(LG!!(K!!2T\q,6(Zis8N',kl:[^!#"Mqs/5p$qYpf]!&jlW!<D3X
3880 s8N)trrOPJg&D!VEr_s7rr<&ah#@R2!7q03!6bBA&JbB3s8Qd5!<<'7!:'UaB`J//rt&01WrHgZ%
3881 dO'2!9X=]-NMj!rt'5OUAt5n!:'UaCB0b%!<D3Xs8N)us8N)trrOPJg&D!QEr_s2s8N)urrO8Bi
3882 ;W`]:B7Qtrr<&aq#C?orVuis!A!:0s8N*!rrO8Bi;W`\:B7Qt*WY'os8N'$`!@LRJcC<$ec,Z%s
3883 7XtGOT>5X<Ib~>
3884 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
3885 qu?`Gr;ZiHnc/[=q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LH!!C[M
3886 !7T9p!7UK=!7UlH!n..ur;ZoJ!7UlH!n..urW)uIr;ZiHp&G6E!7Lqsr;ZiHrVurIr;ZoJ!7UlH
3887 !n..urW)uI!<CUI!!(LH!!(LI!!(LF!!1OKrmUiH!7UoI!n..ur;ZrK!!(LG!!(K!!2KVp,6(Zi
3888 s8N',hZ*WT!!(mUs8E!"rr3%r3Y),h#Qau*C]FJjP26-;rrE#t!^?\!rr36%!!WE&!!(X+ru4$#
3889 `rGi<#Q"K#-NMp$s8)crs8OGHg].<N!!)ip&GcG5s1pD5,6'J#ci=#0!5AI4'E%n7s8N'!g].<N
3890 !!WC=!!+g;h>[HS!<3#u!<)p!56/FsrrW-!"oA9!!<3!"1]Yo%rs/B##64]'!8%#GrrDrr"5m>a
3891 H2[dC!<<'#1]Yo%rs&<"#6-:Udej(E!!5aqTRm,os4%&LN;rV,"J,Vj<E4P~>
3892 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
3893 qu?`Gr;ZiHnc/[=q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LH!!C[M
3894 !7T9p!7UK=!7UlH!n..ur;ZoJ!7UlH!n..urW)uIr;ZiHp&G6E!7Lqsr;ZiHrVurIr;ZoJ!7UlH
3895 !n..urW)uI!<CUI!!(LH!!(LI!!(LF!!1OKrmUiH!7UoI!n..ur;ZrK!!(LG!!(K!!2KVp,6(Zi
3896 s8N'2p](9k!!)cns82j"s8W%R/IDCV#Qau*,QIj=T()aZrrE#t!Y5;#rr36"!"8i,!!)`KruD"J
3897 !V69]!=o,/rsAc#s8Vcm!<<'+!;HNnp&G*grt+f'%f]j]H;jhQ!VHEl%fl+urtG5/$ig5,!;HNn
3898 p&GI",QIj=T()aZrrE&urrE#t!Y5;#rr3&r!"8Z'rrE&u!Y#/%rr35q!"Ju.!!)`fs8N)srri;J
3899 .g*-Vs8N*!rrNW0o`"jpoDf@#$NThrs8N'#*!jrCs+14"rrIuVp=]Y<!;fbrJ,~>
3900 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
3901 qu?`Gr;ZiHnc/[=q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LH!!C[M
3902 !7T9p!7UK=!7UlH!n..ur;ZoJ!7UlH!n..urW)uIr;ZiHp&G6E!7Lqsr;ZiHrVurIr;ZoJ!7UlH
3903 !n..urW)uI!<CUI!!(LH!!(LI!!(LF!!1OKrmUiH!7UoI!n..ur;ZrK!!(LG!!(K!!2KVp,6(Zi
3904 s8N'2r;Zff!!)rss7-.$s8Vh4,6n,I#Qt,,&-)`AXnhtrrrE#t!XA`#rr35f!%\*L!!)oPrs/B*
3905 "o82<!B^;\&Hr13s8UdQ!<<'&!;lfrg&M-Krt*KW3<(>M0>%5g!rDrs#6=PurtFVs/-#VL!;lfr
3906 g&NQ$&-)`AXnhtrrrE&urrE#t!XA`#rr3&a!%[pGrrE&u!X8Z$rr35L!&X`U!!)oks8N)srri21
3907 &e*dus8N*!rrNB)qYpL!cN#g%"p"Mss8N'#$m+ees+14"rrI`Op=0;.!;]\qJ,~>
3908 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie,'.De+!G8
3909 e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He'A!oe+!G:e,B@Ge,KCJe,97Jdf9CIdfBHt
3910 rW)rHpAb3BrW!#K!!)rGrrE#Hrr<&Jr;ZoJ!!*#I!s$dM!<(CG!;t=G!<(CH!!(LD!<1IH!<(CG
3911 !!(LG!;k5r!3#tu,6(Zis8N)ts8N)ts8N*!rtMmA0A$.%!!*'!q0=%^!!@TJrr<&trs]87!s8T*
3912 !!!'"rr<&rh>[KAq>^\?s8N3%qYpNp!<<'#"9A;ts8N)ors;m0\Q!tG#kn<,rr3E6!!<<)!<<*#
3913 s8N'!qYpL(!!3,qGom"d"+1(J!!*#urrE#t#RLJ5!s/K'!!2rrrrE&u!XSl&rVm'%!rr9#!;lQk
3914 rrDoq!qcO!rVults8N-,!;ZTn"TSW("T\Jts8N'#'`s8Ds+14"rrJ)Yp=oeB!;fbrJ,~>
3915 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie,'.De+!G8
3916 e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He'A!oe+!G:e,B@Ge,KCJe,97Jdf9CIdfBHt
3917 rW)rHpAb3BrW!#K!!)rGrrE#Hrr<&Jr;ZoJ!!*#I!s$dM!<(CG!;t=G!<(CH!!(LD!<1IH!<(CG
3918 !!(LG!;k5r!3#tu,6(Zis8N)ts8N)ts8N*!rtK&FB]T0l!!*'!mpQh/!!]Y,rr<&trs]#0!s8T*
3919 !!!'"rr<&uh>[K'q>_5Xs8N*"rr<#t!!*'!!<E-!s8Duuq#:X9!:CQXh@T&S(B4=T!WW<)!W`9$
3920 !WW0"!<3#urW!!!mpQh/!!]Y,rr<&us8N)trs/Z+!s8T*!!!&rs8N)urrN9&rr2p&rW!'#rr<&u
3921 q#C?oqYpW]!##81rrE*!!WrH%rr30$!!E6%!;c`q!!3<,]Rg*6s4%&LM?!;'"I]>f<E4P~>
3922 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie,'.De+!G8
3923 e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He'A!oe+!G:e,B@Ge,KCJe,97Jdf9CIdfBHt
3924 rW)rHpAb3BrW!#K!!)rGrrE#Hrr<&Jr;ZoJ!!*#I!s$dM!<(CG!;t=G!<(CH!!(LD!<1IH!<(CG
3925 !!(LG!;k5r!3#tu,6(Zis8N)ts8N)ts8N*!rtI!aP3r;F!!*'!cV4ZF!#OSnrr<&trsSo.!s8T*
3926 !!!-$rr<&Srr@-:!!MZgrrE-!rs&<"!<<'"!<3!"q>^Njrs9&5p^6M<6F-Yrrr3B-!!<<)!<<*%
3927 s8N'!rr3K)!!WDK9aC_!(Z>>n!!*#urrE#t#QXo-!s/K'!!E)trrE&u!<E3!rs&5u$NL,+!;HNn
3928 !;c]sVZ99ds8N*!rrE-#rVm&r!"/`,!;c`q!!366jFR>^s4%&LK)bPp"H`]\<E4P~>
3929 s!!!oc2[jnhZ*Z*`W5nbg&M-%^An8_JH1K+s!%JCd/X+GrVultrVults8N<I!8IPRq#CEmrs.G3
3930 !!`K'!!)ut!\sc*q>^Hph#@GL!&acU(=<+#s8OGHg].<N!!*'!-NMp$s8)crq#:Z;!(I(\rY1=l
3931 -N=#H1'#i"s8N'&g].<N!!W?$#N(%3#64]'!<3#u!<)p!1'#hrs8N)urrOtVd/O%Lq>^a"rr<&n
3932 s8N)prrE*#rVults8N-V!7:`F#5S<(s"=B#qu?Zr"6L:!MLkeYs4.,MN;rV,"J,Vj<E4P~>
3933 s!!!oc2[jnhZ*Z*`W5nbg&M-%^An8_JH1K+s!%JCd/X+GrVultrVults8N<0!;HNnnc/[frs-kY
3934 !"Ju.!!)ut!Xo)%q>^Hph#@F>!/UXS(5MrSs8NE+p](9e!!*'!$39i#s7QEmq#:Y,!3QM'qurhq
3935 ?N0s+$iotrs8N'&p](9f!"/])#L?fY%KHG.!<3#u!<)p!$iotms8N)urrNW0o`"jpoDf@#rr<&n
3936 s8N)qrrW0"!r`0!!<<'#%06&"rs&)q%K?h:o_\[g!!C%@"MB<cJcF:#!K$jMg'!iEqc-XH~>
3937 s!!!oc2[jnhZ*Z*`W5nbg&M-%^An8_JH1K+s!%JCd/X+GrVultrVults8N<,!;uls`W-#;rs8V=
3938 1]TE5rr<&trrNB)qt^9l!8RSU)?A1art[HlU&Y,r!;lfrg&M-QrriE"s8UdQ!;QR#-30kWrp^(U
3939 !5ea8!X8Z%q>^Hp"oJ?"gAiW#rs8V=1]TE5rr<&us8N)trrNB)qt0pg!<3!""p"N!rs$gM2#mRU
3940 !;HNn!;c]sp](Tus8N*!rrNB)qYpL!ci>p&"p"Mss8N'$NWTjRJcC<$ec,Z%s7XtGOT>5X<Ib~>
3941 s!!!oJH16$rr<&JJH1K+s!%JCd/X+GrVultrVults8N<9!9F1[h#IHPrs/N'!WN**!;HKm!k85!
3942 q>^Hph>[TS%fsZKrtbD7!nmU>!,V]8l2Uhas-<Y$s8V?a!;QR#lMq8(s8S#_!+Z$.!k85!q>^Hp
3943 "`45=lMq[trs&H&!WN*!!<3!"#ls`!rrT\17J-W[!<3!"X8l,srs%?\+92?@!;HNn!;c]so)K0s
3944 s8N*!rrT8%;?$S"hZ+buWrPuns8N'%s5jpqMLkeYs472NN;rV,"J,Vj<E4P~>
3945 s!!!oJH16$rr<&JJH1K+s!%JCd/X+GrVultrVults8N<,!;ZZpVuQhprs/E$!rr9&!<)os!aPen
3946 q>^Hph>[TN"9S,mrtb,+"SVjM!71]Fbl@bDs"ON"s8U=D!;QR#ci>%4s8ODY!7:`F!aPenq>^Hp
3947 "jd5Kc2]Tsrs&?#!rr9#!<3!"!s&<!rrQI+R.UFY!<3!"9)u3qrs#\-9`P+m!;HNn!;c]sirBno
3948 s8N*!rrPgnYl=Y,YQ.As8H>jhs8N'%s1ed@]Rg*6s472NM?!;'"I]>f<E4P~>
3949 s!!!oJH16$rr<&JJH1K+s!%JCd/X+GrVultrVults8N<*!<)rt8cSkgrs%ij#64](!<)p!,llHj
3950 s8N)Trr^pU#5S8u(<$:bqu7B2li7!"!!*'!'`dS"s(VN6q#:Y1!"Y(hrt,J9li-nc,llHjs8N'&
3951 li7!$!13W`#42Bps8N'!rr3!"!<)p!,llHes8N)urrO8Bi;W`\;#m`urr<&ns8N)qrrSSg?N'p(
3952 !<<'#*rt6urru=#XoBFBhY[?Q!!N=]!YFFDs+14$rrI`Op=0;.!;]\qJ,~>
3953 s!!!oJH16$JH1B(s!%JCd/X+GrVultrVults8OC/!'g)36i[5es!t&9r4)eCs8Qa4LAh/Pr)*T5
3954 g\gQQ>Q=^'!8[YVg&MibrtUOo6N?HY%aX]\!!*'!mKX6JnnJ.)q#:Zu#66^_s3q#Li;W`tr)*T5
3955 g\gQQ>Q=^'!/Stl=TOQ_/#_n6\H!EFrr<&ursi]BLAh/Pr)*T5g\gQQ>PeC"!<3!,paQHBq:@,$
3956 _#OE7!;HNn!<<'(0XC6Idn9^grVults8O#4.KuUCf..'@s7e&HQM'Qps8N'!s8V0n!fDR/JcF@%
3957 !K@'Pg]X2Kqc-XH~>
3958 s!!!oJH16$JH1B(s!%JCd/X+GrVultrVults8Nfr!.ape8H8bjs%9rspQkk:s8O&=_Z'QDpF$0)
3959 kPaVF63$rb!8[YVTE$YCrtR0eT`<OD+m.l^!!*'!eH-oVj\GjVq#:Zq!W\>^s,R-]q#::7pF$0)
3960 kPaVF63$rb!)Vh?+Tg3o9"aikQN/lBrr<&urrO/?_Z'Q@pF$0)kPaVF62LW]!<3!,m0jB>qn`^M
3961 mf3:e!;HNn!<<'(;T/;*_B8olrVults8O#)$k'rL_@$h@s6^:%[JJ]es8N'!s8Te:"MB<cJcF@%
3962 !K$jMg'!iEqc-XH~>
3963 s!!!oJH16$JH1B(s!%JCd/X+GrVultrVults8NfO!3Z0sMuWkXs(9LOmpQ3Is8NN.h>[E_g^jsn
3964 nGD(0-NF)G!8[YV63*&DrtQ4JgAd06=n9jo!!*'!NWE;RcA2H#q#:ZY!<CXLs#0o_r;Q^;g^jsn
3965 nGD(0-NF)G!,V5P%L;G%B$C,?@/tlYrr<&urrNW0h>[E[g^jsnnGD(0-MmcB!<3!,^BH.?q4e*E
3966 q#C?o!;HNn!<<'(DpnLSWso<prVults8O"P"Y87$UBN4Ds1S[^bkoUEs8N'!s8S#Z&EJEBJcF@%
3967 !J:@FeHD!7qGgOG~>
3968 s!!!oJH16$JH1B(s!%JCd/X+GrVultrVults8ODAC_6k;hZ*ZVs4M!(!Y\Phs8VOc'*/+5s8J]W
3969 &-<S?WrN)!!8[YVAH6-9rsRrh%0-@Z2$>GQ!!*#u#1k^8/'@nmp\tJ<!0R<]o)K6truM*45S*u3
3970 9WJ-m!!)h!#8W$ns4M!(!Y\Phs8N'!rr3Js;A0'2s8W(l5S*u39WIshrrE#t#530_"V=;Hrr;uu
3971 p](6ns8N;UA/kU]6)XY\rrE&u#530_"V=;Hrr3;sD&NHuM#[JT!<3!#j:DBMJcC<$f`(u2s7Y4N
3972 ScJXf<Ib~>
3973 s!!!oJH16$JH1B(s!%JCd/X+GrVultrVults8OD;:^IM4p](<os1_GE!ZPkJs8U\7$ipA.s8.X0
3974 $j7VX_uK`:!8[YV)?@\QrsQ^E)ZTi<,6L1"!!*#u#-/sN5O\XQp\tI<!9O7\jT$:uruLun1^jL.
3975 ?GlgC!!)LP"!alHs1_GE!ZPkJs8N'!rr3J[4q%Gls8VtQ1^jL.?GlX>rrE#t#3T5,!u>2,rr;uu
3976 p](6ns8N;:;%`mF;9&P6rrE&u#3T5,!u>2,rr3;c<tGHeVuQbs!<3!#]EAAMJcC<$f`(u/s7Y.L
3977 RK34b<Ib~>
3978 s!!!oJH16$JH1B(s!%JCd/X+GrVultrVults8OCq3X$4Bqu?`ss.r!i"=Jj"s8T)Q#6=i)s6aqW
3979 #mVksh#IBS!8[YV$ioGfrsN37AcMda('e+?!!*#u#)*ft>kn@"p\tI-!;$6jOT9D!ruLNK.1$5-
3980 DqtBm!!(.k"?"g2s.r!i"=Jj"s8N'!rr3J.0F%UYs8VM..1$5-Dqt3hrrE#t#/s1G"X8-`rr;uu
3981 p](6ns8N:u5n!i:A**XgrrE&u#/s1G"X8-`rr3;A6OF&`bQ%SB!<3!#M?4@MJcC<$f`(u(s7XtG
3982 OT>5X<Ib~>
3983 s!$b/!7U66s3p34qpYNErmUlIqpYNErmU?:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pT?!7SCW!7TU$
3984 !7QK!JH4:%s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3985 s!$b/!7U66s3p34qpYNErmUlIqpYNErmU?:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pT?!7SCW!7TU$
3986 !7QK!JH4:%s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3987 s!$b/!7U66s3p34qpYNErmUlIqpYNErmU?:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pT?!7SCW!7TU$
3988 !7QK!JH4:%s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3989 s!%.:!7UZB!7U35!7U!/"4I5Me+WhEdf9BsmJm79r;[&N!!(IJ!7U04"4I5Me*m>>df9BspAb<E
3990 !!(L;!!C[M!7UWAs3nFW!7TU$!7QK!JH4:%s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
3991 s!%.:!7UZB!7U35!7U!/"4I5Me+WhEdf9BsmJm79r;[&N!!(IJ!7U04"4I5Me*m>>df9BspAb<E
3992 !!(L;!!C[M!7UWAs3nFW!7TU$!7QK!JH4:%s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
3993 s!%.:!7UZB!7U35!7U!/"4I5Me+WhEdf9BsmJm79r;[&N!!(IJ!7U04"4I5Me*m>>df9BspAb<E
3994 !!(L;!!C[M!7UWAs3nFW!7TU$!7QK!JH4:%s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
3995 s!$b/!7U35!7U$0"4I5Me+WhEdf9Bsm/R.8r;ZoJ!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH
3996 !7UK=!7UlH!7U]C!n..u[K$<Vg&M-%JH16$f)Ygps&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
3997 s!$b/!7U35!7U$0"4I5Me+WhEdf9Bsm/R.8r;ZoJ!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH
3998 !7UK=!7UlH!7U]C!n..u[K$<Vg&M-%JH16$f)Ygps&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
3999 s!$b/!7U35!7U$0"4I5Me+WhEdf9Bsm/R.8r;ZoJ!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH
4000 !7UK=!7UlH!7U]C!n..u[K$<Vg&M-%JH16$f)Ygps&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
4001 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIp](<CrVurIkPt\5!7UlH
4002 !7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7S@V!7U-3qpYQFrR:cH!Rh&Jdt%LM
4003 !8@MR,6(Yos+13$s+138rrJ)Yp=oeB!;fbrJ,~>
4004 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIp](<CrVurIkPt\5!7UlH
4005 !7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7S@V!7U-3qpYQFrR:cH!Rh&Jdt%LM
4006 !8@MR,6(Yos+13$s+138rrIuVp=]Y<!;fbrJ,~>
4007 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIp](<CrVurIkPt\5!7UlH
4008 !7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7S@V!7U-3qpYQFrR:cH!Rh&Jdt%LM
4009 !8@MR,6(Yos+13$s+138rrI`Op=0;.!;]\qJ,~>
4010 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LI!!1OKrmUcF!7UoI
4011 !Rh&Je*R,;df9Bsr;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*A[/^3Umf<:7
4012 qu?iJ!!(LH!!C[Me'n9r!7QK!JH4I*s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4013 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LI!!1OKrmUcF!7UoI
4014 !Rh&Je*R,;df9Bsr;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*A[/^3Umf<:7
4015 qu?iJ!!(LH!!C[Me'n9r!7QK!JH4I*s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4016 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LI!!1OKrmUcF!7UoI
4017 !Rh&Je*R,;df9Bsr;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHp&G*A[/^3Umf<:7
4018 qu?iJ!!(LH!!C[Me'n9r!7QK!JH4I*s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4019 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlHs3prI!7UoI!7UlHs3prI
4020 !7UE;s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7S:T!7U*2!7UlH
4021 s3poH!7UlH!7QK!JH4I*s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4022 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlHs3prI!7UoI!7UlHs3prI
4023 !7UE;s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7S:T!7U*2!7UlH
4024 s3poH!7UlH!7QK!JH4I*s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4025 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlHs3prI!7UoI!7UlHs3prI
4026 !7UE;s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7S:T!7U*2!7UlH
4027 s3poH!7UlH!7QK!JH4I*s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4028 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7UlH!7UlH
4029 !7UH<!7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7S:T!7U-3!7UcE
4030 s3puJ!7UlH!7QK!JH4I*s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4031 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7UlH!7UlH
4032 !7UH<!7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7S:T!7U-3!7UcE
4033 s3puJ!7UlH!7QK!JH4I*s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4034 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7UlH!7UlH
4035 !7UH<!7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7UWA!7S:T!7U-3!7UcE
4036 s3puJ!7UlH!7QK!JH4I*s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4037 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
4038 qu?`Gr;ZiHnc/[=q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LF!!(KS
4039 !!(L5!!(LG!!(LH!!:ULe,97Hdt%LM!8ISS,6(Yos+13$s+138rrJ)Yp=oeB!;fbrJ,~>
4040 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
4041 qu?`Gr;ZiHnc/[=q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LF!!(KS
4042 !!(L5!!(LG!!(LH!!:ULe,97Hdt%LM!8ISS,6(Yos+13$s+138rrIuVp=]Y<!;fbrJ,~>
4043 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
4044 qu?`Gr;ZiHnc/[=q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97Kdf9Bsn,NR>!!(LG!!(LF!!(KS
4045 !!(L5!!(LG!!(LH!!:ULe,97Hdt%LM!8ISS,6(Yos+13$s+138rrI`Op=0;.!;]\qJ,~>
4046 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie,'.De+!G8
4047 e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,B@Fe$T/Ue*@#2e,KFHe,KCJe,97Hdt%LM!8ISS
4048 ,6(Yos+13$s+138rrJ)Yp=oeB!;fbrJ,~>
4049 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie,'.De+!G8
4050 e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,B@Fe$T/Ue*@#2e,KFHe,KCJe,97Hdt%LM!8ISS
4051 ,6(Yos+13$s+138rrIuVp=]Y<!;fbrJ,~>
4052 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie,'.De+!G8
4053 e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,B@Fe$T/Ue*@#2e,KFHe,KCJe,97Hdt%LM!8ISS
4054 ,6(Yos+13$s+138rrI`Op=0;.!;]\qJ,~>
4055 s!!!oc2[jnhZ*Z*WW;qFJH16$\H)XRs&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
4056 s!!!oc2[jnhZ*Z*WW;qFJH16$\H)XRs&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
4057 s!!!oc2[jnhZ*Z*WW;qFJH16$\H)XRs&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
4058 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4059 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4060 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4061 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4062 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4063 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4064 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4065 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4066 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4067 s!$b/!7U66s3p34qpYQFrR:cHqpYNEs3pE:rR:]Fs3p-2s3pT?!7UiGs3pT?!7UE;qpY<?rR:?<
4068 !7U'1!7UoIs3p]B!7UWA!7Spfs3pcD!7UoIrmU'2rmU-4!7R87s3m;7s!%JCJcC<$JcC<$Q2^lD
4069 s7Y4NScJXf<Ib~>
4070 s!$b/!7U66s3p34qpYQFrR:cHqpYNEs3pE:rR:]Fs3p-2s3pT?!7UiGs3pT?!7UE;qpY<?rR:?<
4071 !7U'1!7UoIs3p]B!7UWA!7Spfs3pcD!7UoIrmU'2rmU-4!7R87s3m;7s!%JCJcC<$JcC<$Q2^lA
4072 s7Y.LRK34b<Ib~>
4073 s!$b/!7U66s3p34qpYQFrR:cHqpYNEs3pE:rR:]Fs3p-2s3pT?!7UiGs3pT?!7UE;qpY<?rR:?<
4074 !7U'1!7UoIs3p]B!7UWA!7Spfs3pcD!7UoIrmU'2rmU-4!7R87s3m;7s!%JCJcC<$JcC<$Q2^l:
4075 s7XtGOT>5X<Ib~>
4076 s!%.:!7UZB!7U35!7U!/!n..ur;ZoJ!7UcE"4I5Me+!D<e,97Ndf9Bs!!(L4!!C[M!7UWAs3poH
4077 "4I5Me+NeAe*?u6e+itDe,97He+<V?e)gW1e,97He,'+Fe,B=Ie+NbAe,97He&hXje+itGdf9Bs
4078 rVurIr;ZiHmf3@:rVurIlMpq6p](<CfDkp#aoDFjQN7%0s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
4079 s!%.:!7UZB!7U35!7U!/!n..ur;ZoJ!7UcE"4I5Me+!D<e,97Ndf9Bs!!(L4!!C[M!7UWAs3poH
4080 "4I5Me+NeAe*?u6e+itDe,97He+<V?e)gW1e,97He,'+Fe,B=Ie+NbAe,97He&hXje+itGdf9Bs
4081 rVurIr;ZiHmf3@:rVurIlMpq6p](<CfDkp#aoDFjQN7%0s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
4082 s!%.:!7UZB!7U35!7U!/!n..ur;ZoJ!7UcE"4I5Me+!D<e,97Ndf9Bs!!(L4!!C[M!7UWAs3poH
4083 "4I5Me+NeAe*?u6e+itDe,97He+<V?e)gW1e,97He,'+Fe,B=Ie+NbAe,97He&hXje+itGdf9Bs
4084 rVurIr;ZiHmf3@:rVurIlMpq6p](<CfDkp#aoDFjQN7%0s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
4085 s!$b/!7U35!7U$0"4I5Me,97Jdf@ko!!(LH!!(L=!!(LH!!:ULe,97He*?u6e,97He+`nEdf@kr
4086 !!(LH!!(LC!!:ULe*I&7e+`nCe,97He+E\@e)gW1e,01Ge+WhBe+WhBe&24de+s%Ee,B=Ie)gW1
4087 e)p]2e!9t6e!C(7,6(Yos+13$s+138rrJ)Yp=oeB!;fbrJ,~>
4088 s!$b/!7U35!7U$0"4I5Me,97Jdf@ko!!(LH!!(L=!!(LH!!:ULe,97He*?u6e,97He+`nEdf@kr
4089 !!(LH!!(LC!!:ULe*I&7e+`nCe,97He+E\@e)gW1e,01Ge+WhBe+WhBe&24de+s%Ee,B=Ie)gW1
4090 e)p]2e!9t6e!C(7,6(Yos+13$s+138rrIuVp=]Y<!;fbrJ,~>
4091 s!$b/!7U35!7U$0"4I5Me,97Jdf@ko!!(LH!!(L=!!(LH!!:ULe,97He*?u6e,97He+`nEdf@kr
4092 !!(LH!!(LC!!:ULe*I&7e+`nCe,97He+E\@e)gW1e,01Ge+WhBe+WhBe&24de+s%Ee,B=Ie)gW1
4093 e)p]2e!9t6e!C(7,6(Yos+13$s+138rrI`Op=0;.!;]\qJ,~>
4094 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZrK!7LrIe,KCJe,97H
4095 e*R,:df@kq!!(L6!!(LH!!(LA!!(LI!!(LH!!(LA!!(L8!!(L=!!(L@!!C[M!7UlH!n.,LrR:cH
4096 !Rh&Je,'+Fe,01Ge,04Ge,B=JdfBBrqZ$WFr;clHr;cfFrW)oGrVurIrW!#K!!)uHrW)oGrW)oG
4097 rW)oGqu?`Gq>^NErVurIq>gQErVuuJ!<1IH!<(CG!!(LF!<(CH!!(LH!!(LD!!1OKrmUfGs3prI
4098 !Rh&Je*mA9e+NeAe,9:Fe,B@Ge,B=Ie,B=Kdf9CHe,B@Ge,B@Ge,B@Ge,01Ge!C(7,6(Yos+13$
4099 s+138rrJ)Yp=oeB!;fbrJ,~>
4100 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZrK!7LrIe,KCJe,97H
4101 e*R,:df@kq!!(L6!!(LH!!(LA!!(LI!!(LH!!(LA!!(L8!!(L=!!(L@!!C[M!7UlH!n.,LrR:cH
4102 !Rh&Je,'+Fe,01Ge,04Ge,B=JdfBBrqZ$WFr;clHr;cfFrW)oGrVurIrW!#K!!)uHrW)oGrW)oG
4103 rW)oGqu?`Gq>^NErVurIq>gQErVuuJ!<1IH!<(CG!!(LF!<(CH!!(LH!!(LD!!1OKrmUfGs3prI
4104 !Rh&Je*mA9e+NeAe,9:Fe,B@Ge,B=Ie,B=Kdf9CHe,B@Ge,B@Ge,B@Ge,01Ge!C(7,6(Yos+13$
4105 s+138rrIuVp=]Y<!;fbrJ,~>
4106 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZrK!7LrIe,KCJe,97H
4107 e*R,:df@kq!!(L6!!(LH!!(LA!!(LI!!(LH!!(LA!!(L8!!(L=!!(L@!!C[M!7UlH!n.,LrR:cH
4108 !Rh&Je,'+Fe,01Ge,04Ge,B=JdfBBrqZ$WFr;clHr;cfFrW)oGrVurIrW!#K!!)uHrW)oGrW)oG
4109 rW)oGqu?`Gq>^NErVurIq>gQErVuuJ!<1IH!<(CG!!(LF!<(CH!!(LH!!(LD!!1OKrmUfGs3prI
4110 !Rh&Je*mA9e+NeAe,9:Fe,B@Ge,B=Ie,B=Kdf9CHe,B@Ge,B@Ge,B@Ge,01Ge!C(7,6(Yos+13$
4111 s+138rrI`Op=0;.!;]\qJ,~>
4112 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CH!<:OI!!:UL
4113 e,97He*[2<df9Bsr;ZiHlMpq6r;ZiHp&G*ArVurIr;ZiHp&G*AmK!78oDem?o`,!@rVurIr;ZoJ
4114 !7UlH"4I5Me,B=Ie,97He,'+Fe,'+Fe,B@Ie,B=Ie,97He,'+Fe,B=Ie,97Jdf@kq!!C[M!7UoI
4115 !n..ur;ZiHqZ$]H!7UlH!n..ur;ZiHr;ZiHqZ$WFrW)oGqZ$WFr;ZiHrW!#K!7UlH!Rh&Ie,B=I
4116 e,97Ndf9Bs!!(LI!;t:I!7TEr!!(LH!!(LI!<:OI!!(LC!;t=C!!(LA!!(LI!!(LH!!:ULe,97K
4117 df9BsrW!#K!7UlH!7UfF!n..ur;ZoJ!7UlH!7UlH!7R87s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf
4118 <Ib~>
4119 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CH!<:OI!!:UL
4120 e,97He*[2<df9Bsr;ZiHlMpq6r;ZiHp&G*ArVurIr;ZiHp&G*AmK!78oDem?o`,!@rVurIr;ZoJ
4121 !7UlH"4I5Me,B=Ie,97He,'+Fe,'+Fe,B@Ie,B=Ie,97He,'+Fe,B=Ie,97Jdf@kq!!C[M!7UoI
4122 !n..ur;ZiHqZ$]H!7UlH!n..ur;ZiHr;ZiHqZ$WFrW)oGqZ$WFr;ZiHrW!#K!7UlH!Rh&Ie,B=I
4123 e,97Ndf9Bs!!(LI!;t:I!7TEr!!(LH!!(LI!<:OI!!(LC!;t=C!!(LA!!(LI!!(LH!!:ULe,97K
4124 df9BsrW!#K!7UlH!7UfF!n..ur;ZoJ!7UlH!7UlH!7R87s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b
4125 <Ib~>
4126 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CH!<:OI!!:UL
4127 e,97He*[2<df9Bsr;ZiHlMpq6r;ZiHp&G*ArVurIr;ZiHp&G*AmK!78oDem?o`,!@rVurIr;ZoJ
4128 !7UlH"4I5Me,B=Ie,97He,'+Fe,'+Fe,B@Ie,B=Ie,97He,'+Fe,B=Ie,97Jdf@kq!!C[M!7UoI
4129 !n..ur;ZiHqZ$]H!7UlH!n..ur;ZiHr;ZiHqZ$WFrW)oGqZ$WFr;ZiHrW!#K!7UlH!Rh&Ie,B=I
4130 e,97Ndf9Bs!!(LI!;t:I!7TEr!!(LH!!(LI!<:OI!!(LC!;t=C!!(LA!!(LI!!(LH!!:ULe,97K
4131 df9BsrW!#K!7UlH!7UfF!n..ur;ZoJ!7UlH!7UlH!7R87s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X
4132 <Ib~>
4133 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH!7UfF!n..ur;ZiH
4134 n,WL;rVurIr;ZiHlMpq6r;ZiHp&G*ArVurIr;ZiHp&G*AlMpq6pAk6Bo`,!@r;ZiHr;ZuL!!(Ks
4135 qu?`Gq>^NEq>^NEqZ$WFrVurIr;ZiHrVurIq>^NErVurIqZ-NBrr<5O!7Lqs!;k7F!;t=G!<:OH
4136 !;k7D!!(LG!!(LG!!(LD!!(LH!!(LG!;k7F!!(LG!!(LH!!(LI!<:OB!!(LH!!(LH!!(LI!!(LH
4137 !!(L<!;t=>!!(LI!!(LF!;k7F!!UgOdf@hsqpYQFr6tZGs3poHqpYKD!7R87s!%JCJcC<$JcC<$
4138 Q2^lDs7Y4NScJXf<Ib~>
4139 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH!7UfF!n..ur;ZiH
4140 n,WL;rVurIr;ZiHlMpq6r;ZiHp&G*ArVurIr;ZiHp&G*AlMpq6pAk6Bo`,!@r;ZiHr;ZuL!!(Ks
4141 qu?`Gq>^NEq>^NEqZ$WFrVurIr;ZiHrVurIq>^NErVurIqZ-NBrr<5O!7Lqs!;k7F!;t=G!<:OH
4142 !;k7D!!(LG!!(LG!!(LD!!(LH!!(LG!;k7F!!(LG!!(LH!!(LI!<:OB!!(LH!!(LH!!(LI!!(LH
4143 !!(L<!;t=>!!(LI!!(LF!;k7F!!UgOdf@hsqpYQFr6tZGs3poHqpYKD!7R87s!%JCJcC<$JcC<$
4144 Q2^lAs7Y.LRK34b<Ib~>
4145 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH!7UfF!n..ur;ZiH
4146 n,WL;rVurIr;ZiHlMpq6r;ZiHp&G*ArVurIr;ZiHp&G*AlMpq6pAk6Bo`,!@r;ZiHr;ZuL!!(Ks
4147 qu?`Gq>^NEq>^NEqZ$WFrVurIr;ZiHrVurIq>^NErVurIqZ-NBrr<5O!7Lqs!;k7F!;t=G!<:OH
4148 !;k7D!!(LG!!(LG!!(LD!!(LH!!(LG!;k7F!!(LG!!(LH!!(LI!<:OB!!(LH!!(LH!!(LI!!(LH
4149 !!(L<!;t=>!!(LI!!(LF!;k7F!!UgOdf@hsqpYQFr6tZGs3poHqpYKD!7R87s!%JCJcC<$JcC<$
4150 Q2^l:s7XtGOT>5X<Ib~>
4151 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UfF!n..ur;ZiH
4152 nGiR<qu?`Gr;ZiHlMpq6r;ZiHp&G*ArVurIr;ZiHp&G*AlMpq6p](<Co)Jd>r;ZiHr;ZiHr;clH
4153 rVurIq>^NEq>^NEqZ$WFrVurIr;ZiHrVurIq>^NErVurIqZ$WFq>^`K!7Lqs!7UfF!7UlH!7UlH
4154 s3puJ!7U]C!7UiG!7UiG!7U`D!7UlH!7UiG!7UcE!7UiG!7UlH!7UoIs3p]B!7UlH!7UlH!7UoI
4155 !7UlH!7UK=!7UlH!7UWA!7UoI!7UfF!7UcE#1ES$!7LqsqZ$WFr;ZiHr;clHrr<&Jp](<CQN7%0
4156 s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
4157 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UfF!n..ur;ZiH
4158 nGiR<qu?`Gr;ZiHlMpq6r;ZiHp&G*ArVurIr;ZiHp&G*AlMpq6p](<Co)Jd>r;ZiHr;ZiHr;clH
4159 rVurIq>^NEq>^NEqZ$WFrVurIr;ZiHrVurIq>^NErVurIqZ$WFq>^`K!7Lqs!7UfF!7UlH!7UlH
4160 s3puJ!7U]C!7UiG!7UiG!7U`D!7UlH!7UiG!7UcE!7UiG!7UlH!7UoIs3p]B!7UlH!7UlH!7UoI
4161 !7UlH!7UK=!7UlH!7UWA!7UoI!7UfF!7UcE#1ES$!7LqsqZ$WFr;ZiHr;clHrr<&Jp](<CQN7%0
4162 s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
4163 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UfF!n..ur;ZiH
4164 nGiR<qu?`Gr;ZiHlMpq6r;ZiHp&G*ArVurIr;ZiHp&G*AlMpq6p](<Co)Jd>r;ZiHr;ZiHr;clH
4165 rVurIq>^NEq>^NEqZ$WFrVurIr;ZiHrVurIq>^NErVurIqZ$WFq>^`K!7Lqs!7UfF!7UlH!7UlH
4166 s3puJ!7U]C!7UiG!7UiG!7U`D!7UlH!7UiG!7UcE!7UiG!7UlH!7UoIs3p]B!7UlH!7UlH!7UoI
4167 !7UlH!7UK=!7UlH!7UWA!7UoI!7UfF!7UcE#1ES$!7LqsqZ$WFr;ZiHr;clHrr<&Jp](<CQN7%0
4168 s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
4169 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Jdf@kq
4170 !!^mP!7LoJe+!D<e+s%Hdf9Bskl:h7!!(L@!!(LH!!C[M!7UiG!7UfF!7UE;!7UlH!7UlH!7UoI
4171 !7UN>!7UiG!7UoIs3guKe,97Kdf9BsqZ$WFq#CEDqZ$WFrW)uIrW!&L!!(LD!!(LI!!(LH!!:UL
4172 e,97Qdf9Bs!7Lqs!7UlH!n..urW)uI!<CUI!!:ULe,97He,97He,97He,'+Fe+itDe,97He,01G
4173 e,97Kdf9Bsqu?`Gr;[&N!!(IJ!7U]Cs3prI!7UlH!7UoI!7UlH!7UK=!7UoIs3pZA!7UoI!7UlH
4174 !n..ur;[/Q!!(IJdf@hse,97Jdf@kr!<:LK!7UlH!n..ur;ZiHr;ZiHQN7%0s&FXMJcC<$JcD#8
4175 !K@'Pg]X2Kqc-XH~>
4176 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Jdf@kq
4177 !!^mP!7LoJe+!D<e+s%Hdf9Bskl:h7!!(L@!!(LH!!C[M!7UiG!7UfF!7UE;!7UlH!7UlH!7UoI
4178 !7UN>!7UiG!7UoIs3guKe,97Kdf9BsqZ$WFq#CEDqZ$WFrW)uIrW!&L!!(LD!!(LI!!(LH!!:UL
4179 e,97Qdf9Bs!7Lqs!7UlH!n..urW)uI!<CUI!!:ULe,97He,97He,97He,'+Fe+itDe,97He,01G
4180 e,97Kdf9Bsqu?`Gr;[&N!!(IJ!7U]Cs3prI!7UlH!7UoI!7UlH!7UK=!7UoIs3pZA!7UoI!7UlH
4181 !n..ur;[/Q!!(IJdf@hse,97Jdf@kr!<:LK!7UlH!n..ur;ZiHr;ZiHQN7%0s&FXMJcC<$JcD#8
4182 !K$jMg'!iEqc-XH~>
4183 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Jdf@kq
4184 !!^mP!7LoJe+!D<e+s%Hdf9Bskl:h7!!(L@!!(LH!!C[M!7UiG!7UfF!7UE;!7UlH!7UlH!7UoI
4185 !7UN>!7UiG!7UoIs3guKe,97Kdf9BsqZ$WFq#CEDqZ$WFrW)uIrW!&L!!(LD!!(LI!!(LH!!:UL
4186 e,97Qdf9Bs!7Lqs!7UlH!n..urW)uI!<CUI!!:ULe,97He,97He,97He,'+Fe+itDe,97He,01G
4187 e,97Kdf9Bsqu?`Gr;[&N!!(IJ!7U]Cs3prI!7UlH!7UoI!7UlH!7UK=!7UoIs3pZA!7UoI!7UlH
4188 !n..ur;[/Q!!(IJdf@hse,97Jdf@kr!<:LK!7UlH!n..ur;ZiHr;ZiHQN7%0s&FXMJcC<$JcD#8
4189 !J:@FeHD!7qGgOG~>
4190 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B@Ge,9:He*mA7
4191 e,B@Ie)p`2e+Ne>e,B@Ie,04Fe,B@Fe+!G:e,9:Ge,KFFe+`nCe,'.EdfTU!!!)uHrVurIqZ$WF
4192 qZ-QCrrDuG!W^[LrmUiH!7UfFr6tZGrR:`GrR:]F!n..urW)oGrW)rH!s$dM!<(CG!<(CG!;t=G
4193 !!(LF!!(LF!;t=G!!(LF!<(CG!!(LF!<(CH!!(LH!!(LD!!1OKrmUiHr6kZHe,97He+!G;dfBHt
4194 p]16@rrE#HrW)oGr;ZoJ!7UoIrR:`GrmLrLdf9CHe,B@Ge,B@Fe!U49,6(Yos+13$s+138rrJ)Y
4195 p=oeB!;fbrJ,~>
4196 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B@Ge,9:He*mA7
4197 e,B@Ie)p`2e+Ne>e,B@Ie,04Fe,B@Fe+!G:e,9:Ge,KFFe+`nCe,'.EdfTU!!!)uHrVurIqZ$WF
4198 qZ-QCrrDuG!W^[LrmUiH!7UfFr6tZGrR:`GrR:]F!n..urW)oGrW)rH!s$dM!<(CG!<(CG!;t=G
4199 !!(LF!!(LF!;t=G!!(LF!<(CG!!(LF!<(CH!!(LH!!(LD!!1OKrmUiHr6kZHe,97He+!G;dfBHt
4200 p]16@rrE#HrW)oGr;ZoJ!7UoIrR:`GrmLrLdf9CHe,B@Ge,B@Fe!U49,6(Yos+13$s+138rrIuV
4201 p=]Y<!;fbrJ,~>
4202 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B@Ge,9:He*mA7
4203 e,B@Ie)p`2e+Ne>e,B@Ie,04Fe,B@Fe+!G:e,9:Ge,KFFe+`nCe,'.EdfTU!!!)uHrVurIqZ$WF
4204 qZ-QCrrDuG!W^[LrmUiH!7UfFr6tZGrR:`GrR:]F!n..urW)oGrW)rH!s$dM!<(CG!<(CG!;t=G
4205 !!(LF!!(LF!;t=G!!(LF!<(CG!!(LF!<(CH!!(LH!!(LD!!1OKrmUiHr6kZHe,97He+!G;dfBHt
4206 p]16@rrE#HrW)oGr;ZoJ!7UoIrR:`GrmLrLdf9CHe,B@Ge,B@Fe!U49,6(Yos+13$s+138rrI`O
4207 p=0;.!;]\qJ,~>
4208 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4209 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4210 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4211 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4212 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4213 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4214 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4215 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4216 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4217 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4218 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4219 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4220 s!$b/!7U66s3p34qpYQFrR:]FrmUfGs3pE:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1
4221 !7UoIs3p]B!7UWA!7UoIs3p]B!7Ta(rmUiHrR:B=!7UcE!7Tp-rmU]D!7U]CrR6;t[K-=Os&FXM
4222 JcC<$JcD#8!K@'Pg]X2Kqc-XH~>
4223 s!$b/!7U66s3p34qpYQFrR:]FrmUfGs3pE:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1
4224 !7UoIs3p]B!7UWA!7UoIs3p]B!7Ta(rmUiHrR:B=!7UcE!7Tp-rmU]D!7U]CrR6;t[K-=Os&FXM
4225 JcC<$JcD#8!K$jMg'!iEqc-XH~>
4226 s!$b/!7U66s3p34qpYQFrR:]FrmUfGs3pE:rR:]Fs3p-2s3pB9s3pW@s3pB9s3pW@s3pN=!7U'1
4227 !7UoIs3p]B!7UWA!7UoIs3p]B!7Ta(rmUiHrR:B=!7UcE!7Tp-rmU]D!7U]CrR6;t[K-=Os&FXM
4228 JcC<$JcD#8!J:@FeHD!7qGgOG~>
4229 s!%.:!7UZB!7U35!7U!/!n..ur;ZrK!!(LF!!C[M!7UH<!7UlH#1EPPdf9Bskl:h7!!(L;!!C[M
4230 !7UZB"4I5Me*m>>df9BspAb<E!!(L>!!(L1!!(LH!!(LF!!(LI!!(LA!!(LH!!(LF!!(LI!!(L)
4231 !!(LI!!:ULe,97He+NeAe+s%Ee)LE.e,B=Ie,'+Fe+itDe,97Hdt%M.!<48C<It1$s+13$s-<Tb
4232 N;rV,"J,Vj<E4P~>
4233 s!%.:!7UZB!7U35!7U!/!n..ur;ZrK!!(LF!!C[M!7UH<!7UlH#1EPPdf9Bskl:h7!!(L;!!C[M
4234 !7UZB"4I5Me*m>>df9BspAb<E!!(L>!!(L1!!(LH!!(LF!!(LI!!(LA!!(LH!!(LF!!(LI!!(L)
4235 !!(LI!!:ULe,97He+NeAe+s%Ee)LE.e,B=Ie,'+Fe+itDe,97Hdt%M.!<48C<It1$s+13$s-<Tb
4236 M?!;'"I]>f<E4P~>
4237 s!%.:!7UZB!7U35!7U!/!n..ur;ZrK!!(LF!!C[M!7UH<!7UlH#1EPPdf9Bskl:h7!!(L;!!C[M
4238 !7UZB"4I5Me*m>>df9BspAb<E!!(L>!!(L1!!(LH!!(LF!!(LI!!(LA!!(LH!!(LF!!(LI!!(L)
4239 !!(LI!!:ULe,97He+NeAe+s%Ee)LE.e,B=Ie,'+Fe+itDe,97Hdt%M.!<48C<It1$s+13$s-<Tb
4240 K)bPp"H`]\<E4P~>
4241 s!$b/!7U35!7U$0"4I5Me,97Jdf@ko!!(LH!!(L=!!(LH!!:ULe,97He*?u6e,97He+*J=e,97H
4242 e+itDe,97He+*J=e,97He+itDe,97He+E\@e)gW1e,01Ge+WhBe+WhBe,01Ge+WhBe(t')e,01G
4243 e,97He+WhDdf@ko!!(L-!!(LB!!(LD!!(LH!!(K!!4Mt.,6(Yos+13$s+138rrJ)Yp=oeB!;fbr
4244 J,~>
4245 s!$b/!7U35!7U$0"4I5Me,97Jdf@ko!!(LH!!(L=!!(LH!!:ULe,97He*?u6e,97He+*J=e,97H
4246 e+itDe,97He+*J=e,97He+itDe,97He+E\@e)gW1e,01Ge+WhBe+WhBe,01Ge+WhBe(t')e,01G
4247 e,97He+WhDdf@ko!!(L-!!(LB!!(LD!!(LH!!(K!!4Mt.,6(Yos+13$s+138rrIuVp=]Y<!;fbr
4248 J,~>
4249 s!$b/!7U35!7U$0"4I5Me,97Jdf@ko!!(LH!!(L=!!(LH!!:ULe,97He*?u6e,97He+*J=e,97H
4250 e+itDe,97He+*J=e,97He+itDe,97He+E\@e)gW1e,01Ge+WhBe+WhBe,01Ge+WhBe(t')e,01G
4251 e,97He+WhDdf@ko!!(L-!!(LB!!(LD!!(LH!!(K!!4Mt.,6(Yos+13$s+138rrI`Op=0;.!;]\q
4252 J,~>
4253 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZoJ!7UfF!7UlH!7U<8
4254 !n..ur;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,*C!!(LH!!:UL
4255 !<(CH!!1OKrmU`E!7UiG!7UiGs3prI!Rh&Je,'+Fe,01Ge,04Ge,B=JdfBBrrW)rH!s$dM!<(CG
4256 !<(CH!!1OKrmUiH!7UZB!7U]C"4I5Me,'+Fe,B@HdfTU!!!)uHrW)oGrr<)K!<1IH!!(LF!<1FJ
4257 !7UQ?!7QK![fHFPs&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
4258 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZoJ!7UfF!7UlH!7U<8
4259 !n..ur;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,*C!!(LH!!:UL
4260 !<(CH!!1OKrmU`E!7UiG!7UiGs3prI!Rh&Je,'+Fe,01Ge,04Ge,B=JdfBBrrW)rH!s$dM!<(CG
4261 !<(CH!!1OKrmUiH!7UZB!7U]C"4I5Me,'+Fe,B@HdfTU!!!)uHrW)oGrr<)K!<1IH!!(LF!<1FJ
4262 !7UQ?!7QK![fHFPs&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
4263 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZoJ!7UfF!7UlH!7U<8
4264 !n..ur;ZiHlMpq6r;ZiHnc/[=r;ZiHq#CEDr;ZiHnc/[=r;ZiHq#CEDr;ZiHo`,*C!!(LH!!:UL
4265 !<(CH!!1OKrmU`E!7UiG!7UiGs3prI!Rh&Je,'+Fe,01Ge,04Ge,B=JdfBBrrW)rH!s$dM!<(CG
4266 !<(CH!!1OKrmUiH!7UZB!7U]C"4I5Me,'+Fe,B@HdfTU!!!)uHrW)oGrr<)K!<1IH!!(LF!<1FJ
4267 !7UQ?!7QK![fHFPs&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
4268 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CH!!1OKrmUlI
4269 !7UlH!7U?9"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+NbA
4270 e,B=Ie,97Jdf@kq!!C[M!7UoI!7UlH!7UfF!7UfF!7UoIs3prI!7UlH!7UfF!7UfF!7UoIs3prI
4271 !n..urW!&L!!(LH!!:ULe,97Kdf@kGrVuuJ!<(CC!!(LI!;t:H!7UoI!7UiG!7UoI!7UoI"4I5M
4272 e,97Jdf@kq!!C[Me'n9r!Rh&Ie,B=Ie,B@Ie,KFGe,01Gdt%M-!<48C<It1$s+13$s-<TbN;rV,
4273 "J,Vj<E4P~>
4274 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CH!!1OKrmUlI
4275 !7UlH!7U?9"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+NbA
4276 e,B=Ie,97Jdf@kq!!C[M!7UoI!7UlH!7UfF!7UfF!7UoIs3prI!7UlH!7UfF!7UfF!7UoIs3prI
4277 !n..urW!&L!!(LH!!:ULe,97Kdf@kGrVuuJ!<(CC!!(LI!;t:H!7UoI!7UiG!7UoI!7UoI"4I5M
4278 e,97Jdf@kq!!C[Me'n9r!Rh&Ie,B=Ie,B@Ie,KFGe,01Gdt%M-!<48C<It1$s+13$s-<TbM?!;'
4279 "I]>f<E4P~>
4280 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CH!!1OKrmUlI
4281 !7UlH!7U?9"4I5Me,97He*?u6e,97He+*J=e,97He+itDe,97He+*J=e,97He+itDe,97He+NbA
4282 e,B=Ie,97Jdf@kq!!C[M!7UoI!7UlH!7UfF!7UfF!7UoIs3prI!7UlH!7UfF!7UfF!7UoIs3prI
4283 !n..urW!&L!!(LH!!:ULe,97Kdf@kGrVuuJ!<(CC!!(LI!;t:H!7UoI!7UiG!7UoI!7UoI"4I5M
4284 e,97Jdf@kq!!C[Me'n9r!Rh&Ie,B=Ie,B@Ie,KFGe,01Gdt%M-!<48C<It1$s+13$s-<TbK)bPp
4285 "H`]\<E4P~>
4286 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH"4I8!e,B=Kdf@kq
4287 !!(L;!<:OI!!(LH!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LB!!(LH
4288 !!(LH!!LaN!7TEp!!(LE!!(LE!!(LF!!(LI!!(LH!!(LI!!(LE!!(LF!!(LI!!(LH!!:ULe,B=L
4289 df9BsqZ$WFr;ZoJ!7UlH"4I5Me+s(Ee+WhBe,B=Ie,97He,97He,B=Ldf9BsqZ$WFr;ZoJ!7UlH
4290 "4I5Me,01Ge,97He+WkBdt%M,!<48C<It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
4291 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH"4I8!e,B=Kdf@kq
4292 !!(L;!<:OI!!(LH!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LB!!(LH
4293 !!(LH!!LaN!7TEp!!(LE!!(LE!!(LF!!(LI!!(LH!!(LI!!(LE!!(LF!!(LI!!(LH!!:ULe,B=L
4294 df9BsqZ$WFr;ZoJ!7UlH"4I5Me+s(Ee+WhBe,B=Ie,97He,97He,B=Ldf9BsqZ$WFr;ZoJ!7UlH
4295 "4I5Me,01Ge,97He+WkBdt%M,!<48C<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
4296 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH"4I8!e,B=Kdf@kq
4297 !!(L;!<:OI!!(LH!!(L6!!(LH!!(L=!!(LH!!(LD!!(LH!!(L=!!(LH!!(LD!!(LH!!(LB!!(LH
4298 !!(LH!!LaN!7TEp!!(LE!!(LE!!(LF!!(LI!!(LH!!(LI!!(LE!!(LF!!(LI!!(LH!!:ULe,B=L
4299 df9BsqZ$WFr;ZoJ!7UlH"4I5Me+s(Ee+WhBe,B=Ie,97He,97He,B=Ldf9BsqZ$WFr;ZoJ!7UlH
4300 "4I5Me,01Ge,97He+WkBdt%M,!<48C<It1$s+13$s-<TbK)bPp"H`]\<E4P~>
4301 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!n..ur;ZoJ!7UlH
4302 !7UH<!7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH
4303 !7UlH!7UlHs3prI!7UcE!7UcE!7UfF!7UoI!7UlH!7UoI!7UcE!7UfF!7UoI!7UlH!n.,LrmUiH
4304 !7UfF!7UlH!n..ur;ZrK!!(LF!!(L@!;k7E!!(LG!<1IH!!(LF!!(LH!!:ULe,97Kdf9Bsqu?`G
4305 r;ZiHp](<CJH3"Vs!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4306 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!n..ur;ZoJ!7UlH
4307 !7UH<!7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH
4308 !7UlH!7UlHs3prI!7UcE!7UcE!7UfF!7UoI!7UlH!7UoI!7UcE!7UfF!7UoI!7UlH!n.,LrmUiH
4309 !7UfF!7UlH!n..ur;ZrK!!(LF!!(L@!;k7E!!(LG!<1IH!!(LF!!(LH!!:ULe,97Kdf9Bsqu?`G
4310 r;ZiHp](<CJH3"Vs!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4311 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!n..ur;ZoJ!7UlH
4312 !7UH<!7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7U`D!7UlH!7UK=!7UlH!7U`D!7UlH!7UZB!7UlH
4313 !7UlH!7UlHs3prI!7UcE!7UcE!7UfF!7UoI!7UlH!7UoI!7UcE!7UfF!7UoI!7UlH!n.,LrmUiH
4314 !7UfF!7UlH!n..ur;ZrK!!(LF!!(L@!;k7E!!(LG!<1IH!!(LF!!(LH!!:ULe,97Kdf9Bsqu?`G
4315 r;ZiHp](<CJH3"Vs!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4316 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Jdf@kq
4317 !!^mP!7LoJe+!D<e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`Gr;ZrK
4318 !!(LB!!(LG!!(LI!<:LK!7UlH"4I5Me,'+Fe+itDe,'+Fe,B@Ie,B=Ldf9Bsq#CEDqZ$WFrW)uI
4319 rW!#K!7UfF!7UlH!n..ur;ZoJ!7UlH"4I5Me,01Ge*m>;e,B=Ie,01Ge,'+Fe,97Jdf@kq!!:UL
4320 e,97Kdf9Bsqu?`GrW)uIq#CEDJH2tUs!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4321 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Jdf@kq
4322 !!^mP!7LoJe+!D<e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`Gr;ZrK
4323 !!(LB!!(LG!!(LI!<:LK!7UlH"4I5Me,'+Fe+itDe,'+Fe,B@Ie,B=Ldf9Bsq#CEDqZ$WFrW)uI
4324 rW!#K!7UfF!7UlH!n..ur;ZoJ!7UlH"4I5Me,01Ge*m>;e,B=Ie,01Ge,'+Fe,97Jdf@kq!!:UL
4325 e,97Kdf9Bsqu?`GrW)uIq#CEDJH2tUs!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4326 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Jdf@kq
4327 !!^mP!7LoJe+!D<e+s%Hdf9Bskl:h7!!(L;!!C[M!7UiG!7UlH"4I5Me*m>>df9Bsqu?`Gr;ZrK
4328 !!(LB!!(LG!!(LI!<:LK!7UlH"4I5Me,'+Fe+itDe,'+Fe,B@Ie,B=Ldf9Bsq#CEDqZ$WFrW)uI
4329 rW!#K!7UfF!7UlH!n..ur;ZoJ!7UlH"4I5Me,01Ge*m>;e,B=Ie,01Ge,'+Fe,97Jdf@kq!!:UL
4330 e,97Kdf9Bsqu?`GrW)uIq#CEDJH2tUs!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4331 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B@Ge,9:He*mA7
4332 e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He+NbAe,'.EdfTU!!!)uHrVurIqZ$WFqZ-QC
4333 rrDuG!W^[LrmUiH!7UfFr6tZGr6k]IdfBBrrW)oGrW)oGrW)oGrr<&Jr;ZrK!!(LG!;k7<!!(LI
4334 !!(LF!<(CG!<(CG!<(CH!!(LH!!C[M!7UfFrmLlJe+j"@dt%M.!<48C<It1$s+13$s-<TbN;rV,
4335 "J,Vj<E4P~>
4336 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B@Ge,9:He*mA7
4337 e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He+NbAe,'.EdfTU!!!)uHrVurIqZ$WFqZ-QC
4338 rrDuG!W^[LrmUiH!7UfFr6tZGr6k]IdfBBrrW)oGrW)oGrW)oGrr<&Jr;ZrK!!(LG!;k7<!!(LI
4339 !!(LF!<(CG!<(CG!<(CH!!(LH!!C[M!7UfFrmLlJe+j"@dt%M.!<48C<It1$s+13$s-<TbM?!;'
4340 "I]>f<E4P~>
4341 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B@Ge,9:He*mA7
4342 e,B@Ie)p`2e*[59e,04Fe,9:He*[59e,04Fe,9:He+NbAe,'.EdfTU!!!)uHrVurIqZ$WFqZ-QC
4343 rrDuG!W^[LrmUiH!7UfFr6tZGr6k]IdfBBrrW)oGrW)oGrW)oGrr<&Jr;ZrK!!(LG!;k7<!!(LI
4344 !!(LF!<(CG!<(CG!<(CH!!(LH!!C[M!7UfFrmLlJe+j"@dt%M.!<48C<It1$s+13$s-<TbK)bPp
4345 "H`]\<E4P~>
4346 s!!!oc2[jnhZ*Z*S,`Q<r;ZiHa8c4hr;ZiHJH1E)s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4347 s!!!oc2[jnhZ*Z*S,`Q<r;ZiHa8c4hr;ZiHJH1E)s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4348 s!!!oc2[jnhZ*Z*S,`Q<r;ZiHa8c4hr;ZiHJH1E)s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4349 s!!!oJH3UgrR8adrR6;tK`M,ss&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
4350 s!!!oJH3UgrR8adrR6;tK`M,ss&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
4351 s!!!oJH3UgrR8adrR6;tK`M,ss&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
4352 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4353 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4354 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4355 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4356 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4357 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4358 s!$b/!7U66s3p34qpYQFrR:cHqpYHC!7UE;rR:]Fs3p-2s3pB9s3p]BqpY$7s3pZArR:?<!7U'1
4359 !n..ukPtV3JH16$WrW/Ds&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
4360 s!$b/!7U66s3p34qpYQFrR:cHqpYHC!7UE;rR:]Fs3p-2s3pB9s3p]BqpY$7s3pZArR:?<!7U'1
4361 !n..ukPtV3JH16$WrW/Ds&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
4362 s!$b/!7U66s3p34qpYQFrR:cHqpYHC!7UE;rR:]Fs3p-2s3pB9s3p]BqpY$7s3pZArR:?<!7U'1
4363 !n..ukPtV3JH16$WrW/Ds&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
4364 s!%.:!7UZB!7U35!7U!/!n..ur;ZiHqZ$WFr;clHnGiR<r;[&N!!(IJ!7U04"4I5Me*m>>df9Bs
4365 o)Jd>nGi[?!!(LC!!(LH!!(L?!!(L1!!:ULe+`nCe+*J=e)LE.dt%LM!6P<A,6(Yos+13$s+138
4366 rrJ)Yp=oeB!;fbrJ,~>
4367 s!%.:!7UZB!7U35!7U!/!n..ur;ZiHqZ$WFr;clHnGiR<r;[&N!!(IJ!7U04"4I5Me*m>>df9Bs
4368 o)Jd>nGi[?!!(LC!!(LH!!(L?!!(L1!!:ULe+`nCe+*J=e)LE.dt%LM!6P<A,6(Yos+13$s+138
4369 rrIuVp=]Y<!;fbrJ,~>
4370 s!%.:!7UZB!7U35!7U!/!n..ur;ZiHqZ$WFr;clHnGiR<r;[&N!!(IJ!7U04"4I5Me*m>>df9Bs
4371 o)Jd>nGi[?!!(LC!!(LH!!(L?!!(L1!!:ULe+`nCe+*J=e)LE.dt%LM!6P<A,6(Yos+13$s+138
4372 rrI`Op=0;.!;]\qJ,~>
4373 s!$b/!7U35!7U$0"4I5Me,97He,01Ge,97Jdf@ke!!(LH!!:ULe,97He*?u6e,97He+*J=e,97H
4374 e+E\@e+!D<e,97He+itDe,97He+E\@e)gW4df9Bskl:_4iW&u-JH16$aoMGcs&FXMJcC<$JcD#8
4375 !K@'Pg]X2Kqc-XH~>
4376 s!$b/!7U35!7U$0"4I5Me,97He,01Ge,97Jdf@ke!!(LH!!:ULe,97He*?u6e,97He+*J=e,97H
4377 e+E\@e+!D<e,97He+itDe,97He+E\@e)gW4df9Bskl:_4iW&u-JH16$aoMGcs&FXMJcC<$JcD#8
4378 !K$jMg'!iEqc-XH~>
4379 s!$b/!7U35!7U$0"4I5Me,97He,01Ge,97Jdf@ke!!(LH!!:ULe,97He*?u6e,97He+*J=e,97H
4380 e+E\@e+!D<e,97He+itDe,97He+E\@e)gW4df9Bskl:_4iW&u-JH16$aoMGcs&FXMJcC<$JcD#8
4381 !J:@FeHD!7qGgOG~>
4382 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZiHr;ZiHr;ZrK!!(L7
4383 !!:ULe,97He*?u6e,97He+*J=e,97He+NbAe*m>;e,97He+<V?e+E\Cdf9Bsr;ZoJ!!)uHrr<)K
4384 !<1IE!!LaN!7LrIe,9:He,B=JdfBBrqZ$`I!!(LH!!C[MdfBBrrr<&Jr;ZrK!!(LI!!1OKrR6;t
4385 JH3mos!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4386 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZiHr;ZiHr;ZrK!!(L7
4387 !!:ULe,97He*?u6e,97He+*J=e,97He+NbAe*m>;e,97He+<V?e+E\Cdf9Bsr;ZoJ!!)uHrr<)K
4388 !<1IE!!LaN!7LrIe,9:He,B=JdfBBrqZ$`I!!(LH!!C[MdfBBrrr<&Jr;ZrK!!(LI!!1OKrR6;t
4389 JH3mos!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4390 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZiHr;ZiHr;ZrK!!(L7
4391 !!:ULe,97He*?u6e,97He+*J=e,97He+NbAe*m>;e,97He+<V?e+E\Cdf9Bsr;ZoJ!!)uHrr<)K
4392 !<1IE!!LaN!7LrIe,9:He,B=JdfBBrqZ$`I!!(LH!!C[MdfBBrrr<&Jr;ZrK!!(LI!!1OKrR6;t
4393 JH3mos!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4394 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CE!!(LI!!(LI
4395 !!(L8!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7UWA!7UE;!7UlH!7UT@!7UT@!7UoI!7UlH!n..u
4396 r;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LH!!C[M!7UoI#1EPPdf9Bs
4397 rVurIrW!&L!!(K!!.b-m!<48C<It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
4398 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CE!!(LI!!(LI
4399 !!(L8!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7UWA!7UE;!7UlH!7UT@!7UT@!7UoI!7UlH!n..u
4400 r;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LH!!C[M!7UoI#1EPPdf9Bs
4401 rVurIrW!&L!!(K!!.b-m!<48C<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
4402 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CE!!(LI!!(LI
4403 !!(L8!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7UWA!7UE;!7UlH!7UT@!7UT@!7UoI!7UlH!n..u
4404 r;ZrK!!(LI!!(LH!!(LI!<:OI!!(LH!!(LI!<:OI!!(LH!!(LI!!(LH!!C[M!7UoI#1EPPdf9Bs
4405 rVurIrW!&L!!(K!!.b-m!<48C<It1$s+13$s-<TbK)bPp"H`]\<E4P~>
4406 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH!7UoI!7UlH!7UoI
4407 !7UB:s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7UZB!7UB:!7UlH!7UZBs3pW@!7UlH!7UlH"Od>N
4408 e'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH"4I5Me+s(Ee,97He,B=Ldf9Bs
4409 JH16$aoMGcs&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
4410 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH!7UoI!7UlH!7UoI
4411 !7UB:s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7UZB!7UB:!7UlH!7UZBs3pW@!7UlH!7UlH"Od>N
4412 e'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH"4I5Me+s(Ee,97He,B=Ldf9Bs
4413 JH16$aoMGcs&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
4414 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH!7UoI!7UlH!7UoI
4415 !7UB:s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7UZB!7UB:!7UlH!7UZBs3pW@!7UlH!7UlH"Od>N
4416 e'n3p!7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH"4I5Me+s(Ee,97He,B=Ldf9Bs
4417 JH16$aoMGcs&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
4418 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7UlHqpY'8
4419 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7UZB!7UB:!7UlH!7U]C!7UN>!7UlH!7UlH!7UlHs3prI
4420 !7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH"4I5Me+s(Ee,01Idf@kr!!(K!!.b-m
4421 !<48C<It1$s+13$s-<TbN;rV,"J,Vj<E4P~>
4422 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7UlHqpY'8
4423 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7UZB!7UB:!7UlH!7U]C!7UN>!7UlH!7UlH!7UlHs3prI
4424 !7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH"4I5Me+s(Ee,01Idf@kr!!(K!!.b-m
4425 !<48C<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
4426 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7UlHqpY'8
4427 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7UZB!7UB:!7UlH!7U]C!7UN>!7UlH!7UlH!7UlHs3prI
4428 !7UcE!7UlH!7UlH!7UlH!7UoI!7UlH!7UoI!7UlH!7UlH"4I5Me+s(Ee,01Idf@kr!!(K!!.b-m
4429 !<48C<It1$s+13$s-<TbK)bPp"H`]\<E4P~>
4430 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
4431 p](<CnGiR<q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97He*R,;df9Bsqu?`GrVurIo)Jd>qu?`G
4432 rW)uI!<CUI!!C[M!7UfF!7UiGs3prI!7UlH!7UoI!7UlH"4I5Me,01Ge,B@Ie,KCJe,'+Idf9Bs
4433 r;ZoJ!7UoI!7UoI!7QK!JH3sqs!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4434 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
4435 p](<CnGiR<q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97He*R,;df9Bsqu?`GrVurIo)Jd>qu?`G
4436 rW)uI!<CUI!!C[M!7UfF!7UiGs3prI!7UlH!7UoI!7UlH"4I5Me,01Ge,B@Ie,KCJe,'+Idf9Bs
4437 r;ZoJ!7UoI!7UoI!7QK!JH3sqs!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4438 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
4439 p](<CnGiR<q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,97He*R,;df9Bsqu?`GrVurIo)Jd>qu?`G
4440 rW)uI!<CUI!!C[M!7UfF!7UiGs3prI!7UlH!7UoI!7UlH"4I5Me,01Ge,B@Ie,KCJe,'+Idf9Bs
4441 r;ZoJ!7UoI!7UoI!7QK!JH3sqs!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4442 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie+`nCe+!G8
4443 e,B@Ie)p`2e*[59e,04Fe,B=Ie*I)7e,04Fe,KFFe+`nCe,'.EdfTU!!!)uHrVurIqZ$WFqu?cH
4444 !<1IH!;t:H!7UlH"4I5Me,'.Edf]["!!(LG!!(LH!!(LH!!(LG!<1Gu!.b-p!<48C<It1$s+13$
4445 s-<TbN;rV,"J,Vj<E4P~>
4446 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie+`nCe+!G8
4447 e,B@Ie)p`2e*[59e,04Fe,B=Ie*I)7e,04Fe,KFFe+`nCe,'.EdfTU!!!)uHrVurIqZ$WFqu?cH
4448 !<1IH!;t:H!7UlH"4I5Me,'.Edf]["!!(LG!!(LH!!(LH!!(LG!<1Gu!.b-p!<48C<It1$s+13$
4449 s-<TbM?!;'"I]>f<E4P~>
4450 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie+`nCe+!G8
4451 e,B@Ie)p`2e*[59e,04Fe,B=Ie*I)7e,04Fe,KFFe+`nCe,'.EdfTU!!!)uHrVurIqZ$WFqu?cH
4452 !<1IH!;t:H!7UlH"4I5Me,'.Edf]["!!(LG!!(LH!!(LH!!(LG!<1Gu!.b-p!<48C<It1$s+13$
4453 s-<TbK)bPp"H`]\<E4P~>
4454 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4455 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4456 s!!!oc2[jnhZ*Z*JH16$JH4I*s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4457 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4458 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4459 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4460 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4461 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4462 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4463 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4464 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4465 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4466 s!$b/!7U66s3p34qpYQFrR:cHqpPNFqpY'8rR:]Fs3p-2s3pB9s3pT?!7U?9s3pW@s3pE:!7Tj+
4467 !7QK!JH2&;s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4468 s!$b/!7U66s3p34qpYQFrR:cHqpPNFqpY'8rR:]Fs3p-2s3pB9s3pT?!7U?9s3pW@s3pE:!7Tj+
4469 !7QK!JH2&;s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4470 s!$b/!7U66s3p34qpYQFrR:cHqpPNFqpY'8rR:]Fs3p-2s3pB9s3pT?!7U?9s3pW@s3pE:!7Tj+
4471 !7QK!JH2&;s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4472 s!%.:!7UZB!7U35!7U!/!n..ur;ZiHqZ$]H!7U<8!7UlH#1EPPdf9Bskl:h7!!(L;!!C[M!7UWA
4473 s3pE:"4I5Me+WhEdf9Bsn,NI;huEc+JH16$QiR.1s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
4474 s!%.:!7UZB!7U35!7U!/!n..ur;ZiHqZ$]H!7U<8!7UlH#1EPPdf9Bskl:h7!!(L;!!C[M!7UWA
4475 s3pE:"4I5Me+WhEdf9Bsn,NI;huEc+JH16$QiR.1s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
4476 s!%.:!7UZB!7U35!7U!/!n..ur;ZiHqZ$]H!7U<8!7UlH#1EPPdf9Bskl:h7!!(L;!!C[M!7UWA
4477 s3pE:"4I5Me+WhEdf9Bsn,NI;huEc+JH16$QiR.1s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
4478 s!$b/!7U35!7U$0"4I5Me,97He,01Jdf9Bsm/R.8r;ZoJ!7UlH!7U66!7UlH!7UK=!7UlH!7U]C
4479 !n..un,NI;r;ZiHq#CEDr;ZiHn,NI;i;`l,JH16$QiR.1s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
4480 s!$b/!7U35!7U$0"4I5Me,97He,01Jdf9Bsm/R.8r;ZoJ!7UlH!7U66!7UlH!7UK=!7UlH!7U]C
4481 !n..un,NI;r;ZiHq#CEDr;ZiHn,NI;i;`l,JH16$QiR.1s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
4482 s!$b/!7U35!7U$0"4I5Me,97He,01Jdf9Bsm/R.8r;ZoJ!7UlH!7U66!7UlH!7UK=!7UlH!7U]C
4483 !n..un,NI;r;ZiHq#CEDr;ZiHn,NI;i;`l,JH16$QiR.1s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
4484 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZiHr;ZiHrVuuJ!<1I6
4485 !!:ULe,97He*?u6e,97He+*J=e,97He+NbAe*m>;e,97He+itDe,97He*m>;e*d;6e,KFHe,KCK
4486 dfBBrJH16$S,iR5s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
4487 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZiHr;ZiHrVuuJ!<1I6
4488 !!:ULe,97He*?u6e,97He+*J=e,97He+NbAe*m>;e,97He+itDe,97He*m>;e*d;6e,KFHe,KCK
4489 dfBBrJH16$S,iR5s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
4490 s!%ICs3guKe,9:He,9:Fe,KCKdfBBrrW)oGrW)oGqu?`Gjo>D1rVurIr;ZiHr;ZiHrVuuJ!<1I6
4491 !!:ULe,97He*?u6e,97He+*J=e,97He+NbAe*m>;e,97He+itDe,97He*m>;e*d;6e,KFHe,KCK
4492 dfBBrJH16$S,iR5s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
4493 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CE!!(LI!<:OI
4494 !!(L9!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7UWA!7UE;!7UlH!7U`D!7UlH!7UB:!7U97"4I5M
4495 e,97Kdf@kGrVurIJH16$SH/[6s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
4496 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CE!!(LI!<:OI
4497 !!(L9!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7UWA!7UE;!7UlH!7U`D!7UlH!7UB:!7U97"4I5M
4498 e,97Kdf@kGrVurIJH16$SH/[6s&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
4499 s!%IC"OdA"!7UlH!7UoI!7UlH"4I8!e,B=Ie,'+Hdf@kq!!(LH!!(L1!!(LH!<(CE!!(LI!<:OI
4500 !!(L9!!C[M!7UlH!7U66!7UlH!7UK=!7UlH!7UWA!7UE;!7UlH!7U`D!7UlH!7UB:!7U97"4I5M
4501 e,97Kdf@kGrVurIJH16$SH/[6s&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
4502 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH!7UoI!7U]C!7UE;
4503 s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7UWA!7UE;!7UlH!7U`D!7UlH!7U?9!7U?9!7UlHs3poH
4504 !7UlH!7QK!JH25@s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4505 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH!7UoI!7U]C!7UE;
4506 s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7UWA!7UE;!7UlH!7U`D!7UlH!7U?9!7U?9!7UlHs3poH
4507 !7UlH!7QK!JH25@s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4508 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n.,Lr6kWGqpYKD!7U*2!7UlH!7UlH!7UoI!7U]C!7UE;
4509 s3prI!7UlH!7U66!7UlH!7UK=!7UlH!7UWA!7UE;!7UlH!7U`D!7UlH!7U?9!7U?9!7UlHs3poH
4510 !7UlH!7QK!JH25@s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4511 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7U]C!7UH<
4512 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7UWA!7UE;!7UlH!7U`D!7UlH!7U?9!7UB:!7UcEs3puJ
4513 !7UlH!7QK!JH25@s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4514 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7U]C!7UH<
4515 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7UWA!7UE;!7UlH!7U`D!7UlH!7U?9!7UB:!7UcEs3puJ
4516 !7UlH!7QK!JH25@s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4517 s!%IC"OdA"!7UlH!7UoI!7UfF!7UlH!n..ur;ZoJ!7U]C!7U*2!7UlH!7UlH!7UoI!7U]C!7UH<
4518 !7UiG!7UlH!7U66!7UlH!7UK=!7UlH!7UWA!7UE;!7UlH!7U`D!7UlH!7U?9!7UB:!7UcEs3puJ
4519 !7UlH!7QK!JH25@s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4520 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
4521 qu?`Gr;ZiHnc/[=q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,'+Fe*d8=df9Bsqu?`Gr;ZrK!!(L7
4522 !!(L<!!(LG!!(LH!!:ULe,97Hdt%LM!1a,i,6(Yos+13$s+138rrJ)Yp=oeB!;fbrJ,~>
4523 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
4524 qu?`Gr;ZiHnc/[=q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,'+Fe*d8=df9Bsqu?`Gr;ZrK!!(L7
4525 !!(L<!!(LG!!(LH!!:ULe,97Hdt%LM!1a,i,6(Yos+13$s+138rrIuVp=]Y<!;fbrJ,~>
4526 s!%IC"OdA"!7UlH!7UoI!7UlH!n..ur;ZoJ!7UoIs3guKe,97He,97He*$c3e,01Ge,97Kdf9Bs
4527 qu?`Gr;ZiHnc/[=q>^WH!!(L4!!C[M!7UE;"4I5Me,01Ge,'+Fe*d8=df9Bsqu?`Gr;ZrK!!(L7
4528 !!(L<!!(LG!!(LH!!:ULe,97Hdt%LM!1a,i,6(Yos+13$s+138rrI`Op=0;.!;]\qJ,~>
4529 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie,'.De+!G8
4530 e,B@Ie)p`2e*[59e,04Fe,B@Fe*mA;e,04Fe,9:He*?u6e+*M9e,KFHe,KCJe,97Hdt%LM!1a,i
4531 ,6(Yos+13$s+138rrJ)Yp=oeB!;fbrJ,~>
4532 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie,'.De+!G8
4533 e,B@Ie)p`2e*[59e,04Fe,B@Fe*mA;e,04Fe,9:He*?u6e+*M9e,KFHe,KCJe,97Hdt%LM!1a,i
4534 ,6(Yos+13$s+138rrIuVp=]Y<!;fbrJ,~>
4535 s!%IC!7UoI!n.,Lr6tZGrR:cH!7UlH!n.,LrmLrLdf9CHe,B@Fe*6o5e,'.De,B=Ie,'.De+!G8
4536 e,B@Ie)p`2e*[59e,04Fe,B@Fe*mA;e,04Fe,9:He*?u6e+*M9e,KFHe,KCJe,97Hdt%LM!1a,i
4537 ,6(Yos+13$s+138rrI`Op=0;.!;]\qJ,~>
4538 s!!!oc2[jnhZ*Z*iW/l)JH16$JH5]os&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
4539 s!!!oc2[jnhZ*Z*iW/l)JH16$JH5]os&FXMJcC<$JcD#8!K$jMg'!iEqc-XH~>
4540 s!!!oc2[jnhZ*Z*iW/l)JH16$JH5]os&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
4541 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4542 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4543 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4544 s!"cLqU9uqJH16$JH4C(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4545 s!"cLqU9uqJH16$JH4C(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4546 s!"cLqU9uqJH16$JH4C(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4547 s!"cL!7UiG!7QK!JH16$JH4C(s!%JCJcE@^r\K-*JcC<$hZ!V8s7Y4NScJXf<Ib~>
4548 s!"cL!7UiG!7QK!JH16$JH4C(s!%JCJcE@^r\K-*JcC<$hZ!V5s7Y.LRK34b<Ib~>
4549 s!"cL!7UiG!7QK!JH16$JH4C(s!%JCJcE@^r\K-*JcC<$hZ!V.s7XtGOT>5X<Ib~>
4550 s!%1;s8Vfns8VHdrr:sX!7UiG!7QK!JH16$JH4C(s!%JCcMmn/r\FP#WrE=KIo/?e7;/CCs8FhR
4551 s8Fg*s+13$s5a1\N;rV,"J,Vj<E4P~>
4552 s!%1;s8Vfns8VHdrr;Zls8W*!!<;Ti!7UiG!7QK!JH16$JH4C(s!%JCcMmmcr\FPqX8`J)]QHe+
4553 3(n:sdf9;&rr;sRJcC<$JcFg2!K$jMg'!iEqc-XH~>
4554 s!%1;s8Vfns8VHdrr:sX!7UiG!7QK!JH16$JH4C(s!%JCcMmljr\FQ=X8`J%WGG$_3`1=Adf9;&
4555 rr;sRJcC<$JcFg2!J:@FeHD!7qGgOG~>
4556 s!%1;s8Vfns8VEcs8VHd!7UZB!7UiG!7QK!JH16$JH4C(s!%JCcMmm0r\FO>XT&=sHhfJGs8FhR
4557 s8Fg*s+13$s5a1\N;rV,"J,Vj<E4P~>
4558 s!%1;s8Vfns8VEcs8Vfnqu?Tp!7UZB!7UiG!7QK!JH16$JH4C(s!%JCcMml@r\FONXT&=i?MQD*
4559 s8FhRs8Fg*s+13$s5a1\M?!;'"I]>f<E4P~>
4560 s!%1;s8Vfns8VEcs8VHd!7UZB!7UiG!7QK!JH16$JH4C(s!%JCcMml0r\FP>XT&=K7enjgs8FhR
4561 s8Fg*s+13$s5a1\K)bPp"H`]\<E4P~>
4562 s!$b/s8VEcs8VKerR:QB!7UiG!7QK!JH16$JH4C(s!%JCci4%@2#]931qBdh$N4cs1JGORrT_(<
4563 bl@YuJcC<$JcFg2!K@'Pg]X2Kqc-XH~>
4564 s!$b/s8VEcs8Vfn"TJH%s8W#trR:QB!7UiG!7QK!JH16$JH4C(s!%JCci4%62#]932"%OH$Mm1I
4565 1MG&,q;SVebl@YuJcC<$JcFg2!K$jMg'!iEqc-XH~>
4566 s!$b/s8VEcs8VKerR:QB!7UiG!7QK!JH16$JH4C(s!%JCci4$V2#]932#+6R$L'W.1P=BVpY)?9
4567 bl@YuJcC<$JcFg2!J:@FeHD!7qGgOG~>
4568 ruqUHs8N*!s8E#ts8;rrs8N)ss8E#ss8E#ss8;rts6fphdf@kk!!(LG!!(K!!.b-$!.b.(!<48C
4569 <R:[Lb;1qr1G_r,rrr(H5s9Gbr\OQR#Q:o<5;brWh8fNuf/#3OqYC-rrMa-e2b\kfrr;sR%K2ec
4570 6&GX9J3Z;Ap&G'k1Ca;Q76ue1pOGLmG4kn8r\OTSqD8!Jr\Fr\S4,`#s7_%/5'HVurs/M-A3VqA
4571 HJST#&cA5'4Z,fX_Z0Z6Sln368UJ>Rrs%461Gh-oRf36iomoClGP1qkrr36%Z"-'V7sa!Bs+13b
4572 rrJ)Yp=oeB!;fbrJ,~>
4573 ruqUHs8N*!s8E#ts8;rrs8N)ss8E#ss8E#ss8;rts6fphdf@kk!!(LG!!(K!!.b-$!.b.(!<48C
4574 <R:[LJMT*Y1GaU[rrqP&4[Y2,r\OQR#Q1/t4?-,po>gk6R56X*rqZR!qNb,B3E;@?rr;sR%K(c@
4575 8YQ1MD)t%CrVuos1Ca855"VIJlYS[MN;`eVr\OTSqD8!Jr\Fr[JNcZ!s6FM_6]D!Crs/In><Fl@
4576 Mt?rJ&bq8]3]L#neGoRDMbuMp;M`j%rs#/Q1Gh:(Yl4S*k&*=LN;``3rr36$Sm+<::Q+gqs+13b
4577 rrIuVp=]Y<!;fbrJ,~>
4578 ruqUHs8N*!s8E#ts8;rrs8N)ss8E#ss8E#ss8;rts6fphdf@kk!!(LG!!(K!!.b-$!.b.(!<48C
4579 <R:[L;DU+M1Gd5PrrpMP3D$.Jr\OQR#OdUK3BC95qT&U<>Ve1#q#:T`KM=Eh?E!i%s8Fe`nSL9b
4580 _#MY`2bg4Ls8W'S%In9q;o&FX>;o9Srr<#t1]RLO1]%.N1CN_i3E*`nc!*,$VuH\q#OdUK3BC95
4581 qYpL,jEsT[3a7m3s8V/-9/nt:Q0/)G#$j#@2+)3%rVm&C?o^fVrr+_Qrs/"O;)p[>Sbdp;JcELb
4582 !J:@FeHD!7qGgOG~>
4583 ruqFCqu?Wqs8W&us8W*!s8N9's8N'!s8Vuss8N9's8N'!s8W&us8VKermUWB!7UiG!7QK!JH16$
4584 JH4C(s!%JCd/OCM:GY$,@P]q3rr3#p<;eTQ;#W9NrrN(=q_J75b/jSbHS[IKq>UKnD>Q*k4l65=
4585 r\FPSrA+Is?MuY]>6"X%1B=HR1BDW)rA+LYs8W'Ss8VpOqZ$ON!35uR!Hh`I1B^n]s8@!81B]_\
4586 s8SVc1]RITSGG&@rrBD&1B_aus7oXm1B:8N1]RIUrGqck!BJ;Rs+13crrJ)Yp=oeB!;fbrJ,~>
4587 ruqFCqu?Wqs8W&us8W*!s8N9's8N'!s8Vuss8N9's8N'!s8W&us8VKermUWB!7UiG!7QK!JH16$
4588 JH4C(s!%JCd/OCL3\s#!4u57trr3#i4T.&9GlBN!rrMpmq_J7<nAtV375Ha]q>UKi9`$UJ9DAJd
4589 r\FOorA+JW5Q*A>O8o7Z1B;Fn1BFXCrA+M9s8W'Ss8VpOqZ$ON!-.rn!NnZc1B`d=s7oOh1B]u4
4590 s8QC$1]RIT?2?AVrr?0u1Ba`Xs7/;N1B;\!1]RIUq,.#F!C6.*s+13crrIuVp=]Y<!;fbrJ,~>
4591 ruqFCqu?Wqs8W&us8W*!s8N9's8N'!s8Vuss8N9's8N'!s8W&us8VKermUWB!7UiG!7QK!JH16$
4592 JH4C(s!%JCd/OC@2D\h<3AXJ0rr3#E2uPN4Y5U6WrrM+Dq_J7Wq8iR<4#8\aq>UKP4o7#;D>aG6
4593 r\FOJrA+Jj3W1`8d/X.F1B:,I1BG<PrA+N%s8W'Ss8VpOqZ$ON!)3>I!Ppep1Bc))s5H9?1B^qX
4594 s8POa1]RIT7J\h>rr>Ia1BcS7s3<S%1B=TW1]RIUi]m;r!F,ANs+13crrI`Op=0;.!;]\qJ,~>
4595 ruqFCqu?Wqs8W&us8Vuss8W*!s8W*!r;Q`squ?Wqs8VHd!n..uq#CEDqu?`GJH16$JH16$g&V-s
4596 s&IGG#j4!"?2rS61Ni]s#/;rM9BGr:r\OTS$-4nYJF*6^1G_PBrrYG@1[k/>$cXtY:$)2B1G_o.
4597 s8FeU:$q$@1C$\Bi\NANs8W'S!_r(Cr\FdSmG]oX3WK-Y1]IFR1\^qK1BL;<jSgq]:@7$s1HGL8
4598 a>5W&m/><f1IqKF4u5".rq"*Ss8P8=1VNeZ`HhI_&<5'2rT#aj3rf5p1G_\cpmM+;s8NDH1GaRJ
4599 rR!DW7tL\ks1nX8N;rV,"J,Vj<E4P~>
4600 ruqFCqu?Wqs8W&us8Vuss8W*!s8W*!r;Q`squ?Wqs8VHd!n..uq#CEDqu?`GJH16$JH16$g&V-s
4601 s&IGG#fAGSSH#*81W04l#&uFTEUiR;r\OTS$%F`eW:]o!1G`O^rrY/81]."J$[jfeFRepE1GaIZ
4602 s8FeUGk]A[1C&4"a>5V:s8W'S!dOI^r\Fe)pW,-H5QCc_1]IFR1\^qK1BMgqb5O1CH2#B91I(p>
4603 IkrmZo_H0V1LpIb2D[/Irp@1*s8Ou51Z89"[q,L<&<,H@r73Y[6i[1+1Ga%@nSeC_s8NCT1Gc!%
4604 q7SR?@tFZ2s1nX8M?!;'"I]>f<E4P~>
4605 ruqFCqu?Wqs8W&us8Vuss8W*!s8W*!r;Q`squ?Wqs8VHd!n..uq#CEDqu?`GJH16$JH16$g&V-s
4606 s&IGG#^%pZg&G>61["c;##-m0ReYr9r\OTS#uNK7_>3bp1Gc8VrrY,71]@.L$W/]9SbM8@1Gd&N
4607 s8FeUV#-;R1C'cRO>A\'s8W'S!i5^Ur\FeUqiETiAH2]/1]IFR1\^qK1BOBLOo@-_V>H?11M$Oc
4608 ;):#Eq=U:71U-oZ2)@&VrSskRs8Or41[b5%WDNTo&>8.`q7e^AF8u871GbKpj@]D-s8NC&1GclC
4609 opmlpY^uh*s1nX8K)bPp"H`]\<E4P~>
4610 ruqXIs8N'!s8W&us8W&us8Vuss8W*!s8NB*s8N'!s8N*!s7u`qs6fsde+`nCe,01Gdt%LM!.b-$
4611 !87GQ,6(Zirs4W@2:_a(4#9)"rruab1WBCoq>N2Mrr?C$1B9>SrrYG@1[k/>$XkhIaT);91G_&k
4612 s8FeU`W,o91C(esr\ZJgs8W'S!lb3<r\Fers8Fl32#mUT1]IFR1\^qK1BPPqrVeSY_Z0Tm1Go.3
4613 ?MQA`2ZNf(1G_F=Pfj"*#(&-^6ueI6rr3-#[Uh`^r\Fj<s8Q@\1WBCoq>N2Mrr?C$1B9=as+13c
4614 rrJ)Yp=oeB!;fbrJ,~>
4615 ruqXIs8N'!s8W&us8W&us8Vuss8W*!s8NB*s8N'!s8N*!s7u`qs6fsde+`nCe,01Gdt%LM!.b-$
4616 !87GQ,6(Zirs2=T2>."B2)@u+rrtVB1\(MFnbt?Err>4X1B9GVrrY/81]."J$U-@&o)Ja\1G_5p
4617 s8FeUnc/Od1C*IMrA6;fs8W'S!qH<gr\FfLs8=c12?3^U1]IFR1\^qK1BR+Hr;JJXnc/PE1H#44
4618 4o$l?3WK+K1G`!TS_F)C#"CC)<-Xtfrr3-"TNXK8r\Fj<s8P5<1\(MFnbt?Err>4X1B9Fds+13c
4619 rrIuVp=]Y<!;fbrJ,~>
4620 ruqXIs8N'!s8W&us8W&us8Vuss8W*!s8NB*s8N'!s8N*!s7u`qs6fsde+`nCe,01Gdt%LM!.b-$
4621 !87GQ,6(Zirs1eE48]'.2)C9lrrtG=1\q(N`;VRmrr>%S1B:.jrrY,71]@.L$TU"!q>^K91G`J>
4622 s8FeUq>]s`1C*aUpbXcds8W'S!r;lcr\FfTs7eE,3<0$X1]IFR1\^qK1BRCPnGY3Lq>^4H1H>F7
4623 3;G?::&k5U1G`<cVsXK`#!=[t?%/^=rr3,rNDhkpr\FjCs8P&71\q(N`;VRmrr>%S1B:.#s+13c
4624 rrI`Op=0;.!;]\qJ,~>
4625 ruqXIs8N'!s8W&us8W&us8W*!s8Nc5s8N'!s8N*!rr<'!rrE*!!!*'!rW)uum/R.8pAb3Bqu?`G
4626 JH16$JH16$g&V-ss&IJH!;?1D#.":/3\rSgrr;sRs8N'XpbU"k"+)g[Sb`9f4>Seirr<!S!]C#X
4627 r\FWRs8W'S#Q+Q$2)@&gs8FeUr;Zfr1C*gWs"uSgs8W'Srr;sRp](4K!rW)ur\FiWs8Or41]RJ6
4628 pbVsM!qUOmr\Fa8FT;C4FZ04T">k6#s2"Les8N0^1Gen,s8FhSrr>"Q1P,RWs1nX8N;rV,"J,Vj
4629 <E4P~>
4630 ruqXIs8N'!s8W&us8W&us8W*!s8Nc5s8N'!s8N*!rr<'!rrE*!!!*'!rW)uum/R.8pAb3Bqu?`G
4631 JH16$JH16$g&V-ss&IJH!:9J:$1.]l2)@&fs8W&s1]RIT2>AuKrrY\G1ZeH4$T0^rrr<#t1G^og
4632 s8FeUrr<#t1C*pZs"lMfs8W'S!ri6"r\FfYs8Oo31]RLS1]IFR1\^qK1BRRUs8Fe[rr<!T1Gf(2
4633 2>B!-rrV.h2#]981njsLiF=_D1B]P.s8RZG1]RIZ2)@&fs8W&s1]RIT2>AtYs+13crrIuVp=]Y<
4634 !;fbrJ,~>
4635 ruqXIs8N'!s8W&us8W&us8W*!s8Nc5s8N'!s8N*!rr<'!rrE*!!!*'!rW)uum/R.8pAb3Bqu?`G
4636 JH16$JH16$g&V-ss&IJH!4)AU"nqur1c$rerrDlo1]RIT2#&lJrrY>=1\:GB!];birr3/t1G_2o
4637 s8FhRs8FhRrrb/71]RLS1]IFR1]ICW1c$rfs8FhRs8FhKs8FhRs8FhRrrk581]RJ3pbVsM!kqVj
4638 r\Fa9f)Pca<&FS1"?"d1s&AeMs8N-W1Gf%1!;ZUMs8N'UpbRL$JcEOc!J:@FeHD!7qGgOG~>
4639 ruq[Js8N'!s8N)rs8N)ts8N*!s8N*!s8N)ss8N)ts8N)rs5X.[e,01Gdt%LM!.b-$!87GQ,6(Zj
4640 rrC+71C6nXs'7E:b5_M;r\OTS"(!c>ahn&\f/#3OqYL4"@5B^\s8VmN1HGL8r\OQRr\OQRr\OTS
4641 r\OQRr\OQRr\OTSr\OQRr\O<Kr\OQRr\OQRr\OTS"(!c>anPf=qq8A51H>@5%K"hd1G_#js%Y@+
4642 WVZSm1]RIZ>r+:Zs8Voo1]RIW?8FCZJcC<$])Meis7Y4NScJXf<Ib~>
4643 ruq[Js8N'!s8N)rs8N)ts8N*!s8N*!s8N)ss8N)ts8N)rs5X.[e,01Gdt%LM!.b-$!87GQ,6(Zj
4644 rr@HA1C8I/s#i.oo)Ja[r\OTS"$JFro"tD0QSUF)rqcX&4u5"cs8VXG1Htj=r\OQRr\OQRr\OTS
4645 r\OQRr\OQRr\OTSr\OQRr\O<Kr\OQRr\OQRr\OTS"$JFro(W.fo[Kcp1Hk^:%J8/J1G_2os#Dkk
4646 bl.J=1]RIZ4Ynnbs8VWg1]RIW4YnnbJcC<$])Mefs7Y.LRK34b<Ib~>
4647 ruq[Js8N'!s8N)rs8N)ts8N*!s8N*!s8N)ss8N)ts8N)rs5X.[e,01Gdt%LM!.b-$!87GQ,6(Zj
4648 rr>mj1C;,%s#;ejq>^K5r\OTS"#r(mq83.6>;J("q>Ug_1Gek,s2ZuP@K6B,1]IFR1]IFR1]RLS
4649 1]IFR1]IFR1]RLS1]IFR1\^qK1]IFR1]IFR1]RIW3&<Adp\tE`cAOJ7=oJ@0m*:MF1KjbX2D[/H
4650 rpftDs8N9_1Gek,s2=mms8N0\1GeiXs+13]rrI`Op=0;.!;]\qJ,~>
4651 s!"cL!7UiG!7QK!JH16$JH4C(s!%JCdf0IK9/AB0rr3E$1G^rUs1^?G:ZqPBr\OTS$-=tZ7EbN&
4652 iN[7@rtkWJ1G__>oDS'mFoTH;1JR$-T//9"s8W'Srr;sRrr;sRs8W'Srr;sRrr;sRs8W'Srr3'e
4653 1GciAs8FhRs8FhRs8FhSs!>cC1I]L_q;JSqs8Q$%kl'X"1H#44;m>KajteeNs8PSF1UR"cr\OTS
4654 #/;rM:ZqPBr\OTS$-=tZ7EbN&iN[6Ns+13crrJ)Yp=oeB!;fbrJ,~>
4655 s!"cL!7UiG!7QK!JH16$JH4C(s!%JCdf0II3AWJYrr3Do1G_&gs)BhNH1UQFr\OTS$%arh@+tSQ
4656 fqhrprtkK!1G`ajp\X'X@fLj41N`3ZFYbh$s8W'Srr;sRrr;sRs8W'Srr;sRrr;sRs8W'Srr3'Z
4657 1Ge"bs8FhRs8FhRs8FhSs!<7Q1LSr8p=Z9Is8QfJnG^ro1H#44Bts0:eMB!=s8P&71Y;>ar\OTS
4658 #&uFTH1UQFr\OTS$%arh@+tSQfqhr)s+13crrIuVp=]Y<!;fbrJ,~>
4659 s!"cL!7UiG!7QK!JH16$JH4C(s!%JCdf0I:2D[/`rr3D41G_]&s%P:*U&!eCr\OTS#uWQ8K]W1(
4660 d@!\Lrtjl\1Ga^;qYAsD:]F9J1S+@)9f"TEs8W'Srr;sRrr;sRs8W'Srr;sRrr;sRs8W'Srr3'X
4661 1GeOqs8FhRs8FhRs8FhSs!:Q!1PFlgo?it"s8RSmp&29S1Hkd<J'@Ta[50U%s8Or41[4@=r\OTS
4662 ##-m0U&!eCr\OTS#uWQ8K]W1(d@![Zs+13crrI`Op=0;.!;]\qJ,~>
4663 s!"cLqU9uqJH16$JH4C(s!%JCdf0F21G_2lrs"981N<Bi;uJKP:]<0MrrN(Eq(p(k!Vgm71BRUS
4664 C\omi4l$);r\OQRr\OQRr\OTSr\OQRr\OQRr\OTSr\OQR!1`sCqZ$ONrr;sRrr;sRs8N,uHMKAs
4665 s8"MQ7fWMb1BU,Hs0_e]!)!5Hs8N,q;uJKP:]<0MrrN(Eq(mU%JcEOc!K@'Pg]X2Kqc-XH~>
4666 s!"cLqU9uqJH16$JH4C(s!%JCdf0E_1G_W#rru%N1VNhZ4T.&9GQ'DurrMptq(p(k!UX.f1BRUN
4667 8c(:G8b`8br\OQRr\OQRr\OTSr\OQRr\OQRr\OTSr\OQR!*/qQqZ$ONrr;sRrr;sRs8N,q=SXcQ
4668 s8"MQ@K6B(1BV(cs)Iun!,_]ks8N,j4T.&9GQ'DurrMptq(mU%JcEOc!K$jMg'!iEqc-XH~>
4669 s!"cLqU9uqJH16$JH4C(s!%JCdf0Dg1GajbrrtVB1ZeY]2uPN4Xo:-VrrM7Kq(p(k!R=.01BRU4
4670 4o7#;CAe,3r\OQRr\OQRr\OTSr\OQRr\OQRr\OTSr\OQR!($N=qZ$ONrr;sRrr;sRs8N,^6MWG;
4671 s8"MQU&Y/h1BX?Ns%NAI!3#lQs8N,E2uPN4Xo:-VrrM7Kq(mU%JcEOc!J:@FeHD!7qGgOG~>
4672 s!!!oJH16$JH1B(s!%JCdf0E)1G`kFrsn'F1Hkd<omo@kG4RLG2?*U]rk*,;2EOok`l7ribC*2L
4673 2+2,Os8W%p>s(#;J`Zn2r\OQRr\OQRr\OTSr\OQRr\OQRr\OTSr\OQR!r%(.r\OENr\OQRr\OQR
4674 r\OQR,lYGo75d5-K?!rkjcNY*2bSS_s8V2C=?/<5IH^_2rK]l4C$kmUrr38sJNuAAo.r0[rr39'
4675 ]P^.r4&ppQJcC<$_#FFos7Y4NScJXf<Ib~>
4676 s!!!oJH16$JH1B(s!%JCdf0D@1GcQ=rslOp1J.WHj_d.HMtf(a2u`g_rMa<m2*G3*f#I_&rOI#A
4677 3B'QNYlFb!PuTh)<0R.Ws8FhRs8FhRs8FhSs8FhRs8FhRs8FhSs8FhRrrVP%4T7/5s8FhRs8FhR
4678 s8FhRs!7QBA3`"8>`[J9s3cQs2`X`qq>^KCKMXTf;3(JPs8%.,5CWM/1]IC[j_d.HMtf(a2u`g_
4679 rMa<m2*G3*eq*jPs1nX8M?!;'"I]>f<E4P~>
4680 s!!!oJH16$JH1B(s!%JCdf0D41Ge(hrsij$1Pc#1aBpktVW]fl7/m2lp6]&I2*tiCkJmN7q5A$s
4681 2E=W__#OGsJkJ!a?)@N!s8FhRs8FhRs8FhSs8FhRs8FhRs8FhSs8FhRrrU>J3;t`1s8FhRs8FhR
4682 s8FhRs!7<*><Oi1A=Mc^s1ieK2*5!9rVuo5G"=JP>,(uqs645X7$dfN1]IC[aBpktVW]fl7/m2l
4683 p6]&I2*tiCkCNYas1nX8K)bPp"H`]\<E4P~>
4684 s!!!oJH16$JH1B(s!%JC^Ae<(1G_1Fs/l;'mkZa_JcC<$[/U/cs7Y4NScJXf<Ib~>
4685 s!!!oJH16$JH1B(s!%JC^Ae;g1G_URs/l;'feYEUJcC<$[/U/`s7Y.LRK34b<Ib~>
4686 s!!!oJH16$JH1B(s!%JC^Ae:q1Gao>s/l;'N\`JKJcC<$[/U/Ys7XtGOT>5X<Ib~>
4687 s!!!oJH16$JH1B(s!%JC_uC!B[dX1MAhu5[JcE%U#Z\>%rS2!@1Mq^CJcE+W!K@'Pg]X2Kqc-XH~>
4688 s!!!oJH16$JH1B(s!%JC_uC!Y`qB2Q6o-X'JcE%U#].NRqTVDa1U)H1JcE+W!K$jMg'!iEqc-XH~>
4689 s!!!oJH16$JH1B(s!%JC_uC!ndeWUI3\rSNJcE%U#_CG"p:34?1Z<obJcE+W!J:@FeHD!7qGgOG~>
4690 s!!!oJH16$JH1B(s!%JC_uKQh!E&]Es0D\$1BCALJcC<$[/U/cs7Y4NScJXf<Ib~>
4691 s!!!oJH16$JH1B(s!%JC_uKQh!HJ*is0D\$1BDLpJcC<$[/U/`s7Y.LRK34b<Ib~>
4692 s!!!oJH16$JH1B(s!%JC_uKQh!18?;Z2aYV!18?;JcE(V!J:@FeHD!7qGgOG~>
4693 s!!!oJH16$JH1B(s!%JC_uBu"K1\!c@&!UNs0;S/i.FWZ5@C5aJcC<$Zi:&bs7Y4NScJXf<Ib~>
4694 s!!!oJH16$JH1B(s!%JC_uBq`F@%iOBsiNlYl=pMF@%iOBsiNlJcE%U!K$jMg'!iEqc-XH~>
4695 s!!!oJH16$JH1B(s!%JC_uBqKB0A1DFio:8Yl=p8B0A1DFio:8JcE%U!J:@FeHD!7qGgOG~>
4696 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4697 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4698 s!!!oJH16$JH1B(s!%JCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4699 JKfXhJKfXhJKk+oJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4700 JKfXhJKfXhJKk+oJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4701 JKfXhJKfXhJKk+oJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4702 JKfXhJKfXhJKk+oJcC<$\,X&?JcDSH!K@'Pg]X2Kqc-XH~>
4703 JKfXhJKfXhJKk+oJcC<$\,X'aJcDSH!K$jMg'!iEqc-XH~>
4704 JKfXhJKfXhJKk+oJcC<$\,X&?JcDSH!J:@FeHD!7qGgOG~>
4705 s!WFlJP:VgJP:\is&FXMJcE4Z!!']g!!%TMV>gRTs7Y4NScJXf<Ib~>
4706 s&FVpJTu`jJTufls&FXMJcE4Z!-c-V!-a"oV>gRQs7Y.LRK34b<Ib~>
4707 s*'$^JXM(WJXM.Ys&FXMJcE4Z!!']g!!%TMV>gRJs7XtGOT>5X<Ib~>
4708 JLH'tJLH'tJLLOuJcC<$\,QF.]ncXgJcDSH!K@'Pg]X2Kqc-XH~>
4709 JQ78$JQ78$JQ;_MJcC<$\,QGP^&J(VJcDSH!K$jMg'!iEqc-XH~>
4710 JTlZhJTlZhJTq,oJcC<$\,QF.]ncXgJcDSH!J:@FeHD!7qGgOG~>
4711 JLH'tJLH'tJLLOuJcC<$\,QF.]ncXgJcDSH!K@'Pg]X2Kqc-XH~>
4712 JQ78$JQ78$JQ;_MJcC<$\,QGP^&J(VJcDSH!K$jMg'!iEqc-XH~>
4713 JTlZhJTlZhJTq,oJcC<$\,QF.]ncXgJcDSH!J:@FeHD!7qGgOG~>
4714 JLH'tJLH'tJLLOuJcC<$\,QF.]ncXgJcDSH!K@'Pg]X2Kqc-XH~>
4715 JQ78$JQ78$JQ;_MJcC<$\,QGP^&J(VJcDSH!K$jMg'!iEqc-XH~>
4716 JTlZhJTlZhJTq,oJcC<$\,QF.]ncXgJcDSH!J:@FeHD!7qGgOG~>
4717 kpQQ3lR;f5r@%XEpF-"?r@%^Gr$_UFlR2c5JLH'tJLH'tlmVm6_#OE7VuQbsq>^Hpi;`fWnc/Uh
4718 kl1e`KdI!(lMpkaoDegjm/R(coD\dj]ncXgJcDSH!K@'Pg]X2Kqc-XH~>
4719 ku@``lW*ubrDigrpJq1lrDimtr)NdslW!rbJQ78$JQ78$l;bY"s+mTQrrDlprrD!WrrDThrrD9_
4720 "SldO!s%WdrrDZjrrDEcrrDZj!-c-V!-a"oV>gRQs7Y.LRK34b<Ib~>
4721 l$!.-lZ`C/rHJ5?pNQT9rHJ;Ar-/2@lZW@/JTlZhJTlZhm!&J0_#OE7VuQbsq>^Hpi;`fWnc/Uh
4722 kl1eG<"o?5lMpkaoDegjm/R(coD\dj]ncXgJcDSH!J:@FeHD!7qGgOG~>
4723 oI'_>pF$%Al6lZ4r[7dHr?q[Gq'Z7Cr?qmM-n,*D.0'8p"90bts6M-9s!T;qJLH'tJLH'tmjS39
4724 dJjF.FXm\&/qs'"rrBJ,!jVeLpAb-mq>^Hpi;`fWnc/Uhrr;uumJd9`!+#9^s8N*!rs%A'.gH>4
4725 L&CuN!:9ac!;$3j!8!&,!9o:>!.k0HrrJ)Yp=oeB!;fbrJ,~>
4726 oMknkpJh4nl;[iar`&surD`jtq,IFprDa(%<E9'!<WE%u"92A$s6N_fs&E)!JQ78$JQ78$m8_R6
4727 #3E:[M2nC[p](8L[Jp;)!)WChrrDlprrD!WrrDThrrE&urrDHd"%rWeqW\%[!<<''a($4o%6L3[
4728 s8N)cs8N)jrr@8ps8N)`rr@7os/#_rM?!;'"I]>f<E4P~>
4729 oQL<8pNHW;l?<7.rc\ABrHA8Aq0)i=rHAJGGBa(2GQ7Yd"93Rhs6Oq3s*&\eJTlZhJTlZhms"e3
4730 dJjET;AK?K9"t'"rrBJ,![.QLpAb-mq>^Hpi;`fWnc/Uhrr;uumJd80!6"m$s8N*!rs#]*('>7C
4731 ^AS$2!:9ac!;$3j!8!&,!9o:>!.k0HrrI`Op=0;.!;]\qJ,~>
4732 kpQQ3l6lZ4r[7dHr?q[Gq'Z7Cr?qaI.0'5o!rj\Kr?q[Gr?q[Go-aV=r[7dHJLH'tJLH'tmjS39
4733 dJjFrO4jEoGQ9l$s8N)-rri9>!!DHZs8N)ps8N)Ws8N)cs8N)drrO2@mc=BQ,ELOTk]d(irVult
4734 m/R(coD\djf80G,l%f<>JcDSH!K@'Pg]X2Kqc-XH~>
4735 ku@``l;[iar`&surD`jtq,IFprD`q!<WE"t!rl:#rD`jtrD`jto2Pejr`&suJQ78$JQ78$m8_R6
4736 #Gfl@rpHkD_"ds0Lpm<dq?I!*qY1$i!;ZZp!9!nW!:9ac!:Bdf#6=Y^rs(Z\jo*q/!-eDArrDEc
4737 rrDZj!-d&prrD<`!-a"oV>gRQs7Y.LRK34b<Ib~>
4738 l$!.-l?<7.rc\ABrHA8Aq0)i=rHA>CGQ7Vc!rmKErHA8ArHA8Ao6137rc\ABJTlZhJTlZhms"e3
4739 dJjGNZgR_5+991Os8N)-rrhNf!#tn2s8N)ps8N)Ws8N)cs8N)drrN<'roF(a<3u#iarg]!rVult
4740 m/R(coD\djf80G,l%f<>JcDSH!J:@FeHD!7qGgOG~>
4741 r@%^G!@\!H.0'>G./j2G-is>rrr;sGrVujFrVudD!<<$H!rjYsrr3!Is8=>Gs8+2Gs![pG-j'Ds
4742 s8=>Gs8FGGs7@]@s!T;os8=AGrrjhN-n,*Drr7NtJLH'tJLCRJ<E79C!rDs#q#C?o[f6Kh!"8j*
4743 p](6nq>^Hpi;`fWm/R(cmJm1dhZ!ZS!!N9#rrDEcrrDZj!!(W,rrD;>!!%TMV>gRTs7Y4NScJXf
4744 <Ib~>
4745 rDimt!EK0u<WE*t<W2st<<<,"rr;strVujsrVudq!<<$u!rl8#rr3"!s8>pts8,dts&K*t<<E2#
4746 s8>pts8H$ts7B:ms&E(ts8>strrlF&<E9'!rr7OLJQ78$JQ;\Lbl7b@LlD-/s+n,`"LS4S!4DS$
4747 rrDlprrD!WrrDEcrrDHdrrCpU!qcO!rVultm/R(coD\f7fDkjNl2La-JcDSH!K$jMg'!iEqc-XH~>
4748 rHJ;A!I+SBGQ7^AGQ%RAG6._frr;tArVuk@rVue>!<<%B!rmIgrr3"Cs8@-As8.!As*+MAG67eg
4749 s8@-As8I6As7CL:s*&\cs8@0ArrmWHGBa(2rr7OnJTlZhJTh0><E79C!n@8lq#C?o[f6J.!"8kd
4750 p](6nq>^Hpi;`fWm/R(cmJm1dhZ!Z-!$;+=rrDEcrrDZj!!(W,rrD;>!!%TMV>gRJs7XtGOT>5X
4751 <Ib~>
4752 r?qgK./t^qr?q[Gr[7dHr?qdJ.0'>H-ij;E-j'Dss8=>Gs8=>Gs8FDSs![mq./t\Ds!T;qq^;RH
4753 -n,,o-j'Dss8=>Gs8=>Gs7@]>s8=>Gs8+2Ls![mqs![pIr[7dHJLH'tJLH'ts&I;C!rDs%q#C?o
4754 "oWf]#u1'krs&1@,6ecSb5VG@!<)rt!<3#u!"/Em"987M-jBu7QJqiHI/of<&H)P4fes!bbl@bC
4755 rs%.7"Y@mu!;ZX&70&t[s+M$as7H?trr33#NA(YI5Ipdnrr<`.?O.L)s8VtJ-jBu7QN-sb!<<)r
4756 !<<''r/EB:$pV<!s8)d$s7UX]"qjVPrr;uu!qo7hqZ$QqqYpWo!!`E%rrE&u#536c"qjVPrr3N%
4757 E?56(L]@AS!<<)e)$Hf3rr<&qM#RG_LI)CT2i*2O$jA29reM,;8IY_23/!*DL.)gZ"WU?pqZ-YP
4758 #)5bh"U6/\reURS!eVm&rJ1FRJcDSH!K@'Pg]X2Kqc-XH~>
4759 rDa"#<W?)!rD`jtr`&surD`t"<WE*u<<3'r<<E2#s8>pts8>pts8H"+s&K)!<W?'!s&E)!qc*au
4760 <E9(t<<E2#s8>pts8>pts7B:ks8>pts8,e$s&K)!s&K+!r`&suJQ78$JQ78$s&I;C!rIe5q#CAM
4761 "oPZbO1G8hrs&/'PDPL1pAY*lM#IARM#RGSL^NdHM#[@_QALX"gYr/8,QQ?p,lIZHXs=-:nGiRg
4762 rs#VO"@DVY!;ZX&&HM%ps!&`fs6'Fprr32sFX%)&:u2-Nrr<`&63JU;s8Ve+*<Qa;ZN'q)!<<)r
4763 !<<''pN7\b&Q%<[s8)d$s63i,!uPD2rr;uu!pD?>qZ$QqqYpWj!"8c*rrE&u#3fG2!uPD2rr3Mj
4764 =qh)kVZ6Yr!<<)J"prlVrr@9>s8N',q-FRKL]@$M&.ig[rr3PmB+>(kKDtoNp1PHK%77B#qZ-Zr
4765 #5<6b"qa\frr;uu!pD?>rVlkAJcDSH!K$jMg'!iEqc-XH~>
4766 rHADEGQ2merHA8Arc\ABrHAADGQ7^BG6%[?G67egs8@-As8@-As8I3Ms*+KeGQ2l2s*&\eqf`/B
4767 GBa)cG67egs8@-As8@-As7CL8s8@-As8.!Fs*+Kes*+MCrc\ABJTlZhJTlZhs&I;C!n[K*q#C?o
4768 "m/,T)3+Xprs$P<&dBV+p\t3m!<)rt!<3#u!"-=Z!WUnR'`o(Ldc(3/&-/4#IJj*LL_pG+q#CEo
4769 rs"8r$"3Q/!;ZX&#QXPtrt'h_s.99[rr32[>o<b_BCc'%rr<_V/-\&ds8UhQ'`o(Ldf9=I!<<)r
4770 !<<''hd%*&)/&O:s8)d$s2[kH"seHfrr;uu!kTKSqZ$QqqYpWL!&"6MrrE&u#09IN"seHfrr3MI
4771 7h#\fbQ%SB!<<(l"!d:1rr<&qM#RG^HR/h.?ANYH"V4E-L]qfJ"9]ZEreLf%/IMRe/T?OC!<7iZ
4772 G;9U/%6&k;M#RGVA.Se?L]@F+s/#_rK)bPp"H`]\<E4P~>
4773 r?qgK./t^qr?q[Gr[7dHq^;IEr?qaI-n,#n!%@aEr?q[Gr[7sM./t^qs8FGHs84;Fs8FDHs8=>I
4774 s![pG-ij;:-ij;F-ij;E-jK]"s![mqs8=>Gs+)SL."Ndt.0!;lrr_S<!d"/:rr<b"]D7?b3<0$R
4775 /d8!EegUg@s8N'!rVultrr;uu$@p=Zs+(/OkPX"Rir95W!Y#*>!OVk+&aou7c1,EH!<<)f#S#&K
4776 B)hr-s"(Y[5l^cm$fq?C!$D7@qa^jPo]JaJ[/^.+!/\tj<<89_JH/d7r7Q,jrr<&us8N)trs8Km
4777 "Hi?>8-H<rs8N)urt"lW"eteC.0d]irr<%LbMrBurrDrr"7(L>F8c.=!<<':pau`Epspku_uKK]
4778 "I8TDJcG`M!<;X>"Jkhm!!)kOrr=6?@YIPW2E,*!:&lJoLkH1?Kn)bq*/KD>!%rVQF?PG9!!)tR%
4779 u)D49nI^=!aph?!!#E'H2WO!!.k0HrrJ)Yp=oeB!;fbrJ,~>
4780 rDa"#<W?)!rD`jtr`&suqc*XrrD`q!<E8ts!*/prrD`jtr`'.%<W?)!s8H$us85mss8H!us8>q!
4781 s&K*t<<3'g<<3's<<3'r<<iJ's&K)!s8>pts++1$<In/$<W?(Drr_eqMUqS&s+hAqlh[c?`;fl4
4782 O,`/tif0#os8Rn2rVunRrr<"S$E<UUs.G1jq#'9Xir95M!?(nT!U]md&_@(+jQ'#8!<<)N![$La
4783 9`P1hs"$hDW;l\u"o81q!)3Fmp)OCCq:->gkl:Y_!)M\:*s1'o1B<F(q8u\:rr<&us8N)trs8<=
4784 #I4*T)$oI&s8N)urt"Q.$c2_U$4cS*rr<$gj1tNkrrDrr"5m2_Vu?Yq!<<':mg]`AqnNOKnGhnb
4785 $+0K_@/p6,!<;$c#h8YL!-e;>rr=6Hde6fD\NA75=TFH]s6qGVr8qDfFoVIt!0-LDb#JE@!!)ut
4786 &,%"KZ2)of#jD<g!!#LK_#=95GCfdjrrIuVp=]Y<!;fbrJ,~>
4787 rHADEGQ2merHA8Arc\ABqf`&?rHA>CGB`ub!-e>?rHA8Arc\PGGQ2mes8I6Bs87*@s8I3Bs8@-C
4788 s*+MAG6%[4G6%[@G6%[?G6\(ks*+Kes8@-As+,BFGCashGQ1[grri;I,S&T(s8N'5@cuqt!7(WE
4789 _?MOBpRh[Cq#C?o!<)rt!<3#u!"*<,IfC,_YP.Y!1?/<<ZiO_;$j-2&rt1Cp<q4Fj!!*'!Oo\VR
4790 c%l?"q>Vuf!8[\=$k<.756/4ns4If%b58aX+SPj8!!$d(bmasIrtPO;p@YpNs8N'!rr;uurVm/V
4791 $m*Rg\dKYSqZ$Qqrr3MG"tS="TER"Ds8N'!Aak0Fs8N)srri;I,S&T-s8N*!ru&ZX/(aNg"Y]ZN
4792 ^'5e)qo_#"rr<'!ZNVQ@q#:<oqM>.O+u4In'**/*H@?M-EJTE^-$4l_(]\9+L^O2gK7dVPLkl$2
4793 rJ1u+"qYU*@g3NtLkl$22Ln0nL]@F+s/#_rK)bPp"H`]\<E4P~>
4794 r?qgK./t^qr?q[Gr[7dHq^;IEr?qaI.0'5o!rj\Kpa?.Br[7sM-n,*Ds8FGHs8=>Gs848Fs8=>I
4795 s![pG-ij;:-ij;F-ij;E-jTc#s![mqs8W'H!<7TuJLH'tJLLOuci<tE!=4e]s8N'+C&e5+!"/c+
4796 XT25trs%<[+TMHA!<)rt!<3#u!!$a4rrNK,WS[XZb5aX(ec7?%rt1RtC]FG!!!*'!QN1h$s60L`
4797 q>V#g!#bh'%X;L`VuTits1A>#rr3Pq!#tt<!!$g7s69S"rs8\)qu?Zrrr;uurVlr3!(Hne!p]h*
4798 qZ$Qqrr3&%!)`aq#MoG's8N'!C&%`.!<)rs!!*@er;Zcss8N/&!)`aq#2T>&s/H&pqu?Zr"8FkZ
4799 UA+Zf!;_NO!"1]@Lk>[02Md0A!!W4T#DW9]Lkl37>5O-U!<%]TA,mqTL^/>.%Z#o@!''k3!!%TM
4800 V>gRTs7Y4NScJXf<Ib~>
4801 rDa"#<W?)!rD`jtr`&suqc*XrrD`q!<WE"t!rl:#pf.=or`'.%<E9'!s8H$us8>pts85jss8>q!
4802 s&K*t<<3'g<<3's<<3'r<<rP(s&K)!s8W'u!<7UMJQ78$JQ;_Mci=!#!Kl=7s8Rl^k5YJSLlq`;
4803 X,,L/rs%/4XT/<VM#IARM#RGSL]HW;rrS%5kMH4CG6!p.PlQ%-rt.!dcN!pf!!*'!1'#W"s2tBB
4804 q>V#D!'1).*?EH*2ZUbqs'l&$rr3PV!'pSa!!(=Es31O!rrW8Equ?Zrrr;uurVlq/!2'8j!mgp4
4805 qZ$Qqrr3$n!3lJ&#H[u$s8N'!bkV5<!<)rs!!*bHr;Zcss8N-o!3lJ&#-@l#s%!-jqu?Zr"76^,
4806 e+`kBGP_@>!"6gHs6BXm`rH)(!#GG2#Pe?/s8N0$bPV>>!<)p!@fW/#rs-mN5l^ia!6k??!-a"o
4807 V>gRQs7Y.LRK34b<Ib~>
4808 rHADEGQ2merHA8Arc\ABqf`&?rHA>CGQ7Vc!rmKEpic`<rc\PGGBa(2s8I6Bs8@-As87'@s8@-C
4809 s*+MAG6%[4G6%[@G6%[?G6e.ls*+Kes8W(B!<7UoJTlZhJTq,oci<tE!A!:+s8N'+l2UdY!)ijs
4810 *rt6urru7!Y5eM%!<)rt!<3#u!!)<`rrN3$jPKn@/caK&3rmJ'rt-"HlMplu!!*'!('*Y"s(MH5
4811 q>V"+!36'6Gn0->(]`^us!Ig"rr3ON!2BMn!!)<as(_V%rrE,\qu?Zrrr;uurVlpH!87AO!cn@9
4812 qZ$Qqrr3$A!9!kV#>Y?&s8N'!lM1DZ!<)rs!!+V3r;Zcss8N-B!9!kV##>6%ruM0squ?Zr"2kHf
4813 me?_]!;_NO!"411LfsccI#*S^!&48*#C6@jLkl'3HM`Nu!<%]T'``@TL^-'C<euP3!.Fa#!!%TM
4814 V>gRJs7XtGOT>5X<Ib~>
4815 r?qgK./t^qr?q[Gr[7dHr?qaI.0'5o!rj\Kr[@gH!@\!H-ij;G-ij;H-ij;D-jK]"./t\Ds8",G
4816 s!T;qr[7mK-n,,n-ij;@-ij;E-ij;H-jou&./t^q./t^q./s6t."Ndt."NcJ-rj9lrr_1_!dXS@
4817 rr<D_s8W&u!rr9W!7:`F#5S<(s8N'!rVultrr;uu!8%5M"`+/>0p:AOru4$#`rGi<#Q"K#-NMp$
4818 s8)crs8OGHg].<N!!)ip&GcG5s1pD5,6'J#ci=#0!5AI4'E%n7s8N'!g].<N!!WC=!!+g;h>[HS
4819 !<3#u!<)p!56/FsrrW-!"oA9!!<3!"1]Yo%rs/B##64]'!8%#GrrDrr"5m>aH2[dC!<<'#1]Yo%
4820 rs&<"#6-:Udej(E!!5aqT_ABc!;_NO!"3t+Lkbs1G)1s0!!3(T!a$NLrW!3)Lkn(l!?+^VreURS
4821 rJ1M!!+l.c#DW9]Lkl$2F8Lan!.k0HrrJ)Yp=oeB!;fbrJ,~>
4822 rDa"#<W?)!rD`jtr`&surD`q!<WE"t!rl:#r`0!u!EK0u<<3't<<3'u<<3'q<<iJ'<W?'!s8#^t
4823 s&E)!r`'(#<E9(s<<3'm<<3'r<<3'u<=8b+<W?)!<W?)!<W<#L<In/$<In0L<R1UIrp$#1h"^pL
4824 L^O%Zs8Ih2s8S+8qYpL!qM:13s+lL0s8RoSs8RlTqu6U!R>?["deMi%*<$EKo)J7]%fZM.$39i#
4825 s7QEms8NE+p](9e!!)ip&G,u5s'C"t;u[:-o`+q%!:^!f'D_\:s8N'!p](9e!"/`O!!,cbnG`If
4826 !<3#u!<)p!%fl+urrW#s$i9o'!<3!"%06&"rs//r%KHG.!;?3frrDus"T?^u"1.t+rrE*!!Y#/%
4827 rr32p!"Jr9!;-0grr<*?#grAG!-e;>rr<Z*s8Vus!;HNnqu?m"s8@a*$2so1!WW0F!!,cbnG`If
4828 !<)p!%fl+urs/B#$ig5,!;?<i!-a"oV>gRQs7Y.LRK34b<Ib~>
4829 rHADEGQ2merHA8Arc\ABrHA>CGQ7Vc!rmKErceDB!I+SBG6%[AG6%[BG6%[>G6\(kGQ2l2s8$pA
4830 s*&\erc\JEGBa)bG6%[:G6%[?G6%[[email protected]>G?%Ygrri21&e*dp
4831 s8N'+r;Zff!"Ao-"p"N!rs$dL2#mRU!<)rt!<3#u!!)oqrrir6!G&>.ir98[#6jr'`W81#rt,D7
4832 qu?]M!!*'!"T\H"s4RGQq>V#P!BC*+bqH^/"p4Z$rs&Q!rr3Yr!%\*L!!)ors4RH$rt#/2A?G\,
4833 s8N)us8N)trrNE*q#:9pkl<71s8N)urrNB)qYpL"cN#g%rr<&rq#C?or;Qor]+PP3rVults8N-)
4834 !;c]p#1!9+rrrK"qu?Zr!Xp.;pAY*mqM>.O&Vc*tJH,\)LkpT^$&FCj4;.hr!!iX^L^=%^2-bk7
4835 M#RJRL]R\ZK`6c4HiOt=L]@F0qhP4PJcDSH!J:@FeHD!7qGgOG~>
4836 r?q[Gr[7jJ-n,#ns![jGs!RmIr?qaI-n,)p""=0t./j2F./a,F./j2G-ij;G-is>rqu?XDs8W!F
4837 s8W!Frr;^@!<;mDrr;sG!<<$H!rj\KJLH'tJLH'tr$_SFbl7b;!!rB"rrE#trrE*!!XSl&rVm$$
4838 !rr9#!<)rt!<3#u!!)oqrs&:E*rl9CHfP,+m.p\cF8u7C!;c]prrE*!!X&N"rr;uuq#:Y)!4c'V
4839 n-Jag$i^/8#lk&0!W`9$!WW0"!;c]p%0-G/q0=%^!!@TJrr<&us8N)trs/o2!s8T*!!!&rs8N)u
4840 rrNK,q>L<t!!<3#!!)oks8N)qrrVin#lXf'!<<'##lsf"rriB(rriE#qu?Zr!YkcopAY*mqM>.O
4841 rJ:IRrJ:IRs+h@t!#]j4L]@F2LkS,,!!!'eLkl$2rJ1md!!33&!<<*#Lkl$2LAQc,!.k0HrrJ)Y
4842 p=oeB!;fbrJ,~>
4843 rD`jtr`'%"<E8tss&K$ts&B(!rD`q!<E9%u"',A$<W2ss<W)ms<W2st<<3't<<<,"qu?Xqs8W!s
4844 s8W!srr;^m!<;mqrr;st!<<$u!rl:#JQ78$JQ78$qGkc>!qhA2q#CAMrVunRs8N+VM#@8VLl)03
4845 Lku$0s+p[Ss+pXR#5GTfLkpuCj8T,-q>_5Xs8N*"rr<#t!!*'!!<E-!s8Duuq#:X9!:CQXh@T&S
4846 (B4=T!WW<)!W`9$!WW0"!<3#urW!!!mpQh/!!]Y,rr<&us8N)trs/Z+!s8T*!!!&rs8N)urrN9&
4847 rr2p&rW!'#rr<&uq#C?oqYpW]!##81rrE*!!WrH%rr30$!!E6%!;c`q!!3<,]_;@*GP_@>!<)rt
4848 !<)rt!<<'5AcQN*rr)lts8VOr&c_n9YQ+V&!<)p,!WW<)!W`9$!WW0"!<2lq!-a"oV>gRQs7Y.L
4849 RK34b<Ib~>
4850 rHA8Arc\GDGB`ubs*+GAs*"JCrHA>CGBa&d"*achGQ%R@GPqL@GQ%RAG6%[AG6._fqu?Y>s8W"@
4851 s8W"@rr;_:!<;n>rr;tA!<<%B!rmKEJTlZhJTlZhr-/0@bl7aB!(cnbrrE#trrE*!!<E3!rs&5u
4852 $NL,+!<3!"rVurts8N)trs$eD#QOi@i8ah;F8>k>m/R(d!<3!&q>^NqrrE-!rrW#s!;QR#$NTr/
4853 n9dR/!*fI&$ip>1!s/K'!!E9$!!*#u%f-//s3FCF!!!hns8N'!rr;uurVm-(!!<<)!<<*%qZ$Qq
4854 rr3!"!<)p%p]([$rr<&ns8N)qrrT(u8H&Sg!<<'"!<E)u"o&')rrE,rs8N'#!taPerr<&qM#RJR
4855 M#RJRM#RJTL_LX*:4A"Q!!%h2DCG\g!"=(-L]@GRL^X:a!WiB'!!!(VL]@GOL]@F+s/#_rK)bPp
4856 "H`]\<E4P~>
4857 V^MQFi[=g,JLH'tJLH'tr$_SFbPqSC!Vl]p!<)rt!<<'#1B>f$rs\`(#64]2!:p0iqu?`rs8N)q
4858 rr_//!!_K`!hfTOrr3b]!#kn;-NMp$s8)crs8OGHg].<N!!)fo$,Q[3"7c@)N;t=)rrOqUeG9.E
4859 !!V-Ws8)d"rVm,[J,ffRrr<&us8N)trrOqUeF`e@!<3!"1B>f$rs&<"#64]'!;HNn!;ZWq!!3&u
4860 rrE*!!]'i'rr33!!!`HV!7LcErr</`'EX0drr<&qM#RJRM#RJRM#RJTL^+OmFbkj-!!)qQ#BrQ9
4861 ",Ma5!<%]T)ZXmRM#RJOL]@F+s/#_rN;rV,"J,Vj<E4P~>
4862 Vc<`si`-!YJQ78$JQ78$qGk`=!JlU-s8RoRs8RoTrrS4:qYpL'qM:13s+uR2s8VtPM#RGSM#.,R
4863 l*Z>-j8T0E!/UXS(5MrSs8NE+p](9e!!*'!$39i#s7QEmq#:Y,!3QM'qurhq?N0s+$iotrs8N'&
4864 p](9f!"/])#L?fY%KHG.!<3#u!<)p!$iotms8N)urrNW0o`"jpoDf@#rr<&ns8N)qrrW0"!r`0!
4865 !<<'#%06&"rs&)q%K?h:o_\[g!!C%@"MFL/!-e;>rrE#trrE#trrE*!#7(>(s8VWi!;uj%cX?e_
4866 s8N'!rVlp-!;60frrDoq!-a"oV>gRQs7Y.LRK34b<Ib~>
4867 Vfr.@icbD&JTlZhJTlZhr-/0@bl7b>!!rB"rrE#trrE*!!X8Z$rr3DR!&X`U!W`6"s5!_Urr;uu
4868 qu6fu^GGpJj8T0!!7CfG(,Z)cs8N6&qu?]M!!*'!"T\H"s4RGQq#:XI!2UG0nH2#V_Z'Q:"p"Pr
4869 s8N'&qu?]N!%7dG#l_Rq!&afV!!*#urrE#t!X8Z%o`+pkrr3$(!;c]p#1*?,s8N'!p](6nqYpWl
4870 !!rQ'rrE*!!X8Z$rr32L!&X][!;cTmrr<.]!taPfrr<&qM#RJRM#RJRM#RJTL^*t]L5:Y#!!)tR
4871 #`!"3!$$fN!!)tR!WrFWq2#%NqM5+OJcDSH!J:@FeHD!7qGgOG~>
4872 LF<0&JLH'tJLH'tr$_SFbl7b9!"8T%rrE#trrE*!!iuB!rr3Da!$D7@;?3Qns6'F_rr;uuq>UQr
4873 !!3)\rr`-/!QG'<(AS.9g&I?<D#aP#!!*'!Q2kb$s69Raq#:Zd!"'><s,70_A,cK0\,\tns8N'&
4874 D#aP$!#>G3#6"T'rr2rurr3$+!;HKm!k85!o`+pkrr3&$!)`aq#2]D&s8N'!p](6nqYpWg!"8c*
4875 rrE*!!iuB!rr32[!$D6A!)WRmrr<3%jq7`Qq#:<oqM>.OrJ:IRrJ:IRs+gmd!.'HWFoVO>L^/\8
4876 !JcI7!/1?-!b)-Uq2#%NqM5+OJcDSH!K@'Pg]X2Kqc-XH~>
4877 LK+?SJQ78$JQ78$qGkc>!qM/2q#CAMrVunRs8N/$Lt_k.%,-N<s8S4;p&G'RLku'1s+pLN!r[q3
4878 jSo>U"9S,mrtb,+"SVjM!71]Fbl@bDs"ON"s8U=D!;QR#ci>%4s8ODY!7:`F!aPenq>^Hp"jd5K
4879 c2]Tsrs&?#!rr9#!<3!"!s&<!rrQI+R.UFY!<3!"9)u3qrs#\-9`P+m!;HNn!;c]sirBnos8N*!
4880 rrPgnYl=Y,YQ.As8H>jhs8N'%s1ed@]_ML,GP_@>!<)rt!<)rt!<<'("9A8ts/5ntqu6ou!!<3#
4881 !s&<!rrQI+R/-d^!;c]qGCfdjrrIuVp=]Y<!;fbrJ,~>
4882 LN`auJTlZhJTlZhr-/0@bl7a4!+,I#rrE#trrE*!!ZqF#rr3C(!3Q;$$39c!s(;<3rr;uuq>UN`
4883 !!_Na"5*_[q>UC0`;pMHrtPP"s8Qg6!<<'6!:0[bC&e8/rs<08%upVh&I/=%rr3$G!7^iErr<5g
4884 s8Qm8Qi-jfm/R@jrr<&urrE-#rVlpF!7^Z@rrE&u!ZqF#rr31"!3Q;$!!)cnrrDoq!gs$prVult
4885 s8N-B!9!kV##PB&ruM0squ?Zr"TOG_&ENWd!!)kOrrE"RrrE"RrrE(T#6=g[LkmDY!;hQVIK0J+
4886 L]IMSL]S7jEVYFj!;_KO!.k0HrrI`Op=0;.!;]\qJ,~>
4887 JLH'tJLH'tJLLOudJjG*ZLRnB9*'D7s8N)ts8N*!rt>)V"f(nF.gEfhs31NelfVUT!<3#u!<)p%
4888 /#_n6\H!E+rrUmS'`@tGNW;EGmKX6JnnJ.)s8VKl%aX]\!!)fo$2b#.2uip-!!2$WruV)9!c?]i
4889 n@Mp)rr<%Tcgk3>NrLW.mejTq(B=C7!<3!.BE3ecs8W!p!c?]in@Mp$s8N)urs\ZP"f(nF.gEfh
4890 rr<&ns8N*!rs(6`nbpp0!IOeFrrE*!)YbccU\WLl#/L96.Kl(1l[f*9!!*'!jUqWPq>UEpqM>.O
4891 rJ:IRrJ:IRs+hsr!$[#<,QIh#L_j6EL1:2lLkmti7u)nVL+E?dFbYEW0o1Vc!;_KO!.k0HrrJ)Y
4892 p=oeB!;fbrJ,~>
4893 JQ78$JQ78$JQ;_MdJjHSj88f8Q\jVps8RoRs8RoTrt>'dNT9utNK3c5s29_sqs1PDM#RGSM#I>X
4894 X5NjOcA8.SrrShn0Dthb0*%[FeH-oVj\GjVs8UUN+m.l^!!)fo$2=Q%OT5?A!!;rpruUn_"HM[D
4895 kc7#Lrr<$qk2mfgec/7Sp%OdQ2#mRU!<3!"*!!kTrs8?I"HM[Dkc7#Gs8N)urs\9'$c;eX$OuP(
4896 rr<&ns8N*!rs)H?pA2WK!k\F2rrE*!)XRq@_Y_1X%IX8a$jj?<h-g9_!!*'!^'+YPq>UG=qZ$Qq
4897 rVultrVults8Nfr!.ape8H8bjs%9rspQkk:s8O&=_Z'QDpF$0)kPaVF63$rb!;c]qGCfdjrrIuV
4898 p=]Y<!;fbrJ,~>
4899 JTlZhJTlZhJTq,odJjGide`U:%0tths8N)ts8N*!rt<'M/(jZm"YBHKs#:"=qmr$m!<3#u!<)p%
4900 B$C,?@/tl>rrPLeNr8nl'EHkeNWE;RcA2H#s8S)[=n9jo!!)fo$/bgaeGoP-!!iH$ruTr,%]Agn
4901 hO#Yirr<%8o$7dNmf-nCqX7hmJcG`M!<3!"%055`rs7Bk%]AgnhO#Yds8N)ursZXG/(jZm"YBHK
4902 rr<&ns8N*!rs*JjqXgft#NYj`rrE*!)SZG+f_M9G/GT7Z"s_@hbW5_'!!*'!MujROq>UEpqM>.O
4903 rJ:IRrJ:IRs+hC!!*t:^9)nsJLc0+(Il%-oLkl99G5d:+FU8:UJ;/5E'SqPF!;_KO!.k0HrrI`O
4904 p=0;.!;]\qJ,~>
4905 s!WFlJP:VgJP:\is&IJH#2!H+!>%Ppp](6nrVultrr32rFWgo"9#pr2#QB]""?tiG!<3#u!<)p%
4906 fk)3*'3*fKrrQa3@/U$4jo>his49+2/'@nmrr32S2$>GQ!!)cn#B9a+s8VZj%K-5Hrh2Rg!YnD/
4907 s8N'!q-+(>L&_2+AfLjc<8ITS!!*#u%e!:/!<E0"rh2Rg!YnD/qZ$QqrVm)qFWgo"9#pr2rrDfn
4908 rrE*!#2!H+!>%Ppr;Zcsrr32rFWgo"9#pr2$1r'Q![*=!rr<&urr_<n!fHjS!!)kOrrE"RrrE"R
4909 rrE(T-&"Ad"!`!i!/QGQ2@ffq/Tur+Ik1p-!/QGd<[%hN$Ro;9L]@GOL]@F+s/#_rN;rV,"J,Vj
4910 <E4P~>
4911 s&FVpJTu`jJTufls&IJH#2lYGLm"q%p](8LrVunRrr32pZ]^0.Zh==t#QD8pN3W;:M#RGSM#I>X
4912 iNA9!Q+?eQrrO)=_u0NB_Z1VTs/R@H5O\XQrr32',6L1"!!)cn#93a*s8V0\*;ogWqh[-<"<Lme
4913 s8N'!n3-q!X8i47;A'$MC%qZ-!!*#u%bElQ!<E0"qh[-<"<LmeqZ$QqrVm)b>S[DW?0V@grrDfn
4914 rrE*!#/*kH!>\PPr;Zcsrr32c>S[DW?0V@g$05/!"#$SPrr<&urr]n:"MFU2!-e;>rrE#trrE#t
4915 rrE*!-1k"?$X*6)!<<)6;A'$MC%qZ-f00TD!<<)rM)5VD*aZbarr<&qrr@7os/#_rM?!;'"I]>f
4916 <E4P~>
4917 s*'$^JXM(WJXM.Ys&IJH#,=Hm"!1t6p](6nrVultrr32A8e;.MG4tq8#PCds&9n$P!<3#u!<)p%
4918 V*PLm-\M?XrrNT/k5>5e?iXd<s+M3n>kn@"rr31V('e+?!!)cn#7U\)s8S2]EW#hWmW0f`#:ONG
4919 s8N'!asmNOfDklI5n!lDKDbcL!!*#u%]V2f!<E0"mW0f`#:ONGqZ$QqrVm)@8e;.MG4tq8rrDfn
4920 rrE*!#,=Hm"!1t6r;Zcsrr32A8e;.MG4tq8$,T%:#=-K4rr<&urr\,[&EN]f!!)kOrrE"RrrE"R
4921 rrE(T-#t(0$UBFH!/QG5,6e2a7YZ_T>8dVF!/QG\4Ve2('g$PoL]@GOL]@F+s/#_rK)bPp"H`]\
4922 <E4P~>
4923 s!WEuJH16$JH1B(s![nIJcC<$\,QF.]ncXgJcDSH!K@'Pg]X2Kqc-XH~>
4924 s&FUMJH16$JH1B(rDeFKJcE4Z!-c-V!-a"oV>gRQs7Y.LRK34b<Ib~>
4925 s*'"oJH16$JH1B(s*+KCJcC<$\,QF.]ncXgJcDSH!J:@FeHD!7qGgOG~>
4926 s!WEuJH16$JH1B(s![nIJcC<$\,QF.]ncXgJcDSH!K@'Pg]X2Kqc-XH~>
4927 s&FUMJH16$JH1B(rDeFKJcE4Z!-c-V!-a"oV>gRQs7Y.LRK34b<Ib~>
4928 s*'"oJH16$JH1B(s*+KCJcC<$\,QF.]ncXgJcDSH!J:@FeHD!7qGgOG~>
4929 s!WEuJH16$JH1B(s![nIJcC<$\,QF.]ncXgJcDSH!K@'Pg]X2Kqc-XH~>
4930 s&FUMJH16$JH1B(rDeFKJcE4Z!-c-V!-a"oV>gRQs7Y.LRK34b<Ib~>
4931 s*'"oJH16$JH1B(s*+KCJcC<$\,QF.]ncXgJcDSH!J:@FeHD!7qGgOG~>
4932 s![UAs8Vfns8VHdrr:OL!7UQ?!7QK!JH16$JH5*<s![nIJcC<$\,QF.]ncXgJcDSH!K@'Pg]X2K
4933 qc-XH~>
4934 s&Jdns8Vfns8VHdrr;Zls8W*!!<;0]!7UQ?!7QK!JH16$JH5*<rDeFKJcE4Z!-c-V!-a"oV>gRQ
4935 s7Y.LRK34b<Ib~>
4936 s*+2;s8Vfns8VHdrr:OL!7UQ?!7QK!JH16$JH5*<s*+KCJcC<$\,QF.]ncXgJcDSH!J:@FeHD!7
4937 qGgOG~>
4938 s![UAs8Vfns8VEcs8VHd!7U66!7UQ?"4I5Mdt%LM!.b-$!:^'h.0!:us+13Zrr<&4L]@F+s/#_r
4939 N;rV,"J,Vj<E4P~>
4940 s&Jdns8Vfns8VEcs8Vfnqu?Tp!7U66!7UQ?"4I5Mdt%LM!.b-$!:^'f<It1$s0r".GJ4"VGCfdj
4941 rrIuVp=]Y<!;fbrJ,~>
4942 s*+2;s8Vfns8VEcs8VHd!7U66!7UQ?"4I5Mdt%LM!.b-$!:^'hGQ1Zos+13Zrr<&4L]@F+s/#_r
4943 K)bPp"H`]\<E4P~>
4944 s![15s8VEcs8VKerR:-6!7UT@!7UoI!7QK!JH16$JH53?s![nIJcC<$\,X&?JcDSH!K@'Pg]X2K
4945 qc-XH~>
4946 s&J@bs8VEcs8Vfn"TJH%s8W#trR:-6!7UT@!7UoI!7QK!JH16$JH53?rDeFKJcE4Z]6Ai+V>gRQ
4947 s7Y.LRK34b<Ib~>
4948 s**c/s8VEcs8VKerR:-6!7UT@!7UoI!7QK!JH16$JH53?s*+KCJcC<$\,X&?JcDSH!J:@FeHD!7
4949 qGgOG~>
4950 s!S$Ns8N*!s8E#ts8;rrs8N)ss8E#ss8E#ss8;rts6fphdf@kj!<(CG!<1FJ!7UT@!n.,LrR:]F
4951 s3h,Odf9Bs!<1Gu!.b-$!.k4N.0!:us+13$s+138rrJ)Yp=oeB!;fbrJ,~>
4952 s&B4&s8N*!s8E#ts8;rrs8N)ss8E#ss8E#ss8;rts6fphdf@kj!<(CG!<1FJ!7UT@!n.,LrR:]F
4953 s3h,Odf9Bs!<1Gu!.b-$!.k4L<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
4954 s*"VHs8N*!s8E#ts8;rrs8N)ss8E#ss8E#ss8;rts6fphdf@kj!<(CG!<1FJ!7UT@!n.,LrR:]F
4955 s3h,Odf9Bs!<1Gu!.b-$!.k4NGQ1Zos+13$s+138rrI`Op=0;.!;]\qJ,~>
4956 s!RjIqu?Wqs8W&us8W*!s8N9's8N'!s8Vuss8N9's8N'!s8W&us8VKermUWB!7UlH!n..urW)uI
4957 p&G*Ar;ZiHqZ$lM!7Lqs!7TEr!!(K!!.b-$!.t:O.0!:us+13$s+138rrJ)Yp=oeB!;fbrJ,~>
4958 s&B%!qu?Wqs8W&us8W*!s8N9's8N'!s8Vuss8N9's8N'!s8W&us8VKermUWB!7UlH!n..urW)uI
4959 p&G*Ar;ZiHqZ$lM!7Lqs!7TEr!!(K!!.b-$!.t:M<It1$s+13$s-<TbM?!;'"I]>f<E4P~>
4960 s*"GCqu?Wqs8W&us8W*!s8N9's8N'!s8Vuss8N9's8N'!s8W&us8VKermUWB!7UlH!n..urW)uI
4961 p&G*Ar;ZiHqZ$lM!7Lqs!7TEr!!(K!!.b-$!.t:OGQ1Zos+13$s+138rrI`Op=0;.!;]\qJ,~>
4962 s!RjIqu?Wqs8W&us8Vuss8W*!s8W*!r;Q`squ?Wqs8VHd!n..uq#CEDqZ$WFr;ZiHpAb3Bqu?`G
4963 qZ$iL!7Lqs!7UlH!7QK!JH16$K)kp"s&FXMJcC<$JcD#8!K@'Pg]X2Kqc-XH~>
4964 s&B%!qu?Wqs8W&us8Vuss8W*!s8W*!r;Q`squ?Wqs8VHd!n..uq#CEDqZ$WFr;ZiHpAb3Bqu?`G
4965 qZ$iL!7Lqs!7UlH!7QK!JH16$K)kjMJcC<$JcC<$Q2^lAs7Y.LRK34b<Ib~>
4966 s*"GCqu?Wqs8W&us8Vuss8W*!s8W*!r;Q`squ?Wqs8VHd!n..uq#CEDqZ$WFr;ZiHpAb3Bqu?`G
4967 qZ$iL!7Lqs!7UlH!7QK!JH16$K)kpqs&FXMJcC<$JcD#8!J:@FeHD!7qGgOG~>
4968 s!S'Os8N'!s8W&us8W&us8Vuss8W*!s8NB*s8N'!s8N*!s7u`qs6fsde+`nCe,'+Fe,97He+WhB
4969 e,01Ge,'+Mdf@hsdf@kGrVurIJH16$JH1<&s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4970 s&B7's8N'!s8W&us8W&us8Vuss8W*!s8NB*s8N'!s8N*!s7u`qs6fsde+`nCe,'+Fe,97He+WhB
4971 e,01Ge,'+Mdf@hsdf@kGrVurIJH16$JH1<&rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
4972 s*"YIs8N'!s8W&us8W&us8Vuss8W*!s8NB*s8N'!s8N*!s7u`qs6fsde+`nCe,'+Fe,97He+WhB
4973 e,01Ge,'+Mdf@hsdf@kGrVurIJH16$JH1<&s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4974 s!S'Os8N'!s8W&us8W&us8W*!s8Nc5s8N'!s8N*!rr<'!rrE*!!!*'!rW)uum/R.8pAb3Br;ZoJ
4975 !7UoIs3p`C!7UfF!7UoI$I\tTdf@hsdf@hsrmQDuJH16$JcPg!s&FXMJcC<$JcD#8!K@'Pg]X2K
4976 qc-XH~>
4977 s&B7's8N'!s8W&us8W&us8W*!s8Nc5s8N'!s8N*!rr<'!rrE*!!!*'!rW)uum/R.8pAb3Br;ZoJ
4978 !7UoIs3p`C!7UfF!7UoI$I\tTdf@hsdf@hsrmQDuJH16$JcPaLJcC<$JcC<$Q2^lAs7Y.LRK34b
4979 <Ib~>
4980 s*"YIs8N'!s8W&us8W&us8W*!s8Nc5s8N'!s8N*!rr<'!rrE*!!!*'!rW)uum/R.8pAb3Br;ZoJ
4981 !7UoIs3p`C!7UfF!7UoI$I\tTdf@hsdf@hsrmQDuJH16$JcPgps&FXMJcC<$JcD#8!J:@FeHD!7
4982 qGgOG~>
4983 s!S*Ps8N'!s8N)rs8N)ts8N*!s8N*!s8N)ss8N)ts8N)rs5O+Xe,B@HdfBHtp](<Cq>gNDrVurI
4984 rW!#K!7QK!JH16$JH5ZLs![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4985 s&B:(s8N'!s8N)rs8N)ts8N*!s8N*!s8N)ss8N)ts8N)rs5O+Xe,B@HdfBHtp](<Cq>gNDrVurI
4986 rW!#K!7QK!JH16$JH5ZLrDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
4987 s*"\Js8N'!s8N)rs8N)ts8N*!s8N*!s8N)ss8N)ts8N)rs5O+Xe,B@HdfBHtp](<Cq>gNDrVurI
4988 rW!#K!7QK!JH16$JH5ZLs*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4989 s!W^(!7QK!JH16$JH5ZLs![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
4990 s&FmU!7QK!JH16$JH5ZLrDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
4991 s*';"!7QK!JH16$JH5ZLs*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
4992 s!W^(!7QK!JH16$JH5ZLs![nI_#OE7S,`Kgg&M'Po`+pkq>^HpaT)8?mf3:err;uuq>^HpSH&Th
4993 f)GmNKdI!(lMpkaP5bQAs7Y4NScJXf<Ib~>
4994 s&FmU!7QK!JH16$JH5ZLrDgZ5s+m0ErrCaPrrD]krrDlprrC.?rrDKerrE&urrDlprrAShrrCXM
4995 "SldO!s%WdrrA5^!K$jMg'!iEqc-XH~>
4996 s*';"!7QK!JH16$JH5ZLs*+KC_#OE7S,`Kgg&M'Po`+pkq>^HpaT)8?mf3:err;uuq>^HpSH&Th
4997 f)Gm5<"o?5lMpkaP5bQ7s7XtGOT>5X<Ib~>
4998 s!WEuJH16$JH1B(s![nId/WtCp](6n\,ZI.r;Zcsmf3:eo`+pkkl:Y_o`+pkq>^HpkPkSR$i9o'
4999 !:Bgd!:Kme!<3#u!;ZZp!71]F!7:cG!7q/PUB"Tml2Ub`s8N;\FXm\&/qoep!K@'Pg]X2Kqc-XH~>
5000 s&FUMJH16$JH1B(rDh5EqhY"Hs+n/arrDusrrDKerrD]krrD9_rrD]krrDlprrD6^!T=jks8N)d
5001 s8N)es8N)us8N)ps8N)Fs8N)Gs8N)MrrYmoT_dpQrrE*!#013r!t@>aS,WMGs7Y.LRK34b<Ib~>
5002 s*'"oJH16$JH1B(s*+KCd/WtCp](6n\,ZI.r;Zcsmf3:eo`+pkkl:Y_o`+pkq>^HpkPkRA?2FU$
5003 !:Bgd!:Kme!<3#u!;ZZp!71]F!7:cG!7q/P*WX.Xl2Ub`s8N;-;AK?K9"pep!J:@FeHD!7qGgOG~>
5004 s!WEuJH16$JH1B(s![nId/X+GoDegj\,ZI.r;Zcsmf3:eo`+pkkl:Y_o`+pkh>[Mh2u<RS!:Bgd
5005 !9sO`!;ZZp!71]F!7:cG!7q/O*<>Ngrs'd0g&'uX!'HeO!K@'Pg]X2Kqc-XH~>
5006 s&FUMJH16$JH1B(rDh5Es+p:Hs+n/arrDusrrDKerrD]krrD9_rrD]krrCmT!F1Z]s8N)ds8N)`
5007 s8N)ps8N)Fs8N)Gs8N)MrrNE*qrIb^4JLs9gJ.`mSGrVHs7Y.LRK34b<Ib~>
5008 s*'"oJH16$JH1B(s*+KCd/X+GoDegj\,ZI.r;Zcsmf3:eo`+pkkl:Y_o`+pkh>[L%e,'+E!:Bgd
5009 !9sO`!;ZZp!71]F!7:cG!7q/O"9AG^rs)N0meb-L!5G'(!J:@FeHD!7qGgOG~>
5010 s![UAs8Vfns8VHdrr7NLnc/[=JH16$JH3Ugs![nId/X+GoDegj\,ZI.r;Zcsmf3:eo`+pkkl:Y_
5011 o`+pkh>[L-^A@m0!:Bgd!9sO`!;ZZp!71]F!7:cG!7q2M!8d_WqZ$bhrrJ)Yp=oeB!;fbrJ,~>
5012 s&Jdns8Vfns8VHdrr;Qis8RZN!7QK!JH16$_uTa9d/X-%oDeiH\,ZI.r;Zcsmf3:eo`+pkkl:Y_
5013 o`+pkhZ!ZU%.O,nrrDHdrrD<`rrDlprrCCFrrCFGrrCXMrrCpU!qcO!SGrVHs7Y.LRK34b<Ib~>
5014 s*+2;s8Vfns8VHdrr7NLnc/[=JH16$JH3Ugs*+KCd/X+GoDegj\,ZI.r;Zcsmf3:eo`+pkkl:Y_
5015 o`+pkhZ!ZO#Pe/qrrDHdrrD<`rrDlprrCCFrrCFGrrCXMrrCpU!n@8lSGrVAs7XtGOT>5X<Ib~>
5016 s![UAs8Vfns8VEcs8U^O!7TX%!7Sjd!7UN>!7QK!JH16$dfBCrs&IGGrrDZjrr<6$HkH`[o`"jp
5017 p3._c&kpIIs8N)ts8N)us8N'+p.GMfqgp4##rIt-s8N)ss8N)ts8N'%q-OCEM#RDYfes!bbl@bC
5018 rs84P(]t^kq#CBk!<<''r/EB:$pV;urs%.7"Y@mu!<3!&r/EB:$pV<%s8N'%q-OCEM#RGS!<3!&
5019 o8"4c)eo*Hs8N'&rHo4a:%\Da!UL?ns8)frrs&1@,6ecSb5));!!N+)#T/Bss8N)ts8N)us8N)u
5020 s8N)urs%.7"Y@mu!;ZX!o8"4c)eo*Cs8N',[email protected](CF(9rr39%NA(YI5IpgoqZ-Zr#4mWf
5021 !uktLq#C?o"SlC1(l81k#4mWf!uktLrr3i.E?56(L]@AS!<<)e)$Hf9s7;$`!uktLrr32Q2$GPV
5022 !!*#u#5jH7#n0&/qZ$Em#QOLA,6ecSb5VG@!!;je"8`&t!;c]sqZ$hjrrJ)Yp=oeB!;fbrJ,~>
5023 s&Jdns8Vfns8VEcs8VZjs8W*!s8VEc!7TX%!7Sjd!7UN>!7QK!JH16$dfB>Hd/X-%oDeiH"oPZb
5024 O1G8hrs&/'PDPL1pAY*lM#IARM#RGSL^NdHM#[@_QALX"gZ&85!;uls!<)rt!!MgY"=:5Mrs#VO
5025 "@DVY!<3!([email protected]%l3ss8)frrs&4?,6e`Vh>.'TXs=-:nGiRgrs&4?,6e`Vh>[HS!!MgY"=:5M
5026 s8N)urs%Y!%L"/2rr2rt!!W1&#nLbKrVloI+o;69!<<''l!>2/(glV)s8N'%nNm@)Y5\J$!<)rt
5027 !<3#u!<3#u!<3!&Xs=-:nGiRbrs%Y!%L"/2rqZTo!"8U/%iC*%oiVh;E;ok:#krHd"qa\fs8Vrr
5028 s8N;dB+>(kKDtZGrr<2l63JU;rr32cB+>(kKDtlM)!+p8">-MNrr<'!s3h/Yf)Pd5B+>(kKDtlM
5029 #,iaL6Lk*Vrr32sFX%)&:u2!JqZ$m$l!>2/(glV.s8N'#kV3,7s8N)qrrVlo$_74tM?!;'"I]>f
5030 <E4P~>
5031 s*+2;s8Vfns8VEcs8U^O!7TX%!7Sjd!7UN>!7QK!JH16$dfBDls&IGGrrDZjrr<5b63S6drr2p%
5032 a@m3N,^B(_s8N)ts8N)us8N'+],h"QgJemh'NNT@s8N)ss8N)ts8N'%bU`rWg&D!UL_pG+q#CEo
5033 rrpqH#RE2[rr;iqs8N;\>o<b_BCblu#)F*&@/0d&rr32[>o<b_BCc'%rr<2G/-\&drr;uurr3/P
5034 9F(nZUAb,l!!VLO"W<=!rVln;HM[[=!<<''a@m3N,^B(Zs8N'%bU`rWg&D$O!<)rt!<3#u!<3#u
5035 !<3!&L_pG+q#CEjrrpqH#RE2[q#C?o$Kjha+gD!u5RAEqrVm/\>o<b_BCc*&qZ-Zr"k?9P#Vr.K
5036 s8N'%bU`rWg&D!TeP$5S18=aI(W8fQ#=$E3rr<'!s.BH=n,NF<9F(nZUAb)rJeeZ#q#CEors%@d
5037 )$Cgio(rC`!!iPF9G.OTGk_4;rr<,4*Wc-;rrDoq!n[K*SGrVAs7XtGOT>5X<Ib~>
5038 s![15s8VEcs8UaPrR9O%!7Sjd!7UN>!7QK!JH16$dfBCrs&IGGrr<-?"!WZts8N'5Qb3'O!'(#Y
5039 pau`Epspku_uK`:!<)rt!<3#u!"+8"ir=Q0=6KM7EoR-!!;uls!<)rt!#UR;nPoUQs6g4&c1,EH
5040 !<<)o(9.-!MZ>U5s8N)trs8Km"Hi?>8-H<ss!mIC%F+EU!!*'!qa^jPo]JaJ[/^.+!/\tj<<89_
5041 rr<'!s7dA/q=':B2#dOT!!S_$q2554rVlo!7JZu`!<)p'pau`Epspku_tsE5!""M,nPoUQs8N'!
5042 rVultrr;uurr;uus8N>m#S#&KB)hr.rs/<7WVQ%A!&XNOrr<t)\,)9gAn\[MP5mlJs8,=iOn@g-
5043 "LS4/!!)ut#P](6q=':B2#.+N!'c=bnPoUQs7dA/q=':B2#mUN.Kl%.l@K!8!!*&j.0QIHs7dA/
5044 q=':B2#mUC"qT)OD?'\:s8,=iOn@g-"LS%*rrE&u&,7a\UA3:g#/gK@!!%Pmiqi]T!;lcul[]+Y
5045 SGrVKs7Y4NScJXf<Ib~>
5046 s&J@bs8VEcs8V]ks8W&us8VHdrR9O%!7Sjd!7UN>!7QK!JH16$dfB>Hd/X-%"-AD3g%YOHL_R2]
5047 qQ>Xms8VkTNT0orNK<l7s+lL0s8RoSs8Rl^WUf'KTSUbcr8t3Bs8N)ss8N)ts8N'9:ZURY!n[J(
5048 ![$La9`P1ns6qGVr8qDfFoMF@!<)p'p)OCCq:->gkkkB0f)d&Tj@oUSs8Vd5#I4*T)$oI+rr<$p
5049 jQ%BafDkjN!<<)g.)u2I@/tHLs8N'&?.JRE!.k+K!C`p^s8N)trs8''$c2_U$4cS%s8N'*:ZURY
5050 !n[JP!!)utrrE&urrE&urrE*!#M0#!jQ'#8!;c^#n0l<Sk$\74q>^Hp)HtS_=TGuode6fDNW9%P
5051 *=&kFeJSYVs8N'!rVm,l.)u2I@/tHFs8N'`:ZURY!n[JA.)u2I@/tHMs6^:%[.rEas8N'!s5F@k
5052 eGoR<.)u2I@/tHMs3^rmk2oVC!<<)m*=&kFeJSYVqZ$Qqrr3Mt%L^,M^^:S@s8N'!7cV;\s8N)r
5053 rr_1["K.di!K$jMg'!iEqc-XH~>
5054 s**c/s8VEcs8UaPrR9O%!7Sjd!7UN>!7QK!JH16$dfBDls&IGGrr<-/#sm)8s8N'5@cuqt!7(WE
5055 _?MOBpRh[Cq#C?o!<)rt!<3#u!"*<,IfC,_YP.Y!1?/?6!;uls!<)rt!#TJ@bmasIs,mC`n]cji
5056 !<<)57b[dl/HE`gs8N)trs79d*m4Ak$R#0?s!j04<q4Fj!!*'!faJqEqmm.XpAb-m!,D&K%1)G&
5057 rr<'!s1UtVr7<M#`;]f:!!QipkTBlNrVlm=h"h!M!<)p'_?MOBpRh[Cq"k$j!"!E1bmasIs8N'!
5058 rVultrr;uurr;uus8N=e!ESa8L]@GOrs-8-gAKPS!6"^5rr<sCjm42lgem2",663ms4If%b58aX
5059 +SPj8!!)ut#JN[]r7<M#`;'B4!'b5gbmasIs1UtVr7<M#`;fkO"sV7fb;oV&!!*&*"X<C7s1UtV
5060 r7<M#`;fjp!F#'@MZ<bWs4If%b58aX+SP[3rrE&u&&JN$fCtpA0DPSI!!$U"Ies*E!;uj"rQlf"
5061 gRS9EK)bPp"H`]\<E4P~>
5062 s!S$Ns8N*!s8E#ts8;rrs8N)ss8E#ss8E#ss8;rts4RGSdf@kj!<(CG!<(CH!!1OKrmUiHrR:cH
5063 rR:H?rR:`GrR:cH!Rh&Je,B@Ge,B@Ge,KCKdfBBrrW)oGrr<)K!<1IH!<(CH!<(C@!!1OKrmUlI
5064 !Rh&Je,B@HdfBHtJH16$JH59As![nId/O;/a8==C!I4D>rr<C?s8V`l$NL..!)`aq#2T>&s8N'!
5065 rVultrr;uu!,;H4!XSk+hZ*TUr;ZcsrVult%Vu+El2VV"QN1h$s60L`qYpWq!!`H&rrE#t!k\M%
5066 rr3&c!#th8%$ps0s8V<`!<<)3!(Hne&F0<8s8N'!C]FG"!#GV7!!)lq!rW*'rr;uu"_n#:o`,?u
5067 rrW-;f(o@G!<)p!XT25trrV$W+Su-<!"!H@s69S"s8N'!rVultrr;uurr;uus8N=j!,MW7kl:_V
5068 rrW-!#5S<!!"`cBs7QErB)ho)!"/c+]DtD"rs%ch)uop<!;QQqr;[&ss8N'&C]FG"!#GJ3#Q4W,
5069 s8T)!:](1l!!E!V"JY_l&cD\6s8S;`Du]k'!!*'!]DtD"rrVKd)uBU7!<3!"XT25trs.B\+TMHA
5070 !,;6.rrE#trVus)OIQ7NN;rV,"J,Vj<E4P~>
5071 s&B4&s8N*!s8E#ts8;rrs8N)ss8E#ss8E#ss8;rts7?<ks8N)ss8N*!rr`?%rr<&ss8E!"df@kj
5072 !<(CG!<(CH!!1OKrmUiHrR:cHrR:H?rR:`GrR:cH!Rh&Je,B@Ge,B@Ge,KCKdfBBrrW)oGrr<)K
5073 !<1IH!<(CH!<(C@!!1OKrmUlI!Rh&Je,B@HdfBHtJH16$JH59ArDh5E#.*^qiK&fSq#CAM$KhBg
5074 on\b1s/Ut0rr32ULogXVLku$0s+p[Ss+g[<rr3%VM!*XprrDusrrE#trr<PSs8U=D1B0*0cN!pf
5075 !!)lq!r2g*rr;uurVlq/!2'8j!mgp4qu7'[!7(WEb5_PBs'l&$rr3PV!'pSa!!(=Es31O!s8N'!
5076 qYpWm!"Jr-rr<5Es8V<`'`S+6q?cijs8N)trrPjoYl=Y(XT2,ms8N'*cN!ph!&FTS!!)utrrE&u
5077 rrE&urrE*!#;Q;)s8U7B!;6?nq#Cm"s8N'1`rH))!"6gHs69S"s8QR/TDnipci??2rr<&orrVur%
5078 J]u'!!U[Js31O!qu6os!"Ju.8-#^fs8N'$m1K]Rq>V'&!"Ju.0*'E"s3L`Gs8QR/TDnilci??-s
5079 8N)urrPjoYl=Y-XT2,rrr<&Cq#C?orVuis!>E/9rrIuVp=]Y<!;fbrJ,~>
5080 s*"VHs8N*!s8E#ts8;rrs8N)ss8E#ss8E#ss8;rts4RGSdf@kj!<(CG!<(CH!!1OKrmUiHrR:cH
5081 rR:H?rR:`GrR:cH!Rh&Je,B@Ge,B@Ge,KCKdfBBrrW)oGrr<)K!<1IH!<(CH!<(C@!!1OKrmUlI
5082 !Rh&Je,B@HdfBHtJH16$JH59As*+KCd/O;ukk:bV"6TCYrr<Djs8Sho;ZHb=!9!kV##>6%s8N'!
5083 rVultrr;uu!:'R`!W`;^hZ*TUr;ZcsrVult%dO)oCB0b%('*Y"s(MH5qYpWX!&jiVrrE#t![e!$
5084 rr3%@!2BAj$l/j.s8Qd5!<<'H!87AO&9@iGs8N'!lMpm"!1<fd!!)lq!os>>rr;uu"mQ'eUB"3k
5085 rrVHpqt^9l!<)p!*rt6urrPsrY581u!"%rjs(_V%s8N'!rVultrr;uurr;uus8N<>!:'UaB`J/+
5086 rrV6]2YmCQ!"eAos/>u2kl:[]!*]F&-NMj!rs!NEUAt5n!;QQqj8_+5s8N'&lMpm"!1<Z`#NPkC
5087 s8O,?hY[?Q!!C.F+R](*&``pMs8Nf6m/R*'!!*'!-NMj!rrR6AUAFoi!<3!"*rt6urs)="Y5eM%
5088 !:'@ZrrE#trVusLjdZ8NK)bPp"H`]\<E4P~>
5089 s!RjIqu?Wqs8W&us8W*!s8N9's8N'!s8Vuss8N9's8N'!s8W&us8UaPrmUWB!7UlH!n..ur;ZrK
5090 !!(LI!!:ULe,97Kdf9Bso`,!@r;ZoJ!7UlH"4I5Me,B=Kdf@kq!!:ULe,97Kdf@kGrW!#K!7UlH
5091 "4I8!e,B=Kdf@kq!!C[M!7UT@s3prI"4I8!e,B=Kdf@kr!!(K!!.b-$!:g-i.0!;krrVEb%f$)(
5092 !".T_s8E!"s8OnUd/O%Lq>^a"rr<&ts8N)us8N'!fDbdRC]FJjP25*srrDusrrE#trr<P`s8Vrr
5093 "ofqMg].<N!!*#u!i7pfrVup!rr;uurVlp`!5AI4!rW*&qu7'P!8IPRqZ$Wrs$$Ltrr3Q.!!WE&
5094 !!(dRs8)d"s8N'!rr3%r3Y),h!!3*!rr<5Zs8W&u!ri3#jV@RjrrE#t!]0o(rr3&r!!`<"rr<A[
5095 s8Vrr"onT&!<)rt!<3#u!<3#u!<<'(-NMp$s8)crq>UMm3Y),h!!2oqrr<Ves8W&u!8dbUrW!$"
5096 s$$Ltrr33$!!WE&!!)rs!i7pfrW!!#s8W#trr;uu$JYU\qZ$g"s.qadrW!*&s8O\Odej(E!!5aq
5097 T`"fkV)f+c!"T,1s!@a$s8Vus!<<'`!5AI4!rW*&qZ$Qqrr3$V!7:`F#PnE)s8N'!fD,CG!;lcu
5098 i*$2-SGrVKs7Y4NScJXf<Ib~>
5099 s&B%!qu?Wqs8W&us8W*!s8N9's8N'!s8Vuss8N9's8N'!s8W&us8V`ls8W#ts8W#tqu6j#s8N'!
5100 s8W&urmUWB!7UlH!n..ur;ZrK!!(LI!!:ULe,97Kdf9Bso`,!@r;ZoJ!7UlH"4I5Me,B=Kdf@kq
5101 !!:ULe,97Kdf@kGrW!#K!7UlH"4I8!e,B=Kdf@kq!!C[M!7UT@s3prI"4I8!e,B=Kdf@kr!!(K!
5102 !.b-$!:g-g<QtIEjbT5ts8Rl^qu?]qLl)03NemQ2rs&=UNrT-8M#IARM#RGSL]I>OrrngHLo\u!
5103 iW&oXr;ZcsrVult'_hY-p&GI"$39i#s7QEms8W%R/IDCV!!3*!rrE#t!Y5;#rr3&r!"8]($jm"/
5104 s8Vcm!<<'0!:^!f(A\"=s8N'!p](9e!"/c+!!*'!rJ3$3rVup!rr;uu"o&&squ?iurrKngq#C?o
5105 rVlp.!;-9j!qZI%qZ$Qq$2=K"p&GI"rr<&ts8N)us8N)us8N*!rs&l2p](9e!!)lq"9"$-$2so)
5106 !Vucq!"eo)s82isp](9k!!N?%%fl+urs&<"$ig5,!<)p"rJ3$3rW!!#s8W#trr;uu$MXT#p&GI"
5107 rJ3$3rW!*&s8NH,o_\[g!!4,GdJa(IrJ3$3rW!H0s8NB*p](9f!!*'!%fl+urrW#s$i9o'!<3!"%
5108 06&"rs//r%KHG.!;?3frrDus"T?^u"1+Nt!K$jMg'!iEqc-XH~>
5109 s*"GCqu?Wqs8W&us8W*!s8N9's8N'!s8Vuss8N9's8N'!s8W&us8UaPrmUWB!7UlH!n..ur;ZrK
5110 !!(LI!!:ULe,97Kdf9Bso`,!@r;ZoJ!7UlH"4I5Me,B=Kdf@kq!!:ULe,97Kdf@kGrW!#K!7UlH
5111 "4I8!e,B=Kdf@kq!!C[M!7UT@s3prI"4I8!e,B=Kdf@kr!!(K!!.b-$!:g-iGQ1[errR*=F85e8
5112 !"/Z(s7--us8N9'qYpL!cN#g%rr<&ts8N)us8N'!qu6U!&-)`AXngrUrrDusrrE#trr<c1s8UdQ
5113 ./sGNqu?]M!!*'!pM_>]rVup#rr;uurVlp(!;QQn!pK\8qu7'.!;lfrg&M-Qrs&Q!rr3bu!%\*L
5114 !!)ors4RH$s8N'!s8Vh4,6n,I!!E6#rr<6#s8VWi%0$8->*A[\rrE#t!X8Z$rr3&G!&XQPrr<B&
5115 s8UdQ.0';I!<)rt!<3#u!<3#u!<<'("T\H"s4RGQqYpZlE$GSd!!!,ss8N'1r;Zff!!)rss7-.$
5116 s8N<(q#:9tkl<76rr<&trr`"7,6n,I!X&K&r;cisrr<E's8UdQ.0'$\,6n,I"U"f)"p"Mss8N'#
5117 $m+g7rr`"7,6n,I%g2k3"T\K#s4[MRs8N<(q#:9pkl<71s8N)urrNB)qYpL"cN#g%rr<&rq#C?o
5118 r;Qor]+PP3SGrVAs7XtGOT>5X<Ib~>
5119 s!RjIqu?Wqs8W&us8Vuss8W*!s8W*!r;Q`squ?Wqs8U^O!n..up]1?Cr;ZiHq>^NEqu?`Gr;ZrK
5120 !!(L?!<:OH!!(LE!!(LG!;k4F!;k4G!7UlH"Od>Ne'n6q!7UlH!n..ur;ZrK!!(L@!!(LH!!:UL
5121 e,97Jdf@kr!!(K!!.b-$!:g-i.0!;krrW-!!r2fq!<)rt!<<'##lsf"rriB(s8N'!rVultrr;uu
5122 !;lcq#5NNd!!!+Jir9&_!;l`p!<<0!s8N'!qYpKu!!3*&!;c]prrE*!#IXUcfDPXK!<3#u!<)p'
5123 #lk&0!W`9$!W2lu"9A;ts8N*!rs]87!s8T*!!!'"rr<&qrr3K/!WW0"!<<)-!&)t%rr<&us8N)t
5124 s8N)urrJBdq#C?orVlp*!;ZTn!<<2ts8N'!qYpKu!!3-"!!)utrrE&urrE&urrE*!!X&N"rr;uu
5125 qYpf/!&)t%rr<&ps8N)ts8N)ts8N*!rsT26!s8T*!!!'"rr<&trs?+60A$.%!!*'!r;cisrr<&q
5126 rr3K/!WTS.0A$.%!!*'!"T\Jts8N'#'`s9krsZ=90A$.%!!*'!"9A>us8N*!rs/o2!s8T*!!!&r
5127 s8N)urrNK,q>L<t!!<3#!!)oks8N)qrrVin#b:nqN;rV,"J,Vj<E4P~>
5128 s&B%!qu?Wqs8W&us8Vuss8W*!s8W*!r;Q`squ?Wqs8Vcms8Vuss8W#tqu6j#s8N'!s8W#t!n..u
5129 p]1?Cr;ZiHq>^NEqu?`Gr;ZrK!!(L?!<:OH!!(LE!!(LG!;k4F!;k4G!7UlH"Od>Ne'n6q!7UlH
5130 !n..ur;ZrK!!(L@!!(LH!!:ULe,97Jdf@kr!!(K!!.b-$!:g-g<QtIErJ6@+s8RoRs8RoTrrIt4
5131 r;QqVM?!U3M#IARM#RGSM#I>XppH3>Ll:!HrrN3$rr2p!rVuuts8N'9rr<#t!!3*#!<3#urVuru
5132 s(27EjSo,Y!<3#u!<)p'!WW<)!W`9$!W2mH!<E-!s8Duus8N-#!s8T*!!!'"rr<&us8W&u!WW0"
5133 !<<(2!,1HmrVurts8N)ts8N)urrFmgq#C?orVlp$!<2ut!r`0%qZ$Qq$3'u)rW!!!rr<&ts8N)u
5134 s8N)us8N*!rs&Q)rr<#t!!)lq#A*sLjSo,Y!;ZZp!<)rt!<)rt!<<'-!WW<)!W`9$!WW0"!<)p(
5135 AcQN*rr)lts8W#trr;uu')qq2rW!!!AcQN*rr)lts8N*"qZ$Qq!X/_>rVmjL!,1HmrVururrE-!
5136 s8W&u!<<'#!!<<)!<<*#qZ$Qqrr3$%!<2ut#Q=]*s8N'!rqQNn!;c]skl;?drrIuVp=]Y<!;fbr
5137 J,~>
5138 s*"GCqu?Wqs8W&us8Vuss8W*!s8W*!r;Q`squ?Wqs8U^O!n..up]1?Cr;ZiHq>^NEqu?`Gr;ZrK
5139 !!(L?!<:OH!!(LE!!(LG!;k4F!;k4G!7UlH"Od>Ne'n6q!7UlH!n..ur;ZrK!!(L@!!(LH!!:UL
5140 e,97Jdf@kr!!(K!!.b-$!:g-iGQ1[errVKd&GZ;*!<)rt!<<'"!<E)u#5A0*s8N'!rr3'!!!*#u
5141 rrE#t#1$!L!!!hnir9#[!<)p!qZ$cts8N)urrr6!"oeT'rr3E'!!*'!/-(k#s7lWprr;uurVm-(
5142 !!<<)!<<*%qu6Zt!<3!1q>^NqrrE*%!s/K'!!E9$!!*#u&GcA1s8N'!s8OVMP3r;F!!*#urrE#t
5143 rrE&u!>X\js8N)trrE-#rVlro!"/T&rrE&u#5S<'s8N'!rr3'!!!*#urrE&urrE*!!<E3"rrW#s
5144 !;c^#/-(k#s7lWpq>^HprVultrVults8NK.!!<<)!<<*%s8N'!rVm0T!0ZaLq#CEps8;rss8N)u
5145 rt"r+"og+RP3r;F!!*'!!<Durrr<*&&ENfi$S2:@mJlt^!<<'"!<3!-q>^NqrrE*%!s/K'!!E)t
5146 rrE&u!<E3!rs&5u$NL,+!;HNn!;c]sVZ98XrrI`Op=0;.!;]\qJ,~>
5147 s!S'Os8N'!s8W&us8W&us8Vuss8W*!s8NB*s8N'!s8N*!s7u`qs4RJOe+E_@e,KCJe+s%Ee,01G
5148 e,97Kdf9Bsnc8^=rr<&Jq>^NEqu?`GqZ$WFqZ$WFr;ZiHr;clHrr<&Jr;ZoJ!7UlH"4I5Me+E_@
5149 e,B=Kdf@kq!!:UL!<1Gu!.b-$!:^'h.0!;krrW-!"8Mor!<)rt!<<'#1B>f$rs\`(#64]2!:p0i
5150 qu?`rs8N)qrr_//!!_H_!\+3&rr3&s!!W?$rr<njs8Vrr"ofqMg].<N!!*'!+TU9ss7lWprr;uu
5151 rVlpS!7^]A$mu&0s8Vrr!<<'S!7^iErr<_es8Vrr"onT&!<<'B!8IPRq#CEos8N)ts8N*!rrW'-
5152 kkP2X!<)p!1B>f$rrW#s#5\B"!"[ias8)d"s8NH,o)Jaf!!*#urrE&urrE*!#:BN+s8Vrr!;c^#
5153 +TU9ss7lWpq>^HprVultrVults8N-U!7^iErrE#t#9a*%s8Vlp!;QTo!#+,es8)d"ruhBss8Vlp
5154 !<<'P!7LcErr</`'EX0krtZaXg].<L!!*'!,lld$s82iss8OhSeF`e@!<3!"1B>f$rs&<"#64]'
5155 !;HNn!;ZWq!!/Vi!K@'Pg]X2Kqc-XH~>
5156 s&B7's8N'!s8W&us8W&us8Vuss8W*!s8NB*s8N'!s8N*!s7u`qs7QHms82lss8;rts8N*!rs/W)
5157 rr<'!rr<&te+E_@e,KCJe+s%Ee,01Ge,97Kdf9Bsnc8^=rr<&Jq>^NEqu?`GqZ$WFqZ$WFr;ZiH
5158 r;clHrr<&Jr;ZoJ!7UlH"4I5Me+E_@e,B=Kdf@kq!!:UL!<1Gu!.b-$!:^'f<QtIErJ6@+s8RoR
5159 s8RoTrrS4:qYpL'qM:13s+uR2s8VtPM#RGSM#.,Rl*Z>-ir9&e!;?El!qlU%rVult)#+(1pAbR#
5160 $39i#s7QEms8N?)p](9a!!*#urrE#t!Xo)%p&>F-!;HNnp&G*mrsSo#q>^Hp'DMP,pAbR#rr<'!
5161 rs/W!s8VWi!<3#u!<)rt!<<'#p'CNis8N)trrNW0o`"jloDf?ss8N'0p](9f!"/c+!s&9!s7ZKn
5162 rr;uurr;uus8N<2!;HNnp&G*hrs&f0p](9a!!)iprrE#trrE#trrE*!!Xo)%q>^HprVm*.!;HNn
5163 nc/[bs8N'4p](9f!"/`3!;HNnnc/[irsSo"qu?Zr"2P-D]`.pH#QXW!s7--is8NB*p](9f!!*'!
5164 $iotms8N)urrNW0o`"jpoDf@#rr<&ns8N)qrrW0"!hB8kM?!;'"I]>f<E4P~>
5165 s*"YIs8N'!s8W&us8W&us8Vuss8W*!s8NB*s8N'!s8N*!s7u`qs4RJOe+E_@e,KCJe+s%Ee,01G
5166 e,97Kdf9Bsnc8^=rr<&Jq>^NEqu?`GqZ$WFqZ$WFr;ZiHr;clHrr<&Jr;ZoJ!7UlH"4I5Me+E_@
5167 e,B=Kdf@kq!!:UL!<1Gu!.b-$!:^'hGQ1[errVHc'DVV-!<)rt!<<'#"p"N!rs[6S2#mRW!<3#u
5168 h>dQTs8N)rrri>91]TDmrrN?(qu6Tsf)R?"s8N'9qu?]N!%7dM!;lfrg&M-Qrr`?"s8U(=!<3#u
5169 !<)p!"p"PnrsT&2qu?]M!!*'!"p"Prs8N'4qu?]N!%7gH!!*'!"9AB"s2G$=rr;uurVults8N/P
5170 )#a70rrE#t!X8Z$rr3&H!&XQPrr<T,s8UgR-ia2J!<3#uh>dQTs8N)us8N*!rs&]-qu?]M!!)lq
5171 #6Y&)s8U(=!;ZZp!<)rt!<)rt!<<'#"p"Prs8N)trs&Z,r;Zf:!!)forr<`0s8UgR-iX;Lr;Zf:
5172 !!*'!"p"Mss8N'$NWTjRrr3`:!;uls`W-#=rriE#s8UjS!<<''!;lEgrrE&u!X8Z$rr32L!&X`U
5173 !!)cnrrDoq!r)a$SGrVAs7XtGOT>5X<Ib~>
5174 s!S'Os8N'!s8W&us8W&us8W*!s8Nc5s8N'!s8N*!rr<'!rrE*!!!*'!rW)uufDkp#pAb3Br;ZoJ
5175 !7UlH"4I5Me,01Ge,97Kdf9BsrVurIq#CEDr;ZoJ!7UlH"4I5Me,01Ge,97Jdf@kq!!:ULe,97J
5176 df@kq!!:ULe,97Jdf@kq!!C[M!7UoI!7UlH!7UoI!Rh&Je,KCJe,97Jdf@jJ!.b-$!:Bje.0!;k
5177 rrV9^');M,!<)rt!<<'#X8l,srs[cb+92@=!2]_qkPtV^s8N)prr`6#!WM-Z!h97+rr3&b!#Y\7
5178 rr<mPs8VBb(&sR"D#aP#!!*'!&HLnls4mYTrr3$+!;HKm!k85!p&>Gd!,V]8l2Uhas0r%tq>^Hp
5179 '5[^KlMq\"rr<'!rt,7ls8UmT!<3#u!<)rt!<<'"h&H+g!XSl$rr3&$!)`aq!oEu"qZ$Qq%rD:G
5180 lMq\"s&&ins8V9_!<3#u!<3#u!<<'(Q2kb$s69RaqYpd4!9F1[h#IHNs8N)ts8N)ts8N*!rrT\1
5181 7JZrb#ls`!rs',9jT#89!!)forr<^Ks8VBb(&njGjT#89!!*'!WrPuns8N'>s5jpqMZ<\g!9F1[
5182 h#IHTs-!G&s8VEc!<<)/!(HP[rrE&u!iuB!rr32[!$D7@!!)cnrrDoq!qQC"SGrVKs7Y4NScJXf
5183 <Ib~>
5184 s&B7's8N'!s8W&us8W&us8W*!s8Nc5s8N'!s8N*!rr<'!rrE*!!!*'!rW)uupAk6nqZ-Zr$3:,+
5185 !<<'!!<<'!r;ZZp!7UZB!7UlH!n..ur;ZrK!!(LG!!(LH!!C[M!7UoI!7U`D!7UlH!n..ur;ZrK
5186 !!(LG!!(LH!!:ULe,97Jdf@kq!!:ULe,97Jdf@kq!!:ULe,97Kdf9BsrVurIr;ZiHrVuuJ!<1II
5187 !!(LH!!:ULdt%LM!.b.<!<#pArrV/8S,!$`M#IARM#[JVX,,L/rs[V;X8i3^M"UfJjbS`ls8RoN
5188 rrW.TM;nO:2uq8'rrUIG3;rmW!#X&^s3:U!s"ON"s8U=D!<<'%!;ZZpVuQhsrrN9&rVlfu>l^8b
5189 rsUU^ci=$i!!*'!>l^8fs8N'4ci=$j!&=NR!!*'!"9A8ts/5ntrr;uurVults8N,!621B\!s&<!
5190 rrPgnYl=Y(YQ.Ans8N'0ci=$j!&=NR'EIFus2P*>rr;uurr;uus8N<Y!71]Fbl@b?rs&Z,q>^Jn
5191 !!)iprrE#trrE#trrE*!!aPenq>UKu!<)os#6Y&&s8T"t!;QTo!#*]Ys3:U!rr`>ts8T"t!<<'j
5192 !3H(trr=)>^]akRs8N3%q>^Jn!!*'!0*'K$s3UfHs8Q@)R.UFY!<3!"9)u3qrs#\-9`P+m!;HNn
5193 !;c]sirBmcrrIuVp=]Y<!;fbrJ,~>
5194 s*"YIs8N'!s8W&us8W&us8W*!s8Nc5s8N'!s8N*!rr<'!rrE*!!!*'!rW)uufDkp#pAb3Br;ZoJ
5195 !7UlH"4I5Me,01Ge,97Kdf9BsrVurIq#CEDr;ZoJ!7UlH"4I5Me,01Ge,97Jdf@kq!!:ULe,97J
5196 df@kq!!:ULe,97Jdf@kq!!C[M!7UoI!7UlH!7UoI!Rh&Je,KCJe,97Jdf@jJ!.b-$!:BjeGQ1[e
5197 rrQd4KD>KH!<)rt!<<'#*rt6ursVa)XoJD.!;6BlB)hr2s8N)prrVQf#3,Xa(]`k#rrQs9SGiKf
5198 !#Y&%s(h\%rtPP"s8Qg6!<<'#!<)rt8cSkjrrE-#rVlpF!7^]A$l&d.s8Qg6!<<'F!7^iErr<_u
5199 s8Qm8QiI'c!<<'#!<)rt8cSkjs8N)ts8N*!rrGWgp\t6p!<)p!*rt6urrQ$tXnr(t!"\Dqs(h\%
5200 s8NE+p&G&)!!*#urrE&urrE*!#8I7)s8Qg6!;c^#!W`3!s%37kq>^HprVultrVults8N-H!7^iE
5201 !<E3!rs&T*rVumi!!)forr<_us8Qm8Qi@*erVumi!!*'!*WY'os8N'>s,@'kjT#5]!<)rt8cSkk
5202 rtGJ"s8R!;!<<'F!7^Z@rrE&u!ZqF#rr31"!3Q;$!!)cnrrDoq!gs$pSGrVAs7XtGOT>5X<Ib~>
5203 s!S*Ps8N'!s8N)rs8N)ts8N*!s8N*!s8N)ss8N)ts8N)rs3:WCe,B@Ge,B=Ie,'.De,9:Ge+Wk@
5204 e,B@Ge,B=Ie,'.De,B@Ge,KCJe,97Jdf9CHe,KCJe,97Jdf9CHe,9:Ge,9:Ge,KCJe,'+Fe,97J
5205 df9CHdt%LM!.b.@!<4JI<RLgO0!+O=`@(hYq#C?orVults8N`,.KuUCf..'@s8U=D+m\;u!!*#u
5206 rrE#t"tQY?r4)eCir9;T'b%\Nj%TWPrVult(l6N/=TOQ_mKX6JnnJ.)s8S8_5P*`"!!*#u%VPis
5207 rVuoq;?C^ir:%=&qu8/6#7f)NC&e86s85arD;5!X]3G=8!!%i$nlZ!Rs8N'!s8S8_5P*`"!!*#u
5208 rrE#trrE*!!IJYWrsi]BLAh/PpaQHBq:@,$_#"*2!"Xn3nlZ!Rs8U=D+m\;u!!*#urrE&urrE*!
5209 #OVg,cgkfN!;c^#P5mi=hF%>Dq>^HprVultrVults8Nr6;?C^ir:%=&s8Qa4LAh/PP5mi=hF%>D
5210 q#C?o5D[YV=TOQ_P5mi=hF%>Ds8VjD"IA`HJcG`M!<<)\&d!sjP5mi=hF%>Ds8VHi&(0uf!!*'!
5211 r)*T5g\gQQ>PeC"!<3!,paQHBq:@,$_#OE7!;HNn!<<'(0XC6Idn9^gSGrVKs7Y4NScJXf<Ib~>
5212 s&B:(s8N'!s8N)rs8N)ts8N*!s8N*!s8N)ss8N)ts8N)rs7lZps7u`ps8N*!s8N*!rrN3#s6Tgb
5213 e,B@Ge,B=Ie,'.De,9:Ge+Wk@e,B@Ge,B=Ie,'.De,B@Ge,KCJe,97Jdf9CHe,KCJe,97Jdf9CH
5214 e,9:Ge,9:Ge,KCJe,'+Fe,97Jdf9CHdt%LM!.b.@!<#pFrs,XbqYSs*Ms^<>s+pXRs+p^T').EG
5215 j8J"tNq`SR`/(Vol`u>&rr<"SrVm)&i;3>rLnNc-#iGk+df%T6"l]F[rr<m4k2mfgec4/$+m.l^
5216 !!*'!490p.a@Q@3rr3$>!5ea8#ko_MNp$B)X$QX_.b+SDk2fA=!<<)n-j5RnrTL:Js8N'!;!-m`
5217 !nI>N!!*'!490p.a@Q@3rr;uurVults8N*DchIG@*!!kTrs8!#$c;eX$OuP#s8N'0;!-m`!nI>N
5218 JH/[Ce6)bOrr;uurr;uus8N>S![6^f:B1Ckrs(XdJGR>Y!!)iprrE#trrE#trrE*!%JM7RNp$B)
5219 X$Qdc*!!kTrs(XdJGR>Y!!)forr>8[k2mfgec.`3JGR>Y!!*'!mL0E0qV>QZrr<'!s1SX>]`1(o
5220 JGR>Y!!*'!dK1`Xk>_K^s8VgA"HM[Dkc7#Gs8N)urs\9'$c;eX$OuP(rr<&ns8N*!rs)H?pA2WK
5221 !kY!&!K$jMg'!iEqc-XH~>
5222 s*"\Js8N'!s8N)rs8N)ts8N*!s8N*!s8N)ss8N)ts8N)rs3:WCe,B@Ge,B=Ie,'.De,9:Ge+Wk@
5223 e,B@Ge,B=Ie,'.De,B@Ge,KCJe,97Jdf9CHe,KCJe,97Jdf9CHe,9:Ge,9:Ge,KCJe,'+Fe,97J
5224 df9CHdt%LM!.b.@!<79C<RLgOC<lYEOTcNhq#C?orVults8N_H"Y87$UBN4Ds8P%YNr-DQ!!*#u
5225 rrE#t#%l*UmpQ3Iir9:\"&7hQ\I95DrVult(i8ch%L;G%NWE;RcA2H#s8Nr:Y55)U!!*#u!Y#.c
5226 rr38Z&.YW-qqd\equ8.+!Eo!=L]@GTs4e.qVssT?QmVk5!!$j+cOL3Js8N'!s8Nr:Y55)U!!*#u
5227 rrE#trrE*!!>+SkrrNW0h>[E[^BH.?q4e*Eq"k$j!"Wo:cOL3Js8P%YNr-DQ!!*#urrE&urrE*!
5228 #EAgfo$3$k!;c^#)$$i9W/L]Vq>^HprVultrVults8NP`&.YW-qqd\es8NN.h>[EZ)$$i9W/L]V
5229 q#C?o5A]o:%L;G%)$$i9W/L]Vs8Te;,L$&/3WK*Z!<<(X!YFGm)$$i9W/L]Vs8RrW?1ZI&!!*'!
5230 g^jsnnGD(0-MmcB!<3!,^BH.?q4e*Eq#C?o!;HNn!<<'(DpnLSWso<pSGrVAs7XtGOT>5X<Ib~>
5231 s!WEuWrN.KrVurIoDem?r;ZiHJH16$JH59As![nIdJjF'A/bR^8%A<nrrE#trrE&u#530_"V=;H
5232 rr36&N>Md^irB)Ys8N)trs%.g*!-dQh;SA<mq3XD%RIH!s8N'%q-+(>L&V)`f/3[]b5_PBs8$OD
5233 #!q,H!<3!.mnsf"!<<)uTg0.j'hkY(rs%(4"=qXq!<3!0rh2Rg!YnD/s8N'!q-+(>L&V,P!<<'(
5234 qJ6`J6/MYBrr;uurVult"98-%p%SIqmnsf"!<<)mFWgo"9#pc-rr<2t>6bptrr36&N>Md^irB)Y
5235 s8N)us8N)urs%(4"=qXq!;c^#qJ6`J6/MYBq>^HprVultrVultrr3f6Tg0.j'hkY-s6ii!!<E/r
5236 C_6k;hZ*ZOs8N'/q-+(>L&_2LC_6k;hZ*ZUrsA=7)?M%;s8N'!rr3Ae&-@acC_6k;hZ*ZUrs$t0
5237 ">%dt!WN*(rh2Rg!YnD/qZ$QqrVm)qFWgo"9#pr2rrDfnrrE*!#2!H+!>%PpS,WMJs7Y4NScJXf
5238 <Ib~>
5239 s&HB*s8RWMqZ$WFrVurIoDem?r;ZiHJH16$JH59ArDh8F#2lVFM3G74p](8LrVunRrr32pZ]^0.
5240 Zh==t#QD8pN3W;:M#RGSM#I>XiNA9!Q+?eNrs$tM'EStGeboII!!MdT"!alGrt)4U"$c8T!<<)k
5241 :^IM4p](<nrsmXE$ipA.s8.X0$j7VX_tsB;X!7^2n,NIfrt,'a1^jL.?GlgC!!)LP"!alGs8N*!
5242 rs/0m#n'o2!!*#urrE#trr<0$n-f3hrsdRD$ipA.s6!W&!u>2,q>^Hp"RnSW,HLhD#Q8?H#Zpg%
5243 !<3#u!<3#u!<3!&X!7^2n,NIbrs/0m#n'o2!!)iprrE#trrE#trrE&u(]0%G$j7VX_uKbg4q%Gl
5244 s7B+o$X*6)!;QTo!"SK^"!alHs7B+o$X*6)!<3!)jAulp0;njM!!*#u$bQTF]_##,$X*6)!<3!&
5245 V]l70n,NOhrs/FX1^jL.?GlX>rrE#t#3T5,!u>2,rr;uup](6ns8N;:;%`mF;9#+*!K$jMg'!iE
5246 qc-XH~>
5247 s*'"oWrN.KrVurIoDem?r;ZiHJH16$JH59As*+KCdJjEG577T<D=I<"rrE#trrE&u#/s1G"X8-`
5248 rr35r9aD;Squ?`rs8N)trs#;c$j7r1r8IY[Z9\s'*G=j=s8N'%asmNOfDbd]Kbanuq#CEps4'.6
5249 'R9NU!<3!.W\=YY!<<)eF"%D#-u[o;rs"/m#@.')!<3!0mW0f`#:ONGs8N'!asmNOfDbgM!<<'(
5250 eN*jJGl.OArr;uurVult"96.drqHF%W\=YY!<<)<8e;.MG4tb3rr<2E.KhW\rr35r9aD;Squ?`r
5251 s8N)us8N)urs"/m#@.')!;c^#eN*jJGl.OAq>^HprVultrVultrr3f&F"%D#-u[o@s/IaX!<E/M
5252 3X$4Bqu?`ls8N'/asmNOfDkm$3X$4Bqu?`rrs?P0$3ri>s8N'!rr3@`!YFGC3X$4Bqu?`rrs"#h
5253 #[d3(#lai/mW0f`#:ONGqZ$QqrVm)@8e;.MG4tq8rrDfnrrE*!#,=Hm"!1t6S,WM@s7XtGOT>5X
5254 <Ib~>
5255 s!WEuVZ6_Go)Sa<JH16$JH56@s![nIJcFp5rrAJe!Rr?Fs7--h!71ZHq>^bOs5O%ZN;rV,"J,Vj
5256 <E4P~>
5257 s&HB*s8RWMpAb3Bo)Sa<JH16$JH56@rDeFKkPtP^RK!;J=+UDAs8N)FrrVcl%Y=Z>rrIuVp=]Y<
5258 !;fbrJ,~>
5259 s*'"oVZ6_Go)Sa<JH16$JH56@s*+KCJcFp5rrAJe!B7T@s7--h!71ZHblBbTs5O%ZK)bPp"H`]\
5260 <E4P~>
5261 s!RjIqU9uqJH16$JH1Z0s![nIJcFp5rrAJe!FCJ2s7--h!71ZHiW'mJs5O%ZN;rV,"J,Vj<E4P~>
5262 s&B%!qU9uqJH16$JH1Z0rDeFKkPtP^RK!:(hLY^ss8N)FrrTY05(WanrrIuVp=]Y<!;fbrJ,~>
5263 s*"GCqU9uqJH16$JH1Z0s*+KCJcFp5rrAJe!=SCJs7--h!71ZH<</nIs5O%ZK)bPp"H`]\<E4P~>
5264 s!RjIqU9uqJH16$JH1Z0s![nIJcFp5rr@WML]@ASe,KV3bl$-P!hY&Dir9%<s7Y4NScJXf<Ib~>
5265 s&B%!qU9uqJH16$JH1Z0rDeFKkPtP^JcCN*rrCOJ#%-0a`!uq.JcFa0!K$jMg'!iEqc-XH~>
5266 s*"GCqU9uqJH16$JH1Z0s*+KCJcFp5rr@WML]@ASe,KW&lM@Ib%e>2Nir9%2s7XtGOT>5X<Ib~>
5267 s!RjIqU9uqJH16$JH1Z0s![nIJcFp5rr@WML]@ASe,KTr7LKAQT7R%$rrJ)Yp=oeB!;fbrJ,~>
5268 s&B%!qU9uqJH16$JH1Z0rDeFKkPtP^JcCN*rrCOJ"fjHa#sZ:Xs5EtYM?!;'"I]>f<E4P~>
5269 s*"GCqU9uqJH16$JH1Z0s*+KCJcFp5rr@WML]@ASe,KT1-3FfWk(3QkrrI`Op=0;.!;]\qJ,~>
5270 s!RjIqU9uqJH16$JH1Z0s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5271 s&B%!qU9uqJH16$JH1Z0rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5272 s*"GCqU9uqJH16$JH1Z0s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5273 s!RjIqU9uqJH16$JH1Z0s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5274 s&B%!qU9uqJH16$JH1Z0rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5275 s*"GCqU9uqJH16$JH1Z0s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5276 s!RjIqU9uqJH16$JH1Z0s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5277 s&B%!qU9uqJH16$JH1Z0rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5278 s*"GCqU9uqJH16$JH1Z0s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5279 s!RjIqU9uqJH16$JH1Z0s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5280 s&B%!qU9uqJH16$JH1Z0rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5281 s*"GCqU9uqJH16$JH1Z0s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5282 s!RjIqU9uqJH16$JH1Z0s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5283 s&B%!qU9uqJH16$JH1Z0rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5284 s*"GCqU9uqJH16$JH1Z0s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5285 s!RjIqU9uqJH16$JH1Z0s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5286 s&B%!qU9uqJH16$JH1Z0rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5287 s*"GCqU9uqJH16$JH1Z0s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5288 s!RjIqU9uqJH16$JH1Z0s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5289 s&B%!qU9uqJH16$JH1Z0rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5290 s*"GCqU9uqJH16$JH1Z0s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5291 s!RjIqU9uqJH16$JH1Z0s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5292 s&B%!qU9uqJH16$JH1Z0rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5293 s*"GCqU9uqJH16$JH1Z0s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5294 s!RjIqU9uqJH16$JH1Z0s![nI_#OE7L&_/QoDegjm/R(co`+pkmf3:ePlLa`JcCi3!K@'Pg]X2K
5295 qc-XH~>
5296 s&B%!qU9uqJH16$JH1Z0rDgZ5s+lC/rrDZjrrDEcrrD]krrDKerrA;`rr@WMOT,?<s7Y.LRK34b
5297 <Ib~>
5298 s*"GCqU9uqJH16$JH1Z0s*+KC_#OE7L&_/QoDegjm/R(co`+pkmf3:ePlLa`JcCi3!J:@FeHD!7
5299 qGgOG~>
5300 s!RjIqU9uqJH16$JH1Z0s![nId/WtCp](6n\,ZI.!=&/prr`-.!!(aQrrE*!#2aPR#7)r9r;Zcs
5301 m/R(co`+pkmf3:err;uuRK*9err;uuJcD#8!K@'Pg]X2Kqc-XH~>
5302 s&B%!qU9uqJH16$JH1Z0rDh5EqhY"Hs+n/arr<'-r;Q]uo`P6pgAh0Qs8N;D@itj_4.lHNrrDEc
5303 rrD]krrDKerrE&urrAJerrE&urr@WMQ2^lAs7Y.LRK34b<Ib~>
5304 s*"GCqU9uqJH16$JH1Z0s*+KCd/WtCp](6n\,ZI.!A=BNrr^gR!!(aQrrE*!#-^u@!u+AAr;Zcs
5305 m/R(co`+pkmf3:err;uuRK*9err;uuJcD#8!J:@FeHD!7qGgOG~>
5306 s!WEuJH16$JH1B(s![nId/X+GoDegj\,ZF-!+#U(!8%2Mf)Gt"O4jEoGQ9l)s8N)cs8N)Qs8N(`
5307 s8N(Ms-<TbN;rV,"J,Vj<E4P~>
5308 s&FUMJH16$JH1B(rDh5Es+p:Hs+n/arVur5rr2tdrW(OL#<\aBrS('IGQ%RA!:9ac!8@JQ!0mN`
5309 !.k08rrIuVp=]Y<!;fbrJ,~>
5310 s*'"oJH16$JH1B(s*+KCd/X+GoDegj\,ZF-!9O4[!'gG_f)GtSZgR_5+991Ts8N)cs8N)Qs8N(`
5311 s8N(Ms-<TbK)bPp"H`]\<E4P~>
5312 s!WEuJH16$JH1B(s![nId/X+GoDegj\,ZI.!Ab>errZF/!!(FH!rDs#rVultm/R(cgAh0QPlLa`
5313 JcD#8!K@'Pg]X2Kqc-XH~>
5314 s&FUMJH16$JH1B(rDh5Es+p:Hs+n/arr<'/-iX,J((C6DdJj:@!!rQ'rrDEcrrCdQrrA;`rr@WM
5315 Q2^lAs7Y.LRK34b<Ib~>
5316 s*'"oJH16$JH1B(s*+KCd/X+GoDegj\,ZI.!="&QrrWTb!!(FH!n@8lrVultm/R(cgAh0QPlLa`
5317 JcD#8!J:@FeHD!7qGgOG~>
5318 s!WEuJH16$JH1B(s![nId/X+GoDegj"oWf]#u1'krs&1@,6ecSb5VG@!<)rt!<3#u!"/Em"987M
5319 -jBu7QK%rE!!pFBX8h_j-ia8GrsSOE,6ecSb5_,7"nMZm$i:53ec5Q,0F8.P\bZ:*!;c]sqZ$j!
5320 s8N)urs&1@,6ecSb5VDOol2#U*f'dq!!*'!mMQ/(qZ$Qqrr;uu"oWf]#u1'fs8N*!s8)d$s8.Br
5321 "pm,PqYpcnG9[;)9ZmA7$Uk&fs8Rcas8V`l#lal(!!W=K&d_;)q>^Hp$hd3qs8W"V0F8.P\c2X/
5322 !!N+)#T/BsrtY6O,6ecSb5_M=Jg^g01m\1A!!*'!qZ-Zr#536c"qjVPrr;uu#51[lpB:ZTrr3)u
5323 $3J_.s0Ve,N;rV,"J,Vj<E4P~>
5324 s&FUMJH16$JH1B(rDh5Es+p:Hs+gjVZAajTrr2p%osBp>PI1&_s8RoRs8RoSs8Rl^oUgs>qmi#L
5325 Ni1Xks8N')A-)#rhuI<g!<)p*l!>2/(glV/kPttfrr3B!!X&,qpN7\b&Q%<Zs8N)qrrVlo$iU,*
5326 !<3!&l!>2/(glV.rt"3p'Eg"bs8N'!s8UOP$.etQrrE&urr<5u>6tgSrV?Kn!<<)r!!iPtBH70a
5327 6F-If#3fG2!uPD2rr3?<!9jI_,9m0fkPu4os8N'&q-+.9C&Rl-rr<Gj0`h=SpN7\b&Q%<_s8N'%
5328 nNm@)Y5\G9l!>2/(glV/s7U+H!t@T&s8N'!s8Vrrs8N;f?5Nb]?gI^krr<8e0`gVA#5A,s"8;m"
5329 on!.MrrIuVp=]Y<!;fbrJ,~>
5330 s*'"oJH16$JH1B(s*+KCd/X+GoDegj"m/,T)3+Xprs$P<&dBV+p\t3m!<)rt!<3#u!"-=Z!WUnR
5331 '`o(Ldc1<,!!jtRpA^-Q_>jT7rsQnA&dBV+p]$rf-iX,F$do%bqu>PZ)$Cgio(i=c!;c]sfDmQ&
5332 s8N)urs$P<&dBV+p\t1'`((7A5Kj*,!!*'!TE?G-qZ$Qqrr;uu"m/,T)3+Xks8N*!s8)d$s4^Kf
5333 [email protected]_4;$O?b*s8NX_s8S\k7K3>e!!VLO"W<=!q>^Hp$bIG\s8Ut^)$Cgio)A[h
5334 !!LLs"uk67rtWUK&dBV+p](9J<##HK<RUpI!!*'!qZ-Zr#09IN"seHfrr;uu#.koWYQ5X>rr3)T
5335 !Y"sWs0Ve,K)bPp"H`]\<E4P~>
5336 s!WEuJH16$JH1B(s![nId/X+G!uh=dMtd8O!#1d3q2554s8VjH"eteC.0d]irr<&ts8N)us8N'+
5337 JBQsPJH/d7r7Q,Ms8N')o)L3=ZN-9k!<3!,pau`Epspku_uFcXA,cK:gAi,kqa^jPo]JaJ[/0h&
5338 !;lcul[]+YrVults8Nu3/d8!EegUg@s7e&HQ1O9ls8N'!s77ZBV"t&j!<3#u!!S_$q2554q>^Hp
5339 rr;uurVm(Q!*A@]flHui(AKKcUA3:g#/gK@\,\eor=04rs4dSrrr;uu"dcjsMZ>a4s8N'MJBQsP
5340 qa^jPo]JaJ[/^.+!/\tj<<89_pau`Epspku_uG8f=6KM7ErZ.>!<3#u!<)p2pau`Epspku_uK`:
5341 !.`8Ps-`pLrr3&[!#U:eZi:&bs7Y4NScJXf<Ib~>
5342 s&FUMJH16$JH1B(rDh5Es+gc=MOrMqs8RlhZg7IjLrB>nplCEorSiftq#CAMM#IARM#RGSL^L-P
5343 ir>[-b4tnsYN#T^!!qZdAH,O-jT#;[rs\?+$c2_U$4cS*+99I]rsY\'49,!p#I4*T)$oI&s8N)r
5344 rr_1["K24urrE*!)=J%C_>D"T%e0Md$jj<9ggL0^!!*&Y$4,/Ws8N)us8N'&?.JRE!.jtGrrE&u
5345 rrE#t"u?7=nG14+qu7H#%L^,M^^:S@s8PamW;l\u"o81q!)3Clrr<4.eau]=Jbf?G!%^V"_#O*K
5346 #I4*T)$oI+rr<$pjQ%BafDk:L$c2_U$4cS*1B<F(q8u\:rr<&us8N)trtFi2$c2_U$4cS*rr<$g
5347 j1t[Z!07'Y!kSFlJcE(V!K$jMg'!iEqc-XH~>
5348 s*'"oJH16$JH1B(s*+KCd/X+G!t,E$eG'"C!#/o*kTBlNs8Tq?/(aNg"Y]ZNrr<&ts8N)us8N'+
5349 Aak0K'`bH2oscd:s8N')Q2n]"+TV*6!<3!,_?MOBpRh[Cq#:j)kl1Sj6NE_XfaJqEqmm.XpA4gh
5350 !;uj"rQlf"g\q0P!<<':_?MOBpRh[Cq#A&4,0Tl,3WK*Z!<9A/,4>:,rrE&urr<43kNF#gcM@M?
5351 !<3#u!<)p%'`bH2oscdSrt`HU/(aNg"Y]ZNruV6ss6'k#r;St]\GlO.!!QipkTBlNq>^Hp/7n="
5352 s4If%b58aX+SPj8!!$d(bmasIs2"sjfCtpA0DPP^!3c+h\2+*a!!*#urrE#t'>ar(fCtpA0DPSI
5353 !!$U"IfC;deGfIL;?32;s0M_+K)bPp"H`]\<E4P~>
5354 s!WEuJH16$JH1B(s![nId/O;/a8==C!I4D>rr<C?s8V`l$NL..!)`aq#2T>&s8N'!rVultrr;uu
5355 !,;H4!XSk+hZ*TU#ldg+ko1!0!!*#u!j)H"rr32Z!$M=#!#PY7#'9ics1A>#rr3&c!#te7rrE#t
5356 rVus)OSo.Y!<<'#XT25trs%<[+TJGA:](1l!!E!V"JY\krrE&urr<4:s8V`l$Mj`%!<3#u!<)p!
5357 #lpt!rrT;&;?$S,h>e\us5j;!s6L5?A,iJ-<W<$u!!R*:s7H@!q>^Hp!,;H4!k\M%rr3Pq!#tt<
5358 !!$g7s69S"s/c8urr32Z!$M:J!3,kqrrE&urrE#t!j)H"rr35[!$M=A!!$a4rs8/q#PA&rSH*AT
5359 s0M_+N;rV,"J,Vj<E4P~>
5360 s&FUMJH16$JH1B(rDh5E#.*^qiK&fSq#CAM$KhBgon\b1s/Ut0rr32ULogXVLku$0s+p[Ss+g[<
5361 rr3%VM!*Xprr<?)'FFF;'`S.5rr3$n!3lJ&#-@l#s0D\_rr30E!7:aU!2'8j!mgp4qZ$QqrVuis
5362 !>E0Es8N*!rrPjoYl=Y,XT2,r8-#^fs8N'$m1K]Rq#C?orr;uu"j-fEkl;Fns8N)us8N)trrN9&
5363 bP2#<9E;<rrt):4:B1@3!'1).*?EH*2ZUbps8N'&aoDD*!#58/rr<&Crr3%0!2'8j&C:DBs8N'!
5364 cN!ph!&FRJ!3lJ&#-@l#rrW8Equ?Zrrr;uurVlpm!3lJ&#H[u$s8N'!bl7VJhuF8cs8OqVbCT]"
5365 rrIuVp=]Y<!;fbrJ,~>
5366 s*'"oJH16$JH1B(s*+KCd/O;ukk:bV"6TCYrr<Djs8Sho;ZHb=!9!kV##>6%s8N'!rVultrr;uu
5367 !:'R`!W`;^hZ*TU#lb5WjTAK^!!*#u!ZqF#rr30u!3Z?"!13]b"qCY!s!Ig"rr3%@!2B>irrE#t
5368 rVusLjo#/Y!<<'#*rt6urru7!Y5]OChY[?Q!!C.F+R]%)rrE&urr<5es8Sho;Yg@m!<3#u!<)p!
5369 !<D3TrrO8Bi;W`f:B7Qts&B'!s(ZfhlMh\$k5PD\!!VWes.]Qlq>^Hp!:'R`![e!$rr3ON!2BMn
5370 !!)<as(_V%ruV7!rr30u!3Z>&!9F%WrrE&urrE#t!ZqF#rr34!!3ZA%!!)<`rs4nj3WB'Y(BE`O
5371 s0M_+K)bPp"H`]\<E4P~>
5372 s!WEuJH16$JH1B(s![nIbl7b/!"Sf(rr<D_s8W&u!rr9W!7:`F#5S<(s8N'!rVultrr;uu!8%5M
5373 "`+/>0p:AOs8N')s3Ug(!&X]U!<3!"1]Yo%rt,#,#64WF!n.,D!XJT%56/FsrrW-!"oA9!!;lcu
5374 i*$2-rVults8N-W!7:`F#5S<(s"4<"qu?Zr!_NTgp](6nrr;uu"lB:ZrW!#qs8N)us8N)trrm3=
5375 !ATbnqYpUR!7:`F&GcA2s8Vos#QMUobTd'D!RLcFrr<5Zs8W&u!r;lr!!(XMrrPCb^Ae-Dr;[$$
5376 rr<&Rs8Vrr"ogCZd/O%Oq>^a"C]FJjP26-;rrE&urrE#t!]0o(rr36"!!`K'!!(XLrs+)T=o\F8
5377 #53WJZi:&bs7Y4NScJXf<Ib~>
5378 s&FUMJH16$JH1B(rDh)A!p,6(q#CAM$N'l'reQF2s,Mp3rr33!LlVN8Lku$0s+p[Ss+g[Prr3.i
5379 Lkr+[pu28Q!!rUZ!,MXjrr<&urrNW0o`"k%oDf@#q?R2rs6]mtrr3K/nG`Fhq>^p"s8N)srri;J
5380 .g*-Vs8N*!rrNW0o`"jpoDf@#$NThrs8N'#*!jsds8N)us8N'&p](9k!!E&srrE&urrE#t"XF'K
5381 9V1bMrrNW0o`"k%oDf@#s7?=%s'C"t;u[:-o`"mj!!W,ss82j!q>^Hp!;?El!Y5;#rr3Q+!"8i,
5382 !!)cns7QF"rs\u#rr3;s!"JrR!!,cbnG`If!<3#u!<)p!%06&"rs//r%KHG.!;?Bk#:ok`s7um-
5383 rIP!TrrIuVp=]Y<!;fbrJ,~>
5384 s*'"oJH16$JH1B(s*+KCbl7`_!-@r8rr<E(s8VWi%0->3!;c]p#1!9+s8N'!rVultrr;uu!;lcq
5385 "V:Y7A?G[ds8N')s"j^3!7CfH!<3!""p"N!rt*KV2#lkE$N'k5!B^>]#6=PurrVEb/,K;G!;uj"
5386 qR[@Kir/oW!<<'#"p"N!rs$dL2#da[qYU<m!!3QMmJ$Y\!<3#u!!W<#s7--uq>^Hprr;uurVm$4
5387 !!-W4q>1*m"p"N!rt*KV2#mU%!BC*+bqH^/"p4Z#s8N'&r;Zff!"A]'rr<&rrr3$)!;QQn&Es0F
5388 s8N'!qu?]M!%@jO!;c]p$-rT.rt#/2A?G\,s8N)us8N)trrNB)qYpL"cN#g%rr<&rrVm'8!94%E
5389 "#,<+ZMsrWs7XtGOT>5X<Ib~>
5390 s!WEuJH16$JH1B(s![nIbl7bC!!;rqrrE#trrE*!!XSl&rVm$$!rr9#!<)rt!<3#u!!)oqrs&:E
5391 *rl9CHfG)*!!rW"!WW84rr<&urrNK,q>L=.!!<3#])Y+rd/Yj"rs8Z-!s/K'!!2rrrrDoq!qcO!
5392 rVults8N-,!;ZTn"TSW("T\Jts8N'#'`s9es8N)us8N)ts8N)ps8N)us8N)trs&:E*rl9CHi*gE
5393 #lsf"rrE*$rr3:/!4c'Vn-Jag$iU,*!<)rt!;ZZp!!)oqrs]87!s8T*!!!'"rr<&qrr3-%!WNH+
5394 q>L=&!!<2rGom"d"+1(J!!*#urrE#t!XSl&rVm'%!rr9#!;l`p#4)=!s60M5JcE%U!K@'Pg]X2K
5395 qc-XH~>
5396 s&FUMJH16$JH1B(rDh)A!r[q4q#CAMrVunRs8N+VM#@8VLl)03Lku$0s+p[Ss+pXR#5GTfLkpuC
5397 irB#Y#lj>o!!2Qg!!*#u!WrH%rr3c5!!E9$?3$PrL&cJurrN0&!s/K'!!2rrrrDoq!pK[trVult
5398 s8N-&!<2ut"o\K(rrE,rs8N'#"U)L4s8N)us8N)ts8N)ps8N)us8N)trs%q#&c_n9YP\>$!s&?"
5399 rrW0""9/<,('*b:hVJh2!#GP5rrE#trrDlprr<&urr3`8!!<<)!<<*#s8N'!rr<#t!!3*%!<2ut%
5400 fQG1s6jA/!!!5,s8N'!rr;uurVlp$!<2ut#Q=]*s8N'!rr)j$d/Y-cb5c7-s0DY*M?!;'"I]>f<
5401 E4P~>
5402 s*'"oJH16$JH1B(s*+KCbl7b1!"er*rrE#trrE*!!<E3!rs&5u$NL,+!<3!"rVurts8N)trs$eD
5403 #QOi@i8Xe:!!rV9!<<2rrr<&urrE-#rVmZ.!"/c+,llWu1]Y`!rrE*%!s/K'!!E)trrDoq!iH#h
5404 rVults8N*#!<)p$p]([$!<Durrr<*&&ENTcrrE&urrE#trrDlprrE&urrE#t#1$!L!!!hnqu6Zt
5405 !<)p!p]([#rs9&5p^6M<6F-YrrVultrVultq>^HprVm9,!!<<)!<<*%s8N'!rr3/u!!WB'!<)p-
5406 p]([$cV4ZF!#OSnrr<&us8N)trrE-#rVm)s!"/c+!!)rs#($>\s'l&IJcE%U!J:@FeHD!7qGgOG~>
5407 s!WEuJH16$JH1B(s![nIbl7bC!!E#rrrE#trrE*!!]'i'rr3E'!!`K'$NTbts82isrr;uuqYpZT
5408 J,ff5s8N*!rs!ZI&-)Y0!<3!"1B>f$rt,#,#64_r!"Am-!Or+/1'#hrs8N)prrE*#rVults8N-V
5409 !7:`F#5S<(s"=B#qu?Zr"6L:!MYR5O!<3#u!<)rt!;ZZp!<3#u!;c]thgb\2qu6^R!7:`F!r;m$
5410 rr3;A!(I(\rY1=l-N3uE!<)rt!;ZZp!<)p!1'#i"s8N'*g].<N!!WBY!7:`F!r;m$rVm,[J,ffR
5411 rr<&us8N)trrOtVd/O%Lq>^a"rr<&rrrm!7JZ]!KJcE%U!K@'Pg]X2Kqc-XH~>
5412 s&FUMJH16$JH1B(rDh)A!r[q4q#CAMrVunRs8N.\M#.,N%/Pd?s8Rq3rr<#qLku'1s+pOO"6m4L
5413 NoL*=!<<''+93Sbrr<&urrNW0o`"k%oDf@#s5sA#rtPS&s8NK-p%8:a!;c]srW!#us8N*!rrNW0
5414 o`"jpoDf@#$ioqss8N'$_$'tSq#C?orr;uurVultq>^Hprr;uuqYpZD@/pc6rrNW0o`"jloDf@"
5415 rs<!3Xp+b$"eu'(rVultrVultq>^HprVlp-!;60frr<B"s8Vfn$NCP8o`"jloDf@!rs-kY!"Ju.
5416 !!*#urrE#t!Y#/%rr32p!"Ju.!!)or"WdZp70)S's0DY*M?!;'"I]>f<E4P~>
5417 s*'"oJH16$JH1B(s*+KCbl7b0!#,/-rrE#trrE*!!X8Z$rr3DR!&X`U!W`6"s5!_Urr;uuqu6fu
5418 ^GGpJirB#Ys8N96!-eJC!!*#u!X8Z$rr3PV!&X`UT`A[($3U)'rrrK#o`+pkqYpWl!!rQ'rrE*!
5419 !X8Z$rr32L!&X][!;cTmrr<.]!taPgs8N)us8N)ts8N)ps8N)us8N)rrri>91]TE1rrNB)qYpKr
5420 ci>p%rs:"PV%s"""$ck'rVultrVultq>^HprVlp'!;lTlrr<B&s8UgR-iXANqYpKrci>p%rs8V=
5421 1]TE5rr<&us8N)trrNB)qYpL!ci>p&rr<&rrrii3mMu<#JcE%U!J:@FeHD!7qGgOG~>
5422 s!WEuJH16$JH1B(s![nIbl7b+!##),rrE#trrE*!!iuB!rr3Da!$D7@;?3Qns6'F_rr;uuq>UQr
5423 !!3)Zs8N*!rs%6Y7K<Af!<3!"X8l,srrV'X+9)9CEWD@)&cVe3\,\tis8N)qrrVcl$iU,*!<<'#
5424 X8l,srs%?\+9/AA;#C:m!!N>a&d!sds8N)us8N)ts8N)ps8N)urrNK,p\OmlrVuuur;Qi"!)`aq
5425 !oEu"rr3;j!"'><s,70_A,ZH-!<)rt!;ZZp!<)p!\,\tns8N'*D#aP$!#>O8!)`aq!oEu"r;R!#
5426 !!3*!!!*#u!XSl$rr3&$!)`aq#2]D&s8N'!qu6f\!#?ghJcE"T!K@'Pg]X2Kqc-XH~>
5427 s&FUMJH16$JH1B(rDh)A!o\s)q#CAMrVunRs8N/$Lt_k.%,-N<s8S4;p&G'RLku'1s+pLN!r[q3
5428 irB#Ys8N;$!2oks!!*#u!_WNtrr3&(!)3Cl"<[]j!%7dG!aPeno`+pkqYpWW!#PV6rrE*!!_WNt
5429 rr32,!)3Da!3H(trr<3%^]akRq>^Hprr;uurVultq>^Hprr3$%!<)co!rDs!qu6^j!3lJ&!jDYu
5430 rr3;O!$!?cs!A?Yd/F"E!<)rt!;ZZp!<)p!>l^8fs8N'*ci=$j!&=LH!3lJ&!jDYur;Quu!!<3#
5431 !!*#u!WrH$rr3$m!3lJ&#-\)$s8N'!qu6f5!&Fp$JcE"T!K$jMg'!iEqc-XH~>
5432 s*'"oJH16$JH1B(s*+KCbl7`V!/((HrrE#trrE*!!ZqF#rr3C(!3Q;$$39c!s(;<3rr;uuq>UN`
5433 !!_H_rrE*!#"8OIs8N'!rr3$A!9!kV!`8s"rr3*2!0.&1rr3$G!7^Z@rrDoq!gs$prVults8N-B
5434 !9!kV##PB&ruM0squ?Zr"TOG_&ENZerrE&urrE#trrDlprrE&u!<E2rrrVQf#5eE%*rt6urrQ$t
5435 XoA>,@fR%!s8NZ9!:0U`rrE#trrDlprrE#t![Rirq>^Hp$1%WkC]Kh%*rt6urrQ$tXo/2'm/R@j
5436 rr<&urrE-#rVlp@!9!kV##PB&s8N'!qu6e/!/C\mJcE"T!J:@FeHD!7qGgOG~>
5437 s!WEuJH16$JH1B(s![nIdJjG(XRH&*-j-"7s8N)ts8N*!rt>)V"f(nF.gEfhs31NelfVUT!<3#u
5438 !<)p%/#_n6\H!E)s8N)qs8N)urs8BL"f(nF.gEfgrrh6[#ln'+rs8O#!c?]in@Mp$s8N*!rs(6`
5439 nbpp0!IOeFrrE*!)YbccU\WLl#/L96.Kl(1l[f*9!!*'!jUqWPqZ$Qqrr;uurVultq>^Hprr3C?
5440 !/CIPs!t&9r4)eCqu6rs.KuUCf..'@rr3<&#66^_s3q#Li;N]U!<)rt!;ZZp!<)pGr)*T5g\gQQ
5441 >Q=^'!/Stl=TOQ_paQHBq:@,$_#Gp`mejTq(B=C7!<3!2BE3ecs8VjD"f(nF.gEfhrr<&qrrYpp
5442 !(DJ=Z2Xi`s7Y4NScJXf<Ib~>
5443 s&FUMJH16$JH1B(rDh8F#HZq]qq6semJ-_]M#IARM#[JfpPt6nrSrltp](93Lp-^AZA=>9s8RoR
5444 rs#O^qYSQoT]6"O!;c`q!<3!(m0jB>qn`^Mmf*4hYlGU@])M^8pF$0)kPaVF62LW]!<<'(;T/;*
5445 _B8olrVults8O#)$k'rL_@$h@s6^:%[JJ]es8N'!s8Te:"MFU2rrE&urrE#trrDlprrE&u!ZV3W
5446 rr30p]_2#c!&XTQ#ji$._Y_1X%IX5q$2=Q%OT5?A!!;ros8N)ts8N)ps8N)ts![Ui"HM[Dkc7#L
5447 rr<$qk2mfgec5"F$c;eX$OuP(9"aikQN/lBrr<&urrO/?_Z'QDm0jB>qn`^Mmf3:e!;ld!rY#83
5448 V1JZOrrIuVp=]Y<!;fbrJ,~>
5449 s*'"oJH16$JH1B(s*+KCdJjGdcM?sl"W$S%s8N)ts8N*!rt<'M/(jZm"YBHKs#:"=qmr$m!<3#u
5450 !<)p%B$C,?@/tl<s8N)qs8N)urs6@C/(jZm"YBHJrrc1!#ls#brs7Bk%]AgnhO#Yds8N*!rs*Jj
5451 qXgft#NYj`rrE*!)SZG+f_M9G/GT7Z"s_@hbW5_'!!*'!MujROqZ$Qqrr;uurVultq>^Hprr3$/
5452 !8[YS#%l*UmpQ3Iqu6r:"Y87$UBN4Drr3;_!<CXLs#0o_r;HZq!<)rt!;ZZp!<)pGg^jsnnGD(0
5453 -NF)G!,V5P%L;G%^BH.?q4e*Eq#=sMqX7hmJcG`M!<3!"%055`rsZXG/(jZm"YBHKrr<&rrri0)
5454 !!(c)s0;S)K)bPp"H`]\<E4P~>
5455 s!WEuJH16$JH1B(s![nIdJjF'A/bR^8%A<nrrE#trrE&u#530_"V=;Hrr36&N>Md^irB)Ys8N)t
5456 rs%.g*!-dQh;\J7!;c`q!<)p%p2qM^&5("Arri9C!!M]frs/Os5S*u39WIshrrE*!#2!H+!>%Pp
5457 r;Zcsrr32rFWgo"9#pr2$1r'Q![*=!rr<&urr_<n!fHmTrrE&urrE#trrDlprrE&u%.@(-!<E/Q
5458 AfLjc<8IEN#530_"V=;Hr;R"A!0R<]o)K6ts8N)ts8N)ps8N)srt,1'5S*u39WJ-m!!)h!#8W$m
5459 rtG*K+U&ELa8c1mAfLjc<8ITS!!*#u%I[1.!<E0"p2qM^&5("Bs8N)qrr^jQ!o&;+Z2Xi`s7Y4N
5460 ScJXf<Ib~>
5461 s&FUMJH16$JH1B(rDh8F#2lVFM3G74p](8LrVunRrr32pZ]^0.Zh==t#QD8pN3W;:M#RGSM#I>X
5462 iNA9!Q+?eOs8N)qs8N)trs%Xk('>=Xl2CVbq?R',qu-O"qh[-<"<LmeqZ$Qqs8N;:;%`mF;9&P6
5463 rrE&u#3T5,!u>2,rr3;c<tGHeVuQbs!<3!#]EAAMqu?Zrrr;uurVultq>^Hprr3DY4q%Gls1_GE
5464 !ZPkJqYpc_>S[DW?0V:e#93a*s8V0\*;oj:!<)rt!;ZZp!;uj.qh[-<"<Lmes8N'!n3-q!X8`,4
5465 k?Jc)(1$2)s1_GE!ZPkJs8N'!rr3GZ4q%Gls8V7e('>=Xl2L__!;c]tQiI9`JcE"T!K$jMg'!iE
5466 qc-XH~>
5467 s*'"oJH16$JH1B(s*+KCdJjEG577T<D=I<"rrE#trrE&u#/s1G"X8-`rr35r9aD;Squ?`rs8N)t
5468 rs#;c$j7r1r8RbV!;c`q!<)p%`C^[F,'N\YrrhTi!$V=>rs.t5.1$5-Dqt3hrrE*!#,=Hm"!1t6
5469 r;Zcsrr32A8e;.MG4tq8$,T%:#=-K4rr<&urr\,[&EN`grrE&urrE#trrDlprrE&u%&tud!<E.r
5470 5n!lDKDbTG#/s1G"X8-`r;R!2!;$6jOT9D!s8N)ts8N)ps8N)srt+U>.1$5-DqtBm!!(.k"?"g1
5471 rtE@D&-X8$pAb/h5n!lDKDbcL!!*#u%B;)e!<E0"`C^[F,'N\Zs8N)qrrY:^&H%+ZZ2XiVs7XtG
5472 OT>5X<Ib~>
5473 s!WEuJH16$JH1B(s![nIJcC<$V#UGpaSu=p!#gFgYl=`_s7Y4NScJXf<Ib~>
5474 s&FUMJH16$JH1B(rDeFKJcDPGrrC.?!hTHWJcDtS!K$jMg'!iEqc-XH~>
5475 s*'"oJH16$JH1B(s*+KCJcC<$V#UGpaSu<(!2G,FYl=`Us7XtGOT>5X<Ib~>
5476 s!WEuJH16$JH1B(s![nIJcC<$V#UGpaSu=\!.KM!Yl=`_s7Y4NScJXf<Ib~>
5477 s&FUMJH16$JH1B(rDeFKJcDPGrrC.?!b;;]JcDtS!K$jMg'!iEqc-XH~>
5478 s*'"oJH16$JH1B(s*+KCJcC<$V#UGpaSu;i!:>@;Yl=`Us7XtGOT>5X<Ib~>
5479 s!WEuJH16$JH1B(s![nIJcC<$V#UGpao;G79celcYQ"W^s7Y4NScJXf<Ib~>
5480 s&FUMJH16$JH1B(rDeFKJcDPGrrC1@!pL@kJcDqR!K$jMg'!iEqc-XH~>
5481 s*'"oJH16$JH1B(s*+KCJcC<$V#UGpao;Fn$'Tr?YQ"WTs7XtGOT>5X<Ib~>
5482 s!WEuJH16$JH1B(s![nIJcC<$V#UGpb5VPD"#T"gs0)G'N;rV,"J,Vj<E4P~>
5483 s&FUMJH16$JH1B(rDeFKJcDPGrrC4A!rrO!pjrIKrrIuVp=]Y<!;fbrJ,~>
5484 s*'"oJH16$JH1B(s*+KCJcC<$V#UGpb5VPD$uGims0)G'K)bPp"H`]\<E4P~>
5485 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5486 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5487 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5488 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5489 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5490 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5491 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5492 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5493 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5494 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5495 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5496 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5497 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5498 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5499 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5500 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5501 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5502 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5503 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5504 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5505 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5506 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5507 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5508 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5509 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5510 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5511 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5512 s!WEuJH16$JH1B(s![nI_#OE7OT5=\rr;uun,NCf])Vd1mf3:eg&M'Pp](6nkPtP^aoDA@mJm1d
5513 h>dKTU&Y,mm/I*Fs7Y4NScJXf<Ib~>
5514 s&FUMJH16$JH1B(rDgZ5s+ld:rrE&urrDNfrrBY1rrDKerrCaPrrDfnrrD6^rrC1@rrDHdrrCmT
5515 rrAbmrrDEc!K$jMg'!iEqc-XH~>
5516 s*'"oJH16$JH1B(s*+KC_#OE7OT5=\rr;uun,NCf])Vd1mf3:eg&M'Pp](6nkPtP^aoDA@mJm1d
5517 h>dKTU&Y,mm/I*<s7XtGOT>5X<Ib~>
5518 s!WEuJH16$JH1B(s![nIci41.>o<bpPkb:Y!4W".!;uls!9=+Z!<3#u!:Tsf!4r41!:Kme!9!nW
5519 !;uls!<3#u!;uls!9aC^!6P9@!:Bgd!9F1[!;uls!5nj:!9*tX!:9^dN;rV,"J,Vj<E4P~>
5520 s&FUMJH16$JH1B(rDh2D"ll\HMkf&%s8Rnas8N)ss8N)Zs8N)us8N)fs8N)1s8N)es8N)Ws8N)s
5521 s8N)us8N)ss8N)^s8N)@s8N)ds8N)[s8N)ss8N):s8N)Xs8N)crrIuVp=]Y<!;fbrJ,~>
5522 s*'"oJH16$JH1B(s*+KCci40G4UqipdeNkB!4W".!;uls!9=+Z!<3#u!:Tsf!4r41!:Kme!9!nW
5523 !;uls!<3#u!;uls!9aC^!6P9@!:Bgd!9F1[!;uls!5nj:!9*tX!:9^dK)bPp"H`]\<E4P~>
5524 s!WEuJH16$JH1B(s![nId/O<r"Zt'+hfJSmrrBP.rrDusrrD*ZrrE&urrDNfrrAnqrrD!WrrDfn
5525 rrDusrrD6^rrC1@rrC@ErrDusrrBt:rrC4A!K@'Pg]X2Kqc-XH~>
5526 s&FUMJH16$JH1B(rDh5E#1&+8n,;ISq#CAM\,ZI.r;Zcsj8],Zrr;uun,NCfV>pPqi;`fWp](6n
5527 r;ZcskPtP^aoDA@cN!nEr;Zcs_uK`:b5VL!s7Y.LRK34b<Ib~>
5528 s*'"oJH16$JH1B(s*+KCd/O;_!K$+:]/'0]rrBP.rrDusrrD*ZrrE&urrDNfrrAnqrrD!WrrDfn
5529 rrDusrrD6^rrC1@rrC@ErrDusrrBt:rrC4A!J:@FeHD!7qGgOG~>
5530 s!WEuJH16$JH1B(s![nIdJj:?#[email protected]*ZrrE&urrDNfrrAnqrrD!WrrDfnrrDus
5531 rrD6^rrC1@rrC@ErrDusrrBt:rrC4A!K@'Pg]X2Kqc-XH~>
5532 s&FUMJH16$JH1B(rDh8F!qV8EoDeiH\,ZI.r;Zcsj8],Zrr;uun,NCfV>pPqi;`fWp](6nr;Zcs
5533 kPtP^aoDA@cN!nEr;Zcs_uK`:b5VL!s7Y.LRK34b<Ib~>
5534 s*'"oJH16$JH1B(s*+KCdJj9E!K-LKrrBP.rrDusrrD*ZrrE&urrDNfrrAnqrrD!WrrDfnrrDus
5535 rrD6^rrC1@rrC@ErrDusrrBt:rrC4A!J:@FeHD!7qGgOG~>
5536 s!WEuJH16$JH1B(s![nIdJj9T!-%Q0rr<6$HkH`[o`"jpp3._c&kpIIs8N)ts8N)us8N'+p.GMf
5537 qgp4##rIt-s8N)ss8N)trs&(N(]t^kq#:<n!!W=K&d_;)rr32U2?bYV!!*#urrE&u#5jH7#n0&/
5538 q>^Hprr33#NA(YI5Ipdn#1YR7/C"4qrr32oL_p45C&%]-$2&9Z"<N?m"U!T[rr`0+!n@,I$Uk&f
5539 s8Rcas8V`l#lal(!<3#u!!W=K&d_;)rr32U2?bYV!!*#u#536c"qjVPrr3?p!2';kKb4:ao`,9o
5540 s8)frs8N*!s8)frs8N)urt#$e0F8.P\c;^,Jg^g01m\"<rr<B$?O.L)s7Z[!h>[EVr!EMTqu?Zr
5541 $hd3qs8W"V0F8.P\c2X/!!W=K&d_;)rr32U2?bYV!!*#u#5jH7#n0&/rr;uu#51[ls8N'!rr;uu
5542 "oWf]#u1'krs%"2"Y@q!!;c`m!<<*!!!W=K&d_;)rr33#NA(YI5Ipdnrr<H*Hkm6*s8-jR$<$]q
5543 s8N'&rHo4a:%\Gb#kiHe"qjVPs8VrrqZ$QqrVultrr;uu"oWf]#u1'ks8N)ursn^A*X!O>s8Ve:
5544 ,6ecSb5VDAN;rV,"J,Vj<E4P~>
5545 s&FUMJH16$JH1B(rDh8F!j%4EoDeiH"oPZbO1G8hrs&/'PDPL1pAY*lM#IARM#RGSL^NdHM#[@_
5546 QALX"gZ&85!;uls!<)p%[email protected]%l3rs8N'&q-+.9C&S&2#-K3S6Lb$Urr;uurr32sFX%)&:u1sI
5547 rrE&u#5<6b"qa\frr32$,6U@(!!*#u#3TV/"XSg#rr3;d=qh)kVX+<fp\t0ppB(Njqu7$9!9jI_
5548 ,9m0fkPu4os8N)us8N'&q-+.9C&S&2#-K3S6Lb$Urr32e?5Nb]?gI^k$P<C&s8O;fs8V9_&c2P)
5549 !<<*!!<<)r!<<*!!<3!/pN7\b&Q%<`s7U+H!t@T&qZ$Qq$1U=b-*I:7!=&;trr_ut"82Qkrr<Gj
5550 0`h=SpN7\b&Q%<_s8N'&q-+.9C&S&2#-K3S6Lb$Urr32sFX%)&:u2-Nrr<8e0`h=S!!*#urr<5u
5551 >6tgSrVlg$W$;F3nc/[ds8)frs8N'&q-+.9C&S&2#5<6b"qa\frr;uu$i+*>(l/.a=V)-`rqZTo
5552 !!W1&#nLbKrr38g?5Nb]?gIalqZ-KmrrE#trrE&urr<5u>6tgSrVlis!<3!.j]W?$/Z/RJl!>2/
5553 (glV.rrIuVp=]Y<!;fbrJ,~>
5554 s*'"oJH16$JH1B(s*+KCdJj7j!:BCXrr<5b63S6drr2p%a@m3N,^B(_s8N)ts8N)us8N'+],h"Q
5555 gJemh'NNT@s8N)ss8N)trrpqH#RE2[rVult"m/,T)3+Xprs"8r$"3Q/!<3#u!<3!&hd%*&)/&O9
5556 s8N)urs%@d)$Cgio)AXnJeeZ#q#CEorrpqH#RE2[rVm2B7h#\fbHM!br;Q]ugB%f\qu7$0!;6Bl
5557 &;1#_T)_=Zs8N)us8N'&k!B4hNW/qW#)F*&@/0d&rr32D9G.OTGk_4;$O?b*s8NX_s8S\k7Jd&]
5558 !<<*!!<<)r!<<*!!<3!/hd%*&)/&O?s4^Kf!YeY_qZ$Qq$-Xq)2qe58!?(h7rr_!W%/]r%rr<G=
5559 *Wc<@hd%*&)/&O>s8N'&k!B4hNW/qW#)F*&@/0d&rr32[>o<b_BCc'%rr<88*Wc<@!!*#urr<5b
5560 63S6drr2p%JeeZ#q#CEks8)frs8N'&k!B4hNW/qW#2`](";tkCrr;uu$Kjha+gD!u5RAEqq#C?o
5561 "m/,T)3+Xprs6\>&dBV+p](9j!;c`q!<)rt!<3#u!!VLO"W<=!rr;uurr3JH7h#\fbQ%U`9G.OT
5562 Gk_4;!J:@FeHD!7qGgOG~>
5563 s!WEuJH16$JH1B(s![nIdJjG@!4u&;#W&1Ls8N'5Qb3'O!'(#Ypau`Epspku_uK`:!<)rt!<3#u
5564 !"+8"ir=Q0=6KM7EoR-!!;uls!<3!'p_Kk)n;@9'rr;uu&!sp(MZ>a:s6g4&c1,EH!<3#u!<<')
5565 qa^jPo]JaJ[/0h&!<<'Iqa^jPo]JaJ[/]Lt&('lb!!*'!p_Kk)n;@9's8VjD"I8TDJcD/=49#6]
5566 irBqmrsQ=:5l^cm$fq?C!$D4?rrE&urr=I6]D7?b3<0$I#S#&KB)hr3s7e2MUA3:g#/gK@\,\eo
5567 r=04rs4dSrq>^Hpr;Zcsrr;uur;Zcss8NZ-8-G(Ik=>`_s+(/OkPX"RqZ$Qq$&Qps<<89_RK,GK
5568 rrV3\)#F:4!&fANirAmH"Hi?>8-H="rr<%c]D7?b3<0$I#S#&KB)hr3s8,=iOn@g-"LS4/!!%Pm
5569 irB#Y!<3#u!"YF.q2554s8VHj&('lb!!)iprrDusrr=1.]D7?b3<0$U8-G(Ik=>`_s8N'!R()pU
5570 !+ooRqNCnEq>^Hp'UQH-MZ>a:s7e2MUA3:g#/gK@!!)cnrrE#trrE&urr<4h]D7?b3<&sX!<<'5
5571 paQE3oBLo,pau`Epspku_uK1as7Y4NScJXf<Ib~>
5572 s&FUMJH16$JH1B(rDh8F#EXbsV2^M5jS8cTL_R2]qQ>Xms8VkTNT0orNK<l7s+lL0s8RoSs8Rl^
5573 WUf'KTSUbcr8t3Bs8N)ss8N)urs/$A`r+t-!-S;@rr<R8eau]=JcGc%![$La9`P1ms8N*!rs8<=
5574 #I4*T)$oI&s8N*!s![R]#I4*T)$oI+dK1WTk#;<\s8VR:`r+t-!-S>AmL0E/ptT9W56-`CrrTe4
5575 3;WX_9E;$kq?@-!s/#cirr;uurr;uu-sbBq;#l1Is47;ojQ'#8!<<)f%L^,M^^:S@s8PamW;l\u
5576 "o81q!)34grrDusrrE&urrDusrrE*!&G@+LZ2)of#jD:E!0-LDb#J6;rr<@$jQ%BafDe&8NrK%[
5577 ])Xhes8N'W7cV;ap)OCCq:->gkl:Y_!+".I;#l1Is47;ojQ'#8!<<)m*=&kFeJSYVs8N'!7cV;a
5578 rr<&us8N'0?.JRE!.k1MdK1WTk#;<\q>^Hpr;Zcs+C3Oi;#l1Is7RH<Z2)of#jD<g!!$3Np/qC+
5579 44<h*!0-gSrr<a=eau]=JcGc=%L^,M^^:S@s8N'!p](6nrVultrr;uu"^T[N;#l1Hs8N*!rtOl0
5580 $+0K_@/o[*$c2_U$4cS*f89P$g'!iEqc-XH~>
5581 s*'"oJH16$JH1B(s*+KCdJjFW!1>GC&m"/is8N'5@cuqt!7(WE_?MOBpRh[Cq#C?o!<)rt!<3#u
5582 !"*<,IfC,_YP.Y!1?/?6!;uls!<3!'^.-iSf.@!@rr;uu%q=_c+99^es,mC`n]cji!<3#u!<<')
5583 faJqEqmm.XpA4gh!<<'IfaJqEqmm.XpA^!N>4U$u!!*'!^.-iSf.@!@s8Te;,0Tl,3WButeGfIL
5584 ;?33_rsKnKh>c[I%K-5j!4`%.rrE&urr=HVkNF#gcN!p-!ESa8L]@GTs2"sjfCtpA0DPSI*rt-s
5585 kR7pus$$Lnq>^Hpr;Zcsrr;uur;Zcss8NY`$m*Rg\dKYSrtPO;p@YpNqZ$Qq$#9"T%1)G&)?A:d
5586 rrQ'uS,30b!&eEXIfJ(0*m4Ak$R#0Crr<%.kNF#gcN!p-!ESa8L]@GTs4If%b58aX+SPj8!!$U"
5587 IfKEJ!<3#u!"WQ%kTBlNs8RrW>4U$u!!)iprrDusrr=0NkNF#gcN!pt$m*Rg\dKYSs8N'!?01Dt
5588 !8LH5lluMZq>^Hp'Op7h+99^es2"sjfCtpA0DPSI!!)cnrrE#trrE&urr<43kNF#gcMmkD!<<'5
5589 ^'5e)qo_#"_?MOBpRh[Cq#?M/s7XtGOT>5X<Ib~>
5590 s!WEuJH16$JH1B(s![nIdJjI[!"lC0h*1t%q>^Hp$>KP?o`,@!s/c8urr32Z!$M=A!!)utrrE&u
5591 rr<%5rr3$+!3+iTp]1-i!rW*'rr;uu%r)(Do`,@!s-E_$s8V<`!<3#u!<<'#]DtD"rrVKd)uBU7
5592 !<<'#]DtD"rsS,m)ul-&Du]k'!!)lq#Q4W,s8T)!:]14unc/pes8SViC&7i;jo?;!lje8Ms/5ot
5593 rr;uurr;uu'P[UIo`,@!s-E_$s8V<`!<<)$!)`aq&DdC0s8V3])?9%5G[pcP!*/jprrDusrrE&u
5594 rrDusrrE*!!k\M%rr32g!#tqE!3,\lrr<RFs8V?a(B<q*#PA&rSH*C#s8N'!C&\,6]DtD"ru:8(
5595 )uop<!,;K5o`,@!s-E_$s8V<`!<<)3!(Hne#O;@/s8N'!C&S)3!<3#u!"WfDs7H@!s8S;`Du]k'
5596 !!)iprrDusrr<C?s8V`l$NL.=!(Hne''fN:s8N'!B)ho)!!R!7s7QF"q>^Hp$>KP?o`,@!s/c8u
5597 rr32Z!$M=A!!)cnrrE#trrE&urr<4:s8V`l$NC)*!<<'#WW5imrrT;&;?$S"h>e\uQ]1t<g]X2K
5598 qc-XH~>
5599 s&FUMJH16$JH1B(rDh8F#`4A#k5FG)M<Xj9s+h$Es8VbJOoPH^Lt_k.#2+g6s8Rn2rVunRrr<"S
5600 !9a@]!f;`rhZ*?Nq>UNl!"Jr-rr<SOs8V<`'`\1g!7(WEb5_PAs8N*!rrQ[1TDnilci??-s8N*!
5601 rrQ[1TDniuci??20*'E"s3L`GqYpfr!"Ju.8-#^grs7N_%fQG-2#thrrsQ^E3WIPK*R=[D!5ng9
5602 rrE&urr<bTs8V<`'`\1g!7(WEb5_PBs%EEsrr3P3!)ERo_Z2^sdiBISs#0qqq>^Hpr;Zcsrr;uu
5603 r;Zcss8N.1!2'8j#1*?8rrW8EpAb-m&'k4TblBO!huF8cs8OqVbPM8=!!(7BrrQ[1TDnj0ci??2
5604 rr<&@s8V<`'`\1g!7(WEb5_PBs'l&$rr35M!'pSa!!(7As8N)us8N'0aoDD*!#5J50*'E"s3L`G
5605 q>^Hpr;Zcs$H`>Jkl;Fts'l&$rr3VX!'pSa!!(%=s6BXm`rH)(!#GD1rr<DJs8V<`'`\2,!3lJ&
5606 #-@l#s8N'!p](6nrVultrr;uu"j-fEkl;Fss8N*!rrP^kX8Mu!9E;<rrs#S*:B*)+s7Y.LRK34b
5607 <Ib~>
5608 s*'"oJH16$JH1B(s*+KCdJjIR!'f<8XpGI%q>^Hp$L.TjUB"3lruV7!rr30u!3ZA%!!)utrrE&u
5609 rr<&arr3$#!9E#:p]1-i!os>>rr;uu&*a,oUB"3lrtYV"s8Qd5!<3#u!<<'#-NMj!rrR6AUAFoi
5610 !<<'#-NMj!rsNlJUAkr.m/R*'!!)lq#NPkCs8O,?hYdBZQ2irEs8Nl8lMCMg<<0'!C3^<Srtkau
5611 rr;uurr;uu'^>YtUB"3lrtYV"s8Qd5!<<'@!9!kV&5N;/s8Q(!WrHgZ%dO'2!9X+WrrDusrrE&u
5612 rrDusrrE*!![e!$rr31D!2BJo!9EkRrr<Sps8Qj7R/`HP3WB'Y(BEass8N'!lMgeb-NMj!ru6"Z
5613 UAt5n!9sO`UB"3lrtYV"s8Qd5!<<'H!87AO#BKm>s8N'!lM^b_!<3#u!"\>os.]Qls8Nf6m/R*'
5614 !!)iprrDusrr<Djs8Sho;ZHbE!87AO&p"&Is8N'!kl:[^!#"Mqs/5p$q>^Hp$L.TjUB"3lruV7!
5615 rr30u!3ZA%!!)cnrrE#trrE&urr<5es8Sho;Z?^r!<<'#*WY'prrO8Bi;W`\:B7Qt(4uS[eHD!7
5616 qGgOG~>
5617 s!WEuJH16$JH1B(s![nIdJj7X!-A/>!p]guq>^Hp$Jtg_rW!$"s"j`&rr33!!!`K'!!)utrrE&u
5618 rr<&Nrr3.<!!+g;h;SD6!;uls!<)p!V)f+c!!!'!s8N'0hZ*WT!!<3#-NMp$s8)crrr;uus8N-b
5619 !5AI4!rW*&qZ$Qqs8N-b!5AI4$iL&/s!@a$s8Vus!<3!"V)f+c!!NE's"4<"qu6nP!*T@#'aFC.
5620 rsSZ)#QMUobTd'D!RLcFrrE&urr<bis8W&u!rr9J!8IPRqZ$Wrs"j`&rr3Q+!!`K'q>pp%_(a(W
5621 s"jc&q>^Hpr;Zcsrr;uur;Zcss8N-b!5AI4$2ji-s(hZ90p:Ags8N'0g].<N!!WE&JH/jQr=oP1
5622 qZ$Qq!8%5M!^?\!rr3r9!!WE&!!(mUs8E!"s8OGHg].<N!!*'!56/Fsrs/K&"onT&!8%2LrrE&u
5623 rr<Sds8W&u!rr9I!8RVSqu?`ms8N)ss8N'+hZ*WT!!<3#56/Fsrt>81"onT&!8dbUrVurTs8W&u
5624 !r;lr!".T_s8E!"s8OnUd/O%Lq>^a"rr<&ns8N)ts8N)us8N'&hZ*WT!!<0"rrE*!!\OK$r;QgT
5625 !7:`F#5S<(s!Nd*p=oeB!;fbrJ,~>
5626 s&FUMJH16$JH1B(rDh8F!fDftrr3&`Lme)=s+h$Zs8W(SM?!U9M#.,N#5X.9s8Rn2rVunRrr<"S
5627 !;lcq"dt1&X4$e%s8N)ss8N)urr`4U/IDCV!!3*!rr<T(s8Vus"98B.!;HNnp&G*ls8N*!rrN]2
5628 nG`Fhq>^p"s8N*!rrN]2nG`G"q>^p'#ls`"s7ZKns8W%R/IDCV"TeZ'$NThrrs((T[f?1-%/p&&
5629 $hOH0s'C"t;u[:-o`"mj!<3#u!#52-s82j!s8NE+p](9e!!*'!%06&"rt+f&%KHJ#!=o-9H?rNi%
5630 0?+ss8N)ss8N)us8N)ss8N*!rrN]2nG`Foq>^p',QIj=T()RUrr<T(s8Vcm$NL,W!4Mq("UtA+s
5631 8N'!pAY'n%fl+uru:e7$ig5,!;HNnqu?j!rsAc#s8Vcm!<<'0!:^!f#PnE.s8N'!pAP$k!<3#u!
5632 "\i(s82j!s8NB*p](9f!!)iprrDusrr<E#s8Vus"98B3!:^!f')DS9s8N'!p](9k!!)cns82j"q
5633 >^Hp$MXT#qu?j!rs\u#rr32p!"Ju.!!)cnrrE#trrE&urr<5ss8Vus"9/?#!<<'#$NThsrrNW0o
5634 `"jpoDf@#$AnfVg'!iEqc-XH~>
5635 s*'"oJH16$JH1B(s*+KCdJj7L!:0Xa!ce9kq>^Hp$N0r(nc0*urrrK"rr32K!&X`U!!)utrrE&u
5636 rr<&rrr3-5!!-W4q;MAR!;uls!<3!#pM_>]rVup#rr;uu&,cJ-nc0*urriE"s8UdQ!<3#u!<<'#
5637 #6=PurrVEb/,K;G!<<'##6=Purt4Jq/,obQr;ZfO!!*'!pM_>]rW!*(s8N9'qYU9s'*.%llN8j:
5638 rsR-R3<(>M0>%5g!rDorrrE&urr<c2s8VWi%0->2!;lfrg&M-QrrrK"rr3PU!&X`UcN-$*-I"3U
5639 rrrQ$q>^Hpr;Zcsrr;uur;Zcss8N-*!;QQn$0_F?rt#/2A?G\'s8N'/qu?]M!%@mI'*.%llN8j:
5640 s8N'!qu6Ts#6=Puru:2&/-#VL!;ulsnc0*urriE"s8UdQ!<<'(!;QQn#O)4=s8N'!qu-Qp!<3#u
5641 !"]#-s7--us8N6&r;ZfO!!)iprrDusrr<E(s8VWi%0->4!;QQn''TBHs8N'!r;Zff!!)rss7-.$
5642 q>^Hp$N0r(nc0*urrrK"rr32K!&X`U!!)cnrrE#trrE&urr<6#s8VWi%0$;,!<<'#"p"MtrrNB)
5643 qYpL!cN#g%"bQdJeHD!7qGgOG~>
5644 s!WEuJH16$JH1B(s![nIdJj8.!:'R`!rW*$q>^HprVults8N-,!;ZTn"TSW(rr<&ts8N)us8N'!
5645 qu6U"q0=%^!!@T-s8N)ss8N)urs,t40A$.%!!*#urrE#trrE*!!X&N"rr;uurr;uus8N?2!!<<)
5646 !<<*#qZ$Qqs8NK6!!<<)!<<*#rr`?!rr;uus8NM9!&)t%rr<'!rriE#qu6le!"Jtm!%RdD$!RD?
5647 <.+0@pAbU"s8N)us8N)ts8N*!rrN<'qYpNp!<<'##lsf"rrE*$rr3:/!4c'Vn-Jag$i'c%!;uls
5648 !<3#u!;uls!<<'1#lk&0!W`9$!WVt@*rl9CHi!dB!!)lprsA`,s8VEc%KGYm.f',E!!)oqrsT26
5649 !s8T*!!!'"rr<&ts8N*!rrN<'qYpNp!<<'.#lk&0!W`9$!WW0"!;l`prrE&urrE#trrE*!!X&N#
5650 rr;uuq>^Hpr;ZcsrVults8NK6!!<<)!<<*#s8N'!rVultrVultq>^HprVults8N-,!;ZTn"TSW(
5651 rr<&ns8N)ts8N)us8N)ts8N)us8N*!rrN?(r;?Qr#lsf"rriB(rre;\p=oeB!;fbrJ,~>
5652 s&FUMJH16$JH1B(rDh8F!fr09rr3&uLl;*/s+pXRs+p^T!JuX1rrn48s8Rn2rVunRrr<"SrVm)s
5653 [?-3#Mq[1jrrDusrrE&u#A*sLjSo,Y!<3#u!<)rt!<<'(!<E-!s8Duurr;uus8N?+!!<<)!<<*#
5654 qZ$Qqs8O/B!!<<)!<<*#rrE-!s8W&u!<<(2!,1HmrVururrE,rrs$jN)un(]C&%]7('*b:hVJh2
5655 !#GP5rrE&urrE#trrE*!$ipA-s8W&u!<<'$!<2ut!r`0%rr39?!:CQXh@T&S(ARq0!;uls!<3#u
5656 !;uls!<<'1!WW<)!W`9$!WVUs&c_n9YPS;!!"T#.s8E!!s8UIH)un(]C&.f/!!*#trsSr/!s8T*
5657 !!!'"rr<&ts8N*!rtb\9rr<#t!!*'!!WW<)!W`9$!WW0"!<2rsrrE&urrE#trrE*!#6=i(s8W&u
5658 !;ZZp!;uls!<)rt!<<'-!WW<)!W`9$!WW0"!<)rt!<)rt!;ZZp!<)rt!<<'#!s&?"rs&H&"98B$
5659 !;HNn!<)rt!<3#u!<)rt!<3#u!<<'"!<E#s!WrH%rr33%!!E6%M?!;'"I]>f<E4P~>
5660 s*'"oJH16$JH1B(s*+KCdJj7Q!<)os!pTb$q>^HprVults8N*#!<)p%p]([$rr<&urrW0"!<3#u
5661 !<)p%cV4ZF!#OSQs8N)ss8N)urs((TP3r;F!!*#urrE#trrE*!!<E3"rrW#s!<3#u!<<')!<<3(
5662 !W`9$"8`&t!<<',!<<3(!W`9$"9/B%rr3Q+!!*'!/-(k#s7lWps8N*"qYpbH!+c+>!6"[4#n$b.
5663 $LiF0ZN+5.s8N)us8N)ts8N*!rrE-#rr33!!!*'!!<E)u!r)a&rr394!;HojHpY.>>PS6u!;uls
5664 !<3#u!;uls!<<'1!<<3(!W`9$"96\A#QOi@i;3KR!<3!+q>^^!s*F`Vs'l&Iq>^HprVm9,!!<<)
5665 !<<*%s8N'!rVults8N*#!<3!1q>^NqrrE*%!s/K'!!E9$!!)rsrrE&urrE#trrE*!!<E3"rrW#s
5666 !;ZZp!;uls!<)rt!<<'-!<<3(!W`9$"98B$!<)rt!<)rt!;ZZp!<)rt!<<'"!<E)u#5A0*s8N'!
5667 p](6nrr3'!!!*#urrE#trrE&urrE*!!<E2trrE-#rVm)s!"/`,K)bPp"H`]\<E4P~>
5668 s!WEuJH16$JH1B(s![nIdJj99!:0Xa!rW*$q>^HprVults8N-V!7:`F%/Kr.s8NH,o)Jaf!!*#u
5669 rrDoq"5eV/#3,[_!;uls!<3!'+TU9ss7lWprr;uurVults8N<O!8IPRqZ$Wqs8N*!rrOqUeF`e@
5670 !<<'#1'#i#rtZm\h>dNQ!!*'!+TU9ss7lWps8O_Pde`tIAcRCb!2TDi$,Q[3"7c@)N;t=(s8N)u
5671 s8N)ts8N*!rsU7Tg].<N!!*'!1B>f$rrW#s#6+W/_>m%-nbs5^!%.L@rrDusrrE&urrDusrrE*!
5672 !\sc*p\t?QJ,ffMs8N'&g].<N!!WB%"_IacXoP9ns8N)trrOqUeG9.E!<)rt!<<'--NMp$s8)cr
5673 s8OhSeG9.E!;uls!<3#u!<)rt!<<'(,lld$s82isq>^Hpr;ZcsrVults8N-U!7^iErrE#trrE#t
5674 rrDlprrE#trrE*!!]'i'rr33!!!`K'!!)cn#7CP&s8Vus!<3#u!<)rt!<3#u!<<'#0*'GurrOtV
5675 d/O%Lq>^a"-]J*!g]X2Kqc-XH~>
5676 s&FUMJH16$JH1B(rDh8F!hG/Grr3&uLl;*/s+pXRs+p^T!fi*5rr3E'LlVN8M2;02s8.V.rr<"S
5677 qYpZ^[>9k&s8N)ss8N)urs&f0p](9a!!*#urrE#trrE*!#7:J*s8Vcm!<3#u!<<'#$iotms8N*!
5678 rrNT/p%n\(#ls`"s7ZKns8N?)p](9a!!*'!$ioqrrrjGDejTT'q#:Y,!3QM'qurhq?N'p(!<3#u
5679 !<)rt!<<'-$39i#s7QEms8NN.o`"jloDf@"rs<!3Xp+b$"eu'(q#C?or;Zcsrr;uur;Zcss8N-/
5680 !;6*d"4(BU%Jp,)!!W,ss7ZL#rr3-C!7jR=l1tAZ!<)p!$iotrs8N)ts8N*!rsT57p](9e!!*'!
5681 $iotrs8N)ss8N)us8N)ts8N*!rs&i1p](9f!!)iprrDusrrE#trrE*!!Xo)%q>^HprVultrVult
5682 q>^HprVults8N-0!;-9j#4qm)s8N'!p\tI#!;ulspAb3ms8N)ts8N)us8N*!rrNT/o_e^j%06&"
5683 rs&)q%K?cls7Y.LRK34b<Ib~>
5684 s*'"oJH16$JH1B(s*+KCdJj7^!<)os!pTb&q>^HprVults8N-)!;c]p%+"u2s8N-#rr<#T!!*#u
5685 rrDrr"TH.m!&`d9rrDusrrE&u#6Y&)s8U(=!<3#u!<)rt!<<'("T\H"s4RGQrr;uus8N-)!;lEg
5686 rrE*!!X8Z%qYq<7!;ulsg].?Srr`?"s8U(=!<<''!;cQl"UtJ"*<>d-rs:"PV%s"""$ck'rVult
5687 rr;uurVults8NK2!;lfrg&M-QrrrK"rr3&H!&X]T#poYK(&m_*5QJ[rs8N)ss8N)us8N)ss8N*!
5688 rrNB)qtU0orkC8i2>[@Q!!W9"s4[N$rr3-2!:Cj-p%eXf!<)p!"p"Prs8N)ts8N*!rsT&2qu?]M
5689 !!*'!"p"Prs8N)ss8N)us8N)ts8N*!rs&]-r;ZfP!!)iprrDusrrE#trrE*!!X8Z%q>^HprVult
5690 rVultq>^HprVults8N-)!;c]p#1*?,s8N'!p\tI"!<3#uh>dQTs8N)ts8N)us8N*!rrNB)qY^?p
5691 "p"N!rs$gM2#d`2s7XtGOT>5X<Ib~>
5692 s!WEuJH16$JH1B(s![nIdJj:.!-J5?!p]h"q>^HprVults8N/%!)`aq%,V%,s8PssV>pSZ!!*#u
5693 rrDlp"9&9$ro=%Y!;uls!<3!'&HLnls4mYTrr;uurVults8N=i!,V]8l2Uh`s8N*!rrT\17J-W[
5694 !<<'#\,\tort^duEW?(*!!*'!&HLnls4mYTs8T,";#:1pjT$&A%JTl/lMq8(s8S#_!+Z!-rrE&u
5695 rrE#trrE*!%$gm0s8V?a!<<)#!)`aq!oEu"rr3;j!"'><s,70_A,-'*#ls_us8N)urrNK,p\k-l
5696 !<<'#\,\tkrr`6#!WMurrr<4=s8VBb(&n49jT$&A%J]u'!<)p!\,\tns8N)ts8N*!rsY1nD#aP#
5697 !!*'!\,\tns8N)ss8N)us8N)ts8N*!rs+_fEW?(*!!)ip!XSl$rVultrVults8N/1!(H_`rrE#t
5698 rrE#trrDlprrE#trrE*!!iuB!rr35\!$D7@#ls_prs)F%V>pSZ!!*#urrE#trrE&urrE*!!il;t
5699 r;Qi"!)`aq#2]D&s-AWDp=oeB!;fbrJ,~>
5700 s&FUMJH16$JH1B(rDh8F!oJgurr3&aLn4AAs+pXRs+p^T!iq.2rr3D\Lo^RUObi]1s5f&mrr<"S
5701 q>UNpLl(-krrDusrrE&u#6Y&&s8T"t!<3#u!<)rt!<<'(0`]Q"s31NDrr;uus8N.+!1<EYrrE*!
5702 !aPenqYq<a!7UuJd/X1Hrr`>ts8T"t!<<'j!3H%s"MOjl#or^>$.&Yl-NF)m&cg;Ws8N)us8N)t
5703 s8N*!rsUU^ci=$i!!*'!9)u3qrrTD)9`G%uci>%4s8ODY!7:N@!WrH$rVultrr3$%!<)lrrrE*!
5704 !aPenpAY3k!!<#srr<5Ks8U@E1&h1U^&Tqq*;KR6!<)p!>l^8fs8N)ts8N*!rsUU^ci=$i!!*'!
5705 >l^8fs8N)ss8N)us8N)ts8N*!rs(1We,THq!!)ip!WrH$rVultrVults8N.+!1<T^rrE#trrE#t
5706 rrDlprrE#trrE*!!_WNtrr35-!)3Fm!s&;prs'5<lMpn)!!*#urrE#trrE&urrE*!!_EBnr;Qgk
5707 !3lJ&#-\)$s"TB1p=]Y<!;fbrJ,~>
5708 s*'"oJH16$JH1B(s*+KCdJj8R!:0Xa!d"F"q>^HprVults8N-B!9!kV$rI#,s8NE+p&G&)!!*#u
5709 rrDlp!poslirB#Yr;Zcsrr33)!<)rt8cSkjs8N)ts8N*!rs'8=li7!"!!*#urrE*!![Riro`+pk
5710 s8N-H!7^lF()-c8s8R!;!<<'#!<)rt8cSkkruM0sqYp\.!/C\mp\tP0!"Y(hrt,J9li$k`!<3#u
5711 !<)rt!<<'-'`dS"s(VN6s8O/@i;W`X;#m`trs<08%upVh&I/=%q#:?q!;uls!<3!!!<E&trrE*!
5712 ![RirpAY3]!!`<"rr<5gs8Qm8Qi@!f@fV8eC\[r0!<)p!,llHjs8N)ts8N*!rsTVBli7!"!!*'!
5713 ,llHjs8N)ss8N)us8N)ts8N*!rs'5<m/R*(!!)ip!<E2us8N)ts8N*!rrOJHeG9.E!<)rt!<)rt
5714 !;ZZp!<)rt!<<'#*rt6urru=#XoJD%!;HKu$39c!s(;<3rr;uurVultrr;uus8N-A!8dYR!ZqF#
5715 rr31"!3Q89K)bPp"H`]\<E4P~>
5716 s!WEuJH16$JH1B(s![nId/O>o$F0Kb63EtXs8N)ts8N*!rt>)V"f(nF.gEfhs31NelfVUT!<3#u
5717 !<)p%/#_n6\H!E)s8N)ss8N)urs+_f5P*`"!!*#urrE#trrE*!#OVg,cgkfN!<3#u!<<')r)*T5
5718 g\gQQ>PeC"!<<'Er)*T5g\gQQ>Q='o&(0uf!!*'!P5mi=hF%>Ds8VjD"IA`HJc5TN9E5&]p\tQt
5719 #66^_s3q#Li;N]U!<3#u!<)rt!<<'3mKX6JnnJ.)s8VjD"f(nF.gEfgrsAT.!&srXe,TO-q#:G0
5720 !/CIOs8N)urrZp7LAh,OrrE*!&H#E-D;5!X]3G:cW:'So!#GG2rr<4Ycgk3>NrAt[9E5&]q#C?o
5721 rVm<(;?C^ir:%=&s8N'!rVults8Nl&#7f)NC&e86s85arD;5!X]3G=8!!)rsrrE&urrE#trrE*!
5722 #OM[*dIV;W!;ZWsBE3ecrr;uurVults8NN*;?C^ir:%=&s8N'!rVultrVultq>^HprVults8NT(
5723 .KuUCf..'@s8Qa4LAgrJ#L*5llfVUT!<3#u!<)rt!<3#u!<<'5paQE4p$72/paQHBq:@,$_#Nh]
5724 s7Y4NScJXf<Ib~>
5725 s&FUMJH16$JH1B(rDh5E#GmUHro]H&n+m"`M#IARM#[JfpPt6nrSrltp](93Lp-^AZA=>9s8RoR
5726 rs#O^qYSQoT]6"O!;uls!<3!'490p.a@Q@3rr;uurVults8N>S![6^f:B1Cos8N*!rs8?I"HM[D
5727 kc7#Gs8N*!s!7=e"HM[Dkc7#LdK1`Xk>_K^s8P1]JGR>Y!!*'!mL0E0qV>QYrri<7!!&kirsAH%
5728 !0I6\NrT7VrVultrr;uurVults8N_^![6^f:B1Cps6U4&_Y_1X%IX5q$2=Q%OT5?A!!;rjrrO/?
5729 _YsN7!<3!"*!!kSs8N*!rt+oQ"HM[Dkc7#L9"aikQN/l=s8N'&;!-m`!nI;M"TB&7!2]JjrrE#t%
5730 /2.QNp$B)X$Qdc!!)utrrE*!(=`I0k2fA=!<<)n-j5RnrTL:Js8N'!r;Zcsrr;uurVults8N>P!
5731 [[$m<<*$prrO/?_YsN7!<)rt!<<'-pF$0)kPaVF63$rb!<)rt!<)rt!;ZZp!<)rt!<<'.m0jB>q
5732 n`^Mmf3;,!5eO2#CukSp=*4F!<3#u!<)rt!<3#u!<<'5mL0E0qV>QZm0jB>qn`^Mmf1gos7Y.LR
5733 K34b<Ib~>
5734 s*'"oJH16$JH1B(s*+KCdJjLM)+*3WYmM<;q>^HprVults8N_H"Y87$UBN4Ds8P%YNr-DQ!!*#u
5735 rrE#t#%l*UmpQ3IirB#Yr;Zcsrr33@!3Z0sMuWkWs8N)ts8N*!rs+Pb=n9jo!!*#urrE*!#i#t$
5736 VssT?QmV\0rrE*!,hrq@VssT?QmVij!F><EMuWkXrttg>qP]>Q!<<)5"s_@hbW5\&"SrE)!8I8J
5737 $/bgaeGoP-!!iH#s8N)us8N)ts8N*!rt:=m=n9jo!!*'!^BH.?q4e*Eq#::"huNi-s8P"X#Q4As
5738 !Y#.crVultrr3$/!8[VRrrE*!&DRg,VssT?QmViFbkgd:!.k"Hrr<4=o$7dNmf*4hq?[-%g\CgK
5739 !<)p+g^jsnnGD(0-NF)G!<)rt!<<'7NWE;RcA2H#s8Ujc%]AgnhO#Yirr<&ss8N)us8N)ts8N*!
5740 rs+D^?1ZI&!!)ip!Y#.crVultrVults8NM_&.YW-qqd\es8N'!rVultrVultq>^HprVults8NPC
5741 "Y87$UBN4Ds8NN.h>%!T2uo!9\s36qrr;uurVultrr;uus8NeI"s_@hbW5^<"Y87$UBN4Ds,M^2
5742 p=0;.!;]\qJ,~>
5743 s!WEuJH16$JH1B(s![nId/O=KRP5!U5IL:drrE#trrE&u#530_"V=;Hrr36&N>Md^irB)Ys8N)t
5744 rs%.g*!-dQh;\J7!;uls!<3!'qJ6`J6/MYBrr;uurVultrr32S2$>GQ!!*#urrE&u#QCD^&-<S?
5745 Wqubq!<3!:rh2Rg!YnD/s8US*">%dt!WW2rC_6k;hZ*ZUrrr%3)?M%;rVluO!!:pKrs*NDOoPIQ
5746 !"Jl+rrE&urrE#trrE&u#1k^8/'@nmrr32rFWgo"9#pl0#B9a+s8VZj%JTl.mnsf"!<<'!!<3!(
5747 mnsf"!<<'!!<3!/rh2Rg!YnD/s4M!(!Y\PhqZ$Qq"Sl7,(5;\d"4mMSg\CgK!;uj)rh2Rg!YnD/
5748 s8N'!rVultrr32S2$>GQ!!*#u$iZhb&-<S?WrN)!!;uls!<3#u!<)rt!<3!&e2.:Zbl@e?rs8'k
5749 '*/+5rr<&ts8N)ursSh"5S*u39WJ-m!!)utrrE#trrDlprrE#trrE&u#530_"V=;Hrr3,i;A0'2
5750 qYpg"N>Md^irB)Ys8N)ts8N)us8N)ursn[<)?M%;s8Ve8+U&ELa8Z)>N;rV,"J,Vj<E4P~>
5751 s&FUMJH16$JH1B(rDh5E#5uE*MNFt,q#CAMrVunRrr32pZ]^0.Zh==t#QD8pN3W;:M#RGSM#I>X
5752 iNA9!Q+?eOs8N)ss8N)urs/0m#n'o2!!*#urrE#trrE&u#-/sN5O\XQrr;uurr36#M)5VD*aZb\
5753 s8N)uru1ck1^jL.?GlgCV]l70n,NOis7B+o$X*6)!<3!%jAulp0;ndK".0&kp\+Ul*!#+#s5a5#
5754 r;Zcsrr;uurVultrr32',6L1"!!*#u#3T5,!u>2,r;R!A!9O7\jT$:prs74?$ipA.rr<&urs74?
5755 $ipA.rr<&urt#!`1^jL.?GlfX;A'$MC%qK(rr<2k4p*%1r;Qkd!!N&ks8N)srsS^\1^jL.?GlgC
5756 !!)utrrE&u#-/sN5O\XQrr3B'M)5VD*aZbarr<&ss8N)us8N)ts8N)urs#AF"@;MW!r;j%f00TD
5757 !<<'!!<)rt!<3!+qh[-<"<Lmes8N'!rVultrVultq>^HprVultrr32c>S[DW?0V@g"P5gG!<Dur
5758 #Q8?H#Zpg%!<3#u!<)rt!<3#u!<3!.jAulp0;njMk?Jc)(1$2(rrIuVp=]Y<!;fbrJ,~>
5759 s*'"oJH16$JH1B(s*+KCd/O=;@i,:dBCP]rrrE#trrE&u#/s1G"X8-`rr35r9aD;Squ?`rs8N)t
5760 rs#;c$j7r1r8RbV!;uls!<3!'eN*jJGl.OArr;uurVultrr31V('e+?!!*#urrE&u#OZX^#mVks
5761 h"q'N!<3!:mW0f`#:ONGs8RWb#[d3(#ljqT3X$4Bqu?`rrrp8,$3ri>rVls\!"f)%rs&u5oDeiQ
5762 !-.r:rrE&urrE#trrE&u#)*ft>kn@"rr32A8e;.MG4tk6#7U\)s8S2]EVKJ=W\=YY!<<'!!<3!(
5763 W\=YY!<<'!!<3!/mW0f`#:ONGs.r!i"=Jj"qZ$Qq"Ni1s2:qd+"$-Dnr:p<l!;uj)mW0f`#:ONG
5764 s8N'!rVultrr31V('e+?!!*#u$gr'b#mVksh#IBS!;uls!<3#u!<)rt!<3!&JJAGtoDf0mrs5VY
5765 #6=i)rr<&ts8N)ursS79.1$5-DqtBm!!)utrrE#trrDlprrE#trrE&u#/s1G"X8-`rr3,$0F%UY
5766 qYpfn9aD;Squ?`rs8N)ts8N)us8N)ursln5$3ri>s8U&1&-X8$pAY'mK)bPp"H`]\<E4P~>
5767 s!WEuJH16$JH1B(s![nIJcDGD!r;m%lMgq=!#gFgp&>*H!#hs=!r;m%JcGQG!K@'Pg]X2Kqc-XH~>
5768 s&FUMJH16$JH1B(rDeFKU&P2c!"S;o!hTHWJcGEC!hTHWXT&@n!"OS[q>UJPs7Y.LRK34b<Ib~>
5769 s*'"oJH16$JH1B(s*+KCJcDGD!mL^*lMgoJ!2G,Fp&>(U!2HXq!mL^*JcGQG!J:@FeHD!7qGgOG~>
5770 s!WEuJH16$JH1B(s![nIJcDGD!oa1ulMgq)!.KM!p&>*4!.M$L!oa1uJcGQG!K@'Pg]X2Kqc-XH~>
5771 s&FUMJH16$JH1B(rDeFKU&P2'!']]J!b;;]JcGEC!b;;]XT&@2!'Yu6q>UJPs7Y.LRK34b<Ib~>
5772 s*'"oJH16$JH1B(s*+KCJcDGD!`]5tlMgo6!:>@;p&>(A!:?lf!`]5tJcGQG!J:@FeHD!7qGgOG~>
5773 s!WEuJH16$JH1B(s![nIJcDSH"usj)fero(li.%Y9celcp&>*c9cgM<"usj)fero(JcGQG!K@'P
5774 g]X2Kqc-XH~>
5775 s&FUMJH16$JH1B(rDeFKV>ga,h#5/$"Q8VG!pL@kJcGEC!pL@kYQ"f6h#5/$"Q4k2q>UJPs7Y.L
5776 RK34b<Ib~>
5777 s*'"oJH16$JH1B(s*+KCJcDSH#(Z"8W<Wq(li.%;$'Tr?p&>*E$'VRm#(Z"8W<Wq(JcGQG!J:@F
5778 eHD!7qGgOG~>
5779 s!WEuJH16$JH1B(s![nIJcDSH"jKLE"YZM6rrW6'1ua)dpAY3p"#T#@rrpY:$O&2UJcGNF!K@'P
5780 g]X2Kqc-XH~>
5781 s&FUMJH16$JH1B(rDeFKV>g_"1^47N_X%4(!!Z-lJcGHD!rrO!poj]$X#("e5Ji!Oq#:AOs7Y.L
5782 RK34b<Ib~>
5783 s*'"oJH16$JH1B(s*+KCJcDSH"cOc1&5qZVrrW60D#AkapAY3p$uGjFrrn?.!t\AmJcGNF!J:@F
5784 eHD!7qGgOG~>
5785 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5786 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5787 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5788 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5789 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5790 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5791 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5792 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5793 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5794 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5795 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5796 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5797 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5798 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5799 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5800 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5801 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5802 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5803 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5804 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5805 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5806 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
5807 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
5808 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
5809 s!WEuJH16$JH1B(s![nI_#OE7QN-sb])Vd1huE]V_uK`:l2Ub`rr;uui;WrXKdI!(qu?ZraoDA@
5810 JcGQG!K@'Pg]X2Kqc-XH~>
5811 s&FUMJH16$JH1B(rDgZ5s+m!@rrBY1rrCsVrrBt:rrD<`rrE&urrD!W"SldO!s&5urrC1@rr@WM
5812 q>UJPs7Y.LRK34b<Ib~>
5813 s*'"oJH16$JH1B(s*+KC_#OE7QN-sb])Vd1huE]V_uK`:l2Ub`rr;uui;Wr?<"o?5qu?ZraoDA@
5814 JcGQG!J:@FeHD!7qGgOG~>
5815 s!WEuJH16$JH1B(s![nIdJs%C!!2lprrBP.rrD'YrrC@ErrDNfrrCsVrrC4ArrDusrrD<`rrE&u
5816 rrDcmrrDHd"/>j%p%n^g!6P9@!7:cG!3H2$N;rV,"J,Vj<E4P~>
5817 s&FUMJH16$JH1B(rDh8FqM5-.q#CAM\,ZI.irB#YcN!nEn,NCfhuE]Vb5_JAr;Zcsl2Ub`rr;uu
5818 pAb-mmJd8]!202bs8N)@s8N)Gs8N)#rrIuVp=]Y<!;fbrJ,~>
5819 s*'"oJH16$JH1B(s*+KCdJs%C!"&H#rrBP.rrD'YrrC@ErrDNfrrCsVrrC4ArrDusrrD<`rrE&u
5820 rrDcmrrDHd"!.H\rqcZp!6P9@!7:cG!3H2$K)bPp"H`]\<E4P~>
5821 s!WEuJH16$JH1B(s![nIbl7b&!#,/-rrBP.rrD'YrrC@ErrDNfrrAqrrrDusrrD<`rrDThrrDHd
5822 !Z_:/^]4<6d/X+GXT&<[s7Y4NScJXf<Ib~>
5823 s&FUMJH16$JH1B(rDh)A!o&O$q#CAM\,ZI.irB#YcN!nEn,NCfVZ6Yrr;Zcsl2Ub`nc/UhmJd4m
5824 !;jP2rrCFGrrB/#!K$jMg'!iEqc-XH~>
5825 s*'"oJH16$JH1B(s*+KCbl7`;!0$^QrrBP.rrD'YrrC@ErrDNfrrAqrrrDusrrD<`rrDThrrDHd
5826 !X&N&^]4<6d/X+GXT&<Qs7XtGOT>5X<Ib~>
5827 s!WEuJH16$JH1B(s![nIbl7a#!)E=hrrBP.rrD'YrrC@ErrDNfrrAqrrrDusrrD<`rrDThrrDHd
5828 rrBe5rrCFGrrB/#!K@'Pg]X2Kqc-XH~>
5829 s&FUMJH16$JH1B(rDh)A!h5#$q#CAM\,ZI.irB#YcN!nEn,NCfVZ6Yrr;Zcsl2Ub`nc/UhmJm1d
5830 ^An35d/X+GXT&<Xs7Y.LRK34b<Ib~>
5831 s*'"oJH16$JH1B(s*+KCbl7_W!9*_QrrBP.rrD'YrrC@ErrDNfrrAqrrrDusrrD<`rrDThrrDHd
5832 rrBe5rrCFGrrB/#!J:@FeHD!7qGgOG~>
5833 s!WEuJH16$JH1B(s![nIc2RnB#6N`Vs8N'&rHo4a:%\Gb#536c"qjVPrr;uurVultrr;uu$MI*p
5834 s8.Br"pm,PirB#YrVult$iPGg%qkq>Eu,0]q>UEo!!N+)#T/Bss8N)urs&C\0F8.P\c2X/!"8aQ
5835 ((Y'Xqf<P\;Yg=l#5jH7#n0&/rr;uu#Q9#_#u1'ls8)fmrsA@<*X!O>s8N'!rr33#NA(YI5Ipdn
5836 #4mWf!uktLrr;uu"oWf]#u1'ks8N)us8N'&rHo4a:%\Gb#1YR7/C"4qq>^HprVultrr;uu"SlC1
5837 (l8%gqZ-Zrrr<6$HkH`[o`"jpr/EB:$pV;us8N)us8N*!rs/FQ-jBu7QN-g^qYpipG9[;)9ZmD8
5838 qZ-NnrrE&u#1YR7/C"4qrr;uu"oWf]#u1'krs&1@,6ecSb5VG@!"8Kn"98E!NA(YI5Ipdn#2(m<
5839 /Bn.pq>Uj#NA(YI5Ipge!!VrmrsS]1!nI>KNA(YI5Ipdnrr<<&HkH`[o`+sg!!iQ$Jg^g01mYWN
5840 !K@'Pg]X2Kqc-XH~>
5841 s&FUMJH16$JH1B(rDh,B"8[k2qtU3kL^!^^N/tOKrr32q[$-?1[.aM!s+pXRs+p[Ss+h$ST8<OE
5842 \X&)4Vq^52rrE#trr<H&?4Rm.s7KM+&9.XJs8N'%nNm@)Y5\J$!<3!&pN7\b&Q%<_s8N',q-FRK
5843 L]@$M&.ig[rr32sFX%)&:u2-Nrr<<">6tgSrVuop!;c^%j]W?$/Z/RJ!!*#u#5<6b"qa\frr32c
5844 B+>(kKDtlMrr<5u>6tgSrVlis!<3#u!!W1&#nLbKrr32$,6U@(!!)iprrE#trrE&urr<2l63JU;
5845 qZ$Ems8W*!"o2@/%r)"Ars&4?,6e`Vh>.*N!<3#u!<<'(p1PHK%77B#qZ-Km#jGY4!uPD2s8Vrr
5846 qu?Zrrr32$,6U@(!!*#urr<5u>6tgSrVlg$l!>2/(glV.s8N',kV3,<s7^X\"qa\frr32*,QpI(
5847 !!)ip$hncg"qa\fs6'Fir;Q^(o`>6gs7^X\"qa\frr;uu#PhR1%r)"Bs8)d$s7U+H!t@T&\,QJc
5848 s7Y.LRK34b<Ib~>
5849 s*'"oJH16$JH1B(s*+KCc2Rmm!=eu%s8N'&k!B4hNW/qW#09IN"seHfrr;uurVultrr;uu$G.>[
5850 s4^Kf!YeY_irB#YrVult$Kjha+gD!u5RAEqrVult"O&D$2qe31rrE&u#2`](";tkCrr;uu$Kjha
5851 +gD!u5RAEqrVm)Z>o<b_BCc'%rr<;d63S6drr<#q!;c^%`((7A5Kj*,!!*#u#2`](";tkCrr3/P
5852 9F(nZUAb,l!!VLO"W<=!rr;uurr;uu"m/,T)3+Xprs"&j$"3Q/!;ZZp!<)rt!<3#u!!LLs"uk63
5853 s8)frs8N'&k!B4hNW/qW#2`](";tkCq>^Hprr;uus8N>Y<##HK<RUpE!;c^$a@m3N,^B(`s8)fn
5854 s8N)urs"&j$"3Q/!<3#u!!VLO"W<=!rr32D9G.OTGk_4;rr<G=*Wc<@hd%*&)/&O>rs"8r$"3Q/
5855 !;ZX&hd%*&)/&O?U&ZS?rr3AS!=er+hd%*&)/&O>s8N'(k!B4hNW/tXqZ$m$gJemh'NNSjrrI`O
5856 p=0;.!;]\qJ,~>
5857 s!WEuJH16$JH1B(s![nIc2Rk"!#>8.rr<b"]D7?b3<0$R/d8!EegUg@s8N'!rVultrr;uu$@p=Z
5858 s+(/OkPX"RirB#YrVult$^eF"P5o3.\,)9g5lUf`!',n\nPoUQs8N'!s8Vse"Hi?>8-H="rr<%d
5859 \,)9gAn\[MP5mlJs8,=iOn@g-"LS4/!!&@tq2554rr;uuq#;E1.Kl%.l@K!8!!*'!qa^jPo]JaJ
5860 [/]n:WVQ%A!&X]Trr<4h]D7?b3<&sX!<3#u!"YF.q2554s8VHj&('lb!!)iprrE#trrE&urr<4Z
5861 c1+d7P5>4Y!;uls!"bL/q2554s8Vse"Hi?>8-H<rs8N)us8N*!rsF;W=6KM7ErZ.>!;QR&pau`E
5862 pspku_uK`:!;QTo!<<'(m04*JnnnF-rr;uu.[RdCMZ>a:s7e2MUA3:g#/gK@!!%PmirAmH"Hi?>
5863 8-H="mg'BInRhh%qYq!$8-G(Ik=>`_s)S0Mrr3bg!#bh68-G(Ik=>`_s8N'!Qb3'O!''uXrrE#t
5864 #(ZbUkPX"R\,QJfs7Y4NScJXf<Ib~>
5865 s&FUMJH16$JH1B(rDh,B!nE+!p](8L'XR-%Y)($rs7hY7ir.krO8/bTLku$0s+p[Ss+h#]o&B\B
5866 Ls#Mjk-*eErrE#trr<F1de6fD\NA75=TFH\s8N'Z:ZURY!n[JP!!*'!p)OCCq:->gkl:Y_!*[hE
5867 =TGuode6fDNW9%P*=&kFeJSYVs8N'!?.JRE!.k.LrrDio*psFC[.rEas8N'!s8Vd5#I4*T)$oI+
5868 n0l<Sk$\74rr;uu"^T[N;#l1Hs8N)us8N'0?.JRE!.k1MdK1WTk#;<\q>^HprVultrr;uu"]+4?
5869 *s1'js8N)ss8N'1?.JRE!.k1Mp)OCCq:->gkkb>Z!<3#u!<<'+1B<F(q8u\:rr<&ors\?+$c2_U
5870 $4cS*rr<&os8N*!rs-sR,3J#e!!*#urr=NSeau]=JcGc=%L^,M^^:S@s8N'!7cV;ap)OCCq:->g
5871 kl969+6;KW!!)lq%/(\HZ2)of#jD:2!6>*=(8Lpls7RH<Z2)of#jD<g!!$<ToMGU>rr;uurVm'X
5872 !0-LDb#GkM!K$jMg'!iEqc-XH~>
5873 s*'"oJH16$JH1B(s*+KCc2Ri3!1*BZrr<aBkNF#gcN!p]"tS="TER"Ds8N'!rVultrr;uu$>&^U
5874 rtPO;p@YpNirB#YrVult$XMl\,66Lrjm42le,KCI!'+fabmasIs8N'!s8Ua\*m4Ak$R#0Crr<%)
5875 jm42lgem2",663ms4If%b58aX+SPj8!!$KkkTBlNrr;uuq#;DL"sV7fb;oV&!!*'!faJqEqmm.X
5876 pA_irgAKPS!6"m:rr<43kNF#gcMmkD!<3#u!"WQ%kTBlNs8RrW>4U$u!!)iprrE#trrE&urr<4;
5877 n]_LKn,!(a!;uls!"`W&kTBlNs8Ua\*m4Ak$R#0>s8N)us8N*[email protected]!1B7@S!;QR&_?MOB
5878 pRh[Cq#C?o!;QTo!<<'(M?-oOd#.l(rr;uu.UqT)+99^es2"sjfCtpA0DPSI!!$U"IfJ(0*m4Ak
5879 $R#0COo\VRc%l?"qYpuW$m*Rg\dKYSrso+nrr3a$!1s5D$m*Rg\dKYSs8N'!@cuqt!7(TDrrE#t
5880 "r.-Ap@YpN\,QJ\s7XtGOT>5X<Ib~>
5881 s!WEuJH16$JH1B(s![nIc2Rik!*/dnrr<C?s8V`l$NL..!)`aq#2T>&s8N'!rVultrr;uu!,;H4
5882 !XSk+hZ*TUrVult$YKG=p&G8.s8Vcm$NC)*!"NfEs69S"s8N'!s8T_37K3<'lMqn(rr<%2s8Vcm
5883 "_Rf7p&GI"s1A>#rr3Dm!#tt<!!$a5s7H@!rr;uuq#:Dq!)NLlrrE*!!k\M%rr3&c!#th8!rW*'
5884 rr;uu"_n#:o`,?us8N)us8N'0C&e5+!"/c+PQ5Y%s6BXbq>^HprVultrr;uu"`+/<l2VUrs8N)s
5885 s8N'+C&e5+!"/c+]DtD"rrVKd)uBU7!<3#u!<<'##lpt%s8N)orrT;&;?$S"h>e\urr<&os8N*!
5886 rs+bgDu]k'!!*#urr<C?s8V`l$NL..!)`aq#MoG's8N'!C&\,6]DtD"rsS,m)ul6)C]FG!!!)lq
5887 !k\M%rr32g!#tss!#PY7#'9ics1A>#rr3Dm!#tt<!!$a5s7H@!rr;uurVlp*!3*=)!K@'Pg]X2K
5888 qc-XH~>
5889 s&FUMJH16$JH1B(rDh,B!ge`$p](8L$KhBgon\b1s/Ut0rr32ULogXVLku$0s+p[Ss+g[<rr3%V
5890 M!*XprrE#trr<GHs8VBb$c`5Hl2VV!s8N'/cN!ph!&FTS!!*'!@fW/#rtj#^5l^ia!65'=lMq=4
5891 s8V?a(B=DE!2'8j%+"u>s8N'!aoDD*!#5G4rrDio!_<<lqu?Zrs8N.1!2'8j!mgp4qu6`n!"Jr-
5892 rr<5Es8V<`'`S.4!<3#u!"[3Os60Lts8O_PdJs6n!!)iprrE#trrE&urr<5Js8U=D1A_%N!;uls
5893 !"-jJs60Lts8QR/TDnilci??-s8N)us8N*!rrN9&bPV>>!;QQq9E;<rrs#S*:B1=o!;QTo!<<'(
5894 0*'E"s3L`Grr;uu$H`>Jkl;Fts%EEsrr35*!)ERo!!(7BrrQ[1TDniuci??21'#W"s2tBBqYpV,
5895 !2'8j#1*?8s0D\_rr30E!7:aU!2'8j%+"u>s8N'!aoDD*!#5G4rrE#t!WrGGZi:&_s7Y.LRK34b
5896 <Ib~>
5897 s*'"oJH16$JH1B(s*+KCc2RhU!9EnSrr<Djs8Sho;ZHb=!9!kV##>6%s8N'!rVultrr;uu!:'R`
5898 !W`;^hZ*TUrVult$g@WjW;mRps8T"t>5nR%!"S;os(_V%s8N'!s8OGHg&D!fEr_s7rr<&_s8T%u
5899 ''TAqVuU$$s!Ig"rr3CJ!2BMn!!)9`s.]Qlrr;uuq#:C:!8dVQrrE*!![e!$rr3%@!2BAj!os>>
5900 rr;uu"mQ'eUB"3ks8N)us8N'0l2UdY!)ijs'`dV#s)%f:q>^HprVultrr;uu"mZ-fCB0aus8N)s
5901 s8N'+l2UdY!)ijs-NMj!rrR6AUAFoi!<3#u!<<'#!<D3Xs8N)orrO8Bi;W`\:B7Qtrr<&os8N*!
5902 rs'8=m/R*'!!*#urr<Djs8Sho;ZHb=!9!kV#>Y?&s8N'!lMgeb-NMj!rsNlJUAku/lMplu!!)lq
5903 ![e!$rr31D!2BKk!13]b"qCY!s!Ig"rr3CJ!2BMn!!)9`s.]Qlrr;uurVlp"!9CKd!J:@FeHD!7
5904 qGgOG~>
5905 s!WEuJH16$JH1B(s![nIcMn"B!s7QXs8N'+hZ*WT!!<3#1]Yo%rs&<"#64]'!<)rt!<3#u!!(XM
5906 rrm3=!ATbniW&oXrVult$f:p`rVurTs8W&u!ri6"!"Rc`s8)d"s8N'!s8P:`^Ae-Kr;[$$rr<&U
5907 s8W&u!8dbUrW!$"s$$Ltrr3E*!!WE&!!(mUs8E!"rr;uuq#:CJ!7LcErrE*!!^?\!rr36%!!WE&
5908 V)f+c!!!'!s8N'&hZ*WT!!<0"rrE&urr<Sds8W&u!rr9I!8RVSqu?`ms8N)ts8N)us8N'&g].<N
5909 !!W6!rrDusrr<D_s8W&u!rr9b!5AI4!rW*&qZ$Qqrr;uus8N7=!!+g;h>[HS!;QQq1]Yo%rs&<"
5910 #64]'!;QTo!<<'(-32j$s82isrr;uu$Jtg_rW!$"s"j`&rr36"!!`K'!!(XMrrPCb^Ae-?r;[$$
5911 -NMp$s8)crqYpU]!5AI4&H)S4s8=)Bdf9(D#Q"Hb!5AI4%/g/0s8N'!hZ*WT!!<0"rrE#t"`+/>
5912 0p:A$rrJ)Yp=oeB!;fbrJ,~>
5913 s&FUMJH16$JH1B(rDh/C"8I\0r:g6kL^O%Zs8Ih2s8S+8qYpL!qM:13s+lL0s8RoSs8RlTqu6U!
5914 R>?["deMf$rrE#trr<H$s8Vus!;HNnqu?m!s8N'/p](9e!"/c+!!*'!%fl+urtkM3$ig5,!;HNn
5915 qu?`ks8Vus"TSK4!:^!f%/Kr3s8N'!p](9k!!E6#rrDio!Xf##qu?Zrs8N-2!:^!f#PnE.s8@a*
5916 $2so)!WN-!!!W,ss82j!rr;uurr;uu&,6,(qu?j!rs8]"s8Vfn!;ZZp!<)rt!<3#u!!W,ss7QF"
5917 qZ$Qqr;Zcs$MXT#qu?j!rso,!rr3&r!"8Z'rrE&urrE*!"XF'K9V1bQs8N)orrNW0o`"jpoDf@#
5918 rr<&os8N*!rs&i1p](9f!!*#urr<E#s8Vus"98B1!;-9j#P8!*s8N'!pAY'n%fl+ursSZ'$i^P6
5919 p](9e!!)lq!Y5;#rr3Q+!"8i'#Qsc"mK!gsrso,!rr3E'!"8i,!!)cns82j!rr;uurVm$H!!,cb
5920 n@&>tM?!;'"I]>f<E4P~>
5921 s*'"oJH16$JH1B(s*+KCcMn!a!>>A*s8N'+r;Zff!"Ao-"p"N!rs$dL2#mRU!<)rt!<3#u!!)oq
5922 rrir6!G&>.iW&oXrVult$iL&)nc/[fs8VWi&H;_0!"So+s4RH$s8N'!s8N<(q#::0kl<76rr<&s
5923 s8VWi!;ulsnc07$rs&Q!rr3Dk!%\*L!!)rss7--urr;uuq#:C"!;cTmrrE*!!XA`#rr35f!%\*D
5924 E$GSd!!!-#s8N'&r;Zff!"Al,rrE&urr<T-s8VWi%0->2!;ulsgAh6Ls8N)ts8N)us8N'&qu?]M
5925 !%@^DrrDusrr<E(s8VWi%0->4!;QQn!pK\8qZ$Qqrr;uus8N66!!-W4q>UEo!;QQq"p"N!rs$dL
5926 2#mRU!;QTo!<<'("T\K#s4[MRrr;uu$N0r(nc0*urrrK"rr35L!&X`U!!)oqrrNE*q#::$kl<76
5927 "T\H"s4RGQqYpU%!;QQn&Es0Fs6Bdpqu=/,49,<c!;QQn%-[aBs8N'!r;Zff!"Al,rrE#t"V:Y7
5928 A?G[9rrI`Op=0;.!;]\qJ,~>
5929 s!WEuJH16$JH1B(s![nIcMmss!#YG0rrE#trrE*!!XSl&rVm$$!rr9#!<)rt!<3#u!!)oqrs&:E
5930 *rl9CHfG)*!<)rt!<)rt!<)rt!<3#u!!)lprtGG6s8N'!s8NB*!s8T*!!!'"rr<&ts8N)ts8N*!
5931 rsT26!s8T*!!!'"rr<&ts8N)us8N)orrN?(r;6No!<<'2#lk&0!W`9$!WTS.0A$.%!!*#urrE#t
5932 rrE&urrE&urrE#trrE*!!X&N#rr;uuq>^HprVultrr;uu!;c]p!<</ss8N)ss8N)ts8N*!rs/o2
5933 !s8T*!!!&rs8N)us8N*!rsJRI*rl9CHiO*G!;QQq#lsf"rriB(s8N'!q#C?os8N-'!;lcqrrE&u
5934 rrE#trrE*!!XSl&rVm'%!rr9#!;lcq$jcn9!s/K'!!3*&!;c]prrDoq+:/#M!s/K'!!3-"])Y+r
5935 d/Yj"rs8Z-!s/K'!!3-"!!)utrrE&urrE#t#5NNd!!!+J\,QJfs7Y4NScJXf<Ib~>
5936 s&FUMJH16$JH1B(rDh/C!mZUrpAb/KrVunRs8N+VM#@8VLl)03Lku$0s+p[Ss+pXR#5GTfLkpuC
5937 irB#YrVultrVultrVultrr;uu)#jR8rW!!!rr<'!rrN0&!s/K'!!3-"!!)utrrE#trrE*!$j$D2
5938 !s/K'!!3-"!!)utrrE&urrDio!<E2ss8N*!rt,;4!s8T*!!!'"AcQN*rr)ltrr;uurVultrr;uu
5939 rr;uurVults8N<)!<3#urVuros8N)ts8N)us8N'&rr<#t!!2rrrrDusrrE#trrE*!#Qau.!s/K'
5940 !!2rrrrE&urrE*!$L_C9!!!5,s8N'!q#:Bt!<2ut#6"T)s8N'!q#C?os8N<)!<3#urVurts8N)t
5941 s8N*!rrN9&rr2p&rW!'#rr<&urr3Q3!!<<)!<<*#rrE-!s8W&u!;c^<!WW<)!W`9$!WW1+!1j.E
5942 !-nPD!WW<)!W`9$!WW0"!<)rt!<3#u!<)p%mpQh/!!]X9rrIuVp=]Y<!;fbrJ,~>
5943 s*'"oJH16$JH1B(s*+KCcMmr-!2&ubrrE#trrE*!!<E3!rs&5u$NL,+!<3!"rVurts8N)trs$eD
5944 #QOi@i8Xe:!<)rt!<)rt!<)rt!<3#u!<3!5q>^^!rr<'!rrE*%!s/K'!!E9$!!)utrrE#trrE*!
5945 $ip>1!s/K'!!E9$!!)utrrE&urrDio!<E2ss8N*!rt,83!s8T*!!!-$/-(k#s7lWprr;uurVult
5946 rr;uurr;uurVults8N*#!<3!"q>^Nks8N)urrW0"!<3#u!<3!"q>^]qs8N)ss8N)ts8N*!rs/W*
5947 !s8T*!!!,ts8N)us8N*!rsI(H#QOi@i;`fW!;QQp!<E)u#5A0*s8N'!q#C?os8N*#!<3!"q>^Np
5948 s8N)ts8N*!rrE-#rVm)s!"/c+!!)ut$NU50!s/K'!!E6%!<3!"q>^Nlru_=B!s8T*!!!-$s!7Zu
5949 s"j`!s8N*"!s8T*!!!-$rr<&ts8N)us8N)trs$eD#QOi@i4&^eK)bPp"H`]\<E4P~>
5950 s!WEuJH16$JH1B(s![nIcMmr]!+#<urrE#trrE*!!]'i'rr3E'!!`K'$NTbts82isrr;uuqYpZT
5951 J,ff5s8N)ts8N)ts8N)ts8N)us8N'/g].<N!!WE&!!*'!1'#i"s8N)ts8N)ts8N*!rrOqUeG9.E
5952 !<)rt!<3#u!;QQq0*'Gts8N*!rrOqUeGB1M+TU9ss7lWprr;uurVultrr;uurr;uurVults8N<M
5953 !8[\Tqu?`mrs&o3o)Jaf!!*#urr<5Ws8Vrr"oA9!!;uls!<)rt!<<'#1'#hrs8N)us8N)srs.G3
5954 !!`K'!!)fo!]'i'rr33!!!`K'!!)forrE*!#:0B+s8Vus!<3#u!<)rt!<<'#1B>f$rs&<"#64]'
5955 !<)p!1'#i#rs'nOg].<N!!)lq!\sc*q>Uiq!"Am-!Or+/1'#i"s8N)ts8N)us8N)qrr_//!!]q4
5956 !K@'Pg]X2Kqc-XH~>
5957 s&FUMJH16$JH1B(rDh/C!gST%pAb/KrVunRs8N.\M#.,N%/Pd?s8Rq3rr<#qLku'1s+pOO"6m4L
5958 NoL*=!<)rt!<)rt!<)rt!<3#u!"Sc's7ZL#s8N'!s8NK-p%eXf!<)rt!<)rt!<<'#$iotrs8N)t
5959 s8N)us8N)orrNT/o_\[g!<<'#$iotsrs&f0p](9a!!*#urrE#trrE&urrE&urrE#trrE*!#71D)
5960 s8Vfn!;ZX"!s&9!s7ZKnrr;uu"o&&spAbQss8N)ss8N)ts8N*!rrNT/p%8:a!<3#u!;uj%cX?e_
5961 s8N'!q#:C)!;-9j#4qm)s8N'!q#C?os8N<1!;HNnpAb3ms8N)ts8N*!rrNW0o`"jpoDf@#rr<&t
5962 rrNT/p%n[n$39i#s7QEmqYpU*!;60f$g.L.rtPS&s8NK-p%eXf!<)rt!<3#u!;c]tcX?e_\,QJc
5963 s7Y.LRK34b<Ib~>
5964 s*'"oJH16$JH1B(s*+KCcMmqT!9a(UrrE#trrE*!!X8Z$rr3DR!&X`U!W`6"s5!_Urr;uuqu6fu
5965 ^GGpJirB#YrVultrVultrVultrr;uu%f?;+gAiW$rr<'!rrrK#q>^HprVultrVults8N-)!;lTl
5966 rrE#trrE&urrDio!X8Z$qu?Zrs8N-)!;lWm#6Y&)s8U(=!<3#u!<)rt!<3#u!<3#u!<)rt!<<'(
5967 "T\K#s4dSSq>U[$!<3#uh>dQTs8N'&qu?]N!%7XCrrDusrrE#trrE*!!X8Z%o`+pkrr;uurVm0&
5968 ^GGpJs8N'!q#:C"!;c]p#1*?,s8N'!q#C?os8N<-!;ulsg].?Rs8N)ts8N*!rrNB)qYpL!ci>p&
5969 rr<&trrNB)qtg<t"T\H"s4RGQqYpU$!;lTl$_[Q3rsAl's8N9'qt^9l!<)rt!<3#u!;ld!rkC8i
5970 27NSdK)bPp"H`]\<E4P~>
5971 s!WEuJH16$JH1B(s![nIci4+A!<_Z]s8N)ts8N*!rrT8%;?$S(hZ+bus&&ins8V9_!<3#u!;ZWs
5972 rVuuuj8],ZrVultrVultrVultrr;uu%W)1FlMq\"rr<'!s0r%tq>^HprVultrVults8N/1!(H_`
5973 rrE#trrE&u!XSl$q>UMs!)WRmrrE*!!k85!qYpd4!9F1[h#IHSs8N)ts8N)us8N)us8N)ts8N*!
5974 rs+_fEW?(*!!)ip#>tPus8V9_!<3#u!!R3=s6BY"qYpU'!;HHlrrE#trrE*!!k85!o`+pkrr;uu
5975 qu6p#!!3*!#ls_qrrT8%;?$S"hZ+burr<&os8N*!rs+_fEW?(*!!*#urrE#trrE*!!iuB!rr32[
5976 !$D7@!!)ut!k85!qYped!,V]8l2Uh\rrT\17JQlcEWD@)&cVe3\,\tns8N)ts8N)urrNK,p\Oml
5977 rVuuu\GlSgs7Y4NScJXf<Ib~>
5978 s&FUMJH16$JH1B(rDh2D"8@V0rV$9kM#IARM#[JVX,,L/rs[V;X8i3^M"UfJjbS`ls8RoNrrW.T
5979 M;nR8!<)rt!<)rt!<)rt!<3#u!"R?Ts3:U!s8N'!s8Q@)R/-d^!<)rt!<)rt!<<'#>l^8fs8N)t
5980 s8N)urrN9&rV?Hp8H>jhs8N*!rrQI+R/6gf"9A8ts/5ntrr;uurVultrr;uurr;uurVults8N<W
5981 !7UuJd/X1Brs'5<lMpn)!!*#urr<5Ks8U@E1&CnO!s&;us8N)ts8N*!rrQI+R.UFY!<3#u!;ld$
5982 qZ$]trrW9"q>ULh!3lJ&#-\)$s8N'!q#C?os8N<W!7UuJd/X1Gs8N)ts8N*!rrPgnYl=Y,YQ.As
5983 rr<&trrQI+R/6gf0`]Q"s31NDqYpV&!1<Q]"<[]j!%7dG!aPenq>^HprVultrr3$%!<)co!rDs!
5984 \,QJcs7Y.LRK34b<Ib~>
5985 s*'"oJH16$JH1B(s*+KCci4*T!?(k0s8N)ts8N*!rrO8Bi;W`b;#m`ursAc!s8Q^3!<3#u!;ZWr
5986 m/R@Ms8N)ts8N)ts8N)ts8N)us8N'/li7!$!13`c!!*'!,llHjs8N)ts8N)ts8N*!rrOJHeG9.E
5987 !<)rt!<3!!!<Dop!Zh?uqu?Zrs8N-H!7^lF#6Fo(s8P[k!<3#u!<)rt!<3#u!<3#u!<)rt!<<'(
5988 'EIM"s).l;q>U[,!;6BlB)hr2s8N'&li7!$!13Q^!<E2us8N)ts8N*!rrOJHeF`e@!<3#u!;ld#
5989 m/R@jrrE,prrO8Bi;W`\;#m`urr<&os8N*!rs'5<m/R*(!!*#urrE#trrE*!!ZqF#rr31"!3Q;$
5990 !!)ut![RirqYpd8!:0[bC&e81rrOJHeG0%H%KMLhJc>ZN,llHjs8N)ts8N)urrE-#q>UN`!!]q4
5991 !J:@FeHD!7qGgOG~>
5992 s!WEuJH16$JH1B(s![nIci4'o!#tV2rrE#trrE*!')3p[U\WLl#/L9=blApQk?e2hrr;uurVm'P
5993 W:'So!#FSorrE#trrE#trrE#trrE&urr<mlcgk3>NrT+Z!<<)s;?C^ir:%=&s8N'!rVultrVult
5994 s8NN*;?C^ir:%=&s8N'!rVultrr3(6!/CIKruUqb"IA`HJcG`M!<<)s;?C^ir:%=&s-!FIoA2k8
5995 !<3#u!<)rt!<3#u!<3#u!<)rt!<<'(m0+$Jo5F[0q>U]E!$U[k?N:**s8N'&LsPWp!KR$V")%[h
5996 rVlis!<)rt!<<')r)*T5g\gQQ>PeC"!<3#u!<<'-/#_n6\H!EFs(DCerVHO&paQHBq:@,$_#OE7
5997 !;QTo!<<'(m0+$Jo5F[0rr;uurVults8NN&.KuUCf..'@s8N'!rVmK-;?C^ir:%=&s6^+%cgkfN
5998 !;c^$r)*T5g\gQQ>Q4X*huF&`=8r4.r)*T5g\gQQ>Q=^'!<)rt!<3!,BE3ecs8OUJmejTq(:X;E
5999 N;rV,"J,Vj<E4P~>
6000 s&FUMJH16$JH1B(rDh2D!lp+op&G&JrVunRs8N`+NfE)tj,K)ns8U#nYP[XkLku'1s+pXR#-6\Y
6001 qp("jirB#YrVultrVultrVultrr;uu(f9AW+Tg3orr<'!s7[oENp$B)X$Qdc!!)utrrE#trrE*!%
6002 /2.QNp$B)X$Qdc!!)utrrE&u!ZV3Wq>VN($jj?<h-g9_!!*'!pF$0)kPaVF62s%IJGR>Y!!*#ur
6003 rE#trrE&urrE&urrE#trrE*!#LWZ"kN>hF!;ZX"JH/[Ce6)bOrr;uu"]4@D+Tg3jrrO/?_YsN7!
6004 <)rt!<<')pF$0)kPaVF62LW]!<3#u!<<',9"aikQN/lBru;$Uq>Ulj$k'rL_@$h@s8N'!q#C?os
6005 8N>P![[$m<<*$us8N)ts8N*!rs\9'$c;eX$OuP(rr<&trt4uR"HM[Dkc7#LeH-oVj\GjVqYpiq-
6006 j5RnrTL:Jrr3,+!#P^Irr3E$-j5RnrTL:Js8N'!rVultrr3$>!5ea8#"lQ$pQkk:\,QJcs7Y.LR
6007 K34b<Ib~>
6008 s*'"oJH16$JH1B(s*+KCci4&'!2oMirrE#trrE*!'#+T#f_M9G/GT8F2uo!9\s36qrr;uurVm(6
6009 bkgd:!.j/0rrE#trrE#trrE#trrE&urr<mPo$7dNmf3:e!<<)S&.YW-qqd\es8N'!rVultrVult
6010 s8NM_&.YW-qqd\es8N'!rVultrr3$/!8[JN*khh'bkoUEs8N'!s8Ujc%]AgnhO#Yi)$$i9W/L]V
6011 rr;uurVultrr;uurr;uurVults8N=]!F><EMuWkRrs(L`Nr-DQ!!*#urr<4=o$7dNmeZqb%055_
6012 s8N)ts8N*!rs7Bk%]AgnhO#Yds8N)us8N*!rsNG_qX7hmJcG`Z!8[JN%)2rrf_M9G/GT8F!!)fo
6013 rrE*!#DrOfo?iKs!<3#u!<)rt!<<'-^BH.?q4e*Eq#C?o!<)p0g^jsnnGD(0-NB),=n9jo!!)lq
6014 #i#t$VssT?QmVh4"Ao.*!9=(Y%,;C(VssT?QmVk5!!)utrrE&u!Y#.crr317bkgd:!.hWZ!J:@F
6015 eHD!7qGgOG~>
6016 s!WEuJH16$JH1B(s![nIci4&N!+tp(rrE#trrE&u#530_"V=;Hrr36&N>Md^irB)Ys8N)trs%.g
6017 *!-dQh;\J7!<)rt!<)rt!<)rt!<3#u!!N+%#8W$ms8N)ursSh"5S*u39WJ-m!!)utrrE#trrE&u
6018 $iZhb&-<S?WrN)!!<)rt!<3!$mnsf"!;c^%oPGKJ+Gg't!!*#u&H8@g&-<S?WrMp3&I(PY!!*#u
6019 rrE#trrE&urrE&urrE#trrE&u#1PI4/Bn.qq>U^!N>Md^irB)Ys8N'%q-+(>L&(`Smnsf"!<<'!
6020 !<)rt!<3!'rh2Rg!YnD/qZ$Qqrr;uus8NP]AfLjc<8ITSmnsf"!;c^"p2qM^&5("Bs8N)os8N)u
6021 rs$t0">%dt!WN-!!<)rt!<3!&p2qM^&5("Bs8N)srt,1'5S*u39WJ-mf/3[]b5_P<rs/Os5S*u3
6022 9WJ*l"T9GC"RZ0f$iZhb&-<S?WrN)!!<)rt!<3!,mnsf"!<:_a*!-dQh7*CbN;rV,"J,Vj<E4P~>
6023 s&FUMJH16$JH1B(rDh2D!g8B&p&G&JrVunRrr32pZ]^0.Zh==t#QD8pN3W;:M#RGSM#I>XiNA9!
6024 Q+?eOs8N)ts8N)ts8N)ts8N)us8N'%n3-q!X8`/!!<3!+qh[-<"<Lmes8N'!rVultrVultrr3B'
6025 M)5VD*aZbarr<&ts8N)urrgq;$ipA)rs@af&-FS`s8N'!rr3Q,M)5VD*aZbaoM>i%=nhssrr;uu
6026 rVultrr;uurr;uurVultrr32#+p:4$!!;ur#Q8?H#Zpg%!<3#u!!MdT"!alBrs74?$ipA.rr<&t
6027 s8N)urs/FX1^jL.?GlX>rrE&urrE*!%DPdR!ZPkJs8U\7$ipA)rs%Xk('>=Xl2L__!;QTo!<3!&
6028 V]l70n,NOhs8N)ts8N)urs%Xk('>=Xl2L__!;uj.qh[-<"<Lmes8T,E"$c8T!;ZX"qh[-<"<Lme
6029 rr3,t#QP/-rVm9&M)5VD*aZbarr<&ts8N)urs[LC$ipA.^JY[G)eo&UrrIuVp=]Y<!;fbrJ,~>
6030 s*'"oJH16$JH1B(s*+KCci4%S!:'7WrrE#trrE&u#/s1G"X8-`rr35r9aD;Squ?`rs8N)trs#;c
6031 $j7r1r8RbV!<)rt!<)rt!<)rt!<3#u!!LFo"?"g1s8N)ursS79.1$5-DqtBm!!)utrrE#trrE&u
6032 $gr'b#mVksh#IBS!<)rt!<3!$W\=YY!;c^%_F"Y85g03-!!*#u&FOTg#mVksh#Gnc"Vc4Z!!*#u
6033 rrE#trrE&urrE&urrE#trrE&u#([Kp?h==(q>U]m9aD;Squ?`rs8N'%asmNOfD5FPW\=YY!<<'!
6034 !<)rt!<3!'mW0f`#:ONGqZ$Qqrr;uus8NP)5n!lDKDbcLW\=YY!;c^"`C^[F,'N\Zs8N)os8N)u
6035 rs"#h#[d3(#lal(!<)rt!<3!&`C^[F,'N\Zs8N)srt+U>.1$5-DqtBmKbanuq#CEjrs.t5.1$5-
6036 Dqt?l"R6*i+oVB>$gr'b#mVksh#IBS!<)rt!<3!,W\=YY!<8l]$j7r1r3u\,K)bPp"H`]\<E4P~>
6037 s!WEuJH16$JH1B(s![nIJcFR+rr@WMq#:El!!hrlrrADc!r;m%JcEjl!K@'Pg]X2Kqc-XH~>
6038 s&FUMJH16$JH1B(rDeFKh>dKTJcGNF!qQC%mf3:eQi@-Y!"OS[ao;Bus7Y.LRK34b<Ib~>
6039 s*'"oJH16$JH1B(s*+KCJcFR+rr@WMq#:E?!'0KIrrADc!mL^*JcEjl!J:@FeHD!7qGgOG~>
6040 s!WEuJH16$JH1B(s![nIJcFR+rr@WMq#:ET!#k;*rrADc!oa1uJcEjl!K@'Pg]X2Kqc-XH~>
6041 s&FUMJH16$JH1B(rDeFKh>dKTJcGNF!k/.nmf3:eQi@,r!'Yu6ao;Bus7Y.LRK34b<Ib~>
6042 s*'"oJH16$JH1B(s*+KCJcFR+rr@WMq#:Cq!2f2arrADc!`]5tJcEjl!J:@FeHD!7qGgOG~>
6043 s!WEuJH16$JH1B(s![nIJcFR+rr@WMr;Qs\bl$-P!h\o\rrAPg"usj)fero(JcEjl!K@'Pg]X2K
6044 qc-XH~>
6045 s&FUMJH16$JH1B(rDeFKh>dKTJcGZJ#%-0a`!uq.mf3:eS,W\"h#5/$"Q4k2ao;Bus7Y.LRK34b
6046 <Ib~>
6047 s*'"oJH16$JH1B(s*+KCJcFR+rr@WMr;QtOlM@Ib%eB&frrAPg#(Z"8W<Wq(JcEjl!J:@FeHD!7
6048 qGgOG~>
6049 s!WEuJH16$JH1B(s![nIJcFR+rr@WMr;QrF7LKAQTC)[Y!1Wulbsi'E0;!gqaSu:"s7Y4NScJXf
6050 <Ib~>
6051 s&FUMJH16$JH1B(rDeFKh>dKTJcGZJ"fjHa#sZ;os8N(grroG["pmN2JcEgk!K$jMg'!iEqc-XH~>
6052 s*'"oJH16$JH1B(s*+KCJcFR+rr@WMr;QqZ-3FfWk3`3K!1WulN$\W<;W`Q1aSu9ms7XtGOT>5X
6053 <Ib~>
6054 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6055 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6056 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6057 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6058 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6059 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6060 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6061 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6062 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6063 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6064 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6065 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6066 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6067 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6068 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6069 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6070 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6071 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6072 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6073 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6074 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6075 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6076 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6077 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6078 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6079 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6080 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6081 s!WEuJH16$JH1B(s![nI_#OE7Y5eM%hZ*TU\c2];'(5f"!:Kme!3ZA%!8dbU!<3#u!7h,L!8dbU
6082 !<3#u!8RVS!:Kme!87AQN;rV,"J,Vj<E4P~>
6083 s&FUMJH16$JH1B(rDgZ5s+miXrrCpUrrBV0!Ga4Rs8N)es8N)%s8N)Us8N)us8N)Ls8N)Us8N)u
6084 s8N)Ss8N)es8N)PrrIuVp=]Y<!;fbrJ,~>
6085 s*'"oJH16$JH1B(s*+KC_#OE7Y5eM%hZ*TU\c2[_Hg^q6!:Kme!3ZA%!8dbU!<3#u!7h,L!8dbU
6086 !<3#u!8RVS!:Kme!87AQK)bPp"H`]\<E4P~>
6087 s!WEuJH16$JH1B(s![nId/O<b:DX-A0o#K'rrBP.q>gQqrrCpUrrBY1!q?G:mf3:emf3:eh#IBS
6088 ec5XLhZ*TUrr;uuec5XLhZ*TUrr;uuh#IBSmf3:eh#IBS!rn5Zp=oeB!;fbrJ,~>
6089 s&FUMJH16$JH1B(rDh5E#1TK1M3"L^q#CAM\,Z:)s8W*!hZ*TU])Mif!RL36rrDKerrCjSrrCUL
6090 rrCpUrrE&urrCULrrCpUrrE&urrCjSrrDKerrCjSrr<-#M?!;'"I]>f<E4P~>
6091 s*'"oJH16$JH1B(s*+KCd/O<*1(+4$:;6N'rrBP.q>gQqrrCpUrrBY1!gs)Tmf3:emf3:eh#IBS
6092 ec5XLhZ*TUrr;uuec5XLhZ*TUrr;uuh#IBSmf3:eh#IBS!rmlPp=0;.!;]\qJ,~>
6093 s!WEuJH16$JH1B(s![nIdJjKd!$KM_l$!+hq>^Hp\,ZI.N;is.#Q39TrrCjSrrCULrrCpUrrE&u
6094 rrCULrrCpUrrE&urrC+>rrCjSrr<-#N;rV,"J,Vj<E4P~>
6095 s&FUMJH16$JH1B(rDh8F#eu1sn,DdVLqiccs+n/arrA#X!A+i7s8N)Ss8N)Ls8N)Us8N)us8N)L
6096 s8N)Us8N)us8N)>s8N)Ss8N'#s,$dLg'!iEqc-XH~>
6097 s*'"oJH16$JH1B(s*+KCdJjJ6!.!l,b9$_uq>^Hp\,ZI.N;inl5M6#9!8RVS!7h,L!8dbU!<3#u
6098 !7h,L!8dbU!<3#u!6>->!8RVS!!<1Ps7XtGOT>5X<Ib~>
6099 s!WEuJH16$JH1B(s![nIdJj7i!7UrI!r;m"q>^Hp\,ZI.NW0(P!%-@urrCjSrrCULrrCpUrrE&u
6100 rrD$X!M!6cs8N)Us8N)us8N)>s8N)Ss8N'#s,@!Og]X2Kqc-XH~>
6101 s&FUMJH16$JH1B(rDh8F!fVs3rr3&rLlD00s+n/arrA&Y!p0Jif`1sOh#IBSec5XLhZ*TUrr;uu
6102 ir9)ZDNjhprrCpUrrE&urrC+>rrCjSrr<-#M?!;'"I]>f<E4P~>
6103 s*'"oJH16$JH1B(s*+KCdJj7N!;lcq!n%&kq>^Hp\,ZI.NW0'L!5[=frrCjSrrCULrrCpUrrE&u
6104 rrD'Y!r>4+p](6nhZ*TUrr;uua8c/>h#IBS!rmlPp=0;.!;]\qJ,~>
6105 s!WEuJH16$JH1B(s![nIdJj8+!7UrI!rDs&q>^Hp"oWf]#u1'krs&1@,6ecSb5VG@!<)rt!<3#u
6106 !"/Em"987M-jBu7QK%rE!;c`q!<<')UAtYls8Gdo/c,MI!"8aQ((Y'Xqf<P\;Yg=lrrE*!&Gq&-
6107 "pm,Ps8N'!rHo4a:%\Gb#536c"qjVPrr;uu$iPGg%qkq>Eu,0]q>UBur/EB:$pV<%s8N'#p.GMb
6108 rrU4@?2X^170&t[s+M$as7H?trr;uurr;uu"oWf]#u1'krs%.7"Y@mu!<3!&p3._c&kpIIrsM6q
6109 TE"qF&HDe'!!r;uqZ$`m"U!T[rsS`3!n@5M!;Tt-(l81k#5jH7#n0&/p&G$l"oWf]#u1'krs&(N
6110 (]t^kq#:<n!!W=K&d_;)rr32U2?bYV!!*#urrE&u#5jH7#n0&/rr;uu!qo7ho`#$]!s*iFs8N'&
6111 rHo4a:%\Gb#4mWf!uktLrr;uu"oWf]#u1'krs%.7"Y@mu!<3#u!<3!&r/EB:$pV;qrsM6qTE"qF
6112 &HDe'!!rT(rrE&urr<6$HkH`[o`"jpfes!bbl@bCrs&1@,6ecSb5VDK70&t[s+M$as7H?tpAb'k
6113 !K@'Pg]X2Kqc-XH~>
6114 s&FUMJH16$JH1B(rDh8F!fi*5rr3&rLl_B3s+gjVZAajTrr2p%osBp>PI1&_s8RoRs8RoSs8Rl^
6115 oUgs>qmi#LNi1Xks8N)qs8N*!rs3-8(]==2(BA"Bs8N',q-FRKL]@$M&.ig[rr;uus8NZ(BH70a
6116 6F-Xk!!)h!#nLbKrr32e?5Nb]?gI^krr<H&?4Rm.s7KM+&9.XJrs&4?,6e`Vh>[HS!!;@=!W2lu
6117 CB2]YrsKD=kl:Z-,6.],!"o51rrE&urr<5u>6tgSrVlg$Xs=-:nGiRgrs%^o(]tU^li-nl&HM%p
6118 s!&`fs6'FppAb!i"7-$mp\t1#pB(Njrr<&h63JU;rr32sFX%)&:u1gErr<5u>6tgSrVlg$k@Y8.
6119 -%l3rs8N'&q-+.9C&S&2#-K3S6Lb$Urr;uurr32sFX%)&:u2-Nrr<,a0`gqH"4dJS\+p"'!!W1&
6120 #nLbKrr32cB+>(kKDtlMrr<5u>6tgSrVlg$Xs=-:nGiRgs8N)urs&4?,6e`Vh=^dU&HM%ps!&`f
6121 s6'Fprr;uurr;uu"o2@/%r)"Ars#VO"@DVY!<3!&l!>2/(glV.rsKD=kl:Z-,6.],!"nr)r;ZkT
6122 s7Y.LRK34b<Ib~>
6123 s*'"oJH16$JH1B(s*+KCdJj7P!;lcq!n%'-q>^Hp"m/,T)3+Xprs$P<&dBV+p\t3m!<)rt!<3#u
6124 !"-=Z!WUnR'`o(Ldc1<,!;c`q!<<')/HATGs7-KsU\b#j!".mX#pHPQf0BW^Q2Ua_!<<'1gJemh
6125 'NNT]rr<&]63S6drr2p%a@m3N,^B(_s8N'+k=#\#YlE<?#oo6/rs%@d)$Cgio)A[h!!9bR!W2lu
6126 .KJc3rsK)4p&G%'KE(tD!(HnerrE&urr<5b63S6drr2p%L_pG+q#CEors$P<&dBV+p\t1##QXPt
6127 rt'h_s.99[pAb!i"0_eDr;Q^(gB%f\rr<&C/-\&drr32[>o<b_BCb`qrr<5b63S6drr2p$eP$5S
6128 18=aIrr<5b63S6drr2p%L_pG+q#CEos8N)urs%@d)$Cgio)A[h!!9bR!VHBoL]I_?q#C?o"m/,T
6129 )3+XprrpqH#RE2[rVult"m/,T)3+Xprs"8r$"3Q/!<3#u!<3!&hd%*&)/&O5rsK)4p&G%'KE(tD
6130 !(HnerrE&urr<5b63S6drr2p%L_pG+q#CEors$P<&dBV+p\t1##QXPtrt'h_s.99[pAb'k!J:@F
6131 eHD!7qGgOG~>
6132 s!WEuJH16$JH1B(s![nIdJjL1&g5Ktl?EAVq>^Hp'UQH-MZ>a:s7e2MUA3:g#/gK@!!)utrrE&u
6133 rr<CVbMrPQ!*A@]flH*PrrDoqrrE*!#l\W?4TEP('_M8%rr<Fo\,)9gAn\[MP5mlIs8N*!s#ko5
6134 =6KM7ErZ.>!11=nMZ>a:s7e2MUA3:g#/gK@!!&CqqNCnkBXdi%!'pSaqa^jPo]JaJ[/^.+!.`8P
6135 qu6_8!42V'$b-1%s8<E8jT"!8+9)<?!<3#u!%=2Gq2554s8VNn%F+EU!!*'!pau`Epspku_uKbH
6136 !'pS_%L_@tg]/Ghs8N)trrSVh49#6qirBqrrr<%Uc1+d7P5kDM"Hi?>8-H<ns8N'0Qb3'O!'(#Y
6137 p_Kk)n;@9'rr;uu&!sp(MZ>a:s6g4&c1,EH!<3#u!<<'0qa^jPo]JaJ[/^.+!.`8PoD\p0!!Aqj
6138 s8N'0Qb3'O!'(#Yp_Kk)n;@9'rr;uu&!sp(MZ>a:s6g4&c1,EH!<3#u!<<')qa^jPo]JaJ[.aM-
6139 \,\eor=04rs4dSrrr;uurr;uu.$qRAMZ>a:s6g4&c1,EH!<<)o/d8!EegUg@s8TS/5l^cm$fq?C
6140 !$Cn6rr<-#N;rV,"J,Vj<E4P~>
6141 s&FUMJH16$JH1B(rDh8F#hb*:nG_pYMV@n+s+hAqlh[c?`;fl4O,`/tif0#os8Rn2rVunRrr<"S
6142 $E<UUs.G1jq#'9XirB#YqZ$Qqs8NB'0`Zn,KE*e+qZ$Qq$X2!P=TGuode6fDNW/tX!<<'^1B<F(
6143 q8u\:rr<%)eau]=JcGc=%L^,M^^:S@s8N'!>13+I!4b2>p/qBTs8Vd5#I4*T)$oI+rr<$gj1tQl
6144 !ZM.,r;R-u!3#qo"pOi&V>s<hs8N)us8N'I?.JRE!.k1Mf)d&Tj@oUSs8VNt$c2_U$4cS*s%EEk
6145 s7up'q>[;l9_JGc!<)p!56-`Crt`3H3<0!Y!)M\:*s1'op)OCCq:->gkk>&V!"WAcoMGU>s8VR:
6146 `r+t-!-S;@rr<R8eau]=JcGc%![$La9`P1ms8N*!rt"fD#I4*T)$oI+rr<$gj1t9d",6d[f(o@G
6147 !"WAcoMGU>s8VR:`r+t-!-S;@rr<R8eau]=JcGc%![$La9`P1ms8N*!rs8<=#I4*T)$oI"rsML#
6148 W;l\u"o81q!)3ClrrE&urr=HQeau]=JcGc%![$La9`P1ns6gF*_>D"T%e0Mu9E;$kq?@-!s/#ci
6149 p&G$l!rn,Wp=]Y<!;fbrJ,~>
6150 s*'"oJH16$JH1B(s*+KCdJjJu!da21bT@JUq>^Hp'Op7h+99^es2"sjfCtpA0DPSI!!)utrrE&u
6151 rr<C;n:(BP!3c+h\2*(DrrDoqrrE*!#kSf2b5XO'D#X;2rr<F4jm42lgem2",663ls8N*!s#h(s
6152 YP.Y!1B7@S!+P-T+99^es2"sjfCtpA0DPSI!!$<dlluMc;<@-h!7UuJfaJqEqmm.XpAb-m!+kYK
6153 qu6^,!;HEk$QfB)s6'k#r;St]\GlO.!<3#u!%;=>kTBlNs8S5_<q4Fj!!*'!_?MOBpRh[Cq#C@9
6154 !8[\=$k<.756/4ds8N)trrO)=eGfI`;?33drr<%6n]_LKn,M&L*m4Ak$R#0:s8N'0@cuqt!7(WE
6155 ^.-iSf.@!@rr;uu%q=_c+99^es,mC`n]cji!<3#u!<<'0faJqEqmm.XpAb-m!+kYKoD\nb!#P,"
6156 s8N'0@cuqt!7(WE^.-iSf.@!@rr;uu%q=_c+99^es,mC`n]cji!<3#u!<<')faJqEqmm.Xp@eLo
6157 *rt-skR7pus$$Lnrr;uurr;uu-t;B'+99^es,mC`n]cji!<<)9"tS="TER"Ds8O/@h>c[I%K-5j
6158 !4__%rr<-#K)bPp"H`]\<E4P~>
6159 s!WEuJH16$JH1B(s![nId/O.42?!RV$_I.nrr<C?s8V`l$NL..!)`aq#2T>&s8N'!rVultrr;uu
6160 !,;H4!XSk+hZ*HQrr;uurr33!3s)W!#grJJrr<F=s8Vcm"_Rf7p&GI!s8N*!rrNK,WVc_q!"*H?
6161 s7H@!s8T2$;?$S3h>e\urr<%2s8Vcm"_Rf7p&GI"s1A>#rr35h!#tt<!!$a/rrO5AlMUYijo?;!
6162 lje8Ms/5otrr;uurr;uu'P[UIo`,@!s-E_$s8V<`!<<)$!)`aq&DdC0s8V3])?9%5G[pcP!*/^l
6163 rrE#t(@hG1o`+r^!,;K5!!$g7s69S"s1A>#rr3&c!#tY3rr<4:s8V`l$Msc(r;['$s8N'0C&e5+
6164 !"/c+QN1h$s60L`rr;uus8N/5!(Hne#O;@/s8N'!C&.f&!!!6!s8N'&C&e5+!"/T&!rW*'rr;uu%
6165 r)(Do`,@!s-E_$s8V<`!<3#u!<<'#]DtD"rrVKd)ts:>jo?;!lje8Ms/5otrr;uurr;uu'P[UIo
6166 `,@!s-E_$s8V<`!<<)$!)`aq&DdC0s8V3])?9%5G[pcP!*/^lrr<-#N;rV,"J,Vj<E4P~>
6167 s&FUMJH16$JH1B(rDh5E!ToXGL]Nb'q#CAM$KhBgon\b1s/Ut0rr32ULogXVLku$0s+p[Ss+g[<
6168 rr3%VM!*XpqZ-WqrrE&u#4rK2f`_u[q>^Hp$c`5HlMq=4s8V?a(B4@6!<<'#!s$OAs8N'+aoDD*
6169 !#5J59E;<rrthd;:B1=o!65'=lMq=4s8V?a(B=DE!2'8j#LEH9s8N'!bk_8?#6=VursQ^E3WIPK
6170 *R=[D!5ng9rrE&urr<bTs8V<`'`\1g!7(WEb5_PBs%EEsrr3P3!)ERo_Z2^sdiBISs#0qqp&G$l
6171 rVmYk!"Su-s"sf"s8N'!cN!ph!&FRa!2'8j!mgp4pAb-m"j-fEkl;ForrVur%K?D-!"[3Os60Lt
6172 s8OhScN!pf!!*#urrE*!!b25&rr35M!'pSa!!(7=s7QEm%Jg&(!!ULEs60LtqYpWm!"Jr-rr<SO
6173 s8V<`'`\1g!7(WEb5_PAs8N*!rrQ[1TDnilci??)rsQ^E3WIPK*R=[D!5ng9rrE&urr<bTs8V<`
6174 '`\1g!7(WEb5_PBs%EEsrr3P3!)ERo_Z2^sdiBISs#0qqp&G$l!rn,Wp=]Y<!;fbrJ,~>
6175 s*'"oJH16$JH1B(s*+KCd/O-<$iU,,2=(&;rr<Djs8Sho;ZHb=!9!kV##>6%s8N'!rVultrr;uu
6176 !:'R`!W`;^hZ*HQrr;uurr32M#SO<B48SdQrr<Gjs8T%u''TAqVuU$#s8N*!rrN3$jSSuW!".uj
6177 s.]Qls8O/@i;W`m:B7Qtrr<&_s8T%u''TAqVuU$$s!Ig"rr34E!2BMn!!)<[rrN<'rVZ['<<0'!
6178 C3^<Srtkaurr;uurr;uu'^>YtUB"3lrtYV"s8Qd5!<<'@!9!kV&5N;/s8Q(!WrHgZ%dO'2!9WtS
6179 rrE#t(7"q\rr<!7!:'Ua!!)<as(_V%s!Ig"rr3%@!2B2err<5es8Sho;YpCpj8_+;s8N'0l2UdY
6180 !)ijs('*Y"s(MH5rr;uus8N-J!87AO#BKm>s8N'!lM:JR!!"bLs8N'&l2UdY!)i[n!os>>rr;uu
6181 &*a,oUB"3lrtYV"s8Qd5!<3#u!<<'#-NMj!rrR6AUA"Tp<<0'!C3^<Srtkaurr;uurr;uu'^>Yt
6182 UB"3lrtYV"s8Qd5!<<'@!9!kV&5N;/s8Q(!WrHgZ%dO'2!9WtSrr<-#K)bPp"H`]\<E4P~>
6183 s!WEuJH16$JH1B(s![nIdJjL8&eVkSj&lJ@q>^Hp$Jtg_rW!$"s"j`&rr33!!!`K'!!)utrrE&u
6184 rr<&Nrr3.<!!+g;h;SD6!;c`q!<)p#n.Pm+UA4cg!"7Z`s8DuuhZ*WT!!<0"rrE*!"`+/>0p:Al
6185 s8N'+hZ*WT!!<3#1]Yo%rtkM3#64]'!8dbUrVurTs8W&u!rr9b!5AI4#Q4W+s8N'!fD5FJ!s&8s
6186 rsSZ)#QMUobTd'D!RLcFrrE&urr<bis8W&u!rr9J!8IPRqZ$Wrs"j`&rr3Q+!!`K'q>pp%_(a(W
6187 s"jc&p&G$lr;RL_!*T@#'aFC3rr<&Rs8Vrr"ogde^Ae-6r;[#ps8N'&hZ*WT!!<0"!i7pfrVup!
6188 rr;uu&)R?drW!$"s!Ig$s8Vrr!<3#u!<<'#56/Fsrs/K&"onT&!8%&Hp&G'sq>^Hp"lB:ZrW!$!
6189 rrT#X%fQG.!WN-!!"[rds8E!"s8OGHg].<N!!*#urrE*!!^?\!rr3&u!!W)r$i0o0s1pD5,6'J#
6190 ci3tE!<3#u!#4;is8E!"s8OGHg].<N!!*'!1]Yo%rt,#,#64`"!XJbA0[(a@1]bqqs8N'#s,@!O
6191 g]X2Kqc-XH~>
6192 s&FUMJH16$JH1B(rDh8F#igf4li-4?MW=O4s+h$Zs8W(SM?!U9M#.,N#5X.9s8Rn2rVunRrr<"S
6193 !;lcq"dt1&X4$e%s8N)qs8N)trrh!Y"pN]Ts8N',p](9k!!)cns82j"rr;uus8N6J!!,cbnG`If
6194 !"/K#s82j!s8NN.o`"k,oDf@#rr<&ns8Vus!;HNnqu?m"rso,!rr36"!"8i,!!)`grrE-#qu7&r
6195 !=o-9H?rNi%0?,#s8N)us8N'5p](9k!!E9$$39i#s7QEms8NN.o`"k%oDf@#s7?=%s'C"t;u[:-
6196 o_&7a!;uj3/-*-Yq?7<+s8N'!p](9e!"/`:!:^!f!r;m)pAb-m$hs]$qu?j!s8@a*$2so)!WN-!
6197 !"\i(s82j!s8NE+p](9e!!*#urrE*!!Y5;#rr36"!"8i,!!)`gs7QEm%Jg&(!"8Q$s82j!s8W%R
6198 /IDCV!!3*!rr<T(s8Vus"98B.!;HNnp&G*ls8N*!rrN]2nG`Fhq>^osrsSH"%f]j]H;jhQ!VHBk
6199 rrE&urr<c-s8Vus"98B.!;HNnp&G*mrs\u#rr3Q%!"Ju.oDoI%?@$orrs]#$p&G$l!rn,Wp=]Y<
6200 !;fbrJ,~>
6201 s*'"oJH16$JH1B(s*+KCdJjK/!a=X\]b(q@q>^Hp$N0r(nc0*urrrK"rr32K!&X`U!!)utrrE&u
6202 rr<&rrr3-5!!-W4q;MAR!;c`q!<)p#U&tK2nG*%`!"8`)s7--ir;Zff!"f/0rrE*!"V:Y7A?G\,
6203 s8N'+r;Zff!"Ao-"p"N!rtiu]2#mRU!;ulsnc/[fs8VWi&HDb8!;QQn#O)4=s8N'!qt^6m!<E#s
6204 $dSi5s!GuD]Di':qYpNp!<3#u!#5A2s7--us8N6&qu?]M!!*'!"p"N!rt*KV2#mU%!BC*+bqH^/
6205 "p4Yos8N)srrs,:irA<H0`M+P!"&Q&s4RH$rs&Q!rr3&a!%[dCrr<H)s8VWi%0-A%E$GSd!!!-#
6206 s8N'0r;Zff!"Ao-"T\H"s4RGQrr;uus8N-*!;QQn#O)4=s8N'!qt^9c!!"bLs8N',r;Zff!"Ao-
6207 pM_>]rVup#rr;uu&,cJ-nc0*urriE"s8UdQ!<3#u!<<'##6=PurrVEb/,&uNcN-$*-I"3UrrrQ$
6208 rr;uurr;uu'`A"2nc0*urriE"s8UdQ!<<''!;c]p&C1>5s8UCG3<(>M0>%5g!rDTirr<-#K)bPp
6209 "H`]\<E4P~>
6210 s!WEuJH16$JH1B(s![nIdJj8K!2BJm!qcO#q>^HprVults8N-,!;ZTn"TSW(rr<&ts8N)us8N'!
6211 qu6U"q0=%^!!@T-s8N)qs8N)srrRiR)u'C4!<)rt!<)rt!<3#u!<<'+q0=%^!!@TJrr<&ts8N*!
6212 rrNK,q>L<s!!<3#!!)utrrE#trrE*!%1*":!s/K'!!3-"!!)olrrO5Al21Je>6)35I..F9!"8c*
6213 rrE&urrE#trrE*!!X&N"rr;uus8N-,!;ZTn!<<3#rs;m0\Q!tG#kn<,o`+pkr;Quf!"Jtm!%S!J
6214 rr<&qrr3?+!WNH+!s8T*!!!&ns8N)ts8N*!rs,t40A$.%!!*#urrE#trrE*!!X&N"rr;uurr;uu
6215 s8NN7!!<<)!<<*#s8N'!qsj[g_>j\3q>^HprVults8N>4!&)t%rr<&us8N)ts8N*!rrN<'qYpNp
6216 !<3#u!<<')#lk&0!W`9$!VQI!>6)35I..F9!"8c*rrE&urrE#trrE*!!X&N"rr;uus8N-,!;ZTn
6217 !<<3#rs;m0\Q!tG#kn<,o`+pk!rn5Zp=oeB!;fbrJ,~>
6218 s&FUMJH16$JH1B(rDh8F!g8B3rr3&lLm%T6s+pXRs+p^T!JuX1rrn48s8Rn2rVunRrr<"SrVm)s
6219 [?-3#Mq[1jrrDoqrrDus!\FC=p](6nrVultrVultrr;uus8NGp@1iP?#-\(,!!)utrrE*!!WrH%
6220 rr33%!!E9$!!)utrrE#trrE*!%0?M3!s/K'!!3-"!!*#orrNH+qYU:!('*b:hVJh2!#GP5rrE&u
6221 rrE#trrE*!$ipA-s8W&u!<<'$!<2ut!r`0%rr39?!:CQXh@T&S(A.Y,!;uj$d/Y-cb5c8Us8N'0
6222 rr<#t!!3*$!!<<)!<<*#pAb-mrVults8N=9!,1HmrVurts8N)ts8N*!rs&Q)rr<#t!!*#urrE*!%
6223 0?M3!s/K'!!3-"!!*#grr\#V#1iVMrrE#trrE*!#A*sLjSo,Y!<3#u!<)rt!<<'(!<E-!s8Duur
6224 r;uus8N?+!!<<)!<<*#p&>=6!:CQXh@T&S(B+:5!<3#u!<)rt!<<'-!<E-!s8Duus8N0$rr2p!r
6225 W!'"rs9G@mM+O7&FBH5o`+pk!rn,Wp=]Y<!;fbrJ,~>
6226 s*'"oJH16$JH1B(s*+KCdJj7T!;6?k!hfTqq>^HprVults8N*#!<)p%p]([$rr<&urrW0"!<3#u
6227 !<)p%cV4ZF!#OSQs8N)qs8N)srrNl7U%eTe!<)rt!<)rt!<3#u!<<'+cV4ZF!#OSnrr<&ts8N*!
6228 rrE-#rVm)s!"/c+!!)utrrE#trrE*!$ip>1!s/K'!!E9$!!)fo!X&N%qu6s1!;HojHpY.>>Q+U%
6229 !<3#u!<)rt!<<'"!<E-!#5S<"s8N*"rVlro!"/`*#n$b.$LiF0ZN+5%s8N)srs!fMAH-->`;]f:
6230 !<3!,q>^^!!<<3(!W`9$"8;cp!<)rt!<<'(/-(k#s7lWprr;uurVults8N*#!<3!"q>^Nps8N*!
6231 rsSo.!s8T*!!!-$rr<&grrYjn([q2"rrE#trrE*!#:ok<mJlt^!<3#u!<)rt!<<'"!<E-!!r;ls
6232 rr;uus8N?*!!<<)!<<*%p&>=+!;HojHpY.>>Q+U%!<3#u!<)rt!<<'"!<E-!#5S<"s8N*"rVlro
6233 !"/`*#n$b.$LiF0ZN+5%s8N'#s+::EeHD!7qGgOG~>
6234 s!WEuJH16$JH1B(s![nIdJj7V!;?El!r`0$q>^HprVults8N-V!7:`F%/Kr.s8NH,o)Jaf!!*#u
6235 rrDoq"5eV/#3,[_!;c`q!<)p#eGp6`G52+;!<)rt!<)rt!<3#u!;uj%hgb\2s8N'!rVults8N-V
6236 !7:`F#5S<(s8N'!rVultrVults8N-U!7^iErrDio!cS.Dqu6u>!(I(\rY1=l-N3uE!<3#u!<)rt
6237 !<<'--NMp$s8)crs8OkTd/O%Hq>^a!rs?OB7K`2['TE)>o`+pkqu6h3!.h9QV#LDo!"%E[s8)d"
6238 s"XT(nGiLgrVults8N<I!8IPRq#CEos8N)ts8N*!rs'nOg].<N!!*#urrE*!!\sc*q>^Hpnc&^Z
6239 !s*fEs8N)ts8N*!rs'\Ig].<L!!*#urrE#trrE*!#:BN+s8Vrr!<3#u!<<'#1'#hmrs?OB7K`2[
6240 'TE)>rVultrr;uurVults8NKT!8IPRqZ$Wrs"aZ%rr3&r!!`H&$,Q[3"7c@)N;t<ts8N'#s,@!O
6241 g]X2Kqc-XH~>
6242 s&FUMJH16$JH1B(rDh8F!f;a4rr3'!Ll(s-s+pXRs+p^T!fi*5rr3E'LlVN8M2;02s8.V.rr<"S
6243 qYpZ^[>9k&s8N)qs8N)trrehl.KR!Qs8N)ts8N)ts8N)us8N)srs-kY!"Ju.!!)utrrE*!!Y#/%
6244 rr32p!"Ju.!!)utrrE#trrE*!!Xo)%q>^Hpq#:C7!:9U_$!mV7"oS9%UB"X!s8N)us8N)ts8N*!
6245 rsT57p](9e!!*'!%06&"rrVfm%K?A6?3%,3r;6_n!+,<trrDrr"WdZp70)TOs8N'*p](9f!"/`7
6246 !;5j]rrE#trrE*!#7(>(s8VWi!<3#u!<)rt!<<'($39i#s7QEmrr;uus8N-/!;60frrDTh"4dJS
6247 [eTn&!<)rt!<<'(#QXW!s7--irr;uurVults8N<2!;HNnp&G*ls8N*!rrNT/p$_ne?3%,3r;6_n
6248 !+,X(rrE&urrE#trrE*!$jm"/s8Vcm!<<'.!;-9j!qZI%rr3:2!3QM'qurhq?M+9t!!<1Ws7Y.L
6249 RK34b<Ib~>
6250 s*'"oJH16$JH1B(s*+KCdJj4K!<)p!o`,Ers8N)ts8N*!rrNB)qYpL'ci>p&rrN3"s8UpU!<3#u
6251 !;ld!rkC8i2<+Z9!;c`q!<)p#=9&j5j7rZS!<)rt!<)rt!<3#u!<)p'rkC8i2?3[V!<)rt!<<'#
6252 "p"N!rs$gM2#mRU!<)rt!<)rt!<<'#"p"Prs8N)orrNW0p\Xss-30kWrp^(U!5e^7rrE&urrE#t
6253 rrE*!$j?Y.s8UdQ!<<''!;c]p!mgp(rr39O!2UG0nH2#V_Y!m.!;ld"%05f:!;6?krr<B&s8UgR
6254 -iXANqsaXc!<)rt!<<'("9AB"s2G$=rr;uurVults8N<-!;lfrg&M-Ps8N*!rrNB)qt^9l!:g'k
6255 L]I_>q#C?orVults8N<,!;uls`W-#<s8N)ts8N*!rs&]-qu?]M!!*#urrE*!!X8Z%n,E\@!2UG0
6256 nH2#V_YsN7!<3#u!<)rt!<<'-"T\H"s4RGQs8N9'qYpKrci>p%rs:"PV%s"""$ck'o`+pk!rmlP
6257 p=0;.!;]\qJ,~>
6258 s!WEuJH16$JH1B(s![nIdJj8H!2KPn!qZI"q>^HprVults8N/%!)`aq%,V%,s8PssV>pSZ!!*#u
6259 rrDlp"9&9$ro=%Y!;c`q!<3!&ne)2g,Qt[Rs8N)ts8N)ts8N)us8N)rrs&H&!WN*!!<)rt!<<'#
6260 X8l,srs%?\+92?@!<)rt!<)rt!<<'#\,\tns8N)orrU7A>PnF,lMq8(s8S#_!+Z!-rrE&urrE#t
6261 rrE*!%$gm0s8V?a!<<)#!)`aq!oEu"rr3;j!"'><s,70_A+]d&#ls_trrhE`(*j@fs8N'*D#aP$
6262 !#>OD!(HDWrrE#trrE*!#8$sss8UmT!<3#u!<)rt!<<'(Q2kb$s69Rarr;uus8N/1!(H_`rrDQg
6263 !Lm-as8N)ts8N*!rs',9jT#89!!*#urrE#trrE*!#F5@+s8V?a!<3#u!<<'#\,\tdrs@uk$5*=<
6264 N!B>mrVultrr;uurVults8NLn!,V]8l2Uhas/Z2trr3&W!$D4?$0qQu&c_li#689+rr`W.pPf.G
6265 g]X2Kqc-XH~>
6266 s&FUMJH16$JH1B(rDh8F!g/<3rr3&kLlqN5s+pXRs+p^T!iq.2rr3D\Lo^RUObi]1s5f&mrr<"S
6267 q>UNpLl(-krrDoqrrE&u#2fXpmg09bq>^HprVultrVultrr;uuqu6lt!!<3#!!)utrrE*!!_WNt
6268 rr32,!)3Fm!!)utrrE#trrE*!!aPenq>^Hpq#:D3!6tE@$.&Yl-NF)m&cg;Ws8N)us8N)ts8N*!
6269 rsUU^ci=$i!!*'!9)u3qrrTD)9`G%uci>%4s8ODY!7:B<!WrH$r;Qo6!&Fp$rVult$.&YOc2]U!
6270 >l^8]s8N)ts8N*!rs&Z,q>^Jn!!*#urrE#trrE*!#;H5)s8U=D!<3#u!<<'#>l^8fs8N)hrrW1;
6271 P5#"V!<)rt!<<'("9A8ts/5ntrr;uurVults8N<Y!71]Fbl@bCs8N*!rrQI+R.(%]ci>%4s8ODY
6272 !7:]ErrE&urrE#trrE*!$o%b.s8U=D!<<'l!3lJ&!jDYurr3;O!$!?cs!A?Yd.I>@!s&:Vs7Y.L
6273 RK34b<Ib~>
6274 s*'"oJH16$JH1B(s*+KCdJj7T!;6?k!hTHlq>^HprVults8N-B!9!kV$rI#,s8NE+p&G&)!!*#u
6275 rrDlp!poslirB#YqZ$Qqrr32$!]eX2+SPX2rrE#trrE#trrE&urrDrr#42Bps8N'!rVults8N-B
6276 !9!kV##PB&s8N'!rVultrVults8N-H!7^iErrDio!\499qu6t4!"Y(hrt,J9li$k`!<3#u!<)rt
6277 !<<'-'`dS"s(VN6s8O/@i;W`X;#m`trs<08%upVh&I/=%o`"pm!;ld!@fV8eC]4;5!"%uks(h\%
6278 s!7ZpnGiLgrVults8N<*!<)rt8cSkjs8N)ts8N*!rs'8=li7!"!!*#urrE*!![Rirq>^Hpnc&[e
6279 6-K$&rrE#trrE*!#6Fo(s8P[k!<3#u!<)rt!<<'('`dS"s(VN6rr;uus8N-H!7^K;$"ErGNW9"j
6280 #6=)gs8N)us8N)ts8N*!rsTVBli7!"!!*'!*rt6urrQ$tXoA>,@fR%!s8NZ9!:0:W"9AN&K)bPp
6281 "H`]\<E4P~>
6282 s!WEuJH16$JH1B(s![nIdJjL/!YW<Gj&lCsq>^HprVults8N`,.KuUCf..'@s8U=D+m\;u!!*#u
6283 rrE#t"tQY?r4)eCirB#YqZ$Qqs8NB':&n`&fDlEKqZ$QqrVultrVultrr;uus8NEVW:'So!#GV7
6284 !!)utrrE*!%/;:UU\WLl#/L9=!!)utrrE#trrE*!%/a!)D;5!X]3G=8!!)fo!qZI=qu7!##66^_
6285 s3q#Li;N]U!<3#u!<)rt!<<'3mKX6JnnJ.)s8VjD"f(nF.gEfgrsAT.!&srXe,TO-o`##,!/CIM
6286 rrYpp!(Hkdrr<Rccgk3>NrT#T!c?]in@Mous8N)ts8N*!rs+_f5P*`"!!*#urrE#trrE*!#OVg,
6287 cgkfN!<3#u!<<'-r)*T5g\gQQ>Q=^'!9F1[!<)rt!<<'(P5mi=hF%>Drr;uurVults8N>l#7f)N
6288 C&e85s8N*!rs8O#!c?]in@MotrsAT.!&srXe,TO-rVultrr;uurVults8N`"#7f)NC&e86s7e&I
6289 U\WLl#/L6<$2b#.2uip-!!2$Mrrd!8L5c0+g]X2Kqc-XH~>
6290 s&FUMJH16$JH1B(rDh8F#hOm'li-4>LtMP's+pXRs+p^T').EGj8J"tNq`SR`/(Vol`u>&rr<"S
6291 rVm)&i;3>rLnNc-rrDoqrrE*!#l5G>ZN$Ep,5_6:rrE#trrE#trrE&urrE*!$;.u(pQkk:s8N'!
6292 rVults8NMp$k'rL_@$h@s8N'!rVultrVults8NN%-j5RnrTL:Js8N'!q#:EY!*f@#$2=Q%OT5?A
6293 !!;ros8N)us8N)ts8N*!rt<i`+m.l^!!*'!m0jB>qn`^Mmf*4mp]:GWs8S,[!r2Ef!ZV3Wr;Qp!
6294 '*&$/rVult%oDEN+Tg3opF$0)kPaVF62(?Y!<)rt!<<'(490p.a@Q@3rr;uurVults8N>S![6^f
6295 :B1Cos8N*!rs\WM"HM[Dkc7#Lrr<&[s8N)ts8N*!rs(XdJGR>Y!!*#urrE#trrE*!#Lrl!k2fA=
6296 !<3#u!<<')pF$0)kPaVF61t6ap]:GWs8S,[!r2`orrE&urrE#trrE*!'%I%,k2fA=!<<)d$k'rL
6297 _@$h@rr3<"!W\>^s,R-]q"4Rh*!!j4s7Y.LRK34b<Ib~>
6298 s*'"oJH16$JH1B(s*+KCdJjJc!FFmb]b(>'q>^HprVults8N_H"Y87$UBN4Ds8P%YNr-DQ!!*#u
6299 rrE#t#%l*UmpQ3IirB#YqZ$Qqs8NAg$NT/c:&nJsqZ$QqrVultrVultrr;uus8NF<bkgd:!.k1M
6300 !!)utrrE*!%)2rrf_M9G/GT8F!!)utrrE#trrE*!%,;C(VssT?QmVk5!!)fo!hB>+qu6u\!<CXL
6301 s#0o_r;HZq!<3#u!<)rt!<<'3NWE;RcA2H#s8Th;/(jZm"YBHJrs@Ta!7_&K2ZO*\o`"t%!8[SQ
6302 "SrE)!8IJPrr<RGo$7dNmf2&R%]AgnhO#Y`s8N)ts8N*!rs'DAY55)U!!*#urrE#trrE*!#EAgf
6303 o$3$k!<3#u!<<'-g^jsnnGD(0-NF)G!9F1[!<)rt!<<'()$$i9W/L]Vrr;uurVults8N=a!Eo!=
6304 L]@GSs8N*!rs7Bk%]AgnhO#Y_rs@Ta!7_&K2ZO*\rVultrr;uurVults8N^l!Eo!=L]@GTs1\^f
6305 f_M9G/GT5E$/bgaeGoP-!!iGorr`c2h1G\#eHD!7qGgOG~>
6306 s!WEuJH16$JH1B(s![nId/O=%<YtoH2OF4=rrE#trrE&u#530_"V=;Hrr36&N>Md^irB)Ys8N)t
6307 rs%.g*!-dQh;\J7!;c`q!<<')SH'9$s8QI,./NuD!<)rt!<)rt!<3#u!<<'+fk)3*'3*ffrr<&t
6308 s8N)urs&1>+U&ELa8Z,=!<)rt!<)rt!<3!+rh2Rg!YnD/s8N'!p\t;F#Q+Du#B9a+s8VZj%K-8+
6309 !<3#u!<)rt!<3!&f/3[]b5_PArs&1>+U&ELa8GrBE<).$s764"oD\s^;A0'2rVluO!!:pRs8N'%
6310 q-+(>L&V)Wrh2Rg!YnD/pAb-mrVults8N?#C_6k;hZ*ZUs8N)ts8N)urs%(4"=qXq!<3#u!<3!+
6311 rh2Rg!YnD/s8N'!jT#5[rVults8N?#C_6k;hZ*ZUs8N)ts8N)urs%(4"=qXq!<3#u!<3!'rh2Rg
6312 !YnD/o`#/9!0R<]o)K6ts8N)us8N)ts8N)urs%(4"=qXq!<3!&p2qM^&5("@rs*NDOoPIQ!"JQ"
6313 "Rf5%N;rV,"J,Vj<E4P~>
6314 s&FUMJH16$JH1B(rDh5E#2Q5=Ll\Ljq#CAMrVunRrr32pZ]^0.Zh==t#QD8pN3W;:M#RGSM#I>X
6315 iNA9!Q+?eOs8N)qs8N*!rs2a-.0'>H+95aEs8N)ts8N)ts8N)us8N*!rsHM=&cs"dp](6n!<)rt
6316 !<3!&k?Jc)(1$2(s8N)ts8N)ts8N)ursS^\1^jL.?GlgC!!)cn!\Ou^qu6m@!9O7\jT$:us8N)u
6317 s8N)ts8N)urs#MK"$c8T!<3!&k?Jc)(1$2&rs'MDjo>AB!$(V1"P5gG!<E)u".0&kp\k-l!!MdT
6318 "!alGrs/FX1^jL.?GlL:rrE#trrE*!#P:h!$X*6)!<3#u!<)rt!<3!&X!7^2n,NIfs8N)ursS^\
6319 1^jL.?GlgC!!)*[rrE#trrE*!#P:h!$X*6)!<3#u!<)rt!<3!&X!7^2n,NIfs8N)urs/FX1^jL.
6320 ?GlF8#93a*s8V0\*;oj:!<3#u!<)rt!<3!&X!7^2n,NIfrs%Xk('>=Xl2:Pd*!#+#s5a5#oD\sF
6321 4q*;Jp=]Y<!;fbrJ,~>
6322 s*'"oJH16$JH1B(s*+KCd/O<:2@BU(<nR3IrrE#trrE&u#/s1G"X8-`rr35r9aD;Squ?`rs8N)t
6323 rs#;c$j7r1r8RbV!;c`q!<<'),QMc_s8!3*T_e]g!<)rt!<)rt!<3#u!<<'+V*PLm-\M?srr<&t
6324 s8N)urs$G7&-X8$pAY*l!<)rt!<)rt!<3!+mW0f`#:ONGs8N'!p\t7.48Ss^%06#"s,d;$r;Zcs
6325 rr;uurVultrr31V('e+?!!*#u#/s1G"X8-`r;R!2!;$6jOT9Cmrrf>U#6=i'rrY:^&H)M,rr<2E
6326 .KhW\rr35kF"%D#-u[o7s8N)ts8N*!rs.(8"Vc4Z!!*#urrE#trrE&u#)*ft>kn@"rr;uurr3Ao
6327 F"%D#-u[o@rr<&[s8N)ts8N*!rs.(8"Vc4Z!!*#urrE#trrE&u#)*ft>kn@"rr;uurr35kF"%D#
6328 -u[o5rs&u5oDeiQ!-.r:rrE&urrE#trrE&u#)*ft>kn@"rr32A8e;.MG4tk6#7U\)s8S2]EV'25
6329 W\=[0s7XtGOT>5X<Ib~>
6330 s!WEuJH16$JH1B(s![nIJcC<$rVlrh"`gUB!ndPlr;ZcsJcC<$rr3"Xs7Y4NScJXf<Ib~>
6331 s&FUMJH16$JH1B(rDeFKJcG]K!o<t&WW*$l!'gD]rr@WMJcG`L!K$jMg'!iEqc-XH~>
6332 s*'"oJH16$JH1B(s*+KCJcC<$rVlqf!U?Za!^$IXr;ZcsJcC<$rr3"Ns7XtGOT>5X<Ib~>
6333 s!WEuJH16$JH1B(s![nIJcC<$r;Qf)&ukm4`;kAbs8N(Ms+14LrrJ)Yp=oeB!;fbrJ,~>
6334 s&FUMJH16$JH1B(rDeFKJcGZJ!Ga0arrQ^2eboII!.k0$s8N$!M?!;'"I]>f<E4P~>
6335 s*'"oJH16$JH1B(s*+KCJcC<$r;QdMH`@#H-iiZ4s8N(Ms+14LrrI`Op=0;.!;]\qJ,~>
6336 s!WEuJH16$JH1B(s![nIJcC<$U]1Df9cj33rr@WMJcG`L!K@'Pg]X2Kqc-XH~>
6337 s&FUMJH16$JH1B(rDeFKJcDMF!pL@kqu?ZrJcC<$rr3"Us7Y.LRK34b<Ib~>
6338 s*'"oJH16$JH1B(s*+KCJcC<$U]1DH$'Y8drr@WMJcG`L!J:@FeHD!7qGgOG~>
6339 s!WEuJH16$JH1B(s![nIJcC<$[f?+&q#:Er"#T$7s8N)hs7cSFs7$'`!5JR/!;uitN;rV,"J,Vj
6340 <E4P~>
6341 s&FUMJH16$JH1B(rDeFKJcE1Yp]1*h!rrO!q"t*k!:g*a!.k1>s7cT/s7cTlrrIuVp=]Y<!;fbr
6342 J,~>
6343 s*'"oJH16$JH1B(s*+KCJcC<$[f?+&q#:Er$uGk=s8N)hs7cSFs7$'`!5JR/!;uitK)bPp"H`]\
6344 <E4P~>
6345 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6346 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6347 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6348 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6349 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6350 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6351 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6352 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6353 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6354 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6355 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6356 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6357 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6358 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6359 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6360 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6361 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6362 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6363 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6364 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6365 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6366 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6367 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6368 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6369 s!WEuJH16$JH1B(s![nI_#OE7S,`Kg_>ac<KdI!(rr<&.s8N(Qs8N).s8N)<s8N)frs/IU-3aJM
6370 !!*#urrDrr!K@'Pg]X2Kqc-XH~>
6371 s&FUMJH16$JH1B(rDgZ5s+m0ErrBn8#Pi*R!s&?$!4W".!/:IQ!4W".!6,!<!:Tpmq.^iN!<3$!
6372 rr;uuqu6\Rs7Y.LRK34b<Ib~>
6373 s*'"oJH16$JH1B(s*+KC_#OE7S,`Kg_>ac#<"o?5rr<&.s8N(Qs8N).s8N)<s8N)frs.R`'EJ46
6374 !!*#urrDrr!J:@FeHD!7qGgOG~>
6375 s!WEuJH16$JH1B(s![nId/O<b:DX-A0o#K'rrBP.rrDusrrDKerrD]krrCFG#GV9)p&G$l!:Tsf
6376 !6bEB!<<''hfUFS#VLh4s8N'"#4qio"8`Q.!:Kme!<3!$ka4mC!;?Hm!6kKC!;-<k!:Bgd!!*;q
6377 rr3)t%KHM#s8N)frs,;!?1n6t!!*#urrDrr!K@'Pg]X2Kqc-XH~>
6378 s&FUMJH16$JH1B(rDh5E#1TK1M3"L^q#CAM\,ZI.r;Zcsmf3:eo`+pkd/O>D!202grr<&fs8N)B
6379 s8N*!rs$MR+9N'7T</(m!!*K*rr3)n"98Gis8N)urrgu12ZWpPs8N)Cs8N)ks8N)ds8N'"$iL#(
6380 "8)cs!;$6j!:Tpm9)tX]s8N'!rr;uuqu6\Rs7Y.LRK34b<Ib~>
6381 s*'"oJH16$JH1B(s*+KCd/O<*1(+4$:;6N'rrBP.rrDusrrDKerrD]krrCFG#9El`rr;uu!:Tsf
6382 !6bEB!<<''YYl5='M?*@s8N'"0)kkM"4dMR!:Kme!<3!$aET'5!;?Hm!6kKC!;-<k!:Bgd!!+_O
6383 rr3)O!WW5ls8N)frs'SF`;]f:!!*#urrDrr!J:@FeHD!7qGgOG~>
6384 s!WEuJH16$JH1B(s![nIdJjKd!$KM_l$!+hq>^Hp\,ZI.r;Zcsmf3:eo`+pkd/O.f!:K.PrrC+>
6385 #:#;_qri8)4K\Y_!!$=(rrC[M!:Kme!<3!$(iI4k!;?Hm!6kKC!;-<k!:Bgc!!$=(rrC[M!;$6j
6386 !:Tph*<>O's8N)rrrJ)Yp=oeB!;fbrJ,~>
6387 s&FUMJH16$JH1B(rDh8F#eu1sn,DdVLqiccs+n/arrDusrrDKerrD]krrCFG!XA`&lMpkaa8ZB,
6388 U?2@.:&oL?s8Duu^]+65RJm3Ss8N)urrag$eGoUCs8N)Cs8N)ks8N)ds8Duu^]+65RJm3Xs8N)f
6389 rrNE*qt^9l!;lcsM?!;'"I]>f<E4P~>
6390 s*'"oJH16$JH1B(s*+KCdJjJ6!.!l,b9$_uq>^Hp\,ZI.r;Zcsmf3:eo`+pkd/O.M!<29`rrC+>
6391 #?8%tqoU#]^TIP8!!)-[rr>:_!:Kme!<3!$4-AY*!;?Hm!6kKC!;-<k!:Bgc!!)-[rr>:_!;$6j
6392 !:Tph"9AGss8N)rrrI`Op=0;.!;]\qJ,~>
6393 s!WEuJH16$JH1B(s![nIdJj7i!7UrI!r;m"q>^Hp\,ZI.r;Zcsmf3:eo`+pkd/X+Gl2Ub`_Z']7
6394 !!KG(rr<'U&cVe4=p=s,mf3:equ?ZrpAb-mbl@\Co`+pkmJm1d!Ab>errZF/!!)WjrrDNfrrDio
6395 rrDrr!K@'Pg]X2Kqc-XH~>
6396 s&FUMJH16$JH1B(rDh8F!fVs3rr3&rLlD00s+n/arrDusrrDKerrD]krrCFGrrD<`rrBq9!qcO!
6397 XoJD$!=^FUrrX#G!!)HerrDrrrrDcmrrC:CrrD]krrDHdrr<'/-iX,J((C6DoDegjn,NCfq#C?o
6398 qu6\Rs7Y.LRK34b<Ib~>
6399 s*'"oJH16$JH1B(s*+KCdJj7N!;lcq!n%&kq>^Hp\,ZI.r;Zcsmf3:eo`+pkd/X+Gl2Ub`_Z'\f
6400 !$89Brr<'(J,]HM$8___mf3:equ?ZrpAb-mbl@\Co`+pkmJm1d!="&QrrWTb!!)WjrrDNfrrDio
6401 rrDrr!J:@FeHD!7qGgOG~>
6402 s!WEuJH16$JH1B(s![nIdJj8+!7UrI!rDs&q>^Hp"oWf]#u1'krs&1@,6ecSb5VG@!<)rt!<3#u
6403 !"/Em"987M-jBu7QK%rE!;uls!<)rt!!N+)#T/Bsrs%.7"Y@mu!<3!(o8"4c)eo*Is8)frrs&C\
6404 0F8.P\bZ78ol2#U*f'dqp3._c&kpIIs8N'(rHo4a:%\JcqZ$]t!!*#u#1YR7/C"4qqZ$Ems8N;s
6405 G9[;)9Zm22rrE#trrE*!&,Ur,"pm,Ps8W"V0F8.P\bZ:*!;c]sqZ$j!s8N',[email protected](CF(9
6406 rr33#NA(YI5Ipdnrr<6$HkH`[o`"mj!<)rt!;ZX!p3._c&kpIIs8N'&rHo4a:%\8]rr<>A!NZ7k
6407 !%7gIrVm)qG9[;)9ZmA7#2(m</Bn.pqu?ZrpAb-mqZ$Qq"SlC1(l7harrE#trrE&urr<2t?O.L)
6408 rr32U2?bYV!!*#u#kNih!uktLs8Vrrs8N<$NA(YI5IpUirr<>A!NZ7k!%7gIrVm)nL_p45C&%]-
6409 rrE*!%dk2;V>pSnNA(YI5IpgoqZ$]t!!*#urrE&u"T465N;rV,"J,Vj<E4P~>
6410 s&FUMJH16$JH1B(rDh8F!fi*5rr3&rLl_B3s+gjVZAajTrr2p%osBp>PI1&_s8RoRs8RoSs8Rl^
6411 oUgs>qmi#LNi1Xks8N)ss8N)ts8N'%nNm@)Y5\G*Xs=-:nGiRgrs7e#%L"/2rr<#q!<<''pN7\b
6412 &Q%<Zrsn-o'Eg"bs8V=i(]tU^li-qa!!i=(#nLbKs8Vrr!ri6#rr32$,6U@(!!)lqqZ-Zr#3fG2
6413 !uPD2q>^HprVults8NW'BH70a6F-XkpN7\b&Q%<Zs8N)qrrVlo$iU,*!"8U/%iC*%oiVh;E;ok:
6414 #5<6b"qa\frr;uu"o2@/%r)"As8N)ts8N)prs%^o(]tU^li-qa!!W1&#nLbKq>^Hp#\3u%s53lg
6415 !!)ut#3fG2!uPD2rr32*,QpI(!!)orrrDcmrrDoqrr<2l63JU;o`+pkrVultrr;uu"S"e]-*I7I
6416 #-K3S6Lb$Urr38eB+>(kKDtoNqZ-Zr#5<6b"qa\fq>^Hp#\3u%s53lg!!)ut#3TV/"XSg#rr;uu
6417 s8NSX"prl\s7^X\"qa\fs8Vrr!ri6#rr;uurr3,qFX)bCp=]Y<!;fbrJ,~>
6418 s*'"oJH16$JH1B(s*+KCdJj7P!;lcq!n%'-q>^Hp"m/,T)3+Xprs$P<&dBV+p\t3m!<)rt!<3#u
6419 !"-=Z!WUnR'`o(Ldc1<,!;uls!<)rt!!LLs"uk67rs"8r$"3Q/!<3!%eP$5S18=dJqZ-Zr#2`](
6420 ";tkCq>UrC7h#\fbQ%U`9G.OTGk_4;rr<;d63S6drr<#q!!<0#!<3!&JeeZ#q#CEks8)frrs$P<
6421 &dBV+p\Fjh!<)rt!<<'0gJemh'NNT]s5.*"";tkCq>^HpqYpWL!&"6Mrr<Dh70t-As49LB*0pL&
6422 #2`](";tkCrr;uu"m/,T)3+Xps8N)ts8N)prs$P<&dBV+p\t3m!!VLO"W<=!q>^Hp#Uf`Is,I)r
6423 !!)ut#09IN"seHfrr31Y(^XUG!!)orrrDcmrrDoqrr<2G/-\&do`+pkrVultrr;uu"O&D$2qe31
6424 #)F*&@/0d&rr3/P9F(nZUAk2i!<<''hd%*&)/&O9s8N')-is&ANW?or!<)p$eP$5S18=aIrrE*!%
6425 \NnKn,NFF>o<b_BCc*&qZ$]t!!*#urrE&u"Q*K&K)bPp"H`]\<E4P~>
6426 s!WEuJH16$JH1B(s![nIdJjL1&g5Ktl?EAVq>^Hp'UQH-MZ>a:s7e2MUA3:g#/gK@!!)utrrE&u
6427 rr<CVbMrPQ!*A@]flH*PrrDusrrE#trr<mmc1+d7P5jtV%F+EU!!*'!p_Kk)n;@9'rr;uurVm0#
6428 8-G(Ik=>`_qu7T0.Kl%.l@K!1/d8!EegUg@s8N'!Qb3'O!''uXrrE#trrE*!#OM^+d.2&S!;ZZp
6429 !<)p'pau`Epspku_tsE5!<)rt!<<'1JH/d7r7Q,jqa^jPo]JaJ[/0h&!;lcul[]+YrVult+IKY7
6430 P5o3.\,)9g5l^l]8-G(Ik=>`_s8N'!Qb3'O!''uXrrE#trrDoq')4'_UA3:g#/gK@!!&@tq2554
6431 q>^Hp#kJ$Es0D]k!!*#u&bms^UA3:g#/gK0#S#&KB)hr/s8N)ms8N)qs8N'&M9YQj!L!-UrrE#t
6432 rrE&urr<mmc1+d7P5jtV%F+EU!!*'!p_Kk)n;@9'rr;uurVm0#8-G(Ik=>`_qZ$Qq#kJ$Es0D]k
6433 !!*#u#P](6q=':B2#dOT!#,D(.0QIHs8,=iOn@g-"LS4/!!)utrrE&urrE*!"oCgnOc9>6g]X2K
6434 qc-XH~>
6435 s&FUMJH16$JH1B(rDh8F#hb*:nG_pYMV@n+s+hAqlh[c?`;fl4O,`/tif0#os8Rn2rVunRrr<"S
6436 $E<UUs.G1jq#'9XirB#Yr;ZcsrVult(f05R*s1'of)d&Tj@oUSs8VR:`r+t-!-S;@rrE#t#kf8D
6437 Z2)of#jD0c)X\"?[.rEas6gF*_>D"T%e0Mu!!$<ToMGU>rr;uurVults8N>P![?dh;ucpos8N)t
6438 rs8''$c2_U$4cS%s8N)ts8N*!rt$sdNUZbd<<)Y4#I4*T)$oI&s8N)rrr_1["K24urr=0Fde6fD
6439 \NA75=TFH]s7RH<Z2)of#jD<g!!$<ToMGU>rr;uurVultqYq2s%L^,M^^:S@s8N'!?.JRE!.jtG
6440 rr<>d!+c+-!9F1\rr3T!%L^,M^^:S@s47;ojQ'#8!;lfr!;?Hm!;c`q!!Q0Zj<"HTp&G$lrVult
6441 rr;uu(f05R*s1'of)d&Tj@oUSs8VR:`r+t-!-S;@rrE#t#kf8DZ2)of#jD-brr<>d!+c+-!9F1\
6442 rr35m.)u2I@/tHLs8N'4s5F@keGoRB*=&kFeJSYVs8N'!rVultrr;uus8N8r*=&j+s7Y.LRK34b
6443 <Ib~>
6444 s*'"oJH16$JH1B(s*+KCdJjJu!da21bT@JUq>^Hp'Op7h+99^es2"sjfCtpA0DPSI!!)utrrE&u
6445 rr<C;n:(BP!3c+h\2*(DrrDusrrE#trr<mNn]_LKn,JOO<q4Fj!!*'!^.-iSf.@!@rr;uurVm/V
6446 $m*Rg\dKYSqu7SK"sV7fb;oU>"tS="TER"Ds8N'!@cuqt!7(TDrrE#trrE*!#DrOco$E9p!;ZZp
6447 !<)p'_?MOBpRh[Cq"k$j!<)rt!<<'1'`bH2oscdWfaJqEqmm.XpA4gh!;uj"rQlf"g\q0P!$GS/
6448 lluMc;<@-h!7UuJfaJqEqmm.XpAb-m!+P-T+99^ds8N)ts8N)qrt<0Q/(aNg"Y]ZNrr<%.kNF#g
6449 cM@M?!!nkj^],GWo)Jdirt3*P/(aNg"Y]ZNOo\VRc%l?"qu?ZrpAb-mqZ$Qq"`!SP%1)Fqs8N)t
6450 s8N)us8N'9C@TOX#k.eV!ESa8L]@GTs1UtVr7<M#`;]f:!<)p'faJqEqmm.XpA4gh!!nkj^],GW
6451 o)Jdirs-8-gAKPS!6"m:rr<`4ZNVQ@s8Ua\*m4Ak$R#0Crr<&ts8N)us8N*!rrq'a*m0*7p=0;.
6452 !;]\qJ,~>
6453 s!WEuJH16$JH1B(s![nId/O.42?!RV$_I.nrr<C?s8V`l$NL..!)`aq#2T>&s8N'!rVultrr;uu
6454 !,;H4!XSk+hZ*TUr;ZcsrVult%Vu+El2VV"QN1h$s60L`qYpWq!!`H&rrE#t!k\M%rr3&c!#th8
6455 !ic5rr;Qi#!)`aq%,Lt,s8N'!C&e5+!"/`*rrE#trrE*!#F#4,s8VBb!;ZZp!<)p!XT25trrV$W
6456 +Su-<!<)rt!<<'##lpt&rrTh57K3;glMqn#s8N)ts8E!!#a"uarr<UBs8Vcm"_Rf7p&GI"s1A>#
6457 rr3Dm!#tt<!!$a5s7H@!rr;uurVultqYpW!!)`aq%,Lt,s8N'!C&e5+!"/Q%rr<?);Zu>($NC)+
6458 rr3&%!)`aq$f1k+s-E_$s8V<`!;lfr!;lfh!<<*!!!R0<s69S"p&G$lrVultrr;uu%Vu+El2VV"
6459 QN1h$s60L`qYpWq!!`H&rrE#t!k\M%rr3&c!#te7rr<?);Zu>($NC)+q>UNp!!`H&rr</r3<Z)U
6460 rrTh57K3;klMqn(rr<&ts8N)us8N*!rrp%87K8>Hp=oeB!;fbrJ,~>
6461 s&FUMJH16$JH1B(rDh5E!ToXGL]Nb'q#CAM$KhBgon\b1s/Ut0rr32ULogXVLku$0s+p[Ss+g[<
6462 rr3%VM!*XprrDusrrE#trr<PSs8U=D1B0*0cN!pf!!)lq!r2g*rr;uurVlq/!2'8j!mgp4qu6^g
6463 !3?%t!_`Turr3D/!)ERo!!(.@s60Ltrr;uurVults8N<W!7CiHci=(As8N)trrPjoYl=Y(XT2,m
6464 s8N)ts8N*!rrN9&bP_AA@fW/#rrUOI5l1N\!<)rs!!*bHr;Zcs&B=bMlMq=4s8V?a(B=DE!2'8j%
6465 +"u>s8N'!aoDD*!#5G4rrE#trrDoq!_`Turr3D/!)ERo!!(.@s60Ltq>^Hp#lbSFo`l32!!*#u!
6466 _`Turr3A.!)EPL!7(WEb5_P>s8N)rs7HBls8N'&cN!ph!&F6IrrE#trrE&urr<PSs8U=D1B0*0c
6467 N!pf!!)lq!r2g*rr;uurVlq/!2'8j!mgp4qZ$Qq#lbSFo`l32!!)ip!r2g*rr;uu"76^,e,K@K@
6468 fW/#rs$gM5l^ia!<)rt!<3#u!<<'&@fW/$M?!;'"I]>f<E4P~>
6469 s*'"oJH16$JH1B(s*+KCd/O-<$iU,,2=(&;rr<Djs8Sho;ZHb=!9!kV##>6%s8N'!rVultrr;uu
6470 !:'R`!W`;^hZ*TUr;ZcsrVult%dO)oCB0b%('*Y"s(MH5qYpWX!&jiVrrE#t![e!$rr3%@!2BAj
6471 !Zh?ur;Qg?!9!kV$r6l+s8N'!l2UdY!)igrrrE#trrE*!#8I7*s8Qs:!;ZZp!<)p!*rt6urrPsr
6472 Y581u!<)rt!<<'#!<D3YrrOPJg&D!QEr_s2s8N)ts8E!!/*6^/rr<Vos8T%u''TAqVuU$$s!Ig"
6473 rr3CJ!2BMn!!)9`s.]Qlrr;uurVultqYpU=!9!kV$r6l+s8N'!l2UdY!)iXmrr<?)$7+^8<;upu
6474 rr3$A!9!kV$Vpc*rtYV"s8Qd5!;lfr!;lfh!<<*!!!VZfs(_V%p&G$lrVultrr;uu%dO)oCB0b%
6475 ('*Y"s(MH5qYpWX!&jiVrrE#t![e!$rr3%@!2B>irr<?)$7+^8<;upuq>UNW!&jiVrr</>#U&R7
6476 rrOPJg&D!UEr_s7rr<&ts8N)us8N*!rrjbMg&H[(p=0;.!;]\qJ,~>
6477 s!WEuJH16$JH1B(s![nIdJjL8&eVkSj&lJ@q>^Hp$Jtg_rW!$"s"j`&rr33!!!`K'!!)utrrE&u
6478 rr<&Nrr3.<!!+g;h;SD6!;uls!<)rt!"Rc`s8)d"s!Ig$s8Vrr!<3!"V)f+c!!!'!s8N)trrPCb
6479 ^Ae-6r;[#urrOeQdes+H1]Yo%rs\`(#64]'!8dbUrW!$!s8N)ts8N*!rs'kNh#IEP!!)iprrE#t
6480 !]0o(rr3&r!!`<"rrE#trrE*!$>]\C0p:Ams$$Ltrr3&u!!W6!rrDrr"5m>aH2[dC!"e#es8Duu
6481 hZ*WT!!<3#56/Fsrs\i+"onT&!8dbUrW!$!s8N)ts8N)qrrP"Wd/O%Rq>^a"rr<&Us8W&u!r;lr
6482 !!rVP!&Xa5rr<&urrP"Wd/O%Qq>^a"-NMp$s8)crqu?Zrqu?<hs8W*!"l'(WqZ$fms8N)ts8N)u
6483 s8N'/g].<N!!WBM!8IPRqZ$WqrrT#X%fQG.!WN-!!<)p!56/FsrrW-!"oA9!!!rVP!&Xa5rr<&t
6484 rrT#X%fQG.!WN-!!!5aqT`+ll56/Fsrs&E%"onT&!<)rt!<3#u!<<'&56/FtN;rV,"J,Vj<E4P~>
6485 s&FUMJH16$JH1B(rDh8F#igf4li-4?MW=O4s+h$Zs8W(SM?!U9M#.,N#5X.9s8Rn2rVunRrr<"S
6486 !;lcq"dt1&X4$e%s8N)ss8N)ts8N'5p](9e!"/`5!;HNnp&G*ms8@a*$2so)!WN-!!<)p!%fl+u
6487 rrW#s$iBr*$NThsrrNW0o`"k!oDf@#rr<&ns8Vus"9/?#!<)rt!<<'(#ls`"s7ZKnq>^HprVlp.
6488 !;-9j!qZI%qZ$QqrVults8NEO!!,cbnGiM!!:^!f!r;m)qZ$Qqr;Qoud45=*rVult&GQ5)qu?`k
6489 s8Vus"TSK4!:^!f%/Kr3s8N'!p](9k!!E6#rrE#trrDoq!Y#/%rr3E!!"Ju.!!)cns82j!q>^Hp
6490 #lfVZC]K7j!!*#u!Y#/%rr3Au!"Jr8!;HNnp&G*is8N)rs7HBls8N'&p](9e!"/E!rrE#trrE&u
6491 rr<c-s8Vcm$NCG5p](9e!!*'!rJ3$3rVup!rr;uurVlp0!:^!f!r;m)qZ$Qq#lfVZC]K7j!!*#u
6492 "9"$-$2so)!WN-!!!4,GdJa(H%fl+urs&<"$ig5,!<)rt!<3#u!<<'&%fl,!M?!;'"I]>f<E4P~>
6493 s*'"oJH16$JH1B(s*+KCdJjK/!a=X\]b(q@q>^Hp$N0r(nc0*urrrK"rr32K!&X`U!!)utrrE&u
6494 rr<&rrr3-5!!-W4q;MAR!;uls!<)rt!#5>1s4RH$rriE"s8UdQ!<<)nE$GSd!!!-#s8N)trrNE*
6495 q#:9pkl<72rrNB)qY^?p"p"N!rs[3R2#mRU!;ulsnc0*ts8N)ts8N*!rs&]-r;ZfO!!)iprrE#t
6496 !X8Z$rr3&G!&XQPrrE#trrE*!$4m1<A?G\-rs&Q!rr3&a!%[pGrrDus"T#_C%-%6crr<W.s8VWi
6497 !;ulsnc07$rs&Q!rr3Dk!%\*L!!)rss7--urr;uurVultqYpU$!;c]p%*no1s8N'!r;Zff!"A]'
6498 rr<?)1]T<3dJj1Hrr3$(!;c]p$dSf0rriE"s8UdQ!;lfr!;lfh!<<*!!!W9"s4RH$p&G$lrVult
6499 rr;uu'`7q1g&NQ$"T\H"s4RGQs8Vh4,6n,I!!E6#rrE#t!XA`#rr3&a!%[pGrr<?)1]T<3dJj1H
6500 rr3)pE$GSd!!!-#s8N'#$m+g7rrNE*q#:9tkl<76rr<&ts8N)us8N*!rriW-q#>sGp=0;.!;]\q
6501 J,~>
6502 s!WEuJH16$JH1B(s![nIdJj8K!2BJm!qcO#q>^HprVults8N-,!;ZTn"TSW(rr<&ts8N)us8N'!
6503 qu6U"q0=%^!!@T-rrN<'qu-Nq!!3&urr<&qrr3-%!WN9&qYpNp!<<'([K%u4r;Q`srr;uurVm-0
6504 !!<<)!<<*#qu6^$!;ucp!XSl&rVm$$!rr9#!<)rt!<3#u!<)rt!<<'#"9A>us8N)ps8N)trrNK,
6505 q>L<o!!<#srrE#trrE*!&G^Sn!!!+Jrs8Z-!s/K'!!2rrrrDoq!qcO!rVultrVultrVults8NK6
6506 !!<<)!<<*#s8N'!rVultrr;uurVultqYpU'!;ZTn"TSW(rr<&ts8N)ps8N')s7cWq!P8:2!<3!"
6507 #lsf"rriB(rr`>urr;uuqu?ZrpAb-mqZ$Qq!;c]p!<</ns8N)ts8N)us8N'!qYpKu!!3*&!;c]p
6508 rrE*!#IXUcfDPXK!<3#u!<)p'#lk&0!W`9$!W)ir!!rW"!WW84rr<&urs,t40A$.%!!*#urr<*8
6509 !fHsV$jcn9!s/K'!!3-"!!)utrrE&urrE*!"UP/2"-!9Rg]X2Kqc-XH~>
6510 s&FUMJH16$JH1B(rDh8F!g8B3rr3&lLm%T6s+pXRs+p^T!JuX1rrn48s8Rn2rVunRrr<"SrVm)s
6511 [?-3#Mq[1j!W`<#rr3'!!!3&urr<o8s8W&u!WN0#rr<#t!!*'!AcQN*rr)ltrr;uurVm-)!!<<)
6512 !<<*#qu6Zt!;lct!s&?"rs&H&"98B$!<)rt!<3#u!<)rt!<<'(!<E-!s8Duuq>^HprVlp$!<2ut
6513 !r`0%qZ$QqrVults8NZ!@1iP?#-\%.!!<<)!<<*#qZ$QqqYpW]!##81rrE#trrE#trrE*!$j$D2
6514 !s/K'!!3-"!!)utrrE&urrE#trrDoq!WrH%rr33%!!E9$!!)utrrDlprr<?)mf<Chn,E@frr3$%
6515 !<2ut$iU,.rrE-!s8W&u!;lfr!;?Hm!;c`q!!WB%s8E!!p&G$lrVultrr;uu)#jR8rW!!!!<E-!
6516 s8Duus8Q[2B]T0l!!*#urrE#t#Qau.!s/K'!!2rrrr<?)mf<Chn,E@frr348!,1HmrVurts8N'#
6517 "U)L:rsSr/!s8T*!!!'"rr<&ts8N)us8N*!rriH(!s=D[p=]Y<!;fbrJ,~>
6518 s*'"oJH16$JH1B(s*+KCdJj7T!;6?k!hfTqq>^HprVults8N*#!<)p%p]([$rr<&urrW0"!<3#u
6519 !<)p%cV4ZF!#OSQrrE-#rVlrr!!N9#rrE&u"o83&rrE-!rs\`(!<<'M!0ZaLq#CEos8N)trs/W*
6520 !s8T*!!!,urrE-#qu6Zt!<)p%p]([$rr<&ts8N)us8N)ts8N*!rrE-#rr3&r!!)iprrE#t!<E3!
6521 rrVrq$Msf&!<3!5rVurus3FCF!!!hnrrE*%!s/K'!!E)trrDoq!iH#hrVultrVultrVults8NK.
6522 !!<<)!<<*%s8N'!rVultrr;uurr3'!!!)lq!<E3!rs&5u$NL,+!<)rt!;ZZp!!rV9!<<2rrr<&u
6523 rrE-#rVm&r!"/`,!<3!"q>^Nms8N)ms8N)qs8N)urrW#s"nhoq!<3!"rVurts8N)urrr6!"oeT'
6524 rr3E'!!*'!/-(k#s7lWprr;uurVm-(!!<<)!<<*%qZ$Qq#lhI:!!;rq!!*#u#:ok<mJlt^!<3#u
6525 !!366jSf)e!<<3(!W`9$"98B$!<)rt!<3#u!<<'&!<<3(K)bPp"H`]\<E4P~>
6526 s!WEuJH16$JH1B(s![nIdJj7V!;?El!r`0$q>^HprVults8N-V!7:`F%/Kr.s8NH,o)Jaf!!*#u
6527 rrDoq"5eV/#3,Xa.KJ-#rrW&t"o\K$!#XJjs8)d"s!Ig$s8Vrr!<<'B!8IPRq#CEos8N)trrOqU
6528 eFihC0*'GurrOtVd/O%Lq>^a"rr<&ts8N)us8N)ts8N*!rs'hMh>dNQ!!)iprrE#t!]'i'rr3&r
6529 !!`<"#7CP&s8Vus!;uj%hgb\2s"XT(o`+pkq>UHq!WE&u!<)rt!<)rt!<<'#1'#i"s8N)ts8N)u
6530 rs&o3o)Jaf!!)lq!]'i'rr33!!!`K'!!)utrrDlprrE*!#'U%Xs8N'!rr3$U!7:`F$i0i-s!Ig$
6531 s8Vrr!;lfr!;?Hm!;c`q!!V-Ws8)d"p&>7)!:p0iqu?`rs8N'9g].<N!!WBM!8IPRqZ$WrruhBs
6532 s8Vlp!<3#u!<)p!1'#hrs8N*!rs!ZI&-)Y0!<3!'+TU9ss7lWprr;uu"6L:!MZ3VW1'#i"s8N)t
6533 s8N)us8N*!rrk.XeGkL-p=oeB!;fbrJ,~>
6534 s&FUMJH16$JH1B(rDh8F!f;a4rr3'!Ll(s-s+pXRs+p^T!fi*5rr3E'LlVN8M2;02s8.V.rr<"S
6535 qYpZ^[>9k&rrNN-pAY'np&GL!s8N'9p](9f!"/`5!;HNnp&G*mrs/W!s8VWi!<3#u!<)p!$iotn
6536 rrNT/o_e^j%06&"rs&)q%KHG.!<)rt!<3#u!<)rt!<<'(#ls`"s7ZKnq>^HprVlp.!;-9j!qZI%
6537 qYpd&!;ulspAb3krs-kY!"Jr:!;6!arrDoq!r`0$rVultrVultrVults8N-/!;60frrE#trrE&u
6538 #6Ou(s8Vfn!;c]s%06&"rs&)q%KHG.!<)rt!;ZZp!<<''+93Sbrr<&urrNW0o`"juoDf@#$39i#
6539 s7QEmqu?ZrpAb-mqZ$Qq"o&&spAbQnrs&W+r;Zfk!!*#urr<o1s8Vfn$NCG5p](9e!!*'!#QXW!
6540 s7--irr;uurVlp-!;6!arrE*!"s<mhs8N'!rr33/!;HNnnc/[hs8N'$_$'tSrr3$.!;60frrE#t
6541 rrE&urrE*!"UkD(s,$dLg'!iEqc-XH~>
6542 s*'"oJH16$JH1B(s*+KCdJj4K!<)p!o`,Ers8N)ts8N*!rrNB)qYpL'ci>p&rrN3"s8UpU!<3#u
6543 !;ld!rkC8i2<+W;"T\H!rrUdP/,fMJ!#YV5s4[N$rriE"s8UdQ!<<'%!;uls`W-#<s8N)trrNB)
6544 qt9sj"p"MtrrNB)qYpL!ci>p&rr<&ts8N)us8N)ts8N*!rs&]-r;ZfP!!)iprrE#t!X8Z$rr3&H
6545 !&XQP#6Fo)s8UpU!<)p'rkC8i2?*j\qt0pg!;c]sp](Tus8N)ts8N)ts8N*!rrNB)qt^9l!<)rt
6546 !<3!'!W`6"s5!_UqYpU$!;c]p#1*?,s8N'!rVultq>^Hps8N96!-eJC!!*#u!X8Z$rr3AQ!&X]Z
6547 !;lfrg&M-Ms8N)ms8N)qs8N'&qu?]N!%7I>#6Fo)s8UpU!<3#u!#YV5s4[N$rriE"s8UdQ!<<'%
6548 !;uls`W-#<s8N)trrNB)qt0pg!<<''%fghRrr<&urs&Z,r;Zf:!!*#urr<.]!taPmrrNB)qt^9l
6549 !<)rt!<3#u!<<'&"p"Q#K)bPp"H`]\<E4P~>
6550 s!WEuJH16$JH1B(s![nIdJj8H!2KPn!qZI"q>^HprVults8N/%!)`aq%,V%,s8PssV>pSZ!!*#u
6551 rrDlp"9&9$ro="[S,d@(rrVHc)#aL7!#TPPs6BY"s-<Y$s8V?a!<<'2!9F1[h#IHSrrNK,p\t0o
6552 \,\tjrrT5$;#L=pX8l,srs%?\+92?@!<)rt!<3#u!<)rt!<<'(P5oV&s6K^cq>UL&!;HKm!iuB!
6553 rr3&W!$D(;#>tPus8V9_!;ld#rVuuu\,\tis8N)qrrVcl$iU,*!<)rt!<)rt!<<'#\,\tns8N)t
6554 s8N)urs)F%V>pSZ!!)lq!iuB!rr32[!$D7@!!)utrrDlprrE*!#2B2Is8N'!rr3&$!)`aq$f:q+
6555 s-<Y$s8V?a!;lfr!;?Hm!;c`q!!R3=s6BY"p&>7p!2]_qkPtV^s8N'9D#aP$!#>O"!,V]8l2Uha
6556 rt,7ls8UmT!<3!"#ls`!rrT\17J-W[!<<''g]0eCrr<&urs',9jT#89!!*#urr<B*jq7`Qs8TS/
6557 7JZu`!<)rt!<3#u!<<'&\,\ttN;rV,"J,Vj<E4P~>
6558 s&FUMJH16$JH1B(rDh8F!g/<3rr3&kLlqN5s+pXRs+p^T!iq.2rr3D\Lo^RUObi]1s5f&mrr<"S
6559 q>UNpLl(-k!]U2*rr3&F!''rWrr<n^s8U@E1&is.ci=$i!!*'!"9A8ts/5ntrr3$%!<)os!aPen
6560 p&>(b!3H+u!_WNtrr32,!)3Fm!!)utrrE&urrE#trrE*!#;6)+s8UIH!;ZWr!s&<!rrPgnYl=Y(
6561 YQ.Anrs'5<lMpn)!!)or#5\B%s'5Vlo`+pkqYpWW!#PV6rrE#trrE#trrE*!!aPenq>^HprVult
6562 rr33;!:'Ua`rH,9rrPgnYl=Y,YQ.Asrr<&ts8N)ps8N*!rs#A$VuQbs!<3!"9)u3qrsQ%29`HgI
6563 ci=$i!!)orrrDcmrrDoqrr<5Ks8U@E1%kPO'EIFus2P*>rr;uu(si6^c2]U!0`]Q"s31NDs8N3%
6564 q>^Jn!!*#u!WrH$rr3%*!1<EYrrE*!#,_I!s8N'!rr33+!;ZZpVuQhss8N'*s1ed@]`8";!1<T^
6565 rrE#trrE&urrE*!"^M+qs,$dLg'!iEqc-XH~>
6566 s*'"oJH16$JH1B(s*+KCdJj7T!;6?k!hTHlq>^HprVults8N-B!9!kV$rI#,s8NE+p&G&)!!*#u
6567 rrDlp!poslir9&s!:'R`!c%e+rVult)!h5%C]Kh%'`dS"s(VN6s8N-#rVumi!!*#u!<E3!rrOJH
6568 eFihC*WY'prrO8Bi;W`\;#m`urr<&ts8N)us8N)ts8N*!rs'5<m/R*(!!)ip!<E3!rrO8Bi;W`X
6569 ;#m`prs&l2p&G&)!!)or#42Bps!7Zpo`+pkqYpVb!+,X(rrE#trrE#trrE*!![Rirq>^HprVult
6570 rr331!;6BlB)hr.rrO8Bi;W`\;#m`urr<&ts8N)ps8N*!rrtmlh#IBS!<3!"*rt6ursM[(XoB+9
6571 li7!"!!)orrrDcmrrDoqrr<5gs8Qm8QhC@`$39c!s(;<3rr;uu)!h5%C]Kh%'`dS"s(VN6s8N-#
6572 rVumi!!*#u!<E3!rrOJHeF`e@!<<''70)-Crr<&urs&T*rVumi!!*#urr<B*N<0[Ps8OAFeG9.E
6573 !<)rt!<3#u!<<'&,llHpK)bPp"H`]\<E4P~>
6574 s!WEuJH16$JH1B(s![nIdJjL/!YW<Gj&lCsq>^HprVults8N`,.KuUCf..'@s8U=D+m\;u!!*#u
6575 rrE#t"tQY?r4)eCir9;T'b%\Nj%TWPrVult(l6N/=TOQ_mKX6JnnJ.)s8S8_5P*`"!!*#u%VPis
6576 rVuoq;?C^ir:%=&qu7B*.Kl(1l[f*2.KuUCf..'@s8N'!rVultrr;uurVults8N>k"V9#PDu]n6
6577 rsi]BLAh/PpaQHBq:@,$_#"'LblApQk?e2hs8OUJmejTq(B=;1!c?]in@Mp$s8N*!rs(6`nbpp0
6578 !IOeFrrE#trrE#trrE*!%/a!)D;5!X]3G=8!!)utrrE&u#L*5llfVUT!;c^(paQHBq:@,$_#OE7
6579 !<)rt!;ZZp!;c`q!<3!1paQHBq:@,$_#Ng-%aX]\!!)orrrDcmrrDoqrr<@]cgk3>NrT+Z!;ZX"
6580 blApQk?e2hrr;uu(l6N/=TOQ_mKX6JnnJ.)s8S8_5P*`"!!*#u%VPisrVuoq;?C^ir:%=&qZ$Qq
6581 qZ$Qqrr34e!'g)36i[5ds8N*!rt4?*!fI$U;?C^ir:%=&s8N'!rVultrr;uus8N9#;?C]os7Y4N
6582 ScJXf<Ib~>
6583 s&FUMJH16$JH1B(rDh8F#hOm'li-4>LtMP's+pXRs+p^T').EGj8J"tNq`SR`/(Vol`u>&rr<"S
6584 rVm)&i;3>rLnNc-#iGk+df%T6"l]F[rr<m4k2mfgec4/$+m.l^!!*'!490p.a@Q@3rr3$>!5ea8
6585 #ko_MNp$B)X$QX_'^cA9[JJ]es6U4&_Y_1X%IX8r!!)utrrE&urrE#trrE*!#LWZ"kN>hF!;ZWr
6586 *!!kTrs8!#$c;eX$OuP#ru-Fg<;+gE!!*'!9"aikQN/lBpF$0)kPaVF62LW]!<<'(;T/;*_B8ol
6587 rVultrVultrVults8NN%-j5RnrTL:Js8N'!rVultrr34S!*&[A=TAHurs\9'$c;eX$OuP(rr<&t
6588 s8N)ps8N)qs8N)urt4W,$c;eX$OuP(eH-oVj\GjVqu?ZrpAb-mqZ$Qq#uKdH+Tg3orr<&prs+)T
6589 <;+gE!!*#urr<m4k2mfgec4/$+m.l^!!*'!490p.a@Q@3rr3$>!5ea8#ko_MNp$B)X$QU^rrDoq
6590 rrE&u#<W!:qT)5.!<3#u!<<'2^'+YPs7[oENp$B)X$Qdc!!)utrrE&urrE*!"nsDJNf!f0g'!iE
6591 qc-XH~>
6592 s*'"oJH16$JH1B(s*+KCdJjJc!FFmb]b(>'q>^HprVults8N_H"Y87$UBN4Ds8P%YNr-DQ!!*#u
6593 rrE#t#%l*UmpQ3Iir9:\"&7hQ\I95DrVult(i8ch%L;G%NWE;RcA2H#s8Nr:Y55)U!!*#u!Y#.c
6594 rr38Z&.YW-qqd\equ7AE"s_@hbW5^<"Y87$UBN4Ds8N'!rVultrr;uurVults8N=]!F><EMuWkR
6595 rrNW0h>[E[^BH.?q4e*Eq"k"/2uo!9\s36qs8Q]TqX7hmJcFL:%]AgnhO#Yds8N*!rs*JjqXgft
6596 #NYj`rrE#trrE#trrE*!%,;C(VssT?QmVk5!!)utrrE&u#<2^Dqmr$m!;c^(^BH.?q4e*Eq#C?o
6597 !<)rt!;ZZp!;c`q!<3!1^BH.?q4e*Eq#??T=n9jo!!)orrrDcmrrDoqrr<@Ao$7dNmf3:e!;ZX"
6598 2uo!9\s36qrr;uu(i8ch%L;G%NWE;RcA2H#s8Nr:Y55)U!!*#u!Y#.crr38Z&.YW-qqd\eqZ$Qq
6599 qZ$Qqrr33@!3Z0sMuWkWs8N*!rt11k&ENlH&.YW-qqd\es8N'!rVultrr;uus8N8X&.YUis7XtG
6600 OT>5X<Ib~>
6601 s!WEuJH16$JH1B(s![nId/O=%<YtoH2OF4=rrE#trrE&u#530_"V=;Hrr36&N>Md^irB)Ys8N)t
6602 rs%.g*!-dQh;SA<mq3XD%RIH!s8N'%q-+(>L&V)`f/3[]b5_PBs8$OD#!q,H!<3!.mnsf"!<<)u
6603 Tg0.j'hkY(rsn[<)?M%;s8Ve8+U&ELa8Z,=!<)rt!<3#u!<)rt!<3!&e2.:Zbl@e?rseEp'*/+5
6604 s7URY"V=;Hq>VB4N>Md^irB)Zs4M!(!Y\Phs8W(l5S*u39WIshrrE*!#2!H+!>%Ppr;ZcsrVult
6605 rVultrr3B*Tg0.j'hkY-rr<&ts8N)urs/O_(^*%_!!)ip#530_"V=;Hrr;uurVultq>^HpqZ$Qq
6606 rVm)qFWgo"9#pr2#1k^8/'@nmrr;coq>^HpqZ$Qq$2Id1(5;egqZ%!!rs/O_(^*%_!!*#urr<2t
6607 >6bptrr3P]2$>GQ!!*'!qJ6`J6/MYBrr3Js;A0'2s8W(l5S*u39WIshrrDoqrrE&u#Pr6K#!q,H
6608 !<3#u!<3!0j:DBMs8J]W&-<S?WrN)!!<)rt!<3#u!<3!$rh2T9s7Y4NScJXf<Ib~>
6609 s&FUMJH16$JH1B(rDh5E#2Q5=Ll\Ljq#CAMrVunRrr32pZ]^0.Zh==t#QD8pN3W;:M#RGSM#I>X
6610 iNA9!Q+?eNrs$tM'EStGeboII!!MdT"!alGrt)4U"$c8T!<<)k:^IM4p](<nrsmXE$ipA.s8.X0
6611 $j7VX_tsBCjAulp0;njMk?Jc)(1$2(s8N)ts8N)us8N)ts8N)urs#AF"@;MW!r;j*f00TD!<<)^
6612 >S[DW?0V1b)Z=@[#Zpg%!<<)6;A'$MC%qZ-qh[-<"<LmeqZ$Qqs8N;:;%`mF;9&P6rrE#trrE#t
6613 rrE&u$i>c;$j7VX_uK`:!<)rt!<3!'rFl`I=8;grq>UZ^>S[DW?0V@grrE#trrDlprrDoqrrE#t
6614 #3T5,!u>2,rr32',6L1"!!*#uq#L6jrrDoqrr<Ap4p*%1s8Vcm(A[t8rFl`I=8;grrr;uu"RnSW
6615 ,HLhD&?@#X5O\XQs8V^f#n'o2!!*#u%bElQ!<E0"qh[-<"<LmeqZ$QqqZ$Qqrr35q:^IM4p](<n
6616 s8N)urt)gG"MFd3M)5VD*aZbarr<&ts8N)us8N)urri4U1l;8+g'!iEqc-XH~>
6617 s*'"oJH16$JH1B(s*+KCd/O<:2@BU(<nR3IrrE#trrE&u#/s1G"X8-`rr35r9aD;Squ?`rs8N)t
6618 rs#;c$j7r1r8IY[Z9\s'*G=j=s8N'%asmNOfDbd]Kbanuq#CEps4'.6'R9NU!<3!.W\=YY!<<)e
6619 F"%D#-u[o;rsln5$3ri>s8U&1&-X8$pAY*l!<)rt!<3#u!<)rt!<3!&JJAGtoDf0mrsbt^#6=i)
6620 s2@SA"X8-`q>VB+9aD;Squ?`ss.r!i"=Jj"s8VM..1$5-Dqt3hrrE*!#,=Hm"!1t6r;ZcsrVult
6621 rVultrr3AoF"%D#-u[o@rr<&ts8N)urs/3k#S;4X!!)ip#/s1G"X8-`rr;uurVultq>^HpqZ$Qq
6622 rVm)@8e;.MG4tq8#)*ft>kn@"rr;coq>^HpqZ$Qq$-F_#2:qm.g&OY=rs/3k#S;4X!!*#urr<2E
6623 .KhW\rr3O`('e+?!!*'!eN*jJGl.OArr3J.0F%UYs8VM..1$5-Dqt3hrrDoqrrE&u#Ltj='R9NU
6624 !<3#u!<3!0M?4@Ms6aqW#mVksh#IBS!<)rt!<3#u!<3!$mW0h/s7XtGOT>5X<Ib~>
6625 s!WEuJH16$JH1B(s![nIJcFp5rrAho!r;m%JcDSHrrDoq!nmaRmf3:eO8f6>s7Y4NScJXf<Ib~>
6626 s&FUMJH16$JH1B(rDeFKkPtP^U]1De!"OS[V>pPqqYpVj"lA\IrrA,[!K$jMg'!iEqc-XH~>
6627 s*'"oJH16$JH1B(s*+KCJcFp5rrAho!mL^*JcDSHrrDoq!^dXlmf3:eO8f64s7XtGOT>5X<Ib~>
6628 s!WEuJH16$JH1B(s![nIJcFp5rrAho!oa1uJcDSHrrDoq!G,[+s8N([rrJ)Yp=oeB!;fbrJ,~>
6629 s&FUMJH16$JH1B(rDeFKkPtP^U]1D)!'Yu6V>pPqqYpR7U@&!\!0@-\M?!;'"I]>f<E4P~>
6630 s*'"oJH16$JH1B(s*+KCJcFp5rrAho!`]5tJcDSHrrDoq!=[WJs8N([rrI`Op=0;.!;]\qJ,~>
6631 s!WEuJH16$JH1B(s![nIJcFp5rrAts"usj)fero(JcDSHrrD-[rrA,[!K@'Pg]X2Kqc-XH~>
6632 s&FUMJH16$JH1B(rDeFKkPtP^VuHs.h#5/$"Q4k2V>pPqjT#5[O8f6;s7Y.LRK34b<Ib~>
6633 s*'"oJH16$JH1B(s*+KCJcFp5rrAts#(Z"8W<Wq(JcDSHrrD-[rrA,[!J:@FeHD!7qGgOG~>
6634 s!WEuJH16$JH1B(s![nIJcFp5rrAts"jKLE"YZL!s.o\p!9F1[!0@-\N;rV,"J,Vj<E4P~>
6635 s&FUMJH16$JH1B(rDeFKkPtP^VuHq$1^47N_L_`_s8N)[s8N([rrIuVp=]Y<!;fbrJ,~>
6636 s*'"oJH16$JH1B(s*+KCJcFp5rrAts"cOc1&5qYAs.o\p!9F1[!0@-\K)bPp"H`]\<E4P~>
6637 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6638 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6639 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6640 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6641 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6642 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6643 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6644 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6645 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6646 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6647 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6648 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6649 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6650 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6651 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6652 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6653 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6654 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6655 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6656 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6657 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6658 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6659 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6660 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6661 s!WEuJH16$JH1B(s![nI_#OE7L&_/QoDegjm/R(c_>jN8oDegjm/R(cn,NCf_>jN8OT5=\YQ"W^
6662 s7Y4NScJXf<Ib~>
6663 s&FUMJH16$JH1B(rDgZ5s+lC/rrDZjrrDEcrrBn8rrDZjrrDEcrrDNfrrBn8rrA/\rrB8&!K$jM
6664 g'!iEqc-XH~>
6665 s*'"oJH16$JH1B(s*+KC_#OE7L&_/QoDegjm/R(c_>jN8oDegjm/R(cn,NCf_>jN8OT5=\YQ"WT
6666 s7XtGOT>5X<Ib~>
6667 s!WEuJH16$JH1B(s![nId/O<b:DX-A0o#K'rrBP.rr<'(oD\alq[NT+gAh0Qs8N;\FXm\&/qs6'
6668 rrDEcrrD]krrCRK%e:#-rr<'!s5.rL#7)r9r;Zcsm/R(cn,NCfdf9=Io)J^iaSuJ%FXm\&/qs'"
6669 #4Q=H"<(k?iW&oXs8N;\FXm\&/qph8!K@'Pg]X2Kqc-XH~>
6670 s&FUMJH16$JH1B(rDh5E#1TK1M3"L^q#CAM\,ZI.!=Si)rr_os!!(aQrrE*!#013r!t@>ar;Zcs
6671 m/R(co`+pkeGg$;(]XL8!<<)>@itj_4.lHNrrDEcrrDNfrrCLIrrDWirrC.?#013r!t@>ap\tHM
6672 ;A03YIf&+(rrE*!#013r!t@>a\GlSds7Y.LRK34b<Ib~>
6673 s*'"oJH16$JH1B(s*+KCd/O<*1(+4$:;6N'rrBP.rr<'Prr2p"ecGgOgAh0Qs8N;-;AK?K9"t6'
6674 rrDEcrrD]krrCRK%ZF]nrr<'!s0,B:!u+AAr;Zcsm/R(cn,NCfdf9=Io)J^iaSuIK;AK?K9"t'"
6675 #.?f-#r8(NiW&oXs8N;-;AK?K9"qh8!J:@FeHD!7qGgOG~>
6676 s!WEuJH16$JH1B(s![nIdJjKd!$KM_l$!+hq>^Hp\,ZF-!+#U(!8%2Mf)Gt"O4jEoGQ9l)s8N)c
6677 s8N)ks8N)KrrKelqu6mGO4jEoGQ9l)s8N)cs8N)5s8N)is8N)?rs'd0g&'uX!'L)W#k8];Y5-m<
6678 )u\Xn#:#;_qri8)4LtImN;rV,"J,Vj<E4P~>
6679 s&FUMJH16$JH1B(rDh8F#eu1sn,DdVLqiccs+n/arVur5rr2tdrW(OL#<\aBrS('IGQ%RA!:9ac
6680 !;-<k!7_#L>`S^]#<\aBrS('IGQ%RA!:9ac!5AL5!:p0i!6G0F4JLs9gJ.`mq>U]U"r,2VaV7+u
6681 rs(Z\jo*q/!-c!R!K$jMg'!iEqc-XH~>
6682 s*'"oJH16$JH1B(s*+KCdJjJ6!.!l,b9$_uq>^Hp\,ZF-!9O4[!'gG_f)GtSZgR_5+991Ts8N)c
6683 s8N)ks8N)KrrFFpqu6n#ZgR_5+991Ts8N)cs8N)5s8N)is8N)?rs)N0meb-L!5J@0#GM;bh>+2[
6684 Hen],<3u#iarg]!\c2\^s7XtGOT>5X<Ib~>
6685 s!WEuJH16$JH1B(s![nIdJj7i!7UrI!r;m"q>^Hp\,ZI.!Ab>errZF/!!(FH!rDs#rVultm/R(c
6686 o`+pkeGfP$^@qR.qZ$cts8N)cs8N)5s8N)is8N):rrW&t"Sr'!M?%_srrVKd@+kP]qZ$c0rrJ)Y
6687 p=oeB!;fbrJ,~>
6688 s&FUMJH16$JH1B(rDh8F!fVs3rr3&rLlD00s+n/arr<'/-iX,J((C6DdJj:@!!rQ'rrDEcrrD]k
6689 rrCUL!rWPspAY3e!!rQ'rrDEcrrBe5rrDWirrBt:!qcO!q>ULJ!7(TD!mUeZg&D-H!!p.8!K$jM
6690 g'!iEqc-XH~>
6691 s*'"oJH16$JH1B(s*+KCdJj7N!;lcq!n%&kq>^Hp\,ZI.!="&QrrWTb!!(FH!n@8lrVultm/R(c
6692 o`+pkec,^F#Pe#m!n@8lrVultm/R(c^An35o)J^i_uBeg!$:t9!YbY#rr3%?!9Di5!n@8l\c2\^
6693 s7XtGOT>5X<Ib~>
6694 s!WEuJH16$JH1B(s![nIdJj8+!7UrI!rDs&q>^Hp"oWf]#u1'krs&1@,6ecSb5VG@!<)rt!<3#u
6695 !"/Em"987M-jBu7QK%rE!!pFBX8h_j-ia8GrsSOE,6ecSb5_,7"nMZm$i:53ec5Q,0F8.P\bZ:*
6696 !;c]sqZ$j!s8N)urs&1@,6ecSb5VDOol2#U*f'dq!!*'!mMQ/(qu?Nns8N;sG9[;)9Zm53(&NS2
6697 "pm,Ps8N'!p.GMfs7L@Q"<N?trrMHsrr;uuqYpWo!!`E%rrE&u#536c"qjVPrr3N%E?56(L]@AS
6698 !<<)e)$Hf/s8N)us8N',[email protected](CF(9rr;uu"SlC1(l81k#536c"qjVPrr;uu"85@is8)fm
6699 rs%.7"Y@mu!<3#u!"8aQ((Y'Xqf<P\;Yg=l#5jH7#n0&/rr;uu"oWf]#u1'ks8N)ts8N)krrW&t
6700 #5S9#)$&t$rrW-!(&@k?o8"4c)eo*Is8.Br"pm,PqZ$QqqYpWo!!`E%rr<H*Hkm6*s8-jR$<$^!
6701 rs&C\0F8.P\c2X/!!W=K&d_;)rr;uurVultli.!Es7Y4NScJXf<Ib~>
6702 s&FUMJH16$JH1B(rDh8F!fi*5rr3&rLl_B3s+gjVZAajTrr2p%osBp>PI1&_s8RoRs8RoSs8Rl^
6703 oUgs>qmi#LNi1Xks8N')A-)#rhuI<g!<)p*l!>2/(glV/kPttfrr3B!!X&,qpN7\b&Q%<Zs8N)q
6704 rrVlo$iU,*!<3!&l!>2/(glV.rt"3p'Eg"bs8N'!s8UOP$.f"RqZ-Zr#3fG2!uPD2qYq<(BH70a
6705 6F-Xk!!)4;!WW2]=qh)kVZ-Srdin_jrrDoq!qlU%rVultrr32e?5Nb]?gI^k&*6t/">-MNrr<'!
6706 s3h/Yf(K(C!<3#u!"8U/%iC*%oiVh;E;ok:rr<2l63JU;rr32e?5Nb]?gI^krr</b0`h=O!;c^"
6707 Xs=-:nGiRgs8N',q-FRKL]@$M&.ig[rr32sFX%)&:u2-Nrr<5u>6tgSrVlis!<)rt!;-9mp&GKr
6708 rrNB)qYpKrq>`/Drt":*%L"/2rr<#lBH70a6F-IfrrDoq!qlU%rVult$i+*>(l/.a=V)-`rr2p%
6709 pN7\b&Q%<_s8N'&q-+.9C&S&2rrE#trrDBb!K$jMg'!iEqc-XH~>
6710 s*'"oJH16$JH1B(s*+KCdJj7P!;lcq!n%'-q>^Hp"m/,T)3+Xprs$P<&dBV+p\t3m!<)rt!<3#u
6711 !"-=Z!WUnR'`o(Ldc1<,!!jtRpA^-Q_>jT7rsQnA&dBV+p]$rf-iX,F$do%bqu>PZ)$Cgio(i=c
6712 !;c]sfDmQ&s8N)urs$P<&dBV+p\t1'`((7A5Kj*,!!*'!TE?G-qu?Nns8N;E9G.OTGk_(7(#)\&
6713 !YeY_s8N'!],h"Qs27D:#=$E2rrI(brr;uuqYpWL!&"6MrrE&u#09IN"seHfrr3MI7h#\fbQ%SB
6714 !<<(l"!d:-s8N)us8N'+k=#\#YlE<?#oo6/s8N'%bU`rWg&D!Ua@m3N,^B(_s8N'$],h"QqZ-Km
6715 #)F*&@/0d&rr;uu$Kjha+gD!u5RAEqrVm)Z>o<b_BCc'%rr<5b63S6drr2rt!<)rt!;-9mfDmQ"
6716 rrN9&rVlful2[7JrrpqH#RE2[rr32W<##HK<RUaDrrDoq!n[K*rVult$Kjha+gD!u5RAEqrVm)Z
6717 >o<b_BCc'%rr<5b63S6drr2rt!<)rt!:0XcK)bPp"H`]\<E4P~>
6718 s!WEuJH16$JH1B(s![nIdJjL1&g5Ktl?EAVq>^Hp'UQH-MZ>a:s7e2MUA3:g#/gK@!!)utrrE&u
6719 rr<CVbMrPQ!*A@]flH*Prr<>r!%@lR!1!Tbrr3E%/d8!EegUg@s)S0Mrr3D]!#bh68-G(Ik=>`_
6720 qZ$Qqqu6caJHBoks8N*!ru(Sa"eteC.0d]ipaQE3oBLo,rr<'!o-jg<q>^HprVm/u/d8!EegUg@
6721 qu7C^!*A@]flI,m!!%PmirAd'"I8TDJc>ZMX%!$frrDrr"7(L>F8c.=!<<':pau`Epspku_uKK]
6722 "I8TDJcG`M!<;X>"Jk\irrE&urr<Fo\,)9gAn\[MP5mlIs8N';M9YQj!L!KX/d8!EegUg@s8N'!
6723 JBQsPrr<&ors.uu%F+EU!!*#urr=1/\,)9gAn\[MP5mlJs8,=iOn@g-"LS4/!!&@tq2554rr;uu
6724 rVultp&>-[JHBogrrNo8li-ncr;[*!rt+r@WVQ%A!&X`UJH/d7r7Q,es8N)rrr_S<!d">?rr=1/
6725 \,)9gAn\[MP5mlJs8,=iOn@g-"LS4/!!&@tq2554rr;uurVultli.!Es7Y4NScJXf<Ib~>
6726 s&FUMJH16$JH1B(rDh8F#hb*:nG_pYMV@n+s+hAqlh[c?`;fl4O,`/tif0#os8Rn2rVunRrr<"S
6727 $E<UUs.G1jq#'9XirB#Y#iu%ss&&jY!!*#u%.=Z6_>D"T%e0K@!6>*=%&<kbs7RH<Z2)of#jD-b
6728 rrDrr"5m2_Vu?Yq!<<':mg]`AqnNOKnGhnb$+0K_@/p6,!<;$c#h8\MrrE#t#k&62_>D"T%e0Aq
6729 'f,iLnG14+s8N'!7cV;amL0E/ptT9VrrGQdrr;uuqu6cV<Wo?!s8N*!ru(88$c2_U$4cS*mL0E/
6730 ptT9Wrr<'!iX,t@o`+pkrr;uu$X2!P=TGuode6fDNW/tX!#eYoj<"HTs6gF*_>D"T%e0Mu!!#LK
6731 _#OE7!;QR!f)d&Tj@oUSrr;uu+Bm4e=TGuode6fDNW9%P*=&kFeJSYVs8N'!?.JRE!.k.LrrE#t
6732 rrD`l"5m2_Vtp>o"T\DurrW#s%f62:n0l<Sk$\74s8OkTNUZbd<;QXp!;lcui)TuYrVult+Bm4e
6733 =TGuode6fDNW9%P*=&kFeJSYVs8N'!?.JRE!.k.LrrE#trrDBb!K$jMg'!iEqc-XH~>
6734 s*'"oJH16$JH1B(s*+KCdJjJu!da21bT@JUq>^Hp'Op7h+99^es2"sjfCtpA0DPSI!!)utrrE&u
6735 rr<C;n:(BP!3c+h\2*(Drr<=j!5JOW!:p0jrr3DD"tS="TER"Drso+nrr3Bo!1s5D$m*Rg\dKYS
6736 qZ$Qqr;Qoucm0+UrVults8NtR"tS="TER"Ds1S[]bPTICs8N'!s0DkQmeQn_!<)p'_?MOBpRh[C
6737 q"t(+'`bH2oscdWrr<%1n:(DO"sV7fb;oS%!?Ktps8N)srri;I,S&T-s8N*!ru&ZX/(aNg"Y]ZN
6738 ^'5e)qo_#"rr<'!ZNVQ@o`+pkrr;uu$XMl\,66Lrjm42le,KCI!#fVBbmasIs2"sjfCtpA0DPSI
6739 !!$U"IfKEJ!;QR!Oo\VRc%l?"rr;uu+C4*q,66Lrjm42le,TI$$m*Rg\dKYSs8N'!@cuqt!7(TD
6740 rrE#trrDcm"T?[m%bpgZ!WrH$rr3&b!'9uV&ACWfr7<M#`;fiP!3c+h\2*p\rrDus"T?[m%bps^
6741 rr=0Ijm42lgem2",663ms4If%b58aX+SPj8!!$KkkTBlNrr;uurVultli.!;s7XtGOT>5X<Ib~>
6742 s!WEuJH16$JH1B(s![nId/O.42?!RV$_I.nrr<C?s8V`l$NL..!)`aq#2T>&s8N'!rVultrr;uu
6743 !,;H4!XSk+hZ*TU#ldg+ko1!0!!*#u!j)H"rr32Z!$M=#!#PY7#'9ics1A>#rr3&c!#te7rrE#t
6744 rVus)OSo.Y!<<'#XT25trs%<[+TJGA:](1l!!E!V"JY\krrE#t!j)H"rr3&V!$M1=!XSk+qu?Zr
6745 !,;H4!ic5rqu6`r)V4ofrrE#trVus)OSo.Y!<<'#XT25trs%<[+TJGA:](1l!!E!V"JYMfrrE&u
6746 rr<F=s8Vcm"_Rf7p&GI!s8N'*C]FG"!#GU:!)`aq#MoG's8N'!C&S)3!;QR!QN1h$s60L`rr;uu
6747 &8(tBp&G8.s8Vcm$NL.=!(Hne%-mm4s8N'!C&e5+!"/`*rrE#trrDfnrVus)OSJhWI/nBgrrVKd
6748 !qlQur;['%rs8\)pAb-mrVuis!=4ebs8N'1B)ho)!!R!7s7QF"s8T_37K3;qlMqn(rr<%5s8V`l
6749 $NC)*!<)rt!:0XcN;rV,"J,Vj<E4P~>
6750 s&FUMJH16$JH1B(rDh5E!ToXGL]Nb'q#CAM$KhBgon\b1s/Ut0rr32ULogXVLku$0s+p[Ss+g[<
6751 rr3%VM!*Xprr<?)'FFF;'`S.5rr3$n!3lJ&#-@l#s0D\_rr30E!7:aU!2'8j!mgp4qZ$QqrVuis
6752 !>E0Es8N*!rrPjoYl=Y,XT2,r8-#^fs8N'$m1K]Rq#C?orVlpm!3lJ&!j)Gtqu6^"!6b9>rr<&C
6753 rr3$j!3?"s!r<5rrr;uurVuis!>E0Es8N*!rrPjoYl=Y,XT2,r8-#^fs8N'$m1K]RoDegjrr;uu
6754 $c`5HlMq=4s8V?a(B4@6!"$sNs31O!s%EEsrr35*!)ERo!!(7As8N)ors(:ZcN!pf!!*#urr<VM
6755 s8VBb$c`5Hl2VV"s'l&$rr3DR!'pSa!!(.@s60Ltrr;uurVultp](3m!>E0ArrODFci3qGcN"+@
6756 rs/?"%KHG1!6b*9rrE#trVus4^&7p1!"d0Ms6BXm`rH)(!#GV7@fW/#rs[6S5l^ia!6P9@kl;Fs
6757 s8N)ts8N)brrIuVp=]Y<!;fbrJ,~>
6758 s*'"oJH16$JH1B(s*+KCd/O-<$iU,,2=(&;rr<Djs8Sho;ZHb=!9!kV##>6%s8N'!rVultrr;uu
6759 !:'R`!W`;^hZ*TU#lb5WjTAK^!!*#u!ZqF#rr30u!3Z?"!13]b"qCY!s!Ig"rr3%@!2B>irrE#t
6760 rVusLjo#/Y!<<'#*rt6urru7!Y5]OChY[?Q!!C.F+R]%)rrE#t!ZqF#rr3$q!3Z5!!W`;^qu?Zr
6761 !:'R`!Zh?uqu6`_%K$/)rrE#trVusLjo#/Y!<<'#*rt6urru7!Y5]OChY[?Q!!C.F+R\k$rrE&u
6762 rr<Gjs8T%u''TAqVuU$#s8N'*lMpm"!1<d.!9!kV#>Y?&s8N'!lM^b_!;QR!('*Y"s(MH5rr;uu
6763 &Es/oW;mRps8T"t>6"UM!87AO%!)ECs8N'!l2UdY!)igrrrE#trrDfnrVusLjnSiW&-2%qrrR9B
6764 &,#r-j8_+<rrE,\pAb-mrVuis!A!:0s8N'1kl:[^!#"Mqs/5p$s8OGHg&D![Er_s7rr<&`s8Sho
6765 ;Z?^r!<)rt!:0XcK)bPp"H`]\<E4P~>
6766 s!WEuJH16$JH1B(s![nIdJjL8&eVkSj&lJ@q>^Hp$Jtg_rW!$"s"j`&rr33!!!`K'!!)utrrE&u
6767 rr<&Nrr3.<!!+g;h;SD6!!rVP!&Xa5rr<&urrP"Wd/O%Vq>^a"r?26js7cX#qYrb[^Ae-6r;[#t
6768 s8N)rrr_1_!dXbErrE*!!]0o(rr33!!!`HU!7LcErr<*m"JGMhrrE#t!]0o(rr3&r!!`?#"`+/>
6769 0p:Als8N'!fDbdO/ca>srrM3rrVultqu6cV=os!Js8N*!rrP"Wd/O%Lq>^a"/ca>ss8N'#8d(gX
6770 s8N)us8N',hZ*WT!!(mUs8E!"rr;uu$/>L[qZ$g"1]Yo%rs/B##64]'!8%2LrrDio#:BN+s8Vrr
6771 !<3#u!"e#es8DuuhZ*WT!!<3#56/Fsrs\i+"onT&!8dbUrW!$!s8N)ts8N*!s8;rprr_1_!dXVA
6772 #jVa'Z2<BE!!;ur!i7pfrW!3)s8Qm8!ATbnq>^Hpqu6cV=os!Js8N'1hZ*WT!!(mUs8E!"s8P:`
6773 ^Ae-@r;[$$rr<&Us8W&u!ri6"!<)rt!:0XcN;rV,"J,Vj<E4P~>
6774 s&FUMJH16$JH1B(rDh8F#igf4li-4?MW=O4s+h$Zs8W(SM?!U9M#.,N#5X.9s8Rn2rVunRrr<"S
6775 !;lcq"dt1&X4$e%s8N')s+UMi!/LRS!<3!"%06&"rt+f&%KH81"82]^!=o,/%fl+urrW#s$i9o'
6776 !;uj"rR!+tZi0q(!<<'#%06&"rs&)q%K?e9o_\[g!!4,GdJ*\@!<)p!%06&"rrVfm%K$//,QIj=
6777 T()aZrr<&mrr3$-!;-0g!PgAes8N)srri;J.g*-Vs8N*!rrNW0o`"jpoDf@#$NThrs8N'#*!js_
6778 s8N)us8N',p](9k!!)cns82j"rr;uu$2=K"p&GI"%06&"rs//r%KHG.!;?BkrrDio#7:J*s8Vcm
6779 !<3#u!"eo)s82isp](9k!!N?%%fl+urs\`($ig5,!;HNnqu?ius8N)ts8N*!s8;rqrri;J.g*-R
6780 rs6gM(<c["(B=R6rr`4U/IDCV#Qau*,QIj=T()RUrrDus"T?^u"1.t+rr<W)s8Vus!;HNnqu?m"
6781 rso,!rr3E'!"8i,!!)cns82j!rr;uurVultli.!Bs7Y.LRK34b<Ib~>
6782 s*'"oJH16$JH1B(s*+KCdJjK/!a=X\]b(q@q>^Hp$N0r(nc0*urrrK"rr32K!&X`U!!)utrrE&u
6783 rr<&rrr3-5!!-W4q;MAR!!rT]!&FW&rr<&urrNB)qYpL+cN#g%lN@Rls0r(ks8N<(q#:9pkl<71
6784 s8N)srri21&e*dus8N*!rrNB)qYpL!cN#g%"p"Mss8N'#$m+g1s8N)trrNB)qYpKrcN#g!rrir6
6785 !G&>.rr;uu!;lcq!X8Z$qu6\#P5YF\!;uj"qR[@Kir/oW!<<'#"p"N!rs$dL2#da[qYU<m!!3QM
6786 mIL;W!<3#u!"8`)s7--ir;Zff!"f/0rr<B&s8UdQ./sJOqYpL"cN#g%rr<&rrVultq#:R&!;lfr
6787 g&M-Ps8N'1r;Zff!!)rss7-.$s8N<(q#::%kl<76rr<&ss8VWi%0$;,!<)rt!<<)t!;uj"qR[@K
6788 iq`T[M#fs"qlp_5%/Tu+pM_>]rW!3+s8NW1!G&>.q>^Hpr;Qor]+PP3rVult&H)S.nc/[fs8VWi
6789 &HDb8!;QQn%-[aBs8N'!r;Zff!"Al,rrE#trrDBb!J:@FeHD!7qGgOG~>
6790 s!WEuJH16$JH1B(s![nIdJj8K!2BJm!qcO#q>^HprVults8N-,!;ZTn"TSW(rr<&ts8N)us8N'!
6791 qu6U"q0=%^!!@T-s8N')s7cWq!P8:2!<3!"#lsf"rtPM8s8T\25l]430E;%Y!!<<)!<<*#qZ$Qq
6792 qYpWi!!rQ'rrE*!!XSl&rVm$$!riE(r;6No!!3l:MYI/N!<)p!#lsf"rrE*$qu7'"Gom"d"+1(J
6793 !!)oqrrN?(r;6KpPumqarrDoq!qcO!rVults8N-,!;ZTn"TSW("T\Jts8N'#'`s9`s8N)us8N)t
6794 s8N)ts8N)us8N'!qYpKu!!3*+!;ZTn"on`)rr<&rrVultq#:Bu!;c]prrE&urrE#trrE#trrE*!
6795 $jcn9!s/K'!!3-"!!)utrrE&urrE#trrE*!r;c]o!qcO!q#:TZ;\0']PlM*drt)U=0A$.%!!*'!
6796 q0=%^!!@TEs8N)qrrVin#lXf'!<)rt!<)rt!<<'-#lk&0!W`9$!WW0"!<)rt!<3#u!<)rt!:0Xc
6797 N;rV,"J,Vj<E4P~>
6798 s&FUMJH16$JH1B(rDh8F!g8B3rr3&lLm%T6s+pXRs+p^T!JuX1rrn48s8Rn2rVunRrr<"SrVm)s
6799 [?-3#Mq[1jrr<?)mf<Chn,E@frr3$%!<2ut(B+:9s8QC*Sc=EEGlRdF!!<<)!<<*#qZ$QqqYpW]
6800 !##81rrE*!!WrH%rr30$!!E6%!;c`q!!3<,]_DI+!<)p!!s&?"rrW0""8i*+mpQh/!!]Y,rr<&u
6801 rr3!"!;c]r1;3YdrrDoq!pK[trVults8N-&!<2ut"o\K(rrE,rs8N'#"U)L/s8N)us8N)ts8N)t
6802 s8N)us8N'*rr<#t!!3*%!<2ut#Q=]*s8N'!rr)ls!;QR!!<E-!s8Duurr;uurVultrVults8NK/
6803 !!<<)!<<*#s8N'!rVultrr;uurVults8W#tqYpW]!##),#J`P3#s,?l&c2M=AcQN*rr)lts8VOr
6804 &c_n9YPS;!!;c]skl;@ps8N)ts8N)ts8N*!rsSr/!s8T*!!!'"rr<&ts8N)us8N)ts8N)brrIuV
6805 p=]Y<!;fbrJ,~>
6806 s*'"oJH16$JH1B(s*+KCdJj7T!;6?k!hfTqq>^HprVults8N*#!<)p%p]([$rr<&urrW0"!<3#u
6807 !<)p%cV4ZF!#OSQs8N')s1/42!r2cq!<3!!!<E)u(AIk:s8OAFg&El/bQ%SC!!<<)!<<*%qZ$Qq
6808 qYpVp!(d(grrE*!!<E3!rrr/t$NC,,qZ$Qq!Ws"pp](6nrVlm!!<)p!p](ZursI(H#QOi@i;`fW
6809 !<)ou!<Dur!>X\os8N)qrrT(u8H&Sg!<<'"!<E)u"o&')rrE,rs8N'#!taPas8N)us8N)ts8N)t
6810 s8N)us8N)urrr6!"oeT'rVm)s!"/c+!!)rsrrDio!<E3"rrW#s!<3#u!<)rt!<)rt!<<'-!<<3(
6811 !W`9$"98B$!<)rt!<3#u!<3!$rVurus8;rorrT(u8GN2iShUHZ9Xt-mqYq*X!0ZaLq#CEps3FCF
6812 !!!hnqZ$QqqYpVp!(d(grrE#trrE#trrE*!$ip>1!s/K'!!E9$!!)utrrE&urrE&u!r`0"li.!;
6813 s7XtGOT>5X<Ib~>
6814 s!WEuJH16$JH1B(s![nIdJj7V!;?El!r`0$q>^HprVults8N-V!7:`F%/Kr.s8NH,o)Jaf!!*#u
6815 rrDoq"5eV/#3,[_!<<''G5r0Rrr<&urrOtVd/O%Vq>^a"s7H@#s&B*/s8OhSeF`e@!;ZWq!!3&u
6816 rrE*!!]'i'rr33!!!`HV!7LcErr</`'EX0es8N)trrOtVd/O%Hq>^`prs.G3!!`K'!!)ut!\XQ%
6817 r;Qiq%d<lkrrDlp!<<0!s8N*!rrOtVd/O%Lq>^a"0*'Gts8N'$jqIlSoDegjrr;uurVultrVult
6818 rr;uu$/>L[qZ$g"1B>f$rs&<"#64]'!;uls!;QR!-NMp$s8)crrr;uurVultrVults8N-U!7^iE
6819 rrE#trrE&u#7CP&s8Vus!;$3k!!2]k!pot0qYpdD!8IPRq#CEmrr_//!!`<"rrDlp!<<0!s8N)t
6820 s8N)ts8N*!rrOqUeG9.E!<)rt!<3!'$NTbts82isli.!Es7Y4NScJXf<Ib~>
6821 s&FUMJH16$JH1B(rDh8F!f;a4rr3'!Ll(s-s+pXRs+p^T!fi*5rr3E'LlVN8M2;02s8.V.rr<"S
6822 qYpZ^[>9k&s8N*!rrsSG+ohQB!<3!"%06&"rt+f&%KHIk!#kkP!Ug!f$iotms8N)qrrW0"!r`0!
6823 !<<'#%06&"rs&)q%K?h:o_\[g!!C%@"MFO0rrE#t!Y#/%rr3&l!"J`'#L?fY%KHG.!<)p!$ioqt
6824 rrVm"qYgHo!;c]srW!#us8N*!rrNW0o`"jpoDf@#$ioqss8N'$_$'tSoDegjrr;uurVultrVult
6825 rr;uu$2=K"pAbR#%06&"rs&)q%KHG.!;uls!;QR!$39i#s7QEmrr;uurVultrVults8N-/!;60f
6826 rrE#trrE&u#6Ou(s8Vfn!;-9mrW!#krrUaO:&=kp#QXW!s7--ir;QlF@/pc5s8N)qrrW0"!r`0!
6827 !<)rt!<)rt!<<'#$iotrs8N)ts8N)urs&W+r;Zfk!!)?b!K$jMg'!iEqc-XH~>
6828 s*'"oJH16$JH1B(s*+KCdJj4K!<)p!o`,Ers8N)ts8N*!rrNB)qYpL'ci>p&rrN3"s8UpU!<3#u
6829 !;ld!rkC8i2<+Z9!<<''%fghRrr<&urrNB)qYpL+ci>p&s.KF(rsAl's8N9'qt0pg!;c]sp](Tu
6830 s8N*!rrNB)qYpL!ci>p&"p"Mss8N'$NWTjRq#C?orVlp'!;c]p!mgp(q>Ua"^GGpJs8N'!rVlp'
6831 !;cWn!nS:frVultqYpWl!!rQ'rrE*!!X8Z$rr32L!&X][!;cTmrr<.]!taPbs8N)us8N)ts8N)t
6832 s8N)us8N'*qu?]N!%7dN!;c]p#1*?,s8N'!r;Zcsq#:R&!;lfrg&M-Ps8N)ts8N)ts8N*!rrNB)
6833 qt^9l!<)rt!<3!'!W`6"s5!_Uo`#!f!!r2r!c\4IqYpd'!;uls`W-#;rri>91]TE0s8N)qrrVrq
6834 #lXf'!<)rt!<)rt!<<'#"p"Prs8N)ts8N)urs&T*rr<#T!!)?b!J:@FeHD!7qGgOG~>
6835 s!WEuJH16$JH1B(s![nIdJj8H!2KPn!qZI"q>^HprVults8N/%!)`aq%,V%,s8PssV>pSZ!!*#u
6836 rrDlp"9&9$ro=%Y!<<''g]0eCrr<&urrT8%;?$RshZ+btrrd?BPlMEqrrT\17J-W[!;c]so)K0s
6837 s8N*!rrT8%;?$S"hZ+buWrPuns8N'%s5jpqMY[8R#ls`!rrT8%;?$RshZ+bmrs&H&!WN*!!<)p!
6838 WrPuorrLppr;ZcsqYpWg!"8c*rrE*!!iuB!rr32[!$D6A!)WRmrr<3%jq7`Qo`+pkrr;uurVult
6839 rVultrr;uu$#KYAlMq\"X8l,srs%?\+92?@!;uiu#ls_qrs+hiD#aP#!!*#urrE#trrE#trrE*!
6840 !k85!q>^HprVultrr34$!2]_qkPtVTrrVcl$hOB"NWGpOrs',9jT#89!!)or"9&9$rql`q!;c]s
6841 o)K0ss8N)ts8N)ts8N*!rrT\17JZu`!<)rt!<3!';?3Qns6'F_li.!Es7Y4NScJXf<Ib~>
6842 s&FUMJH16$JH1B(rDh8F!g/<3rr3&kLlqN5s+pXRs+p^T!iq.2rr3D\Lo^RUObi]1s5f&mrr<"S
6843 q>UNpLl(-krrE*!#,_I!s8N'!rr3$m!3lJ&!jDYurr3*D!7(Wmrr3%*!1<EYrrDoq!oj7srVult
6844 s8N-n!3lJ&#-\)$s%*3lqu?Zr"TQ7@"MFR1!WrH$rr3$m!3lJ&!jDYup\tHp!!<3#!!)ut!_EBn
6845 r;Qes62^c_!;c]sirBnos8N*!rrPgnYl=Y,YQ.As8H>jhs8N'%s1ed@]_)7(!<3#u!<)rt!<)rt
6846 !<3#u!"%!Os3:U!s%<?rrr32,!)3Fm!!)rs!WrH$q>U[S!71]Fbl@bCs8N)ts8N)ts8N*!rrQI+
6847 R/-d^!<)rt!<3!''EIFus2P*>o`#!Q!#P8,!^6\IqYpd'!;ZZpVuQhprrW&t!rDrs!;c]sirBno
6848 s8N)ts8N)ts8N*!rrQI+R/-d^!<)rt!<3!''EIFus2P*>li.!Bs7Y.LRK34b<Ib~>
6849 s*'"oJH16$JH1B(s*+KCdJj7T!;6?k!hTHlq>^HprVults8N-B!9!kV$rI#,s8NE+p&G&)!!*#u
6850 rrDlp!poslirB#Ys8N9l!8RVS!!*#u!ZqF#rr3$s!3Q8#":bEl!.k.L![Riro`+pkqYpVb!+,X(
6851 rrE*!!ZqF#rr31"!3Q8B!8dVQrr<3%N<0[Pq>UHr!<)p!*rt6urrQ$tXnVi"m/R@jrr<&trrO5A
6852 hYdBS8#Z@crrDoq!gs$prVults8N-B!9!kV##PB&ruM0squ?Zr"TOG_&ENK`rrE&urrE#trrE#t
6853 rrE&urr<Aks8Qm8QiA--i;W`\;#m`urr<&srrE-#q#:R6!:0[bC&e85s8N)ts8N)ts8N*!rrOJH
6854 eG9.E!<)rt!<3!'$39c!s(;<3o`"u\!+,9s!Z;78qYpd%!<)rt8cSkgrrVQf#5\B"!;c]sR/gRl
6855 s8N)ts8N)ts8N*!rrOJHeG9.E!<)rt!<3!'$39c!s(;<3li.!;s7XtGOT>5X<Ib~>
6856 s!WEuJH16$JH1B(s![nIdJjL/!YW<Gj&lCsq>^HprVults8N`,.KuUCf..'@s8U=D+m\;u!!*#u
6857 rrE#t"tQY?r4)eCirB#YqZ$Qqrr39!.KuUCf..'@rr3,Z!!rX,rr39%;?C^ir:%=&qZ$Qqs8N<X
6858 ZLRnB9*'D<s8N*!ru1Y^"f(nF.gEfhpaQE4p$72/rr<'!s5ajpMYd>_BE3ecs8VjD"f(nF.gEfd
6859 rsC9TmejTq(B=C7!<)p(paQE4p$72/HYiW[rrE*!#;EIRrR4C?Hi=!E!<<'?paQHBq:@,$_#O0Z
6860 "IA`HJcG`M!<<)\&d!sjrr<&ps8N)us8N)ts8N)ts8N)us8N'4LsPWp!KR3T.KuUCf..'@s8N'!
6861 r;Qk4!/CIKrs.rs%aX]\!!*#urrE#trrE#trrE*!%/a!)D;5!X]3G=8!!)utrrE&u#L*5llfVUT
6862 !;ZX"0XC6Idn9^grVultrr30Y^\R2R!Fts*&<d)YoA2k8!<<'LW:'So!#GG2rrE*!#;EIRrR4C?
6863 Hi=!E!<)rt!<)rt!<<'-r)*T5g\gQQ>Q=^'!<)rt!<3!'blApQk?e2hli.!Es7Y4NScJXf<Ib~>
6864 s&FUMJH16$JH1B(rDh8F#hOm'li-4>LtMP's+pXRs+p^T').EGj8J"tNq`SR`/(Vol`u>&rr<"S
6865 rVm)&i;3>rLnNc-rrDoqrrE&u#ji$._Y_1X%IX5q"L.qD!4r10#ko_MNp$B)X$QU^rrE*!#?&M6
6866 qSF?V]D_d0!<<';m0jB>qn`^Mmf2\`$+9Wc@/p6,!<<)5"U)L7rrO/?_Z'Q@m0jB>qn`^Mmed"k
6867 9"aikQN/lBrr<&trsA*%$+9Wc@/hFsr;Zcss8N=%`:j&E+9K1Rs8N*!ruUP9$c;eX$OuP(mL0E0
6868 qV>QZrr<'!s1SX>]`8!3!;ZZp!<3#u!<)rt!<)rt!<3#u!#&2kjrjfVs6U4&_Y_1X%IX8r!!)rs
6869 !ZV3Wq>U]M![6^f:B1Cos8N)ts8N)ts8N*!rs\WM"HM[Dkc7#Lrr<&ts8N)urs+)T<;+gE!!)ip
6870 #?&M6qSF?V]D_d0!<3!&<mgj&C&sRprt%9mJGR>Y!!*'!9"aikQN/l=s8N*!rs)H?pA2WK!k\F2
6871 rrE#trrE#trrE*!%/2.QNp$B)X$Qdc!!)utrrE&u#CukSp=*4F!:0XcM?!;'"I]>f<E4P~>
6872 s*'"oJH16$JH1B(s*+KCdJjJc!FFmb]b(>'q>^HprVults8N_H"Y87$UBN4Ds8P%YNr-DQ!!*#u
6873 rrE#t#%l*UmpQ3IirB#YqZ$Qqrr38="Y87$UBN4Drr3*u!!rYcrr38Z&.YW-qqd\eqZ$Qqs8N=B
6874 de`U:%0ttms8N*!ru/WU/(jZm"YBHK^'5h+qoh)#rr<'!s,7!jjSJlX%055`rs6@C/(jZm"YBHG
6875 rsEA^qX7hmJcG`M!<)p(^'5h+qoh)#&F98orrE*!#B/&eoW&E+jSf,Y!<<'?^BH.?q4e*Eq#A&4
6876 ,L$&/3WK*Z!<<(X!YFGmrr<&ps8N)us8N)ts8N)ts8N)us8N'4D">m^#O_W,"Y87$UBN4Ds8N'!
6877 r;Qg-!8[JN#EAgfo$3$k!<3#u!<)rt!<)rt!<<'-g^jsnnGD(0-NF)G!<)rt!<3!'2uo!9\s36q
6878 q>U\<de`U:%0ttms8N)urs!W)qU%M1bPD/L)$$i9W/L]Vs8Q]TqX7hmJboEH!<<'(DpnLSWso<p
6879 rVultrVultrVults8NM_&.YW-qqd\es8N'!rVultrr33_!06rfPlLgMrrI`Op=0;.!;]\qJ,~>
6880 s!WEuJH16$JH1B(s![nId/O=%<YtoH2OF4=rrE#trrE&u#530_"V=;Hrr36&N>Md^irB)Ys8N)t
6881 rs%.g*!-dQh;\J7!;c`q!<)p%p2qM^&5("Arri9C!!M]frs/Os5S*u39WIshrrE*!#2!H+!>%Pp
6882 r;Zcsrr32rFWgo"9#pr2$1r'Q![*=!rr<&urr_<n!fHmT%I[1.!<E0"p2qM^&5(">rsIFk*!-dQ
6883 h>dKT!;uj&oPGKJ+Gfdup&+ji!<<''fOPs&&4*5ls8N)urs&1>+U&ELa8Z)FoPGKJ+Gg't!!*#u
6884 #36<sMYdA\q>^Hprr;uurVultrVultrr;uu"Sl7,(5;bf#530_"V=;Hrr;uur;Qog;A0'2qYpcO
6885 2$>GQ!!*#urrE#trrE#trrE&u$iZhb&-<S?WrN)!!<)rt!<3!'rf%`t52uVCq>UZOA/kU]6)XY\
6886 rrE&u"jp$P%6L?[rt,$C&I(PY!!*'!fk)3*'3*fas8N*!rs%+d*!$U:Vu6Sp!<)rt!<)rt!<3!+
6887 rh2Rg!YnD/s8N'!rVultrr36&N>Md^irB)FrrJ)Yp=oeB!;fbrJ,~>
6888 s&FUMJH16$JH1B(rDh5E#2Q5=Ll\Ljq#CAMrVunRrr32pZ]^0.Zh==t#QD8pN3W;:M#RGSM#I>X
6889 iNA9!Q+?eOs8N)qs8N)trs%Xk('>=Xl2CVbq?R',qu-O"qh[-<"<LmeqZ$Qqs8N;:;%`mF;9&P6
6890 rrE&u#3T5,!u>2,rr3;c<tGHeVuQbs!<3!#]EAAMqu7,W4q%Gls8V7e('>=Xl2(De^JY[G)eo'H
6891 rr<&srs7[e&-FS`n-f3ms8N*!rs$/6&cibF`r,l:!<3!&k?Jc)(1$2(rs@af&-FS`s8N'!rr328
6892 "9cC2!#GD1rrE&urrE#trrE#trrE&urr<2k4p*%1rr32c>S[DW?0V@grrDus"P5gG!<Dur#-/sN
6893 5O\XQrr;uurVultrVultrr3B'M)5VD*aZbarr<&ts8N)urs/L:%L?/3!!)ip#/*kH!>\PPr;Zcs
6894 rr3/,3X-3i_>+$AoM>i%=nhsss8Ti3&cs"dp\Opi!<<'']hoCC(/`*Ls8N)ts8N)ts8N)ursS^\
6895 1^jL.?GlgC!!)utrrE&u#Q8?H#Zpg%!:0XcM?!;'"I]>f<E4P~>
6896 s*'"oJH16$JH1B(s*+KCd/O<:2@BU(<nR3IrrE#trrE&u#/s1G"X8-`rr35r9aD;Squ?`rs8N)t
6897 rs#;c$j7r1r8RbV!;c`q!<)p%`C^[F,'N\YrrhTi!$V=>rs.t5.1$5-Dqt3hrrE*!#,=Hm"!1t6
6898 r;Zcsrr32A8e;.MG4tq8$,T%:#=-K4rr<&urr\,[&EN`g%B;)e!<E0"`C^[F,'N\VrsGSg$j7r1
6899 r;Zcs!;uj&_F"Y85g-qmrqufr!<<''UHo:j*b4=0s8N)urs$G7&-X8$pAY'u_F"Y85g03-!!*#u
6900 #)WHnjOsT(q>^Hprr;uurVultrVultrr;uu"Ni1s2:qj-#/s1G"X8-`rr;uur;Qo"0F%UYqYpbR
6901 ('e+?!!*#urrE#trrE#trrE&u$gr'b#mVksh#IBS!<)rt!<3!'oh>]'GPhF@q>UYo5n!i:A**Xg
6902 rrE&u"d:D=(gGnmrt*^A"Vc4Z!!*'!V*PLm-\M?ns8N*!rs#5a$j.P\jo#/Y!<)rt!<)rt!<3!+
6903 mW0f`#:ONGs8N'!rVultrr35r9aD;Squ?`_rrI`Op=0;.!;]\qJ,~>
6904 s!WEuJH16$JH1B(s![nIJcC<$iVrr.,Kp)gg&n54s8N(Ms,d6]N;rV,"J,Vj<E4P~>
6905 s&FUMJH16$JH1B(rDeFKJcF^/!KL7)rrSkthW+Y9!.k03rrIuVp=]Y<!;fbrJ,~>
6906 s*'"oJH16$JH1B(s*+KCJcC<$iVrp;]$(*T6PK%Ns8N(Ms,d6]K)bPp"H`]\<E4P~>
6907 s!WEuJH16$JH1B(s![nIJcC<$iVrpbL!0JsARONtrr@WMOT,??s7Y4NScJXf<Ib~>
6908 s&FUMJH16$JH1B(rDeFKJcF^/!>jV9rrF%4irB#YJcCi3!K$jMg'!iEqc-XH~>
6909 s*'"oJH16$JH1B(s*+KCJcC<$iVrodnB:h4%+sS>rr@WMOT,?5s7XtGOT>5X<Ib~>
6910 s!WEuJH16$JH1B(s![nIJcC<$M#[JTJcCi3!K@'Pg]X2Kqc-XH~>
6911 s&FUMJH16$JH1B(rDeFKJcCQ+rr@WMOT,?<s7Y.LRK34b<Ib~>
6912 s*'"oJH16$JH1B(s*+KCJcC<$M#[JTJcCi3!J:@FeHD!7qGgOG~>
6913 s!WEuJH16$JH1B(s![nIJcC<$M#[JTJcCi3!K@'Pg]X2Kqc-XH~>
6914 s&FUMJH16$JH1B(rDeFKJcCQ+rr@WMOT,?<s7Y.LRK34b<Ib~>
6915 s*'"oJH16$JH1B(s*+KCJcC<$M#[JTJcCi3!J:@FeHD!7qGgOG~>
6916 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6917 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6918 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6919 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6920 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6921 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6922 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6923 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6924 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6925 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6926 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6927 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6928 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6929 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6930 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6931 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6932 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6933 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6934 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6935 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6936 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6937 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6938 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6939 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6940 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
6941 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
6942 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
6943 s!WEuJH16$JH1B(s![nI_#OE7QN-sbScA]i[f?@-d/X+Gj8],ZScA]iec5XLmf3:eo`"rNs7Y4N
6944 ScJXf<Ib~>
6945 s&FUMJH16$JH1B(rDgZ5s+m!@rrAVirrBM-rrCFGrrD*ZrrAVirrCULrrDKerrD]k!K$jMg'!iE
6946 qc-XH~>
6947 s*'"oJH16$JH1B(s*+KC_#OE7QN-sbScA]i[f?@-d/X+Gj8],ZScA]iec5XLmf3:eo`"rDs7XtG
6948 OT>5X<Ib~>
6949 s!WEuJH16$JH1B(s![nId/O<b:DX-A0o#K'rrBP.rrD'YrrC@ErrCLIrrC+>rrDWirrCFGrrD*Z
6950 rrC@ErrCLIrrCULrrDKerrD]k!K@'Pg]X2Kqc-XH~>
6951 s&FUMJH16$JH1B(rDh5E#1TK1M3"L^q#CAM\,ZI.irB#YcN!nEdf9=Ia8c/>o)J^id/X+Gj8],Z
6952 cN!nEdf9=Iec5XLmf3:eo`"rKs7Y.LRK34b<Ib~>
6953 s*'"oJH16$JH1B(s*+KCd/O<*1(+4$:;6N'rrBP.rrD'YrrC@ErrCLIrrC+>rrDWirrCFGrrD*Z
6954 rrC@ErrCLIrrCULrrDKerrD]k!J:@FeHD!7qGgOG~>
6955 s!WEuJH16$JH1B(s![nIdJjKd!$KM_l$!+hq>^Hp\,ZI.irB#YcN!nEQN-sbTE"okcN!nEO8o4[
6956 o`"rNs7Y4NScJXf<Ib~>
6957 s&FUMJH16$JH1B(rDh8F#eu1sn,DdVLqiccs+n/arrD'YrrC@ErrAAbrrA\krrC@ErrA,[rrD]k
6958 !K$jMg'!iEqc-XH~>
6959 s*'"oJH16$JH1B(s*+KCdJjJ6!.!l,b9$_uq>^Hp\,ZI.irB#YcN!nEQN-sbTE"okcN!nEO8o4[
6960 o`"rDs7XtGOT>5X<Ib~>
6961 s!WEuJH16$JH1B(s![nIdJj7i!7UrI!r;m"q>^Hp\,ZI.irB#YcN!nEQN-sbTE"okcN!nEO8o4[
6962 o`"rNs7Y4NScJXf<Ib~>
6963 s&FUMJH16$JH1B(rDh8F!fVs3rr3&rLlD00s+n/arrD'YrrC@ErrAAbrrA\krrC@ErrA,[rrD]k
6964 !K$jMg'!iEqc-XH~>
6965 s*'"oJH16$JH1B(s*+KCdJj7N!;lcq!n%&kq>^Hp\,ZI.irB#YcN!nEQN-sbTE"okcN!nEO8o4[
6966 o`"rDs7XtGOT>5X<Ib~>
6967 s!WEuJH16$JH1B(s![nIdJj8+!7UrI!rDs&q>^Hp"oWf]#u1'krs&1@,6ecSb5VG@!<)rt!<3#u
6968 !"/Em"987M-jBu7QK%rE!<)rt!"8aQ((Y'Xqf<P\;Yg=lrr<2t?O.L)rr;uurr33#NA(YI5Ipdn
6969 rr<H*Hkm6*s8-jR$<$^!rs&C\0F8.P\c2X/!!iIM&d_;)s8VrrqZ$Qq$iPGg%qkq>Eu,0]q>UC%
6970 p3._c&kpIJo`,0drr33"#m/ZW!!*#urr<6$HkH`[o`"jpeMRL]c2[k?rsn^A*X!O>s8Ve:,6ecS
6971 b5VG@!!iIM&d_;)s8Vrrs8N;pL_p45C&%]-rrE&urr<6$HkH`[o`"jpr/EB:$pV<%s8N'+p.GMf
6972 qgp4##rIt@s8N)us8N',[email protected](CF(9rr;uu"SlC1(l81krrE&u#5jH7#n0&/rr;uu$iPGg%
6973 qkq>Eu,0]q>UBur/EB:$pV<%s8N'(rHo4a:%\JcqZ-Kmrr<H*Hkm6*s8-jR$<$^!rsSOE,6ecSb
6974 5_,7"nMZm#5\].ec,ULrr;uu"oWf]#u1'krs%"2"Y@q!!;ZX&70&t[s+M$as7H?trr;uurr;uu"
6975 oWf]#u1'krs%.7"Y@mu!<3!&p3._c&kpIIrrJ)Yp=oeB!;fbrJ,~>
6976 s&FUMJH16$JH1B(rDh8F!fi*5rr3&rLl_B3s+gjVZAajTrr2p%osBp>PI1&_s8RoRs8RoSs8Rl^
6977 oUgs>qmi#LNi1Xks8N)ts8N',q-FRKL]@$M&.ig[rr;uu"S"e]-*I7IrrE&u#5<6b"qa\frr;uu
6978 $i+*>(l/.a=V)-`rr2p%pN7\b&Q%<_s8N'(q-+.9C&S)3qZ-Kmrr<H&?4Rm.s7KM+&9.XJrsS't
6979 (]tU^li6/K$N0o'#5&$"p&>!lrr;uu"o2@/%r)"Ars#DH"@DYZ!;ZX)j]W?$/Z/RJl!>2/(glV.
6980 s8N'(q-+.9C&S)3qZ-Zr#3TV/"XSg#rr;uurr;uu"o2@/%r)"Ars&4?,6e`Vh>[HS!".pE!WVk,
6981 *<Qa;ZM"7t!<3#u!"8U/%iC*%oiVh;E;ok:rr<2l63JU;rr;uurr32sFX%)&:u2-Nrr<H&?4Rm.
6982 s7KM+&9.XJrs&4?,6e`Vh>[HS!!i=(#nLbKs8VrrqZ$Qq$i+*>(l/.a=V)-`rr2p*l!>2/(glV/
6983 kPttfrr32q!X&,q!!*#urr<5u>6tgSrVlg$W$;F3nc/[crsKD=kl:Z-,6.],!"o51rrE&urr<5u
6984 >6tgSrVlg$Xs=-:nGiRgrs%^o(]tU^li-nbM?!;'"I]>f<E4P~>
6985 s*'"oJH16$JH1B(s*+KCdJj7P!;lcq!n%'-q>^Hp"m/,T)3+Xprs$P<&dBV+p\t3m!<)rt!<3#u
6986 !"-=Z!WUnR'`o(Ldc1<,!<)rt!".mX#pHPQf0BW^Q2Ua_!!LLs"uk67s8N)urs%@d)$Cgio)A[h
6987 !".mX#pHPQf0BW^Q2U^ehd%*&)/&O>s8N'(k!B4hNW/tXqZ-Kmrr<Dh70t-As49LB*0pL&$cl!S
6988 "seHfs.TK@rr2p%dK'gSrr<&us8N'&k!B4hNW/qW#(dTs@/0d&q>UrC7h#\fbQ%U`9G.OTGk_4;
6989 rr<;d63S6drr<#q!<<'&eP$5S18=aIrrE&urr<5b63S6drr2p%hd%*&)/&O>s8N'+],h"QgJemh
6990 'NNTSs8N)us8N'+k=#\#YlE<?#oo6/s8N'%bU`rWg&D$O!<3!&hd%*&)/&O>s8N'+k=#\#YlE<?
6991 #oo6/rs%@d)$Cgio)A[h!!hXQ"W<=!s8VrrqZ$Qq$Kjha+gD!u5RAEqrVm8H9G.OTGk_64!%7dF
6992 rs$mP%K$/*!<3#u!!VLO"W<=!rr31S(("CE!!)ip$O?b*s8NX_s8S\k7K3>e!<3#u!!VLO"W<=!
6993 rr31Y(^XUG!!*#u#09IN"seHfrr3"Ns7XtGOT>5X<Ib~>
6994 s!WEuJH16$JH1B(s![nIdJjL1&g5Ktl?EAVq>^Hp'UQH-MZ>a:s7e2MUA3:g#/gK@!!)utrrE&u
6995 rr<CVbMrPQ!*A@]flH*PrrE#trr<Fo\,)9gAn\[MP5mlIs8N'ZM9YQj!L!K_!!*'!qa^jPo]JaJ
6996 [/^.+!1:7lP5o3.\,)9g5l^l]8-G(Ik=>`_s8N'!Qb3'O!''uXrrDfnrr<t)\,)9gAn\[MP5mlJ
6997 s7e2MUA3:g#/gI^!+Z$.#29+qs8N'!rr;uu&!sp(MZ>a:s6U"$d.2&S!;c^6paQE3oBLo,pau`E
6998 pspku_uK`:!11=nMZ>a9s8N)trs/<7WVQ%A!&X]TrrE&urr=.-]D7?b3<0$U8-G(Ik=>`_s8N'!
6999 JBQsPJH/d7r7Q,`s8N)us8N',R()pU!+ooRqNCnErr;uu3Jl#N<<89_rr<'!s8,=iOn@g-"LS4/
7000 !!&CqqNCnkBXdi%!'pSaqa^jPo]JaJ[/^.+!11=nMZ>a9s8N)ns8N';R()pU!+ooRqNCnEs8VjH
7001 "eteC.0d]iEr]_Lrs%3X)?9^:!<3#u!"YF.q2554s8VHj&('lb!!)ip$b-1%s8<E8jT"!8+9)<?
7002 !<3#u!$7K=q2554s8VNn%F+EU!!*'!pau`Epspku_uKaqs7Y4NScJXf<Ib~>
7003 s&FUMJH16$JH1B(rDh8F#hb*:nG_pYMV@n+s+hAqlh[c?`;fl4O,`/tif0#os8Rn2rVunRrr<"S
7004 $E<UUs.G1jq#'9XirB#YrVult$X2!P=TGuode6fDNW/tX!'*j9j<"HTs8N'!s8Vd5#I4*T)$oI+
7005 rr<%&de6fD\NA75=TFH]s7RH<Z2)of#jD<g!!$<ToMGU>rr;uup](6n)HtS_=TGuode6fDNW9%I%
7006 L^,M^^:S@ru_<^rr31u!'C5\!!*#urr<R8eau]=JcGbu![?dh;ucppru1;6$+0K_@/o[*$c2_U$
7007 4cS*rr<%)eau]=Jc>]L!<)p&n0l<Sk$\74rr;uurr;uu+'mFh;#l1Is7RH<Z2)of#jD<g!!#LK_
7008 #H1jNUZbd<;$:k!<3#u!"2uYp/qC+44<h*!0.!Xrr>&TjQ%BafDkjN!<<)m*=&kFeJSYVs8N'!>
7009 13+I!4b2>p/qBTs8Vd5#I4*T)$oI+rr<%)eau]=Jc>]L!;HNn!#f%hp/qC+44<h*!0.$Ymg]`Aq
7010 nNOKnGaU2a8Z)CU]<LVrr<&us8N'0?.JRE!.k1MdK1WTk#;<\q>Ugr!3#qo"pOi&V>s<hs8N)us
7011 8N'??.JRE!.k1Mf)d&Tj@oUSs8VNt$c2_U$4cS*s,$dLg'!iEqc-XH~>
7012 s*'"oJH16$JH1B(s*+KCdJjJu!da21bT@JUq>^Hp'Op7h+99^es2"sjfCtpA0DPSI!!)utrrE&u
7013 rr<C;n:(BP!3c+h\2*(DrrE#trr<F4jm42lgem2",663ls8N'ZC@TOX#k.fn!!*'!faJqEqmm.X
7014 pAb-m!+"^Q,66Lrjm42le,TI$$m*Rg\dKYSs8N'!@cuqt!7(TDrrDfnrr<sCjm42lgem2",663m
7015 s2"sjfCtpA0DPPX!9jF^#"&B^s8N'!rr;uu%q=_c+99^es,$h\o$E9p!;c^6^'5e)qo_#"_?MOB
7016 pRh[Cq#C?o!+P-T+99^ds8N)trs-8-gAKPS!6"m:rrE&urr=-MkNF#gcN!pt$m*Rg\dKYSs8N'!
7017 Aak0K'`bH2oscdMs8N)us8N',?01Dt!8LH5lluMZrr;uu3GS*/%1)G&rr<'!s4If%b58aX+SPj8
7018 !!$<dlluMc;<@-h!7UuJfaJqEqmm.XpAb-m!+P-T+99^ds8N)ns8N';?01Dt!8LH5lluMZs8Tq?
7019 /(aNg"Y]ZN%fkhmrrtgjT)\fj!<3#u!"WQ%kTBlNs8RrW>4U$u!!)ip$QfB)s6'k#r;St]\GlO.
7020 !<3#u!$5V4kTBlNs8S5_<q4Fj!!*'!_?MOBpRh[Cq#CAGs7XtGOT>5X<Ib~>
7021 s!WEuJH16$JH1B(s![nId/O.42?!RV$_I.nrr<C?s8V`l$NL..!)`aq#2T>&s8N'!rVultrr;uu
7022 !,;H4!XSk+hZ*TUrVult$YKG=p&G8.s8Vcm$NC)*!"NfEs69S"s8N'!s8T_37K3<'lMqn(rr<%2
7023 s8Vcm"_Rf7p&GI"s1A>#rr3Dm!#tt<!!$a5s7H@!rr;uup](6n&8(tBp&G8.s8Vcm$NL..!)`aq
7024 #2T>&s5<qorr31E!-8,>!!*#urr<RDs8V`l$NL-j!,qo;lMpq]rrT2#:]14oXT25trs[`a+TMHA
7025 !,;K5o`,?us8N)orrW-!#6+Z&!<3#u!"*H?s7H@!s8T_37K3;llMqn(rr<%5rr3$+!3,MgrrE&u
7026 rr<F=s8Vcm"_Rf7p&GI!s8N'/C]FG"!#GV7!!*'!]DtD"rtju$)uop<!+u92p&G8.s8Vcm$NL.=
7027 !(Hne%-mm4s8N'!C&e5+!"/`*rrDfnrr<UBs8Vcm"_Rf7p&GI"s/c8urr32Z!$M=#!#PY7#'9ic
7028 s8N'!rr;uu%r)(Do`,@!s-*M%s8VBb!;ZX&jo?;!lje8Ms/5otrr;uurr;uu'P[UIo`,@!s-E_$
7029 s8V<`!<<)$!)`aq#2T>&s8S&Xp=oeB!;fbrJ,~>
7030 s&FUMJH16$JH1B(rDh5E!ToXGL]Nb'q#CAM$KhBgon\b1s/Ut0rr32ULogXVLku$0s+p[Ss+g[<
7031 rr3%VM!*XprrE#trr<GHs8VBb$c`5Hl2VV!s8N'/cN!ph!&FTS!!*'!@fW/#rtj#^5l^ia!65'=
7032 lMq=4s8V?a(B=DE!2'8j%+"u>s8N'!aoDD*!#5G4rrDfnrr<VMs8VBb$c`5Hl2VV"s%EEsrr32)
7033 !)ER#!&acU"s3ils8N'!rr;uu&'=kOkl;Fts"=B"s8UFG!;c]s8-#^grrPjoYl=Y2XT2,rrr<&@
7034 s8V<`'`S.4!;QQqq#Cm's8N)us8N'+aoDD*!#5J5@fW/#rs-mN5l^ia!6kHB!WrGGnc/Uhrr;uu
7035 $c`5HlMq=4s8V?a(B4@6!"R<Ss31O!s8N'!s8QR/TDnj,ci??2rr<&=s8VBb$c`5Hl2VV"s'l&$
7036 rr3DR!'pSa!!(.@s60Ltrr;uup](6n&B=bMlMq=4s8V?a(B=D.!3lJ&#-@l#s0D\_rr30E!7:cG
7037 !!*#urr<SOs8V<`'`\1d!7CiHci=(ArsQ^E3WIPK*R=[D!5ng9rrE&urr<bTs8V<`'`\1g!7(WE
7038 b5_PBs%EEsrr32)!)ERoM?!;'"I]>f<E4P~>
7039 s*'"oJH16$JH1B(s*+KCd/O-<$iU,,2=(&;rr<Djs8Sho;ZHb=!9!kV##>6%s8N'!rVultrr;uu
7040 !:'R`!W`;^hZ*TUrVult$g@WjW;mRps8T"t>5nR%!"S;os(_V%s8N'!s8OGHg&D!fEr_s7rr<&_
7041 s8T%u''TAqVuU$$s!Ig"rr3CJ!2BMn!!)9`s.]Qlrr;uup](6n&Es/oW;mRps8T"t>6"UE!9!kV
7042 ##>6%s&&i`rr304!:0[b!!*#urr<Sos8Sho;ZHb3!:9acD?'\5rrO5AhYdBT*rt6ursV['Y5eM%
7043 !9sO`UB"3ks8N)orrV6]2ZEaV!<3#u!".ujs.]Qls8OGHg&D!VEr_s7rr<&arr3$#!9E\MrrE&u
7044 rr<Gjs8T%u''TAqVuU$#s8N'/lMpm"!1<fd!!*'!-NMj!rtf_VUAt5n!9jI_W;mRps8T"t>6"UM
7045 !87AO%!)ECs8N'!l2UdY!)igrrrDfnrr<Vos8T%u''TAqVuU$$ruV7!rr30u!3Z?"!13]b"qCY!
7046 s8N'!rr;uu&*a,oUB"3lrtPP#s8Qs:!;ZX&<<0'!C3^<Srtkaurr;uurr;uu'^>YtUB"3lrtYV"
7047 s8Qd5!<<'@!9!kV##>6%s8R]Np=0;.!;]\qJ,~>
7048 s!WEuJH16$JH1B(s![nIdJjL8&eVkSj&lJ@q>^Hp$Jtg_rW!$"s"j`&rr33!!!`K'!!)utrrE&u
7049 rr<&Nrr3.<!!+g;h;SD6!<)rt!"7Z`s8DuuhZ*WT!!<0"rr<P`s8Vrr"onT&!<<'`!5AI4(]==;
7050 s8N'!hZ*WT!!(mUs8E!"s8P:`^Ae-@r;[$$rr<&Us8W&u!ri6"!;HNn!"e#es8DuuhZ*WT!!<3#
7051 1]Yo%rt,#,#64WF!n.,D!XJT%rr<&us8N'0hZ*WT!!<3#-32j$s82isqYpUL!7LfF!]0o(rr3E'
7052 !!`K'!!(mUs8E!"rr;uur;Qhp3Y),h!!3*!rrE&urr<D_s8W&u!rr9b!5AI4#Q4W+s8N'!fDbdR
7053 C]FJjP25d1rrE&urr<G`s8W&u!8dbUrW!$!s8N'/g].<N!!WE&!!*'!56/FsrtkV6"onT&!8dbU
7054 rVurTs8W&u!rr9b!5AI4%/g/0s8N'!hZ*WT!!<0"rrDfnrr<Ves8W&u!8dbUrW!$"s"j`&rr3Q+
7055 !!`K%+Tg*lp]:]ss8N'!rr;uu&)R?drW!$"s!@a$s8Vus!;ZX&q>pp%_(a(Ws"jc&rr;uurr;uu
7056 ']/lirW!$"s!Ig$s8Vrr!<<'U!7:`F#5S<(s8S&Xp=oeB!;fbrJ,~>
7057 s&FUMJH16$JH1B(rDh8F#igf4li-4?MW=O4s+h$Zs8W(SM?!U9M#.,N#5X.9s8Rn2rVunRrr<"S
7058 !;lcq"dt1&X4$e%s8N)ts8N',p](9k!!)cns82j"rr;uu%ep#'p&GI"rr<'!rso,!rr3f2!"8i,
7059 !!)cns82isp](9k!!N?%%fl+urs\`($ig5,!;HNnqu?ius8N)ns8N'1p](9k!!)cns82j"s8NN.
7060 o`"k%oDf@#q?R2rs6]mtrr;uu!<3#u!"\i(s82j!s8NB*p](9f!!)lq!Xf##r;Qg-!;-9j%.jN/
7061 s8N'!p](9k!!E6#rrE#t"9"$-$2so)!WN-!!<3#u!"/K#s82j!s8NT0nG`Fmq>^p'rr<&mrr3-I
7062 !!,cbnFZb\!<3#u!"8Q$s82isp](9k!!N<$rr<Q's8Vcm$NL,+!<<'0!:^!f(]"+>s8N'!p](9k
7063 !!)cns82j"s8NT0nG`Frq>^p'rr<&ns8Vus"9/?#!;HNn!"eo)s82isp](9k!!N?%%06&"rt+f&%
7064 KH81"82]^!=o,/rr<&us8N'0p](9k!!E9$#ls`"s7ZKnq>Uip!=o-9H?rNi%0?,#s8N)us8N'5p
7065 ](9k!!E9$$39i#s7QEms8NN.o`"jpoDf@#s,$dLg'!iEqc-XH~>
7066 s*'"oJH16$JH1B(s*+KCdJjK/!a=X\]b(q@q>^Hp$N0r(nc0*urrrK"rr32K!&X`U!!)utrrE&u
7067 rr<&rrr3-5!!-W4q;MAR!<)rt!"8`)s7--ir;Zff!"f/0rr<Q+s8UdQ.0';I!<<'(!;QQn([1oM
7068 s8N'!r;Zff!!)rss7-.$s8N<(q#::%kl<76rr<&ss8VWi%0$;,!;HNn!"f).s7--ir;Zff!"f21
7069 "p"N!rsR-Q2#lkE$N'k5!B^;\rrE&urr<T-s8VWi%0->2!;ulsgAh6MrrNB)qY^?p"p"N!rs[3R
7070 2#mRU!;ulsnc0*ts8N)trr`"7,6n,I!!E6#rrE&urr<E(s8VWi%0->4!;QQn#O)4=s8N'!qu6U!
7071 &-)`AXnhVhrrE&urr<H)s8VWi!;ulsnc07#s8N'/qu?]M!%@mI!!*'!#6=Purtjo"/-#VL!;uls
7072 nc/[fs8VWi&HDb8!;QQn%-[aBs8N'!r;Zff!"Al,rrDfnrr<W.s8VWi!;ulsnc07$rrrK"rr3AP
7073 !&X`A":G&+\,e\js8N)us8N'0r;Zff!"Ao-"T\K#s4[MRq>UiK!BC*+bqH^/"p4Z#s8N)us8N'5
7074 r;Zff!"Ao-"T\H"s4RGQs8N9'qYpL!cN#g%s+::EeHD!7qGgOG~>
7075 s!WEuJH16$JH1B(s![nIdJj8K!2BJm!qcO#q>^HprVults8N-,!;ZTn"TSW(rr<&ts8N)us8N'!
7076 qu6U"q0=%^!!@T-s8N)ts8N)ts8N)ts8N)us8N'!qYpL/!!3-"!!*'!#lk&0!W`9$!WW0"!<)rt
7077 !<)rt!<<'-#lk&0!W`9$!WW0"!<)rt!<3#u!;HNn!<)rt!<)rt!<<'##lsf"rsA`-s8T\25l]43
7078 0E2"O!<3#u!<)rt!<<'#"9A>us8N)qrrN?(r;?Qr#lsf"rriB(s8N'!rVultrr;uurVm,2!&)t%
7079 rr<&us8N)us8N)ts8N*!rs]87!s8T*!!!'"rr<&rrr32uGom"d"+0_@rrE&urrE#trrE#trrE&u
7080 rr<&qrr3Z4!WW0"!<<'*!!<<)!<<*#s8N'!rVultrVults8NK6!!<<)!<<*#s8N'!rVultrr;uu
7081 p](6nrVultrVults8N-,!;ZTn$31/-s187rs3Ug"rr;uurr;uurVults8N-'!;lcqrrDio$!RD?
7082 <.+0@pAbU"s8N)us8N)ts8N*!rrN<'qYpNp!<<'##lsf"rriB(s8S&Xp=oeB!;fbrJ,~>
7083 s&FUMJH16$JH1B(rDh8F!g8B3rr3&lLm%T6s+pXRs+p^T!JuX1rrn48s8Rn2rVunRrr<"SrVm)s
7084 [?-3#Mq[1jrrE#trrE#trrE#trrE&urr<o8s8W&u!WW0"!<<'#!!<<)!<<*#s8N'!rVultrVult
7085 s8NK/!!<<)!<<*#s8N'!rVultrr;uup](6nrVultrVults8N-&!<2ut$iU,.s8QC*Sc=EEGlIaC
7086 !<3#u!<)rt!<<'(!<E-!s8DuuqYpQs!;lct!s&?"rs&H&"98B$!<)rt!<3#u!<)p&AcQN*rr)lt
7087 rr;uurr;uurVults8NN0!!<<)!<<*#s8N'!rr2p%mpQh/!!]Y"s8N)us8N)ts8N)ts8N)us8N'9
7088 rr<#t!!3-"!!*'!!WW<)!W`9$!WW0"!<)rt!<)rt!<<'-!WW<)!W`9$!WW0"!<)rt!<3#u!;HNn
7089 !<)rt!<)rt!<<'#!s&?"rsSf+"98C-!1j.E!-nMCrrE&urrE#trrE*!#6=i(s8W&u!;QR#('*b:
7090 hVJh2!#GP5rrE&urrE#trrE*!$ipA-s8W&u!<<'$!<2ut#6"T)s8RrUp=]Y<!;fbrJ,~>
7091 s*'"oJH16$JH1B(s*+KCdJj7T!;6?k!hfTqq>^HprVults8N*#!<)p%p]([$rr<&urrW0"!<3#u
7092 !<)p%cV4ZF!#OSQs8N)ts8N)ts8N)ts8N)us8N)urtYA1"onT&!<<'"!!<<)!<<*%s8N'!rVult
7093 rVults8NK.!!<<)!<<*%s8N'!rVultrr;uup](6nrVultrVults8N*#!<)p*p]([$s!7Zus"j`!
7094 rr;uurr;uurVults8N*#!<3!"q>^NlrrE-#qu6Zt!<)p%p]([$rr<&ts8N)us8N)trs((TP3r;F
7095 !!*#urrE&urrE#trrE*!$ip>1!s/K'!!E9$!!)ut#1$!L!!!hnp&G$lrr;uurVultrVultrr;uu
7096 rr3`0!!WE&!!*'!!<<3(!W`9$"98B$!<)rt!<)rt!<<'-!<<3(!W`9$"98B$!<)rt!<3#u!;HNn
7097 !<)rt!<)rt!<<'"!<E)u$hs]/s8OAFg&El/bPqPA!<3#u!<)rt!<<'"!<E-!!r;lsq#:X.!;Hoj
7098 HpY.>>Q+U%!<3#u!<)rt!<<'"!<E-!#5S<"s8N*"rVm)s!"/c+K)bPp"H`]\<E4P~>
7099 s!WEuJH16$JH1B(s![nIdJj7V!;?El!r`0$q>^HprVults8N-V!7:`F%/Kr.s8NH,o)Jaf!!*#u
7100 rrDoq"5eV/#3,[_!<)rt!<)rt!<)rt!<3#u!"Rc`s8)d"s8N'!s8OhSeG9.E!<)rt!<)rt!<<'#
7101 1'#i"s8N)ts8N)us8N)ns8N)ts8N)ts8N*!rrOtVd/O%Qq>^a"s7H@#s&B*/rr;uurr;uurVult
7102 s8N<M!8[\Tqu?`nrrOhRdes+H1B>f$rs&<"#64]'!<)rt!<3#u!<)p&+TU9ss7lWprr;uurr;uu
7103 rVults8N-U!7^iErrDoq"5eV/#5/#r!<3#u!<)rt!<)rt!<3#u!"Rc`s8)d"s8N'!s8OhSeG9.E
7104 !<)rt!<)rt!<<'#1'#i"s8N)ts8N)us8N)ns8N)ts8N)ts8N*!rrOtVd/O%Qq>^a"s7H@#s&B*/
7105 rr;uurr;uurVults8N<M!8[\Tqu?`lrs?OB7K`2['TE)>rVultrr;uurVults8NKT!8IPRqZ$Wr
7106 s"aZ%rr33!!!`K'N;rV,"J,Vj<E4P~>
7107 s&FUMJH16$JH1B(rDh8F!f;a4rr3'!Ll(s-s+pXRs+p^T!fi*5rr3E'LlVN8M2;02s8.V.rr<"S
7108 qYpZ^[>9k&s8N)ts8N)ts8N)ts8N)us8N'/p](9f!"/c+!!*'!$iotrs8N)ts8N)ts8N*!rrNT/
7109 p%eXf!<)rt!<3#u!;HNn!<)rt!<)rt!<<'#%06&"rsSH!%KHIk!#kkP!UfserrE&urrE#trrE*!
7110 #71D)s8Vfn!;c]s$ioqtrrNW0o`"jpoDf@#rr<&ts8N)us8N)trs&f0p](9a!!*#urrE&urrE#t
7111 rrE*!!Xo)%q>^HpqYpZD@/pc0s8N)us8N)ts8N)ts8N)us8N'/p](9f!"/c+!!*'!$iotrs8N)t
7112 s8N)ts8N*!rrNT/p%eXf!<)rt!<3#u!;HNn!<)rt!<)rt!<<'#%06&"rsSH!%KHIk!#kkP!Ufse
7113 rrE&urrE#trrE*!#71D)s8Vfn!;QR#?3%,3r;6_n!+,X(rrE&urrE#trrE*!$jm"/s8Vcm!<<'.
7114 !;-9j#4qm)s8RrUp=]Y<!;fbrJ,~>
7115 s*'"oJH16$JH1B(s*+KCdJj4K!<)p!o`,Ers8N)ts8N*!rrNB)qYpL'ci>p&rrN3"s8UpU!<3#u
7116 !;ld!rkC8i2<+Z9!<)rt!<)rt!<)rt!<3#u!"So+s4[N$s8N'!s8N9'qt^9l!<)rt!<)rt!<<'#
7117 "p"Prs8N)ts8N)us8N)ns8N)ts8N)ts8N*!rrNB)qYpL&ci>p&s.KF(rsAl'rr;uurr;uurVult
7118 s8N<-!;ulsg].?NrrNB)qY^?p"p"N!rs$gM2#mRU!<)rt!<3#u!<)p&"9AB"s2G$=rr;uurr;uu
7119 rVults8N-)!;lTlrrDrr"TH.m!&aHLrrE&urrE#trrE#trrE&urr<Q+s8UgR-ia2H!<<''!;lTl
7120 rrE#trrE#trrE*!!X8Z%q>^HprVultrr;uup](6nrVultrVults8N-)!;c]p$d\l1s8SbmAcE)>
7121 q#:<n!<3#u!<)rt!<<'("T\K#s4dSSq#:XI!2UG0nH2#V_YsN7!<3#u!<)rt!<<'-"T\H"s4RGQ
7122 s8N9'qYpL!ci>p&s+::EeHD!7qGgOG~>
7123 s!WEuJH16$JH1B(s![nIdJj8H!2KPn!qZI"q>^HprVults8N/%!)`aq%,V%,s8PssV>pSZ!!*#u
7124 rrDlp"9&9$ro=%Y!<)rt!<)rt!<)rt!<3#u!"NiFs6BY"s8N'!s8TS/7JZu`!<)rt!<)rt!<<'#
7125 \,\tns8N)ts8N)urrNK,p\=dg!<)rt!<)rt!<<'#X8l,srrV'X+9)9CEWD@)&cMb0!<3#u!<)rt
7126 !<<'(P5oV&s6K^cqYpVt!)WUn!iuB!rr32[!$D7@!!)utrrE&u!XSl$rr338!9F1[h#IHSs8N)u
7127 s8N)ts8N*!rrT\17JZu`!;ZWsrVuuupAb-mrr;uurVultrVultrr;uu%W)1FlMq\"rr<'!s0r%t
7128 q>^HprVultrVults8N/1!(H_`rrE#trrE&u!XSl$q#C?orVultrVults8N/%!)`aq!oEu"rr3+A
7129 !0mNrrVultrr;uurVults8N=f!-/&=li7%\rs@uk$5*=<N!B>mrVultrr;uurVults8NLn!,V]8
7130 l2Uhas/Z2trr32[!$D7@N;rV,"J,Vj<E4P~>
7131 s&FUMJH16$JH1B(rDh8F!g/<3rr3&kLlqN5s+pXRs+p^T!iq.2rr3D\Lo^RUObi]1s5f&mrr<"S
7132 q>UNpLl(-krrE#trrE#trrE#trrE&urr<PTs8U@E1&q7R!<<()!1<T^rrE#trrE#trrE*!!aPen
7133 q>^HprVultrr3$%!<)]mrrE#trrE#trrE*!!_WNtrr3&(!)3Cl"<[]j!%7aFrrE&urrE#trrE*!
7134 #;6)+s8UIH!;c]s8H>jirrPgnYl=Y,YQ.Asrr<&ts8N)urrN9&rVlg%"9A8ts/5ntrr;uurr;uu
7135 rVults8N.+!1<T^rrDlp!rDs!p&G$lrr;uurVultrVultrr;uu%aY1Tc2]U!rr<'!s'5Vlq>^Hp
7136 rVultrVults8N.+!1<T^rrE#trrE&u!WrH$q#C?orVultrVults8N-n!3lJ&!jDYurr3*D!7(Wm
7137 rVultrr;uurVults8N<W!7UuJd/X1Ars@$P*%(^c-5$=*rVultrr;uurVults8NK^!71]Fbl@bD
7138 s%<?rrr32,!)3FmM?!;'"I]>f<E4P~>
7139 s*'"oJH16$JH1B(s*+KCdJj7T!;6?k!hTHlq>^HprVults8N-B!9!kV$rI#,s8NE+p&G&)!!*#u
7140 rrDlp!poslirB#YrVultrVultrVultrr;uu%dX/pC]Kh%rr<'!s!7Zpq>^HprVultrVults8N-H
7141 !7^iErrE#trrE&u!<E2ps8N)ts8N)ts8N*!rrO8Bi;W`X;#m`trr`f3NW=Y/s8N)us8N)ts8N*!
7142 rs'5<m/R*(!!)lq!Zh?ur;Qg?!9!kV##PB&s8N'!rVultrr3!"!<)p&!W`3!s%37krr;uurr;uu
7143 rVults8N-H!7^iErrDlp!poslp&G$lrr;uurVultrVultrr;uu%dX/pC]Kh%rr<'!s!7Zpq>^Hp
7144 rVultrVults8N-H!7^iErrE#trrE&u!<E2ps8N)ts8N)ts8N*!rrO8Bi;W`X;#m`trr`f3NW=Y/
7145 s8N)us8N)ts8N*!rs'5<m/R*(!!)fo$"ErGNW9"j#6=)gs8N)us8N)ts8N*!rsTVBli7!"!!*'!
7146 *rt6urru=#XoJEQs7XtGOT>5X<Ib~>
7147 s!WEuJH16$JH1B(s![nIdJjL/!YW<Gj&lCsq>^HprVults8N`,.KuUCf..'@s8U=D+m\;u!!*#u
7148 rrE#t"tQY?r4)eCirB#YrVultrVultrVultrr;uu(l6N/=TOQ_rr<'!s85arD;5!X]3G=8!!)ut
7149 rrE#trrE*!%/a!)D;5!X]3G=8!!)utrrE&u")%[hrV?Kn!<)rt!<)rt!<<')paQHBq:@,$_#F?:
7150 huF&`=8i1!!<3#u!<)rt!<<'(m0+$Jo5F[0qYq9).Kl(1l[f*2.KuUCf..'@s8N'!rVultrr3F@
7151 !/CIPs-!FIoA2k8!<3#u!<3#u!<)rt!<<'-r)*T5g\gQQ>Q=^'!<)p)/#_n6\H!EFrr<&ps8N)u
7152 s8N)ts8N)ts8N)us8N'9LsPWp!KR3[!!*'!r)*T5g\gQQ>Q=^'!<)rt!<)rt!<<'-r)*T5g\gQQ
7153 >Q=^'!<)rt!<3!#BE3ecq>^HprVultrVults8NB".KuUCf..'@rr3,Z!!rX,rVultrr;uurVult
7154 s8N>k"V9#PDu]n5rsAT.!&srXe,TO-rVultrr;uurVults8Nl&#7f)NC&e86s7e&IU\WLl#/L9=
7155 N;rV,"J,Vj<E4P~>
7156 s&FUMJH16$JH1B(rDh8F#hOm'li-4>LtMP's+pXRs+p^T').EGj8J"tNq`SR`/(Vol`u>&rr<"S
7157 rVm)&i;3>rLnNc-rrE#trrE#trrE#trrE&urr<m4k2mfgec5XL!<<)n-j5RnrTL:Js8N'!rVult
7158 rVults8NN%-j5RnrTL:Js8N'!rVultrr3$>!5eO2rrE#trrE#trrE*!#ji$._Y_1X%IX5q"L.qD
7159 !4r./rrE&urrE#trrE*!#LWZ"kN>hF!;c^0mL0E0qV>QZm0jB>qn`^Mmf3:e!<)rt!<3!"*!!kT
7160 rs(XdJGR>Y!!*#urrE&urrE#trrE*!%/2.QNp$B)X$Qdc!!)ut$;.u(pQkk:s8N'!q>^Hprr;uu
7161 rVultrVultrr;uu(f9AW+Tg3orr<'!s7[oENp$B)X$Qdc!!)utrrE#trrE*!%/2.QNp$B)X$Qdc
7162 !!)utrrE&u!ZV3Wq#C?orVultrVults8NAl$k'rL_@$h@rr3,+!#P^IrVultrr;uurVults8N>P
7163 ![[$m<<*$orsAH%!0I6\NrT7VrVultrr;uurVults8Nkb![6^f:B1Cps6U4&_Y_1X%IX8rM?!;'
7164 "I]>f<E4P~>
7165 s*'"oJH16$JH1B(s*+KCdJjJc!FFmb]b(>'q>^HprVults8N_H"Y87$UBN4Ds8P%YNr-DQ!!*#u
7166 rrE#t#%l*UmpQ3IirB#YrVultrVultrVultrr;uu(i8ch%L;G%rr<'!s4e.qVssT?QmVk5!!)ut
7167 rrE#trrE*!%,;C(VssT?QmVk5!!)utrrE&u!Y#.cq#C?orVultrVults8NA>"Y87$UBN4Drr3*u
7168 !!rYcrVultrr;uurVults8N=]!F><EMuWkSrtN0O,L$&/3WHht/(jZm"YBHKrr<&ts8N)urrNW0
7169 h>[EZ)$$i9W/L]Vrr;uurr;uurVults8NM_&.YW-qqd\es8N'!rVm4:bkgd:!.k1M!!)iprrE&u
7170 rrE#trrE#trrE&urr<mPo$7dNmf3:e!<<)S&.YW-qqd\es8N'!rVultrVults8NM_&.YW-qqd\e
7171 s8N'!rVultrr3$/!8[GMrrE#trrE#trrE*!#epNnf_M9G/GT5E"Ao.*!9=%XrrE&urrE#trrE*!
7172 #DrOfo?iKs!;QR#huNi-s8P"X#Q4Q#rrE&urrE#trrE*!(6/Duo$3$k!<<)6"Y87$UBN4Ds8R]N
7173 p=0;.!;]\qJ,~>
7174 s!WEuJH16$JH1B(s![nId/O=%<YtoH2OF4=rrE#trrE&u#530_"V=;Hrr36&N>Md^irB)Ys8N)t
7175 rs%.g*!-dQh;\J7!<)rt!<)rt!<)rt!<3#u!!N+%#8W$ms8N)ursSh"5S*u39WJ-m!!)utrrE#t
7176 rrE&u$iZhb&-<S?WrN)!!<)rt!<3!$mnsf"!;c`q!<)rt!<)rt!<3!&p2qM^&5("Arri9C!!M]f
7177 s8N)us8N)ts8N)urs$t0">%dt!Vua*oPGKJ+Gg'tp2qM^&5("Bs8N)ts8N)urseEp'*/+5qJ6`J
7178 6/MYBrr;uurr;uurVultrr3B*Tg0.j'hkY-rr<&trsIFk*!-dQh>d?P$Mj`%!<3#u!<)rt!<)rt
7179 !<3#u!!N+%#8W$ms8N)ursSh"5S*u39WJ-m!!)utrrE#trrE&u$iZhb&-<S?WrN)!!<)rt!<3!$
7180 mnsf"!;c`q!<)rt!<)rt!<3!&p2qM^&5("Arri9C!!M]fs8N)us8N)ts8N)urs$t0">%dt!VcU!
7181 E<).$s764"r;Zcsrr;uurVultrr32S2$>GQ!!*#u#530_"V=;Hrr3"Xs7Y4NScJXf<Ib~>
7182 s&FUMJH16$JH1B(rDh5E#2Q5=Ll\Ljq#CAMrVunRrr32pZ]^0.Zh==t#QD8pN3W;:M#RGSM#I>X
7183 iNA9!Q+?eOs8N)ts8N)ts8N)ts8N)us8N'%n3-q!X8`/!!<3!+qh[-<"<Lmes8N'!rVultrVult
7184 rr3B'M)5VD*aZbarr<&ts8N)urrgq;$ipA)s8N)ts8N)ts8N)urs%Xk('>=Xl2CVbq?R',qu-Qp
7185 !<3#u!<)rt!<3!&V]l70n,NOcrsn*k&-FS`s8V7e('>=Xl2L__!<)rt!<3!-f00TD!<;[f#n'o2
7186 !!*#urrE&urrE#trrE&u$i>c;$j7VX_uK`:!<)p)^JY[G)eo'Hp&Gm(s8N)us8N)ts8N)ts8N)u
7187 s8N'%n3-q!X8`/!!<3!+qh[-<"<Lmes8N'!rVultrVultrr3B'M)5VD*aZbarr<&ts8N)urrgq;
7188 $ipA)s8N)ts8N)ts8N)urs%Xk('>=Xl2CVbq?R',qu-Qp!<3#u!<)rt!<3!&V]l70n,NOars'MD
7189 jo>AB!$(q:rrE&urrE#trrE&u#-/sN5O\XQrr32c>S[DW?0V@g!K$jMg'!iEqc-XH~>
7190 s*'"oJH16$JH1B(s*+KCd/O<:2@BU(<nR3IrrE#trrE&u#/s1G"X8-`rr35r9aD;Squ?`rs8N)t
7191 rs#;c$j7r1r8RbV!<)rt!<)rt!<)rt!<3#u!!LFo"?"g1s8N)ursS79.1$5-DqtBm!!)utrrE#t
7192 rrE&u$gr'b#mVksh#IBS!<)rt!<3!$W\=YY!;c`q!<)rt!<)rt!<3!&`C^[F,'N\YrrhTi!$V=>
7193 s8N)us8N)ts8N)urs"#h#[d3(#l4K1_F"Y85g03-`C^[F,'N\Zs8N)ts8N)ursbt^#6=i)eN*jJ
7194 Gl.OArr;uurr;uurVultrr3AoF"%D#-u[o@rr<&trsGSg$j7r1r;YIN8,<2b!<3#u!<)rt!<)rt
7195 !<3#u!!LFo"?"g1s8N)ursS79.1$5-DqtBm!!)utrrE#trrE&u$gr'b#mVksh#IBS!<)rt!<3!$
7196 W\=YY!;c`q!<)rt!<)rt!<3!&`C^[F,'N\YrrhTi!$V=>s8N)us8N)ts8N)urs"#h#[d3(#l"?(%
7197 06#"s,d;$r;Zcsrr;uurVultrr31V('e+?!!*#u#/s1G"X8-`rr3"Ns7XtGOT>5X<Ib~>
7198 s!WEuJH16$JH1B(s![nIJcFR+rr@WMs8N/s!!f;!!nmaRj8],ZJcGcM!r;m%`r?'us7Y4NScJXf
7199 <Ib~>
7200 s&FUMJH16$JH1B(rDeFKh>dKTJcGcM!qQC%U]1Ch"lA;>rr@WMs8N/l!"R$K!K$jMg'!iEqc-XH~>
7201 s*'"oJH16$JH1B(s*+KCJcFR+rr@WMs8N/F!'-hS!^dXlj8],ZJcGcM!mL^*`r?'ks7XtGOT>5X
7202 <Ib~>
7203 s!WEuJH16$JH1B(s![nIJcFR+rr@WMs8N/[!#hX4!G,Zus8N(Ms8W*#iW'n:rrJ)Yp=oeB!;fbr
7204 J,~>
7205 s&FUMJH16$JH1B(rDeFKh>dKTJcGcM!k/.nU]1?5U>l4Q!.k1MrrTY050!U'M?!;'"I]>f<E4P~>
7206 s*'"oJH16$JH1B(s*+KCJcFR+rr@WMs8N.#!2cOk!=[W?s8N(Ms8W*#<</o9rrI`Op=0;.!;]\q
7207 J,~>
7208 s!WEuJH16$JH1B(s![nIJcFR+rr@]O"usj)fero(K)biNKDu-8bl$-P!h[L4!K@'Pg]X2Kqc-XH~>
7209 s&FUMJH16$JH1B(rDeFKh>dKTKDu-_h#5/$"Q4n3rr@]O#%-0a`!uq.`r?'rs7Y.LRK34b<Ib~>
7210 s*'"oJH16$JH1B(s*+KCJcFR+rr@]O#(Z"8W<Wq(K)biNKDu.+lM@Ib%e@X>!J:@FeHD!7qGgOG~>
7211 s!WEuJH16$JH1B(s![nIJcFR+rr@]O"jKLE"YZL!s8N(OrrpY:$O&2U`W#sts7Y4NScJXf<Ib~>
7212 s&FUMJH16$JH1B(rDeFKh>dKTKDu+U1^47N_L_ae!/(:TX#("e5JkD>!K$jMg'!iEqc-XH~>
7213 s*'"oJH16$JH1B(s*+KCJcFR+rr@]O"cOc1&5qYAs8N(Orrn?.!t\Am`W#sjs7XtGOT>5X<Ib~>
7214 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
7215 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
7216 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
7217 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
7218 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
7219 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
7220 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
7221 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
7222 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
7223 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
7224 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
7225 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
7226 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
7227 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
7228 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
7229 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
7230 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
7231 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
7232 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
7233 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
7234 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
7235 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
7236 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
7237 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
7238 s!WEuJH16$JH1B(s![nI[K$7,U&Y,mScA]ih#IBSrr;uu\GuR/l2Ub`o`#'lKdI!(o`+pkrr3-!
7239 KdI!(o`+pk^]4<6o`#'lKdI!(b5VL$s7Y4NScJXf<Ib~>
7240 s&FUMJH16$JH1B(rDg9*s+mBKrrAVirrCjSrrE&urrBS/rrD<`rrD]k"SldO!s%unrrE&u"SldO
7241 !s%unrrBh6rrD]k"SldO!s$LD!K$jMg'!iEqc-XH~>
7242 s*'"oJH16$JH1B(s*+KC[K$7,U&Y,mScA]ih#IBSrr;uu\GuR/l2Ub`o`#'S<"o?5o`+pkrr3,]
7243 <"o?5o`+pk^]4<6o`#'S<"o?5b5VKos7XtGOT>5X<Ib~>
7244 s!WEuJH16$JH1B(s![nIdJjF/GV0403MHBNqZ-BjrrBq9rrD'YrrC@ErrCLIrrCjSrrE&urrD<`
7245 rrDNfrrDHdrrDusrrD<`rrD]k#GV9)p&G$l!;HNn!<3!#UB"TmqZ$Qqr;Zcs^]4<6o`#/k!+#9t
7246 rr<&Ps8N)nrrJ)Yp=oeB!;fbrJ,~>
7247 s&FUMJH16$JH1B(rDh8F#3NF_MNFjtr;ZYMp](8L_Z0W9irB#YcN!nEdf9=Ih#IBSrr;uul2Ub`
7248 n,NCfmJm1dr;Zcsl2Ub`o`#.h!202grr<&ns8N)urrYmoT_eNbrrDusrrBh6rrD]k#>5&iqZ$Qq
7249 !87DP!;HKoM?!;'"I]>f<E4P~>
7250 s*'"oJH16$JH1B(s*+KCdJjEW<>YiV>iGV\qZ-BjrrBq9rrD'YrrC@ErrCLIrrCjSrrE&urrD<`
7251 rrDNfrrDHdrrDusrrD<`rrD]k#9El`rr;uu!;HNn!<3!#*WX.XqZ$Qqr;Zcs^]4<6o`#.;!6"m:
7252 rr<&Ps8N)nrrI`Op=0;.!;]\qJ,~>
7253 s!WEuJH16$JH1B(s![nIdJjFO+0Y@s>6/mFs8N)js8N)9s8N)Ys8N)Es8N)"s8N)[s8N)fs8N)d
7254 s8N)ss8N)`s8N)krrO2@mf*7d!:p-k*<>O's8N)ss8N)6s8N)krrO2@mf*7d!87DP!;HKoN;rV,
7255 "J,Vj<E4P~>
7256 s&FUMJH16$JH1B(rDh8F#Df8<rT]r1h#79QM"CZHLr02l!94%Y!7(WE!3?/"!9F1[!:Tsf!:Bgd
7257 !;uls!9sO`!;-9m#6=Z#s8N)irrNE*qt^9l!;uls!5JR6!;-9m#6=Z#s8N)Ps8N)nrrIuVp=]Y<
7258 !;fbrJ,~>
7259 s*'"oJH16$JH1B(s*+KCdJjFOAD-dl&d@:ns8N)js8N)9s8N)Ys8N)Es8N)"s8N)[s8N)fs8N)d
7260 s8N)ss8N)`s8N)krrN<'rr2rt!:p-k"9AGss8N)ss8N)6s8N)krrN<'rr2rt!87DP!;HKoK)bPp
7261 "H`]\<E4P~>
7262 s!WEuJH16$JH1B(s![nIdJj58r;Q]tp&GHus8N)js8N)9s8N)Ys8N)Es8N)"s8N)[s8N)fs8N)d
7263 s8N)ss8N)`s8N)ks8N)ts8N)is8N)os8N)ss8N)6s8N)ks8N)ts8N)Ps8N)nrrJ)Yp=oeB!;fbr
7264 J,~>
7265 s&FUMJH16$JH1B(rDh8F!5AF3!qqG4rVunRoDeiH_Z0W9irB#YcN!nEX8i2"jT#5[n,NCfmJm1d
7266 r;Zcsl2Ub`o`+pkrVulto)J^iq#C?or;Zcs^]4<6o`+pkrVultg&M'Pp\t8Ns7Y.LRK34b<Ib~>
7267 s*'"oJH16$JH1B(s*+KCdJj3BrVlr&!*&psrrDZjrrBq9rrD'YrrC@ErrB,"rrD-[rrDNfrrDHd
7268 rrDusrrD<`rrD]krrE#trrDWirrDiorrDusrrBh6rrD]krrE#trrCaPrrDfn!J:@FeHD!7qGgOG~>
7269 s!WEuJH16$JH1B(s![nIbl7bC!!<-!rrDZjrr<6$HkH`[o`"jpp3._c&kpIIs8N)ts8N)us8N'+
7270 p.GMfqgp4##rIt8s8N)ts8N',[email protected](CF(9rr;uu"SlC1(l81krrE&u#5jH7#n0&/rr;uu
7271 $iPGg%qkq>Eu,0]q>UBur/EB:$pV<%s8N'(rHo4a:%\JcqZ-Kmrr<H*Hkm6*s8-jR$<$^!rsSOE
7272 ,6ecSb5_,7"nMZm#5\].ec,ULrr;uu"oWf]#u1'krs%"2"Y@q!!;ZX$ol2#U*f'dq!!*#urrE&u
7273 #5jH7#n0&/rr;uu#Q9#_#u1'ls8)d$s8.Br"pm,Pqu?Nns8N;sG9[;)9Zm53qZ-Zrrr<6$HkH`[
7274 o`"jpr/EB:$pV;us8N)urs8O^0F8.P\c;^&!;c`q!<<)r!;ulo!<<*!!!W=K&d_;)rr3B(NA(YI
7275 5Ipgg"U!T[rr`0+!n@,I#4mWf!uktLrr;uu$hd3qs8W"V0F8.P\bZ:*!<3!(r/EB:$pV<&s7HBl
7276 s8N',[email protected](CF(9rr3Q'G9[;)9ZmD8qgp4##rItJqZ-Km!K@'Pg]X2Kqc-XH~>
7277 s&FUMJH16$JH1B(rDh)A!r[q3rVunRoDeiH"oPZbO1G8hrs&/'PDPL1pAY*lM#IARM#RGSL^NdH
7278 M#[@_QALX"g[5%@!<)rt!"8U/%iC*%oiVh;E;ok:rr<2l63JU;rr;uurr32sFX%)&:u2-Nrr<H&
7279 ?4Rm.s7KM+&9.XJrs&4?,6e`Vh>[HS!!i=(#nLbKs8VrrqZ$Qq$i+*>(l/.a=V)-`rr2p*l!>2/
7280 (glV/kPttfrr32q!X&,q!!*#urr<5u>6tgSrVlg$W$;F3nc/[crs@dj'Eg"bs8N'!rr;uurr32s
7281 FX%)&:u2-Nrr<<">6tgSrVuop!!iPtBH70a6F-LgqZ-Zr#3fG2!uPD2qZ$Ems8W*!"o2@/%r)"A
7282 rs&4?,6e`Vh>.*N!<3!(pN7\b&Q%<`s7HBgs8N*!s8)fos8)frs8N'&q-+.9C&S&2$hncg"qa\f
7283 s6Kajp\t0ppB(Njqu6l`B+>(kKDtlMrr<Gj0`h=SpN7\b&Q%<Zs8N)urs8@A,6e`Vh>dNJ!<<*!
7284 !"8U/%iC*%oiVh;E;ok:&F!L<!uPD2s8Ve+*<Qa;ZN'e%qYpSQs7Y.LRK34b<Ib~>
7285 s*'"oJH16$JH1B(s*+KCbl7b2!"Jo,rrDZjrr<5b63S6drr2p%a@m3N,^B(_s8N)ts8N)us8N'+
7286 ],h"QgJemh'NNTKs8N)ts8N'+k=#\#YlE<?#oo6/s8N'%bU`rWg&D$O!<3!&hd%*&)/&O>s8N'+
7287 k=#\#YlE<?#oo6/rs%@d)$Cgio)A[h!!hXQ"W<=!s8VrrqZ$Qq$Kjha+gD!u5RAEqrVm8H9G.OT
7288 Gk_64!%7dFrs$mP%K$/*!<3#u!!VLO"W<=!rr31S(("CE!!)ip$,f=C#=$E3rr<&us8N)urs%@d
7289 )$Cgio)A[h!!hXQ"W<=!s8Vrr#QNOX'`o(Ldej(A!<<''a@m3N,^B([s8)frs8N'&k!B4hNW/qW
7290 #2`](";tkCq>^Hprr38]>o<b_BCc*&o`4jgrrE*!qZ-QoqZ-Zrrr<5b63S6drr2p*hd%*&)/&O?
7291 YQ5X>rr3)T!Y"u'rrpqH#RE2[rVult$bIG\s8Ut^)$Cgio(i=c!<3!(hd%*&)/&O?s7HBls8N'+
7292 k=#\#YlE<?#oo6/rt*7F&dBV+p](9J<##HK<RUpE!;c]rK)bPp"H`]\<E4P~>
7293 s!WEuJH16$JH1B(s![nIbl7b-!"&W(rr<-?"!WZts8N'5Qb3'O!'(#Ypau`Epspku_uK`:!<)rt
7294 !<3#u!"+8"ir=Q0=6KM7Ep`o,!<)rt!"51'qNCnkBXdi%!'pP`rr>'9c1+d7P5kO^!<<)r8-G(I
7295 k=>`_s8N'!R()pU!+ooRqNCnEs8Vse"Hi?>8-H="rr<%c]D7?b3<&sX!;HNn!#h66qNCnkBXdi%
7296 !'pSapau`Epspku_uFcXA,cK4gAi,krr<&us8N'0Qb3'O!'(#Ym04*JnnnF-qYpot.Kl%.l@K!8
7297 !!*#urrE*!')P3&On@g-"LS4/!!&@tq2554rr;uurVm(Q!*A@]flHrhrrE#t#l$"UUA3:g#/g<;
7298 rrDusrr<Us]D7?b3<0$U8-G(Ik=>`_qZ$Qqs8NN)8-G(Ik=>`_s8N'!rVultp](6nrr;uuq#C?o
7299 r;Zcs'UQH-MZ>a:s8,=iOn@g-"LS2t!'C2[!oj7tqu6or(9.-!MZ>U5s8N'-JBQsPqa^jPo]JaJ
7300 [/0h&!<<'-qa^jPo]JaJ[/^.+!<)rt!;uls!$[f>qNCnkBXdi%!'pSapau`Epspku_uG8f=6KM7
7301 ErZ.>!;HKoN;rV,"J,Vj<E4P~>
7302 s&FUMJH16$JH1B(rDh)A!oo*!rVunR"-AD3g%YOHL_R2]qQ>Xms8VkTNT0orNK<l7s+lL0s8RoS
7303 s8Rl^WUf'KTSUbcr8t3Ms8N)ts8N',>13+I!4b2>p/qBTrr;uu3D\_s*s1'orr<'!s7RH<Z2)of
7304 #jD<g!!$3Np/qC+44<h*!0.$Yp)OCCq:->gkl:Y_!+".I;#l1Hs8N)ns8N';>13+I!4b2>p/qBT
7305 s8VNt$c2_U$4cS*+99I]rs#8!49,<\!<3#u!"WAcoMGU>s8ULK,3J#e!!)lq$LS</[.rEas8N'!
7306 rr;uus8N`**=&kFeJSYVs8N'!?.JRE!.k.LrrE#t"u?7=nG14+qZ$QqrVm/l%L^,M^^:S@qZ$Qq
7307 r;Zcs&7*iY;#l1Is7RH<Z2)of#jD-brrE*!%/(\HZ2)of#jD<g!!)utrrDfnrrE&urrDiorrDus
7308 rr<a=eau]=JcGcD*=&kFeJSYVs$$LDrr3&3!''lU#Oj.]r8qDfFoMF@!";?W_#O*K#I4*T)$oI&
7309 s8N*!rs\TA#I4*T)$oI+rr<&ts8N)ss8N'C>13+I!4b2>p/qBTs8VNt$c2_U$4cS*1B<F(q8u\:
7310 rr<&nrrIuVp=]Y<!;fbrJ,~>
7311 s*'"oJH16$JH1B(s*+KCbl7`W!)`^prr<-/#sm)8s8N'5@cuqt!7(WE_?MOBpRh[Cq#C?o!<)rt
7312 !<3#u!"*<,IfC,_YP.Y!1@>,A!<)rt!"3)olluMc;<@-h!7UrIrr>&on]_LKn,NCf!<<)P$m*Rg
7313 \dKYSs8N'!?01Dt!8LH5lluMZs8Ua\*m4Ak$R#0Crr<%.kNF#gcMmkD!;HNn!#f/)lluMc;<@-h
7314 !7UuJ_?MOBpRh[Cq#:j)kl1Sd6NE_Xrr<&us8N'0@cuqt!7(WEM?-oOd#.l(qYpo:"sV7fb;oV&
7315 !!*#urrE*!'%m[7b58aX+SPj8!!$KkkTBlNrr;uurVm':!3c+h\2*p\rrE#t#f6crfCtpA0DPDD
7316 rrDusrr<U>kNF#gcN!pt$m*Rg\dKYSqZ$Qqs8NM\$m*Rg\dKYSs8N'!rVultp](6nrr;uuq#C?o
7317 r;Zcs'Op7h+99^es4If%b58aX+SPgR!7_#J!`B#fqu6o87b[dl/HE`gs8N'-Aak0KfaJqEqmm.X
7318 pA4gh!<<'-faJqEqmm.XpAb-m!<)rt!;uls!$Y_1lluMc;<@-h!7UuJ_?MOBpRh[Cq#;'/YP.Y!
7319 1B7@S!;HKoK)bPp"H`]\<E4P~>
7320 s!WEuJH16$JH1B(s![nIc2RnD5lk]urrtF&qpRD'Gkh==!"*H?s7H@!s8T2$;?$S"h>e\urr<&t
7321 s8N)us8N'!C&\,6#lpshs8N)ts8N',B)ho)!!R!7s7QF"rr;uu%Vu+El2VV"rr<'!s1A>#rr3f#
7322 !#tt<!!$X2s7QErB)ho)!"/c+]DtD"rs\2n)uop<!,;K5o`,?us8N)ns8N'1B)ho)!!R!7s7QF"
7323 s8T2$;?$S"h>e\ui;a\nrs!QFErZ.>!<3#u!"WfDs7H@!s8S;`Du]k'!!)lq!ic5rqu?Zrrr;uu
7324 s8N/5!(Hne%-mm4s8N'!C&e5+!"/`*rrE#t!XSk+pAb-mrVlr$!)`aq!o<o"qZ$Qqr;Zcs$>KP?
7325 o`,@!s1A>#rr3&c!#te7rrE*!!k\M%rr32g!#tt<!!)utrrDfnrrE&urrDiorrDusrr<C?s8V`l
7326 $NL.=!(Hne%-mm4s7--po`+r^!,;0,!rW*'rr;uu!,;H4!k\M%rr3&c!#te7rrE*!!k\M%rr32g
7327 !#tt<!!)utrrDusrr<UBs8Vcm"_Rf7p&GI"s/c8urr32Z!$M:J!3,kqrrDfn!K@'Pg]X2Kqc-XH~>
7328 s&FUMJH16$JH1B(rDh,B"8e19ec#LPZgI_MO,2fjs8Rl^k5YJSLlq`;X,,L/rs%/4XT/<VM#IAR
7329 M#RGSL]HW;rrS%5kNW$H!<)rt!"6gHs6BXm`rH)(!#GS6rr<PSs8U=D1B7@S!<<(/!2'8j(XN.I
7330 s8N'!`rH))!"6gHs69S"s8QR/TDnj!ci??2rr<&@s8V<`'`S.4!;HNn!"d0Ms6BXm`rH)(!#GV7
7331 9E;<rrs#S*:B.X#2?*U[*rs[frr<&us8N'0aoDD*!#5J50*'E"s3L`GqYpUf!3?"srrE&urrE*!
7332 !b25&rr3DR!'pSa!!(.@s60Ltrr;uurVlp$!6b*9rrE#t!_`Turr3&%!)ECjrrDusrr<DJs8V<`
7333 '`\2C!2'8j!mgp4qZ$Qqs8N.1!2'8j#1*?8s8N'!rVultp](6nrr;uuq#C?or;Zcs$H`>Jkl;Ft
7334 s'l&$rr3DR!'pSB!"Su-s"sf"pAY3i!"Jr-rr<&Crr3%0!2'8j!mgp4qZ$Qqs8N.1!2'8j#1*?8
7335 s8N'!rVultr;Zcs&B=bMlMq=4s8V?a(B=D.!3lJ&#-@l#rrW8Equ?Zrp\t8Ns7Y.LRK34b<Ib~>
7336 s*'"oJH16$JH1B(s*+KCc2Rn##Qro]rs!o8p7hipk4nuV!".ujs.]Qls8O/@i;W`\:B7Qtrr<&t
7337 s8N)us8N'!lMgeb!<D3Fs8N)ts8N',kl:[^!#"Mqs/5p$rr;uu%dO)oCB0b%rr<'!s!Ig"rr3dU
7338 !2BMn!!)6_s/>u2kl:[]!*]F&-NMj!rsWrKUAt5n!9sO`UB"3ks8N)ns8N'1kl:[^!#"Mqs/5p$
7339 s8O/@i;W`\:B7Qt;?3'_rrrr5li6tb!<3#u!"\>os.]Qls8Nf6m/R*'!!)lq!Zh?uqu?Zrrr;uu
7340 s8N-J!87AO%!)ECs8N'!l2UdY!)igrrrE#t!W`;^pAb-mrVlp@!9!kV!`&g!qZ$Qqr;Zcs$L.Tj
7341 UB"3ls!Ig"rr3%@!2B>irrE*!![e!$rr31D!2BMn!!)utrrDfnrrE&urrDiorrDusrr<Djs8Sho
7342 ;ZHbE!87AO%!)ECs-<XFrr<!7!:':X!os>>rr;uu!:'R`![e!$rr3%@!2B>irrE*!![e!$rr31D
7343 !2BMn!!)utrrDusrr<Vos8T%u''TAqVuU$$ruV7!rr30u!3Z>&!9F%WrrDfn!J:@FeHD!7qGgOG~>
7344 s!WEuJH16$JH1B(s![nIcMn"GEWV'lrrVEb%f$)(!".T_s8E!"s8OnUd/O%Lq>^a"rr<&ts8N)u
7345 s8N'!fDbdRC]FJjP25L)rrE#trr<G`s8W&u!8dbUrW!$!s8N'/g].<N!!WE&!!*'!56/FsrtkV6
7346 "onT&!8dbUrVurTs8W&u!rr9b!5AI4%/g/0s8N'!hZ*WT!!<0"rrDfnrr<Ves8W&u!8dbUrW!$"
7347 s"j`&rr3Q+!!`K%+Tg*lp]:]ss8N'!rr;uu&)R?drW!$"s!@a$s8Vus!;c]s/ca>ss8N)us8N*!
7348 rrPCb^Ae-@r;[$$rr<&Us8W&u!ri6"!<)p$C]FJjP25s6rrE#t!]0o(rr3&r!!`<"rrDusrr<D_
7349 s8W&u!rr9b!5AI4!rW*&qZ$Qqs8N-b!5AI4#5nN*s8N'!rVultp](6nrr;uuq#C?or;Zcs$Jtg_
7350 rW!$"s$$Ltrr3E*!!WE&JH/jQr=oP1qYpVn3Y),h!!3*!rr<&Nrr3$a!5AI4!rW*&qZ$Qqs8N-b
7351 !5AI4#5nN*s8N'!rVultr;Zcs&DmHerVurTs8W&u!rr9W!7:`F$2OW+s(hZ90p:Als8N)nrrJ)Y
7352 p=oeB!;fbrJ,~>
7353 s&FUMJH16$JH1B(rDh/C"9,'Qh"^mNjbT5ts8Rl^qu?]qLl)03NemQ2rs&=UNrT-8M#IARM#RGS
7354 L]I>OrrngHLo\u!m/R(crVult$hs]$qu?`ks8Vus"TJH$!"Sc's7QF"s8N'!s8NT0nG`G(q>^p'
7355 rr<&ns8Vus!;HNnqu?m"rso,!rr3E'!"8i,!!)cns82j!rr;uup](6n&GQ5)qu?`ks8Vus"TSK2
7356 !;-9j&G,r3s8!!'p&FF\%fZM.!!*#urr<T(s8Vus"98B-!;HNnpAb3irrNQ.o_\[g!<3#u!<<'#%
7357 fl+urs\`($ig5,!;HNnqu?ius8N)trrjYJ!DK*Sq>^HprVlp.!;-9j!qZI%qZ$Qqr;Zcs$MXT#q
7358 u?j!rso,!rr3&r!"8Z'rrE*!!Y5;#rr33!!"8i,!!)utrrDfnrrE&urrDiorrDusrr<E#s8Vus"
7359 98B3!:^!f%/Kr3s8OVM[f?1-%/p)'"9"$-$2so)!WN-!!!)`lrrN]2nG`Fhq>^p"s8N*!rrN]2n
7360 G`Flq>^p'rr<&ts8N)ss8N'1p](9k!!)cns82j"s8NN.o`"jsoDf@#,QIj=T()aZrrDfn!K$jMg
7361 '!iEqc-XH~>
7362 s*'"oJH16$JH1B(s*+KCcMn":(D#3orrR*=F85e8!"/Z(s7--us8N9'qYpL!cN#g%rr<&ts8N)u
7363 s8N'!qu6U!&-)`AXnh>`rrE#trr<H)s8VWi!;ulsnc07#s8N'/qu?]M!%@mI!!*'!#6=Purtjo"
7364 /-#VL!;ulsnc/[fs8VWi&HDb8!;QQn%-[aBs8N'!r;Zff!"Al,rrDfnrr<W.s8VWi!;ulsnc07$
7365 rrrK"rr3AP!&X`A":G&+\,e\js8N)us8N'0r;Zff!"Ao-"T\K#s4[MRqYpU$!;cTmrrE&urrE*!
7366 !XA`#rr3Dk!%\*L!!)rss7--urr;uurVm$4!!-W4q>('j!<)p!"p"N!rrULH2#@7P!;uls!"/Z(
7367 s7--us8N<(q#:9pkl<71s8N*!rrNE*q#:9tkl<76rr<&ts8N)ns8N)us8N)os8N)ss8N'+r;Zff
7368 !"Ao-#6=PursS&k/-#V_!94%E"#0TO"8?aZ#6"T&"9/?#!!)oqrrNE*q#:9pkl<71s8N*!rrNE*
7369 q#:9tkl<76rr<&ts8N)ss8N'1r;Zff!!)rss7-.$s8N9'qYpL$cN#g%&-)`AXnhtrrrDfn!J:@F
7370 eHD!7qGgOG~>
7371 s!WEuJH16$JH1B(s![nIcMms!!e9tE!rW*#q#C?orVults8N-,!;ZTn"TSW(rr<&ts8N)us8N'!
7372 qu6U"q0=%^!!@T8s8N)ts8N)ts8N)ts8N)us8N'!qYpL/!!3-"!!*'!#lk&0!W`9$!WW0"!<)rt
7373 !<)rt!<<'-#lk&0!W`9$!WW0"!<)rt!<3#u!;HNn!<)rt!<)rt!<<'##lsf"rsA`-s8T\25l]43
7374 0E2"O!<3#u!<)rt!<<'#"9A>us8N)qrrN?(r;6No!<3#u!<<'-#lk&0!W`9$!WW0"!<)rt!<3#u
7375 !<)p%q0=%^!!@TEs8N)trrNK,q>L<o!!<#srrDusrrE#trrE*!#RLJ5!s/K'!!2rrrrE*!$jcn9
7376 !s/K'!!3-"!!)utrrDfnrrE&urrDiorrDusrrE#trrE*!&IAF>!s/K'!!3-"li7Lpkl<40rs,t4
7377 0A$.%!!*#urr<&rrr361!!<<)!<<*#qZ$Qqs8NK6!!<<)!<<*#s8N'!rVultr;ZcsrVultrVult
7378 s8N-,!;ZTn%0-J0q0=%^!!@TJrr<&nrrJ)Yp=oeB!;fbrJ,~>
7379 s&FUMJH16$JH1B(rDh/C!j.=7p\t<nLl2!-s+pXRs+p^T!JuX1rrn48s8Rn2rVunRrr<"SrVm)s
7380 [?-3#Mq[RurrE#trrE#trrE#trrE&urr<o8s8W&u!WW0"!<<'#!!<<)!<<*#s8N'!rVultrVult
7381 s8NK/!!<<)!<<*#s8N'!rVultrr;uup](6nrVultrVults8N-&!<2ut$iU,.s8QC*Sc=EEGlIaC
7382 !<3#u!<)rt!<<'(!<E-!s8DuuqYpQs!;c`q!<3#u!<<'-!WW<)!W`9$!WW0"!<)rt!<3#u!<)p%
7383 mpQh/!!]Y's8N)trrN9&rr2p!rW!&ss8N)ss8N)ts8N*!rs/Z+!s8T*!!!&rs8N*!rsSr/!s8T*
7384 !!!'"rr<&ts8N)ns8N)us8N)os8N)ss8N)ts8N*!rt,;4!s8T*!!!'"s3Ufcs2tCVqYpe4!,1Hm
7385 rVurts8N'!rr2p'!WW<)!W`9$!W)ir!<<'-!WW<)!W`9$!WW0"!<)rt!;uls!<)rt!<)rt!<<'#
7386 !s&?"rso#."97gu&c_n9YQ+V&!;HKoM?!;'"I]>f<E4P~>
7387 s*'"oJH16$JH1B(s*+KCci4+B+Ud6&rrVKd&GZ;*!<)rt!<<'"!<E)u#5A0*s8N'!rr3'!!!*#u
7388 rrE#t#1$!L!!!hnmJm1drVultrVultrVultrr;uurr3`0!!WE&!!*'!!<<3(!W`9$"98B$!<)rt
7389 !<)rt!<<'-!<<3(!W`9$"98B$!<)rt!<3#u!;HNn!<)rt!<)rt!<<'"!<E)u$hs]/s8OAFg&El/
7390 bPqPA!<3#u!<)rt!<<'"!<E-!!r;lsqYpQs!;c`q!<3#u!<<'-!<<3(!W`9$"98B$!<)rt!<3#u
7391 !<)p%cV4ZF!#OSis8N)trrE-#rVlro!"/T&rrDusrrE#trrE*!#QXo-!s/K'!!E)trrE*!$ip>1
7392 !s/K'!!E9$!!)utrrDfnrrE&urrDiorrDusrrE#trrE*!&HMk6!s/K'!!E9$HN7UV@fXIDrs((T
7393 P3r;F!!*#urrE#t#QXo-!s/K'!!E)trrE*!$ip>1!s/K'!!E9$!!)utrrDusrrE#trrE#trrE*!
7394 !<E3!rsnf($NJFH#QOi@i;`fW!;HKoK)bPp"H`]\<E4P~>
7395 s!WEuJH16$JH1B(s![nIci4'0!I4><!rW*$q#C?orVults8N-V!7:`F%/Kr.s8NH,o)Jaf!!*#u
7396 rrDoq"5eV/#4;Hj!<)rt!<)rt!<)rt!<3#u!"Rc`s8)d"s8N'!s8OhSeG9.E!<)rt!<)rt!<<'#
7397 1'#i"s8N)ts8N)us8N)ns8N)ts8N)ts8N*!rrOtVd/O%Qq>^a"s7H@#s&B*/rr;uurr;uurVult
7398 s8N<M!8[\Tqu?`nrrOhRdej(E!<3#u!<<'#1'#i"s8N)ts8N)us8N)qrr_//!!`<"rrE#t!]'i'
7399 rr3&r!!`<"rrDusrrE#trrE*!!\sc*o`+pks8N-U!7^iErrE#trrDfnrrE&urrDiorrDusrrE#t
7400 rrE*!!\sc*q#:M0!.h9QV#()r+TU9ss7lWprr;uurVlpS!7^Z@rrE*!!\sc*q>^HprVultr;Zcs
7401 rVultrVults8N-V!7:`F!r;m$rVm,[J,ffRrr<&nrrJ)Yopu6cqc-XH~>
7402 s&FUMJH16$JH1B(rDh2D!jda:pAY3mLl2!-s+pXRs+p^T!fi*5rr3E'LlVN8M2;02s8.V.rr<"S
7403 qYpZ^[>9k1s8N)ts8N)ts8N)ts8N)us8N'/p](9f!"/c+!!*'!$iotrs8N)ts8N)ts8N*!rrNT/
7404 p%eXf!<)rt!<3#u!;HNn!<)rt!<)rt!<<'#%06&"rsSH!%KHIk!#kkP!UfserrE&urrE#trrE*!
7405 #71D)s8Vfn!;c]s$ioqss8N)us8N*!rrNT/p%eXf!<)rt!<3#u!;c]tcX?e_qZ$QqrVlp.!;-9j
7406 !qZI%qZ$Qqr;ZcsrVults8N-/!;6!arrE*!!Xo)%q>^HprVultp](6nrr;uuq#C?or;ZcsrVult
7407 s8N-/!;6-e"WdZp70)TKrs&f0p](9a!!*#urrE#t!Xo)%o`+pks8N-/!;60frrE#trrDusrrE#t
7408 rrE#trrE*!!Y#/%rr3&l!"Jo,#L?fY%KHG.!;HKoM?!7;!s&3u<Ib~>
7409 s*'"oJH16$JH1B(s*+KCd/O4G.gOi&rrVHc'DVV-!<)rt!<<'#"p"N!rs[6S2#mRW!<3#uh>dQT
7410 s8N)rrri>91]TE#s8N)ts8N)ts8N)ts8N)us8N'/qu?]N!%7gH!!*'!"p"Prs8N)ts8N)ts8N*!
7411 rrNB)qt^9l!<)rt!<3#u!;HNn!<)rt!<)rt!<<'#"p"N!rsR0R2#mTL!+l0;"8MlqrrE&urrE#t
7412 rrE*!#6b,*s8UjS!;c]s"p"Mss8N)us8N*!rrNB)qt^9l!<)rt!<3#u!;ld!rkC8i2>[@Q!<)p!
7413 "p"N!rrUOI2#@7P!;uls!<)rt!<<'#"p"Pms8N*!rrNB)qt^9l!<)rt!;HNn!<3#u!;QTo!;uls
7414 !<)rt!<<'#"p"Pqrrii3mMu<#qYpd'!;uls`W-#<s8N)trrNB)qt0pg!<<'#"p"Prs8N)ts8N)s
7415 s8N)ts8N)ts8N*!rrNB)qYpKrci>p%rs8V=1]TE5rr<&nrrI`OooT=VqGgOG~>
7416 s!WEuJH16$JH1B(s![nId/O0>!GV6,!p'Cpq#C?orVults8N/%!)`aq%,V%,s8PssV>pSZ!!*#u
7417 rrDlp"9&9$rpKgd!<)rt!<)rt!<)rt!<3#u!"NiFs6BY"s8N'!s8TS/7JZu`!<)rt!<)rt!<<'#
7418 \,\tns8N)ts8N)urrNK,p\=dg!<)rt!<)rt!<<'#X8l,srrV'X+9)9CEWD@)&cMb0!<3#u!<)rt
7419 !<<'(P5oV&s6K^cqYpVt!)WRmrrE&urrE*!!k85!q>^HprVultrr3$+!;H?i"9&9$rql]s#ls`!
7420 rrT8%;?$RshZ+bprrNK,p\k-l!<)rt!<<'#\,\tis8N*!rrT\17JZu`!<)p!#ls_ps8N)us8N)o
7421 rrNK,p\k-l!<)rt!<<'#\,\tmrrhE`(*j@brs',9jT#89!!*#urrE#t!k85!o`+pks8N/1!(H_`
7422 rrE#t!XSl$rVultrVultrVults8N/%!)`aq!oEu"r;R$$!!3*!#ls_prrA#L!!<$t<Ib~>
7423 s&FUMJH16$JH1B(rDh5E!kF-9p&>*PLn"2>s+pXRs+p^T!iq.2rr3D\Lo^RUObi]1s5f&mrr<"S
7424 q>UNpLl(O!rrE#trrE#trrE#trrE&urr<PTs8U@E1&q7R!<<()!1<T^rrE#trrE#trrE*!!aPen
7425 q>^HprVultrr3$%!<)]mrrE#trrE#trrE*!!_WNtrr3&(!)3Cl"<[]j!%7aFrrE&urrE#trrE*!
7426 #;6)+s8UIH!;c]s8H>jhs8N)us8N*!rrQI+R/-d^!<)rt!<3!"!s&;rrrW&t!rDou!s&<!rrPgn
7427 Yl=Y(YQ.AnrrN9&rVccr!<)rt!<<'#>l^8as8N*!rrQI+R/-d^!<)p!!s&;ps8N)us8N)orrN9&
7428 rVccr!<)rt!<<'#>l^8errg%91C5&srs&Z,q>^Jn!!*#urrE#t!aPeno`+pks8N.+!1<T^rrE#t
7429 !WrH$rVultrVultrVults8N-n!3lJ&!jDYur;R$!!!<3#!s&;prr@oI!!<$t<Ib~>
7430 s*'"oJH16$JH1B(s*+KCd/O/("4[#D!bMFbq#C?orVults8N-B!9!kV$rI#,s8NE+p&G&)!!*#u
7431 rrDlp!poslmJm1drVultrVultrVultrr;uu%dX/pC]Kh%rr<'!s!7Zpq>^HprVultrVults8N-H
7432 !7^iErrE#trrE&u!<E2ps8N)ts8N)ts8N*!rrO8Bi;W`X;#m`trr`f3NW=Y/s8N)us8N)ts8N*!
7433 rs'5<m/R*(!!)lq!Zh?uqu?Zrrr;uus8N-H!7^iErrE#trrE&u!<E2rrrVQf#5\?#!<E)u!ZqF#
7434 rr3$s!3Q+t!<E2us8N)ts8N*!rrOJHeF`e@!<<'#,llHjs8N)trrE-#p](6nrr;uuq#:?q!;uls
7435 !<)rt!<<'#,llHirrcg3LBMDgrs&T*rVumi!!*#urrE#t![Riro`+pks8N-H!7^iErrE#t!<E2u
7436 s8N)ts8N)ts8N*!rrO8Bi;W`X;#m`rrs%ij#64](!;HKnK(AsDqGgOG~>
7437 s!WEuJH16$JH1B(s![nIdJj9P!*/jp#;3+Hqo'rcSG<-a!<)rt!<<'3paQHBq:@,$_#OGZ!$U[k
7438 ?N:**s8N)trrt!PmejTq(@D/%!<)rt!<)rt!<)rt!<3#u!#UO<nlZ!Rs8N'!s8W!p!c?]in@Mp)
7439 rr<&ts8N)ts8N*!rs\g'!c?]in@Mp)rr<&ts8N)urrZp7LAgrJrrE#trrE#trrE*!#l#kQU\WLl
7440 #/L6<"Q07d!*B.!rrE&urrE#trrE*!#OM[*dIV;W!;c^&paQE4p$72/rr<&us8N*!rs\g'!c?]i
7441 n@Mp)rr<&ts8N)ursWQ@LAh/P/#_n6\H!EArsi]BLAh/PpaQHBq:@,$_#"'5BE3ecrr;uurVult
7442 s8NB&;?C^ir:%=&qZ$Qqs8NN*;?C^ir:%=&s8N'!rVlt5!/CIJs8N)us8N)orrZp7LAh,OrrE#t
7443 rrE*!#lIR%D;5!X]3G76"&&[p7JZrgP5mi=hF%>Drr;uurVm0$;?C^ir:%=&qZ$Qqs8NN*;?C^i
7444 r:%=&s8N'!rVlt5!/CIOs8N)ts8N)ts8N*!rtbAZ"f(nF.gEfh/#_n6\H!EFs(DCerV?HnN:Xsh
7445 qc-XH~>
7446 s&FUMJH16$JH1B(rDh8F!l0W7q>U]$iqiQ*NJm3!s8RoRs8RoTrt>'dNT9utNK3c5s29_sqs1PD
7447 M#RGSM#I>XX5NjOcA8.\s8N)ts8N)ts8N)ts8N)us8N'9;!-m`!nI>N!!*'!pF$0)kPaVF63$rb
7448 !<)rt!<)rt!<<'-pF$0)kPaVF63$rb!<)rt!<3!"*!!kNs8N)ts8N)ts8N*!rs8!#$c;eX$OuP'
7449 rrfS,(]_/Gs8N)us8N)ts8N*!rs-sR-0OGk!!)lq$LS</[JJ]es8N'!rr;uus8NN%-j5RnrTL:J
7450 s8N'!rVultrr3$>!5ea8#"lQ$pQkk:qYpU:!5ea8#ji$._Y_1X%IX)m!ZV3WrVultrVults8NB!
7451 -j5RnrTL:JqZ$Qqs8NN%-j5RnrTL:Js8N'!rVlp=!5eO2rrE&urrDio!ZV3WrVultrVults8NB!
7452 -j5RnrTL:Jrr3-#'*&$/q>U[^!.ape8H8bis8N)trs8?I"HM[Dkc7#Gs8N*!rs\WM"HM[Dkc7#L
7453 rr<&trrO/?_YsN7!<)rt!<)rt!<<'6m0jB>qn`^Mmf,nlp%OdQ2#mRq!5eO2!/^<a!rGttJ,~>
7454 s*'"oJH16$JH1B(s*+KCdJj85!6+d6#AVQ[n<!kin+cq_!<)rt!<<'3^BH.?q4e*Eq#C@R!06rf
7455 PlLg`s8N)trs!)ZqX7hmJaNL;!<)rt!<)rt!<)rt!<3#u!#TPCcOL3Js8N'!s8Ujc%]AgnhO#Yi
7456 rr<&ts8N)ts8N*!rs[Zo%]AgnhO#Yirr<&ts8N)urrNW0h>%$M!<)rt!<)rt!<<')^BH.?q4e*E
7457 q#:9r;#gn&j8K#X!<3#u!<)rt!<<'(M?.#Sd>S&*qYpo:"s_@hbW5_'!!*#urrE*!%,;C(VssT?
7458 QmVk5!!)utrrE&u!Y#.crr317bkgd:!.k"H!Y#.crr38="Y87$UBN4DqYpU+!8[VRrrE#trrE*!
7459 #i#t$VssT?QmV\0rrE*!%,;C(VssT?QmVk5!!)ut!Y#.cq#C?orr;uuq#:C)!8[VRrrE#trrE*!
7460 #i#t$VssT?QmVh4"SrE)!8I>L#8mNEqP]>Q!<3#u!<)p'g^jsnnGD(0-MmcB!<<'-g^jsnnGD(0
7461 -NF)G!<)p!%055_s8N)ts8N)ts8N*!rtW9P/(jZm"YBHKB$C,?@/tlYrs\taq#:>Go=Y5%<E4P~>
7462 s!WEuJH16$JH1B(s![nIdJs"B$/Y^^fOPp&&P'A*s8N)ts8N)urs&1>+U&ELa8Z)Drf%`t52uVC
7463 rr;uurVm)TAfLjc<8HsArrE#trrE#trrE#trrE&urr<2t>6bptrr;uurr3B*Tg0.j'hkY-rr<&t
7464 s8N)ts8N)ursSh"5S*u39WJ-m!!)utrrE&u"Rf5%!<DurrrE#trrE#trrE&u#530_"V=;HrVm$!
7465 +92Q3rVultrr;uurVultrr32P1^#AS!!2oq$1r'Q![*=!rr<&us8N)ursSh"5S*u39WJ-m!!)ut
7466 rrE&u%.@(-!<E/QAfLjc<8IEN%I[1.!<E0"p2qM^&5("=rs8'k'*/+5rr<&ts8N)urs/Os5S*u3
7467 9WIshrrE&u$iZhb&-<S?WrN)!!<)p#mnsf"!;c`q!<3#u!;QR"mnsf"!<<'!!<)rt!<3!'rh2Rg
7468 !YnD/rVluO!!:pNrs/C:&I(PY!!*#urrDus#QCD^&-<S?Wqubq!<3!+rh2Rg!YnD/s8N'!rVm/l
7469 ;A0'2s8N'!rVultrVultrr3c-FWgo"9#pu3fk)3*'3*ffs6ii!!<Dur!0$Nf!rGttJ,~>
7470 s&FUMJH16$JH1B(rDh8Fq1o@Ss8V#ZOGT1,mJ$Y\M#IARM#RDYoWs^;P-ai\rs/P6O,U@ALku'1
7471 s+pXR#2u_HM3YXKmJm1drVultrVultrVultrr;uu"RnSW,HLhDrrE&u$i>c;$j7VX_uK`:!<)rt
7472 !<)rt!<3!+qh[-<"<Lmes8N'!rVultrr3,Q4q%GlqZ$QqrVultrVultrr32c>S[DW?0V=f"SrB(
7473 #lFT#rrE&urrE#trrE&u#,`XJ61=jUq>Uc^<tGHeVuQbs!<3#u!<3!+qh[-<"<Lmes8N'!rVult
7474 rr3DY4q%Gls1_GE!ZPkJqYq#V4q%Gls8V7e('>=Xl1t>bf00TD!<<'!!<)rt!<3!'qh[-<"<Lme
7475 qZ$Qqrr3B'M)5VD*aZbarr<&trrgq;$ipA)s8N)us8N)ors74?$ipA.rr<&ts8N)urs/FX1^jL.
7476 ?GlaA".0&kp\FgooM>i%=nhssrr;uur;R$!M)5VD*aZb\s8N)ursS^\1^jL.?GlgC!!)ut#hM6K
7477 !<E0"!!)utrrE#trrE&u(?\p<!u>2,s8Ti3&cs"dp](9F4q%GlqYpPPo>1S+<E4P~>
7478 s*'"oJH16$JH1B(s*+KCdJs"B$2ji'UH]+h,&QiDs8N)ts8N)urs$G7&-X8$pAY'soh>]'GPhF@
7479 rr;uurVm(u5n!lDKDb-:rrE#trrE#trrE#trrE&urr<2E.KhW\rr;uurr3AoF"%D#-u[o@rr<&t
7480 s8N)ts8N)ursS79.1$5-DqtBm!!)utrrE&u"KF-\!<DurrrE#trrE#trrE&u#/s1G"X8-`rVm#c
7481 "99VDrVultrr;uurVultrr31R'aS1=!!rE#$,T%:#=-K4rr<&us8N)ursS79.1$5-DqtBm!!)ut
7482 rrE&u%&tud!<E.r5n!lDKDbTG%B;)e!<E0"`C^[F,'N\Urs5VY#6=i)rr<&ts8N)urs.t5.1$5-
7483 Dqt3hrrE&u$gr'b#mVksh#IBS!<)p#W\=YY!;c`q!<3#u!;QR"W\=YY!<<'!!<)rt!<3!'mW0f`
7484 #:ONGrVls\!"f)(rs.(8"Vc4Z!!*#urrDus#OZX^#mVksh"q'N!<3!+mW0f`#:ONGs8N'!rVm/'
7485 0F%UYs8N'!rVultrVultrr3bQ8e;.MG4tt9V*PLm-\M?ss/IaX!<Dur!.sgU!r>nsJ,~>
7486 s!WEuJH16$JH1B(s![nIJcFR+rr@WMs8N/s!!e)T\GlW`!#ggr!0$Nf!rGttJ,~>
7487 s&FUMJH16$JH1B(rDeFKh>dKTJcGcM!qQC%JcE7[!hTHWN;im7o>1S+<E4P~>
7488 s*'"oJH16$JH1B(s*+KCJcFR+rr@WMs8N/F!',W1\GlUm!2GMQ!.sgU!r>nsJ,~>
7489 s!WEuJH16$JH1B(s![nIJcFR+rr@WMs8N/[!#gFg\GlWL!.Kn,!0$Nf!rGttJ,~>
7490 s&FUMJH16$JH1B(rDeFKh>dKTJcGcM!k/.nJcE7[!b;;]N;im7o>1S+<E4P~>
7491 s*'"oJH16$JH1B(s*+KCJcFR+rr@WMs8N.#!2b>I\GlUY!:>aF!.sgU!r>nsJ,~>
7492 s!WEuJH16$JH1B(s![nIJcFR+rr@]O"usj)fero(JcE:\!q]2.MuNd9o>C_-<E4P~>
7493 s&FUMJH16$JH1B(rDeFKh>dKTKDu-_h#5/$"Q4k2\c2`q'2+8`!/^<a!rGttJ,~>
7494 s*'"oJH16$JH1B(s*+KCJcFR+rr@]O#(Z"8W<Wq(JcE:\!nI[AMuNd/o=Y5%<E4P~>
7495 s!WEuJH16$JH1B(s![nIJcFR+rr@]O"jKLE"YZL!s1/.3!!>(;MuNd9o>C_-<E4P~>
7496 s&FUMJH16$JH1B(rDeFKh>dKTKDu+U1^47N_L_`trrW6*9_aPG!/^<a!rGttJ,~>
7497 s*'"oJH16$JH1B(s*+KCJcFR+rr@]O"cOc1&5qYAs1/.3!"<]AMuNd/o=Y5%<E4P~>
7498 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7499 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7500 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7501 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7502 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7503 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7504 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7505 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7506 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7507 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7508 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7509 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7510 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7511 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7512 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7513 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7514 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7515 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7516 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7517 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7518 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7519 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7520 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7521 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7522 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7523 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7524 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7525 s!WEuJH16$JH1B(s![nIdJs.Fmf34cJcC<$JcC<$i;We9o>C_-<E4P~>
7526 s&FUMJH16$JH1B(rDh8Fr;c9cr;_EKJcC<$JcF[.!/^<a!rGttJ,~>
7527 s*'"oJH16$JH1B(s*+KCdJs.Fmf34cJcC<$JcC<$i;We/o=Y5%<E4P~>
7528 s!WEuJH16$JH1B(s![nIdJs4HlMpkaJcC<$JcC<$i;We9o>C_-<E4P~>
7529 s&FUMJH16$JH1B(rDh8FrrD?arr@WMJcC<$JcF[.!/^<a!rGttJ,~>
7530 s*'"oJH16$JH1B(s*+KCdJs4HlMpkaJcC<$JcC<$i;We/o=Y5%<E4P~>
7531 s!WEuJH16$JH1B(s![nIdJs4HlMpkaJcC<$JcC<$i;We9o>C_-<E4P~>
7532 s&FUMJH16$JH1B(rDh8FrrD?arr@WMJcC<$JcF[.!/^<a!rGttJ,~>
7533 s*'"oJH16$JH1B(s*+KCdJs4HlMpkaJcC<$JcC<$i;We/o=Y5%<E4P~>
7534 s!WEuJH16$JH1B(s![nIdJs4HlMpkaJcC<$JcC<$i;We9o>C_-<E4P~>
7535 s&FUMJH16$JH1B(rDh8FrrD?arr@WMJcC<$JcF[.!/^<a!rGttJ,~>
7536 s*'"oJH16$JH1B(s*+KCdJs4HlMpkaJcC<$JcC<$i;We/o=Y5%<E4P~>
7537 s!WEuJH16$JH1B(s![nIdJs4HlMpkaJcC<$JcC<$i;We9o>C_-<E4P~>
7538 s&FUMJH16$JH1B(rDh8FrrD?arr@WMJcC<$JcF[.!/^<a!rGttJ,~>
7539 s*'"oJH16$JH1B(s*+KCdJs4HlMpkaJcC<$JcC<$i;We/o=Y5%<E4P~>
7540 s!WEuJH16$JH1B(s![nIdJs4HlMpkaJcC<$JcC<$i;We9o>C_-<E4P~>
7541 s&FUMJH16$JH1B(rDh8FrrD?arr@WMJcC<$JcF[.!/^<a!rGttJ,~>
7542 s*'"oJH16$JH1B(s*+KCdJs4HlMpkaJcC<$JcC<$i;We/o=Y5%<E4P~>
7543 s!WEuJH16$JH1B(s![nIdJs4HlMpkaJcC<$JcC<$i;We9o>C_-<E4P~>
7544 s&FUMJH16$JH1B(rDh8FrrD?arr@WMJcC<$JcF[.!/^<a!rGttJ,~>
7545 s*'"oJH16$JH1B(s*+KCdJs4HlMpkaJcC<$JcC<$i;We/o=Y5%<E4P~>
7546 s!WEuJH16$JH1B(s![nIdJs4HlMpkaJcC<$JcC<$i;We9o>C_-<E4P~>
7547 s&FUMJH16$JH1B(rDh8FrrD?arr@WMJcC<$JcF[.!/^<a!rGttJ,~>
7548 s*'"oJH16$JH1B(s*+KCdJs4HlMpkaJcC<$JcC<$i;We/o=Y5%<E4P~>
7549 s!WEuJH16$JH1B(s![nIdJs4HlMpkaJcC<$JcC<$i;We9o>C_-<E4P~>
7550 s&FUMJH16$JH1B(rDh8FrrD?arr@WMJcC<$JcF[.!/^<a!rGttJ,~>
7551 s*'"oJH16$JH1B(s*+KCdJs4HlMpkaJcC<$JcC<$i;We/o=Y5%<E4P~>
7552 s!WEuJH16$JH1B(s![nIdJs4HlMpkaJcC<$JcC<$i;We9o>C_-<E4P~>
7553 s&FUMJH16$JH1B(rDh8FrrD?arr@WMJcC<$JcF[.!/^<a!rGttJ,~>
7554 s*'"oJH16$JH1B(s*+KCdJs4HlMpkaJcC<$JcC<$i;We/o=Y5%<E4P~>
7555 s!WEuJH16$JH1B(s![nIdJs4HlMpkaJcC<$JcC<$i;We9o>C_-<E4P~>
7556 s&FUMJH16$JH1B(rDh8FrrD?arr@WMJcC<$JcF[.!/^<a!rGttJ,~>
7557 s*'"oJH16$JH1B(s*+KCdJs4HlMpkaJcC<$JcC<$i;We/o=Y5%<E4P~>
7558 s!WEuJH16$JH1B(s![nIdJs4Hqu?Zrrr;uurr;uur;ZcsJcC<$JcC<$i;We9o>C_-<E4P~>
7559 s&FUMJH16$JH1B(rDh8FrrDrrrrE&urrE&urrDusrr@WMJcC<$JcF[.!/^<a!rGttJ,~>
7560 s*'"oJH16$JH1B(s*+KCdJs4Hqu?Zrrr;uurr;uur;ZcsJcC<$JcC<$i;We/o=Y5%<E4P~>
7561 s!WEuJH16$JH1B(s![nIdJs4Hqu?Zrrr;uurr;uur;ZcsJcC<$JcC<$i;We9o>C_-<E4P~>
7562 s&FUMJH16$JH1B(rDh8FrrDrrrrE&urrE&urrDusrr@WMJcC<$JcF[.!/^<a!rGttJ,~>
7563 s*'"oJH16$JH1B(s*+KCdJs4Hqu?Zrrr;uurr;uur;ZcsJcC<$JcC<$i;We/o=Y5%<E4P~>
7564 s!WEuJH16$JH1B(s![nIdJs4HlMpkaJcC<$JcC<$i;We9o>C_-<E4P~>
7565 s&FUMJH16$JH1B(rDh8FrrD?arr@WMJcC<$JcF[.!/^<a!rGttJ,~>
7566 s*'"oJH16$JH1B(s*+KCdJs4HlMpkaJcC<$JcC<$i;We/o=Y5%<E4P~>
7567 s!WEuJH16$JH1B(s![nIdJs.Fmf34cJcC<$JcC<$i;We9o>C_-<E4P~>
7568 s&FUMJH16$JH1B(rDh8Fr;c9cr;_EKJcC<$JcF[.!/^<a!rGttJ,~>
7569 s*'"oJH16$JH1B(s*+KCdJs.Fmf34cJcC<$JcC<$i;We/o=Y5%<E4P~>
7570 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7571 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7572 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7573 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7574 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7575 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7576 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7577 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7578 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7579 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7580 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7581 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7582 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7583 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7584 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7585 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7586 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7587 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7588 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7589 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7590 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7591 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7592 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7593 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7594 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7595 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7596 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7597 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7598 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7599 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7600 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7601 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7602 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7603 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7604 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7605 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7606 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7607 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7608 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7609 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7610 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7611 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7612 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7613 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7614 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7615 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7616 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7617 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7618 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7619 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7620 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7621 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7622 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7623 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7624 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7625 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7626 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7627 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7628 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7629 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7630 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7631 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7632 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7633 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7634 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7635 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7636 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7637 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7638 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7639 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7640 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7641 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7642 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7643 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7644 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7645 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7646 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7647 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7648 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7649 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7650 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7651 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7652 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7653 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7654 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7655 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7656 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7657 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7658 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7659 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7660 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7661 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7662 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7663 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7664 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7665 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7666 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7667 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7668 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7669 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7670 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7671 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7672 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7673 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7674 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7675 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo>C_-<E4P~>
7676 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^<a!rGttJ,~>
7677 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o=Y5%<E4P~>
7678 s!WEuJH16$JH1B(s![nI`W,onJcC<$JcC<$eGfN-o>C_-<E4P~>
7679 s&FUMJH16$JH1B(rDgi:r\K-*JcC<$JcF7"!/^<a!rGttJ,~>
7680 s*'"oJH16$JH1B(s*+KC`W,onJcC<$JcC<$eGfN#o=Y5%<E4P~>
7681 s!WEuJH16$JH1B(s![nIcMn0pIo/?e7;/Cpr\K-*JcC<$JcF7"!0$Nf!rGttJ,~>
7682 s&FUMJH16$JH1B(rDh2D$3%S[8NAb'Ej>ZD1P,RWs+13$s4%&KM=\Rcqc-XH~>
7683 s*'"oJH16$JH1B(s*+KCci4=JWGG$_3`1=As8Fg*s+13$s+14"rr@ZB]`S%1<Ib~>
7684 s!WEuJH16$JH1B(s![nId/O.BHhfGts8Fg*s+13$s+14"rrA#L_ufg9<Ib~>
7685 s&FUMJH16$JH1B(rDh5E!Uj@j1B@IS1P,RWs+13$s4%&KM=\Rcqc-XH~>
7686 s*'"oJH16$JH1B(s*+KCd/O-o7enh?s8Fg*s+13$s+14"rr@ZB]`S%1<Ib~>
7687 s!WEuJH16$JH1B(s![nIdJjUQCbmk@^@M6f]la;R1P,RWs+13$s4%&KN:Xshqc-XH~>
7688 s&FUMJH16$JH1B(rDh8F$i3:J1MG&,q;SVes8Fg*s+13$s+14"rr@oI_?0U7<Ib~>
7689 s*'"oJH16$JH1B(s*+KCdJjU=4#8[Fg%kBrU.t[e1P,RWs+13$s4%&KK(HYWqGgOG~>
7690 s!WEuJH16$JH1B(s![nIdJj@$1G_JrqZ$ONrr36%WF%eI9S;R.s8FeXrhi7IC[V3%#Q:o<5;brW
7691 h1>TWs+13$s7ZHmN:Xshqc-XH~>
7692 s&FUMJH16$JH1B(rDh8F"IV&%?N0g$r\OQR#Ps`d3]U3*q>UEn1Bm`75sBhrrr36$Sm+<::Q+gq
7693 s+13$s+14Drr@oI_?0U7<Ib~>
7694 s*'"oJH16$JH1B(s*+KCdJj;R1Gb9ks8FhRrs.eA9fP:BW;Z_qr\F`OFZN![rVlg%mu1+(3`qsL
7695 JcC<$JcC<$pAY,Eo=Y5%<E4P~>
7696 s!WEuJH16$JH1B(s![nIdJj;q1GbTts8FhSrrN%7q_J=;hZ*WT1B=ZX1B^\Ws8@!81BBMYJcC<$
7697 JcC<$p\t5Po>C_-<E4P~>
7698 s&FUMJH16$JH1B(rDh8F"%>"%jn\rU1]RIUpItH?"&&Cgs8FeSH2TN%L&_2K;>W-M5k'@)JcC<$
7699 JcGKE!/^<a!rGttJ,~>
7700 s*'"oJH16$JH1B(s*+KCdJj;11GeXus8FhSrrLt>q_J=kr;Zfr1B:;N1Bbi"s5H9?1BC_UJcC<$
7701 JcC<$p\t5Fo=Y5%<E4P~>
7702 s!WEuJH16$JH1B(s![nIdJj;41GeLqs8FhSrsQh&1JR!,Shi0"s8W'S&P_ZK1G_&ks2ZuPJF*6^
7703 1G_OPs+13$s+14ErrA#L_ufg9<Ib~>
7704 s&FUMJH16$JH1B(rDh8F"#_qkqt^9k1]RI_I5<[$na^fY1O]<'r\G./p:iC>56(Y41Gc!%q7SR?
7705 @tFZ2s+13$s7cNnM=\Rcqc-XH~>
7706 s*'"oJH16$JH1B(s*+KCdJj;+1Gf"*s8FhSrsM[[1S+:&9f"TFs8W'S&Yf,Y1G`G=s%tR._>3bp
7707 1Gc7ds+13$s+14Err@ZB]`S%1<Ib~>
7708 s!WEuJH16$JH1B(s![nIdJj;41GeLqs8FhSrsN6k1W]Urq(jfes8W'S#f?W?1G^lfs'GLW!&fE.
7709 JcC<$JcGKE!0$Nf!rGttJ,~>
7710 s&FUMJH16$JH1B(rDh8F"#_qkqt^9k1]RI_4u5"cs8VXG1Htj=r\FiMs84Z/2?3\>q(i"2JcC<$
7711 JcC<$p\t5Mo>1S+<E4P~>
7712 s*'"oJH16$JH1B(s*+KCdJj;+1Gf"*s8FhSrsLhC1\q(Na>5V\s8W'S#l4Mj1G^uis#Bg1!)8%E
7713 JcC<$JcGKE!.sgU!r>nsJ,~>
7714 s!WEuJH16$JH1B(s![nIdJj;q1GbTts8FhSrrYA>1]%+Ns"a^6s8W'S!rW)ur\OTS!&s[/JcC<$
7715 JcC<$p\t5Po>C_-<E4P~>
7716 s&FUMJH16$JH1B(rDh8F"%>"%jn\rU1]RI_2)@&fs8W'S1H#44r\FWTs8W'Ss8N'VpbRL$JcC<$
7717 JcGKE!/^<a!rGttJ,~>
7718 s*'"oJH16$JH1B(s*+KCdJj;11GeXus8FhSrrP&61]ICXq(jfis8W'Ss8N)tr\OTS!&XI,JcC<$
7719 JcC<$p\t5Fo=Y5%<E4P~>
7720 s!WEuJH16$JH1B(s![nIdJj@$1G_JrqZ$ONs8NI81Gd,Ps7nH,3WK-Y1]IFR1]RIW?8FCZJcC<$
7721 JcC<$nc&TJo`#!nqc-XH~>
7722 s&FUMJH16$JH1B(rDh8F"ICo#?iKp%r\OTS$U-@&o)Ja\1G_5ps8FhRs8FhSrrYD?1\-+sJcC<$
7723 JcG9?!/^@J!s&3u<Ib~>
7724 s*'"oJH16$JH1B(s*+KCdJj;Q1Gb9ks8FhSrsLhC1\q(Na>5V\s8W'Srr;sRs8N0\1GeiXs+13$
7725 s+14?rr@ZCrrW8t<E4P~>
7726 s!WEuJH16$JH1B(s![nIdJjUQBeqP=^[qEk_0,eW1]RI_`\TDFk4tW*1Jn,Or\OQRr\OTS$-=tZ
7727 7EbN&iN[6Ns+13$s+14ErrJ)Yp=oeB!;fbrJ,~>
7728 s&FUMJH16$JH1B(rDh8F$i*1H1MP//qrP+ms8FhSrsO621N`3ZFYbh$s8W'Srr;sRs8NCW1G`Fm
7729 rV"p@>_2p+s+13$s7cNoM?!;'"I]>f<E4P~>
7730 s*'"oJH16$JH1B(s*+KCdJjU<4#8[Gg%tO#V,.-j1]RI_;):#!q<(I.1WBCor\OQRr\OTS#uWQ8
7731 K]W1(d@![Zs+13$s+14ErrI`Op=0;.!;]\qJ,~>
7732 s!WEuJH16$JH1B(s![nId/O.AGPO#ps8FhSrrN%5q_J=;h#IER1]IFR1]RIUrHe8qJcC<$JcC<$
7733 p\t8Qs7Y4NScJXf<Ib~>
7734 s&FUMJH16$JH1B(rDh5E!UX.f1B@IS1]RIUpIY6<"%i7es8FhRs8FhSrrMptq(mU%JcC<$JcGKE
7735 !K$jMg'!iEqc-XH~>
7736 s*'"oJH16$JH1B(s*+KCd/O-l7JS_>s8FhSrrLq=q_J=hr;Zfr1]IFR1]RIUk!Jl"JcC<$JcC<$
7737 p\t8Gs7XtGOT>5X<Ib~>
7738 s!WEuJH16$JH1B(s![nIcMn0nI8E$`6ti:or\OQR#Q:N*4>of_jo5;Z1]IFR1]IC[rk*,;2EOok
7739 `e"/@s+13$s7cNoN;rV,"J,Vj<E4P~>
7740 s&FUMJH16$JH1B(rDh2D$2qDV8NA_%Ej5TC1]ICZq3=r?3E24<rr;sRrr;sRrr39&WFS7O4^='!
7741 JcC<$JcC<$p\t8Ns7Y.LRK34b<Ib~>
7742 s*'"oJH16$JH1B(s*+KCci4=IW+naZ3Dk4?s8FhRrs.\<9/\n<V>^Dnr\OQRr\OQR#kjWi4Z,Q:
7743 S*,A&JcC<$JcGKE!J:@FeHD!7qGgOG~>
7744 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
7745 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
7746 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
7747 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^uGs4lC6qu?t+gt\J$qc-XH~>
7748 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8"H!04g04CS#?oj8RK34b<Ib~>
7749 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^u=s4,Y%qu?t(e^]c^qGgOG~>
7750 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2_#Hs4lD_6iI&k6eU8MScJXf<Ib~>
7751 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8"c<95g=J^k!!ksDg=htqqc-XH~>
7752 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2_#>s4,ZJ62gii6.4<6OT>5X<Ib~>
7753 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs8LdVdk:\Se,J,*ScJXf<Ib~>
7754 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jUg'#eV!&)b!g'!iEqc-XH~>
7755 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s8LOObq8uKc2Q5rOT>5X<Ib~>
7756 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs8C^Sb!*uHg]X2Kqc-XH~>
7757 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jTg&f>ZaSjfqRK34b<Ib~>
7758 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s8CIL_`Yj8eHD!7qGgOG~>
7759 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
7760 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
7761 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
7762 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
7763 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
7764 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
7765 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Y4NScJXf<Ib~>
7766 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jMg'!iEqc-XH~>
7767 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7XtGOT>5X<Ib~>
7768 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^lDs7Mrc!;fbrJ,~>
7769 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!K$jLRKEQe<E4P~>
7770 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^l:s7MKV!;]\qJ,~>
7771 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2^iCo)Jjh<E4P~>
7772 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8!/^:I!rGttJ,~>
7773 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2^i9o)Jjg<E4P~>
7774 s!WEuJH16$JH1B(s![nIJcC<$JcC<$Q2gCOs&FR~>
7775 s&FUMJH16$JH1B(rDeFKJcC<$JcD#8nb`>dJ,~>
7776 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$Q2gCNs&FR~>
7777 s!WEuJH16$JH1B(s![nIJW,/=JW,/=QAbh@n_F.EJ,~>
7778 s&FUMJH16$JH1B(rDeE*JVer7JVf\L!;l<?s&FR~>
7779 s*'"oJH16$JH1B(s*+KCJV&H)JV&H)Q@],5n^[Y>J,~>
7780 s!WEuJH16$JH1B(s![nI!0$RM!!%TMJcFF'!!%SgJ]-?^o`"plqsiJA<Ib~>
7781 s&FUMJH16$JH1B(rD`iSo`"mkJcC<$g&D$PJ\luTgqr^`!<E#egAb0'~>
7782 s*'"oJH16$JH1B(s*+KC!.skC!!%TMJcFF'!!%S`J\BjPo`"plqXN,9<Ib~>
7783 s!WEuJH16$JH1B(s![nI!K@'Pg]F&Is+/sVgtUTbScF>[J]-?^!<;cJ!hKDhn_F.EJ,~>
7784 s&FUMJH16$JH1B(rD`lTs7Y.JRK3A=g4@u4g&[WBJ\luTgqj'kp=]S:!;l<?s&FR~>
7785 s*'"oJH16$JH1B(s*+KC!J:@FeH1j5s+/^Oe_AUTOT9sGJ\BjP!<;cC!g*KZn^[Y>J,~>
7786 s!WEuJH16$JH1B(s![nI!K@'Pg]F&Is+/sVgtUTbScF>[J]-?^!<;cJ!hKDhn_F.EJ,~>
7787 s&FUMJH16$JH1B(rD`lTs7Y.JRK3A=g4@u4g&[WBJ\luTgqj'kp=]S:!;l<?s&FR~>
7788 s*'"oJH16$JH1B(s*+KC!J:@FeH1j5s+/^Oe_AUTOT9sGJ\BjP!<;cC!g*KZn^[Y>J,~>
7789 s!WEuJH16$JH1B(s![nI!K@'Vg]?0(rS.IG!<7W*J_]#8!M0:B`.>k^_uTi9g]:g:r7h@F!;l<A
7790 s&FR~>
7791 s&FUMJH16$JH1B(rD`lTs8:ROfqJAu!h',hJ_G\/gY)[s!.i"<_VE!.s8CXP?eG;1!h',dn_4"C
7792 J,~>
7793 s*'"oJH16$JH1B(s*+KC!J:@LeH+0lrRCt3!<7W#J^rN*!KdA5]n*lP]`A*2eH&t)r7(k2!;c69
7794 s&FR~>
7795 s!WEuJH16$JH1B(s![nI!K@'Wg]Q2pFn#Cc!hKDlJ_Yh3gY;h$!.i(>`8&92s8C^S!(YQ;g]F&I
7796 qsiJA<Ib~>
7797 s&FUMJH16$JH1B(rD`lTs8CXRes1CHrn7FB!<7W(J_Jl4!La">_L]SZ_>sW7g&_7Ddf%l$RK36T
7798 gAb0'~>
7799 s*'"oJH16$JH1B(s*+KC!J:@MeH=3_Fm]1Y!g*K_J^o>%gXQ=e!.hh7^"g:$s8CIL!(>*1eH1j5
7800 qXN,9<Ib~>
7801 s!WEuJH16$JH1B(s![nI!K@'Xg]Z,bF`m``g]F&Is+/sVgtUTbScF>[J]-?^!<<#Qrr<'RbPp8u
7802 ScJZXh#CB)~>
7803 s&FUMJH16$JH1B(rD`lTs8L^TdYi6js8L^RRK3A=g4@u4g&[WBJ\luTgqj'krS%8O!AMXpg&d]C
7804 qsiD?<Ib~>
7805 s*'"oJH16$JH1B(s*+KC!J:@NeHF-SF`m``eH1j5s+/^Oe_AUTOT9sGJ\BjP!<<#Jrr<'Q`;\9g
7806 OT>7Jec/X"~>
7807 s!WEuJH16$JH1B(s![nI!K@'Xg]3N:FTDI@g]F&Is+/sVgtUTbScF>[J]-?^!<<#QrVup^rnIRH
7808 !;l<As&FR~>
7809 s&FUMJH16$JH1B(rD`lTs8L^PP5]S(s8L^RRK3A=g4@u4g&[WBJ\luTgqj'krS%5N!'^D9!h',d
7810 n_4"CJ,~>
7811 s*'"oJH16$JH1B(s*+KC!J:@NeGt^1FTDI@eH1j5s+/^Oe_AUTOT9sGJ\BjP!<<#JrVup\rm_(4
7812 !;c69s&FR~>
7813 s!WEuJH16$JH1B(s![nI!K@'Xg]Z,hF`m``g]F&Is+/sVgtUTbScF>[J]-?^!<<#Qrr<'RbPp8u
7814 ScJZXh#CB)~>
7815 s&FUMJH16$JH1B(rD`lTs8L^TdZJZps8L^RRK3A=g4@u4g&[WBJ\luTgqj'krS%8O!AMXpg&d]C
7816 qsiD?<Ib~>
7817 s*'"oJH16$JH1B(s*+KC!J:@NeHF-YF`m``eH1j5s+/^Oe_AUTOT9sGJ\BjP!<<#Jrr<'Q`;\9g
7818 OT>7Jec/X"~>
7819 s!WEuJH16$JH1B(s![nI!K@'Wg]Q<&FoVHr!hKDlJ_Yh3gY;h$!.i(>`8&92s8C^S!(YQ;g]F&I
7820 qsiJA<Ib~>
7821 s&FUMJH16$JH1B(rD`lTs8CXRfq*?drn7FB!<7W(J_Jl4!La">_L]SZ_>sW7g&_7Ddf%l$RK36T
7822 gAb0'~>
7823 s*'"oJH16$JH1B(s*+KC!J:@MeH=<mFoVHk!g*K_J^o>%gXQ=e!.hh7^"g:$s8CIL!(>*1eH1j5
7824 qXN,9<Ib~>
7825 s!WEuJH16$JH1B(s![nI!K@'Ug]=MVrnIRH!<7W*J_]#8!M0:B`.>k^_uTi9g]:g:r7h@F!;l<A
7826 s&FR~>
7827 s&FUMJH16$JH1B(rD`lTs81LNXT/:R!h',hJ_G\/gY)[s!.i"<_VE!.s8CXP?eG;1!h',dn_4"C
7828 J,~>
7829 s*'"oJH16$JH1B(s*+KC!J:@KeH)`Nrm_(4!<7W#J^rN*!KdA5]n*lP]`A*2eH&t)r7(k2!;c69
7830 s&FR~>
7831 s!WEuJH16$JH1B(s![nI!K@'Tg]6jCg]F&Is+/sVgtUTbScF>[J]-?^!<;cJ!hKDhn_F.EJ,~>
7832 s&FUMJH16$JH1B(rD`lTs8(FLn,D#BRK3A=g4@u4g&[WBJ\luTgqj'kp=]S:!;l<?s&FR~>
7833 s*'"oJH16$JH1B(s*+KC!J:@JeH#"9eH1j5s+/^Oe_AUTOT9sGJ\BjP!<;cC!g*KZn^[Y>J,~>
7834 s!WEuJH16$JH1B(s![nI!K@'Pg]F&Is+/sVgtUTbScF>[J]-?^!<;cJ!hKDhn_F.EJ,~>
7835 s&FUMJH16$JH1B(rD`lTs7Y.JRK3A=g4@u4g&[WBJ\luTgqj'kp=]S:!;l<?s&FR~>
7836 s*'"oJH16$JH1B(s*+KC!J:@FeH1j5s+/^Oe_AUTOT9sGJ\BjP!<;cC!g*KZn^[Y>J,~>
7837 s!WEuJH16$JH1B(s![nI!K@'OScJikJY%Fag7A9EJ]*,Xgr'3mopu0aqsiJA<Ib~>
7838 s&FUMJH16$JH1B(rD`lTs7Mf]!<7V=JXY;]!!%SeJ\p3Z!<;_\!<E#egAb0'~>
7839 s*'"oJH16$JH1B(s*+KC!J:@EOT>I^JWYMGg5u@8J\?WJgq<^fooT7TqXN,9<Ib~>
7840 s!WEuJH16$JH1B(s![nI!/uI/JH3gmJ]*,Xgr/da!;l<As&FR~>
7841 s&FUMJH16$JH1B(rD`iSJH16$aoI"0J\p3Zo)Jdfn_4"CJ,~>
7842 s*'"oJH16$JH1B(s*+KC!.ob%JH3gmJ\?WJgqE:Z!;c69s&FR~>
7843 s!WEuJH16$JH1B(s![nIJbt#qJbt#qQ2C+,s&FR~>
7844 s&FUMJH16$JH1B(rDeFGJbt#qJbt`0n_4"CJ,~>
7845 s*'"oJH16$JH1B(s*+KCJbjroJbjroQ2:%$s&FR~>
7846 s!WEuJH16$JH1B(s![nIJH16$JH16$K`M-QJ,~>
7847 s&FUMJH16$JH1B(rDeCKJH16$JH1B(s&FR~>
7848 s*'"oJH16$JH1B(s*+KCJH16$JH16$K`M-QJ,~>
7849 s!WEuJH16$JH1B(s![nIJH16$JH16$K`M-QJ,~>
7850 s&FUMJH16$JH1B(rDeCKJH16$JH1B(s&FR~>
7851 s*'"oJH16$JH1B(s*+KCJH16$JH16$K`M-QJ,~>
7852 s!WEuJH16$JH1B(s![nIJH16$JH16$K`M-QJ,~>
7853 s&FUMJH16$JH1B(rDeCKJH16$JH1B(s&FR~>
7854 s*'"oJH16$JH1B(s*+KCJH16$JH16$K`M-QJ,~>
7855 s!WEuJH16$JH1B(s![nIJH16$JH16$_Z9`:m/[1dqZ-TpnGrUhpAk4nJ,~>
7856 s&FUMJH16$JH1B(rDeCKJH16$JH1B(s&FR~>
7857 s*'"oJH16$JH1B(s*+KCJH16$JH16$K`M-QJ,~>
7858 s!WEuJH16$JH1B(s![nIrrE*![fHI.`rQ)<r;cltf)YjNjT,>\lN$tbirK)Y!9s1W!/pjVJH4a2
7859 rr2u_jo>C>rr;BdrVufrrVuKiq>]XYs8N3"m'fL`!<<)d!<<)p!<<)h!<<)n!<6&L~>
7860 s&FUMJH16$JH1B(rDijts8TP.s8U+>rVufrs8U[Ns8V0\s8VBbs8V*Zrr2uEp&G*Qrr7NLj8f2Z
7861 !70d-!9=(YmK!4cr;cfrMZEcWJ,~>
7862 s*'"oJH16$JH1B(s*+KCrrE*![fHI.`rQ)<r;cltf)YjNjT,>\lN$tbirK)Y!)3(d!:p-hJH4a2
7863 rr2sljo>DPrr;BdrVufrrVqcUs&FR~>
7864 s!WEuJH16$JH1B(s![nIrrE*!q#LHpqZ-Zrkl:bos7-!e!Y,2"li@(cjT,>\irK,Zr;cltf)YjN
7865 o)Jh$s7,d_s8Vrrs8Vlp!Y,2"rW)uur;[$LSEKk6W[@WD!Y,2"p&P-mnc8^iJH4a2s8Voq!^$G^
7866 qZ$[,s7-$f!^$G^quHcsoDer(s6KR_s8Vrrs8VThs8V0\s8N3%)6`s6kQ(Y_q#LHpnGrUhpAk4n
7867 J,~>
7868 s&FUMJH16$JH1B(rDijts8Vlps8Vrrs8V<`!Zh="qu?d=s5E;Es8V0\s8V*Zs8W#ts8U[Ns8VZj
7869 !Zh="p&P-mqZ-Zrq#CI:s5EqWs8W#t#"#N_qr!_Hqu?d=s5EYOs8VWis8RWMj8f5[q>^SEs8Vrr
7870 !Zh="r;ZnHs8Vuss8V]k!n.+squHcsqZ-ZrMZEcWJ,~>
7871 s*'"oJH16$JH1B(s*+KCrrE*!q#LHpqZ-Zrkl:d#s-*?\!c.h"li@(cjT,>\irK,Zr;cltf)YjN
7872 o)Ji-s-*-Vs8Vrrs8Vlp!c.h"rW)uur;[%-_"IKQI0BHJ!c.h"p&P-mnc8^iJH4a2s8Voq!l+d8
7873 qZ$\5s-*B]!l+d8quHcsoDesYs(2*.s8Vrrs8RuWs&FR~>
7874 s!WEuJH16$JH1B(s![nIrrE*!q#LHpqZ-Zrkl:c_s/c+u!`K'"li@(cjT,>\irK,Zr;cltf)YjN
7875 o)Jhis/bVgs8Vlp!`K'"p](NPC*!IJs6TX`!`K'"p&P-mnc8^iJH4a2s8Vrr!u(J0s8)ct;ZEit
7876 !!<o0s8Vuss8V]k"5EkQ"T8?#s8)frs7$*hs82j"A)m9_"9&<#rr[W,rVuWms8W*!!uM!s!<)rr
7877 !!N_#lMT7QrW!?ngABDk!!*'!J+VPIr;[email protected](!!!/$q8NC6pAk4nJ,~>
7878 s&FUMJH16$JH1B(rDijts8Vlps8Vrrs8V<`!j_i"qu?f(s%MbZs8V0\s8V*Zs8W#ts8U[Ns8VZj
7879 !j_i"mK!:eq#CK%s%N1f#/O=R#&XChqu?f(s%N+ds8VWis8RWMj8f5[qZ$^OrVuop!!9J+9`>"o
7880 0E(qNquHcso`,*qpAager;cltqZ-ZrMZEcWJ,~>
7881 s*'"oJH16$JH1B(s*+KCrrE*!q#LHpqZ-Zrkl:eCruV(<!oX)"li@(cjT,>\irK,Zr;cltf)YjN
7882 o)JjMruUS.s8Vlp!oX)"p](Mr71B^*s,$XR!oX)"p&P-mnc8^iJH4a2s8Vrr")\&;s8)cti;Xkt
7883 !!@*;s8Vuss8V`l!sJN$g\_'Os8)frs,-mW<Ib~>
7884 s!WEuJH16$JH1B(s![nIrrE*!"b?+6K`D,Lrr<&qrrrK's*sXu0(],G"RZ$tr;[0-mJ7Cp!&VXh
7885 l@T!8$tJ>kWWN5$"KD49s8W&u"CgEd]GUAC#7@$er7>lf!;c`q!";3Jqpe4;!<<(KoAD8#!!Hck
7886 pq.IB!<<)t!<<'$J+VPIrW!(1j7p8(rW)uu$@Cb1rr<.kq9T*@pAb@"WVOO5s8E!$@cR6r)#O@B
7887 "RZ$t!!Abeci="F!<)rr!;c`o!!EGlq@N`+s7lWr!WW,s!!<Akq@WE$s8VWis8RWMj8f5[qu?j&
7888 _t!d,qu@',mJ7Cp!!L40s8Vuss8V`l":G2)s'bj+s8Vrrs8VThs8W#t"Y'J\0)rE[!<<'$jt?m=
7889 p]1?orr<*(s7lQns8W#t"eYg""!36s!"?Xi('!S"!<<)10)s])!<<)t!"CCWU*'Eh!!#Oh\1ms_
7890 pAk4nJ,~>
7891 s&FUMJH16$JH1B(rDijts8N8$pZbZW!;c]q!;c^"!<<(tq9'0<!!<Q(o`Y3n$46S%"98F-eGJ'1
7892 rW!%Xn*c/5!!N_Nq5F>nrW!(Yn+3:XpAbF:[.=%6;?-^ns8N'-DX7)8)?9d;s/>b:$iU,/MXU/3
7893 "oSH$s8;rtrr]4q`sVeG"H)[>UBUVss8NFqli-na#Jg2Gs8Vfn"U`?HW;lns!!J2Jo:lKe!"921
7894 o`P7"_"tS@rr<&ts8;ros8;p#$2X;t!<)rn!!39&r;?Tt$2X;tp&P-mnc8^iJH4a2s8Vus":4GQ
7895 s8Vus$46S%"98E-mbe'EquHcso`,+2s7$%)r;cltqZ-ZrMZEcWJ,~>
7896 s*'"oJH16$JH1B(s*+KCrrE*!"iC/k+TMN=rr<&qrrrK's2=`7"nVcs-iMWtr;[EWrRV&M!.No(
7897 b;fP&"02(T@f??:/`-,Ls8N'!"0(tZK*(cI#=6B(oX-@Q!;c`q!#1Ugo;rB#!<<);q5a`"!!B4n
7898 l[o9;!<<)t!<<',`VHG8!!!,#p$753rW)uu$FB@'rr=(mp6>UWpAbXShXl<trr<$$WV,S0!rN$,
7899 -iMWt!$0bdPlLa`!<)rr!;c`o!!F\Jf)YmMs7lWr%fc+u!!=VIf)bRFs8VWis8RWMj8f5[qu?jF
7900 pSn2mqu@'OrRV&M!$q<<s8Vuss8V`l"C_?+rsJ])s8Vrrs8RuWs&FR~>
7901 s!WEuJH16$JH1B(s![nIrrE*!".^/+q#(3ms8)frs8;rtrr]hbs4dJPs8Voq!\46"qu@ojs3q#K
7902 *WP@O$>TVA.K?k0s0ht.8,p(Qs8N'!.K?+as4[2I"eYg""!36r!<<)s!#33q('!S"!<<)10)sZ+
7903 !%IrB+91'n!<<)t!<<',\h=$;!!"JJU*'EhrW)uu$K`uF<WG,Z].s?cpAbXms0sc_rr<$Js.UV8
7904 gACpX.f[uu!'("j1&q:P!<<)r!<<)q!!4YMeGTCIs7u]t!^cqBr;ZmKs4$]As8VWis8RWMj8f5[
7905 qu?kAqaUVcqu?dJs4%#J"EaN1s8Vuss8V`l"=4#ms1nR5s8Vrrs8VThs8W#t"eu#X#64>p!<<'!
7906 ;tU.js8E!!s8Muts8W#t!qZF\p](X#qZ$Wrs#^Mcp\b*ls8;p,T`5u5s7lWp]Djnrs8Vfns&FR~>
7907 s&FUMJH16$JH1B(rDijts8N0t0)tG>!<<)r!<<)t!<<'$ARb\:r;cltq>^S6s-!9[,&R@C!!#Uj
7908 a;#AL!!$d6@Uf@P!!&qs@V5Z?!!$d6:dk>WpAbBWs"XX-VYpMps82j2Q5)+RdJs:Is(,[>V>pU2
7909 s%l,`U&=uks8;rtrsNCIs.o\qCB%*us.TDls8NGA*"%&nO8ig+s8Vfn%B'58B)hl2!,DO17/rtY
7910 !"*TCOoPKCs(6!Fs8;rts8)frs7u]sD?#dt!<<)q!!<C9s02G%!c@t#o`5$lnc8^iJH4a2s8Vus
7911 "Ln+@s8Vus!c@t#rW!)1pD3f/quHcso`,+us*4QIr;cltqZ-ZrMZEcWJ,~>
7912 s*'"oJH16$JH1B(s*+KCrrE*!""/$e_#495s8)frs8;rtrrXpas$lqes8Voq!lP%"qu@qYs#U2\
7913 PQ-^P,eF$V\Gn1ks![pJh#B"=s8N'!\Gmk<s%2qb"nM[7#!^9/!<<)s!#0J_D#\PV!<<'P\Go"u
7914 !4`%TP5e,P!<<)t!<<',0=_$N!!'P/-'J:"rW)uu$B>Z3Y5m#N0Y[SepAbZXs":q`rr<&/s!<j.
7915 8c/Pq_uDdu!7Lm$^An63!<<)r!<<)q!!:(<48f0Zs7u]t%&!W5r;Zo:s#]lRs8VWis8RWMj8f5[
7916 qu?lZh$O,]qu?f9s#^2["QJ5Ds8Vuss8V`l"Mk&\s!7OCs8Vrrs8RuWs&FR~>
7917 s!WEuJH16$JH1B(s![nIrrE*!!u(b8rquiss8)frs8;rtrrY@fs7cHls8Voq!kA5!qu?u3r^Hkf
7918 P5fFt!#;7.3X5WV!!'Y23X5Wa!!&\l*!609pAb9ds$cbas8Vlp&c__.!<<']#64Dt!20?3!rr)p
7919 !<<)t!<<',49ki[!!&\l*!609rW)uu!)rgr"g%_e#QOhu!"HR?3X5Wa!!&\l*!609qu@)6r^Hkf
7920 XT(Egs8W#ts8Vrrs8Voq!kA5!r;cltqZ-Wq!RD,O!!9\07eHc]s7-0is+(12!<<)t!!OnPJcPiN
7921 qu@)6r^Hkf/,k,#s8Vuss8V`l"BkbVs60C]s8Vrrs8VThs8W#t"nMZu!<<#s!<<'!$M=E!s8N'#
7922 !WW,t!<<)t!#9STrQU-/!!!V<oDeji!!*'!#QXo'r;cltr;[;ss8;lrrVurirs&Q(s7ZNn<Ib~>
7923 s&FUMJH16$JH1B(rDijts8N0(!WW/t!<<)r!<<)t!<<*!%KZUtr;cltqZ$^!mf!gs!!iVnrXf,1
7924 jSp4t!#=_t%M&O&!!)He%M&O=!!)6_"pFttpAb9mru(Y5s8Vlp&c_S*!<<'/%fbqs!9jFe"TS)l
7925 !<<)t!<<*!%LN1'!!)6_"pFttrW)uu!#5A3"mc0u&-)\(!"JAr%M&O=!!)6_"pFttr;[3+mf!du
7926 !:0Xp&-)\.!<<)r!<<)r!!<8irXo)/s8Vrrrr3#%!r`0%!Ufq!o`5$lnc8^iJH4a2s8W#t"_Ra%
7927 !<<)t!"/hqrXf,1B)Y0us8Vuss8V`l"Ng[&s2k3>s8Vrrs8RuWs&FR~>
7928 s*'"oJH16$JH1B(s*+KCrrE*!!s/],r;?Wqs8)frs8;rtrrWHds1/(.s8Vrr!sJAp#Q4W."S_`t
7929 !!)Ti%/^)?o`#+Vs.KDmp\tF\s8N'!o`#"+s3LE>!r`-+q>gQqq>_-0s53kWs8N9as1&+0o`#"+
7930 s3LWDs8W#ts8NH23rc_j!;-9n'*$;W!<<'!$2ji-p&>4^s8Vfn%JTl,4obN^!;-9n'*$;V!"/r(
7931 q?I!#p&>4^s8W#ts8Vrrs8Vrr!sJAp#Q4Z&s8)fqrrIcRrW!$'p\G-f!<<)i!<<(M!9=.[s8;p$
7932 X8<e8s8W#t$O$5##64b)q\fJ7s82lss7H?pkl6)2=oA@#s8)frs,-mW<Ib~>
7933 s!WEuJH16$JH1B(s![nIrrE*!rrE*!r;cltqZ-Zrr;clt!seo,rVZ`rs8)ct'`[Ir!!3l7lM^bb
7934 nGa$s!#>))#6=f&!!)Wj#6=f(!!)Qhr;Q`qpAbA<s8C2u&,cM.s8;p4&[_00s8Duus8N?)s8;ot
7935 nc/Ods8Mrss8W#ts8NH4!<;ut!:g*err;us!<<'!$N0r.nc&jps8Vfn%J0T)!<<'!!:g*err;ur
7936 !!3l7lM^benc&jps8W#ts8Vrrs8Vrr!Yk\"quHcsq>^U"@/nOO!!3l7lLY)Vs82lqs8)frs+(12
7937 !<<)t!!Vf*!!*'!r;Zm5s6BR`"n',*!<<)s!<<)l!!LUI/-#GD!<<)r!<<)h!<<)t!!Vuo#6=f&
7938 rW)uuoDnpkrr<*(s7lQns8W#t'`qdOr;YaV!2ojJ"98B$!<<')!<<#r!<<)t!!;cl$iBu.o`#-r
7939 s8Vfns&FR~>
7940 s&FUMJH16$JH1B(rDijts8W*!s8W#ts8Vrrs8W#ts8W*#!WW)r!<<)r!!4nTc27PC1&oMt!!<&t
7941 "8i-6r;Qd!s82isr;Qd!s8N'!qu?Tns8M`m"i:69_K,hX!<<)t!#7'+q#CBn!!*'!!WrE"!!)or
7942 r;Q`qr;cltr;cltrrNN,qu?`os8;lrrr)otrr<-!!!W9"!WrE%pAb[#rrE3$rr<&rs8;lrrqufu
7943 1&oMt!!W9"!WrE%r;cltqZ-ZrqZ$[Ps3:HAs8Voq!sk"gQMpjc1&oMj!<<)s!<)rp!<<(M!9=.[
7944 s8;p$qg\YHs8W#t!\s`"rW!-!J,fTLs82lss7H?poD]I'oDJ[hs8)frs,-mW<Ib~>
7945 s*'"oJH16$JH1B(s*+KCrrE*!rrE*!r;cltqZ-Zrr;clt!rrW,oDJ[hs8)ctNrO(r!!82\E;fh=
7946 rVlor!#>J4!!rVq!!)ut!"&]*!!)utr;Q`ppAbBZs6mC#!W<#us8;p4=kEQNs8Duus8N')s763j
7947 rVufps8Dlrs8W#ts8NH,#ljJr!<)rqrr;rr!<<'!!W<!%rVlj(s8Vfn%K6;,$31#*!<)rqrr;rq
7948 !!82\E;fh@rVlj(s8W#ts8Vrrs8Vrr!fm;"quHcsq>^U1cMpK8!!82\E:a/1s82lqs8)frs+(12
7949 !<<)t!!W<d!!*'!r;ZnZs)@r;"oU[d!<<)s!<<)l!!N,t.K@]l!<<)r!<<(W!<6&L~>
7950 s!WEuJH16$JH1B(s![nIrrE*!rrE*!r;cltqZ-Zrr;clt!seo,rUg-lE;tsr!!7->NrB"[nGa!r
7951 !#"o'#6=f&!!)Zk#6=f(!!)Wj$hOE&!arJ7s5NtWs8W#t&uYb\"98B$!<<')!<;ut!;$3uq>gQq
7952 r;clt#RCG1r;ZihrsS](s8Vus"n_g#!<<)n!"/Au#6=f(!!)Wj$i0i)E;tst!!W#p#QXo)r;clt
7953 qZ-ZrqZ$\:s,R!Ws8Vlp!X/Q#rW!"=s,Q^Os8VusrVu`ps8RWMj8f5[r;c]orW!"=s,R'YqZ$Ko
7954 s8Vcm!!rN&!)`^qs8Vrrs8VThs8W#t"eu#W#64>p!<<)k!<<*!!!3r9iViiWs7u^.(]XF6!;QR!
7955 #64]'!<<']#64Gr!!;Zi%fQG0V>jWp!!U"73X5WapAk4nJ,~>
7956 s&FUMJH16$JH1B(rDijts8W*!s8W#ts8Vrrs8W#ts8W*#!WW)j!!:FF1&M"Qc2TNt!!<&t"8i-3
7957 r;Qd!s82isr;Qd!s8N'!r;Qij!!NOL`r?"Kr;cltr;[Jps$Qqgrr<'!rrN9%qu?`prrW#ss8W#t
7958 s8W*##64T$!;uiuqZ-Zrqu?ourrN9%s7ZL#r;Qd!s8N'!r;Qip!!:FF1&_.Vr;Qg"s8W#ts8Vrr
7959 s8Vrr!mUa"quHcsq#CI's7cKm!mUa"oDnpkquH]qqZ-ZrJH4a2s8W#tqZ$Np!mUa"rW)fpr;clt
7960 p&G(+r;Qa1rW)uuqZ-ZrMZEcWJ,~>
7961 s*'"oJH16$JH1B(s*+KCrrE*!rrE*!r;cltqZ-Zrr;clt!rrW,oCW(blMhRr!!;Hc'`J(6rVlor
7962 !##81!!rVq!!)ut!"&]*!!)ut!V??q'T(E?s(hQ5s8W#t'(u8P#64]'!<<'!#ljJr!<)ouq>gQq
7963 r;clt#QP/1o)JdhrrMuss8Vus"o\H$$31&"!"/])!"&]*!!)ut!VuctlMhRt!!W?$!"&]*r;clt
7964 qZ-ZrqZ$]_rtPA2s8Vlp!\+0-rW!#brtP)*s8VusrVu`ps8RWMj8f5[r;c]orW!#brtPG4qZ$Ko
7965 s8Vcm!)`[o!!rQ(s8Vrrs8RuWs&FR~>
7966 s!WEuJH16$JH1B(s![nIrrE*!rrE*!r;Zlrs8)csr;Z]qs8N0`#64Gr!<<)s!!<K&pB:Ep!se\s
7967 "TAB&P5f=q!"u%+3<oNU!!'Y23X5Wa!!&kq=8Dpss7u]s(]XI4!!3#tr;[K*rs&c.rr<'!s#^Mc
7968 pAb2is&]$s!q?4"rW)uu#Wr=kpAb2is&]'ts8Vus"h=Rq#QOi&!<<)t!"-@<3X5Wa!!&kq=8Mt"
7969 #Q"/trW!,3s#gVes8;rts8)csr;ZZp!se\s"T/9"s7lX#!rr/u!!iAp"S;]os7-0is+(12!<<)p
7970 !<<)u!!<K&pB:<ms8Vuss8Vcm"s<m*!)3F'rW!#hrsnr,!q?4"nc8^ir;[!Ms0aKY\GcL.s7?<k
7971 rr`<<Y5D,q!<<)t!#<aI#93^9!!'/$B0?4o!!*'!\h3s;r;[Lms,[6]!%Is('GGoq!(d.!0E;(H
7972 !<6&L~>
7973 s&FUMJH16$JH1B(rDijts8W*!s8W#t!WN,r!!3*!r;cltrsf)0mem.cs82j!&cV2!r;Zp3rpBgd
7974 !!;6])uK[Kkl2)%s6'F_mf*b,s8N'!l2MLp!<<)q!!4tVqu$Kqrr;os')hh2%fcP/!<<'/%fbqs
7975 !9sLuq>^Torr`6#s8W*/#64)k!9sLuqZ-Zrqu?ogrsfS>s8;rts8;p)mf*b,s8N'!l2MLq!!<i4
7976 mK*:e"n)C#&-)\.!<<)r!!3*!qu?g2rpBgb!<<)p!!if/q#CC,rpBgZ!<<)i!<<(M!9=.[s7lZp
7977 s8E!#&cV2!q>gQqquHcsp&G:js189Cs%NCl!rN!"qu?fqrr\2[s&FR~>
7978 s*'"oJH16$JH1B(s*+KCrrE*!rrE*!r;Zlts8)csrr;oss8N0*3rcbh!<<)s!!5Xh\blF/7fKss
7979 !!;`k%/^)<o`#+Vs.TJnp\tF\s8N'!p&>?p!<<)q!!6U/nbiFgrr;os')qn249,<\!<<''3rc_j
7980 !;6?uq>^TqrrN*!s8N?/3rcbk!;6?uqZ-Zrqu?oprrt^fs8;rts8;p)p\tF\s8N'!p&>?q!!5Xh
7981 \buL3p\tF^s8W#ts8Vrr!WN,s!!5Xh\bcC,s7lX")?8n#!(Qsuo)Sgjnc8^iJH4a2s8Vlps8W&u
7982 !_31"q#LHpquHcsp&G<-s%EFQru_4?!r`-"qu?fsrrJ&Ys&FR~>
7983 s!WEuJH16$JH1B(s![nIrrE*!rrE*!r;Zo=s'ts,!lk7MrW)uu"1g)ag\h-Ps82iu49*4r!!57^
7984 _u0QU*WP=M$"s;=.K?h-s0r%/8H6.Ps8N'!.KA3<'7Tl[s8W#t"jKI@)uoU0!!:1?A,ZHCXoE#r
7985 s8N'!s8TY^s4[MR.KA3<'7Tl['9N6U!<<-"s10f^g].='s4nA&If9?Is82j#5l\GLs8W#ts8W#t%
7986 7pN.0E;%P!%Is('GGrp!!57^_u0Q=5l\GLs8W#ts8Vrr!lk7Mr;Zm\s24^6s8W#t$dhlc"CM2c!
7987 !#+\_t*m.s7-0is+(12!<<)p!<<)u!!57^_ta<4s82lss7QEs:]Ig&*WP4"!!A>_O9,:["-EPE!
7988 V6<ks82j"AEEQd"9&<#s7?<krri>h\4?Vrs8N'6/?A:;e5cPL(XW&ss8N'!s8RWBi@k-0'+r%Us
7989 8N'!=kNZ2GQ7^IXnp-=s7ZNn<Ib~>
7990 s&FUMJH16$JH1B(rDijts8W*!s8W#t!qH:Dqu?fgs"F?Os8N13@fN;'!<<)s!!8;_D>XA8OoK:s
7991 !$+]3`Y9#D!!$g7?ss"M!!&tt@:fK=!!$g7W!FN<r;cltr;[#%1BT?2lMU\anc(9A!#=i".WbXi
7992 !!*'!A7GS8!!$g7W!FN<r;ZoYs%<7js8NI;@fN>+!,MV5#U#c=!<<)s!!SnmAS1uBr;cltr;[;*
7993 s']L=rr<%7s/62GTDeflOoK:s!!SnmAS1uBr;cltqZ$]fs"F<N!g3M"qZ-Zrr;[525RRpWs/c8$
7994 OoK:i!<<)i!<<(M!9=.[s7lZps8E!"OoK:o!<<)s!<<)m!!^1;7fZ'Z^A\*6ir;XK!!;0[8rNcM
7995 <Ib~>
7996 s*'"oJH16$JH1B(s*+KCrrE*!rrE*!r;ZoorttY6!r2d4rW)uu""q+`7K!5ds82iueGh#r!!:[M
7997 .fB>fPQ-UL+M%OQ\c44hs![pJh#At;s8N'!\,U=K0uj.ls8W#t"cX`.>5t]&!!;rq)#aLMp&>]A
7998 s8N'!s8O^]s$Znf\,U=K0uj.l!qQ@>rW)uu$SJsh7fWOus)%ro`r5u<s82j#f`*V;s8W#ts8W#t%
7999 G^t8])Vd1!4VuG">Rpq!!:[M.fB>Nf`*V;s8W#ts8Vrr!r2d4r;ZoKs!mmGs8W#t$^EIP(!$>X!
8000 !(OK.e<Z?s7-0is+(12!<<)p!<<)u!!:[M.es)Es82lss7QEsjSp5#[Js&%!!;`k./X&Ho)C+s!
8001 <6&L~>
8002 s!WEuJH16$JH1B(s![nIrrE*!rrE*!r;ZsEbP2&:rW!<MbP2&:!<<(Kp"h7u!<<)t!!<8Rr?qOD
8003 !s.$P-i<rI29,IZM#IA_AEEQd!rr<)Xnp-=s8E!$=kNZ2Gl7XBs8;p$/?A:;e5lMJ'-bWos8N'8
8004 d/1`\rr<'!s*s^u/H,VP=kNZ2Gl7UM&]"5BrrE*!JG%kSrW!((f_j]QrW)uuqu?m'U\`I>rquis
8005 s8;p$"g.XBs8W&u$<c$ZiHP>&!S@8tr;[$)U\`I>rW)fpr;[-JbP2&:!!1^M-iO,Bs8N',/#Vb4
8006 kFiLg!S@8to)Sgjnc8^iJH4a2s8Vlps8W*!!s.$P-i!cBs82lss7QEs^]-k*#ljYu!!EnLq>^Ko
8007 !!EnLq>^JT!<6&L~>
8008 s&FUMJH16$JH1B(rDijts8W*!s8W#t"BF.Ps8W&u$WYmWs8N*!s/>e8$N0u)s8;p""SMTtr;Zp&
8009 p%f!m!!HWZr8D;f!!A2MnVmGI"UiQNXT/>"!!If5r6eaH!<<)t!!Q$0p@uTVr;[L2g&(gL!'TB;
8010 WrN)!!<<(tqT'$C!!If5r6eaH!"1@-rVults8T+qbR=CM"FoP2dTQPLs8Vus"UN'E\GuR,!<<)t
8011 !!NbSqQ0_srW!:Tjo!P0!!!/pq?d*#"pi0F\GuO.qZ$Ko$!#[Us8N'%p%f!o!;c`q!"2E2oDII&
8012 "98Stq?c`ns8VWis8RWMj8f5[q#LHprr<-(p%f!j!<<)s!<<)m!!_ol&HEFCn,<:i/CaXus8E!$
8013 /CaXus,I*Z<Ib~>
8014 s*'"oJH16$JH1B(s*+KCrrE*!rrE*!r;ZtOjSf,YrW!=WjSf,Y!<<)=qPaVr!<<)t!!<i0m0*@f
8015 !tkCs"T/6-J)gIS4TGHaX7t^drW!B]iUqj'rr<$#SaZBj2#RFSs8;p$B?pDFYRpa5)hI)Ks8N(<
8016 n*u/4rr<'!s2Oo7"98E'SaZBj2#RCf?K1tarrE*!a82nA!!!(kn+jdVrW)uuqu?mGg\I'5rquis
8017 s8;p20]D\Ws8N'!!hJfU_)),l&c1ktr;[$Ig\I'5rW)fpr;[.TjSf,Y!"o(p"TADts8N',B$0lD
8018 dVT$c&c1kto)Sgjnc8^iJH4a2s8Vlps8W*!!tkCs"Si&ts82lss7QEsp\tL!8cQR)!!HWfrr<#t
8019 !!HWfrr<"Y!<6&L~>
8020 s!WEuJH16$JH1B(s![nIk5bP^o)Jh5s5<eT!ZqC"]E&!3ci=+Ks8;$[!ZqC"q#CHts8;<c!ZqC"
8021 li7).s5<GJrr2u_p&G)Nrr7NLj8f2Z!9s4X!ZqC"o)JcKrr7NLli@&cJ,~>
8022 s&FUMJH16$JH1B(rDi"\s8VZj!_iX"qu?dls0B9;s8UFG!X8W!k5YQWs0DG#!X8W!mf3D_s0Ctk
8023 !_iX"nc8[h!71?=!9=(YJH4a2rr2uEpAb7gs0D4r!9=(YJH5$:s&FR~>
8024 s*'"oJH16$JH1B(s*+KCk5bP^o)Jins&/ap!j)E"]E&!3ci=+as5`>C!j)E"q#CI5s5`VK!j)E"
8025 li7*gs&/Cfrr2slp&G*`rr7NLj8f2Z!)3+e!j)E"o)Jd]rr7NLli@&cJ,~>
8026 s!WEuJH16$JH1B(s![nIk5bP^o)JiUs(qT5!gEY#]E&!3dJsEW'e]OPk5YRIs(qQ4"LJmrs6K+R
8027 !gEY#li7*Ns(m5dZiC/ks(m5dg&V.QJ,~>
8028 s&FUMJH16$JH1B(rDi"\s8VZj!oa/"qu?fWruJ`Ps8ULI"G7%_s3Tp/!oa/"qZ$bO$<R8Smf3FJ
8029 ruLG+!oa/"JH3%W!oa/"JH4C(s&FR~>
8030 s*'"oJH16$JH1B(s*+KCk5bP^o)Jj^rsel+!qH:"]E&!3dJsDT"eu$;k5YSRrsei*"C),)s)RQ.
8031 !qH:"li7+WrsaMZZiC0trsaMZg&V.QJ,~>
8032 s!WEuJH16$JH1B(s![nIk5bP^UB(>odJsD7f_s;eh>d[Cf_s;eJH16$JH4L+s&FR~>
8033 s&FUMJH16$JH1B(rDi"\s8Shos8ULI"DR)r_AD&/"DR)r_A@b'JH16$h#RITJ,~>
8034 s*'"oJH16$JH1B(s*+KCk5bP^UB(>odJsE0o(B!hh>d\<o(B!hJH16$JH4L+s&FR~>
8035 s!WEuJH16$JH1B(s![nIJH16$JH16$K`M-QJ,~>
8036 s&FUMJH16$JH1B(rDeCKJH16$JH1B(s&FR~>
8037 s*'"oJH16$JH1B(s*+KCJH16$JH16$K`M-QJ,~>
8038 s!WEuJH16$JH1B(s![nIJH16$JH16$K`M-QJ,~>
8039 s&FUMJH16$JH1B(rDeCKJH16$JH1B(s&FR~>
8040 s*'"oJH16$JH1B(s*+KCJH16$JH16$K`M-QJ,~>
8041 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8042 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8043 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8044 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8045 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8046 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8047 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8048 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8049 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8050 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8051 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8052 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8053 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8054 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8055 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8056 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8057 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8058 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8059 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8060 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8061 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8062 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8063 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8064 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8065 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8066 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8067 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8068 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8069 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8070 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8071 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8072 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8073 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8074 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8075 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8076 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8077 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8078 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8079 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8080 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8081 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8082 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8083 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8084 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8085 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8086 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8087 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8088 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8089 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8090 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8091 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8092 s!WEuJH16$JH1B(s![nIJcC<$JcC<$L&_0QJ,~>
8093 s&FUMJH16$JH1B(rDeFKJcC<$JcCH(s&FR~>
8094 s*'"oJH16$JH1B(s*+KCJcC<$JcC<$L&_0QJ,~>
8095 JLH'tJLH'tJLLOuJcC<$JcC<$L&_0QJ,~>
8096 JQ78$JQ78$JQ;_MJcC<$JcC<$L&_0QJ,~>
8097 JTlZhJTlZhJTq,oJcC<$JcC<$L&_0QJ,~>
8098 JLH'tJLH'tJLH(LJQ78$JQ78$J,~>
8099 JQ78$JQ78$JQ78$JQ78$JQ78$J,~>
8100 JTlZhJTlZhJTlZFJQ78$JQ78$J,~>
8101 JMVj5JMVj5JMVjWJQ78$JQ78$J,~>
8102 JMVj5JMVj5JMVjWJQ78$JQ78$J,~>
8103 JMVj5JMVj5JMVjWJQ78$JQ78$J,~>
8104 JH16$JH16$JH16$JH16$JH16$J,~>
8105 JH16$JH16$JH16$JH16$JH16$J,~>
8106 JH16$JH16$JH16$JH16$JH16$J,~>
8107 n4\B5JH16$JH16$JH16$JH16$OoU"~>
8108 n9BKaJH16$JH16$JH16$JH16$OoU"~>
8109 n<nh-JH16$JH16$JH16$JH16$OoU"~>
8110 !)2r3!).qDJH16$JH16$JH16$JH16$OoU"~>
8111 !-n'7!-j%pJH16$JH16$JH16$JH16$OoU"~>
8112 !1ED%!1AB<JH16$JH16$JH16$JH16$OoU"~>
8113 !)2r3!).qDJH16$JH16$JH16$JH16$OoU"~>
8114 !-n'7!-j%pJH16$JH16$JH16$JH16$OoU"~>
8115 !1ED%!1AB<JH16$JH16$JH16$JH16$OoU"~>
8116 !)2r3!).qDJH16$JH16$JH16$JH16$OoU"~>
8117 !-n'7!-j%pJH16$JH16$JH16$JH16$OoU"~>
8118 !1ED%!1AB<JH16$JH16$JH16$JH16$OoU"~>
8119 !)35;!<;mD!).qDJH16$JH16$JH16$JH16$OoU"~>
8120 !-n??!<;mq!-j%pJH16$JH16$JH16$JH16$OoU"~>
8121 !1E\-!<;n>!1AB<JH16$JH16$JH16$JH16$OoU"~>
8122 !)38<s8VpD!).qDJH16$JH16$JH16$JH16$OoU"~>
8123 !-nB@s8Vpq!-j%pJH16$JH16$JH16$JH16$OoU"~>
8124 !1E_.s8Vq>!1AB<JH16$JH16$JH16$JH16$OoU"~>
8125 !)3;=!rj\KqBu>;JH16$JH16$JH16$JH16$JH1i5J,~>
8126 !-nEA!rl:#qGdN?JH16$JH16$JH16$JH16$JH1i5J,~>
8127 !1Eb/!rmKEqKDq-JH16$JH16$JH16$JH16$JH1i5J,~>
8128 !)35;!<;mD!).qDJH16$JH16$JH16$JH16$OoU"~>
8129 !-n??!<;mq!-j%pJH16$JH16$JH16$JH16$OoU"~>
8130 !1E\-!<;n>!1AB<JH16$JH16$JH16$JH16$OoU"~>
8131 !)35;!<;mD!).qDJH16$JH16$JH16$JH16$OoU"~>
8132 !-n??!<;mq!-j%pJH16$JH16$JH16$JH16$OoU"~>
8133 !1E\-!<;n>!1AB<JH16$JH16$JH16$JH16$OoU"~>
8134 !)35;!<;mD!).qDJH16$JH16$JH16$JH16$OoU"~>
8135 !-n??!<;mq!-j%pJH16$JH16$JH16$JH16$OoU"~>
8136 !1E\-!<;n>!1AB<JH16$JH16$JH16$JH16$OoU"~>
8137 !)35;!<;mD!).qDJH16$JH16$JH16$JH16$OoU"~>
8138 !-n??!<;mq!-j%pJH16$JH16$JH16$JH16$OoU"~>
8139 !1E\-!<;n>!1AB<JH16$JH16$JH16$JH16$OoU"~>
8140 !)35;!<;mD!).qDJH16$JH16$JH16$JH16$OoU"~>
8141 !-n??!<;mq!-j%pJH16$JH16$JH16$JH16$OoU"~>
8142 !1E\-!<;n>!1AB<JH16$JH16$JH16$JH16$OoU"~>
8143 !)3;=r;Z[C!).qDJH16$JH16$JH16$JH16$OoU"~>
8144 !-nEAr;Z[p!-j%pJH16$JH16$JH16$JH16$OoU"~>
8145 !1Eb/r;Z\=!1AB<JH16$JH16$JH16$JH16$OoU"~>
8146 !)2r3!).qDJH16$JH16$JH16$JH16$OoU"~>
8147 !-n'7!-j%pJH16$JH16$JH16$JH16$OoU"~>
8148 !1ED%!1AB<JH16$JH16$JH16$JH16$OoU"~>
8149 !)2r3!).qDJH16$JH16$JH16$JH16$OoU"~>
8150 !-n'7!-j%pJH16$JH16$JH16$JH16$OoU"~>
8151 !1ED%!1AB<JH16$JH16$JH16$JH16$OoU"~>
8152 !)2r3!).qDJH16$JH16$JH16$JH16$OoU"~>
8153 !-n'7!-j%pJH16$JH16$JH16$JH16$OoU"~>
8154 !1ED%!1AB<JH16$JH16$JH16$JH16$OoU"~>
8155 n4\B5JH16$JH16$JH16$JH16$OoU"~>
8156 n9BKaJH16$JH16$JH16$JH16$OoU"~>
8157 n<nh-JH16$JH16$JH16$JH16$OoU"~>
8158 JH16$JH16$JH16$JH16$JH16$J,~>
8159 JH16$JH16$JH16$JH16$JH16$J,~>
8160 JH16$JH16$JH16$JH16$JH16$J,~>
8161 %%EndData
8162 showpage
8163 %%Trailer
8164 end
8165 %%EOF
0 %!PS-Adobe-3.0 EPSF-3.0
1 %%Creator: GIMP PostScript file plugin V 1,17 by Peter Kirchgessner
2 %%Title: xft.eps
3 %%CreationDate: Sat Jun 20 20:49:20 2009
4 %%DocumentData: Clean7Bit
5 %%LanguageLevel: 2
6 %%Pages: 1
7 %%BoundingBox: 14 14 553 304
8 %%EndComments
9 %%BeginProlog
10 % Use own dictionary to avoid conflicts
11 10 dict begin
12 %%EndProlog
13 %%Page: 1 1
14 % Translate for offset
15 14.173228346456694 14.173228346456694 translate
16 % Translate to begin of first scanline
17 0 288.99323244445742 translate
18 537.98740157480313 -288.99323244445742 scale
19 % Image geometry
20 538 289 8
21 % Transformation matrix
22 [ 538 0 0 289 0 0 ]
23 % Strings to hold RGB-samples per scanline
24 /rstr 538 string def
25 /gstr 538 string def
26 /bstr 538 string def
27 {currentfile /ASCII85Decode filter /RunLengthDecode filter rstr readstring pop}
28 {currentfile /ASCII85Decode filter /RunLengthDecode filter gstr readstring pop}
29 {currentfile /ASCII85Decode filter /RunLengthDecode filter bstr readstring pop}
30 true 3
31 %%BeginData: 94268 ASCII Bytes
32 colorimage
33 b1cpOp"TN#s4dS-s5!M*qqCf!qq@t&"kqY_gY1BZg\0@qg\]^Og\oq'gAp%.g\oiWgQpTE~>
34 b1ZjMp"KH#s4[M-s4R5%qqLl!qqKTRs4c/Z"l%bbgtUT]gAKY$g\9G!gX+[Qg\KP'g]#q*fn%kC
35 g40~>
36 b1-LCo@<lls4."ts4."ts4./#s4./#s4./#s4./#ldc$dl.,g_f$siOe^sZJr7(bss46els45KG
37 rRUep!7q/"rR?DKQIUK~>
38 b1d$Rh;$fagAK_*g'-4I()@])rYYSH!sSo5"o];<)>tENE<+PgdfU$h%1]Als4%(trXAu?g=tB;
39 r7h,&pY5T!d+eL(q:kiQJ_Q@BJ,~>
40 b1ZsPgtUT^g&0S(gBH:H(Ddi&rYPMF!sJl6#5oD;(]A=Oe,p0k%LpqAs4c2["4PfMeG]p\%GBIh
41 g\fe&g\9G!gX+[Q#5R!O#(bKkg40~>
42 b1-UFf@JOOeG@\uee/Q,')`LD%2fQ`!<E6&',(um'+tokChmg&d*Bq_#mgkCma_?gl.,g_f[U,M
43 cd'iCrWiVUe^`7Iec44lec44GeboOEeboN"eWSI5~>
44 b1lmMrS%2(rn@>e!#PSNr=T)7rWN?>()QlcrG`1oe'leV%1Ng%gYB!e"5MYceGdo!%1WgWptP]"
45 pY5T!d+eL([email protected]@G.r<N;U!8N.[QeR#~>
46 b1cgKrRq,&rnIDg!#GMLr=Su3!Z2^jr"o<N$IdMSeIN-"%GKOjYM'*5g=k$Te,p0k%Lr3eqqM,(
47 !8ID)qqKKOr<E8T!8IM,!8IGVrRq8+J_HIEJ,~>
48 b16IArRChsr7:i[!#5AHrXAi<r<!'6')N@@D#V`]cjKaY!nPoQYLN^*e^j]F":5DA$.f"(pt#Jq
49 !7UnspX[dCr;loJ!7q/"!7q)LrRCo!J^p+;J,~>
50 b1lmMrS%2(rn@>e!#PSNrXo5D#6"f*(]P<R(Dn"fE<F_>daS1)!"Q!_!7_"srXAi;r7_5,rnI>(
51 pY5T!d+eL(q:kiQJ_Q@BJ,~>
52 b1cgKrRq,&rnIDg!#GMLrXf,Ar<3EB(`4&*()IecE!+S=e("@,!"Gp]!7UqsrXJo;r7V/*rn@8(
53 rn7A,qqCr%d+\F&q:bcOJ_H:@J,~>
54 b16IArRChsr7:i[!#5AH!tPhM%fHJ0(&\dI&ebrWD#_f^cHlFq!7n4$!7q+pr<WJTrRCr"eb@Vq
55 e^OKIpX[dCr;l`Er;hK"P1>'~>
56 b1lmMrRqD/gtgc?rn@>e!#PVO#T"*c&eYBP"pOuBr"oESrc%qfrmUiU":j5AgYApc!7_"srs\u;%
57 fY2_h#,q(g@sA!g<eUQ#QNN[gtUQ^g\hA.gQL<A~>
58 b1cgKrRh>-g"P37rnIDg!#GPM$Pj<c&J50M"pGe[)#P0MEW0nWe,Ikr%Km6qg=k<RgAfp?g&TV$
59 eGg$Y%K>&]g\fe(g\KP'g]#q(gX+[Q#63BYgY1?[gAM5,g610?~>
60 bLHXEfDaA"e-"7Ne^scNrXo2FrY5_R%h&mX!s8Z.(&\gG&ciY_rbVPZr<WSXe^`7Iec45!ec4+g
61 ec44HeH+7Krm1TN#RCafe^`:&e^aQJs4IA&rRCqteb@YCeboOKeH4=PeGe"s!J/daeUR~>
62 b1cpOrn@G,rS.A.rnIJ,"5DP`g\on-T`1Vb0`Ea)f`g*cgt^`@rnID#rX8c9WS7F&rmUiU!"St^
63 !8RP-qqCf!qqBKQ"l.k7Xfef)h#6",#64u,gk"4GgOK~>
64 b1ZjMrn7A*q:Z&.gY:N<gY2V\!2'7`r@\H0g=k68gY:N<rn7A#rm^oV!"A>M!8G0?!7UqsrXJo;
65 rRq8+rS%5)q:Yi'rn@8(db4lZg8qBXXSpoPgAV9V"o[2,g6UHC~>
66 bLHXEfDa;#eGIerecsaWf%8L(f_sJ*SXc4Ar@J$$rm_/(f%/L*rmh(prm1NK!7pnps47+u!7UJg
67 s45NH!S5Ztci".Sf%&=%f@AFKf)OD&f)=,"e(+3DeC=`ReYf=DVu>3Fec#RL!<(K"eX"a9~>
68 b1cpOp"KK"r7V/*rnIM.rLj3Fr\+9(!8@D,rS%>%rmUiT!=dhagB5sRe'n:*!"SeYqqCf!qqBEO
69 riH1'rS7G-!SZ<,#6<TZgk"4GgOK~>
70 b1ZjMo\'<"r7_/)!8@CEr@\9+g=k6Yg\oh+e,Ikr%06mlWnRL%s4%#X!"J_WqqLl!qqKKOri?+%
71 rS.A+!SQ3*"p!HXgO\(Eg40~>
72 b1-LCpXT;p!S,d!f`'P(f_qE?/HFE%ec"+uf)<qn#QWKTf)O:qf"0B7f$DXfci"1>f)+"hf%/CN
73 VZ<[of)O8$eCFKu!8%5$J^p(:J,~>
74 b1cpOp"TAt!ScH0h#3oH0`Ea)f`9b)g]ZBegY:6WdfU!f$k9;m"5MYceGdqr%0R0qg=tE\g\]_!
75 g\]^QgC;lkXf\b.gtg`?gY:H:r<E>YrnN(ZQJ6o~>
76 b1ZjMp"KH#r7V/+rnICEr@\9+g=k6YgB?6bg=k$Te,p-i%1K>l"5DP`e,Ikr%Km6pg"P3YgABY!
77 gABXQg'u`hXK8P*gYCN;g=k66r<<8WrnE"XQJ-i~>
78 b1-LCpXT5nr7D#'rn77Ar@J$$rmgu!"4l)Tf)<ns#RLbBr7:nupX[%.!nPoQrQkEK"4l#RfC[Yk
79 eaqAEeIC$YVl-Jkf%8I'e^`1"r;coMrmlYNQIUK~>
80 _V5(GrS.5'r7q7E!&4C*"5;G\gATh*gB5sRe'n:)!"J_Xs4[M-s4[D*!8RP-s4[M-s4RM.h#?%.
81 h#6"-g&p-bg=lP\!8RM,!nuD_o@s<!s4dS-qqD>1gY:6,daS1)!"SeYqqD#'!o2ParnI>(!8RM,
82 !8RS.s4[)!s4[M-s4ZtsrN6%R#M[tcg'7fd#Q<HMgAp#[gSESS~>
83 _V,"ErS$u"rLa-Dr\+H/g=b0Xg\ok+e,Rqs%0-h3gAfq-gAfq*g&Tn+gAfq-gAfn.g=uV\!8IJ+
84 [email protected];_]!8IG*!nl;\o@j6!s4[M-qq;8/g=k$*e("@,!"J_WqqM)'!o)G^rn@5'r7V/*rn@D,
85 s4[M.pY,Z%s4[M-nCmiBrS%S2gY1<b#6tJ3g[s2"gO\(Sg40~>
86 bLQXDqUGSsqpkYrs4RG("kfK;S=V>3.g+AQeCFNL#M.GUf$DXfci".If)O;!f)OD$f)O8$f%9WG
87 &_>L_f%8I&f%/C%f@JL&f%/CNf)O8>f%&=#f%/C%f%/C%f%/C%f%/C%f%/C%f%/C%rmh8'f$D[f
88 ci"1>f)O8&f%&:#rRV#!s4.2%rmh>,f%/C&f%&=Jf)+"tf)O;#f)O;#f)+"tf)O;#f)O8(eu5LE
89 W7V%"s4./!r;llJp=9/n!7h&!J^paMJ,~>
90 _V>%E!8IM,#MIhbgYCT=g\mfG0`E^,g=t?VgAob&e,BdZ%W#orD#G[r*ZQ.?WMlbpgY1H;`l5s;
91 +!)IFgtLK[g\nMb/M&G)gY1B9rRCiVrso!Ar?_Ij!@9)kZNs2r8kU3G*?I?B49*e3e^W+Je,BdV%
92 fKu;/-@1D,:*8e!3,qO"OtuOe-u<arac(BrC6`6#-"Q"WS?.\r7h0?"=Y`I.3JO1r_`_prR^l"r
93 <N;U"PVP^g'@T]rS.:urB^B,r?h\Q?=$oggT'"Y~>
94 _V4tC!8@G,#MRqeg=tB9gARZE0E*X,gYCQYg&TV$eG]p\%;T]nC],RY*=s3hWMuiMg"Y6"`5T\:
95 +!2R'g\fe(Zj/-6/M,W1gY2VTrs\o:rFl-Ts!7[k-2k+T8kVfL*?H7B48q;@dfS%Je,Ikr%KHt:
96 AGn"\,UF]^ri#mrrRqD'eC2kSrXAa;rC-Z4#,nN#W7p"\r7_*=#:M#M-lsHP*WAn9;Z52BgAM6S
97 g'?<bg=ZZ8#6k([rQtL.r?D1e"'f,;>_1V/g40~>
98 bLQXDqUPPqrm_J/e^i=(g"4g-St)=B/cI7$f%9cLs4%,#rQkEK$tj0aB-AB?+W2+6)Q*M0#M.GV
99 f"o,:_#5,Nf)*uGf!)?]YUCkH.+Zr!f$DXecNja]$"ROVA0<!:+<_jL+g.rLY!tiL7f=2.2`<NO
100 cd)F6r<`F1r?qUf!?WH_U]B!FeH=+CcHlIp"9r7B@:K4%%7;?b+sWnYUSQJke^i=Nec%i<66md#
101 ,T?Y""&2H_:&`NLdalt!f%/C%ecGjQ!nRA$rRCfI!!)uJrQG.$rZ)7c+sA*R=BSd.J^pdNJ,~>
102 _V>%Ep"TG=!&4C*!nuD_ptGeurmUlVrsf0JD/=#7r[%UcrYu0BW2Q]NgY:H\`W.+[*ramkg]+Y_
103 [^@^d/-FY\g=uVV!7UlVrFu6W!$qLirNcJsr_!/1!$;)#qpbYprXAi;rFQ![!\5fJrZqNB"fJ?S
104 gY1E\e,TpV$iX];B)P3t-ig7GW;bNKgAj_B7fY";./k7f+8o+9fD4/'"pbG=rS%>+rn78T!!iJW
105 "4>KCdJZB0,60(i-iIA&gT'"Y~>
106 _V,+Hgt^ZWgARZE0E*X,gYCQYg&TV$eGg!_%h3;jCMP3p-2ee`WW&gugY1B7rP\aXrZD-or7_1X
107 !k#Bdr[e6-gY:H]df@hp%K0u>,QK(f-2k+L9)_K_*WR5Z3rIG.e^W+J%KHt:AH+.].OueD-3'tE
108 W;kQPg"QDR!"8c7ral.ArC-Z4!3#mrrnIA)!(HlV!%@gqrZ;+]rDEOEq:YoS#6kD2g&Th*gAV<W
109 #6!6Xd*L(crBU<*!%%UkrEY!.WnMt~>
110 cdhd@rm_,%eC<(KebI_oSGar=f%9cLs4%,#rQkKM#mpuOB4bd!+X&*/)??]7V?>H$f%'`8!#khS
111 rmgqts0)O/Yl,sMfDaA#cN)8h$2nE6+9<N+rZV6CrC6`'rAOT"!mo9>r<`F1s!Igo-iG1fU]mNh
112 f%&:#rltMir<N:0rB^B,rM98?!($TNr?V=[rD!7=q:5WK!s/Q&f)F2"eGTFHeH=";bKKlH!'L3$
113 !$V=crE0-OJ^pgOJ,~>
114 _V>%Ep"TG=!&4C*rn@2&!Sl3(dfU!f%M&GRr?_Ue*#fmsVuWgqgAo:n`W.+[*ramkg\nM[/cI=#
115 g&Tn,e,[tr%fL,?-2f.nZa@'F9E%Q_*<7/Z48dV-e,KjX%LrAJr@@pprZqKA!3,qOrR:fUrX8^:
116 !G4k$7f=_?WMlepg=k<8rS.9@"">WI./k7f+8o+9fD42$#6>#6rS%>+rn.DX"pP=drnID!rB^B,
117 r?qVO!FK/agT'"Y~>
118 _V,+Hgt^ZWgARZE0E*[)g\KP(gXH/O!t>_N%K1)@-3"qc)]\gTrRq7krl"jYrZD-or7_+V!%e+$
119 rn@G,rmLkqr=/^=r?V=f"L>A>Z:b*hrZ2%[rAsl*rm^rX!=oV;AGn"Y,lT+hW;rmqgATJ#$iUS6
120 AcZI4r^Hc5#H4W%WS?1_g&9Y'7KY%f.Ok?=!$;)9rRUeurrrK-#6!6Ug&B\."pYA;g&B_(d/?6.
121 ,5ikg>le8;J_I-XJ,~>
122 cdhd@rm_,%eC<(KebI_oSGau5f)O8#fDX###RLhEB4kghrZMCh)B'J3rMBSIrmh(drkSRQrYb^c
123 r7:hNr@%Wqrm(Sir<`F5rZD4`+T<MdY-5"2rC6`'rAOJtrs8]5#lS00-iG1dU]B!Fec*hoci"+I
124 @/rXn62`&.U]mTjf%/I'rRUp6s!.Uk,lJY[:&WN9f)GdP!<W5Nrm_&!!<*!!eGe"sbPjR'4T-?"
125 ,6(dI>$9F-eZ75N~>
126 _V>%Ep=fT&rLj3Fr\+9)ptGeurmUiU!"SsD"=>NF,out)s/>ssrS%IpaN;FDrZ;'m!8RP-"LY_J
127 [4VA/rn7A,rR:oZ%h9*KB`VrorZqOlr[%cS[C*>6r_!/1!$;)#r7(_prseu<rFQ!["YD8O,pXc8
128 VuWgqgBZ6WeC4m7$k*&G$"cXs7RedU.O_:qW;bNKgB9u:8Ok6/-j(M4*Zk8X!8.;&s4[P/r7h/T
129 "P_bggY2Y["9eu6#Mf=5rR(R0r?M7grEf0O!8<"Y\(cE~>
130 _V4tCp=]N$rLa-Dr\4?+pt>i!eC;tG%K1&B-2o1g*<2r<WModL"NA<u`?,"#rS.;)"LPMAZn22.
131 rn@G,rR1iX%LimHBE;flrZhIjrZq]QZ*CT,r_*53!$2#!r6t\q"Odeh%LrAIs!n7(.jQGf-2sk]
132 W7ot[g=+L!dgHNl$Y<p^AOT'W740E/-`I$DrnIA)"@Y^I7O\6b"!8X-*W8h8fDaA$g&Tn*gAM3Y
133 g=b05g&B\."pYA;g]#n/d*^7frBU<*r?hJKp"BE!J_ITeJ,~>
134 dFIp@rmgtuqUPPq!8%1>r@@fss4./#s4%,#rm(Slr<rR:rZM7cr>P^5&Z;MYf%&?f_8=#,)&X@D
135 e^`:Mf);iP-ik^Grmq(p$.0+h$O^QWA7Zk^+93Vb,64tIY5Lig)>uJicNV]($OdDPra>aR"Xk`@
136 +Wqp+U^Yi)e()agcHc_%$415A@08e^5sbGorM98?s$?ZOr?MI`)]BUm9`WZAdf7kufDO2"!r`<&
137 f`'J#eboLKf)F2%bK7lLr]:*Br>tn]rE0-Op=0/mJ^q6[J,~>
138 cJ/<Qq:bo)o%X,:!&4C*rn@;)rRq8%rm^oJ!!<+`"P_bggPc&g"$&D'48mn:`lQ6@+9!>\g&]s`
139 rn@R`[^WXrr[e'&!8IJ%r;cnarg3T<rH&8W'bq@p]tD&Xg&Tn+7K/8IN7@jUrW*!#rJgm5rn@OQ
140 VP^9j)ZUlVg&9D#!r`6"VuWgqgB=(>T:J(C3We$igAK\.b08)Pg]#q+f`9b)=8mpSL&'L%#6`f;
141 h:p]`gAV9Z#M\%gg\m95:AruIgB?6Vcd'l0g],uYgUQ!g~>
142 cJ&6Oq:Yi'o%O&8!&+=*rnIA)rRh;&e^`1J!WA2ag=b05rJCS8r]:#3"NA<t`?,"#rn@J-g]#n0
143 ['I$F/H.7#gAot+e,97HQ2[*JgAQ*k&Hf\[]tXL#!8@B>repu<e'umrr;lkV!8IM,"/_uoW;[b>
144 )q`frf_s:t!<]:"WModL"ItsNS3$X2!o)Mbr7V:qaN2KWrnIG+!87<Ore1?*q:bcO"PVP^g=lP\
145 rW`]5g=t?8OHGZerD!7Frn7M.cHa\[p"KH!J_IWfJ,~>
146 dFJ6IrR^turm_#"pXT2mrLEg:r7:nu"P2,QeCFQF!7LfG!0R8Armh)%rJ1G4r]'r/!S,d"_$Cqs
147 )&h)Ve^i@OecW.[Yd"*T!@QFsf)EtqdJX%FPQ$aDec9XfE<d!a%LoqY\@MRhrBU@<!/LR"!7C`F
148 !/pi5!8%5$rh9Cfr>,Rce'ZYDc2c2h!!&nqV#AmCR/JoDf%9fMrPe`drRLjErdb'"q:5NIrWE5R
149 qUPWJrW*8Sf%&</M2@/i8,u6[fDa>)e]Q%Vb1?::s3uVM\CH*~>
150 cJ/BS!SuQ,gAp%"g\mfG0`Ea)gAK\.g=t?8ec+(t!<<3"PQ]^rh:mkeMZ,X:48mn:`Q6-?+T<G]
151 gAK\.[(!NP0)dF#gATP"!WAA`g\l3s',;5q^AbhFg'$/!77K`EN<@YZe'n9s"9OUENfO+n!SjXQ
152 VZ%M7*<"Rhe,TRL!<]9uWN#jN#G%KZSNAno3r[k4gBQHfb08)Pg]#q,g&Kb.=BAR)rJ(:*!8RS.
153 r<EJ[h;-i?rn@>U!!iJWrK7(S!)NRK"5DVcg\oIsgAot+gB-0bg]#oXgUZ'h~>
154 cJ&<Q!SlH*g&TmugARZE0E*[)g\fb1g"P-4eCE+!rW*!!rKI66!8@F0!K0&=3rRe3_uRdT+9($m
155 gA\DY[/DTUgAoq+df@hp!<&5^gAQ('&eP]g]tV4og=tB96psI3rJUj,e^W(H!<\=ANK*qk!8IIM
156 rYtnWrRh(tr;lqs!NN*sg'=.;S")N%4$3Grrn7S2g<%FWakHaKs4RY2fiM3T<W.XMg&Tn,gAM3Y
157 g=b05gA]k+#64u,g&R66OoA&T:AroLg=t?8rQbAq!87>)!o)G_rn2kV\_;Q~>
158 cd`0Lf@S[,r7:kt!7pnprRM#"S,SrV/,n,teH==OeCFQF!R^uI!<A8]Ns!q`f%BtX"GSfo3&^`d
159 !5STM!#tnTrmgqt!3cC+"">TF./qctfDa.te,97HPl?jFec=A$EW$FO]=GJaf`'J%5QO/9rJ1j,
160 d*L)>!<E1YMM[8jfE'U!rhB?-!7_"srlteq!!**#VPBu`rRUq7"#`(r2Z)&+f@Ko>rRV#!&_>K2
161 ;GpACJ:N4%e^i=)f%/LP"T6pOf)>^N!WCOKMuJS58-):SrRV/&f@JOOaoL#leH"+teH4=Pec+'L
162 e[a4\~>
163 cJ/<Qq:bo)o%X,:!&4C*rn@;)"PVVag=?2P!s&B&!r\>ggYL]?Mi3IMr]1$@rS.:j!$D1]!nu>]
164 r7_Ia\$i[r.kE7Ng&Tn+eGTFJQN<[email protected]&8X'bqCs]tM)Xg&Tn+70&AIN<@\ZdaS0r!!<+Z
165 rS%=Mrhf]7!?)sVg&9D#!r`6"VuWgqgB=(>T:J(C3r[k2gB>[Dbf\]>gAT_'<s+24L5#HXr<EDY
166 h;/(bs4R\]"pP=egYCQ^Oo8&Rh#5t0cd'k_ptH#.gY:H8g=h,4]%_`~>
167 cJ&6Oq:Yi'o%O&8!&+=*rnIA)$ea7eg!nR&e,]OM!<&)eg=b05MMm@M48q;>gAStj*r[5_gY1E[
168 g'>!kZEu/6/M6tV!8@G$!7LfGs-<\PQN#S<g\l0q&eP]grk8BFrn@G,rBpXFreps.eC2nF!WA#V
169 g&S#LVuIb:)u\Ffe,9:LW2ZbprRqCES"#p/r]C,6r7_1m!m&L;rnIG+!8.6N",2J`K_a@#"q]MA
170 g"P08gY2o;#6ro9gY.bgOo8#Qg\oh.cHXY[pt>r,g=k64g"Cr1]%VZ~>
171 cd`$HrR^turm_#"pXT5n!S*\=SGau;f)4&#eCE(!rm1hs!!!$#OoCF@ed0oaM26mE3&ihpf)<Db
172 )ZCTUe^W.If)MrXYHTE%-ReuF!8.:u!7UlH"-et4P5a#4g&5ph&-KSU\[qajrBL@>reUU##0tTr
173 !<E1Yre^X,!7q+Crtb_P(Y&H5rltMir;ZhprhTMDrL!OAq:5Ye`l5pqf)F2"eGW;FJcC6*f%&@&
174 f[eX+r<3&N$eNt\!<N<'e^`7$MuJP58H)3ZfDX8'b/qfKf(mi#f%&=#e'ulue[j:]~>
175 dG+KPlJ)92!&4C*rn@5's4[M's4%&L"TSUgQ'7I2gAm02MZ#U7g&o=6`Pqft!$2'mr7h1Xr@Is%
176 !8IJ%r;lk`rS.9mr=f.D"5DVcg\jS>NW%?*!=8jfNfT4Tg=tA[rh]c:)B0[pg&9D#!r`3'W2HSn
177 h#?(,SH(bN3rdn6g&B_,gtVeMrS%8(!8@BQrJ(@,!8@A*r<N8Trn@>U!!iMX"PT!"OcfT;rS7A+
178 rQk/kr7Z_V]A%i~>
179 dG"ENp"KH#ptG\>!&+=*rnI;'s4Ie0f%&7N!<<.aP`h7/g'!:kMi'Rp48mn9`lH*=rZ;+]rnIA)
180 rNlPTr[n-(!8@D#r;ce^rS%3kr=](B"5;M`gAOG<N!%MXeC4Bt#m-'FNfDcGg=iG'Vu@Y9)u\Cl
181 e'ujq!WE0"W<&sPrn@=@!':*@s4dM+!Sc?,aT1#ng]#n,g&4tML&]j,g&0S&#5m3Sg\qEX#6*<Z
182 foV;XOSqoPg\ok)cLoohfn%khg40~>
183 dFJ'Dp!s)krRLhsrLEg:r7:er"k;)LdEp>?!!JFGNfMZhf)CC)LcGAlrRM+f_SO&,rYYdge^aWL
184 !SF^WYQ-'M./h]sci2>j!!&8_P5a#4f_ogg&-0?A\HCF7e^j[arJ1R$cd1#;!!eC<MM]p7f%0eo
185 r>,I`rmLtpbg+Q5!<&\nfDaA"R/JrCec=8"ecFCRrP\cermq)!!S:<M;Z21Hec=8!ec=A$"T6pO
186 ec5dN!WLUQe;K->Mb*h=rR_#!rQ5,kp=9)jJ^qB_J,~>
187 [bLf8!8IIH!&=I,!o)G_ptGeurmUiO!!rPWrS%Fi^V@S_+9U?Ng"QDDr>tslr7_4YrjDbX!A#c#
188 g&Tn+eGT[Kg\mlL2E*QSq:kmhr,VkfrmLrP!s8])f_jM'g&i94)]\gh!7Uqsr<WS[g"P6[g\nqj
189 +WqmLrn@;)rHSAur\=C0!&jd!"(5JC@/8RU#Q3?UgAV9V#Q<HV^&8oQ@:NbUrL<i=$/!kagY1E;
190 h;$f`g4A"fgOK~>
191 ^"WM@r7_/'!8@CF!&4C,!o2Pbpt>i!eC;tG#Q<?Sg&Sne^]5MV+TpKQg=uSGr?)$nr7V.Wrj2bY
192 /hJXRgAot+e,9OIgAR`J2)[?Oq:bgfr,MqheC;qMrWE,Nr7_/)rYtnWrOW3\eC2kPrX/VYrS%4c
193 "!Aa1+TC-ngAQ6r1&`s-2?5W5+9PtW?=3N^r<E2RrnIDW!!`DV"2)=\]_rcO?t*PQrL3c;$.mb^
194 g=b37gtUT]fn%kdg40~>
195 ^"*/3rRCo!rm_#"rLNm<!8%2#qpb\trm(Slr<3>Ue^`1"rmq(\!PTWS*!=dBe^j]8"r\?s)V3Hh
196 rRM#%Z2Us0-n-PlrRLtprmCZJqUPZ!rLa9L1c.)BrRV#!!7q-dr,2M[!RUuJ!<gs%e'ceCf)6Bb
197 \,Nf=c-4JY"TAT(ec=>#f)<8\)uprRf)9^h/cII*1EQN8"'\r4>PcnNf_ksNf`'G%!r`6!ec`Ii
198 [C6qN(B[oK?![Dps3_5&dalsue^i@'f)4$Ke[O(Z~>
199 \_@2>gY;\\rLs9Hr\+E.g=l>V!7_"srs/Q0rS%8*!SkKi^\o;RgAT"h*ramkgAnV[[/_fX/H4?'
200 g\oY##Qic7gAK_*UB70b2Z>Z2g\l0kEra_he,KOM"T@!Ng]#q+)[%.n]tD#VeGT^QgATb+h#5%h
201 +oWV`gAK\*GlDsg1B'$-2#oQ5+Tl+Z?srfbr<N8Trn7GY#6kG3h#4qb*;s@FS,Lt;g\oq+g4A"e
202 gOK~>
203 ^"WM@s4RP-g=lMYrLj3Fr\4K0gY;MW!7Uqsrs/W3#Q<?Tg&]sCrkSIUrS.:jr?)$nr7V.Wrj2YV
204 r[n-(!8@D#r<EDXg"H;Ws.TRgU,Dp.q:bderGhnerm^rN!<iT(fDOA%g\r/q)nWbp]D^1Y#lY21
205 g\oh+g\nnf+T<P`g\fb*GQ)ge1&`s-2?5W5+9PtW?XNW_r<E2Rrn@M[#R:S4gB5+%]tF:_rF,Yn
206 rRUr$rS.;(J_IQdJ,~>
207 ^"*/3s4%2#e^j]LrLNm<!8%2#qpb\trQkKG!<`N'ec+,"fDW>[*<"Ie_>P;Of)4/#Z2V$/.fLjp
208 f)<qn!s7'(eG[r%fV"n0TJQR(!8.8$s4%,#rGDLNrQkEBrR:Snr>5LCs0hmO!s8Z/"o?dMfDWA\
209 *;S.cF8g:[/cII)1]8?s?!:H:qUPZ!r<3&Nrmq)NrrN)L"LkeH[herZrE]AfrR(\srmgturR?DK
210 [afm~>
211 [bLc7rLs9Hr\+E.g=l>Vs3q(udf'IS#hn"egATb.^q[\"r?2'mrPe^Vrn@;)rNuVWr[e'&!8IJ%
212 !!iK/r7_S6gY8KuU8'Y,2`L`j!SlE.g\l-tF)l>BeC2prrW<-'rRh,(!SlH/gAW#o*5&tt]`$=[
213 $N:>;gY1B9gYCQ<_Z%@O+oWSbgY2PZrHSAur\=C0!&sj"rF#HUr<N>V!SlH/gAV9V#Q<HV^&8rL
214 @K;krS,Lt;g\oq+g&]s`J_R]hJ,~>
215 ^"WM@r7_,&rLj3Fr\4K0gY;MW"4PfMe,BUU#MIeag&9V,^VI\$r?;-orPndXrnIA)rNlPUr[n-(
216 !8@D#!!`E-r7VM4g=i9qTqXG(2E(Qg!Sc<,gAQ!rEcH,>e'uptrWE3'rR_&&!Sc?-g\r/q)nWbp
217 ]D^1Y$2t8;gtUT;g=t?8_>_4M+T<McgtUW^gAQ6r1&`s,2Z4cs?hrFS#6*<WgY2Y]rW`E-rS%Fe
218 ]tM)W)uX1FRJrZRf)=>$g\oe+g=q24\CuH~>
219 ^"*/3rRCo!rRLk;r@@s#rRUkr"P1oGcd)Iks4%/$ec")!])fRVr>bderPAFNrmq#"rNZDQr[@`r
220 rQbHFrW<hbe^`7%f@JTITV%l62)I/Bf%/IPeH"2!D$OrqDJd_Gd*MXjrR:bs!8%2#r>5LCs0hmO
221 rWE6*fDX8&f@JNdrk/1L!nZ#Tr7:ggr@S"'!&XWq!+#S.qUPZ!r<3,P!SQ-)ec5dN!WCRP\$`WQ
222 (B,-K>l^/hQMo53f)F4uf)=)!e^f<%\CH*~>
223 [bLi9!Sc?,U'!,(0JEFZptGf!rmM)W#R:Xhg"P0ZgB$*FrkJIU"Wnl@g"P0Y`;gqX*ramkg\nM[
224 /cI=#g&Tn+e,TaQ#l36RU]!.Ig\l0kEs'q@eC4C!"pET2g">'[email protected]"QEE!?AfP]`$=[$N:A2
225 gA]h-gtVeD"!Jd1+o^3ng\lBt1B'$-2#oQ5+oPgEg\hBTg]#n7"pY>;gt^`@]tV1nr>bcFrL<c;
226 s4[V/gY;__rRuhW[bH<~>
227 ^"WM@r7_2(!SZ6*T`Zu'0eiU]ptG\r#7(VA#MIb_g&B\+gV<a'ruhOg+kt`*g\o+l*r[8\g\fe(
228 ZiDZV/cOK)gATJ##6"l'gARcE2Yl)*EW'n[e'uptrWEE-f@S[,g=uV\!o)G`rYtqX]`,PAdf9^R
229 $NAfZg&]s^rP/LX+X/-0g\fe(GQ9Jt1B'032>nZr?hrFS#5m3SgC"5l#6rr;gtTKU]tF:_rF,Yn
230 rRV#&!nl;]rnID)J_IQdJ,~>
231 ^"*/3rRD&%e^`7$rLNp=!%[uuqpb_ud/M>r!sA].e^N$trm_##rO`(L"WJH4e^i=M_#PAP)ZJ=c
232 f_r)U.fLjpf)<np!r`9%f)*tuet2l6!&X[1r7:nu!7q*crGMY]!RT0k!!^p#e'ln!ec+,#e^j[8
233 "LtnK\'P'!r<3,Mrmh,%f)<8]*<.&Tf)9^h/cII)1]8?p?2e(+f)O8$ecPgRr7M#"rrW3$s4.D+
234 f!i)q[herZrE]AfrR(i"e^W."rmq%tJ^q3ZJ,~>
235 ZJ5>O!&4C*rn@/%!7_"srXAo=gY2PZ!5nfQ$Q^<0*no<$g;h:T`r6qX*WFdjgAnPYZ2H6Qg&Tn+
236 eG]pY&)-m7rM9BUq:kjirG_hermUiK!!N8Qr7h5)rYtnYrOi-Z!RhPX%K>&agY1?7gASnh+9!>\
237 g&Tn+V>VqFdf.YogAfq+HMq+Ig]#t.g\hBUgAot,g&;0]#M[tfgY:N<g\oFrPlFM[:f%$H!8@;(
238 !8<"YZeL!~>
239 ^"WM@ptG\>!&+=*rnI5%!7UqsrXJu=g=cAW!5e`Q$QgE3+5>N(gW7LXa8R(Z*raplg&SDWYQ-3Q
240 /cOK)gATM"%06slqV(nCrB9u1rH%pV!7UqsrWE3'rR^u$rnIDm!$(sLrmLnr%K6k:gB?6`f\+sV
241 _>kYV+9(!pgARiG.fdurdf8&&gtM^PrEK6Srn@G,r<E5S!87A*rW`]5g=b67g>(H:rQY;)s%WSj
242 :AlsKg%sD&fn%k`g40~>
243 ^"*/3rRLhsrLEg:r7:bq!7q+pr<WMUeGRhsf)<;j)AsG3f%&@&_o0I0rYPVQrmq#"!3cC)!%Imq
244 rRUqnrWrQ3qUGVtTDkMa48q8<f)O8#f)9OcD#M]Y!!^p#daQdtebn"s(^IOY[^XT.cHZ:nrm_/&
245 e^W."rP&4KrRUq?r?qQgs4.5&f_p!o=oMM$ec=>$ec5dN"T?sQfDa;#!r`3+e^W1#e^W'uaSs<[
246 O8hfQ91o.9q:,JpJ^q*WJ,~>
247 ZJ5>O!&4C*rn@/%!7_"srseu<r7_>/gY9XF_?1i$*Zk:6"38F%a8I"WgA]h2gtT'<Yd#eZ/H4?'
248 g\oV%%K6k5gB44HUndlP!8RM,"kq^QFEM^(E<+Mfe,BFL"T@!Ng]#n/*$$">rOi-Z!S%\Z%K>&]
249 g\ok)_Z1eX*rajng\muI/-+,tdJhi&gj49lHMq(NgY1E:rS7>VrS%>+rn78T!!iDU#27hWcHje"
250 rfm@WrA4N0J_R6[J,~>
251 ^"WM@ptG\>!&+=*rnI5%!7Uqsrsf&?%K+o^gY1Aurkeg[+<M^(gB5O;aN4<#rn@b5g"G*5YHP+5
252 /H.7#gAot+df9gU%Je][U8+KXrB1/8r7V>-g2h=WF8^%Xe,Ikr"98Q&fD=2(gDq=U*<!MKdfIr-
253 rXSq^!8@D)rPAOUrZD-o!8@CIr@7lqrmLc"s*4WiH2UqLg=b36rS.8TrRq8)rn@>V!!`AT#M[td
254 c-=PYP5^[D:AlsKgO\(Zg40~>
255 ^"*/3rRLhsrLEg:r7:bq!7q+prs8`6$.f(*!nPoQrOr@P)]BXnecWh,_o)EirmhD.g=k<6Xg#"3
256 .fLjpf)<np#lY,1f)*u$et/S/TKE-5!8%2##1_5SDf9T5rG2S^cHac7!!(LIdf.esf)OA+eef8A
257 (q9LQrltMir<WDQ!7q,!rP&4KrRUq?r?qQgrmh8+GB\4S=oMJ.f%&@&f@JO)!r`?$fDsP&eboOL
258 f)=,(e'cdgai__crf@"Mr@\0&J^pgOJ,~>
259 ZJ5>O!&4C*rn@8(#27hdeC2mprXAi;q:bnerkeUT!87A*rQ"jVrn@;)rNQ>Sr[e'&!8IJ%r=8YX
260 s.f[lV#<LQg\l6mE<+Pge,BFL"T@!Ng]#q+)uq#Y]E#SBe,U!X%K>&]g\ok*_Z@[trZ20rg=k<[
261 V>i(M/M,>tdF/$J!8IHu"'f,:>Q*:Ygtgc@r<N;U!8@G*rWW?-q:kknrKR7VrA=Q/"5MVbg4A"_
262 gOK~>
263 ^"WM@ptG\>!&+=*rnI>(#2._ae'umrrXJo;q:Yhcrkn[V!8@G,rQ+pXrn@G,rn.J/Yck77/H.7#
264 gAot+e,9aOgAdoKUndlOq:bdgrG__brWE3'rR^o"!8IJn!$)!M!4r-X!"Jo;rn@G,rRq1e!Q,uX
265 *s:<QgY2V%s!n7(/()ene,J)%gAQ:!>?kB9rRqA.gtUT^#6!6Ug&B_)#64u+g&g$_gAT:pPPn8T
266 1]Q/2gY(<6J_I?^J,~>
267 ^"*/3rRLhsrLEg:r7:hs!n>cOrm(Sir<WJTqpb\trP&4K!7h)"rPSRNrmh)%rn7P.Y->.5.fLjp
268 f)<qn#lrQReHONrTq\5Br]0o-s4%,#rGVXN"45?=ci!kBdf.esf)OA&f)6Ef\$i`QrQb?Irm_#"
269 rRLn]!5JIN!8%5$rLj0<!@T>pblH&gec=A$G6:uM='#:Ns47>'f)kpSrR_,%rmgrK!7q,!!n5]N
270 rQ5#!rC[#A"kM5TeCE'"eZdSS~>
271 ZJ5>O!&4C*rn@;)!8RS.!7_"srXAi;q:bnerkeUTrS%4j!$2%Yrn@;)rNZ;Prn7A,rmUqsr=8YX
272 rhKOjrBC&3rH/!X!7_"srW<-'rRh&&#2Ite*#fk<rOi*YrXJo;rn7M0g=k66rPJUWrZ;'m!8IIK
273 #:qGX/CMnmdJhi"g\lHs>lEFUg].WZ#Q<BZg=b05rWW?-q:kknrKR7VrA=K-!8N.[YM4R~>
274 ^"WM@ptG\>!&+=*rnIA)!8IM,!7UqsrXJo;q:Yhcrkn[VrS.:l!$;+[rnIA)"L,)5YUf])rn@G,
275 rmLkqr=/SVrhBIhrB9u1rH%pV#Lh2PdfT[T"9$jLg'6<cgDq7S*<!MJe,BdV%fY2cg=b03g&8bf
276 *r[8\gAot+U^&D$.kB#pdaJ-L!8@Et!-nHHrS%5)!!iK-rRqA,g=k<\#64u(gAT:pPPn8T1]?#-
277 gO\(^g40~>
278 ^"*/3rRLhsrLEg:r7:kt"4l#Qf)<qn#lrQReH"2!^ASrPf%&=%rPJ^T(Ddqff)4/'Y->.5.K1ao
279 f)EtqcM\%Lf)*u$et8Y0U-&?7r7:nu!7q*erG;JZ"OR5N!!)uG%+`tZf%/I(eef2?(q9LQrQbBJ
280 #RT)4e^i:$eCFN3r>PXcrLaBC-mpCebg"E3ec=A%G6)tlr`B'L"P;5Uf)u!TrR_5(e^`7L!W^gK
281 eH"2!ao.;!9)UCCf)F2"eq)ATeUR~>
282 ZJ5>O!&4C*rn@;)rS.D'rmUiT!"Jn]rS.Cjrk\XUrZ;$lrRV#^rXo.Q!6kDrrH&#kr[e'&!8IJ%
283 r=8YXrM9BUq:kjirG_qhdaQ\E!!!&uO8[f8Vl$AhrYkhWrRq/!rXJo;rn@A+!SZ<,_uLnY*rajr
284 gR+CrR/KGRg]#q,f`0Y'2#^_\?/>J7rnIAV"PhhhgtVh^rWNE/gY:N<rP\ZarS.:q!so5>$2rS/
285 gTK:]~>
286 ^"WM@ptG\>!&+=*rnIA)rS.;#rXAi9rS%5)!5e`Q!$;+]rS.;'!#,>ErlbAcrRqBqEcQ4Pr[n-(
287 !8@D#r=/SVrM0<Sq:bdgrG_ec!S#Ts!<%rVg&n4KVPjD5!#tmhrR:`T!"T"_rn7D+gASnh*r[8\
288 gB?5sR$X0<6ibs?g],q-g=ZB\!&FOX!F4FYg]#q*"pE]9gtUQ^g\qB["kq\bgASqfe,A#!bQA+U
289 #RLC^J_I9\J,~>
290 ^"*/3rRLhsrLEg:r7:ktrmh,%d/MAi#QWHTec+,"fDWD`)?(NVf%&=%rR1iY$k*UE`rO6[fE?28
291 F)`]/./h`qci".Mf)*tuet;r8!'C0?r7:nu!7q*erG2S^cHjo:!<.f\MUp>.etSk4UAYl.eGdqq
292 cMe(O$.dYWrmh,#f)<A^)ZA4hPE_8prBU>4s3q)"f)@B-1Kdd\=P3T(s4%/$!r`<*g"P05f`'J#
293 !<^p'f%'c6!5JKYrRUqg"9\f0"P*M$J^ppRJ,~>
294 ZJ5>O!&4C*rn@;)rS.D&rmUiT!"Jn]rS.CjrkeUT"5;G^gATY%&cTrRbl-;pF9!ol/H4?'g\oY#%
295 f+lXV#<LQg\l6mEW+Al!<<*#O,oB`rn@S0W2HSlr>bgi!8@D$r=8\Y!8ROk!$D1]rn7A,rL!OP!
296 8IM,"5);Yg&3c+>lEIVg\hBUg]6+.gAV6U#6!<U_uRdTeGe2&gAT:p$2rS/gTK:]~>
297 ZJ,8M!&+=*rnIA)rS%>$rm^oV!"Ah[rS%=hrkn[V"5DPag\oe(&c`OBbPg/nEr[cj/HFQ)gATM!%
298 Je`VU]!@OgAQ*kE;e8a!<8&[O,j4n"PK]MVl'D3rn%5(rR:]SqUtr(rPJUVrZD-o!8@C<rBpY>r
299 [email protected]=Y'V1]:PVg\ok)#6!9VgA]k+"oni*gA\ti`;S0ag&Th)bl%hGfn%k[g40~>
300 \(1E-rLEg:r7:nu"P22Uf%9lHr<NDSrmh#!!8%1`r>GdheCE.Ke,BdV&,jWKf_odi.fLgrf)F>#
301 d/XRR#lrQReH+6nrh0<Rr]0o-s4%,#rGM[Prb_hccd1#;!<7oWMi.Mb"kTTHV5,".(B`19e("BB
302 !71TMqUPYurP/:LrRUq2rBU>4"4YlMf)7<'=oMM$f*'[Te^ag$"T@!Rf`'J#!<C^Mec*8__#;UY
303 ec=8!aSc5Aec+'LeZRGQ~>
304 ZJ5>O!&4C*rn@;)rS.D&rmUiT!"Jn]rS.CjrkeUTrS%5%r=T"OrS.9m!&"7%rn7A,rRCcUq:kkD
305 rBC&3rH/!XrR:oM!!*-!O8[i3Vu7V6g&9G!%f+lX_uLnY*rajng\mN<70)*AgA]_)g&3c+>lEIV
306 g\hBUg]6+.g&hH]"U=q[rP\Zarn@G,rQY9IrRuhWY1nI~>
307 ZJ,8M!&+=*rnIA)rS%>$rm^oV!"Ah[rS%=hrkn[VrS.;'rXo2CrlY;arS%3kr@J$(rn@>"r=/SV
308 rM0<Sq:bdgrG__arr<'#!<%rVgARoI)u\Ffe,9aOgASnh*r[8\gAot+Qi0;PgA]k+f`9\'1]:PV
309 g\ok)#6!9VgA]h/"U5/7rS%4frR:c"!87=pr<WATJ_I9\J,~>
310 \(1E-rLEg:r7:nu"P22Uf%9lHr<NDSrmh#!!8%1`r>Gdhe^`7Le,BdV&,sZNaSjciE<%Ng-ihit
311 f_s1t$iUG4f)*tuet;r8!'C0?r7:nu!7q*e!,VXP#gpuEd/X.I!0$o7rmh)%rM0E2rYGRarmUkl
312 !71TMq:>MZr>PXcrKI1FrRUtt!7q*'!*T;&rRV2'e^`4PrWN2Q!8.;%!!*!!!7q/"rk8BIrQkJo
313 !7h%hr<*,NrmZMLY18%~>
314 ZJ5>O!&4C*rn@;)rS.D&rmUiT!"Jn]rS.CjrkeUTrS%5%rXf;FbKS/RgA]k*F9aBK/1]E-g=uVV
315 !7h#Xq:kkDrBC&3rH/!X"4YfLeGTFHO8[i3VZ7\8*<"RheGTmQg\o%j+9!>\g&Tn+R/]SS70)*A
316 g&osZf\69\!*fG-rS7A+r<N;V!8IM,[email protected]]drm^o$rQY9Ir7Z_VYM4R~>
317 ZJ,8M!&+=*rnIA)rS%>$rm^oV!"Ah[rS%=hrkn[VrS.;'rXoAHbg"ATg&B_(EsF6J/M,W1gY2YU
318 !7^rVq:beBrB9u1rH%pV"4P]Ie,9:FNr@]1V>qP6)u\Ffe,9aOgASnh*r[8\gAot+QiBGQ6ibs?
319 gAon*g&3],>5hb)g\ok)#6!9VgA]k+"oni+g&Tn+_Z83ce,A#!bl%hFfn%k\g40~>
320 \(1E-rLEg:r7:nu"P22Uf%9lHr<NDSrmh#!!8%1`r>G[ermh"r!7UoV#Rnbpa2urcf[g">r[7dp
321 ec+/!cN)>j#lrQReH"2!TD^bMf)*ttf)9OcC]i#/cdD[k!0$o7rRUqA!#GPM!7_"srltbp#n%+I
322 f%&=Kf)<A^)ZA7cPQ*lI5lK:5df@qs0*#&P=8peOf)F2"f)>^O"PNe+rRLrLrW)rJ!7q.`!Pd"\
323 ci)GnaSc5Aec"!KeZ[MR~>
324 ZJ5>O!&4C*rn@;)!8RS.!7UqqrXAi;q:bnerkeUTqq;)*gAZ[,K./2t.fE!<?iqu3/M-nT!8IJ&
325 r=8YXrM9HVs$$85rH/'Z!cW2/rm^lVrF,j[.kE7M,lahIWi=b-gtVeWr=8YXrPJUWrZ;'m!8IJ'
326 rC-lQ4Zu".8H;B];>jbug\ok)#Q3?UgAV9V#Q<EUSGai8.01nIr?h]%LPCP7gT'"Y~>
327 ZJ,8M!&+=*rnIA)!8IM,!7LkqrXJo;q:Yhcrkn[VqqD/,g\ug.KISE#.K)j:?NVi2/hR(W!8@D$
328 r=/SVrM0BTs#p23rH&!X!cN),rmUfTrF#dY.P!%J,QF\GWMnP)gY2VTr=/SVrPAOUrZD-o!8@D%
329 rC$fO5!D418cVH];#OVsgAT_'#5m3Sg\qEX#6!9SS,F]6-ikbFr?_W#L4t>4g8`kW~>
330 \(1E-rLEg:r7:nu"P22Te^j]Er<WJTqpb\trP&4K!7q(us470u"Fh^C,q&[^!(Hijs!Rms./h`q
331 d/=7Nf)*ttf);6@3<(u=f)*ttf)9OeC^"TkcHjhar<iU4r`oUR-7:2>+9/,?V52\mf%'cF#L<\a
332 $OPD7ebn"s^ASuKf)="p62ikI3^lG)7K#pY=8pbNec+%uec#UN"PES%!!<-#rRLn5!13X.s!.Uk
333 ,lJniJV&H(eq)APeUR~>
334 ZJ5>O!&4C*rn@;)!8RS.!7UqqrXAi;q:bnerkeUTrRq8)rn7I+JV&LP.K)m;?iVeX/H4?'g]#_'
335 f)6*Sg\mrH4o*k2FT$4Ze,e%Jr=8d8r@Ipn!%%TCrS.;#r=8YXrPJUWrZ;'m"P_MZf%0gi!C]3O
336 4Te8H8P8qYrET<UrS%2Tr7h5)rWW?-rS.:@r?hRnr[IdnrIt=-J_R6[J,~>
337 ZJ,8M!&+=*rnIA)!8IM,!7LkqrXJo;q:Yhcrkn[VrS%>+rn@O-JqJ^T.KCmq8c;ur/H.7#gAot,
338 e,\%t%Je`VU]!=NgAQ*kE<"AfdaS.(rF,XTrZ_CgrM]\KrR:]Sq:bea!$;+]rn@S0e^i:$r^?iU
339 4oRVI8kDWHrD<GsrS%5'r<E2RrnIDW!!`DUrL<a4!%7aor?hJs!8E(YX4i(~>
340 \(1E-rLEg:q:5Ptrmq%nr<WJTqpb\trP&4K!7q/"#h7DTep`$rIO4t=rC-Zhr@%Wqrm1Ymr<WJT
341 qpb\trLa$J!7q%t!7q*erG;M[!RB$i$2n0.-iP1f+T8)9f)F5!c2c2h$3&NSeH"2!^ASuKecX=J
342 dF%qZ!'pKC"%>UH7K#pY<rghNec+%ueboRFec5dN!WCRJQ2m9M+oike,lJqcJH4;QeZ75N~>
343 ZJ5>O!&4C*rn@;)!8RS."4YfJdf'[U&,Fr[_u@OO*r4OgJe'=[.4Rq_8kNK!?XPH:/M-nT!Sc3)
344 ebp!Rg\moM4Zkkjq:kjirGhkfs4$uWrF,jZ/M&IO,QOkDWVtTMeGTmQg\o"i+9!>\g&Tn+f)8&<
345 55m_E8H;B];>jbug\ok)#Q3?UgAV9V#Q<BZS"-%>r?qOmr?qPuJ_R3ZJ,~>
346 ZJ,8M!&+=*rnIA)!8IM,"4PcKe,9dPg&T"h_u1\Qg\la8.k3"t8P2QG?XI,H/1iJ+rn@J-ec+(s%
347 Je`VUB<V?4?WGnrH%pVs4%(tr=/^6""GiP/,^[mWW&jpgATM!%Je`V_>kYV+9(!pgATS#70#LM5
348 5n.S8c;Ka>Q*:Sg&2-QgA]k+#64u,g&me5S=BI(r@%UkrIogVWnMt~>
349 \(1E-rLEg:q:5Ptrmq+qs3CTM!=IETeH"2!^ASrMf)*ttf):%.-6si_77K^7>?b98-n$MmrRLtr
350 rm:TM!7q%t!7q+@"?8>"37duW!7q*erG;M\s3LWMrETLP-mpD@*rr/:U]B!Fec*hoci"1Lf)=,!
351 f)<>])ZA7cdJZB03W2DF9`8#mf)F5!e,\%t!r:CI!r`6!eH;)&Q^@Xpr?V=crIFt"J^pgOJ,~>
352 ZJ,VWU7n870.npWgA'D&e,Iep%0-n;gF1k3g=k<!_SX54*ZZ<WgY1E:g=k;6JqAV)-n-W<8P)N^
353 ?XR7n/M&LPg\o\$%fY2_h#6"+V#<IPg\u9tF)c2=EW+Dc%fKl8/H$goWrAt"gY1E:rR:oZ%1WmH
354 gAot,g]#(j`;LeVg],h*f@Bghr]U<FrC[&d"B&N1>[.0]rn7M0#6kD;q:blRrWiDVrL<s:-RU8>
355 .17LM-ROV'Kn\=:g>%86Y1nI~>
356 _:nqDo\'PBTqJ&30J>-Zg\BJ&df._p%KHt;g'-6bgY:H!rkffu+!)HWgtUQ:gY:G6K7eb).4Qc<
357 8kMZ^?=.%j/1W:MgATP"%K>&]g\ok)U]!=NgAZ-rEc>u9E;e8a%K0`6/,^[mWW&gug=b36rR1iX
358 $k3[Eg&Th*gA\qh_u1YTgAf\(f$sXer]L6DrCQub"ArE.>?_!Zrn.G."pG27q:YfPrW`>T#Fh6R
359 RjBC.-2f5"-7'ubL4t;6gY1?8J_I9\J,~>
360 _:AS7s4.)!rRLr!#hY]=S=D)[.P(;Fs4@>&rQYBLrWrMR!7q,!rk/NM(`=/-f%0`Krd>Z5,pOZ]
361 779O4>?P-6-mp>if%&=%d*L%b$2t50eH"2!ebu*<2u2#'D@p`$CMI\3cHa`B#RC`B>[1P^r[.Rb
362 !2TUh"4boOec*i"cNsg^$.dYWf)F27f"Si2^D[t-)V3Hhf$Vjlcp9o^5rnp($UmHO78-?I9itFs
363 <W1JIe-4A'!!*)MrRUtu!!*!!rRD%:Pa%IVrZMdt,9nHX+<_n[J:E("e^W0$eZRGQ~>
364 cJ/<Qo%O/uq:bo)[email protected]!rn7G.g"Q>Xs4[M-s4[M-s4[M-s4[M-s4[M-s4[G+"5V_bg@s>%
365 h"ob*gA0J'gABV)g?dPog@<ntg?%&kg=b36rS%>-leDBlrn@G,ptGf&q:bo)J_QIEJ,~>
366 cJ&6OptGc&rRq8)q:Yi'rn@5'pY,W$!o2MaqqD))s4[M-s4[M-s4[M-s4[M-s4[M-s4[J-s4RJ-
367 pY#W%qUtr&q:Yi%qq;&'m+MHmn_*urjk9gif\+sVg&TmngAT_(g&Th$g&Th%g'$0ag=tA5g6pZF~>
368 cIMmEpsoDns4./#!S,d#ec+,#f\-8T!8$Yi!S>i^ec"&,f[eR&f%/C%f%/C%rmh>)f%/C%f%/@H
369 eH"+reH"+gec45"eHjaVe^i=%e^i=JeH"+nec45#ec45#ec45#ec45#ec42$eC4BHrmh_4f%/C%
370 f%/C%f%/C%f%/C%f%0iNrRChs!7^qsrRLtuq:,W!e^`-trRLr!s4./#s4./#J^p[KJ,~>
371 cJ/<Qo\0B"o\0E#g\]_#gB$$_qV(Jo!8RD)!nuD`rS7A+!8RA(!8RD)!8@5&!8@5&!8@>)!8@"u
372 !8@5&!o2Pakh?*jrn@A+"5MYcgA0J'h#5t-h"oe(g?.,igAK\*g@s>%gk"4\gOK~>
373 cJ&6Oo\';uo\'Q'g=tB9g=tBXg&]m\qqD,(n_*utq:Yo'g=lM[rRq8+pt>`&q:Yi%pt>`$pt>`$
374 qq;&'o%F)spt>f(g=b]D!8.;(rn7J/g=k6Ug&Tn+g&Tn(gAT^ggAfn-g&0P(g%X2#gO\(Zg40~>
375 cIMmEp=92o!7gttrn.2#!7h)"s4IA&s4I5"!7gqs!7^Ph!7ptr!n>cNrRUqt!7pqq!7ptr!7^eo
376 !7^eo!7^nr!7^Si!7^eo!nPoOkg][^rm^qt"4l#QeG7Vpf)=,!f)!qqeEGH_df@nsec42&eCE.$
377 qUGSsJ^pgOJ,~>
378 cJ/<Qp"KK%n_<rpqqD,+rnI>(o@j9#p=fZ&gY;\^iS+@fr7_5*o%O/uo@j9#[email protected]_5,
379 qqD2*g=lDX!8RP-!8?tts4RS.g=k?UgAot*gB$$`rS%>-qV)&+g4A"PgOK~>
380 cJ&6Op"BE#n_4#trn7A,qq;&)rn@8(o@a3!p=]T$g=lM[iS":dr7V/(o%F)so@a3!nCdlqrn7A,
381 r7V/*qq;,(g"H5U!8IJ+!86nrs4IM,g"G-Rg&Th(g&]m]rRq;-g\]\*gY%/3U"Y"~>
382 cIMmEp=02pfDF.sf_X1ufE0XVf_sA$fD*qgeH"1oeH47Nec"(XeH"1ueH"+ieH"+jeH"1ieH"+u
383 eH"1ueH"1teH44LeG@\qf)=,!eFD)he-"1LeCO?D!7^qs!S#^!eH+1KrRLnu!n>fPJ^pOGJ,~>
384 cJ/<Qq:c#*gtUQ\g],t2gYCN:gY;\\"52D_g\]_)g\0A#gAot%gAot"gB66egt_n`"5MYch##h+
385 gA'D&gA]h,g?RDmh##h+gATe+g&Tq*gAp$kgAot,gB60_g"Q8V!8@D+!8R2#rRq;,h#5t-h#,n,
386 h"BD%h"08#h#,n,g4A"\gOK~>
387 cJ&6Oq:Yr(gY1?Vg&Tn'g&fs]g%X4qgAoq*g&Tn&g&Th#gAfn1g=tH=g]#n/gY1B9qq;&'pt>`$
388 rn7A*lIl6mqq;&'rS%;)!8ID)!8HYi!87A*"52>Zg%j>%g&9V)g[j.tf`Bg]rRq8+r7V/*q:bf%
389 !SlH%g&Tn*g&TfWg9'(Z~>
390 cIMmEq:,Ssf%&:Lec45"fDsV#fE0[Wg@s8!f)*tteGdu!daS!A!7^bns3h,$f%&:$rm_,%e^`7J
391 eH"+oeH"+ueH"+aeH"1teH"+tec4,!f)*ttf&kK_eGdu#eC2mrq:,JprRCo!o@<fh!S,d"eH"1u
392 eH"1rec!qteC4'?!7q(u!7ZSMXjqq~>
393 ceAHRp"TH!rS%SY!!!$#!!!$#rW)ourrW3$r;ciurW)lMs4[P/q:kl'qqD,+qV)#(r7_5*mb@]q
394 n_=#rrS.;+s4[P/ptPc&kh?*kp=fT&^YAeDs4dM+J_R'VJ,~>
395 ce8BPp"KAtrS$oErW3$!rrMlpr7h8,!8IM,s4dP,rS.5'!8ID)!8IM,s4[S.g$[Smg[X"rg&9Y'
396 g],t-g\BM$gZ[>kg%O,"gWJ7Ig\fe*g]-"+fn%kSg40~>
397 cd`$Fp!s#jrm_#"nc8[jp&G*DrRLnurmh%trmgtuqpb\tqpbr#dacmse()t9ec"(hec""rec")!
398 eH"1qec"(_eH"+meH"1Cebdhnec45#ec"!KeY^lI~>
399 `S1UPgY:H8g=cGZ!s&B%!Vl]s!<<,u!VcZng&p*`gYDVZrS.J/h;.YV!8?kq"kq_dgYCTVgB-0b
400 g\ok)g\oq#gBHBggt^Z<rS%>-eCt/^gY:N<h"ob,g=tECgAot&gBH<cg=k<8J_R-XJ,~>
401 `S(ONg=k64g"?8WrVup!q#CHs!Wr<$p]19I"5MYdg]#q,g]#q*g[s4tg[3\ug"P37gY;AS!o)G_
402 rRq/'rS.#!"l%hegY1?Zg&TmWg'-6bg=t?9qUu#(g=tiFr7gu""khV_g"P,1g8N_U~>
403 `RP1De^`0ueC4EI!7q,L!!2lqq>p?k#M.GUe'uq!f)F5"e,Inrf(@Mjdf@haeHOIQf%&@&o[O#o
404 e^aWJrRLktp!j5sf@JO'eG[ntf$r4Rf%&=%e^jTI!n>cOkgfU[!7LYm"k;)PeCE'"eYq#K~>
405 `S1ILgY;\\rS%;Qqu?]tqu?d!!!)otqZ$p'!8?2]g>(E:h"f_'g]H6dh>>q,h"ob*g@X/"g]?0b
406 r7_>/gYCT\gD&GtgYCQ<gtUT;gY(<8gtUT=h;$fYg\oq-gAot,gAp%.gB?6bgY1BXgAp$ugAp%%
407 gAp%!gAot*gB66cgYCoFrS%;+!8<"YWS;q~>
408 `S(CJg=lMYrS%,K!!2ut!W`?(quQZp#lt%\gtUT>gYCQ_gAfq,gATe$g&Tn,gATb,g=u;Ss4[S.
409 g\fb-gY1E:qUuY<g=k<8g=t?8g"P*3g=t?8gYCQ<p"KB!s4RJ+rn7A,rn7M.g=k65qUtr(nCdls
410 p"BE#n_*urr7V8-g=k<RgABY"gAT_)g&TfWg8WeV~>
411 `RP%@e^aWJrm_#"qZ$TsquHNnq#LHG"kD)Pe^i=Nec4+tec"(oeH"2"ec!qtdaRm>s4.5$f)4&#
412 f%&@&qUH;2e^`7$e^i:$eCE$te^i:$f%8L(p!s#ls4%,!rm_#"rm_/$e^`1!qUGSsnC7Nip!j&n
413 n^RWhr7(o#e^`7Cebdhjec""teH"*MeZ%)L~>
414 _:o%Fg"QDZ#QXo*!<E0#!<N-!q>pQqquI)Xg=k<;gY:N=rS./'g"ZJ\p"T;rq:tf#q:qCmq:^DS
415 VqZ_~>
416 _:etDf\-5W!WW6%pAk$jq#CNNgY:H]h#H.-gA0LrgABXjgATe!gA0Ftg\KS!gSNX(g]-"-g\]_#
417 fn%kTg40~>
418 _:8b>e(*%"e^ig^!7q/"!8%2#rRL_pp!rrgldbsbp!rlfq:>Alq:;Cms3q"us3pkqq:'uGVq$:~>
419 \_I/<s4dS-s4d/!qqM/)s4dS-J_Pb1J_ST,J,~>
420 \_@)<s4[M-s4[)!qqD))s4[M-kM#gfJ_K#8s4dS-s4`+YRG*/~>
421 ^X`A8s4./#!7g5_iRRhSJ^rZ.s3q"us3lPLRFQf~>
422 ]A!>@o\98sJ_Pb1J_S#qJ,~>
423 ]@m8>o\02sf@p,VJ_G\/J_KYJJ,~>
424 ]@?r5ec+.@ebdgHeUc8%ea_1?~>
425 ]\<G?o@s/rp=f]'gtUQ*gAorYgO\+8gOK~>
426 ]\3A=o@j)rp=]W%gY1?CgABXjg&TfWg4@t6g40~>
427 ][[#3ime.\f%&:4ebdh]eH"*MeUc8,eUR~>
428 ^tSkCq:kr*q:kf#q:kr*rn@G,J_Pb1J_SN*J,~>
429 ^tJqEg=k<9o@j)ro\';ujkBUdJ_G\/J_KYJJ,~>
430 ^srS;e^`-ti7.hWjjj7WJ^o>%J^s;@J,~>
431 \(^o=ptP]"q:kr*J_Pb1J_SB&J,~>
432 ^"WM@s4[M-pY,N!f@p,VJ_G\/J_KYJJ,~>
433 ^"*/3s4..ua4:(9J^o>%J^s;@J,~>
434 [+bT7qqM#%rS.A+J_Pb1J_S6"J,~>
435 ^"WA<rn7A,qqCr%rS%;+h:hb\rS%;+J_KYJs4dS-s4`+YNS8m~>
436 ^"*#/a4:(9rRLqsJ^s;@s3q"us3lPLNR`O~>
437 [G1`8qqM#%rS.A+rS%>+J_Pb1J_SE'J,~>
438 ^"WA<s4[M-qqCr%rS%;+rRq8)inF:arS%;+J_KYJs4dS-s4`+YNS8m~>
439 ^"*#/kLBR^immqTrRLqsJ^s;@s3q"us3lPLNR`O~>
440 J_Pb1J_Pb1kM(L~>
441 J_G\/J_G\/kLtF~>
442 J^o>%J^o>%kLG(~>
443 J_Pb1J_Pb1kM(L~>
444 J_G\/J_G\/kLtF~>
445 J^o>%J^o>%kLG(~>
446 J_Pb1J_Pb1kM(L~>
447 J_G\/J_G\/kLtF~>
448 J^o>%J^o>%kLG(~>
449 J_Pb1J_Pb1kM(L~>
450 J_G\/J_G\/kLtF~>
451 J^o>%J^o>%kLG(~>
452 J_Pb1J_Pb1kM(L~>
453 J_G\/J_G\/kLtF~>
454 J^o>%J^o>%kLG(~>
455 J_Pb1J_Pb1kM(L~>
456 J_G\/J_G\/kLtF~>
457 J^o>%J^o>%kLG(~>
458 J_Pb1J_Pb1kM(L~>
459 J_G\/J_G\/kLtF~>
460 J^o>%J^o>%kLG(~>
461 J_Pb1J_Pb1kM(L~>
462 J_G\/J_G\/kLtF~>
463 J^o>%J^o>%kLG(~>
464 J_Pb1J_Pb1kM(L~>
465 J_G\/J_G\/kLtF~>
466 J^o>%J^o>%kLG(~>
467 J_Pb1J_Pb1kM(L~>
468 J_G\/J_G\/kLtF~>
469 J^o>%J^o>%kLG(~>
470 J_Pb1J_Pb1kM(L~>
471 J_G\/J_G\/kLtF~>
472 J^o>%J^o>%kLG(~>
473 J_Pb1J_Pb1kM(L~>
474 J_G\/J_G\/kLtF~>
475 J^o>%J^o>%kLG(~>
476 J_Pb1J_Pb1kM(L~>
477 J_G\/J_G\/kLtF~>
478 J^o>%J^o>%kLG(~>
479 J_Pb1J_Pb1kM(L~>
480 J_G\/J_G\/kLtF~>
481 J^o>%J^o>%kLG(~>
482 J_Pb1J_Pb1kM(L~>
483 J_G\/J_G\/kLtF~>
484 J^o>%J^o>%kLG(~>
485 J_Pb1J_Pb1kM(L~>
486 J_G\/J_G\/kLtF~>
487 J^o>%J^o>%kLG(~>
488 J_Pb1J_Pb1kM(L~>
489 J_KqRs4`+YJ_G\/n_/K~>
490 J^sSHs3lPLJ^o>%n^W-~>
491 J_Pb1J_Pb1kM(L~>
492 J_KqRs4`+YJ_G\/n_/K~>
493 J^sSHs3lPLJ^o>%n^W-~>
494 J_Pb1J_Pb1kM(L~>
495 J_G\/J_G\/kLtF~>
496 J^o>%J^o>%kLG(~>
497 J_Pb1J_Pb1kM(L~>
498 J_G\/J_G\/kLtF~>
499 J^o>%J^o>%kLG(~>
500 J_Pb1J_Pb1kM(L~>
501 J_G\/J_G\/kLtF~>
502 S(7PiJ^o>%J^r)sJ,~>
503 J_Pb1J_Pb1kM(L~>
504 J_G\/J_G\/kLtF~>
505 S(7PiJ^o>%J^r)sJ,~>
506 J_Pb1J_Pb1kM(L~>
507 J_G\/J_G\/kLtF~>
508 J^sGDs42bOJ^o>%p!nQ~>
509 J_Pb1J_Pb1kM(L~>
510 J_G\/J_G\/kLtF~>
511 J^sGDs42bOJ^o>%p!nQ~>
512 b1cpMqqM)*n_43%g=tB9pY,]'r7_5*hV/%aJ_Pb1J_TeNJ,~>
513 b1ZjKkLp'ng"P05pY#W%r7V/(hV%t_J_G\/J_K_LJ,~>
514 b1-LAldc$ds4%8'eCE+!pXK8prRCo!h:2MTJ^o>%J^sABJ,~>
515 cJ/<QqV1u)ptP`SrPnB^r<N;TrS%>-mb@]o"*8L(F+N(sgO\,MgOK~>
516 cJ&6OmFqLFrPe<\r<E5RrRq8+mb7Wm"*/C%Ee2qqg4@uKg40~>
517 cIMmEmFD1=!<p==_"#tS!<E8Prm^ns!7pSgrR:pdCi+$?eUc8%eah7@~>
518 cJ/<Qr7h&'qV1rUrl+rYn_=!IrS$Pkr7_*jJ_Pb1J_TbMJ,~>
519 cJ&6OmFqLFrl"lWn_3pGrRpJir7V$hJ_G\/J_K\KJ,~>
520 cIMmEmaV<gr<<2:!Q*FZeH"2!!r^XLf&kN]D?/7=eUc8%eaq=A~>
521 cJ/<Qr7h&'qV1uV"UW2f`l?a*gBQHfgBRrh#Q<B@g\ok)F+N(sgO\,MgOK~>
522 cJ&6OmFqOG"UN)c`PpO'g'6<cg'.`d#6!6>gAT_'Ee2qqg4@uKg40~>
523 cIMmEmaV<grWNE-_8*n'o[O/se^ad'!s8GO!7pJd!7q,!rGDVdJ^o>%J^sABJ,~>
524 cJ/<Qr7h&'qV1rUrl+rYo\0H&gY;Z3rS$MjrRq?pFE;MSgO\+1g[a*L~>
525 cJ&6OmFqLFrl"lWo\'B$g=lK0rRpGhrRh9nF)l;Pg4@t/g@EsJ~>
526 ldbsbkgfX_maV<grWNE0_nj1+rmpho!nZ#Sr;urJ!7pJd!7q,!"E&3uDUsBhJ^o>%o@8?~>
527 rnID,dG+WR!8RS1!8RP/qqD,)rX&c9`lH*=rS7A+rS7G-!SlH.Xl\=9f_l0Ugk"42gO\,QgOK~>
528 rn@>*dG"QPrS%>*pY#W#rWr]7`Q#m9rS.;)rS.A+!Sc?,XQA17fDQ$SgO\(0g4@uOg40~>
529 rmgtuo%!]ijOO4YrRLtup=9-G":2o^_86-&!7q,!rRM)$f%8LOW;P64eH"2!df]gZ#6i`Yeq)A&
530 eUc9EeUR~>
531 rnIJ.!SuPYgB?6`g=k?]h>l@0h>5n)$NA$F`VnTjg]-%0h;%t`rN529rRh&UrS2tYJ_Pb1p=k)~>
532 rn@D,!SlGWg&p$\g"H>Y!87)"r<`JB!6"ijrS%;+!SlH.gAS,7gATY%$2rV0g4@t/g@j6N~>
533 rmh&"!S>otea_5UeH==MeC=HJ!7^bn!S.GR#QDUA_V+q?!7q/"s4.5&f)F2"f);QFf'Cidf)=(r
534 "o[$Qeq)A&eUc9FeUR~>
535 rnID,dG+WR!8RS1!8RP/qV1rUrPnfkrS.;+rS%=RriPA<!SZ<,f_l0Ugk"42gO\,QgOK~>
536 rn@>*dG"QPrS%>*p=fHOrPe`irS%5)rRq7PriG;:!SQ3*fDQ$SgO\(0g4@uOg40~>
537 rmgtupsnoclIGj_rRLtupXK;q"o\c*_Z8Bhf)XD$ec"(ueH+7!ri#bGm*u-df)=(r"o[$Qeq)A&
538 eUc9FeUR~>
539 q:tVs$JO:ig=k<9gtUW<r7_5*nD!oqrS7)#r<`YHa2Z0th#?(,h#5t0XfSV+rn@/%!8R/"!8.;&
540 rWrQ3rS2tYJ_Pb1p=k)~>
541 q:kSr$f'Lkg=tB9g=t?9g&0P(g$m_og&9[ugAM<[`Q#m:r7h5)rS.;)"0AW,Y5[2Ng&Tmug&Tb(
542 f_u3X$2rV0g4@t/g@j6N~>
543 q:>Srqptets4.P/f%J^,f%AX,f%9oOs4.5$eF;#eeG[tpec"&!f_l$X_o0I2g&9P%ec"(ueH"2"
544 VuWglf)O8,f%8I&f%/C%f%0`K!7q+t!sJf1"o['Peq)A&eUc9HeUR~>
545 o%X,T">hnk2%'<hrA=Sfrk&-`rS%5)!8RD)!SuQ#g\hKX`qnEigATb+gA]h,#Q=r,g&Tn+dJlK5
546 5XG>n"",EC-iIBMgAkmcB)Vl4"T:@]7fGo/gO\+1g\TZT~>
547 o%O&R#;\1o1^OKr#lQR[]DfD?gAT_'g&Tn'g&^!`nCmgIrPeWe!87>)!87A*!!`E-rn@G,rQtR0
548 !C&jJ+p0/<-78[srRq6`rb)35!!E0[!(HlVJ_G\/J_KtSJ,~>
549 pXT2m%(<RO[P'9f1'[sd"u?03"LkhI[atH.rRCer!7ptr!S>oqec"&!f_l'R_Z8?ff)O8#eG[o"
550 eCE+#r;urKrQG[44$#JF*??1F+<_q3r`K0M!7q*Xr;cdR"$o7?6%RR;eUc9IeUR~>
551 q:bo)qqD@g]=Y^51Ggrf#lk>22>t,eh#?(,gA'D)g=tE=rS6tur<iMCr7_5,r7_D1gY:H;#Q=r,
552 g&Tn+dJZB0,Q0"g?3&d[gAkmcAci,:!sJQ`rC;FnJ_Pb1qV-N~>
553 q:Yi'qq;:e]"5L11Ggre$2l^Z\cCLagAT_"g&p$^gYDb^o%O$KrPe]g!8IG*"l%bbg"Q`1#QEHX
554 gATCs5lDo*-N.3Mg]#q*Aci/<"9\T_rC2@lJ_G\/qV$H~>
555 q:,Msebmu'\$i`U1,1O>r<N9VrO)^XrmgtspsfJre^i@Nf([_nec=A$#Q;O?f_j=ueHFIRe^W4L
556 !r^^Kbl'[&*rR;]=Td:,f%Bq3r;cdRrB^M8J^o>%J^sYJJ,~>
557 q:c#,gY:N_gAnnc])X_f2#[d]$N2j\]D^L_g@j8%gthqao%X*MrPnH`!nuB6rW`AU!8IM#!7:[1
558 r?M7gra#S3rS%<brau-3!!N6]rC?kA!8N.[J_Pb1rnDr~>
559 q:Yr*g=k<\g&Sba])=Ja$2l^Z])C@]g%O,#gYDb^o%O$KrPeB^!nl93rWiGW!8@G!!71U/r?D1e
560 r`oM1rS%3^!s8Z/"8t7Y7fM*AgO\(0g4@uWg40~>
561 q:,Sue^i@OecWCi[^c8kr<N9V!4`$:!7q/"rRCPk!S5m$f([_nec=A$#Q;O?f_sCreH+1Nr;urK
562 rlbAcrB1$"r?D5D!*]BQ!8.6\!!3'!rAFO?"4l#Qeq)A&eUc9MeUR~>
563 o%X/U"MHZL1Go(;":@"C1c>6DrS.;)p"TH#n_=!LrPnB^!!iK-rn7A-rR(U1!CA"0,6K>A-RSdu
564 rS%<brau-3!!N6]rC;FnJ_Pb1qV-N~>
565 o%O)S"M$?G2)P:=!=1L\2#Y#agAT^tgATdrgAM?V`UVX^#6"l+g\oLu5QO.orZVFl-71&;?2`LU
566 Aci,<"9\T_rC2@lJ_G\/qV$H~>
567 pXT2mrjDg:r\=X6#mU\A2#]61\Gio:f)F4ueFhAjf(RYmec=A$#Q;O?f_sCqeH"2!!rgaNfDWqm
568 497ScrZ2.d+sJ3/=oQtPf_o=\!WE)t2$6056pgn(J^o>%J^s_LJ,~>
569 o%O:(2)R;nqZ-Wsrr<$"rAE9_r<iMCq:kl'rS%;XrW`PYg=k<[P5S,XgtUT=rS.:s!8RS.!8.;&
570 !sf2>$MrKWgk"42gO\,UgOK~>
571 o%F:(1c-ug!!2iprA<3]r<`GAq:bf%rRq5VrWiV[gY:H\Oo7uVgY1B9rS%4q!8IM,rRV,W$47+9
572 g&TlYg4@t/gA9NR~>
573 pXT2m""u>^1A(YI1B0'.f&5*Wec=A$#Q;O?f_sD#ec"(ueH"2!!s$mNf):U,8H[Sqf%9lOrQ55o
574 f%/LPeGogQ"oQsOfDsP&eq)A&eUc9LeUR~>
575 ptGl(gY2Y]rA=QUpAb<s2)[9Kg"ZH4rPnZfrS7A+!!rQ/rn7A,[email protected]!)<:DrQkGs!87A'rs8]3
576 $3&ZZgk"42gO\,QgOK~>
577 pt>f&g=cJZrA=0I"#Mkk1tgU]$2qj=gATe)g&MBW#l`QYgAR059`Rl_gAT=qg&Te)f)l<d#mgOa
578 !8E(YJ_G\/p=b#~>
579 psfGqf%'cNr\+=-o`,(L1GLZ_f&P<Zec=A$#Q;O?f_sD#ec"(ueH"2!"9$gLNW)KL8GUj8b5Trm
580 f[g&P!s\u4"THsPfDO3NeUc8%ebdmI~>
581 o%X+#rrMlp!!3$UrS%>+mFqWro@s3NrPnZfrS7A+!!rQ/rn7M1P*;&lrD*1CrQkMu!nuG^rn%,U
582 !"/PV"5MYcg4A"0gO\,YgOK~>
583 o%O%!!<</p!!"hS2#Z,.g$RJng[j.t$2qj=gATe)g&MBW#lWK[OckihrD!+ArQbGs!SQ6+f)l<d
584 $46O^"5DP`fn%k.g4@uWg40~>
585 pXT2mr\+C/!!2fo!&X[1!8.;%m*u*epso>o!8.5TrPJWfrRUturRUtu!7q)Nrmh5(NK0!XrCQh9
586 rQ>/k!S,m%eGojR"o6^Of@AF$J^o>%J^sbMJ,~>
587 o%O.&r\XZVqu?]tquH^Q!&`Har<iMCq:kl'rS%D[#7(P5g'$/nP*;(-:ANZCcNN"XgY:B[fDZ'V
588 $A$r_gO\,MgOK~>
589 o%F($r\XKP!!2utrA<3]r<`GAq:bf%rRq>Y#RLb8gB?5mOckk*:&3NAc32kUg=k0Xf_u3X$%^f]
590 g4@uKg40~>
591 pXT2m"#2J`1A_%O!W2ot2#]61f_sC]ec"&!f_l'R_Z8?ff)F4uf)F2&ecQ!W!r^^MN<,'!rCQh9
592 rQ>/k!S,d"e,9IJeq)A&eUc9FeUR~>
593 o%O9T$k*LErW)ltr;Zg(rX/VZh:ql8rPnQc!8RP-!!iK-"5DPah#4te*!I9$@U`hVrL3]:rS%>)
594 rn%,U!"+;3J_Pb1o%SZ~>
595 o%F0Q$O[=?!;urs!!<N7$46[ch:hf6rPeKa!8IJ+!!`E-"5MYdg\nhc)[.-!@:<VRrL*W8rRq8'
596 rn.2W!""51J_G\/o%JT~>
597 pXT2m!sSu8#lOc%!W<!$#m^eAg&BS'f&P<Zec=A$#Q;O?f_sCueH"2"eH"2!!X%'*f@Tu3rtbhS
598 (L:<Q?2^&edKA(Ne^j]Jr<<,MJ^o>%J^sMFJ,~>
599 o%X*O!!3'!r;lisrX&W5rS65`r<iMCn_4-N"U,,0gAp%-^AT&M@f;bqf)aISrS%>)rn%,U!"+;3
600 J_Pb1o%SZ~>
601 o%O$Mr;ccsr;cd'rS-/^r<`GAn_3sH!!iMY!8IIcr>Y]DrL*]:!S,d"g&Tb(f_u3X$2`EVgO\(0
602 g4@uRg40~>
603 pXT2mrW`E0r;ccsr;Zg)rWiMWrmq/$j44+Z!8.5TrPJWfrRU_n"P*VT!<W5OrOMkCrE]Aes3^qq
604 df%bqe,BLO#MB"+!S,YMeUc8%ebRaG~>
605 ptGf(r7h/Y!!3'!r;lis!"8c5rS65`r<iMCn_4$KrWWJZgtUW_^AT&N@K9p:RKM0mf@TuU!8.;&
606 rWrQ3J_Pb1J_TbMJ,~>
607 pt>`&r7_)Wr;ccsr;Zp-$47+<gYLT^$2qj5g&M?V#6Wc;gtVe@r>Y`E!+Pnp"4l#Rf)=;&fDaG%
608 $31D0g&TlYg4@t/gA0HQ~>
609 pso8mrW`E0r;ccsr;Zs.#RC[grmq/$j44+Z!8.5TrPJWfrRU_n!7q)M"4u2WfDW8Y(]I\??N$,k
610 da?LkrRUqrrWN9,rRV#!!7QMLJ^o>%q:0u~>
611 ptGf&r7_2ZrX8c-rW)s!!<<0!!!<Q7$4Hgfq:bo)k1fhArPnB^!!iK-"5DVch#4tc*;s@FRf:n=
612 f_sP)f`'M%#lk<`gO\+1g[a*L~>
613 pt>`$r7V,XrX8Z)rrE-#!W<!#$4@1JrS./%!8HYir<`GAn_*sIrW`P\h;$c`^&8oK@JuVnec=>#
614 g&Tb(f_u3X$%^f]g4@uKg40~>
615 psfAor71rS#6tS6!<3'#!!3#u!"/]2!87A'!7q"s!7pJdrRLu$r<N;=!8.8$pXK8pr;m)Qf[naR
616 \c!?C?2^&fdK%bpf)=(r"om/)eUc8%eb%CB~>
617 rnID,q:kj+!!2cn"#Vnl2YGi)gumGj$N8!;g\on-#Q=o/g=t?[gB$*Trlk\4Q'@M/:/=[a2#uG2
618 gBZEaf@L96#mu7<J_Pb1o%SZ~>
619 rn@>*q:bd)o`,(O2E!GcgAfpjgAM?V`V%s`gAhHW#6NZ8g\oh,gWf`A#EtC9P>4hI:Am!Lg]#n3
620 f\+p0#mgqFJ_G\/J_K\KJ,~>
621 rmgturmgqtr\4C/o`+tLr\FQ,rRUhqs46PerRLu$r<N;=!8.8$qUPSr!8%/N!S5m#ecFCErl>>*
622 OH5Gp8P2VR0EB`(f)O8"e,KRN"T[,)eUc8%eaq=A~>
623 rnIJ.!SuQ,gB9Dl2)YL6!!!&s!!>)81cG-`!nuD`rnQ_lr<iMCp"TH#!!iK-rn@;)rQPG/PEV70
624 :]E9Q1c>6d!87A(rWiK1J_Pb1J_TbMJ,~>
625 rn@D,!SlH*g&j2h1c>12!!2rs"#Vtp2>Gl,g"P0ZgZ[Ai$2qj9gATb+#6"l,g\fe(bQF&lP*>i>
626 s"ja42#Z,.f`'S'#lk6^g4@t/g@EsJ~>
627 rmh&"!S>p%ebmu#0eb:;qu?]tqZ$URr\FQ,rRUqt!n>cNrmpJerRLu$r<N;=!8.8$qUPSr!8%/N
628 q:>Mc"-8J&O8V]N0EEg\rRUqsr<*8Se^`7%J^o>%J^sMFJ,~>
629 rnID,q:bm.r\a`Wp&G1P1c.)bgBQBdgYCW?h!*Sl$N8!BgAot)g\oq+#6*?SgB5^Ec-?3OrD3AL
630 rS%>*rn%;Y#7(WegO\+1g[a*L~>
631 rn@>*q:Yg,r\a?K"#Vtp2#,c/g"P07gtUTJgAM?V`VeEig&'M%gAhEV#QEKUg&oRBbfp$LrD*;J
632 rRq8(rn.A[#RLcfg4@t/g@EsJ~>
633 rmgturmgqt"#;Sc1\C_N2)@$Df_sD"eHXORe^i@'f'_)eec=A$#Q;O?f_sA$eGIeqecFA'rW;oH
634 "3AO(aSh1u9)UIBf)=)("9Sc0f%&=%eq)A&eUc9FeUR~>
635 rnID,!Sc?*gB9An3&Ug2!!G/91c=(]g\opmgC=Ps#n+bl`Q$Zdg=tB9gAK_(g].WZ"p3N3gAK_(
636 c2En+:B4/g2>u80g&BV+#R:VAJ_Pb1J_TbMJ,~>
637 rn@>*!SZ6(gAWo/2>$qP2)[?Lg\';!gZmMl#lk>2`<P&NgY1B9g\fe(g\hBVg\fe(bl*b):&n#e
638 2#Z,.f`'S'#lk6^g4@t/g@EsJ~>
639 rmgtu!S,]seH7HZ0f/J&r\FR1g&9Ltec"(fec"&!f_u*Z#fFX#_q=q=s4./#s4%;(f@JO)"9&At
640 f)<\gO8_`O8c:@Af)=+s"T$]#eUc8%ebRaG~>
641 s4[P-rS%>+qV)7e^:h-:2DmAj$N2jd]",DagYCuHrS%5)!8RS.%LNLK$HC'(`nT5$gY:H9ptGcR
642 rWWJYg"P3Z_unN<eC4BNrQY9Iq:bfS!"/\V!o)Mcr7_5*J_Pb1J_U4ZJ,~>
643 s4RJ+rRq8)qV(t\"hD3%2DmAj$N2jd]">Pbg=tfErRq/'!8IM,r<`GA#27hdg=k<9pt>]PrWiGW
644 !8@Ch"4P]Idf%nubl%hFg&B_.$4@1IrRM&(gY;Y[!82qWJ_G\/s4Vu~>
645 s4%,!rRCntqUH"^\$ie&1c$ur#RCbqr\XS`!SH$'f':faeGdu$f%8L(f_l$X_o9U4f_sD$ec45#
646 ec45#eH"2!!r^^K^B;g-cd)L?rQ+p?r71et!sJl4"oZjNf%8OOeH"*MeUc8%ec40M~>
647 !8RM,!8RD)rOW:m2)I/s$4@4>2ZC8f]B.fGgABV/gtN/C#n"]O`;nZigABY)g&]q5rW`AU!8IIj
648 rRCf#rQY9IrRq8+rn@>X!"/\VqqD/*gk"42gO\,YgOK~>
649 !8IG*!8I>'rON4k2Dm>u$4@4>2Z:5KgAT_%g'-6b#mptFrl"lUrS%8*qqD)'!SRbW#QEHXgASqf
650 e,A#!bl%hGf`9b*g\qN[$2rHPg&]m]J_G\/J_L+WJ,~>
651 !7q(u!7ptr!4Dg7s"O[21C"0l#lQUY\,b1[f':fbe,\%recj[X#7(P>rke`QrR_2&e^aQJs4%,#
652 r;urKrP/<WrRUqgr<3)LrRUoNrR1Vp!nGfOJ^o>%J^sbMJ,~>
653 p"KQ%gY;\=#<"Ft2$s]u$N2jb]">PcrS%>-q:bo'o@s5tq:c/^#mgsY`Q#pPqqCi"!!iK-"5;M`
654 g\o(heGe2&gAT:q#lk81gAfn/g"P0Z#lk>2fDOA'gk"42gO\,WgOK~>
655 p"BK#g=lM:#;nCu2$s]u$N2jb]">PbrRq8+q:Yi%o@j/rq:bcRs2>#Y`VeHig\BJ&#6"i0gYCQ;
656 rPST_rn7A*rQP6H!!iMVrn@D,rX&W3rRUo#!8E(YJ_G\/r7ZZ~>
657 p!j/oe^_),[f8&c1,B1B#RLAc"1YnO\GatYfD3qseFV5ie,\%qec=A$#QM[B`5DN*!S5frf)5XP
658 f%8L(rP/<Wrmh)"rQ+s@!!E5Ns4.8%f%0d'rR1SoJ^o>%J^s\KJ,~>
659 o%X,T#W=Os2$sWs$98#Crji*AjkKafq:blVrWr_H`5KXLqqCi"!!iK-rn7A,rP\ZarS.:qr<`GV
660 !8IM,rWrQ3rRZVTJ_Pb1p=k)~>
661 o%O&R#;nCt2$s^!$N2p_])]G(gAT_#gAM<\`Pf^6g\ok+g\BJ-"pYA;g=tB9rPST_rS%4or<WAT
662 !8@G,rX&W3rRQPRJ_G\/p=b#~>
663 o%!`I!4Mk]"Z$Dg"pd*c1B"Z]f&tT_e,\%qec=A$#6_r]_Sb(*f_3nq!W`GVrmq%_rQkGnrQ+p?
664 rRLktr<</J!nQ#VrRQPMJ^o>%rRHD~>
665 rnID,o\0i/g"P05g=k<9g"P-5g>pugg@j8$$N:A2'EAmE(BG@(r[n*'!!iK-rn7A-rL=*?-mpAl
666 .k3%I-NJr$LA]g*g';(q@U^N++sQtHs4[P/J_Pb1J_U.XJ,~>
667 rn@>*o\0?"s4[M-s4RY3g=t?9gZ7&gg%O.u$2tV=(&SmJ(]bF'r[e$%"9o)9#29(2rL4$=-RL/h
668 .OchF-3/f"L&B[(gBV4t@ppN)+X-eEs4RJ-J_G\/J_L(VJ,~>
669 rmgtup=9,ms4IA&s4@G*e^i:Lf&kKaeCE+Fec=A$#Q>>9'DrUE'*'EZ./h`r!X&YYf%/IOQNn]Z
670 +sJ<[,piL6!.t3$q:6$^?!^eW*ZZ7Y2`EVFf%5K'J^o>%rRHD~>
671 rnID,ptGf&rnI%ujP'[gp=oTSrsAW<r>,SP(Ddo@r[n*'!!iK-rn7A,rLEg6r@7anrJ(7)s4RJ+
672 ra>e9r?D2$J_Pb1J_U%UJ,~>
673 rn@>*pt>`$rn?tujOsUep=]TT$4.%;'`AgJ(B,*M/cI="g&M?V#QEHXgARN>-N,Cl-N/YrgAfn-
674 gAYO]@JqAJ3J#n8g4@uSg40~>
675 rmgtupsfDpeaM)OeH47NebRc!fEVZe#Q5;6'`\sI'`]c`./h`q!r^^KQi/-,-2f%dJbmptebreP
676 *W7hqeq)A&eUc9JeUR~>
677 rnID,[email protected]'g\9D&g"P*5!"/]3r=fMR()Ri((`+#?r[n*'!!iK-rn7A,rL<j9r[7^q!@oVt
678 -iSi#L&Tg-g=uV\ra>e9rZV=erAju6g4A"0gO\,WgOK~>
679 rn@>*rn7A,pt>c'h"TP(g=t96r<`E:#T"6n(Ddo)(G#J9rRq5UrWiGW!8@C@!%7ams![su./bLl
680 K`Hf*g&]m\rnIE]!+GjM!$_A%!SZ4Xg4@t/gAKZT~>
681 rmgturm_#"qUPSr!8$tr!7h)"j43tV!8.5Tr=TAN'G_Du()7Q5r[@`rr;urKrKdL/rZ_@g!@B)j
682 ,6!,nJH"+"ec"(t?2biE*rRqsf$o9$J^o>%r7-;~>
683 q:tYts4[M-s4[M-s4[M-s4ZDc!8@;(#mptF#S[sd'c._d(BP?g)#Z&bg\qEX"od3Ug\mWB-N5Ck
684 .fLdq-N/\qgAot,@/sd8,5sV'3J#q9gO\,UgOK~>
685 q:kSrs4dS-s4dS-s4dS-s4cJc!875&rWrc7'GM2q(E!)e!>lXO/H+<$#6*[email protected]
686 -2iPog&Tn,@K9j8+oXJ%3.]e7g4@uSg40~>
687 q:>/fs475#s475#s46)X!S5fuec=A%#6kAF&ePcl(B,$N&ec!0r[@`r!!<-##M.GUesD\gQi8-3
688 +seK[,pN=3(P.*eJ_&B%f%/C%em2Nc>oan)*AoZ11P+)-eUc9IeUR~>
689 mG%Zps4dS-s4dS-s4dS-hqJ.drn@G,rnIG+!87A*s4dJ*p"TH!p"KK%rS%>+ptGi'g]#oXgO\+1
690 g[X$K~>
691 mFqTps4[M-s4[M-s4[M-hqA(brn7A*qq;&'rn@D,rn@D,p"KB!p"BE#rRq8)pt>c%h#?&Zg4@t/
692 g@<mI~>
693 ldc$ds4./#s4./#hpqbX!8%5$!S,d!fDsP&f`0Y(f`0P&f_O+uec45#ec45#ec45#ec45#eHFLT
694 e^`7Mec45#eHOOSe^W4%rm_,%e^`6%eUc8%eb7OD~>
695 ]%d5<s4d/!!8Q_k!8@&!!8RP-!8@A*!8<"YJ_Pb1ptL<~>
696 ]%R5=gY;VZs4dS-s4dS-rnHSh!86tt!8IJ+!87;(!SQ4Yg4@t/gA0HQ~>
697 jjjC^h:;GS!nGlQqq1r"s4IA&s4IA&!8%"sn'qEfo@3ilrRCntr7(htdt-&#eUc9HeUR~>
698 \_I/<s4d5#!SQ3%gAp%,gAp%&gAp%-gBH<cgtUT=p"KT(gY:G5gO\+1g\9HQ~>
699 \_7&<q:Yi'rn7A,rn7A,pt>`&r7V/*p=]N$rRqG.g=t?8g\'8(gY1B7gY7;5J_G\/q:^?~>
700 jjjC^h:;AQq:G\urn%>(f\"aKec=>"eH"1oeH"2!eHOIQf%&=%p!j5se^`0udt-&#eUc9HeUR~>
701 _:ntFqV1bu!8I;&!8RJ+!8RD)!8@&!s4m;%!8@>)!8N.[J_Pb1ptL<~>
702 _:enDnCdlspt>`&qq;&)rS%;+s4RJ+ptGc&rn@D,p"BE!qq;&)J_G\/J_KnQJ,~>
703 _:8S;ec"(pfDsY)fDs\$fDsV(f`'G%fDX8"e,RqueG.Soe,Intf(IPneGIbreq)A&eUc9GeUR~>
704 ]%[2crVup!rW)Tl!!*!!J_Pb1J_S3!J,~>
705 ]%[)_!!3'!o`>!kptGc&p"KH#J_G\/J_K#8J,~>
706 ^X`;6!8.)IrrE0$!<Mlo!8.8$rRLqsp!s)kJ^o>%J^rZ.J,~>
707 gY;b^jkBmoh:hu,!;$<l!!!&cgAp%.gB66cgYDGU!8N.[J_Pb1o%SZ~>
708 gY2\^jOsXfgA(a@!WE)bg&Tn,g&p*`g=u8R!8E(YJ_G\/o%JT~>
709 ^X`A8!nZ#Uq>^Ksp&Y'k!8.8$nC7Nirm_,%e^`7CeH"0OeUc8%eah7@~>
710 gY;b^jkBmmh:hu,!;QWt!!**%rVup!ptGo)gY:NVgAosmgBQHfgtUQ;gk"42gO\,YgOK~>
711 gY2\^jk9dgg"Q6%q#LQt!<E9#!;P7Mg"P07p"BE!lIlHsg=t?7g=q24J_G\/rn;l~>
712 ^X`A8!nGlSq#L3k!<</t!;tFHeH==Oe^jED!7^;a#1h>Ue^W.#J^o>%J^sbMJ,~>
713 dG+]TpY5T!rn@J-g\_*P!;$9l!<*"MgO\+1gW%uu~>
714 dG"WTpY,N!rn7D+g@t[A!W<"Lg4@t/g;_is~>
715 ][[&4f'*27eq)A&eUc8leUR~>
716 dG+]T!8IJ+r7h,&pY5`%s4d5#[email protected]%X,srS%>-J_Pb1J_T):J,~>
717 dG"WT!8@D)r7_&&p=]T&g=l5Srn7A,o%O&qrRq8+J_G\/J_K#8J,~>
718 cIMmCo%!Wg!nc)Vn^[]lo%!]grRCo!J^o>%J^rZ.J,~>
719 cJ/<Or7h,&s4[P-o\92qrS%>+n_=#rJ_Pb1J_So5J,~>
720 cJ&6Mr7_&&s4RJ+o\0,qrRq8)n_3rpJ_G\/J_Ji3J,~>
721 cIMmCo[NrkqUGYue^j<A!7^PhrR?DKJ^o>%g=:]~>
722 cJ/<Or7h/'s4dS/!8@,#q:Yr+gY:NQg\oiWgO\+1gY1D4~>
723 cJ&6Mr7_)'"Ph_cgY)8RptPi&!8I"srRlbUJ_G\/g=h&~>
724 cIMmCpXKDte^i=$mF;<ie^`7?ec"!KeUc8%e_8Q(~>
725 cJ/<Or7h,&p"TN&rS.5'm+_KmJ_Pb1J_So5J,~>
726 cJ&6Mr7_&&n(RZnm+VEkJ_G\/J_Ji3J,~>
727 cIMmCjOO:Zs4..um+)'aJ^o>%J^rK)J,~>
728 ceAHTptPc$!Sc?$g]-+-g\fdlgAorYgO\+1gXk21~>
729 ce8BRptG]$!SlGugABXkg&TfWg4@t/g=P&/~>
730 cd`$Ho[Nrmma_?ds4..um*u*cJ^o>%J^rB&J,~>
731 `S::[email protected].,'r7h8*m+VNoJ_Pb1J_Sf2J,~>
732 `S14Drn7A,o@j)rm+MHmJ_G\/J_J`0J,~>
733 ][[#5o@<`em*u*cJ^o>%J^rB&J,~>
734 `S:@F!SQ3&g\9P%gAorYgO\+1gVMWp~>
735 `S1:F!SZ;sgATb,gtRD6J_G\/_:jD~>
736 _:8P8ma_9b!S#SLeUc8%e\Tdd~>
737 _;#"Dq:kZ""l%hfgY1A4gO\+1gVMWp~>
738 _:nqDn(J*&gtUQ;gY1B9gO\(0g4@tsg40~>
739 Xjma,eCN1!e(*!tdt-&#eUc8ieUR~>
740 _;#"Dq:kZ"rS.A+J_Pb1J_S#qJ,~>
741 _:nqDn(Rfrs4[M-s4[M-J_G\/J_J)sJ,~>
742 Xk!I#s4..us4..uJ^o>%J^q`iJ,~>
743 \(gZ5rS.A+J_Pb1J_S#qJ,~>
744 WS7C,J_G\/J_IroJ,~>
745 J^o>%J^o>%kLG(~>
746 \(gZ5rS.A+J_Pb1J_S#qJ,~>
747 WS7C,J_G\/J_IroJ,~>
748 J^o>%J^o>%kLG(~>
749 b1cpOn([`qs5*[email protected]_Pb1J_RroJ,~>
750 b1ZjMl.Z0jr7V/*J_G\/J_IlmJ,~>
751 b1-LCime%[J^o>%J^qNcJ,~>
752 b1lsOnCn0'hVR)Fgthtbrn7D-h!a"rgk"42gO\,1gOK~>
753 b1cmMn(Rfr"5;M_f_a>&g=u)MrS)nWJ_G\/f%PW~>
754 b16OCn(%Hh!S,cse,e+Nn(%BfJ^o>%J^r?%J,~>
755 c.`<RgY;__n_4*#hu;L2h#5t+h!j(ug]?6dJ_Pb1J_Sc1J,~>
756 c.W6Pg=lP\nCdltrnI8%rnHqrs4[S0gO\(0g4@u/g40~>
757 c.)mFe^aZMnC7NjrmpnprmpShs4.5&eq)A&eUc9%eUR~>
758 c.`HVgY:N>gt_JT!8[V1rnRG*"5M_fh!s.tgk"42gO\,1gOK~>
759 c.WBTg=k<:gY;8PrS./$"5DVcg[X"rgO\(0g4@u/g40~>
760 c.*$Je^`7&f%0BArRUeo"4l)Tf(%;heq)A&eUc9%eUR~>
761 mG%Zps4dS-s4dS-s4dS-n_4'!rS.;+n_40$h;$c]gAfq,h!s/!g]?6dm+_Qos4[Y0gY:P8gO\+1
762 g[j0M~>
763 mFqTps4[M-s4[M-s4[M-n_*utrS%5)r7_2*pt>i)h;$cagAT_)gA]jsgAfn.gtV2Ls4dS-!8E(Y
764 J_G\/nCiB~>
765 cd`$HrRLktr71hrpsfJte^W(Idf%\qec+.iec42$f@KfKs475#s475#rRQPMJ^o>%l.(:~>
766 mG%Zp!8IJ+"5DP`g]#pugB-*`g\ok%g\ok)h#,q,h!s/!g]H<eh#5t&g\ok)gAp%%g]-"-g],t.
767 gYIG8J_Pb1o@nc~>
768 mFqTp!8@D+"5;MagA]jug&fs]gAT_#g&p$^g=cGZr7_2+rS.#!s4[V1gY;\[q:bf#rRq8+p"KH#
769 s4[M-J_G\/J_KYJJ,~>
770 dFA<Je^aWJq:,SsdaHYDf)4(ueG[khec42%f@JOOeG7YneGdu'f%8I&f%/C%rRQPMJ^o>%l.(:~>
771 mG%6dnD!oqqV1r%rS6YlrS7A*q:bo&rn?krqq?VUJ_Pb1n_8Q~>
772 mFq0dnCmioqV(l#rS.8(qqLbsrS.;(q:Yi$rn6epqqH\UJ_G\/n_/K~>
773 cIMmCqUPMnrRUnsqpY2frRUqsq:,SreC<%<eq)A&eUc9:eUR~>
774 mG%6dnD!oqq:kl%rS6YlrS7A*!ScE,g\ojqg\]]UgO\+1g[X$K~>
775 mFq0dnCmioq:bf#rS.8(qqLbsrS.;(!SZ<*gAT^ogABWUg4@t/g@<mI~>
776 cIMmCq:5GnrRUnsqpY2frRUqs!S,cuec+%ueaV.@eUc8%ea(b9~>
777 mG%6dnD!oqq:kl%rS.G.g?[Mlh#5t&g\ojug]-+0g\]]UgO\+1g[X$K~>
778 mFq0dnCmioq:bf#rS%A,g&B_&g[s4ug\oh$gAT^sgAfk+gABWUg4@t/g@<mI~>
779 cIMmCq:5GnrRM#"eGe"qe+D2hf)=+oec+%ueb%Gmf_sBPeUc8%ea:n;~>
780 mG%6di7e@hgY:NFgAot$gAostg]-+0g\]]UgO\+1g[X$K~>
781 mFq0di7\:fg=k<ZgABXog&Th"g&TgrgAfk+gABWUg4@t/g@<mI~>
782 ^=<>:e^`7KebdhbeH"+meH47NeaqAlf_sBPeUc8%ea:n;~>
783 mG%6di7e7e_;"k@J_Pb1J_T_LJ,~>
784 mFq0di7\1cq:b`#ceA9NJ_G\/J_KYJJ,~>
785 ^=<57q:5AkiRRDJJ^o>%J^s):J,~>
786 mG%6di7e7emFqWpmb7`qlJ)3iJ_Pb1J_T_LJ,~>
787 mFq0di7\1cq:b`#qq;&'mb.ZolIu-iJ_G\/J_KYJJ,~>
788 ^=<57q:5Akqpb\rmaV<er718eJ^o>%J^s):J,~>
789 mG%Zps4dS-s4dS-s4dS-g=uY]rS%>+c.i-LJ_Pb1J_T_LJ,~>
790 mFqTps4[M-s4[M-s4[M-g=lS[rRqV3gY:H9gY:H9gY:?6qqH\UJ_G\/n_/K~>
791 \CLW/rRD8)e'ljte'ljte'mF/s475#s475#s42bOJ^o>%kLG(~>
792 mG%Zps4dS-s4dS-s4dS-f\?A[q:kl%rS%>-h:qh\J_Pb1J_T_LJ,~>
793 mFqTps4[M-s4[M-s4[M-f\6;Y$ej@ig=k<9g=b36g&9V)gYLT\gO\(0g4@uJg40~>
794 [ak?-$e<_Te^`-te^W$qeG[ntf'Cldf)O8#f)F2"eq)A&eUc95eUR~>
795 [bLc9q:kl%J_Pb1J_S&rJ,~>
796 [bC]7r7_/)rn7A*lIu9mpt>`&rn7A,J_G\/J_KABJ,~>
797 [ak?-r71eqrmCerlIGp`psfAnrm_"tJ^o>%J^s#8J,~>
798 [bLc9q:kl%J_Pb1J_S&rJ,~>
799 [bC]7r7_/)rn7A*lIu9mq:bl's4[M-J_G\/J_KABJ,~>
800 [ak?-r71eqrmCerlIGp`q:5Mos4..uJ^o>%J^s#8J,~>
801 [bLc9q:kl%J_Pb1J_S&rJ,~>
802 [bC]7r7_/)rn7A*J_G\/J_IupJ,~>
803 [ak?-"P))Se^aZJ"4GQEe:H/$eUc8feUR~>
804 [bLc9q:bo'J_Pb1J_RroJ,~>
805 [bC]7r7_/)!nuD`J_G\/J_IroJ,~>
806 [ak?-"P))Se^aZJ!n,QHJ^o>%J^qTeJ,~>
807 gY;b^hV8"aq:bo'J_Pb1J_RroJ,~>
808 gY2\^hV.q_ptGc&le;BnJ_G\/J_Jf2J,~>
809 [ak?-q:,Ppe'mX5s3lPLJ^o>%g!tT~>
810 gY;b^hV8"aJ_Pb1J_RWfJ,~>
811 gY2\^hV.q_ptGc&le;BnJ_G\/J_Jf2J,~>
812 [ak?-psoDnldc$aJ^o>%J^rH(J,~>
813 \_@2@gY;\^r7_5*`7k:IJ_Pb1J_U%UJ,~>
814 dG"WTpY,N!qq;,+g=lM[qq;2-g=k<9ceAERs4[M-!SlF\g4@t/gABTS~>
815 dFJ9GpXT/iqpbc!e^aZM!S>p$eHOCMe^`-tj441\n(%Hes4..u!S#SLeUc8%ebdmI~>
816 \D%&<g\hKX`p)7WguR5gh#6"+g4A"0gO\,YgOK~>
817 dG"WTpY,N!qUtu'gAM?V`W+WpgY1B9g[NqrgZ7&kgYCT=gA]h,gA]cVg4@t/gA]fV~>
818 dFJ9GpXT/iqUGVrec#[Z"i8$j^t$uae^`-tnC@NhpXT;pnC7ZmeC<("rmLkqrmZMLJ^o>%rmcN~>
819 [bL`frPn*VrS6MhrS.M0gtUT^g4A"0gO\,YgOK~>
820 `S14DptGZQrPeKas4d8$rS-Gf!8IM."5DVcgAT]Ug4@t/gA]fV~>
821 `RXk7pso?H!!W>;p=92lp=9,mjja@^rmV&!eC2tHe:H/$eUc9MeUR~>
822 [bLcg!"&VDl.c0ljkKahrS.;)J_Pb1J_U1YJ,~>
823 `S14DptG]R!!rPBp=fQ$p=fK"jk9^hrnRM-!8@D)J_G\/J_L+WJ,~>
824 `RXk7pso<G"Mr!n_:JA2s3p\lrRU)\!7q/!rmLktrR?DKJ^o>%rmcN~>
825 b1cpOqV)#(p=fQTrX/[email protected]:bo)p=oQ$jkKahrS.;)q:bo'J_Pb1LYI=~>
826 b1ZjMrS%8*!nuD`pt>]TrX&PBrn7A,q:Yi'p=fK"!nuD`kh69rgt^Z<gY:H\g&Kb+g\fb*fn%k.
827 g5"C4~>
828 b1-LCrRLnr!n,QHq:,Z""pG/8_u@ISf%&=%q:,Jrp=9,m!nGcKmFD6frm_8)eC<("e'lkHeGdtu
829 e,7_re:H/$eVD\*~>
830 b1laIp"TEPrPnik!8@8's4mA'rS7A*rS.A-nCmrsp"T;tJ_Pb1L>.4~>
831 b1cdJrnRM-ptGZQrPeci!872%s4d;%rS%G-g=k6YgAfpsg'?<bgY:H9gY;Y[s4[P/r7ceVJ_Gk4
832 J,~>
833 b16F@rm^qrq:,JrrWN<-_u@LPecF=Nq:5MrpXT5n"4YcIeG[qtf(@Mmf)O8*eCE$se^`-trRLnu
834 !7^qtJ^o>%L=Le~>
835 c.`<RgY;S[p=fW'g\hKX`q\9ig=tB]h"]Y&h#5t*g]$!hg\T]VgO\+5gOK~>
836 c.W6Pg=lJZs4mS-qUtu)gAM?V`VA-gg"P0Zg\BM$g\oh(gA]k$gAfq%gAfq*gA9QTg4@t3g40~>
837 c.)mFe^aTKs4%"rqUPVs!!W?,rPSQarRCu!e^aZMpso>ormUqurRLu#q:>Mps3p_ms3pnrqUU5J
838 J^oJ)J,~>
839 c.`<RgY;Y]!o;YepY,`(g\hKX`q\9mg=tB;h;$f`gB-0bg\oq+gATb.gtgc@jkK^g!o;YeJ_Pb1
840 L>.4~>
841 c.W6Pg=lJZ!o;YernI;'!Sc?,$2qj<g'66ag=tE;g\fb,gY1B[g\oh(g&p*bgY;MWs4d8$!8IG*
842 r7_;.gY7;5J_Gk4J,~>
843 c.)mFe^aTK!nGfMrmU_os4./RrWiD>!8.8$rRD,%e^`7&f%0cL!nPoPrRUtt!7h&!s47;&fDO4u
844 ec4+leH"(rebmu"f@JN(eUc8*eUR~>
845 akQXHp=oNQ"3/="`r4Wlh"oe(h#?%.gATe)h#5t+gAot+h#H+/h"]V(h##h+h"f\*gthk_p"KK%
846 qqD,)J_Pb1RbN>~>
847 akHLDptGZQ"3&3t`VnKjg\TY&g]#n,g&9Y'g\oh)g&Th)g],t-g]#n,g\fb*g\]\)g\KP(gYD\\
848 p"BE#qq;&'J_G\/RbE8~>
849 ajp4<s3peo!S.GR#6_r]_o(.+ecOIRebmu$f@JO)f)F2-f%&=%f@JO)e^W+!rmhJ-f@JO)f%/I(
850 f%&7IeH"1teK<Doe^`7%e^`7&f@JR*f%/I(e^`7%e^`7%e^`7&e^aWL!7ZSMJ^p4>J,~>
851 [bL`frPnfjrL<a5"!f0<,lK+h^AZgbN;Xt!+oO\)aSjomeGTgSAckLm7Rm>)!36$trS.:us$6ZN
852 62`&,-iIBMh#5t-g4A"0gS`eV~>
853 _:nqDptGZQrPe`hrL3[3"!]'9,Q/tf^&?[`Mu=gt+T4P'a8Ocke,9[QAHP@j77I/&!3,srrS%4s
854 s$-TL5lDo*-N.6Kg\oh+fn%k.g8EYT~>
855 _:AS7q:,Ms"o\c*_Z8?gecV5'Q'V@mruVgo+!MjO,.Y4n\^o<]eq]!7L]&7n*!$uurAt"srkeWb
856 rQbEIrs/R4*FN;A5sR^\+sJ8.USFX9e^`6pbKJ*l4$#JF*??4#+oieb=T-hLeH"*MeUc8KeUR~>
857 [bL`frPnfjs-j%XS,F`5,lK+h^AZgbN;Xt!+oO\)aSjomeGTgSB)P3t./g.Dg\oOu62`&,-iIBM
858 gk"42gS3GQ~>
859 [bCZdrPe`hs-`tVRf+T3,Q/tf^&?[`Mu=gt+T4P'a8Ocke,9[QAc5'r-iL"BgATCs5lDo*-N.6K
860 gO\(0g7m;O~>
861 \((N1"o\c*_Z8?gf)M$:Q'V@mr?(t^rOMmXreCK1r?)"Y!$;)%rPJWermq(o!71TKrF,Xjr?M9:
862 rRUqkrB1$"r?;5Er`K-MJ^o>%U=Fb~>
863 [bL`frPnfjrL<g7!@T>o,lK+h^'!-DgY;[cruqXj+sA-R+[>rkrQ#E&h;$f8e^W(W$k!JTral.#
864 r^Qo9!@K;oWVtTNd/_Pl62`&,-NINQ?3&aZgk"42gS3GQ~>
865 [bCZdrPe`hrL3a5!@K5m,Q/tf]`[!Ag=lL`ruhRh+WqpN+?ochrPo?$gtUT4eC2kS$OR8Prac(!
866 r^Hi7!@B2mW;YHLciDDj5lDo*-3.BO>l`UXgO\(0g7m;O~>
867 \((N1"o\c*_Z8?gf):p7+oro4r?(t^rOE$]e^i=NLC&eZ+!)LF*?6+_r]L8#rkncfs4.J$cd'iA
868 #6kE@ra>dnr^$Q/!?rceV#AmDbQ,ib4T-?"+okgG=9-nNeq)A&eY:TE~>
869 [bL`fs2G,\`n^RJrL<g6s!Rajs!Isu-bmC0^&?^aN;b"$,Q/ea5lJe&h#5_&$iUS5B)P3t./g.E
870 gAp%-dJcE466cCR!%@gos'>_5?N&Z1gO\+RgOK~>
871 [bCZds2>&Z`S:CGrL3a4s!I[hs!@ms-GI1,]`$R_MuFk",5iY_5Q/Y$g\oS$$N:G3Ac5'r-iL"C
872 g&Tn+d/H925p?4O!%7ams'5Y3?2`N/g4@tPg40~>
873 \((N1"o\c,_ZIcog&BS$QN&-.,5iV`+pK89]",A]f)F;(M2-kCrZ;7c*ZQ.@rB1/"rke`frmq(o
874 !RCuL#lnK7@JrLj,Q4G;ec=>$bQuKX4?PhM*Zc@#+p1tM=]kXRJ^o>%U=Fb~>
875 [bL`frPnfSr=f@F\[oBNgBc<ZeC;modaPu1_#4oE_ZSZKgY;[<"&2Na9`EcHh#5b$!WB"rg\mTA
876 3rV5>g\m<6:'9;+gYDe_!8RP!J_Pb1T%eb~>
877 [bCZdrPe`Qr=]:D\@K0Kg'H0We'l[kdF,c.^\ncC_?8NHg=lL9"&)E^9E*WFg\oV"!<&kpgARH?
878 3W;)<gAR049`s/(g=uV\!8IItJ_G\/T%\\~>
879 \((N1"o\c*_Z7OP^\nZF[C!?LrRM8#d*L%^c-=PFrk/CE%1NjH^]W6@f%Bq1#>.QX8(Q5@f)Eqp
880 ci!hDVZ*Cif):m72?#N4f)CX7O%W,;9A.nIfDa>%f?4*7J^o>%T%/>~>
881 [bL`frPnfSr=o4ArS.;#rmCeqrP8@ErPSTgrac(ArD!7FrRCcHrMfbM!1NnVrAt#7rnIC7r_<Gf
882 q:c"td*L$hgO\+NgOK~>
883 [bCZdrPe`Qr=f.?rS%5!rm:_orP/:CrPJNeraZ"?rCm1DrR:]FrM]\K!1EhTrAjr5rn@@6!0I1S
884 !)34B"4#6<c@O]#g7I#K~>
885 \((N1"o\c*_Z7OP^\n]A[0>.3e^i'lrm1Vh!7:\Xr=AkBrRh*Y!Fnb$8H%*Acd'h^r;ZhprhTMD
886 !1!PLrAFc0f%/LQNrY=A9*%Z;qUY\hs2fiBJ^p@BJ,~>
887 [bL`frPniT!Q>`O'`PZD]DgOcg=?2PrR1_]!PcGK')ocO`7s)%g\taaAGo7$g\oY#!WB"rg]*`D
888 R[a7;rn@S2P*;&lrD*1C"4,??c[ji%gRd/M~>
889 [bCZdrPecR!Q5WM'E5NB])LCag!p#MrR(Y[!PZ>I&cTWM_qNl!gAYU_A,T+"gATM!!<&kpgAdTB
890 R@=(8rn7M0OckihrD!+A"4#6<c@O]#g7I#K~>
891 \((N1"o\c*_Z[fj^VC?Y&,rs;[atH.$dd2Ecd0k\cb7$)^&8K@^]_L+g"=sV@KBn0r^d"="4,9<
892 ci!hDVZ*Cif)M$:Q'VA,rmh5*O-#E`rC[:Gf%/L+rmq+ls2fiBJ^p@BJ,~>
893 [bL`frPnfS!#,>GrOVs^!7UqsrR1Y[r=](H!8@G,rFPt&!D_AJgAoe'e,o^Q!<N.urn@J/Rf8fV
894 3rqB(rS%F;PEM+-:ANZCc[ji%gRd/M~>
895 dG"WTpY,N!ptGZQrPe`Q!##8ErOMm\!7LkqrR(SYr=T"F!87A*rFGn$!DV8Hg&TY%dfTRN!!)tr
896 rn7D-RJrZT3WV6%rRq@9P*(n*:&3NAc@O]#g7I#K~>
897 dFJ9GpXT/iq:,Ms"o\c*_Z7OP^AncC%fj$:[/SSUf)Eqpci2/hci1TY]++`M!5STJ"4buRf`#=[
898 @/`[t8_*gk"45?=ci!hDVZ*Cjec=>$Pm!C22DmDkecUnlNK*m.q:5PgrlK`AJ^p@BJ,~>
899 [bL`frPneps%W_n:>FXZh#?%1gtUT=r7h1."%l3Z9`!KDh#4nb'`\sHg\oV%$2t;-gAo+i_>YSX
900 +T:'n^&K&U)]W<r@q,D*rR^;grS%5)!8N.[J_RroJ,~>
901 dG"WTpY,N!ptGZQrPe_ns%NYl:#"FVg]#n/gY1B9r7_+,"%c*W9D[?Bg\nb`'EAgFgATJ##lY/+
902 g&Stg_#>GV+8spl]`/oS)B3*n@U]5'rRU5erRq/'!8E(YJ_IlmJ,~>
903 dFJ9GpXT/iq:,Ms"o\c*_Z5PmL]9pL8kIXce^j`M!nZ#Rr71l#reL`477]s@f_a5"g&AM^\,Hp=
904 &,k&^cd'h^"TAW+f_X/$]t:nhrYtnWrRUqWrtbhS(L:<Q?2^#gdf.YYec""reH"0OeUc8ceUR~>
905 [bL`frPequNJrhp:AruBgBlTgMi3OP91qlMq:bn_rk/1ErS.>$!S%MU$MiEY_8=%)r?20prnICb
906 r>bcFrL3c<!S5leg\oiWgO\+jgOK~>
907 `S14DptGZQrP\ksN/NVm:&Wi@g'QHdMMd=L8kMZIq:Yh]rk&+CrS%8"!RqDS$2N9W^qmh%r?)*n
908 rn@=`r>Y]DrL*]:!S,ccgAT]Ug4@thg40~>
909 `RXk7q:,Ms"o\c*_ZPaOLPPh"!8%5$qUPSr$J!dbLl$pY84Q5'qpkf#])K5?')iI@ed'OHcHl\!
910 #6jqSs1ABE]_rfMec+.u\G[6B?2^#jda?Fhl.,a^J^o>%]%)<~>
911 [bL`frPneprD*=H!8@A*!8@A*rJUVIr7_J3gY9BQ]Y#$Z(&lqfh#5_)#mq"Gq:kkar?;-orOr.L
912 raGk;rL*i?f%8O<g\oiWgO\+jgOK~>
913 `S14DptGZQrPe_nrD!7F!87;(!87;(rJLPGr7VD1g=j0M]=SgW'`Qedg\oS'#RLeCq:be_r?2'm
914 rOi(Jra>e9rL!c=e^i=9gAT]Ug4@thg40~>
915 `RXk7q:,Ms"o\c*_Z5PmL]'dEfDa>$eGRhseGRnrM#BjEf_sA+f@JTb\@K-`rXf([#hRDJcHcUu
916 #6akR"2)7X]_riKf)<,W(]I\??N$,kda6Chl.,a^J^o>%]%)<~>
917 [bL`frPequNJrhp:AruIgAot'g]*04MMqF+q:kk\!u2Rd(&cnceG]dW$/=4gr7h1d!$_CcrS%=d
918 rk/:NrZ(lGrL3`;!8.,%!8R/"rRuhWJ_RcjJ,~>
919 `S14DptGZQrP\ksN/NVm:&WiGg&Th%gAd$2M2M7(q:beZ!u)Ia'`Hbae,BXU#hn"cr7_+b!$V=a
920 rRq7brk&4LrYtfErL*Z9!8%&#!8I(urRlbUJ_I]hJ,~>
921 `RXk7q:,Ms"o\c*_ZPaOLPPh"!8%5$rRCu#e^aTKs+UQ.M#BjEf_a5"f_r>_&ePZdrRM(scHac8
922 "U,%[f%&@&rmh"[!PBHP*<"Fg\c0)=(B,-K?2^#jda?Ijq:,Jro%!]gJ^o>%]%)<~>
923 [bL`frPehqrf$eNqV),+gY:H[g\m'/9`<]Gh#?(,]_rQIgtg`?rRCcUq:kkcr?)$n!8RP-rQPS3
924 Q'@M/:/=[a2#uG.g]-(#gAorYgO\+ggOK~>
925 `S14DptGZQrP\borep_LqUu&)g=k6XgAQp-9E!QEg]#q*]DWEGgYCN;rR:]Sq:bear>tsl!8IJ+
926 rQGM1P`q;+9hnI^1]Z;,gAfq!g&TfWg4@teg40~>
927 `RXk7q:,Ms"o\c*_Z5MlL]'dEf)!nuf%&:KecaNWL5(N_8H@EBecXOTf%Br3!##8B#M7VZf?_af
928 ci"1Jf)F5!]`>eF)ZJ:ffDX;!a9[igO,ln)8kLf:0*'T"ec44leH"*MeUc8[eUR~>
929 [bL`frPneprD)n;rJUVJq:kn]!58@H!#5Ce"4YlNebp!TgB$$_rPJ^Z+<DX#g\oA!P`q;qrD3GN
930 !Al\3gB-*`g]$"#gAorYgO\+ggOK~>
931 `S14DptGZQrPe_nrCuh9rJLPHq:bh[!5/:F!#,=c"4PcKeGTjRg&]m\rPAXX*uuEugAT4tPEM)m
932 rD*AL!AcS1g&fs]gA]k!g&TfWg4@teg40~>
933 `RXk7rRLkt!8.8U!<p==_Z5PmL]'gBf)+"qf)CC(M#BmFf_a5"f`&Da\e5Pc&,k,[cN2><r<`DQ
934 !nGfNrk/HK)B0P4q:>Mc"-8J&O8VZQ0J>%3r7(kue^aZMo[NrkJ^o>%\(-!~>
935 [bL`frPneps%`Yj:\!0>MZ/P49_mHC]E,^Yr>#:drRCcUq:knd!6"gXs4[P/r7_=ubg"E2Pl4DV
936 2>l25g=tB;h;$e:gO\+ZgOK~>
937 `S14DptGZQrPe_ns%WSh:@[$<M>iD29DR<A])fRVr=o4brR:]Sq:bhb!5naVs4RJ-r7V7sbKS3/
938 PPn8T2#Q&3g"P07gtUS7g4@tXg40~>
939 `RXk7rRLkt!8.8U!<p==_Z5PmL]9sI8P8p3qpkVq",2JaM#BmFf_a5'fX\Q(\J"lQrRV.tcHac7
940 $2iBRec*5^^\o)Nec=>"ecX"6aN4=@rCR&Dr\+3"#1V2Rf%8L(J^o>%WmuV~>
941 [bClk$OR7>`r1kq:&n#ZgAp%-MuHBM9DR?@]`/]I'G^T%rRCcUq:kkcr?(jirQY;*"&;Wf:Am'G
942 g\ooYgO\+ZgOK~>
943 _:nqDpt>fV$4.%;`Vk_o9`RlXg&Tn+MZ-6K9)73>]DiQG',:E"rR:]SqUtu)_u@OO*r4Ogbl*_-
944 9hnGXrA=?(rS)nWJ_I-XJ,~>
945 _:AS7rRLkt"P<qb#7(4F!/^]1r^d)\r7:bqrRM,'L5:Y?r^QrXqUPZ!rOE"C&.]?Nf)s@EcHlFq
946 r7:nu"Ojur]tXF`q:>McrJq(Q8kMZ/r\+)trRQPMJ^pdNJ,~>
947 ^>&V?rS.8XrPnfSr>,@GrS.;%rR1Y[r=o4NrS%3as%NMf:&`lMg==a'ebp!Rg\o%g*WXpngAo4l
948 `;S3bgAot+c2@tIg4A"0gS3GQ~>
949 _:nqD!8@D)rS%2VrPe`Qr>#:ErS%5#rR(SYr=f.LrRq-_s%EGd9`E`Kg!nO#eGTjQg&]sGrkeUS
950 !87A*!6"lSrR:c"!87=pr<WATJ_G\/U=t+~>
951 _:AS7!7h(u!7h)"!8.5TrPJWOrkJCDrODpZrmh"p!7Cbi"1u7[]DW9=_Z&'cfDT:`8k;HCrmh5&
952 d*L"ar<`DQs4%8$]=knlr>>Ucrmh(brkJEXrmh)"rQ"sArWE,KJ^o>%U=Fb~>
953 ^>&V?rS.8XrPnfSrtYVO(B(uGg\o_%df$u['`Q,UaP,A$gAPaa9`s,(gYDbXr=8YXrPSRTrS.:h
954 rRCl%!SlH.c2@tIg4A"0gS3GQ~>
955 ^=rP=rS%2VrPe`QrtPPM(&biEgATS#dJ^iY'E5uSa4].ug&5U_9EWu%g=uSUr=/VW!SbNk_YkMR
956 gASqfe,S,&gY2VMr<WATJ_G\/U=t+~>
957 ^=E54!7h)"!8.5TrPJWOrkJIF!>6"C\c(+XdJ_>g]DW9>_?@d,e^W4LAcPI&8-d\rf%89pcd;Us
958 r7:nu"Ojur]tXF_rRUq^!71Yls4@D+fZO37!!N9'rR?DKJ^pLFJ,~>
959 ^>&V?rS.8Xrl,)]`5KX5rY>JMrP&6b"4l)Tf)F(te,@&^'E/^Ea8O`lB`Vm]rCm:GrnID%r=8YX
960 rPSRTrS.:hrRCf#rQY<J!!rPWJ_Pb1U>(1~>
961 ^=rP=rS%2Vrl##[_o'F1rY5DKrOr0`"4buQec*qrdf$o\')iRC`r4TjBE;aZrCd4Ern@>#r=/VW
962 !SbNk_YkMRgASqfe,A#!bl.kJ#Q<>,g4@tPg40~>
963 ^=E54!7h)"!8.5TrkelW_8!e#rXf,CrOMmX"4>QEdJhAjcMb?T%fR";_Z&'hf4JW+AkN%n!7h)"
964 "45B?d/=:Kf)O8'e%<<,^ASrJf)<>`ci2>jfDs(na9)PI!s8GNJ^o>%U=Fb~>
965 ^>&V?rS.8XrPf)\_o0J.()@Y`^AZgbecX@LdaS01r=o7O!6G,m")2F_C&Ld)g\o\$%KP;\g\o%g
966 *ramogAStie,e+LrS.:qr<`GVJ_Pb1U>(1~>
967 ^=rP=rS%2VrP]#Z_Sa8*'bqG]^&?[`eH=4IdF/!.r=f1M!6>&k"))=\B`1X'gATP"%05/ZgASne
968 *WFamg&8hgdfItIrS%4or<WATJ_G\/U=t+~>
969 ^=E54!7h)"!8.5TrPJlV^;%Do&J5TQ\c1.\f[KiI"3o-9cMbBR&,sEG_u8*fA7K.\rC?q>rmh"o
970 !7:ZN!8%2#rmh"]!5ACLrmh)"rP/BY!RT0kf)<Yi"TAN%e:H/$eY:TE~>
971 `[email protected]:kiSrPerog=tB\Rf+T9-mpDkr@Io]rS.:0r?V=fs$$NJ5Q/\%g\oY#%JecX_Z7XR
972 +91'rg=uRrr?hIlr?hT#reBstrS%5*!8<"YJ_RZgJ,~>
973 `nLCGrn7A,q:bcQrP\lmg"P0YRJeH7-RL2gr@@i[rS%4.r?M7ds#pHH55iP#gATM!%/JWV_>qLP
974 *rjppg"QCor?_Cjr?_N!re9mrrRq/(!82qWJ_ITeJ,~>
975 `mt%=rm_#"rmgtu!8.5SrPJ`ie^i=MQ2Mm0,9e?Y.K1^n\c(+XL]&=n+TFJ'3BI,V!7q/"rltMi
976 r<W>Prmh"]!5JINs4.5$f):s6+oN\b+om5oJFV1geG[que:H/$e[O(Z~>
977 `nUOK!SuQ(g\hHY`W=&urS%IDR@9Qkr[7[n!%IjtrP&6brJ^_$r$D;+!6>)[rS.;#r=/SWrPSRU
978 rS.:@""#BB-N,Cl-iJeigB60_g=lM\!8<"YJ_RZgJ,~>
979 `nLII!SlH&gAM<W`<!orrRqCBR$j?gr[.Ul!%@drrOr0`rJUY"r$;5)!65#YrS%5!r=&MUrPJLS
980 rS%4>"!o9?-2f7j-N/Ygg&p$\g"H>Y!82qWJ_ITeJ,~>
981 `mt+?!S>p!ec45"f_l$S_ZI]mf`'G)Q'@Q#,Q8tf,lf:j.0.!Z\c(+XL]/Cn+T4>$_Z%FQf)F5!
982 c2c2h#lN9Qec*5^^ASuKf):p;+X/'Qr?V=c!.k-"n^R`ke'unGec=3NeUc8[eUR~>
983 `nUIIp"TEOrPnfj".GXHRf+T9-mpDkr@Io]s4mY/rJ^\#r?_D,#KOp,akPP(g\oY#%JecW_u1\V
984 gB$#trg`p6r@.[mre:E,n_=#rrS.D,J_Pb1\(cE~>
985 `nLCGp"K?MrPe`h".>OERJeH7-RL2gr@@i[s4dS-rJUV!r?V>*#KFg)aP,>$gATM!%/JWU_YkPT
986 g&]lqrgWj4r@%Ukre1?*n_3rprS%>*J_G\/\(Z?~>
987 `mt%=qUPSrs4I8SrPSTb"-o+9Qi/03,pXc_r@%`Yrji'\s47.(r?(t\rAk2#_o'FDeCE+Kc2c2h
988 #lN9Qec*5^^ASuLecF<erg3R,r?V=c"+buQJ+;(feG[que:H/$e[O(Z~>
989 `nUIIp"THP!!rPCrS.@@!LoPV-iGIl/H*<]g\m*0,lK%f56K!KaN4>7rRCcT!8@G,!8@G,rkelW
990 +!2OFrS.@B!hGi-r[%^q.OchG-NGLlL@O"#g=b37rS2tYJ_RWfJ,~>
991 `nLCGp"KBN!!iJArS%:>!LfGT-N,=j/,d0[gAQs.,Q/nd4p/jHa2e/4rR:]R!87A*!87A*rk\fU
992 *Zc=BrS%:@!h>`*rZqXo.4?VD-3,@jL%3k!g">!3rS)nWJ_IQdJ,~>
993 `mt%=pXT;prWE6*_u@LPed9mXQ'IZ%,U+EXr?_Ck!5&6@rRMX;L5(I**ZcCG+!2Ud3B9.<_ns:h
994 ec!em#65&.eH"+uec*5j^)7e*):m?gesD\hQi8*5+X86W,U+BT+T6i\eH==MeCFNKJ^o>%[afm~>
995 YhK03o\9E"!Sc?+gAp%)gAp%(g\opkgB-*`g\oq&g]-((gAorYgO\+KgOK~>
996 YhB*1o\0>u!SZ6)g&Tn'g&Tn&gATdig&fs]gATe$gAfq&g&TfWg4@tIg40~>
997 \(1H.s4@M+e^i=%ec")!f`0M*f[na-fDO8$fD=%uec+/"ec45#eHOOUf%/I(o@<llq:,Pre^aZM
998 #M7PWe^i=%ebdqtec45"eH"*MeUc8?eUR~>
999 [+b`=gY:N;q:bo)rS.;)o@j9!ptPc&jkKahJ_Pb1L>.4~>
1000 [+YZ;g=k<7q:Yi'rRqA,f\"mKg&Th$gATdfgATcWg4@t4g40~>
1001 \(1K/"P;;Yf@B]J!87>'#hRb_f@\[*f\$#N!S,]pec"(\ec+,#f@GN'J^oP+J,~>
1002 ZeGK8qqD,)rS%>-rS.;)r7_5,rS%M0gY:N<h"oe'h"08#gABV)h##k)h#H+/h!s,&g=tE;gY@A7
1003 J_QgOJ,~>
1004 Ze>E6qq;&'rRq8+rRqA,f\"mTg&Tn+g'-0`g=t?9qV(l%o@a2tqq;&)qqD#'s4RJ-n_+0"g=t?8
1005 gO\(0g7R)L~>
1006 \(1H.!878#!7h&!!87>'$.mk`f@\a,f\"gSec=8"ecF=PqUPMpo@3ijqpb\tqpk\s"4u,Sf(%8o
1007 eCE.#e^f<%J^pCCJ,~>
1008 [bCf9rS.A+s4dS-s4\.>g"Y98g=t?7g"P37g=tB9g@Eu!g=uS]r7_5,q:bo'ptGf&rnID,mG%Zr
1009 pY,]%J_Pb1VqZ_~>
1010 [b:`7rS%;)qUtr&rRqD-f\+s1le2BmgATe(g&Tn(g&Tn,gAfq*g&Th*gATdngAfq%g&TfWg4@tU
1011 g40~>
1012 [abZ5e^`7%e^W1$r7D>-f%/L+g=b*0g%sA$f(@JneCFNKr7(euqUGbudacmse,7_reGe"sf'V#f
1013 f([\pe:H/$eYgrJ~>
1014 cJ/<QrS.;)mFr'N!!!$$!!!$#!!!$#!<*$!!<3*"!!*,UqV1u(q:ki&"P__egYDY[!8@/$!SlDe
1015 g\oiWgO\+ZgOK~>
1016 cJ&6OrS%5'mFqL=!!2ip!!2ip!8IA(rS./%r7_A.gY:H:rn@D,rn7A,pY#Z&g#1T_fn%k.g8`kW~>
1017 cIMmErRLkro%!cks4%,#kl:_8qUPPqq:5Do"P))Se^j`Ms3q"u!RfHkeH+7Ni77eUJ^o>%WmuV~>
1018 cJ/BS!SuQ0g\ojngAh9K!!!&n!!<8Vg=lJZrS75'q:to&!8Qbl!8@5&"5MYch"ob,gtUT^g4A"0
1019 gT'"Y~>
1020 cJ&<Q!SlH.gAT^sgAfq*g@bLH!VHEog=tB[gATe%gA0M$g&Tq+g[*Vog%a8'gY1B9qUu#*g=lMY
1021 J_G\/WnMt~>
1022 cIMsG!S>p$ec""iec4+seH"1o!!!&m!!(UHec"(pebReoeH"+se*PTbeG.Prf%&=%qUGYue^aWJ
1023 J^o>%WmuV~>
1024 cJ/<QrS.A+!Sc>qgAh9?!!<;Wg=lJZrS75'!SlH,h"f\)g@3hsh"08#g@j8&gtUT^g4A"0gT'"Y~>
1025 cJ&6OrS%;)!SZ6!gAfq*g?JY?!SZ;_r7_,(q:Yl(gABY&gA]h.g=tBQg&Tn!g&Th"g&g$_gAT]U
1026 g4@tXg40~>
1027 cIMmErRLqt!S,]lec4+seH"1b!!(UHec"(peH+7Oqpt\qrmLqse'mm<!7pbl!7^_m!nPoPrR?DK
1028 J^pdNJ,~>
1029 cJ/<Q!8I>'n(Rp"!<E*"rrE'"rrE'"rrE'"rrE'"rr<$"q:kl'!ScE,g\BRGg\oiWgO\+[gOK~>
1030 cJ&6O!8@8%p"K>u"PVN/!<MWhrrE*"q:bf%!SZ<*gA'G$gAfq-gAfpVgAT]Ug4@tYg40~>
1031 cIMmE!7gnpp!ruh!S,cc!!(UHec"&"e^jWJpt#Dos3q"us3oHIrR?DKJ^pgOJ,~>
1032 ceAHRrS%>+kM$g/gY:H:gY1B9gY1B9gY1B9gY1B9gY1BRgB66egt[J8J_Pb1inJt~>
1033 ce8BPrRq8)mFqHlrn7M0g=k<9o@j6!o\'E%gtUTQgAfq-gAfoYg4@t/gA0HQ~>
1034 cd`$FrRCntmFD*_!7gqso[j;te^`7%p=08rf@JOBec4+uec4*LeUc8%ebRaG~>
1035 dG"ZVr7_5,khH-ngtVe_J_Pb1J_T2=J,~>
1036 dFnTTr7V/*m+VEmg=lM[m+VKoJ_G\/J_KqRJ,~>
1037 dFA6Jr7(eum+)!^q:5)fo%!]im+)-bJ^o>%J^sSHJ,~>
1038 Z.f<9h<Werg>)Y]!8RD)rS5'?!8N.[J_R-XJ,~>
1039 [G(Q5rn@D,n(Ifqg\oh+g\KS%g[*YogXFjVgO\(0g8N_U~>
1040 [FP6)"k;#Oe^N"Geaq>meCOTK!7ptrrRU>cs3oHI!7l_OJ^p^LJ,~>
1041 WnRO/lIu<mqV1u(J_Pb1J_T2=J,~>
1042 [G(N4r7_/)m+MHmqV(o&J_G\/J_K,;J,~>
1043 [FP6)!R]BoeH4=Ne,@hsf)O;#f(RVoeG@_of&"sWeq)A&eVD\*~>
1044 cJ/<QUtbn&J_Pb1J_U1YJ,~>
1045 cJ&6Om+V?kqqD))a4gOGJ_G\/J_L+WJ,~>
1046 cIMmEm+)'`!R]Bnec4+sec45#ec44Jec+(pec43OeUc8+eUR~>
1047 cJ/<QV;(t&J_Pb1J_U1YJ,~>
1048 cJ&6Om+V?kkM#sjgtM_[J_G\/J_L+WJ,~>
1049 cIMmEm+)!^kLKU]gsuAQqUPVsJ^o>%LXgn~>
1050 cJ/<[email protected]"g=tB9hV8"_J_Pb1J_U1YJ,~>
1051 cJ&6Om+V?k!SZ6+g&Tmqg'$0agY1?;gAT]Ug4@t/gA]fV~>
1052 cIMmEm+)!^!S,^!eH"1geHFIOe()t)ec""oec43OeUc8+eUR~>
1053 cJ/<QW8%.%inFIgJ_Pb1TA+k~>
1054 cJ&6OW7q(#in=CeJ_G\/TA"e~>
1055 cIMmEW7C^nime%[J^o>%T@JG~>
1056 ceAHRrS%>+K%p7ZrS%>+J_Pb1VqZ_~>
1057 ce8BPrRq8)K%g1XrRq8)J_G\/VqQY~>
1058 cd`$FrRCntK%9hNrRCntJ^o>%Vq$:~>
1059 dG"ZVr7_5,J_U.YJ_Pb1U>(1~>
1060 dFnTTr7V/*J_L(WJ_G\/U=t+~>
1061 dFA6Jr7(euJ^s_MJ^o>%U=Fb~>
1062 J_S?%rS2tYJ_QpRJ,~>
1063 J_J9#rS)nWJ_HjPJ,~>
1064 J^qonrRQPMJ^pLFJ,~>
1065 WnRO/o%O0"lIu<mr7_5,kh?*mlJ)9mJ_Pb1U>(1~>
1066 WnII-o%F)ulIl6kr7V/*kh6$klIu3kJ_G\/U=t+~>
1067 Wmq+#o$m`klI>mar7(eukg][alIGjaJ^o>%U=Fb~>
1068 cJ/<QiS4Cfo@s<#leDBlrS.A+leDHple;Epmb@]qJ_Pb1[bH<~>
1069 cJ&6OiS+=do@j6!le;<jrS%;)le;Bnle2?nmb7WoJ_G\/[b?6~>
1070 cIMmEiRRtZo@<llldbs`rRLqtldc$dldZ!dma_9eJ^o>%[afm~>
1071 cJ/<QjP'aigY;__pY,c'gY;__n(Rp!gY;Y[rnIG+n(RotgY;__m+VNqmb@cs!SuO^gO\+fgOK~>
1072 cJ&6OjOs[gg=lP\pY#]%g=lP\n(Iitg=lJXrn@A)n(Iirg=lP\m+MHomb7]q!SlF\g4@tdg40~>
1073 cIMmEjOF=]e^aZMpXK>pe^aZMn'qKje^aTIrmh"tn'qKhe^aZMm*u*ema_?g!S>nReUc8ZeUR~>
1074 cJ/<QjP'mmgY:N>gt_\Z#27hdgtgc@nCn$"gY;\\rS%G.g"P0LgBQBdgYCW?h!Nhrh!Wqqgk"42
1075 gU>je~>
1076 cJ&6OjOsgkg=k<:gY;MW#2._agYCQ<nCdrug=lMYrRqA,f\+sIg'66ag=tE;g[3\pg[<eogO\(0
1077 g:#^c~>
1078 cIMmEjOFIae^`7&f%0WH#1V2Rf%8L(nC7Tke^aWJrRD#"e'un:eHXORe^i@'f'Uuff'_)eeq)A&
1079 e[F"Y~>
1080 dG+KPiS4=dp"TH#mG%<fmG%Tph:qb\J_Pb1\(cE~>
1081 dG"ENiS+7bp"KB!mFq6dmFqNnh:h\ZJ_G\/\(Z?~>
1082 dFJ'DiRRnXp!s#lmFCmZmFD0dh:;>PJ^o>%\(-!~>
1083 J_Pb1J_Pb1kM(L~>
1084 J_G\/J_G\/kLtF~>
1085 J^o>%J^o>%kLG(~>
1086 J_Pb1J_Pb1kM(L~>
1087 J_G\/J_G\/kLtF~>
1088 J^o>%J^o>%kLG(~>
1089 WS7F,o%O/uinFIglIu<mJ_Pb1LtdF~>
1090 WS.@*o%F)sin=CelIl6kJ_G\/Lt[@~>
1091 WRV!uo$m`iime%[lI>maJ^o>%Lt."~>
1092 o%O0"J_Pb1J_Pb1pY12~>
1093 o%F)uJ_G\/J_G\/pY(,~>
1094 o$m`kJ^o>%J^o>%pXOc~>
1095 o%X3"J_Pb1J_Pb1ptL<~>
1096 o%O,uJ_G\/J_G\/ptC5~>
1097 o%!ckJ^o>%J^o>%psjl~>
1098 p"KQ%gY;__J_Pb1J_Pb1q:gE~>
1099 p"BK#g=lP\J_G\/J_G\/q:^?~>
1100 p!j,ne^aZMJ^o>%J^o>%q:0u~>
1101 p"K])gY:N>gt[J8J_Pb1J_U%UJ,~>
1102 p"BW'g=k<:gY7;5J_G\/J_KtSJ,~>
1103 p!j8re^`7&f%,E&J^o>%J^sVIJ,~>
1104 s4dS0s4dS0s4`%ZhV6f@hV?oCh:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?
1105 h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?
1106 h:p]?h:p]?h:p]?h:p]?h:p]ah>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70
1107 h>c70h>c70h>c70h>c70h>c70h>c70h>c40h>Q(ih:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?
1108 h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?rS'EigY:Q?gY:Q?gY:Q?gY:Q?gY:Q?gY:Q?
1109 gY:Q?gY:Q?gY:Q?gY:Q?gY:Q?gY:Q?gY:Q?gY:Q?gY:Q_gH46GgYL]?gYL]?gYL]?gYL]?gYL]?
1110 gYL]?gYL]?gYL]?gYL]?gYL]?gYL]?gYL]?gYL]?gYL]?gYMh_45JZGh;-i?h;-i?h;-i?h;-i?
1111 h;-i?h;-i?h;-i?h;-i?h;-i?h;-i?h;-i?h;-i?h;-i?h;-i?h>Q(hh:p]?h:p]?h:p]?h:p]?
1112 h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]]h>c70h>c5[~>
1113 s4dS-s4dS-s4[P-rnDqVgYCT=g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9
1114 g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9
1115 g=tB9g=tB9g=tB9g=tB9g=tB9g=tB^gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1116 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1117 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1118 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1119 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1120 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1121 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq)gAfq-gAfoX~>
1122 qpYSqs3h/%f$i*uf)F1ue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1123 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1124 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1125 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1126 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1127 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1128 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1129 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1130 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtudsq~>
1131 s4dS0s4dS0s4dS0s4dS0s4`%ZgtUT>h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?
1132 h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?
1133 h:p]?h:p]?h:p]?h:p]?h:p]?h:p]?h:p]ah>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70
1134 h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70
1135 h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70
1136 h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70
1137 h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70
1138 h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70
1139 h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c70h>c7,h>c70h>c5[~>
1140 s4dS-s4dS-s4dS-s4dS-s4`%Wg"Y98g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9
1141 g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9
1142 g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB^gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1143 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1144 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1145 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1146 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1147 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1148 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq)gAfq-gAfoX~>
1149 qpYSqs3q"us3q"urmMh7e'ljte'ljte'ljte'ljte'ljte'ljte'lkHe,Rtue,Rtudf@qte,Rtu
1150 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtudf@qte,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1151 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1152 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1153 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1154 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1155 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1156 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtu
1157 e,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtue,Rtudsq~>
1158 J_e/us4dG,s4d/$s4c;as4dG,s4d/$s4c;as4dG,s4d/$s4c;as4dG,s4d/$s4c;as4dG,s4d/$
1159 s4c;as4dG,s4d)"J,~>
1160 J_Iros4dG)s4d/!s4c;^s4dG)s4d/!s4c;^s4dG)s4d/!s4c;^s4dG)s4d/!s4c;^s4dG)s4d/!
1161 s4c;^s4dG)s4d(tJ,~>
1162 d*i!Bp<s#hhU;JPJ^]2!J^_`iJ,~>
1163 J_e/us4dG,s4d/$s4c;as4dG,s4d/$s4c;as4dG,s4d/$s4c;as4dG,s4d/$s4c;as4dG,s4d/$
1164 s4c;as4dG,s4d)"J,~>
1165 J_Iros4dG)s4d/!s4c;^s4dG)s4d/!s4c;^s4dG)s4d/!s4c;^s4dG)s4d/!s4c;^s4dG)s4d/!
1166 s4c;^s4dG)s4d(tJ,~>
1167 dF8-Cp<s#hhU;JPJ^]2!J^_`iJ,~>
1168 qV;/.J_bn5J_bn5n(iK~>
1169 qUtr(J_G\/J_G\/n(N9~>
1170 qU5GoqpYSqo@*`is3q"us3q"qq:#Ak#h.>Qe(*!te(+HHs4..us4..us4..us4..us4..us4..u
1171 s4..us4..u!7h(ts4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..u
1172 s4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..u
1173 s4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..u
1174 s4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..u
1175 s4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..u
1176 s4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..u
1177 s4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..us4..u
1178 s4..us4..us4..us4..us4..us4..us4..us4..uJ,~>
1179 qORSVrLNnWJXq@_JXq@_qON-~>
1180 qO7APrL3\QJXV.YJXV.YqO2p~>
1181 qNLlBrf[AJPl?j>PQ-pJPQ$j>PQ-pJPP^XFPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJ
1182 PQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJ
1183 PQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJ
1184 PQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJ
1185 PQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJ
1186 PQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJ
1187 PQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJ
1188 PQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJ
1189 PQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPQ-pJPCN~>
1190 qORSVrLNnWJXsrSs-poss-poss-poss-poss-poss-rVNJ,~>
1191 qO7APrL3\QnsTQHJXV.YJXVIbJ,~>
1192 rK[AGrfdDKrK[>G!1!GFq3:rGrK[AGr0@8FJX(eOJX)XgJ,~>
1193 rLF"[SXo_NrLNnWJXsrSs-poss-poss-poss-poss-poss-rVNJ,~>
1194 rL*eUR[X2ErL3\Qns]THm@+'CJXV.YJXW:$J,~>
1195 rKRGIPEZ!1!1*SKrKI;Iqigi@s-EVKs-*>Fs-*>Fs-A5$JX(eOTp:-~>
1196 !1`qUrLEhUrL2l<!1\V0ig]t=_jg[s_jg[s_jg[s_jg[s_jg[spR?[~>
1197 !1WtVs-j.[S"-"<rL3\Q#+D$NR[T_8opYiKrL*hXR[]dtRcU"<RDYKnRDYKnRDYKnRDYKnRDYKn
1198 RJ3/#~>
1199 !1*VLs-!SNQB[W"rfmMMQ2[!PQ'7DsQ'7F1Q2d0MQ2d0MQ2QpFPlm>;PEYs1qj.8Is-E\Ms-EPI
1200 s-E\Ms-E\Ms-E\Ms-E\MpQkiEs-E\Ms-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPI
1201 s-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPI
1202 s-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPI
1203 s-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPI
1204 s-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPI
1205 s-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIs-E\Ms-E\Ms-EPIJ,~>
1206 JcC<$JcC<$kPp&~>
1207 rr<#t"onT$s8N#os8N!$s8N#trr2Kg!<2rss8E'!rdk+6s8N#trVlf<s8N#trVlf<s8N#trVlf<
1208 s8N#trVlf<s8N#trVlf<s8MutrVc`ls*t~>
1209 rqcZj"o%igp\FXaqZ$HmqYp9op\FXZq>($ds82ims82fl"8MWbq>L0iq#U6crqcNhs8)cms8)cm
1210 qtg?is8)cms8)cms8)cms8)Hd%f6)"qYL*dqYL*dqYL*dqtg?is8)cms8)cmqtg?is8)cms8)cm
1211 qtg?is8)cms8)cmqtg?is8)cms8)cmqtg?is8)cms8)cmqt^WrqYBs`qYBs`qtp6iqu?Nmqu?Nm
1212 qtp6iqu?Nmqu?Nmqtp6iqu?Nmqu?Nmqtp3rqtg-aqYL$`qYU0ds82ims82ims82]is82ims82im
1213 s82]is82ims82ims82]i$2aSpq>0s`q>1!cqZ$HmqZ$HmqZ$HiqZ$HmqZ$HmqZ$HiqZ$HmqZ$Hm
1214 qZ$Hiq?d&qq>'m`q>'maqtg?is8)cms8)cmqtg?is8)cms8)cmqtg?is8)cms8)cmqt^WrqYBs`
1215 qYBs`qtp6iqu?Nmqu?Nmqtp6iqu?Nmqu?Nmqtp6iqu?Nmqu?Nmqtp3rqtg-aqYL$`qYU0dJ,~>
1216 rr;fnqZ$?ip&G!irVuiqJcC<$JcDMFs8MlpJ,~>
1217 JcE1Yq>SM9q>SM9q>SM9q>SM9q>SM9qu6BjJ,~>
1218 rqlQf!;cQh!;cQf!;cBcrqQQjrVQTi!;bFHq#-WXq>/51q>/51q>/51q>/51q>/51q>0sbJ,~>
1219 rr;fnq>^9ip&G!irVuiqJcC<$JcDPGrr2coJ,~>
1220 JcE1Yq>SM9q>SM9q>SM9q>SM9q>SM9r;QHjJ,~>
1221 rqc]lqtU9hrVHBkqYU'hqYg-b"8_ihqYg9nqYBs`gACXCReupWanto1anto1anto1anto1anto1
1222 qYPd~>
1223 rVu`nq#C3ip&G!ir;ZfrJcC<$JcD/<J,~>
1224 rr2uto)A^hk5PP_s8W(Ls69RZrlP39rlP39rlP39rlP39rlP39rqcYF~>
1225 rqc]lqtU6gq>10gqtU6gp%njfq>'mcqZH]jq>/hBs8Dutqu)u\q>/51q>/51q>/51q>/51q>/51
1226 q>0sbJ,~>
1227 s4[M-pY,Z%s4[M-pY,Z%s4[M-rn7J-g=k6ZgAfq-gAfq%gAfq-gAfq%gAfq-gAfq%gAfq-gAfq%
1228 gAfq-gAfq%gAfq-gAfq%gAfq-gAfq%gAfq-gAfq%gAfq-gAfq-gAfq-gAfq-gAfq%g@s@rgAfq-
1229 gAfq%gAfq-gAfq-gAfq-gAfq-gAfq%g@s@rgAfq-gAfq%gAfq-gAfq-gAfq-gAfq-gAfq%g@s@r
1230 gAfq-gAfq%gAfq-gAfq-gAfq-gAfq-gAfq%g@s@rgAfq-gAfq%gAfq-gAfq-gAfq-gAfq-gAfq%
1231 g@s@rgAfq-gAfq%gAfq-gAfq-gAfq-gAfq-gAfq%g@sA%gAfq-g40~>
1232 s4dS-pY5`%s4dS-pY5`%s4dS-rn@P/gY:H]g]-"-g]-"%g]-"-g]-"%g]-"-g]-")g\9Frg]-"-
1233 g]-"%g]-"-g]-"%g]-"-g]-"%g]-"-g]-"%g]-"-g]-"-g]-"-g]-"-g]-"%g\9Frg]-"-g]-"%
1234 g]-"-g]-"-g]-"-g]-"-g]-"%g\9Frg]-"-g]-"%g]-"-g]-"-g]-"-g]-"-g]-"%g\9Frg]-"-
1235 g]-"%g]-"-g]-"-g]-"-g]-"-g]-"%g\9Frg]-"-g]-"%g]-"-g]-"-g]-"-g]-"-g]-"%g\9Fr
1236 g]-"-g]-"%g]-"-g]-"-g]-"-g]-"-g]-"%g\9G%g]-"-gOK~>
1237 rRUkrpX]5lo[`ukr7:nug"-2Us4[A&J_#D'J_&#qJ,~>
1238 rS.;)!nl;]ptPc$!nl;]ptPc$!nl;]ptPc$!nl;]ptPc$!nl;]ptPc$!nl;]ptPc$!nl;]ptPc$
1239 !nl;]ptPc$!nl;]ptPc$!nl;]ptPc$!nl;]khH-ko@s<!s4dS-pY5Z#!nl;]khH-ko@s<!s4dS-
1240 pY5Z#!nl;]khH-ko@s<!s4dS-pY5Z#!nl;]khH-ko@s<!s4dS-pY5Z#!nl;]khH-ko@s<!s4dS-
1241 pY5Z#!nl;]khH-kn([lrJ,~>
1242 rS%5)!o2PbptG]$!o2PbptGT!ptGT!ptGT!ptG]$!SlH(gA9S!gA9S!gA9S!gA9S!gA9RfgAfq!
1243 gAfq-gAfq%gA9RfgAfq!gAfq-gAfq%gA9RfgAfq!gAfq-gAfq%gA9RfgAfq!gAfq-gAfq%gA9Rf
1244 gAfq!gAfq-gAfq%gA9RfgAfprgAfoX~>
1245 rRUkr!S5p!f)*tuf%BNDs4GrS!S,cqfR_V)eq)Dqepm~>
1246 rS.5'pY5T!pY5T!pY5T!pY5T!pY5T!pY5T!pY5T!pY5T!pY5T!pY5T!kM-$jo@s<!s4dS-pY5T!
1247 kM-$jo@s<!s4dS-pY5T!kM-$jo@s<!s4dS-pY5T!kM-$jo@s<!s4dS-pY5T!kM-$jo@s<!s4dS-
1248 pY5T!kM-$jn([lrJ,~>
1249 rS%/'pY,N!pY,N!pY,N!pY,N!pY,N!pY,N!pY,N!pY,N!pY,N!pY,N!kM#sjo@j6!s4[M-pY,N!
1250 kM#sjo@j6!s4[M-pY,N!kM#sjo@j6!s4[M-pY,N!kM#sjo@j6!s4[M-pY,N!kM#sjo@j6!s4[M-
1251 pY,N!kM#sjn(RfrJ,~>
1252 rRUkrpX]5l_q+k<!7ptuJ_#D'J_%upJ,~>
1253 rS.A+!8IM,s4dS-qqM/)!8IM,s4dS-qqM/)!8IM,s4dS-qqM/)!8IM,s4dS-qqM/)!8IM,s4dS-
1254 qqM/)!8IM,s4dS-qqM/)!8IM,s4dS-qqM/)!8IM,s4dS-qqM/)!8IM,s4dS-qqM/)!8IM,s4dS-
1255 qqM/)!8IM,s4dS-leDHns4dS-s4dS-qqM/)s4dS-s4dS-qqM/)!8IM,s4dS-leDHns4dS-s4dS-
1256 qqM/)s4dS-s4dS-qqM/)!8IM,s4dS-leDHns4dS-s4dS-qqM/)s4dS-s4dS-qqM/)!8IM,s4dS-
1257 leDHns4dS-s4dS-qqM/)s4dS-s4dS-qqM/)!8IM,s4dS-leDHns4dS-s4dS-qqM/)s4dS-s4dS-
1258 qqM/)!8IM,s4dS-leDHns4dS-s4dS-qqM/)s4dS-J,~>
1259 rS%;+!8@G,s4[M-qqD))!8@G,s4[M-qqD))!8@G,s4[M-qqD))!8@G,s4[M-qqD))!8@G,s4[M-
1260 qqD))!8@G,s4[M-qqD))!8@G,s4[M-qqD))!8@G,s4[M-qqD))!8@G,s4[M-qqD))!8@G,s4[M-
1261 qqD))!8@G,s4[M-le;Bns4[M-s4[M-qqD))s4[M-s4[M-qqD))!8@G,s4[M-le;Bns4[M-s4[M-
1262 qqD))s4[M-s4[M-qqD))!8@G,s4[M-le;Bns4[M-s4[M-qqD))s4[M-s4[M-qqD))!8@G,s4[M-
1263 le;Bns4[M-s4[M-qqD))s4[M-s4[M-qqD))!8@G,s4[M-le;Bns4[M-s4[M-qqD))s4[M-s4[M-
1264 qqD))!8@G,s4[M-le;Bns4[M-s4[M-qqD))s4[M-J,~>
1265 hpqbXs4./#s4."ts4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4.)!s4I8#
1266 Ib!$#e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%
1267 e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%e^`7%
1268 e^`7%e^`7%s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#
1269 s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#
1270 s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#
1271 s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#
1272 s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#
1273 s4./#s4./#s4./#s4./#s4)W~>
1274 rS.A+s4dS-s4dS-s4dP,$JX:ggYCN:gY:H9qqM/)s4dS-s4dS-qqM/)s4dS-s4dS-qqM/)s4dS-
1275 s4dS-qqM/)s4dS-s4dS-qqM/)s4dS-s4dS-qqM/)s4dS-s4dS-qqM/)s4dS-s4dS-qqM/)s4dS-
1276 s4dS-qqM/)s4dS-s4dS-leDHns4dS-s4dS-qqM/)s4dS-s4dS-qqM/)s4dS-s4dS-leDHns4dS-
1277 s4dS-qqM/)s4dS-s4dS-qqM/)s4dS-s4dS-leDHns4dS-s4dS-qqM/)s4dS-s4dS-qqM/)s4dS-
1278 s4dS-leDHns4dS-s4dS-qqM/)s4dS-s4dS-qqM/)s4dS-s4dS-leDHns4dS-s4dS-qqM/)s4dS-
1279 s4dS-qqM/)s4dS-s4dS-leDHns4dS-s4dS-qqM/)s4dS-J,~>
1280 rS%;+s4[M-s4[M-s4[J*"5;MagA]k,gAfq)gAfq-gAfq-gAfq)gAfq-gAfq-gAfq)gAfq-gAfq-
1281 gAfq)gAfq-gAfq-gAfq)gAfq-gAfq-gAfq)gAfq-gAfq-gAfq)gAfq-gAfq-gAfq)gAfq-gAfq-
1282 gAfq)gAfq-gAfq-gAfpngAfq-gAfq-gAfq)gAfq-gAfq-gAfq)gAfq-gAfq-gAfpngAfq-gAfq-
1283 gAfq)gAfq-gAfq-gAfq)gAfq-gAfq-gAfpngAfq-gAfq-gAfq)gAfq-gAfq-gAfq)gAfq-gAfq-
1284 gAfpngAfq-gAfq-gAfq)gAfq-gAfq-gAfq)gAfq-gAfq-gAfpngAfq-gAfq-gAfq)gAfq-gAfq-
1285 gAfq)gAfq-gAfq-gAfpngAfq-gAfq-gAfq)gAfq-gAfoX~>
1286 n^[WgrRCo!pXT;ps4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#
1287 s4./#s4.)!s4I;$s4%,#rmh&"s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#
1288 s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#
1289 s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#
1290 s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#
1291 s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#
1292 s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#
1293 s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4./#
1294 s4./#s4./#s4./#s4./#s4./#s4./#s4./#s4)W~>
1295 o%X,sJ_Pb1J_Pb1qV-N~>
1296 o%O&qX4dR.J_G\/J_JN*J,~>
1297 o%!]g]%-W-qUGSpJ^o>%J^r/uJ,~>
1298 o%X,sJ_Pb1J_Pb1qV-N~>
1299 o%O&qJ_G\/J_G\/qV$H~>
1300 o%!]g`74q?e^jTIpst#HJ^o>%b12"~>
1301 s4[M-s4[M-s4[M-s4VtWg=b05gY1B9gY1B9gY1B9gY1B9gY1B9gY1B9gY1B9gY1B9gY1B9gY1B9
1302 gY1B9gY1B9gY1B9gY1B9gY1B9gY1B9gY1B9gY1B9gY1B9gY1B9gY1B9gtLK:gY1B9gY1B9gY1B9
1303 gY1B9gY1B9gY1B9gY1B9gY1B9gY1B]g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-
1304 g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-")g]-"-g]-"-g]-"-g]-"-g]-"-
1305 g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-")g]-"-g]-"-g]-"-
1306 g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-
1307 g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-
1308 g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-
1309 g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g]-"-g],uX~>
1310 s4dS-s4dS-s4dS-s4]clg"P05g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9g=tB9
1311 g=tB9g=tB9g=tB9g=tB9g=tB]g'HHeg=tB9g=tBVgAfn-gA]k,gAfq-gAfq-gAfq-gAfq-gAfq-
1312 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1313 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAft.gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1314 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAft.gAfq-gAfq-gAfq-
1315 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1316 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1317 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-
1318 gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfq-gAfoX~>
1319 o%*ci`7>"Bf%BiMpt5Pr!8!4]s4=m6s4;hQNRiU~>
1320 rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"
1321 rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"rrE'"rr<'#!rW0"!<3*"!<3*"!<3*"
1322 !<3*"!<3*"!<3*"!<3*"!<3*"!<3*"!<3*"!<3*"!<3*"!<3*"!<3*"!<3*"!<3*"!<3*"!<3)s
1323 !<3*"!<3*"!<3*"!<3*"!<3*"!<3*"!<3*"!<3*"!;up5!W`9$!<E0#!<E0#!<E0#!<E0#!<N&t
1324 rrN-"rrN-"rrN-"rrN-"rrN-"rrN-"rrN-"rrN-"rrN-"rrN-"r;d?/!<<*#!<<*#!<<*#!W)ls
1325 !WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!W)ls
1326 !WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!W)ls
1327 !WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!W)ls
1328 !WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN0"!WN.M~>
1329 RK3<fNr].[]E%p3JH1`2!!.T~>
1330 JH16$JH16$k5^#~>
1331 RK3<fO9#4[]`A!3JH1]1J,~>
1332 RK3<fO9#4[]`A!3JH1]1J,~>
1333 RK3<fO9#4[]`A!3JH1]1J,~>
1334 RK39eOT>C^!<N;8!<3'#!WdiPNW=S~>
1335 RK39e[K-=.h>mQV!<N;e!<3)N!<3'#!WhilrrL";rrL";rrL";rrM!WJ,~>
1336 RK39eOT>C^!<N;8!<3'#!WdiPNW=S~>
1337 R/m0dPlUU\_#X93JH1`2J,~>
1338 R/m0dPlUU\_#X93JH1`2J,~>
1339 R/m0dPlUU\_#X93JH1`2J,~>
1340 JH1]1r;lEgr;hHLd/a+GW;unuJ,~>
1341 JH1]1r;lEgr;hHLd/a+GW;unuJ,~>
1342 JH1]1r;lEgr;hHLd/a+GW;unuJ,~>
1343 JH1]1r;lEgr;hHLd/a+GW;unuJ,~>
1344 JH1]1r;lEgr;hHLd/a+GW;unuJ,~>
1345 JH1]1r;lEgr;hHLd/a+GW;unuJ,~>
1346 JH1]1r;lEgr;hHLd/a+GW;unuJ,~>
1347 JH1]1r;lEgr;hHLd/a+GW;unuJ,~>
1348 JH1]1r;lEgr;hHLd/a+GW;unuJ,~>
1349 JH1]1r;lEgr;hHLd/a+GW;unuJ,~>
1350 JH1]1r;lEgr;hHLd/a+GW;unuJ,~>
1351 JH1]1r;lEgr;hHLd/a+GW;unuJ,~>
1352 JH16$q>^KrSH/WiJH4@'!W`9$J,~>
1353 JH16$q>^KrSH/WiJH4@'!W`9$J,~>
1354 JH16$q>^KrSH/WiJH4@'!W`9$J,~>
1355 JH16$q>^KrScJ]iJH4@'!W`9$J,~>
1356 JH16$q>^KrScJ]iJH4@'!W`9$J,~>
1357 JH16$q>^KrScJ]iJH4@'!W`9$J,~>
1358 JH16$Q2pjaJH47$J,~>
1359 JH16$Q2pjaJH47$J,~>
1360 JH16$Q2pjaJH47$J,~>
1361 JH16$R/m$`JH4^1!!2cnJ,~>
1362 JH16$R/m$`JH4^1!!2cnJ,~>
1363 JH16$R/m$`JH4^1!!2cnJ,~>
1364 q>gHpf`2!QdK'4HJH50>!!.WNnc/XjhZ3TUo`4pknGrLgeH#OKl2Z>~>
1365 q>gHpf`2!QdK'4HJH50>!!.WNnc/XjhZ3TUo`4pknGrLgeH#OKl2Z>~>
1366 q>gHpf`2!QdK'4HJH50>!!.WNnc/XjhZ3TUo`4pknGrLgeH#OKl2Z>~>
1367 q#LBph#IEUc2deDJH5KG!!.WNq>^Krc2deDo`4pknGrLgo`+smiW/oXl2Z>~>
1368 q#LBph#IEUc2deDJH5KG!!.WNq>^Krc2deDo`4pknGrLgo`+smiW/oXl2Z>~>
1369 q#LBph#IEUc2deDJH5KG!!.WNq>^Krc2deDo`4pknGrLgo`+smiW/oXl2Z>~>
1370 q>gHpW;uktJH16$]`A!3o`4pknGrLgeH#OKl2Z>~>
1371 q>gHpW;uktJH16$]`A!3o`4pknGrLgeH#OKl2Z>~>
1372 q>gHpW;uktJH16$]`A!3o`4pknGrLgeH#OKl2Z>~>
1373 q>gHpec5[NeH#OKJH5*<!!.WNnc/Xji;ifWo`4pknGrLgeH#OKp&G'np&KU~>
1374 q>gHpec5[NeH#OKJH5*<!!.WNnc/Xji;ifWo`4pknGrLgeH#OKp&G'np&KU~>
1375 q>gHpec5[NeH#OKJH5*<!!.WNnc/Xji;ifWo`4pknGrLgeH#OKp&G'np&KU~>
1376 roMc4rrE*"qW._>JH3morrE*"roF.Bq#LHW!U&UP!<*#S!<3'"!<2'[k4&HOjoOZ-_#OH9o`5!m
1377 "9@QFk2lOBkl:\ap&OsN!9X+XJ,~>
1378 roMc4rrE*"qW._>JH3morrE*"roF.Bq#LHW!U&UP!<*#S!<3'"!<2'[k4&HOjoOZ-_#OH9o`5!m
1379 "9@QFk2lOBkl:\ap&OsN!9X+XJ,~>
1380 roMc4rrE*"qW._>JH3morrE*"roF.Bq#LHW!U&UP!<*#S!<3'"!<2'[k4&HOjoOZ-_#OH9o`5!m
1381 "9@QFk2lOBkl:\ap&OsN!9X+XJ,~>
1382 roO.[!!1^PqrIk>k(*NS!<)$W!!WH(!9WD*k-Y3f!SIJOjn&NW!<<,^jlY^A!!!&j!!D?DjlQFA
1383 kl:\ap&OpMq>c$~>
1384 roO.[!!1^PqrIk>k(*NS!<)$W!!WH(!9WD*k-Y3f!SIJOjn&NW!<<,^jlY^A!!!&j!!D?DjlQFA
1385 kl:\ap&OpMq>c$~>
1386 roO.[!!1^PqrIk>k(*NS!<)$W!!WH(!9WD*k-Y3f!SIJOjn&NW!<<,^jlY^A!!!&j!!D?DjlQFA
1387 kl:\ap&OpMq>c$~>
1388 s5a7AeH#F,JH3dlrT3hTrT:Kfr;kROrT3PLrT:?brT++^!W`>X!;YaQ!.Y~>
1389 s5a7AeH#F,JH3dlrT3hTrT:Kfr;kROrT3PLrT:?brT++^!W`>X!;YaQ!.Y~>
1390 s5a7AeH#F,JH3dlrT3hTrT:Kfr;kROrT3PLrT:?brT++^!W`>X!;YaQ!.Y~>
1391 roMi6"T\T(!!)0ZjT4N*jT#8]JH4g4!9X:Bq#LBU\,c=*g&V*5nGrOMYlOdb!9X4\h#IH;qW7PR
1392 J,~>
1393 roMi6"T\T(!!)0ZjT4N*jT#8]JH4g4!9X:Bq#LBU\,c=*g&V*5nGrOMYlOdb!9X4\h#IH;qW7PR
1394 J,~>
1395 roMi6"T\T(!!)0ZjT4N*jT#8]JH4g4!9X:Bq#LBU\,c=*g&V*5nGrOMYlOdb!9X4\h#IH;qW7PR
1396 J,~>
1397 "p"](jlY[dfDl!S!!)*ZjlldDjfngbjT+GV!!!'!!!D?DjlQ:<roO4B]`A#md/a.,nGrOLr;kRO
1398 rT<&=!9O4BeH#R0q>c$~>
1399 "p"](jlY[dfDl!S!!)*ZjlldDjfngbjT+GV!!!'!!!D?DjlQ:<roO4B]`A#md/a.,nGrOLr;kRO
1400 rT<&=!9O4BeH#R0q>c$~>
1401 "p"](jlY[dfDl!S!!)*ZjlldDjfngbjT+GV!!!'!!!D?DjlQ:<roO4B]`A#md/a.,nGrOLr;kRO
1402 rT<&=!9O4BeH#R0q>c$~>
1403 rW!&^jQ5LT!<3)ujlldDjfngajgbBijnSoVjoOZ-]`A#md/a.,nGrOLr;kROrT<&=!9O4BeH#R0
1404 q>c$~>
1405 rW!&^jQ5LT!<3)ujlldDjfngajgbBijnSoVjoOZ-]`A#md/a.,nGrOLr;kROrT<&=!9O4BeH#R0
1406 q>c$~>
1407 rW!&^jQ5LT!<3)ujlldDjfngajgbBijnSoVjoOZ-]`A#md/a.,nGrOLr;kROrT<&=!9O4BeH#R0
1408 q>c$~>
1409 rW)oYf`2*T!!!&ujlldDjo5;\!OMh,k5OJQ!<)$T!<)&n!<)$,!<)$N!!**#rT3tYf`;!5i;`l>
1410 roV`2rT3kUJ,~>
1411 rW)oYf`2*T!!!&ujlldDjo5;\!OMh,k5OJQ!<)$T!<)&n!<)$,!<)$N!!**#rT3tYf`;!5i;`l>
1412 roV`2rT3kUJ,~>
1413 rW)oYf`2*T!!!&ujlldDjo5;\!OMh,k5OJQ!<)$T!<)&n!<)$,!<)$N!!**#rT3tYf`;!5i;`l>
1414 roV`2rT3kUJ,~>
1415 rW)oYeH#U1!9EAE!9X:B]`8$5q#CU"!!)*BjlO#[email protected]=),jmrHQ!<E)[r;l9c
1416 !!2KfrT<&=!9O4Bec5[NrT3kUJ,~>
1417 rW)oYeH#U1!9EAE!9X:B]`8$5q#CU"!!)*BjlO#[email protected]=),jmrHQ!<E)[r;l9c
1418 !!2KfrT<&=!9O4Bec5[NrT3kUJ,~>
1419 rW)oYeH#U1!9EAE!9X:B]`8$5q#CU"!!)*BjlO#[email protected]=),jmrHQ!<E)[r;l9c
1420 !!2KfrT<&=!9O4Bec5[NrT3kUJ,~>
1421 rW)oYeH#R0T`G#lr;ccsV#^Mr^AnAujlPXP!<2*\jm`?LjlldF!UBac!TO1YjjaA0jn\t-~>
1422 rW)oYeH#R0T`G#lr;ccsV#^Mr^AnAujlPXP!<2*\jm`?LjlldF!UBac!TO1YjjaA0jn\t-~>
1423 rW)oYeH#R0T`G#lr;ccsV#^Mr^AnAujlPXP!<2*\jm`?LjlldF!UBac!TO1YjjaA0jn\t-~>
1424 rW)oYeH#R0i;`iY_>sK7rW)lt\,ZL0mf<=f^]=>pd/a.-nGrRM!9EAErW2?crW2'["6JV*jjaA0
1425 jn\t-~>
1426 rW)oYeH#R0i;`iY_>sK7rW)lt\,ZL0mf<=f^]=>pd/a.-nGrRM!9EAErW2?crW2'["6JV*jjaA0
1427 jn\t-~>
1428 rW)oYeH#R0i;`iY_>sK7rW)lt\,ZL0mf<=f^]=>pd/a.-nGrRM!9EAErW2?crW2'["6JV*jjaA0
1429 jn\t-~>
1430 rW)oYeH#R0T`G#lr;ccs[f?C/o`+smr;Zp#!W`><!<)$,!!DBHk2u16rT38D!s&H(!UTjh!<N9&
1431 jT,8@eH#R0q>c$~>
1432 rW)oYeH#R0T`G#lr;ccs[f?C/o`+smr;Zp#!W`><!<)$,!!DBHk2u16rT38D!s&H(!UTjh!<N9&
1433 jT,8@eH#R0q>c$~>
1434 rW)oYeH#R0T`G#lr;ccs[f?C/o`+smr;Zp#!W`><!<)$,!!DBHk2u16rT38D!s&H(!UTjh!<N9&
1435 jT,8@eH#R0q>c$~>
1436 !W`9$rT2Q0"6JV*jlugG!P&4/!WE)r!N#kq!SdYT!TsI_jT4H(d/X1.roW_NrT38Dr;l9cquPp[
1437 rT2Q0rT3kUJ,~>
1438 !W`9$rT2Q0"6JV*jlugG!P&4/!WE)r!N#kq!SdYT!TsI_jT4H(d/X1.roW_NrT38Dr;l9cquPp[
1439 rT2Q0rT3kUJ,~>
1440 !W`9$rT2Q0"6JV*jlugG!P&4/!WE)r!N#kq!SdYT!TsI_jT4H(d/X1.roW_NrT38Dr;l9cquPp[
1441 rT2Q0rT3kUJ,~>
1442 rr<$"rT3hTp#Z/7m/[+Hm/["E!TjFV!;5FRjS%^2!;5IPk4&HIjk0Y4jo#2Xjo+?@jT+H=!!!*"
1443 !VPOSjSn9:!<2'\joP#Q!9X:Bqu?g"!!)0Xjo#2XjnSoLjo+?;!;urs!;urc!<)!Z!V-3jjSn9=
1444 !!30$!<)'YjT+B@jT+B@jm`?Hjm`?Djo#2XjnSoLjo+?/!<)$U!.Y~>
1445 rr<$"rT3hTp#Z/7m/[+Hm/["E!TjFV!;5FRjS%^2!;5IPk4&HIjk0Y4jo#2Xjo+?@jT+H=!!!*"
1446 !VPOSjSn9:!<2'\joP#Q!9X:Bqu?g"!!)0Xjo#2XjnSoLjo+?;!;urs!;urc!<)!Z!V-3jjSn9=
1447 !!30$!<)'YjT+B@jT+B@jm`?Hjm`?Djo#2XjnSoLjo+?/!<)$U!.Y~>
1448 rr<$"rT3hTp#Z/7m/[+Hm/["E!TjFV!;5FRjS%^2!;5IPk4&HIjk0Y4jo#2Xjo+?@jT+H=!!!*"
1449 !VPOSjSn9:!<2'\joP#Q!9X:Bqu?g"!!)0Xjo#2XjnSoLjo+?;!;urs!;urc!<)!Z!V-3jjSn9=
1450 !!30$!<)'YjT+B@jT+B@jm`?Hjm`?Djo#2XjnSoLjo+?/!<)$U!.Y~>
1451 rW)oY!<</t!;5IPk3W0Ijm<'JjT+HBjT4H(o`4=>"6S\F!W)lijo+??!!!&n!;Ya0!<)$X!<)$X
1452 k5FE;!<3'#!!2WOq#LHV!T`A4!<2'[k4o#Qjo#2XjnSlVk4[p8k4o#U!W<#s!UTmcjm`?LjnSoT
1453 k4Rj7!!!&n!;YaO!!!&s!;5IP!<)$X!!!'!!;5IPk3W0Ijn\t-~>
1454 rW)oY!<</t!;5IPk3W0Ijm<'JjT+HBjT4H(o`4=>"6S\F!W)lijo+??!!!&n!;Ya0!<)$X!<)$X
1455 k5FE;!<3'#!!2WOq#LHV!T`A4!<2'[k4o#Qjo#2XjnSlVk4[p8k4o#U!W<#s!UTmcjm`?LjnSoT
1456 k4Rj7!!!&n!;YaO!!!&s!;5IP!<)$X!!!'!!;5IPk3W0Ijn\t-~>
1457 rW)oY!<</t!;5IPk3W0Ijm<'JjT+HBjT4H(o`4=>"6S\F!W)lijo+??!!!&n!;Ya0!<)$X!<)$X
1458 k5FE;!<3'#!!2WOq#LHV!T`A4!<2'[k4o#Qjo#2XjnSlVk4[p8k4o#U!W<#s!UTmcjm`?LjnSoT
1459 k4Rj7!!!&n!;YaO!!!&s!;5IP!<)$X!!!'!!;5IPk3W0Ijn\t-~>
1460 rW)oYq#L'Ks5j=Em/[+Hm/ZtDo`4RE!9X1?!T`A<!;,CQjoFT;!!!'!!!;<Ek5=>o!<)$X!<)$X
1461 k5FE;!!!*"!VPOSjSn9?!!!&u!<)$L!!DBFjlZC>!!2oWr;cfXq#LEU!p8V,qrRe=q#L?or;ccs
1462 m/[+HnGrOLq#LEVr8dq>roF.@roNYMq;q,Hp#Z,P!9X:Bq#L*LrT<JIrT3kUJ,~>
1463 rW)oYq#L'Ks5j=Em/[+Hm/ZtDo`4RE!9X1?!T`A<!;,CQjoFT;!!!'!!!;<Ek5=>o!<)$X!<)$X
1464 k5FE;!!!*"!VPOSjSn9?!!!&u!<)$L!!DBFjlZC>!!2oWr;cfXq#LEU!p8V,qrRe=q#L?or;ccs
1465 m/[+HnGrOLq#LEVr8dq>roF.@roNYMq;q,Hp#Z,P!9X:Bq#L*LrT<JIrT3kUJ,~>
1466 rW)oYq#L'Ks5j=Em/[+Hm/ZtDo`4RE!9X1?!T`A<!;,CQjoFT;!!!'!!!;<Ek5=>o!<)$X!<)$X
1467 k5FE;!!!*"!VPOSjSn9?!!!&u!<)$L!!DBFjlZC>!!2oWr;cfXq#LEU!p8V,qrRe=q#L?or;ccs
1468 m/[+HnGrOLq#LEVr8dq>roF.@roNYMq;q,Hp#Z,P!9X:Bq#L*LrT<JIrT3kUJ,~>
1469 rW)oYq#L3O!p8V+rT<JIrT3DH#Nk.0k2k^cjo,5[!Vl]qk4Rg9jSIs>k2k_#!;PXWk2k_'k5,,Y
1470 !VcZjjk0V6k5OK@!<)$Xk5FE;!;urhjT+B;!<;-]jQ6@@!!2lq!!3'!rT3hTq;qPTrT3hTrT+%A
1471 qW7\<q#L?or;ccsm/[+HnGrOLq#LBUp>l;8nGiROqW75Ip#Z,PrT3hT!TiJ<jo+?/!<)$U!.Y~>
1472 rW)oYq#L3O!p8V+rT<JIrT3DH#Nk.0k2k^cjo,5[!Vl]qk4Rg9jSIs>k2k_#!;PXWk2k_'k5,,Y
1473 !VcZjjk0V6k5OK@!<)$Xk5FE;!;urhjT+B;!<;-]jQ6@@!!2lq!!3'!rT3hTq;qPTrT3hTrT+%A
1474 qW7\<q#L?or;ccsm/[+HnGrOLq#LBUp>l;8nGiROqW75Ip#Z,PrT3hT!TiJ<jo+?/!<)$U!.Y~>
1475 rW)oYq#L3O!p8V+rT<JIrT3DH#Nk.0k2k^cjo,5[!Vl]qk4Rg9jSIs>k2k_#!;PXWk2k_'k5,,Y
1476 !VcZjjk0V6k5OK@!<)$Xk5FE;!;urhjT+B;!<;-]jQ6@@!!2lq!!3'!rT3hTq;qPTrT3hTrT+%A
1477 qW7\<q#L?or;ccsm/[+HnGrOLq#LBUp>l;8nGiROqW75Ip#Z,PrT3hT!TiJ<jo+?/!<)$U!.Y~>
1478 roNqUs5a:Bjm`?MjT+H5!<)'F!!E>ajlGOb!!)3]k4o#WjT4H(nGrOLnGrOLquH]sh#RE8q>^Kr
1479 r;cfYkl:hJjlPY'!<;-]jQ6%7r;llYq#LBTrr<*$!9X:Br;cfXr;cft"9@QGjlQ"4!!2'Zmc=H2
1480 rT3tXs5a:Bjm`<Qk2bXcnGrOLo`5$R!T`A8!;Y^]!!*'"jlPXdo`+smrW)oYnGrOLq>c$~>
1481 roNqUs5a:Bjm`?MjT+H5!<)'F!!E>ajlGOb!!)3]k4o#WjT4H(nGrOLnGrOLquH]sh#RE8q>^Kr
1482 r;cfYkl:hJjlPY'!<;-]jQ6%7r;llYq#LBTrr<*$!9X:Br;cfXr;cft"9@QGjlQ"4!!2'Zmc=H2
1483 rT3tXs5a:Bjm`<Qk2bXcnGrOLo`5$R!T`A8!;Y^]!!*'"jlPXdo`+smrW)oYnGrOLq>c$~>
1484 roNqUs5a:Bjm`?MjT+H5!<)'F!!E>ajlGOb!!)3]k4o#WjT4H(nGrOLnGrOLquH]sh#RE8q>^Kr
1485 r;cfYkl:hJjlPY'!<;-]jQ6%7r;llYq#LBTrr<*$!9X:Br;cfXr;cft"9@QGjlQ"4!!2'Zmc=H2
1486 rT3tXs5a:Bjm`<Qk2bXcnGrOLo`5$R!T`A8!;Y^]!!*'"jlPXdo`+smrW)oYnGrOLq>c$~>
1487 roNqUrT3PLrT3PLrT<>EroF.Bk5YM`!<)'U!<)$L!!D?DjlQ"4rT3tXr;k^SrT3\PrT<>ErT3tX
1488 roF.Bo`4pk"6J\,jnSlVk5OKA!!!&ujo#2Xjo#2X!WD-M!!!&Z!;tpYk4Rg9jS\-<!<;-]k2l+5
1489 rT3PLrT3\PrT3\Pq;qPTrT3PLrT3PLrT3kUJ,~>
1490 roNqUrT3PLrT3PLrT<>EroF.Bk5YM`!<)'U!<)$L!!D?DjlQ"4rT3tXr;k^SrT3\PrT<>ErT3tX
1491 roF.Bo`4pk"6J\,jnSlVk5OKA!!!&ujo#2Xjo#2X!WD-M!!!&Z!;tpYk4Rg9jS\-<!<;-]k2l+5
1492 rT3PLrT3\PrT3\Pq;qPTrT3PLrT3PLrT3kUJ,~>
1493 roNqUrT3PLrT3PLrT<>EroF.Bk5YM`!<)'U!<)$L!!D?DjlQ"4rT3tXr;k^SrT3\PrT<>ErT3tX
1494 roF.Bo`4pk"6J\,jnSlVk5OKA!!!&ujo#2Xjo#2X!WD-M!!!&Z!;tpYk4Rg9jS\-<!<;-]k2l+5
1495 rT3PLrT3\PrT3\Pq;qPTrT3PLrT3PLrT3kUJ,~>
1496 roNqUrT3PL!9F.@nGrOMn,NFhqZ-TVjT,;B!9a.XrT3PL"6AS)jm`?Ljo#2X!T3q^!<<,]jQ5Lr
1497 !<)'G!!**#rT3tXrT3\P!s&H(!WD-U!!)0\jo#2ZjT"??!<;-ajQ-@B!!)rurT3>F!!29`qrInA
1498 jlZ0r!9X4[rT3VN!<E3!jm`?Ljn/WPjn/WLjo,5[!WD-Y!!!&n!<)$L!<)$U!.Y~>
1499 roNqUrT3PL!9F.@nGrOMn,NFhqZ-TVjT,;B!9a.XrT3PL"6AS)jm`?Ljo#2X!T3q^!<<,]jQ5Lr
1500 !<)'G!!**#rT3tXrT3\P!s&H(!WD-U!!)0\jo#2ZjT"??!<;-ajQ-@B!!)rurT3>F!!29`qrInA
1501 jlZ0r!9X4[rT3VN!<E3!jm`?Ljn/WPjn/WLjo,5[!WD-Y!!!&n!<)$L!<)$U!.Y~>
1502 roNqUrT3PL!9F.@nGrOMn,NFhqZ-TVjT,;B!9a.XrT3PL"6AS)jm`?Ljo#2X!T3q^!<<,]jQ5Lr
1503 !<)'G!!**#rT3tXrT3\P!s&H(!WD-U!!)0\jo#2ZjT"??!<;-ajQ-@B!!)rurT3>F!!29`qrInA
1504 jlZ0r!9X4[rT3VN!<E3!jm`?Ljn/WPjn/WLjo,5[!WD-Y!!!&n!<)$L!<)$U!.Y~>
1505 roNqU"6JV*jm`?LjmiBO!WD-\!U9[`jllaF!WE)tk4o#Ujn&NT!<<,^roNYMrT+"Zq#TFS!W`9$
1506 roF.Bo`4sQrVup!m/[+Hr;cfXoDnjk!9X:Bq#LBTr;cfXr;cfXquH]s!9X:Bd/`Lo!TrMB!<)$O
1507 !!<6%!9X:BnGi[QjQ5Lr!<)$P!!)0Xjo#2YjT+H5!<)$L!<)$U!.Y~>
1508 roNqU"6JV*jm`?LjmiBO!WD-\!U9[`jllaF!WE)tk4o#Ujn&NT!<<,^roNYMrT+"Zq#TFS!W`9$
1509 roF.Bo`4sQrVup!m/[+Hr;cfXoDnjk!9X:Bq#LBTr;cfXr;cfXquH]s!9X:Bd/`Lo!TrMB!<)$O
1510 !!<6%!9X:BnGi[QjQ5Lr!<)$P!!)0Xjo#2YjT+H5!<)$L!<)$U!.Y~>
1511 roNqU"6JV*jm`?LjmiBO!WD-\!U9[`jllaF!WE)tk4o#Ujn&NT!<<,^roNYMrT+"Zq#TFS!W`9$
1512 roF.Bo`4sQrVup!m/[+Hr;cfXoDnjk!9X:Bq#LBTr;cfXr;cfXquH]s!9X:Bd/`Lo!TrMB!<)$O
1513 !!<6%!9X:BnGi[QjQ5Lr!<)$P!!)0Xjo#2YjT+H5!<)$L!<)$U!.Y~>
1514 p&P'QnGrOLnGrOLklC\DquH]so`4pkrT3\P"6JV*jo+??jT+B?jT+B@jT=N)jm`?LjjaA0k32m<
1515 jT=T+jo+9>!<<,ujm`?LjnSoTjo#2Xjo#2XjnSoTjnSoT!SmbSjn&NT!<<,\roF7_!<<,^n`9c3
1516 roF4BjlQ"4rT3\PrT3PLrT3tXl/hU=quQcXq>c$~>
1517 p&P'QnGrOLnGrOLklC\DquH]so`4pkrT3\P"6JV*jo+??jT+B?jT+B@jT=N)jm`?LjjaA0k32m<
1518 jT=T+jo+9>!<<,ujm`?LjnSoTjo#2Xjo#2XjnSoTjnSoT!SmbSjn&NT!<<,\roF7_!<<,^n`9c3
1519 roF4BjlQ"4rT3\PrT3PLrT3tXl/hU=quQcXq>c$~>
1520 p&P'QnGrOLnGrOLklC\DquH]so`4pkrT3\P"6JV*jo+??jT+B?jT+B@jT=N)jm`?LjjaA0k32m<
1521 jT=T+jo+9>!<<,ujm`?LjnSoTjo#2Xjo#2XjnSoTjnSoT!SmbSjn&NT!<<,\roF7_!<<,^n`9c3
1522 roF4BjlQ"4rT3\PrT3PLrT3tXl/hU=quQcXq>c$~>
1523 p&P'QnGrOLnGrOLklC\DquH]so`4pk#3G"/jT#8]p](<TroO+@n`B9@rT2Q0rT<SL!!2rspuMM:
1524 qrItAjlGJ&rW2uZnGrOLq#LBTr;cfXr;cfXq#LBTq#L?oh#RE8o)SdkrT3tXl/hF8rT3\PrT3PL
1525 rT3tXr8dq>oAp):jlPXt!;ursjn\t-~>
1526 p&P'QnGrOLnGrOLklC\DquH]so`4pk#3G"/jT#8]p](<TroO+@n`B9@rT2Q0rT<SL!!2rspuMM:
1527 qrItAjlGJ&rW2uZnGrOLq#LBTr;cfXr;cfXq#LBTq#L?oh#RE8o)SdkrT3tXl/hF8rT3\PrT3PL
1528 rT3tXr8dq>oAp):jlPXt!;ursjn\t-~>
1529 p&P'QnGrOLnGrOLklC\DquH]so`4pk#3G"/jT#8]p](<TroO+@n`B9@rT2Q0rT<SL!!2rspuMM:
1530 qrItAjlGJ&rW2uZnGrOLq#LBTr;cfXr;cfXq#LBTq#L?oh#RE8o)SdkrT3tXl/hF8rT3\PrT3PL
1531 rT3tXr8dq>oAp):jlPXt!;ursjn\t-~>
1532 p&P'QnGrOLnGrOLklC\DquH]so`4pk"6JV*jn/WPjo4E?jT+B=jT4H)roNYMrT2Q0"6Se/k4eoV
1533 !V6<]jo+9=!WD-M!<)$T!<)$X!<)$X!<)$T!<)$T!;urS!<)$M!!!&ujo#/Zk3qC4jQ?I'nGrOL
1534 o`4sPnGrOLr;c`V!p&J*o&]NEr;llYq>c$~>
1535 p&P'QnGrOLnGrOLklC\DquH]so`4pk"6JV*jn/WPjo4E?jT+B=jT4H)roNYMrT2Q0"6Se/k4eoV
1536 !V6<]jo+9=!WD-M!<)$T!<)$X!<)$X!<)$T!<)$T!;urS!<)$M!!!&ujo#/Zk3qC4jQ?I'nGrOL
1537 o`4sPnGrOLr;c`V!p&J*o&]NEr;llYq>c$~>
1538 p&P'QnGrOLnGrOLklC\DquH]so`4pk"6JV*jn/WPjo4E?jT+B=jT4H)roNYMrT2Q0"6Se/k4eoV
1539 !V6<]jo+9=!WD-M!<)$T!<)$X!<)$X!<)$T!<)$T!;urS!<)$M!!!&ujo#/Zk3qC4jQ?I'nGrOL
1540 o`4sPnGrOLr;c`V!p&J*o&]NEr;llYq>c$~>
1541 p&P'QnGrOLnGrOLklC\DquH]so`4pkrT3\PrT4"?n`B9@rT2]4!!3'!!9O4Bp&G'no`4ODrT*tZ
1542 !<<0!jm`?LjnSoTjo#2Xjo#2XjnSoTjnSoT!Ta:]!VufrjT4H(nGrRM!9F(Yl/hF8rT3\PrT3SM
1543 !!3&[r;c`V!9We4o`4pkrT3kUJ,~>
1544 p&P'QnGrOLnGrOLklC\DquH]so`4pkrT3\PrT4"?n`B9@rT2]4!!3'!!9O4Bp&G'no`4ODrT*tZ
1545 !<<0!jm`?LjnSoTjo#2Xjo#2XjnSoTjnSoT!Ta:]!VufrjT4H(nGrRM!9F(Yl/hF8rT3\PrT3SM
1546 !!3&[r;c`V!9We4o`4pkrT3kUJ,~>
1547 p&P'QnGrOLnGrOLklC\DquH]so`4pkrT3\PrT4"?n`B9@rT2]4!!3'!!9O4Bp&G'no`4ODrT*tZ
1548 !<<0!jm`?LjnSoTjo#2Xjo#2XjnSoTjnSoT!Ta:]!VufrjT4H(nGrRM!9F(Yl/hF8rT3\PrT3SM
1549 !!3&[r;c`V!9We4o`4pkrT3kUJ,~>
1550 rW)ltr;cfYnGrOLnGrOLklC\Dm/[1J!TrM6!!)0\jkTq8jk0V9!<N9%rT3DHs5j@Dk4&HMjo#2X
1551 jm`?LjnSoTjo#2Xjo#2XjnSoTjnSlV!TF+T!WM3]kOAQNjo#2XjkTq8k4J`Qjm`?Ljo#2Xjm<'J
1552 !V??l!WD-V!.Y~>
1553 rW)ltr;cfYnGrOLnGrOLklC\Dm/[1J!TrM6!!)0\jkTq8jk0V9!<N9%rT3DHs5j@Dk4&HMjo#2X
1554 jm`?LjnSoTjo#2Xjo#2XjnSoTjnSlV!TF+T!WM3]kOAQNjo#2XjkTq8k4J`Qjm`?Ljo#2Xjm<'J
1555 !V??l!WD-V!.Y~>
1556 rW)ltr;cfYnGrOLnGrOLklC\Dm/[1J!TrM6!!)0\jkTq8jk0V9!<N9%rT3DHs5j@Dk4&HMjo#2X
1557 jm`?LjnSoTjo#2Xjo#2XjnSoTjnSlV!TF+T!WM3]kOAQNjo#2XjkTq8k4J`Qjm`?Ljo#2Xjm<'J
1558 !V??l!WD-V!.Y~>
1559 rW)ltr;cfYnGrOLnGrOLklC\Dm/R.KroNYMrT2i8rT2]4rrE-#!WD-I!<)'M!<)$X!<)$L!<)$T
1560 !<)$X!<)$X!<)$T!<)$T!!!&Z!;QZok5>8[!VQNljo#2XjkTq8k4J`Qjm`?Ljo#2XjT#>L!<*#l
1561 !!!&ujn\t-~>
1562 rW)ltr;cfYnGrOLnGrOLklC\Dm/R.KroNYMrT2i8rT2]4rrE-#!WD-I!<)'M!<)$X!<)$L!<)$T
1563 !<)$X!<)$X!<)$T!<)$T!!!&Z!;QZok5>8[!VQNljo#2XjkTq8k4J`Qjm`?Ljo#2XjT#>L!<*#l
1564 !!!&ujn\t-~>
1565 rW)ltr;cfYnGrOLnGrOLklC\Dm/R.KroNYMrT2i8rT2]4rrE-#!WD-I!<)'M!<)$X!<)$L!<)$T
1566 !<)$X!<)$X!<)$T!<)$T!!!&Z!;QZok5>8[!VQNljo#2XjkTq8k4J`Qjm`?Ljo#2XjT#>L!<*#l
1567 !!!&ujn\t-~>
1568 rW)ltr;cfYnGrOLnGrOLklC\Dm/[+HnGi[Qk2bX[!<)$4!;urtjT+B/!<)'O!!**#rT3tXrT3PL
1569 rT3hTrT3tXrT3tXrT3hTrT2]4q#LT[jlY^q!<)!]!!*'#rT2i8rT<bQrT3PLrT3tXrT3DH!s&H(
1570 !VHHkjn\t-~>
1571 rW)ltr;cfYnGrOLnGrOLklC\Dm/[+HnGi[Qk2bX[!<)$4!;urtjT+B/!<)'O!!**#rT3tXrT3PL
1572 rT3hTrT3tXrT3tXrT3hTrT2]4q#LT[jlY^q!<)!]!!*'#rT2i8rT<bQrT3PLrT3tXrT3DH!s&H(
1573 !VHHkjn\t-~>
1574 rW)ltr;cfYnGrOLnGrOLklC\Dm/[+HnGi[Qk2bX[!<)$4!;urtjT+B/!<)'O!!**#rT3tXrT3PL
1575 rT3hTrT3tXrT3tXrT3hTrT2]4q#LT[jlY^q!<)!]!!*'#rT2i8rT<bQrT3PLrT3tXrT3DH!s&H(
1576 !VHHkjn\t-~>
1577 q#UHprT<VMrT3_Q!!3#urT38D!9X:Br;Zfunc8XMnGrOLp&G'nq#CBqpAb0or;cfXq#CBqi;iiX
1578 !9X:Bm/[+InGrOLr;cfXo`+smrVur\roNqUrT3tXrT3tXrT3hTrT2Z3q>pQW!!2WjrT3tXrT3/A
1579 !!2lqrT<bQrT3PL"6J\,jo#2Xjm<'H!VHEpk2k^eq>c$~>
1580 q#UHprT<VMrT3_Q!!3#urT38D!9X:Br;Zfunc8XMnGrOLp&G'nq#CBqpAb0or;cfXq#CBqi;iiX
1581 !9X:Bm/[+InGrOLr;cfXo`+smrVur\roNqUrT3tXrT3tXrT3hTrT2Z3q>pQW!!2WjrT3tXrT3/A
1582 !!2lqrT<bQrT3PL"6J\,jo#2Xjm<'H!VHEpk2k^eq>c$~>
1583 q#UHprT<VMrT3_Q!!3#urT38D!9X:Br;Zfunc8XMnGrOLp&G'nq#CBqpAb0or;cfXq#CBqi;iiX
1584 !9X:Bm/[+InGrOLr;cfXo`+smrVur\roNqUrT3tXrT3tXrT3hTrT2Z3q>pQW!!2WjrT3tXrT3/A
1585 !!2lqrT<bQrT3PL"6J\,jo#2Xjm<'H!VHEpk2k^eq>c$~>
1586 p](<q!<)$L!!D?DjlQ"4rT3tX!!2Kf"Qe_+jT5>\!!2cnrT+%[!VZQo!Vucuk2kaenGrOLnGrOL
1587 eH#R0mf3@h!<)$P!;YaT!<)$P!;YaP!<)!Z!WE*!jT=T+!WE)tjno,X!WD-Q!<)$<!<)$L!<)$X
1588 !!DBFk2l+5rT<bQr;llYr;Zfuq>^W[jlY[t!<)$Xk5G>\!WD-M!<2'[k4J]S!WE'$jlGObq>c$~>
1589 p](<q!<)$L!!D?DjlQ"4rT3tX!!2Kf"Qe_+jT5>\!!2cnrT+%[!VZQo!Vucuk2kaenGrOLnGrOL
1590 eH#R0mf3@h!<)$P!;YaT!<)$P!;YaP!<)!Z!WE*!jT=T+!WE)tjno,X!WD-Q!<)$<!<)$L!<)$X
1591 !!DBFk2l+5rT<bQr;llYr;Zfuq>^W[jlY[t!<)$Xk5G>\!WD-M!<2'[k4J]S!WE'$jlGObq>c$~>
1592 p](<q!<)$L!!D?DjlQ"4rT3tX!!2Kf"Qe_+jT5>\!!2cnrT+%[!VZQo!Vucuk2kaenGrOLnGrOL
1593 eH#R0mf3@h!<)$P!;YaT!<)$P!;YaP!<)!Z!WE*!jT=T+!WE)tjno,X!WD-Q!<)$<!<)$L!<)$X
1594 !!DBFk2l+5rT<bQr;llYr;Zfuq>^W[jlY[t!<)$Xk5G>\!WD-M!<2'[k4J]S!WE'$jlGObq>c$~>
1595 p&P-S!p&GDnc8XMnGrRM!9WeO!!2orrT3PLrT3DH!9X:BnGrOLnGrRM!9Vf3rT3DHs5a=CjT5&T
1596 !9X7A#3P%/!!!$"rT3\Pr8e"BjlQ:<rT3tX!9F.@r;cfXquH`t!!)uZo`,!SroN)="6JV*jm`?L
1597 jo#/Zk5OK4!<)'Q!;up#jlY[do`,!SroNeQ!TiDAjo4E@!!)0\jm`?Ljm`?Ljn\t-~>
1598 p&P-S!p&GDnc8XMnGrRM!9WeO!!2orrT3PLrT3DH!9X:BnGrOLnGrRM!9Vf3rT3DHs5a=CjT5&T
1599 !9X7A#3P%/!!!$"rT3\Pr8e"BjlQ:<rT3tX!9F.@r;cfXquH`t!!)uZo`,!SroN)="6JV*jm`?L
1600 jo#/Zk5OK4!<)'Q!;up#jlY[do`,!SroNeQ!TiDAjo4E@!!)0\jm`?Ljm`?Ljn\t-~>
1601 p&P-S!p&GDnc8XMnGrRM!9WeO!!2orrT3PLrT3DH!9X:BnGrOLnGrRM!9Vf3rT3DHs5a=CjT5&T
1602 !9X7A#3P%/!!!$"rT3\Pr8e"BjlQ:<rT3tX!9F.@r;cfXquH`t!!)uZo`,!SroN)="6JV*jm`?L
1603 jo#/Zk5OK4!<)'Q!;up#jlY[do`,!SroNeQ!TiDAjo4E@!!)0\jm`?Ljm`?Ljn\t-~>
1604 p&P'QnGrOLnGrOLklC\DoDepn!!)uZrW!$$!!!&l!<)$N!!**#rT4%Z!!2]lrT2Q0rT3DHrT3_Q
1605 !!2oWr;Zr]k2k^t!;YaP!<)$X!<)$X!<)$W!!30&!WD-R!!E>ak2k^`!<)$L!<)$X!<)$L!<;0^
1606 jlZ49r;llYo`4sPpAb3p!<)$Xk5PDb!<D9EjlQ%5!!3&[qZ$Tsp]19Sq>c$~>
1607 p&P'QnGrOLnGrOLklC\DoDepn!!)uZrW!$$!!!&l!<)$N!!**#rT4%Z!!2]lrT2Q0rT3DHrT3_Q
1608 !!2oWr;Zr]k2k^t!;YaP!<)$X!<)$X!<)$W!!30&!WD-R!!E>ak2k^`!<)$L!<)$X!<)$L!<;0^
1609 jlZ49r;llYo`4sPpAb3p!<)$Xk5PDb!<D9EjlQ%5!!3&[qZ$Tsp]19Sq>c$~>
1610 p&P'QnGrOLnGrOLklC\DoDepn!!)uZrW!$$!!!&l!<)$N!!**#rT4%Z!!2]lrT2Q0rT3DHrT3_Q
1611 !!2oWr;Zr]k2k^t!;YaP!<)$X!<)$X!<)$W!!30&!WD-R!!E>ak2k^`!<)$L!<)$X!<)$L!<;0^
1612 jlZ49r;llYo`4sPpAb3p!<)$Xk5PDb!<D9EjlQ%5!!3&[qZ$Tsp]19Sq>c$~>
1613 p&P'Qo)Jdl!<)$Q!!E<&!!*)ujn\rW!V??n!<<0!jo,5[!VHEmk5OKB!!!&m!!!&u!<)$T!!!&r
1614 !<)$Q!!E<&!!*)ujm`<N!TjC\jm<'Hjn/WLjo#/]jlY[do`,!Sr8dt?jnSoTjo#2Xjo#2Xjno,Y
1615 !<<3"jn/TRjSn9"!<)$L!<)$X!<)$L!<)'V!<3)u!<*#tjn\rW!W<#sjn/WQjT+B?k5>8^jlY[d
1616 nGrOLnGrOLq>c$~>
1617 p&P'Qo)Jdl!<)$Q!!E<&!!*)ujn\rW!V??n!<<0!jo,5[!VHEmk5OKB!!!&m!!!&u!<)$T!!!&r
1618 !<)$Q!!E<&!!*)ujm`<N!TjC\jm<'Hjn/WLjo#/]jlY[do`,!Sr8dt?jnSoTjo#2Xjo#2Xjno,Y
1619 !<<3"jn/TRjSn9"!<)$L!<)$X!<)$L!<)'V!<3)u!<*#tjn\rW!W<#sjn/WQjT+B?k5>8^jlY[d
1620 nGrOLnGrOLq>c$~>
1621 p&P'Qo)Jdl!<)$Q!!E<&!!*)ujn\rW!V??n!<<0!jo,5[!VHEmk5OKB!!!&m!!!&u!<)$T!!!&r
1622 !<)$Q!!E<&!!*)ujm`<N!TjC\jm<'Hjn/WLjo#/]jlY[do`,!Sr8dt?jnSoTjo#2Xjo#2Xjno,Y
1623 !<<3"jn/TRjSn9"!<)$L!<)$X!<)$L!<)'V!<3)u!<*#tjn\rW!W<#sjn/WQjT+B?k5>8^jlY[d
1624 nGrOLnGrOLq>c$~>
1625 q#CBqqZ-<N"6Se/k4J`KjT=T+k546?k555Z!<<,qjo+99jo#2Zk5XNCk3qC3k4o#Rjo"9@jT4N*
1626 o`4aJ!p8V,roO1Bs6'1Xr;lisrrMQgrT3MK!!2rsp#Z,PrT<nUpZ2G<jo#2XjnSoTjn/WPjn\rW
1627 !W<#ljT+HA!<3)[!<)$L!<)$T!;PXVk2cI%r;Zfuq>fsF!9X(WrT4"?rT3tXroF.@q#L$J"6S\F
1628 !VZTfjT+B?jT=T+ja[~>
1629 q#CBqqZ-<N"6Se/k4J`KjT=T+k546?k555Z!<<,qjo+99jo#2Zk5XNCk3qC3k4o#Rjo"9@jT4N*
1630 o`4aJ!p8V,roO1Bs6'1Xr;lisrrMQgrT3MK!!2rsp#Z,PrT<nUpZ2G<jo#2XjnSoTjn/WPjn\rW
1631 !W<#ljT+HA!<3)[!<)$L!<)$T!;PXVk2cI%r;Zfuq>fsF!9X(WrT4"?rT3tXroF.@q#L$J"6S\F
1632 !VZTfjT+B?jT=T+ja[~>
1633 q#CBqqZ-<N"6Se/k4J`KjT=T+k546?k555Z!<<,qjo+99jo#2Zk5XNCk3qC3k4o#Rjo"9@jT4N*
1634 o`4aJ!p8V,roO1Bs6'1Xr;lisrrMQgrT3MK!!2rsp#Z,PrT<nUpZ2G<jo#2XjnSoTjn/WPjn\rW
1635 !W<#ljT+HA!<3)[!<)$L!<)$T!;PXVk2cI%r;Zfuq>fsF!9X(WrT4"?rT3tXroF.@q#L$J"6S\F
1636 !VZTfjT+B?jT=T+ja[~>
1637 nc8@E"6S_-k4J`CjT4H)q#L?S#3P%0jQ,F`q;qPTlfA0.k5,,Z!<DrWrT=(?!!2or!!3'!o]6/:
1638 jlQI'q#L<nrW)oun,WFKklCG=!9X4[rT<nUp#Z,P!9F.@!!2orrT+%[!W;uu!W2rrjnJiU!<<,n
1639 jT+HA!<*#[!<)$L!<)$V!!**#n`BZK!!2rsn)XT2k5,,Z!<E)[rT44Dk2k_'!<)$T!:o4Ok4nuW
1640 !WE)ujo=E5ja[~>
1641 nc8@E"6S_-k4J`CjT4H)q#L?S#3P%0jQ,F`q;qPTlfA0.k5,,Z!<DrWrT=(?!!2or!!3'!o]6/:
1642 jlQI'q#L<nrW)oun,WFKklCG=!9X4[rT<nUp#Z,P!9F.@!!2orrT+%[!W;uu!W2rrjnJiU!<<,n
1643 jT+HA!<*#[!<)$L!<)$V!!**#n`BZK!!2rsn)XT2k5,,Z!<E)[rT44Dk2k_'!<)$T!:o4Ok4nuW
1644 !WE)ujo=E5ja[~>
1645 nc8@E"6S_-k4J`CjT4H)q#L?S#3P%0jQ,F`q;qPTlfA0.k5,,Z!<DrWrT=(?!!2or!!3'!o]6/:
1646 jlQI'q#L<nrW)oun,WFKklCG=!9X4[rT<nUp#Z,P!9F.@!!2orrT+%[!W;uu!W2rrjnJiU!<<,n
1647 jT+HA!<*#[!<)$L!<)$V!!**#n`BZK!!2rsn)XT2k5,,Z!<E)[rT44Dk2k_'!<)$T!:o4Ok4nuW
1648 !WE)ujo=E5ja[~>
1649 nc8@ErT<bQq;hV;p>u)MroF.BrT4"=roF:Dk2tder;c*Dq#L?S!p&J)rT=(?o`4gL!9F"<s5jCG
1650 joP;Yr;lis!s&H(!V$0gjlld<jo#2Xk4o#Wk549?k5XQA!<)$T!<)$P!<)$P!;5IP!!<6'!<M9^
1651 rT3PLrT3hTn`BEDs5a7CroF.Bo]>lKr8mq?"6J\,jo#2XjT#>\!!!'!!<;3Qjn/WNjT4N)qW._<
1652 roJY~>
1653 nc8@ErT<bQq;hV;p>u)MroF.BrT4"=roF:Dk2tder;c*Dq#L?S!p&J)rT=(?o`4gL!9F"<s5jCG
1654 joP;Yr;lis!s&H(!V$0gjlld<jo#2Xk4o#Wk549?k5XQA!<)$T!<)$P!<)$P!;5IP!!<6'!<M9^
1655 rT3PLrT3hTn`BEDs5a7CroF.Bo]>lKr8mq?"6J\,jo#2XjT#>\!!!'!!<;3Qjn/WNjT4N)qW._<
1656 roJY~>
1657 nc8@ErT<bQq;hV;p>u)MroF.BrT4"=roF:Dk2tder;c*Dq#L?S!p&J)rT=(?o`4gL!9F"<s5jCG
1658 joP;Yr;lis!s&H(!V$0gjlld<jo#2Xk4o#Wk549?k5XQA!<)$T!<)$P!<)$P!;5IP!!<6'!<M9^
1659 rT3PLrT3hTn`BEDs5a7CroF.Bo]>lKr8mq?"6J\,jo#2XjT#>\!!!'!!<;3Qjn/WNjT4N)qW._<
1660 roJY~>
1661 pAb?t!!*'"k4n$=k2lR(o`4sP!9Wk6rW!*&!!*'"k5"-<jS@p9!!)0Hjo,5`!<<-#!9X+=roX7B
1662 !TrM=!!NB'!9NA*p>l>;jo+?:!;-B`!!)0\jmE*P!<<-#!9X%;!9X4[!9a@Dq#LBT!9X.>r;Zi[
1663 roO+Z"T\T(!!)0\jo5;\!W)j$!<<,^jlY\$!!NB'!<<,^p>u5QquQ*`"T\T(!!)0\jo5;\!V??l
1664 k5OKA!!NB'!<<,^o&]NErT+%Ao&]iN"T\T(!!)0Tjo#/]k2k^equ?d!!!*#[!9Eh7q>^["!!*'"
1665 k3qD^~>
1666 pAb?t!!*'"k4n$=k2lR(o`4sP!9Wk6rW!*&!!*'"k5"-<jS@p9!!)0Hjo,5`!<<-#!9X+=roX7B
1667 !TrM=!!NB'!9NA*p>l>;jo+?:!;-B`!!)0\jmE*P!<<-#!9X%;!9X4[!9a@Dq#LBT!9X.>r;Zi[
1668 roO+Z"T\T(!!)0\jo5;\!W)j$!<<,^jlY\$!!NB'!<<,^p>u5QquQ*`"T\T(!!)0\jo5;\!V??l
1669 k5OKA!!NB'!<<,^o&]NErT+%Ao&]iN"T\T(!!)0Tjo#/]k2k^equ?d!!!*#[!9Eh7q>^["!!*'"
1670 k3qD^~>
1671 pAb?t!!*'"k4n$=k2lR(o`4sP!9Wk6rW!*&!!*'"k5"-<jS@p9!!)0Hjo,5`!<<-#!9X+=roX7B
1672 !TrM=!!NB'!9NA*p>l>;jo+?:!;-B`!!)0\jmE*P!<<-#!9X%;!9X4[!9a@Dq#LBT!9X.>r;Zi[
1673 roO+Z"T\T(!!)0\jo5;\!W)j$!<<,^jlY\$!!NB'!<<,^p>u5QquQ*`"T\T(!!)0\jo5;\!V??l
1674 k5OKA!!NB'!<<,^o&]NErT+%Ao&]iN"T\T(!!)0Tjo#/]k2k^equ?d!!!*#[!9Eh7q>^["!!*'"
1675 k3qD^~>
1676 `;fl=aoDDBl2UebP5tO^li7"dJH56@!!2'Z!!1sWrW*!#dK"d~>
1677 `;fl=aoDDBl2UebP5tO^li7"dJH56@!!2'Z!!1sWrW*!#dK"d~>
1678 `;fl=aoDDBl2UebP5tO^li7"dJH56@!!2'Z!!1sWrW*!#dK"d~>
1679 kPtS`o)JakTE"rmirB&[YQ4V&rr<$"qZ$TshuE`XnGiOirVup!`rH)?bQ%VDb5hJAdK"d~>
1680 kPtS`o)JakTE"rmirB&[YQ4V&rr<$"qZ$TshuE`XnGiOirVup!`rH)?bQ%VDb5hJAdK"d~>
1681 kPtS`o)JakTE"rmirB&[YQ4V&rr<$"qZ$TshuE`XnGiOirVup!`rH)?bQ%VDb5hJAdK"d~>
1682 nc/Xjo`+smo`+smm/R+eq#CBqdf9@Kq#CBqq#CBqqu?]tj8]/\^An67p&P$lpAb0oo`+smnGiXl
1683 !!!&l!!!&k!!!&q!!!&S!!<6%!!20]!!2Zk!!2fo!!2He!!2lq!!2?b!s&B&!Ta:]!Ug#=~>
1684 nc/Xjo`+smo`+smm/R+eq#CBqdf9@Kq#CBqq#CBqqu?]tj8]/\^An67p&P$lpAb0oo`+smnGiXl
1685 !!!&l!!!&k!!!&q!!!&S!!<6%!!20]!!2Zk!!2fo!!2He!!2lq!!2?b!s&B&!Ta:]!Ug#=~>
1686 nc/Xjo`+smo`+smm/R+eq#CBqdf9@Kq#CBqq#CBqqu?]tj8]/\^An67p&P$lpAb0oo`+smnGiXl
1687 !!!&l!!!&k!!!&q!!!&S!!<6%!!20]!!2Zk!!2fo!!2He!!2lq!!2?b!s&B&!Ta:]!Ug#=~>
1688 df9@KJH3(Xr;lHh!!.WNg&M*Rd/X7L!W`>M!.Y~>
1689 df9@KJH3(Xr;lHh!!.WNg&M*Rd/X7L!W`>M!.Y~>
1690 df9@KJH3(Xr;lHh!!.WNg&M*Rd/X7L!W`>M!.Y~>
1691 !!.WNk5bG]JH4p7r;hHLdf9@Kn,WCfoDnjkp&KU~>
1692 !!.WNk5bG]JH4p7r;hHLdf9@Kn,WCfoDnjkp&KU~>
1693 !!.WNk5bG]JH4p7r;hHLdf9@Kn,WCfoDnjkp&KU~>
1694 rrIZNkQ(P^JH50>rrN#tr;hHLcN!qGoDngjoDnjkp&KU~>
1695 rrIZNkQ(P^JH50>rrN#tr;hHLcN!qGoDngjoDnjkp&KU~>
1696 rrIZNkQ(P^JH50>rrN#tr;hHLcN!qGoDngjoDnjkp&KU~>
1697 !WiB'kl:\a^&S-6`;oi;p&G'n[/^1-_Z9W9li7"dJH59A!!2ip!!2Qhr;lQkr;lTlJ,~>
1698 !WiB'kl:\a^&S-6`;oi;p&G'n[/^1-_Z9W9li7"dJH59A!!2ip!!2Qhr;lQkr;lTlJ,~>
1699 !WiB'kl:\a^&S-6`;oi;p&G'n[/^1-_Z9W9li7"dJH59A!!2ip!!2Qhr;lQkr;lTlJ,~>
1700 rW.QMklCY_JH4p7r;hHL_#XE7o`4pkp&KU~>
1701 rW.QMklCY_JH4p7r;hHL_#XE7o`4pkp&KU~>
1702 rW.QMklCY_JH4p7r;hHL_#XE7o`4pkp&KU~>
1703 %%EndData
1704 showpage
1705 %%Trailer
1706 end
1707 %%EOF
0 %!PS-Adobe-2.0 EPSF-2.0
1 %%Title: /home/michael/i3/docs/GPN-2009-06-27/xserver_konzept.dia
2 %%Creator: Dia v0.96.1
3 %%CreationDate: Mon Jun 15 22:27:54 2009
4 %%For: michael
5 %%Orientation: Portrait
6 %%Magnification: 1.0000
7 %%BoundingBox: 0 0 937 517
8 %%BeginSetup
9 %%EndSetup
10 %%EndComments
11 %%BeginProlog
12 [ /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
13 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
14 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
15 /.notdef /.notdef /space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright
16 /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash /zero /one
17 /two /three /four /five /six /seven /eight /nine /colon /semicolon
18 /less /equal /greater /question /at /A /B /C /D /E
19 /F /G /H /I /J /K /L /M /N /O
20 /P /Q /R /S /T /U /V /W /X /Y
21 /Z /bracketleft /backslash /bracketright /asciicircum /underscore /quoteleft /a /b /c
22 /d /e /f /g /h /i /j /k /l /m
23 /n /o /p /q /r /s /t /u /v /w
24 /x /y /z /braceleft /bar /braceright /asciitilde /.notdef /.notdef /.notdef
25 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
26 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
27 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
28 /space /exclamdown /cent /sterling /currency /yen /brokenbar /section /dieresis /copyright
29 /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron /degree /plusminus /twosuperior /threesuperior
30 /acute /mu /paragraph /periodcentered /cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf
31 /threequarters /questiondown /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla
32 /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde
33 /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash /Ugrave /Uacute /Ucircumflex
34 /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring
35 /ae /ccedilla /egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis
36 /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide /oslash /ugrave
37 /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] /isolatin1encoding exch def
38 /cp {closepath} bind def
39 /c {curveto} bind def
40 /f {fill} bind def
41 /a {arc} bind def
42 /ef {eofill} bind def
43 /ex {exch} bind def
44 /gr {grestore} bind def
45 /gs {gsave} bind def
46 /sa {save} bind def
47 /rs {restore} bind def
48 /l {lineto} bind def
49 /m {moveto} bind def
50 /rm {rmoveto} bind def
51 /n {newpath} bind def
52 /s {stroke} bind def
53 /sh {show} bind def
54 /slc {setlinecap} bind def
55 /slj {setlinejoin} bind def
56 /slw {setlinewidth} bind def
57 /srgb {setrgbcolor} bind def
58 /rot {rotate} bind def
59 /sc {scale} bind def
60 /sd {setdash} bind def
61 /ff {findfont} bind def
62 /sf {setfont} bind def
63 /scf {scalefont} bind def
64 /sw {stringwidth pop} bind def
65 /tr {translate} bind def
66
67 /ellipsedict 8 dict def
68 ellipsedict /mtrx matrix put
69 /ellipse
70 { ellipsedict begin
71 /endangle exch def
72 /startangle exch def
73 /yrad exch def
74 /xrad exch def
75 /y exch def
76 /x exch def /savematrix mtrx currentmatrix def
77 x y tr xrad yrad sc
78 0 0 1 startangle endangle arc
79 savematrix setmatrix
80 end
81 } def
82
83 /mergeprocs {
84 dup length
85 3 -1 roll
86 dup
87 length
88 dup
89 5 1 roll
90 3 -1 roll
91 add
92 array cvx
93 dup
94 3 -1 roll
95 0 exch
96 putinterval
97 dup
98 4 2 roll
99 putinterval
100 } bind def
101 /dpi_x 300 def
102 /dpi_y 300 def
103 /conicto {
104 /to_y exch def
105 /to_x exch def
106 /conic_cntrl_y exch def
107 /conic_cntrl_x exch def
108 currentpoint
109 /p0_y exch def
110 /p0_x exch def
111 /p1_x p0_x conic_cntrl_x p0_x sub 2 3 div mul add def
112 /p1_y p0_y conic_cntrl_y p0_y sub 2 3 div mul add def
113 /p2_x p1_x to_x p0_x sub 1 3 div mul add def
114 /p2_y p1_y to_y p0_y sub 1 3 div mul add def
115 p1_x p1_y p2_x p2_y to_x to_y curveto
116 } bind def
117 /start_ol { gsave 1.1 dpi_x div dup scale} bind def
118 /end_ol { closepath fill grestore } bind def
119 28.346000 -28.346000 scale
120 -3.500000 -22.300000 translate
121 %%EndProlog
122
123
124 0.100000 slw
125 [] 0 sd
126 [] 0 sd
127 0 slj
128 1.000000 1.000000 1.000000 srgb
129 n 7.300000 4.112500 m 7.300000 9.862500 l 24.300000 9.862500 l 24.300000 4.112500 l f
130 n 7.300000 4.362500 m 7.300000 4.362500 0.250000 0.250000 180.000000 270.000000 ellipse f
131 n 24.300000 4.362500 m 24.300000 4.362500 0.250000 0.250000 270.000000 360.000000 ellipse f
132 n 7.050000 4.362500 m 7.050000 9.612500 l 24.550000 9.612500 l 24.550000 4.362500 l f
133 n 7.300000 9.612500 m 7.300000 9.612500 0.250000 0.250000 90.000000 180.000000 ellipse f
134 n 24.300000 9.612500 m 24.300000 9.612500 0.250000 0.250000 0.000000 90.000000 ellipse f
135 0.000000 0.000000 0.000000 srgb
136 n 7.300000 4.112500 m 24.300000 4.112500 l s
137 n 7.300000 9.862500 m 24.300000 9.862500 l s
138 n 7.300000 4.362500 0.250000 0.250000 180.000000 270.000000 ellipse s
139 n 24.300000 4.362500 0.250000 0.250000 270.000000 360.000000 ellipse s
140 n 7.050000 4.362500 m 7.050000 9.612500 l s
141 n 24.550000 4.362500 m 24.550000 9.612500 l s
142 n 7.300000 9.612500 0.250000 0.250000 90.000000 180.000000 ellipse s
143 n 24.300000 9.612500 0.250000 0.250000 0.000000 90.000000 ellipse s
144 0.100000 slw
145 [] 0 sd
146 [] 0 sd
147 0 slj
148 0.945098 0.247059 0.247059 srgb
149 n 3.800000 17.250000 m 3.800000 22.250000 l 9.500000 22.250000 l 9.500000 17.250000 l f
150 n 3.800000 17.500000 m 3.800000 17.500000 0.250000 0.250000 180.000000 270.000000 ellipse f
151 n 9.500000 17.500000 m 9.500000 17.500000 0.250000 0.250000 270.000000 360.000000 ellipse f
152 n 3.550000 17.500000 m 3.550000 22.000000 l 9.750000 22.000000 l 9.750000 17.500000 l f
153 n 3.800000 22.000000 m 3.800000 22.000000 0.250000 0.250000 90.000000 180.000000 ellipse f
154 n 9.500000 22.000000 m 9.500000 22.000000 0.250000 0.250000 0.000000 90.000000 ellipse f
155 0.000000 0.000000 0.000000 srgb
156 n 3.800000 17.250000 m 9.500000 17.250000 l s
157 n 3.800000 22.250000 m 9.500000 22.250000 l s
158 n 3.800000 17.500000 0.250000 0.250000 180.000000 270.000000 ellipse s
159 n 9.500000 17.500000 0.250000 0.250000 270.000000 360.000000 ellipse s
160 n 3.550000 17.500000 m 3.550000 22.000000 l s
161 n 9.750000 17.500000 m 9.750000 22.000000 l s
162 n 3.800000 22.000000 0.250000 0.250000 90.000000 180.000000 ellipse s
163 n 9.500000 22.000000 0.250000 0.250000 0.000000 90.000000 ellipse s
164 0.100000 slw
165 [] 0 sd
166 [] 0 sd
167 0 slj
168 1.000000 1.000000 1.000000 srgb
169 n 11.355000 17.250000 m 11.355000 22.250000 l 17.055000 22.250000 l 17.055000 17.250000 l f
170 n 11.355000 17.500000 m 11.355000 17.500000 0.250000 0.250000 180.000000 270.000000 ellipse f
171 n 17.055000 17.500000 m 17.055000 17.500000 0.250000 0.250000 270.000000 360.000000 ellipse f
172 n 11.105000 17.500000 m 11.105000 22.000000 l 17.305000 22.000000 l 17.305000 17.500000 l f
173 n 11.355000 22.000000 m 11.355000 22.000000 0.250000 0.250000 90.000000 180.000000 ellipse f
174 n 17.055000 22.000000 m 17.055000 22.000000 0.250000 0.250000 0.000000 90.000000 ellipse f
175 0.000000 0.000000 0.000000 srgb
176 n 11.355000 17.250000 m 17.055000 17.250000 l s
177 n 11.355000 22.250000 m 17.055000 22.250000 l s
178 n 11.355000 17.500000 0.250000 0.250000 180.000000 270.000000 ellipse s
179 n 17.055000 17.500000 0.250000 0.250000 270.000000 360.000000 ellipse s
180 n 11.105000 17.500000 m 11.105000 22.000000 l s
181 n 17.305000 17.500000 m 17.305000 22.000000 l s
182 n 11.355000 22.000000 0.250000 0.250000 90.000000 180.000000 ellipse s
183 n 17.055000 22.000000 0.250000 0.250000 0.000000 90.000000 ellipse s
184 0.100000 slw
185 [] 0 sd
186 [] 0 sd
187 0 slj
188 1.000000 1.000000 1.000000 srgb
189 n 21.555000 17.250000 m 21.555000 22.250000 l 27.255000 22.250000 l 27.255000 17.250000 l f
190 n 21.555000 17.500000 m 21.555000 17.500000 0.250000 0.250000 180.000000 270.000000 ellipse f
191 n 27.255000 17.500000 m 27.255000 17.500000 0.250000 0.250000 270.000000 360.000000 ellipse f
192 n 21.305000 17.500000 m 21.305000 22.000000 l 27.505000 22.000000 l 27.505000 17.500000 l f
193 n 21.555000 22.000000 m 21.555000 22.000000 0.250000 0.250000 90.000000 180.000000 ellipse f
194 n 27.255000 22.000000 m 27.255000 22.000000 0.250000 0.250000 0.000000 90.000000 ellipse f
195 0.000000 0.000000 0.000000 srgb
196 n 21.555000 17.250000 m 27.255000 17.250000 l s
197 n 21.555000 22.250000 m 27.255000 22.250000 l s
198 n 21.555000 17.500000 0.250000 0.250000 180.000000 270.000000 ellipse s
199 n 27.255000 17.500000 0.250000 0.250000 270.000000 360.000000 ellipse s
200 n 21.305000 17.500000 m 21.305000 22.000000 l s
201 n 27.505000 17.500000 m 27.505000 22.000000 l s
202 n 21.555000 22.000000 0.250000 0.250000 90.000000 180.000000 ellipse s
203 n 27.255000 22.000000 0.250000 0.250000 0.000000 90.000000 ellipse s
204 gsave 18.350000 20.562500 translate 0.035278 -0.035278 scale
205 start_ol
206 1664 1920 moveto
207 3264 1920 lineto
208 3264 0 lineto
209 1664 0 lineto
210 1664 1920 lineto
211 end_ol grestore
212 gsave 18.999387 20.562500 translate 0.035278 -0.035278 scale
213 start_ol
214 1664 1920 moveto
215 3264 1920 lineto
216 3264 0 lineto
217 1664 0 lineto
218 1664 1920 lineto
219 end_ol grestore
220 gsave 19.648773 20.562500 translate 0.035278 -0.035278 scale
221 start_ol
222 1664 1920 moveto
223 3264 1920 lineto
224 3264 0 lineto
225 1664 0 lineto
226 1664 1920 lineto
227 end_ol grestore
228 gsave 13.024625 6.975000 translate 0.035278 -0.035278 scale
229 start_ol
230 640 7232 moveto
231 1701 7232 lineto
232 3515 4544 lineto
233 5339 7232 lineto
234 6400 7232 lineto
235 4053 3759 lineto
236 6528 0 lineto
237 5477 0 lineto
238 3442 3076 lineto
239 1382 0 lineto
240 320 0 lineto
241 2914 3861 lineto
242 640 7232 lineto
243 end_ol grestore
244 gsave 13.858840 6.975000 translate 0.035278 -0.035278 scale
245 start_ol
246 512 3072 moveto
247 3136 3072 lineto
248 3136 2304 lineto
249 512 2304 lineto
250 512 3072 lineto
251 end_ol grestore
252 gsave 14.330898 6.975000 translate 0.035278 -0.035278 scale
253 start_ol
254 5312 6976 moveto
255 5312 6016 lineto
256 4759 6307 4268 6449 conicto
257 3777 6592 3320 6592 conicto
258 2525 6592 2094 6277 conicto
259 1664 5963 1664 5384 conicto
260 1664 4897 1951 4649 conicto
261 2238 4401 3038 4249 conicto
262 3627 4129 lineto
263 4720 3922 5240 3399 conicto
264 5760 2876 5760 1998 conicto
265 5760 952 5047 412 conicto
266 4334 -128 2957 -128 conicto
267 2438 -128 1852 -15 conicto
268 1267 98 640 320 conicto
269 640 1344 lineto
270 1244 995 1823 817 conicto
271 2403 640 2963 640 conicto
272 3813 640 4274 971 conicto
273 4736 1302 4736 1916 conicto
274 4736 2452 4410 2754 conicto
275 4085 3056 3342 3207 conicto
276 2749 3322 lineto
277 1635 3540 1137 4004 conicto
278 640 4469 640 5297 conicto
279 640 6256 1318 6808 conicto
280 1996 7360 3187 7360 conicto
281 3698 7360 4228 7264 conicto
282 4758 7168 5312 6976 conicto
283 end_ol grestore
284 gsave 15.162615 6.975000 translate 0.035278 -0.035278 scale
285 start_ol
286 5632 2936 moveto
287 5632 2496 lineto
288 1536 2496 lineto
289 1594 1589 2092 1114 conicto
290 2591 640 3481 640 conicto
291 3996 640 4480 768 conicto
292 4964 896 5440 1152 conicto
293 5440 320 lineto
294 4956 101 4447 -13 conicto
295 3939 -128 3416 -128 conicto
296 2106 -128 1341 627 conicto
297 576 1383 576 2672 conicto
298 576 4004 1299 4786 conicto
299 2023 5568 3250 5568 conicto
300 4351 5568 4991 4860 conicto
301 5632 4152 5632 2936 conicto
302 4736 3200 moveto
303 4726 3930 4327 4365 conicto
304 3929 4800 3271 4800 conicto
305 2527 4800 2080 4379 conicto
306 1633 3959 1565 3195 conicto
307 4736 3200 lineto
308 end_ol grestore
309 gsave 15.969355 6.975000 translate 0.035278 -0.035278 scale
310 start_ol
311 4096 4608 moveto
312 3944 4707 3765 4753 conicto
313 3587 4800 3372 4800 conicto
314 2609 4800 2200 4302 conicto
315 1792 3805 1792 2874 conicto
316 1792 0 lineto
317 896 0 lineto
318 896 5440 lineto
319 1792 5440 lineto
320 1792 4608 lineto
321 2076 5095 2531 5331 conicto
322 2986 5568 3636 5568 conicto
323 3729 5568 3841 5552 conicto
324 3954 5536 4091 5504 conicto
325 4096 4608 lineto
326 end_ol grestore
327 gsave 16.508849 6.975000 translate 0.035278 -0.035278 scale
328 start_ol
329 320 5440 moveto
330 1270 5440 lineto
331 2976 874 lineto
332 4682 5440 lineto
333 5632 5440 lineto
334 3585 0 lineto
335 2367 0 lineto
336 320 5440 lineto
337 end_ol grestore
338 gsave 17.285616 6.975000 translate 0.035278 -0.035278 scale
339 start_ol
340 5632 2936 moveto
341 5632 2496 lineto
342 1536 2496 lineto
343 1594 1589 2092 1114 conicto
344 2591 640 3481 640 conicto
345 3996 640 4480 768 conicto
346 4964 896 5440 1152 conicto
347 5440 320 lineto
348 4956 101 4447 -13 conicto
349 3939 -128 3416 -128 conicto
350 2106 -128 1341 627 conicto
351 576 1383 576 2672 conicto
352 576 4004 1299 4786 conicto
353 2023 5568 3250 5568 conicto
354 4351 5568 4991 4860 conicto
355 5632 4152 5632 2936 conicto
356 4736 3200 moveto
357 4726 3930 4327 4365 conicto
358 3929 4800 3271 4800 conicto
359 2527 4800 2080 4379 conicto
360 1633 3959 1565 3195 conicto
361 4736 3200 lineto
362 end_ol grestore
363 gsave 18.092355 6.975000 translate 0.035278 -0.035278 scale
364 start_ol
365 4096 4608 moveto
366 3944 4707 3765 4753 conicto
367 3587 4800 3372 4800 conicto
368 2609 4800 2200 4302 conicto
369 1792 3805 1792 2874 conicto
370 1792 0 lineto
371 896 0 lineto
372 896 5440 lineto
373 1792 5440 lineto
374 1792 4608 lineto
375 2076 5095 2531 5331 conicto
376 2986 5568 3636 5568 conicto
377 3729 5568 3841 5552 conicto
378 3954 5536 4091 5504 conicto
379 4096 4608 lineto
380 end_ol grestore
381 0.100000 slw
382 [] 0 sd
383 [] 0 sd
384 0 slc
385 n 6.966054 16.879747 m 12.383946 10.532753 l s
386 [] 0 sd
387 0 slj
388 0 slc
389 n 6.722588 17.164964 m 6.857064 16.622363 l 6.966054 16.879747 l 7.237355 16.946985 l ef
390 n 6.722588 17.164964 m 6.857064 16.622363 l 6.966054 16.879747 l 7.237355 16.946985 l cp s
391 [] 0 sd
392 0 slj
393 0 slc
394 n 12.627412 10.247536 m 12.492936 10.790137 l 12.383946 10.532753 l 12.112645 10.465515 l ef
395 n 12.627412 10.247536 m 12.492936 10.790137 l 12.383946 10.532753 l 12.112645 10.465515 l cp s
396 0.100000 slw
397 [] 0 sd
398 [] 0 sd
399 0 slc
400 n 14.307736 16.774161 m 15.697264 10.338339 l s
401 [] 0 sd
402 0 slj
403 0 slc
404 n 14.228595 17.140715 m 14.089747 16.599216 l 14.307736 16.774161 l 14.578486 16.704737 l ef
405 n 14.228595 17.140715 m 14.089747 16.599216 l 14.307736 16.774161 l 14.578486 16.704737 l cp s
406 [] 0 sd
407 0 slj
408 0 slc
409 n 15.776405 9.971785 m 15.915253 10.513284 l 15.697264 10.338339 l 15.426514 10.407763 l ef
410 n 15.776405 9.971785 m 15.915253 10.513284 l 15.697264 10.338339 l 15.426514 10.407763 l cp s
411 0.100000 slw
412 [] 0 sd
413 [] 0 sd
414 0 slc
415 n 24.105642 16.866122 m 19.099358 10.446378 l s
416 [] 0 sd
417 0 slj
418 0 slc
419 n 24.336247 17.161835 m 23.831631 16.921288 l 24.105642 16.866122 l 24.225916 16.613814 l ef
420 n 24.336247 17.161835 m 23.831631 16.921288 l 24.105642 16.866122 l 24.225916 16.613814 l cp s
421 [] 0 sd
422 0 slj
423 0 slc
424 n 18.868753 10.150665 m 19.373369 10.391212 l 19.099358 10.446378 l 18.979084 10.698686 l ef
425 n 18.868753 10.150665 m 19.373369 10.391212 l 19.099358 10.446378 l 18.979084 10.698686 l cp s
426 gsave 13.450000 9.125000 translate 0.035278 -0.035278 scale
427 start_ol
428 576 4992 moveto
429 1152 4992 lineto
430 1152 0 lineto
431 576 0 lineto
432 576 4992 lineto
433 end_ol grestore
434 gsave 13.692267 9.125000 translate 0.035278 -0.035278 scale
435 start_ol
436 2050 3200 moveto
437 1575 3200 1299 2832 conicto
438 1024 2464 1024 1824 conicto
439 1024 1184 1298 816 conicto
440 1572 448 2050 448 conicto
441 2521 448 2796 817 conicto
442 3072 1187 3072 1824 conicto
443 3072 2458 2796 2829 conicto
444 2521 3200 2050 3200 conicto
445 2048 3712 moveto
446 2825 3712 3268 3211 conicto
447 3712 2710 3712 1824 conicto
448 3712 941 3268 438 conicto
449 2825 -64 2048 -64 conicto
450 1268 -64 826 438 conicto
451 384 941 384 1824 conicto
452 384 2710 826 3211 conicto
453 1268 3712 2048 3712 conicto
454 end_ol grestore
455 gsave 14.226767 9.125000 translate 0.035278 -0.035278 scale
456 start_ol
457 3264 3520 moveto
458 3264 2944 lineto
459 3012 3072 2757 3136 conicto
460 2503 3200 2244 3200 conicto
461 1665 3200 1344 2838 conicto
462 1024 2477 1024 1824 conicto
463 1024 1171 1344 809 conicto
464 1665 448 2244 448 conicto
465 2503 448 2757 512 conicto
466 3012 576 3264 704 conicto
467 3264 128 lineto
468 3014 32 2745 -16 conicto
469 2477 -64 2175 -64 conicto
470 1353 -64 868 446 conicto
471 384 957 384 1824 conicto
472 384 2704 873 3208 conicto
473 1362 3712 2214 3712 conicto
474 2490 3712 2753 3664 conicto
475 3017 3616 3264 3520 conicto
476 end_ol grestore
477 gsave 14.706316 9.125000 translate 0.035278 -0.035278 scale
478 start_ol
479 2272 1856 moveto
480 1531 1856 1245 1692 conicto
481 960 1528 960 1133 conicto
482 960 818 1174 633 conicto
483 1389 448 1757 448 conicto
484 2265 448 2572 796 conicto
485 2880 1144 2880 1722 conicto
486 2880 1856 lineto
487 2272 1856 lineto
488 3456 2092 moveto
489 3456 0 lineto
490 2880 0 lineto
491 2880 576 lineto
492 2674 248 2366 92 conicto
493 2058 -64 1612 -64 conicto
494 1049 -64 716 246 conicto
495 384 557 384 1078 conicto
496 384 1686 795 1995 conicto
497 1207 2304 2023 2304 conicto
498 2880 2304 lineto
499 2880 2358 lineto
500 2880 2760 2605 2980 conicto
501 2330 3200 1832 3200 conicto
502 1516 3200 1216 3120 conicto
503 917 3040 640 2880 conicto
504 640 3456 lineto
505 969 3584 1278 3648 conicto
506 1588 3712 1882 3712 conicto
507 2674 3712 3065 3310 conicto
508 3456 2908 3456 2092 conicto
509 end_ol grestore
510 gsave 15.240816 9.125000 translate 0.035278 -0.035278 scale
511 start_ol
512 576 4992 moveto
513 1152 4992 lineto
514 1152 0 lineto
515 576 0 lineto
516 576 4992 lineto
517 end_ol grestore
518 gsave 15.483083 9.125000 translate 0.035278 -0.035278 scale
519 start_ol
520 3584 2195 moveto
521 3584 0 lineto
522 3008 0 lineto
523 3008 2176 lineto
524 3008 2690 2806 2945 conicto
525 2604 3200 2199 3200 conicto
526 1713 3200 1432 2893 conicto
527 1152 2586 1152 2056 conicto
528 1152 0 lineto
529 576 0 lineto
530 576 4992 lineto
531 1152 4992 lineto
532 1152 3072 lineto
533 1365 3394 1654 3553 conicto
534 1943 3712 2321 3712 conicto
535 2945 3712 3264 3327 conicto
536 3584 2942 3584 2195 conicto
537 end_ol grestore
538 gsave 16.037559 9.125000 translate 0.035278 -0.035278 scale
539 start_ol
540 2050 3200 moveto
541 1575 3200 1299 2832 conicto
542 1024 2464 1024 1824 conicto
543 1024 1184 1298 816 conicto
544 1572 448 2050 448 conicto
545 2521 448 2796 817 conicto
546 3072 1187 3072 1824 conicto
547 3072 2458 2796 2829 conicto
548 2521 3200 2050 3200 conicto
549 2048 3712 moveto
550 2825 3712 3268 3211 conicto
551 3712 2710 3712 1824 conicto
552 3712 941 3268 438 conicto
553 2825 -64 2048 -64 conicto
554 1268 -64 826 438 conicto
555 384 941 384 1824 conicto
556 384 2710 826 3211 conicto
557 1268 3712 2048 3712 conicto
558 end_ol grestore
559 gsave 16.572059 9.125000 translate 0.035278 -0.035278 scale
560 start_ol
561 2944 3520 moveto
562 2944 2944 lineto
563 2690 3072 2417 3136 conicto
564 2144 3200 1851 3200 conicto
565 1406 3200 1183 3066 conicto
566 960 2932 960 2664 conicto
567 960 2459 1123 2342 conicto
568 1286 2226 1778 2121 conicto
569 1988 2076 lineto
570 2611 1942 2873 1697 conicto
571 3136 1453 3136 1016 conicto
572 3136 517 2739 226 conicto
573 2342 -64 1647 -64 conicto
574 1358 -64 1044 -16 conicto
575 731 32 384 128 conicto
576 384 768 lineto
577 717 608 1040 528 conicto
578 1363 448 1679 448 conicto
579 2103 448 2331 588 conicto
580 2560 728 2560 982 conicto
581 2560 1218 2392 1343 conicto
582 2224 1469 1655 1585 conicto
583 1442 1633 lineto
584 882 1749 633 1989 conicto
585 384 2229 384 2648 conicto
586 384 3158 748 3435 conicto
587 1112 3712 1781 3712 conicto
588 2112 3712 2404 3664 conicto
589 2697 3616 2944 3520 conicto
590 end_ol grestore
591 gsave 17.026629 9.125000 translate 0.035278 -0.035278 scale
592 start_ol
593 1152 4608 moveto
594 1152 3584 lineto
595 2368 3584 lineto
596 2368 3136 lineto
597 1152 3136 lineto
598 1152 1197 lineto
599 1152 761 1272 636 conicto
600 1393 512 1762 512 conicto
601 2368 512 lineto
602 2368 0 lineto
603 1762 0 lineto
604 1088 0 832 258 conicto
605 576 516 576 1197 conicto
606 576 3136 lineto
607 128 3136 lineto
608 128 3584 lineto
609 576 3584 lineto
610 576 4608 lineto
611 1152 4608 lineto
612 end_ol grestore
613 gsave 17.368802 9.125000 translate 0.035278 -0.035278 scale
614 start_ol
615 768 832 moveto
616 1408 832 lineto
617 1408 0 lineto
618 768 0 lineto
619 768 832 lineto
620 768 3392 moveto
621 1408 3392 lineto
622 1408 2560 lineto
623 768 2560 lineto
624 768 3392 lineto
625 end_ol grestore
626 gsave 17.663523 9.125000 translate 0.035278 -0.035278 scale
627 start_ol
628 2110 4416 moveto
629 1601 4416 1344 3920 conicto
630 1088 3425 1088 2430 conicto
631 1088 1439 1344 943 conicto
632 1601 448 2110 448 conicto
633 2623 448 2879 943 conicto
634 3136 1439 3136 2430 conicto
635 3136 3425 2879 3920 conicto
636 2623 4416 2110 4416 conicto
637 2112 4928 moveto
638 2921 4928 3348 4288 conicto
639 3776 3649 3776 2430 conicto
640 3776 1215 3348 575 conicto
641 2921 -64 2112 -64 conicto
642 1303 -64 875 575 conicto
643 448 1215 448 2430 conicto
644 448 3649 875 4288 conicto
645 1303 4928 2112 4928 conicto
646 end_ol grestore
647 gsave 5.180219 19.900000 translate 0.035278 -0.035278 scale
648 start_ol
649 1664 3328 moveto
650 1664 3008 lineto
651 1268 3008 lineto
652 1059 3008 977 2926 conicto
653 896 2845 896 2633 conicto
654 896 2432 lineto
655 1536 2432 lineto
656 1536 2112 lineto
657 896 2112 lineto
658 896 0 lineto
659 512 0 lineto
660 512 2112 lineto
661 128 2112 lineto
662 128 2432 lineto
663 512 2432 lineto
664 512 2591 lineto
665 512 2976 694 3152 conicto
666 876 3328 1272 3328 conicto
667 1664 3328 lineto
668 end_ol grestore
669 gsave 5.385023 19.900000 translate 0.035278 -0.035278 scale
670 start_ol
671 384 2432 moveto
672 768 2432 lineto
673 768 0 lineto
674 384 0 lineto
675 384 2432 lineto
676 384 3328 moveto
677 768 3328 lineto
678 768 2816 lineto
679 384 2816 lineto
680 384 3328 lineto
681 end_ol grestore
682 gsave 5.547369 19.900000 translate 0.035278 -0.035278 scale
683 start_ol
684 1792 2112 moveto
685 1725 2145 1645 2160 conicto
686 1566 2176 1470 2176 conicto
687 1131 2176 949 1944 conicto
688 768 1712 768 1277 conicto
689 768 0 lineto
690 384 0 lineto
691 384 2432 lineto
692 768 2432 lineto
693 768 2048 lineto
694 894 2275 1096 2385 conicto
695 1298 2496 1588 2496 conicto
696 1629 2496 1679 2496 conicto
697 1729 2496 1790 2496 conicto
698 1792 2112 lineto
699 end_ol grestore
700 gsave 5.787140 19.900000 translate 0.035278 -0.035278 scale
701 start_ol
702 1984 2368 moveto
703 1984 1984 lineto
704 1812 2080 1627 2128 conicto
705 1442 2176 1244 2176 conicto
706 942 2176 791 2083 conicto
707 640 1990 640 1804 conicto
708 640 1662 750 1581 conicto
709 861 1500 1196 1427 conicto
710 1339 1397 lineto
711 1759 1305 1935 1138 conicto
712 2112 972 2112 673 conicto
713 2112 333 1844 134 conicto
714 1576 -64 1108 -64 conicto
715 913 -64 701 -16 conicto
716 490 32 256 128 conicto
717 256 512 lineto
718 481 384 699 320 conicto
719 918 256 1132 256 conicto
720 1419 256 1573 355 conicto
721 1728 455 1728 636 conicto
722 1728 804 1614 893 conicto
723 1500 982 1113 1065 conicto
724 968 1097 lineto
725 591 1175 423 1336 conicto
726 256 1498 256 1780 conicto
727 256 2123 501 2309 conicto
728 747 2496 1199 2496 conicto
729 1423 2496 1620 2464 conicto
730 1817 2432 1984 2368 conicto
731 end_ol grestore
732 gsave 6.089352 19.900000 translate 0.035278 -0.035278 scale
733 start_ol
734 768 3136 moveto
735 768 2432 lineto
736 1600 2432 lineto
737 1600 2112 lineto
738 768 2112 lineto
739 768 788 lineto
740 768 490 850 405 conicto
741 933 320 1185 320 conicto
742 1600 320 lineto
743 1600 0 lineto
744 1185 0 lineto
745 730 0 557 170 conicto
746 384 340 384 788 conicto
747 384 2112 lineto
748 64 2112 lineto
749 64 2432 lineto
750 384 2432 lineto
751 384 3136 lineto
752 768 3136 lineto
753 end_ol grestore
754 gsave 6.316637 19.900000 translate 0.035278 -0.035278 scale
755 start_ol
756 end_ol grestore
757 gsave 6.501457 19.900000 translate 0.035278 -0.035278 scale
758 start_ol
759 2176 2368 moveto
760 2176 1984 lineto
761 2010 2080 1843 2128 conicto
762 1676 2176 1506 2176 conicto
763 1125 2176 914 1924 conicto
764 704 1672 704 1216 conicto
765 704 760 914 508 conicto
766 1125 256 1506 256 conicto
767 1676 256 1843 304 conicto
768 2010 352 2176 448 conicto
769 2176 64 lineto
770 2009 0 1830 -32 conicto
771 1652 -64 1450 -64 conicto
772 902 -64 579 282 conicto
773 256 628 256 1216 conicto
774 256 1812 582 2154 conicto
775 908 2496 1476 2496 conicto
776 1660 2496 1835 2464 conicto
777 2011 2432 2176 2368 conicto
778 end_ol grestore
779 gsave 6.821156 19.900000 translate 0.035278 -0.035278 scale
780 start_ol
781 384 3328 moveto
782 768 3328 lineto
783 768 0 lineto
784 384 0 lineto
785 384 3328 lineto
786 end_ol grestore
787 gsave 6.983503 19.900000 translate 0.035278 -0.035278 scale
788 start_ol
789 384 2432 moveto
790 768 2432 lineto
791 768 0 lineto
792 384 0 lineto
793 384 2432 lineto
794 384 3328 moveto
795 768 3328 lineto
796 768 2816 lineto
797 384 2816 lineto
798 384 3328 lineto
799 end_ol grestore
800 gsave 7.145850 19.900000 translate 0.035278 -0.035278 scale
801 start_ol
802 2496 1352 moveto
803 2496 1152 lineto
804 704 1152 lineto
805 730 714 950 485 conicto
806 1171 256 1565 256 conicto
807 1793 256 2007 320 conicto
808 2221 384 2432 512 conicto
809 2432 128 lineto
810 2215 34 1988 -15 conicto
811 1761 -64 1527 -64 conicto
812 941 -64 598 275 conicto
813 256 615 256 1194 conicto
814 256 1793 576 2144 conicto
815 897 2496 1441 2496 conicto
816 1928 2496 2212 2188 conicto
817 2496 1881 2496 1352 conicto
818 2112 1472 moveto
819 2108 1793 1932 1984 conicto
820 1757 2176 1468 2176 conicto
821 1140 2176 943 1991 conicto
822 747 1806 717 1470 conicto
823 2112 1472 lineto
824 end_ol grestore
825 gsave 7.503012 19.900000 translate 0.035278 -0.035278 scale
826 start_ol
827 2432 1463 moveto
828 2432 0 lineto
829 2048 0 lineto
830 2048 1450 lineto
831 2048 1814 1908 1995 conicto
832 1769 2176 1490 2176 conicto
833 1155 2176 961 1959 conicto
834 768 1743 768 1370 conicto
835 768 0 lineto
836 384 0 lineto
837 384 2432 lineto
838 768 2432 lineto
839 768 2048 lineto
840 914 2273 1111 2384 conicto
841 1309 2496 1568 2496 conicto
842 1994 2496 2213 2234 conicto
843 2432 1972 2432 1463 conicto
844 end_ol grestore
845 gsave 7.872660 19.900000 translate 0.035278 -0.035278 scale
846 start_ol
847 768 3136 moveto
848 768 2432 lineto
849 1600 2432 lineto
850 1600 2112 lineto
851 768 2112 lineto
852 768 788 lineto
853 768 490 850 405 conicto
854 933 320 1185 320 conicto
855 1600 320 lineto
856 1600 0 lineto
857 1185 0 lineto
858 730 0 557 170 conicto
859 384 340 384 788 conicto
860 384 2112 lineto
861 64 2112 lineto
862 64 2432 lineto
863 384 2432 lineto
864 384 3136 lineto
865 768 3136 lineto
866 end_ol grestore
867 gsave 13.396469 19.950000 translate 0.035278 -0.035278 scale
868 start_ol
869 2176 2368 moveto
870 2176 1984 lineto
871 2010 2080 1843 2128 conicto
872 1676 2176 1506 2176 conicto
873 1125 2176 914 1924 conicto
874 704 1672 704 1216 conicto
875 704 760 914 508 conicto
876 1125 256 1506 256 conicto
877 1676 256 1843 304 conicto
878 2010 352 2176 448 conicto
879 2176 64 lineto
880 2009 0 1830 -32 conicto
881 1652 -64 1450 -64 conicto
882 902 -64 579 282 conicto
883 256 628 256 1216 conicto
884 256 1812 582 2154 conicto
885 908 2496 1476 2496 conicto
886 1660 2496 1835 2464 conicto
887 2011 2432 2176 2368 conicto
888 end_ol grestore
889 gsave 13.716168 19.950000 translate 0.035278 -0.035278 scale
890 start_ol
891 384 3328 moveto
892 768 3328 lineto
893 768 0 lineto
894 384 0 lineto
895 384 3328 lineto
896 end_ol grestore
897 gsave 13.878515 19.950000 translate 0.035278 -0.035278 scale
898 start_ol
899 384 2432 moveto
900 768 2432 lineto
901 768 0 lineto
902 384 0 lineto
903 384 2432 lineto
904 384 3328 moveto
905 768 3328 lineto
906 768 2816 lineto
907 384 2816 lineto
908 384 3328 lineto
909 end_ol grestore
910 gsave 14.040861 19.950000 translate 0.035278 -0.035278 scale
911 start_ol
912 2496 1352 moveto
913 2496 1152 lineto
914 704 1152 lineto
915 730 714 950 485 conicto
916 1171 256 1565 256 conicto
917 1793 256 2007 320 conicto
918 2221 384 2432 512 conicto
919 2432 128 lineto
920 2215 34 1988 -15 conicto
921 1761 -64 1527 -64 conicto
922 941 -64 598 275 conicto
923 256 615 256 1194 conicto
924 256 1793 576 2144 conicto
925 897 2496 1441 2496 conicto
926 1928 2496 2212 2188 conicto
927 2496 1881 2496 1352 conicto
928 2112 1472 moveto
929 2108 1793 1932 1984 conicto
930 1757 2176 1468 2176 conicto
931 1140 2176 943 1991 conicto
932 747 1806 717 1470 conicto
933 2112 1472 lineto
934 end_ol grestore
935 gsave 14.398024 19.950000 translate 0.035278 -0.035278 scale
936 start_ol
937 2432 1463 moveto
938 2432 0 lineto
939 2048 0 lineto
940 2048 1450 lineto
941 2048 1814 1908 1995 conicto
942 1769 2176 1490 2176 conicto
943 1155 2176 961 1959 conicto
944 768 1743 768 1370 conicto
945 768 0 lineto
946 384 0 lineto
947 384 2432 lineto
948 768 2432 lineto
949 768 2048 lineto
950 914 2273 1111 2384 conicto
951 1309 2496 1568 2496 conicto
952 1994 2496 2213 2234 conicto
953 2432 1972 2432 1463 conicto
954 end_ol grestore
955 gsave 14.767672 19.950000 translate 0.035278 -0.035278 scale
956 start_ol
957 768 3136 moveto
958 768 2432 lineto
959 1600 2432 lineto
960 1600 2112 lineto
961 768 2112 lineto
962 768 788 lineto
963 768 490 850 405 conicto
964 933 320 1185 320 conicto
965 1600 320 lineto
966 1600 0 lineto
967 1185 0 lineto
968 730 0 557 170 conicto
969 384 340 384 788 conicto
970 384 2112 lineto
971 64 2112 lineto
972 64 2432 lineto
973 384 2432 lineto
974 384 3136 lineto
975 768 3136 lineto
976 end_ol grestore
977 gsave 23.596469 20.050000 translate 0.035278 -0.035278 scale
978 start_ol
979 2176 2368 moveto
980 2176 1984 lineto
981 2010 2080 1843 2128 conicto
982 1676 2176 1506 2176 conicto
983 1125 2176 914 1924 conicto
984 704 1672 704 1216 conicto
985 704 760 914 508 conicto
986 1125 256 1506 256 conicto
987 1676 256 1843 304 conicto
988 2010 352 2176 448 conicto
989 2176 64 lineto
990 2009 0 1830 -32 conicto
991 1652 -64 1450 -64 conicto
992 902 -64 579 282 conicto
993 256 628 256 1216 conicto
994 256 1812 582 2154 conicto
995 908 2496 1476 2496 conicto
996 1660 2496 1835 2464 conicto
997 2011 2432 2176 2368 conicto
998 end_ol grestore
999 gsave 23.916168 20.050000 translate 0.035278 -0.035278 scale
1000 start_ol
1001 384 3328 moveto
1002 768 3328 lineto
1003 768 0 lineto
1004 384 0 lineto
1005 384 3328 lineto
1006 end_ol grestore
1007 gsave 24.078515 20.050000 translate 0.035278 -0.035278 scale
1008 start_ol
1009 384 2432 moveto
1010 768 2432 lineto
1011 768 0 lineto
1012 384 0 lineto
1013 384 2432 lineto
1014 384 3328 moveto
1015 768 3328 lineto
1016 768 2816 lineto
1017 384 2816 lineto
1018 384 3328 lineto
1019 end_ol grestore
1020 gsave 24.240861 20.050000 translate 0.035278 -0.035278 scale
1021 start_ol
1022 2496 1352 moveto
1023 2496 1152 lineto
1024 704 1152 lineto
1025 730 714 950 485 conicto
1026 1171 256 1565 256 conicto
1027 1793 256 2007 320 conicto
1028 2221 384 2432 512 conicto
1029 2432 128 lineto
1030 2215 34 1988 -15 conicto
1031 1761 -64 1527 -64 conicto
1032 941 -64 598 275 conicto
1033 256 615 256 1194 conicto
1034 256 1793 576 2144 conicto
1035 897 2496 1441 2496 conicto
1036 1928 2496 2212 2188 conicto
1037 2496 1881 2496 1352 conicto
1038 2112 1472 moveto
1039 2108 1793 1932 1984 conicto
1040 1757 2176 1468 2176 conicto
1041 1140 2176 943 1991 conicto
1042 747 1806 717 1470 conicto
1043 2112 1472 lineto
1044 end_ol grestore
1045 gsave 24.598024 20.050000 translate 0.035278 -0.035278 scale
1046 start_ol
1047 2432 1463 moveto
1048 2432 0 lineto
1049 2048 0 lineto
1050 2048 1450 lineto
1051 2048 1814 1908 1995 conicto
1052 1769 2176 1490 2176 conicto
1053 1155 2176 961 1959 conicto
1054 768 1743 768 1370 conicto
1055 768 0 lineto
1056 384 0 lineto
1057 384 2432 lineto
1058 768 2432 lineto
1059 768 2048 lineto
1060 914 2273 1111 2384 conicto
1061 1309 2496 1568 2496 conicto
1062 1994 2496 2213 2234 conicto
1063 2432 1972 2432 1463 conicto
1064 end_ol grestore
1065 gsave 24.967672 20.050000 translate 0.035278 -0.035278 scale
1066 start_ol
1067 768 3136 moveto
1068 768 2432 lineto
1069 1600 2432 lineto
1070 1600 2112 lineto
1071 768 2112 lineto
1072 768 788 lineto
1073 768 490 850 405 conicto
1074 933 320 1185 320 conicto
1075 1600 320 lineto
1076 1600 0 lineto
1077 1185 0 lineto
1078 730 0 557 170 conicto
1079 384 340 384 788 conicto
1080 384 2112 lineto
1081 64 2112 lineto
1082 64 2432 lineto
1083 384 2432 lineto
1084 384 3136 lineto
1085 768 3136 lineto
1086 end_ol grestore
1087 0.100000 slw
1088 [] 0 sd
1089 [] 0 sd
1090 0 slj
1091 1.000000 1.000000 1.000000 srgb
1092 n 29.650000 4.112500 m 29.650000 9.912500 l 36.250000 9.912500 l 36.250000 4.112500 l f
1093 n 29.650000 4.362500 m 29.650000 4.362500 0.250000 0.250000 180.000000 270.000000 ellipse f
1094 n 36.250000 4.362500 m 36.250000 4.362500 0.250000 0.250000 270.000000 360.000000 ellipse f
1095 n 29.400000 4.362500 m 29.400000 9.662500 l 36.500000 9.662500 l 36.500000 4.362500 l f
1096 n 29.650000 9.662500 m 29.650000 9.662500 0.250000 0.250000 90.000000 180.000000 ellipse f
1097 n 36.250000 9.662500 m 36.250000 9.662500 0.250000 0.250000 0.000000 90.000000 ellipse f
1098 0.000000 0.000000 0.000000 srgb
1099 n 29.650000 4.112500 m 36.250000 4.112500 l s
1100 n 29.650000 9.912500 m 36.250000 9.912500 l s
1101 n 29.650000 4.362500 0.250000 0.250000 180.000000 270.000000 ellipse s
1102 n 36.250000 4.362500 0.250000 0.250000 270.000000 360.000000 ellipse s
1103 n 29.400000 4.362500 m 29.400000 9.662500 l s
1104 n 36.500000 4.362500 m 36.500000 9.662500 l s
1105 n 29.650000 9.662500 0.250000 0.250000 90.000000 180.000000 ellipse s
1106 n 36.250000 9.662500 0.250000 0.250000 0.000000 90.000000 ellipse s
1107 gsave 30.563500 7.412500 translate 0.035278 -0.035278 scale
1108 start_ol
1109 640 4800 moveto
1110 3648 4800 lineto
1111 3648 4288 lineto
1112 1280 4288 lineto
1113 1280 2816 lineto
1114 3584 2816 lineto
1115 3584 2304 lineto
1116 1280 2304 lineto
1117 1280 512 lineto
1118 3712 512 lineto
1119 3712 0 lineto
1120 640 0 lineto
1121 640 4800 lineto
1122 end_ol grestore
1123 gsave 31.115479 7.412500 translate 0.035278 -0.035278 scale
1124 start_ol
1125 3648 3584 moveto
1126 2337 1840 lineto
1127 3712 0 lineto
1128 3011 0 lineto
1129 1958 1408 lineto
1130 898 0 lineto
1131 192 0 lineto
1132 1608 1875 lineto
1133 320 3584 lineto
1134 1023 3584 lineto
1135 1984 2307 lineto
1136 2945 3584 lineto
1137 3648 3584 lineto
1138 end_ol grestore
1139 gsave 31.632491 7.412500 translate 0.035278 -0.035278 scale
1140 start_ol
1141 1152 4608 moveto
1142 1152 3584 lineto
1143 2368 3584 lineto
1144 2368 3136 lineto
1145 1152 3136 lineto
1146 1152 1197 lineto
1147 1152 761 1272 636 conicto
1148 1393 512 1762 512 conicto
1149 2368 512 lineto
1150 2368 0 lineto
1151 1762 0 lineto
1152 1088 0 832 258 conicto
1153 576 516 576 1197 conicto
1154 576 3136 lineto
1155 128 3136 lineto
1156 128 3584 lineto
1157 576 3584 lineto
1158 576 4608 lineto
1159 1152 4608 lineto
1160 end_ol grestore
1161 gsave 31.974663 7.412500 translate 0.035278 -0.035278 scale
1162 start_ol
1163 3712 1944 moveto
1164 3712 1664 lineto
1165 1024 1664 lineto
1166 1062 1070 1389 759 conicto
1167 1716 448 2299 448 conicto
1168 2637 448 2954 528 conicto
1169 3272 608 3584 768 conicto
1170 3584 192 lineto
1171 3266 67 2931 1 conicto
1172 2597 -64 2253 -64 conicto
1173 1391 -64 887 437 conicto
1174 384 938 384 1792 conicto
1175 384 2675 860 3193 conicto
1176 1336 3712 2144 3712 conicto
1177 2869 3712 3290 3236 conicto
1178 3712 2761 3712 1944 conicto
1179 3136 2112 moveto
1180 3130 2608 2866 2904 conicto
1181 2603 3200 2169 3200 conicto
1182 1678 3200 1383 2914 conicto
1183 1088 2628 1043 2109 conicto
1184 3136 2112 lineto
1185 end_ol grestore
1186 gsave 32.511660 7.412500 translate 0.035278 -0.035278 scale
1187 start_ol
1188 3584 2195 moveto
1189 3584 0 lineto
1190 3008 0 lineto
1191 3008 2176 lineto
1192 3008 2690 2806 2945 conicto
1193 2604 3200 2199 3200 conicto
1194 1713 3200 1432 2893 conicto
1195 1152 2586 1152 2056 conicto
1196 1152 0 lineto
1197 576 0 lineto
1198 576 3584 lineto
1199 1152 3584 lineto
1200 1152 3072 lineto
1201 1365 3394 1654 3553 conicto
1202 1943 3712 2321 3712 conicto
1203 2945 3712 3264 3327 conicto
1204 3584 2942 3584 2195 conicto
1205 end_ol grestore
1206 gsave 33.066136 7.412500 translate 0.035278 -0.035278 scale
1207 start_ol
1208 2944 3520 moveto
1209 2944 2944 lineto
1210 2690 3072 2417 3136 conicto
1211 2144 3200 1851 3200 conicto
1212 1406 3200 1183 3066 conicto
1213 960 2932 960 2664 conicto
1214 960 2459 1123 2342 conicto
1215 1286 2226 1778 2121 conicto
1216 1988 2076 lineto
1217 2611 1942 2873 1697 conicto
1218 3136 1453 3136 1016 conicto
1219 3136 517 2739 226 conicto
1220 2342 -64 1647 -64 conicto
1221 1358 -64 1044 -16 conicto
1222 731 32 384 128 conicto
1223 384 768 lineto
1224 717 608 1040 528 conicto
1225 1363 448 1679 448 conicto
1226 2103 448 2331 588 conicto
1227 2560 728 2560 982 conicto
1228 2560 1218 2392 1343 conicto
1229 2224 1469 1655 1585 conicto
1230 1442 1633 lineto
1231 882 1749 633 1989 conicto
1232 384 2229 384 2648 conicto
1233 384 3158 748 3435 conicto
1234 1112 3712 1781 3712 conicto
1235 2112 3712 2404 3664 conicto
1236 2697 3616 2944 3520 conicto
1237 end_ol grestore
1238 gsave 33.520707 7.412500 translate 0.035278 -0.035278 scale
1239 start_ol
1240 576 3584 moveto
1241 1152 3584 lineto
1242 1152 0 lineto
1243 576 0 lineto
1244 576 3584 lineto
1245 576 4992 moveto
1246 1152 4992 lineto
1247 1152 4224 lineto
1248 576 4224 lineto
1249 576 4992 lineto
1250 end_ol grestore
1251 gsave 33.762974 7.412500 translate 0.035278 -0.035278 scale
1252 start_ol
1253 2050 3200 moveto
1254 1575 3200 1299 2832 conicto
1255 1024 2464 1024 1824 conicto
1256 1024 1184 1298 816 conicto
1257 1572 448 2050 448 conicto
1258 2521 448 2796 817 conicto
1259 3072 1187 3072 1824 conicto
1260 3072 2458 2796 2829 conicto
1261 2521 3200 2050 3200 conicto
1262 2048 3712 moveto
1263 2825 3712 3268 3211 conicto
1264 3712 2710 3712 1824 conicto
1265 3712 941 3268 438 conicto
1266 2825 -64 2048 -64 conicto
1267 1268 -64 826 438 conicto
1268 384 941 384 1824 conicto
1269 384 2710 826 3211 conicto
1270 1268 3712 2048 3712 conicto
1271 end_ol grestore
1272 gsave 34.297474 7.412500 translate 0.035278 -0.035278 scale
1273 start_ol
1274 3584 2195 moveto
1275 3584 0 lineto
1276 3008 0 lineto
1277 3008 2176 lineto
1278 3008 2690 2806 2945 conicto
1279 2604 3200 2199 3200 conicto
1280 1713 3200 1432 2893 conicto
1281 1152 2586 1152 2056 conicto
1282 1152 0 lineto
1283 576 0 lineto
1284 576 3584 lineto
1285 1152 3584 lineto
1286 1152 3072 lineto
1287 1365 3394 1654 3553 conicto
1288 1943 3712 2321 3712 conicto
1289 2945 3712 3264 3327 conicto
1290 3584 2942 3584 2195 conicto
1291 end_ol grestore
1292 gsave 34.851949 7.412500 translate 0.035278 -0.035278 scale
1293 start_ol
1294 2944 3520 moveto
1295 2944 2944 lineto
1296 2690 3072 2417 3136 conicto
1297 2144 3200 1851 3200 conicto
1298 1406 3200 1183 3066 conicto
1299 960 2932 960 2664 conicto
1300 960 2459 1123 2342 conicto
1301 1286 2226 1778 2121 conicto
1302 1988 2076 lineto
1303 2611 1942 2873 1697 conicto
1304 3136 1453 3136 1016 conicto
1305 3136 517 2739 226 conicto
1306 2342 -64 1647 -64 conicto
1307 1358 -64 1044 -16 conicto
1308 731 32 384 128 conicto
1309 384 768 lineto
1310 717 608 1040 528 conicto
1311 1363 448 1679 448 conicto
1312 2103 448 2331 588 conicto
1313 2560 728 2560 982 conicto
1314 2560 1218 2392 1343 conicto
1315 2224 1469 1655 1585 conicto
1316 1442 1633 lineto
1317 882 1749 633 1989 conicto
1318 384 2229 384 2648 conicto
1319 384 3158 748 3435 conicto
1320 1112 3712 1781 3712 conicto
1321 2112 3712 2404 3664 conicto
1322 2697 3616 2944 3520 conicto
1323 end_ol grestore
1324 0.100000 slw
1325 [] 0 sd
1326 [] 0 sd
1327 0 slc
1328 n 25.036797 6.990009 m 28.913203 7.009991 l s
1329 [] 0 sd
1330 0 slj
1331 0 slc
1332 n 24.661802 6.988076 m 25.163084 6.740657 l 25.036797 6.990009 l 25.160507 7.240650 l ef
1333 n 24.661802 6.988076 m 25.163084 6.740657 l 25.036797 6.990009 l 25.160507 7.240650 l cp s
1334 [] 0 sd
1335 0 slj
1336 0 slc
1337 n 29.288198 7.011924 m 28.786916 7.259343 l 28.913203 7.009991 l 28.789493 6.759350 l ef
1338 n 29.288198 7.011924 m 28.786916 7.259343 l 28.913203 7.009991 l 28.789493 6.759350 l cp s
1339 showpage
0 %
1 % © 2009 Michael Stapelberg
2 %
3 % 2009-03-12
4 %
5 \documentclass[mode=print,paper=screen,style=jefka]{powerdot}
6 \usepackage[utf8]{inputenc}
7 \usepackage{graphicx}
8 \usepackage{ngerman}
9 \usepackage{url}
10 \usepackage{listings}
11 \newcommand{\bs}{\textbackslash}
12 \pdsetup{palette=white}
13 \definecolor{darkblue}{rgb}{0,0,.6}
14 \definecolor{darkred}{rgb}{.6,0,0}
15 \definecolor{darkgreen}{rgb}{0,.6,0}
16 \definecolor{darkgray}{gray}{.3}
17 \definecolor{lightblue}{rgb}{0.97,0.99,1}
18
19 \lstloadlanguages{C}
20 \lstdefinestyle{colors}{keywordstyle={\bf\color{darkblue}}, commentstyle={\em\color{magenta}}, stringstyle={\color{darkred}},%
21 emphstyle={\color{darkgray}}}
22 \lstnewenvironment{code}{%
23 \lstset{frame=single, basicstyle=\footnotesize\ttfamily, language=C, showstringspaces=false,%
24 style=colors, numbers=left, morekeywords={xcb_get_window_attributes_cookie_t, xcb_map_request_event_t,%
25 xcb_connection_t, xcb_get_window_attributes_reply_t, window_attributes_t, xcb_intern_atom_cookie_t,%
26 xcb_intern_atom_reply_t, xcb_atom_t},%
27 moreemph={xcb_get_window_attributes_reply, xcb_get_window_attributes_unchecked, manage_window,%
28 add_ignore_event, xcb_intern_atom, xcb_intern_atom_reply, fprintf, printf, free, load_configuration,%
29 XInternAtom, exit, strlen}}
30 }{}
31 \title{i3 - an improved dynamic tiling window manager}
32 \author{sECuRE beim NoName e.V.\\
33 ~\\
34 powered by \LaTeX, of course}
35 \begin{document}
36 \maketitle
37
38 \begin{slide}{Geschichte}
39 \begin{list}{$\bullet$}{\itemsep=1em}
40 \item<1-> „All window managers suck, this one just sucks less”?
41 \item<2-> Desktop environment vs. window manager (GNOME, KDE, Xfce, …)
42 \item<3-> Stacking (e17, fluxbox, IceWM, fvwm, …) vs Tiling (dwm, wmii, xmonad, …)
43 \item<4-> dwm, awesome, xmonad, …: statisches Layout
44 \item<5-> wmii, ion: dynamisches layout
45 \item<6-> Problem an ion: tuomov (Lizenz, Kommunikation), Config, Look and feel
46 \item<7-> Probleme an wmii: Xinerama-support, Xlib, undokumentierter code, nur Spalten, keine Reihen, Kleinigkeiten (titellose Fenster)
47 \end{list}
48 \end{slide}
49
50 \begin{slide}{Screenshots!}
51 \centering
52 Drücken Sie Mod1+2 um diese Demo zu starten.
53 \end{slide}
54
55 \begin{slide}{Merkmale}
56 \begin{list}{$\bullet$}{\itemsep=1em}
57 \item<1-> gut lesbarer, dokumentierter Code. Dokumentation.
58 \item<2-> XCB anstelle von Xlib
59 \item<3-> Xinerama done right™
60 \item<4-> Spalten und Zeilen
61 \item<5-> command-mode, wie in vim
62 \item<6-> UTF-8 clean
63 \item<7-> kein Antialiasing, schlank und schnell bleiben
64 \end{list}
65 \end{slide}
66
67 \begin{slide}{Typische Kommunikation mit X}
68 \begin{list}{$\bullet$}{\itemsep=1em}
69 \item<1-> Verbindung aufbauen
70 \item<2-> Requests über die Leitung schicken (Fenster erzeugen)
71 \item<3-> Eventloop starten, reagieren (Fenster zeichnen, Eingaben, …)
72 \end{list}
73 \end{slide}
74
75 \begin{slide}{Was genau macht ein WM?}
76 \begin{list}{$\bullet$}{\itemsep=1em}
77 \item<1-> Events umlenken
78 \item<2-> Neue Fenster anzeigen/positionieren (MapRequest)
79 \item<3-> Titelleisten malen (reparenting)
80 \item<4-> Den Fokus verwalten
81 \item<5-> Mit Hints umgehen (Fenstertitel, Fullscreen, Dock, …)
82 \item<6-> Auf Benutzereingaben reagieren
83 \end{list}
84 \end{slide}
85
86 \begin{slide}{Was an X toll ist}
87 \begin{list}{$\bullet$}{\itemsep=1em}
88 \item<1-> Man hat an Window Manager gedacht (Mac OS X *hust*)
89 \item<2-> Netzwerk-transparent (debugging, xtrace)
90 \item<3-> Das Protokoll ist gut designed (Extensions möglich, simpel)
91 \end{list}
92 \end{slide}
93
94 \begin{slide}[method=direct]{Protokoll, Beispielcode}
95 \begin{code}
96 int handle_map_request(void *prophs, xcb_connection_t *conn,
97 xcb_map_request_event_t *event) {
98 xcb_get_window_attributes_cookie_t cookie;
99 xcb_get_window_attributes_reply_t *reply;
100
101 cookie = xcb_get_window_attributes_unchecked(conn, event->window);
102
103 if ((reply = xcb_get_window_attributes_reply(conn, cookie, NULL))
104 == NULL) {
105 LOG("Could not get window attributes\n");
106 return -1;
107 }
108
109 window_attributes_t wa = { TAG_VALUE };
110 wa.u.override_redirect = reply->override_redirect;
111
112 add_ignore_event(event->sequence);
113
114 manage_window(prophs, conn, event->window, wa);
115
116 return 1;
117 }
118 \end{code}
119 \end{slide}
120
121 \begin{slide}{Was an X nicht so toll ist}
122 \begin{list}{$\bullet$}{\itemsep=1em}
123 \item<1-> Einige race conditions vorhanden
124 \item<2-> Man kann nicht fein genug angeben, welche Events man gerne hätte
125 \item<3-> Xlib ist ziemlich eklig, aber es gibt ja xcb
126 \item<4-> Bugs: Keyboard state wird nicht richtig übermittelt
127 \item<5-> Ich empfehle auch: „Why X is not our ideal window system” \url{http://www.std.org/~msm/common/WhyX.pdf}
128 \end{list}
129 \end{slide}
130
131 \begin{slide}{XCB}
132 \begin{list}{$\bullet$}{\itemsep=1em}
133 \item \url{http://xcb.freedesktop.org/}
134 \item<1-> „X-protocol C-language Binding”
135 \item<2-> Klein, wartbar (aus einer Protokollbeschreibung auto-generiert)
136 \item<3-> Sinnvoll benannte Funktionsnamen und Datentypen
137 \item<4-> Threadsafe (nicht dass wir das bräuchten, aber…)
138 \item<5-> Nutzt die Asynchronität von X aus
139 \item<6-> Dokumentation? Ne, das ist was für Anfänger.
140 \item<7-> xcb-util: XCB noch mal ein bisschen gekapselt, nützliche Funktionen abstrahiert
141 \end{list}
142 \end{slide}
143
144 \begin{slide}[method=direct]{Xlib-Beispielcode}
145 \begin{code}
146 char *names[10] = {"_NET_SUPPORTED", "_NET_WM_STATE",
147 "_NET_WM_STATE_FULLSCREEN", "_NET_WM_NAME" /* ... */};
148 Atom atoms[10];
149
150 /* Get atoms */
151 for (int i = 0; i < 10; i++) {
152 atoms[i] = XInternAtom(display, names[i], 0);
153 }
154 \end{code}
155 \end{slide}
156
157 \begin{slide}[method=direct]{XCB-Beispielcode}
158 \begin{code}
159 char *names[10] = {"_NET_SUPPORTED", "_NET_WM_STATE",
160 "_NET_WM_STATE_FULLSCREEN", "_NET_WM_NAME" /* ... */};
161 xcb_intern_atom_cookie_t cookies[10];
162
163 /* Place requests for atoms as soon as possible */
164 for (int c = 0; c < 10; c++)
165 xcb_intern_atom(connection, 0, strlen(names[c]), names[c]);
166
167 /* Do other stuff here */
168 load_configuration();
169
170 /* Get atoms */
171 for (int c = 0; c < 10; c++) {
172 xcb_intern_atom_reply_t *reply =
173 xcb_intern_atom_reply(connection, cookies[c], NULL);
174 if (!reply) {
175 fprintf(stderr, "Could not get atom\n");
176 exit(-1);
177 }
178 printf("atom has ID %d\n", reply->atom);
179 free(reply);
180 }
181 \end{code}
182 \end{slide}
183
184 \begin{slide}{Xft}
185 \begin{list}{$\bullet$}{\itemsep=1em}
186 \item<1-> „X FreeType”, library um antialiased fonts zu benutzen
187 \item<2-> Benutzt man am besten mit Pango (rendert fonts) und Cairo
188 \item<3-> Keine Möglichkeit, pixel fonts zu benutzen („x core fonts”)
189 \item<4-> Was macht man (urxvt) also? Beide APIs benutzen, fallback fonts
190 \item<5-> Was machen wir (i3)? misc-fixed-*-iso10646!\\
191 ISO 10646 = Universal Character Set, selbe Zeichen wie Unicode
192 \item<6-> Fontconfig/xft soll wohl x core fonts ablösen :-(
193 \end{list}
194 \end{slide}
195
196 \begin{slide}{Ein paar Zahlen}
197 \begin{list}{$\bullet$}{\itemsep=1em}
198 \item<1-> 6118 Zeilen Code, Dokumentation, Website, READMEs
199 \item<2-> \~{} 2800 Zeilen Sourcecode
200 \item<3-> 73 KB groß (ohne debug symbols)
201 \end{list}
202 \end{slide}
203
204 \begin{slide}{Benutzen}
205 \begin{list}{$\bullet$}{\itemsep=1em}
206 \item git clone \url{git://code.stapelberg.de/i3}
207 \item Debian: cd i3; dpkg-buildpackage; sudo dpkg -i ../i3-wm*deb
208 \item non-Debian: cd i3; cat DEPENDS; make; sudo make install
209 \item in \~{}/.xsession: exec /usr/bin/i3
210 \item Siehe manpage i3(1)
211 \end{list}
212 \end{slide}
213
214 \begin{slide}{Mehr infos}
215 \begin{list}{$\bullet$}{\itemsep=1em}
216 \item git-webinterface: \url{http://code.stapelberg.de/git/i3}
217 \item Website: \url{http://i3wm.org}
218 \item IRC: \#i3 auf irc.twice-irc.de
219 \end{list}
220 \end{slide}
221
222 \end{document}
0 #
1 # xhtml11.conf
2 #
3 # Asciidoc configuration file.
4 # xhtml11 backend, generates XHTML 1.1 conformant markup.
5 #
6
7 [miscellaneous]
8 outfilesuffix=.html
9
10 [attributes]
11 basebackend=html
12 basebackend-html=
13 basebackend-xhtml11=
14
15 [replacements2]
16 # Line break.
17 (?m)^(.*)\s\+$=\1<br />
18
19 [replacements]
20 ifdef::asciidoc7compatible[]
21 # Superscripts.
22 \^(.+?)\^=<sup>\1</sup>
23 # Subscripts.
24 ~(.+?)~=<sub>\1</sub>
25 endif::asciidoc7compatible[]
26
27 [ruler-blockmacro]
28 <hr />
29
30 [pagebreak-blockmacro]
31 <div style="page-break-after:always"></div>
32
33 [blockdef-pass]
34 asciimath-style=template="asciimathblock",subs=[]
35 latexmath-style=template="latexmathblock",subs=[]
36
37 [macros]
38 # math macros.
39 # Special characters are escaped in HTML math markup.
40 (?su)[\\]?(?P<name>asciimath|latexmath):(?P<subslist>\S*?)\[(?P<passtext>.*?)(?<!\\)\]=[specialcharacters]
41 (?u)^(?P<name>asciimath|latexmath)::(?P<subslist>\S*?)(\[(?P<passtext>.*?)\])$=#[specialcharacters]
42
43 [asciimath-inlinemacro]
44 `{passtext}`
45
46 [asciimath-blockmacro]
47 <div class="mathblock{role? {role}}"{id? id="{id}"}>
48 <div class="content">
49 <div class="title">{title}</div>
50 `{passtext}`
51 </div></div>
52
53 [asciimathblock]
54 <div class="mathblock{role? {role}}"{id? id="{id}"}>
55 <div class="content">
56 <div class="title">{title}</div>
57 `|`
58 </div></div>
59
60 [latexmath-inlinemacro]
61 {passtext}
62
63 [latexmath-blockmacro]
64 <div class="mathblock{role? {role}}"{id? id="{id}"}>
65 <div class="content">
66 <div class="title">{title}</div>
67 {passtext}
68 </div></div>
69
70 [latexmathblock]
71 <div class="mathblock{role? {role}}"{id? id="{id}"}>
72 <div class="content">
73 <div class="title">{title}</div>
74 |
75 </div></div>
76
77 [image-inlinemacro]
78 <span class="image{role? {role}}">
79 <a class="image" href="{link}">
80 {data-uri%}<img src="{imagesdir=}{imagesdir?/}{target}" alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"}{title? title="{title}"} />
81 {data-uri#}<img alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"}{title? title="{title}"} src="data:image/{eval:os.path.splitext('{target}')[1][1:]};base64,
82 {data-uri#}{sys3:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join("{indir={outdir}}","{imagesdir=}","{target}")}"}" />
83 {link#}</a>
84 </span>
85
86 [image-blockmacro]
87 <div class="imageblock{style? {style}}{role? {role}}"{id? id="{id}"}{align? style="text-align:{align};"}{float? style="float:{float};"}>
88 <div class="content">
89 <a class="image" href="{link}">
90 {data-uri%}<img src="{imagesdir=}{imagesdir?/}{target}" alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"} />
91 {data-uri#}<img alt="{alt={target}}"{width? width="{width}"}{height? height="{height}"} src="data:image/{eval:os.path.splitext('{target}')[1][1:]};base64,
92 {data-uri#}{sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join("{indir={outdir}}","{imagesdir=}","{target}")}"}" />
93 {link#}</a>
94 </div>
95 <div class="title">{caption={figure-caption} {counter:figure-number}. }{title}</div>
96 </div>
97
98 [unfloat-blockmacro]
99 <div style="clear:both;"></div>
100
101 [indexterm-inlinemacro]
102 # Index term.
103 {empty}
104
105 [indexterm2-inlinemacro]
106 # Index term.
107 # Single entry index term that is visible in the primary text flow.
108 {1}
109
110 [footnote-inlinemacro]
111 # footnote:[<text>].
112 <span class="footnote"><br />[{0}]<br /></span>
113
114 [footnoteref-inlinemacro]
115 # footnoteref:[<id>], create reference to footnote.
116 {2%}<span class="footnoteref"><br /><a href="#_footnote_{1}">[{1}]</a><br /></span>
117 # footnoteref:[<id>,<text>], create footnote with ID.
118 {2#}<span class="footnote" id="_footnote_{1}"><br />[{2}]<br /></span>
119
120 [callout-inlinemacro]
121 ifndef::icons[]
122 <b>&lt;{index}&gt;</b>
123 endif::icons[]
124 ifdef::icons[]
125 ifndef::data-uri[]
126 <img src="{icon={iconsdir}/callouts/{index}.png}" alt="{index}" />
127 endif::data-uri[]
128 ifdef::data-uri[]
129 <img alt="{index}" src="data:image/png;base64,
130 {sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join("{indir={outdir}}","{icon={iconsdir}/callouts/{index}.png}")}"}" />
131 endif::data-uri[]
132 endif::icons[]
133
134 # Comment line macros.
135 [comment-inlinemacro]
136 {showcomments#}<br /><span class="comment">{passtext}</span><br />
137
138 [comment-blockmacro]
139 {showcomments#}<p><span class="comment">{passtext}</span></p>
140
141 [literal-inlinemacro]
142 # Inline literal.
143 <tt>{passtext}</tt>
144
145 # List tags.
146 [listtags-bulleted]
147 list=<div class="ulist{style? {style}}{compact-option? compact}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<ul>|</ul></div>
148 item=<li>|</li>
149 text=<p>|</p>
150
151 [listtags-numbered]
152 # The start attribute is not valid XHTML 1.1 but all browsers support it.
153 list=<div class="olist{style? {style}}{compact-option? compact}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<ol class="{style}"{start? start="{start}"}>|</ol></div>
154 item=<li>|</li>
155 text=<p>|</p>
156
157 [listtags-labeled]
158 list=<div class="dlist{compact-option? compact}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<dl>|</dl></div>
159 entry=
160 label=
161 term=<dt class="hdlist1{strong-option? strong}">|</dt>
162 item=<dd>|</dd>
163 text=<p>|</p>
164
165 [listtags-horizontal]
166 list=<div class="hdlist{compact-option? compact}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<table>{labelwidth?<col width="{labelwidth}%" />}{itemwidth?<col width="{itemwidth}%" />}|</table></div>
167 label=<td class="hdlist1{strong-option? strong}">|</td>
168 term=|<br />
169 entry=<tr>|</tr>
170 item=<td class="hdlist2">|</td>
171 text=<p style="margin-top: 0;">|</p>
172
173 [listtags-qanda]
174 list=<div class="qlist{style? {style}}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<ol>|</ol></div>
175 entry=<li>|</li>
176 label=
177 term=<p><em>|</em></p>
178 item=
179 text=<p>|</p>
180
181 [listtags-callout]
182 ifndef::icons[]
183 list=<div class="colist{style? {style}}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<ol>|</ol></div>
184 item=<li>|</li>
185 text=<p>|</p>
186 endif::icons[]
187 ifdef::icons[]
188 list=<div class="colist{style? {style}}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<table>|</table></div>
189 ifndef::data-uri[]
190 item=<tr><td><img src="{iconsdir}/callouts/{listindex}.png" alt="{listindex}" /></td><td>|</td></tr>
191 endif::data-uri[]
192 ifdef::data-uri[]
193 item=<tr><td><img alt="{listindex}" src="data:image/png;base64, {sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join("{indir={outdir}}","{icon={iconsdir}/callouts/{listindex}.png}")}"}" /></td><td>|</td></tr>
194 endif::data-uri[]
195 text=|
196 endif::icons[]
197
198 [listtags-glossary]
199 list=<div class="dlist{style? {style}}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<dl>|</dl></div>
200 label=
201 entry=
202 term=<dt>|</dt>
203 item=<dd>|</dd>
204 text=<p>|</p>
205
206 [listtags-bibliography]
207 list=<div class="ulist{style? {style}}{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<ul>|</ul></div>
208 item=<li>|</li>
209 text=<p>|</p>
210
211 [tags]
212 # Quoted text.
213 emphasis=<em>{1?<span class="{1}">}|{1?</span>}</em>
214 strong=<strong>{1?<span class="{1}">}|{1?</span>}</strong>
215 monospaced=<tt>{1?<span class="{1}">}|{1?</span>}</tt>
216 singlequoted={lsquo}{1?<span class="{1}">}|{1?</span>}{rsquo}
217 doublequoted={ldquo}{1?<span class="{1}">}|{1?</span>}{rdquo}
218 unquoted={1?<span class="{1}">}|{1?</span>}
219 superscript=<sup>{1?<span class="{1}">}|{1?</span>}</sup>
220 subscript=<sub>{1?<span class="{1}">}|{1?</span>}</sub>
221
222 ifdef::deprecated-quotes[]
223 # Override with deprecated quote attributes.
224 emphasis={role?<span class="{role}">}<em{1,2,3? style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</em>{role?</span>}
225 strong={role?<span class="{role}">}<strong{1,2,3? style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</strong>{role?</span>}
226 monospaced={role?<span class="{role}">}<tt{1,2,3? style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</tt>{role?</span>}
227 singlequoted={role?<span class="{role}">}{1,2,3?<span style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?">}{amp}#8216;|{amp}#8217;{1,2,3?</span>}{role?</span>}
228 doublequoted={role?<span class="{role}">}{1,2,3?<span style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?">}{amp}#8220;|{amp}#8221;{1,2,3?</span>}{role?</span>}
229 unquoted={role?<span class="{role}">}{1,2,3?<span style="{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}">}|{1,2,3?</span>}{role?</span>}
230 superscript={role?<span class="{role}">}<sup{1,2,3? style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</sup>{role?</span>}
231 subscript={role?<span class="{role}">}<sub{1,2,3? style="}{1?color:{1};}{2?background-color:{2};}{3?font-size:{3}em;}{1,2,3?"}>|</sub>{role?</span>}
232 endif::deprecated-quotes[]
233
234 # Inline macros
235 [http-inlinemacro]
236 <a href="{name}:{target}">{0={name}:{target}}</a>
237 [https-inlinemacro]
238 <a href="{name}:{target}">{0={name}:{target}}</a>
239 [ftp-inlinemacro]
240 <a href="{name}:{target}">{0={name}:{target}}</a>
241 [file-inlinemacro]
242 <a href="{name}:{target}">{0={name}:{target}}</a>
243 [irc-inlinemacro]
244 <a href="{name}:{target}">{0={name}:{target}}</a>
245 [mailto-inlinemacro]
246 <a href="mailto:{target}">{0={target}}</a>
247 [link-inlinemacro]
248 <a href="{target}">{0={target}}</a>
249 [callto-inlinemacro]
250 <a href="{name}:{target}">{0={target}}</a>
251 # anchor:id[text]
252 [anchor-inlinemacro]
253 <a id="{target}"></a>
254 # [[id,text]]
255 [anchor2-inlinemacro]
256 <a id="{1}"></a>
257 # [[[id]]]
258 [anchor3-inlinemacro]
259 <a id="{1}"></a>[{1}]
260 # xref:id[text]
261 [xref-inlinemacro]
262 <a href="#{target}">{0=[{target}]}</a>
263 # <<id,text>>
264 [xref2-inlinemacro]
265 <a href="#{1}">{2=[{1}]}</a>
266
267 # Special word substitution.
268 [emphasizedwords]
269 <em>{words}</em>
270 [monospacedwords]
271 <tt>{words}</tt>
272 [strongwords]
273 <strong>{words}</strong>
274
275 # Paragraph substitution.
276 [paragraph]
277 <div class="paragraph{role? {role}}"{id? id="{id}"}>{title?<div class="title">{title}</div>}<p>
278 |
279 </p></div>
280
281 [admonitionparagraph]
282 template::[admonitionblock]
283
284 # Delimited blocks.
285 [listingblock]
286 <div class="listingblock{role? {role}}"{id? id="{id}"}>
287 <div class="title">{caption=}{title}</div>
288 <div class="content">
289 <pre><tt>
290 |
291 </tt></pre>
292 </div></div>
293
294 [literalblock]
295 <div class="literalblock{role? {role}}"{id? id="{id}"}>
296 <div class="title">{title}</div>
297 <div class="content">
298 <pre><tt>
299 |
300 </tt></pre>
301 </div></div>
302
303 [sidebarblock]
304 <div class="sidebarblock{role? {role}}"{id? id="{id}"}>
305 <div class="content">
306 <div class="title">{title}</div>
307 |
308 </div></div>
309
310 [openblock]
311 <div class="openblock{role? {role}}"{id? id="{id}"}>
312 <div class="title">{title}</div>
313 <div class="content">
314 |
315 </div></div>
316
317 [partintroblock]
318 template::[openblock]
319
320 [abstractblock]
321 template::[quoteblock]
322
323 [quoteblock]
324 <div class="quoteblock{role? {role}}"{id? id="{id}"}>
325 <div class="title">{title}</div>
326 <div class="content">
327 |
328 </div>
329 <div class="attribution">
330 <em>{citetitle}</em>{attribution?<br />}
331 &#8212; {attribution}
332 </div></div>
333
334 [verseblock]
335 <div class="verseblock{role? {role}}"{id? id="{id}"}>
336 <div class="title">{title}</div>
337 <pre class="content">
338 |
339 </pre>
340 <div class="attribution">
341 <em>{citetitle}</em>{attribution?<br />}
342 &#8212; {attribution}
343 </div></div>
344
345 [exampleblock]
346 <div class="exampleblock{role? {role}}"{id? id="{id}"}>
347 <div class="title">{caption={example-caption} {counter:example-number}. }{title}</div>
348 <div class="content">
349 |
350 </div></div>
351
352 [admonitionblock]
353 <div class="admonitionblock{role? {role}}"{id? id="{id}"}>
354 <table><tr>
355 <td class="icon">
356 {data-uri%}{icons#}<img src="{icon={iconsdir}/{name}.png}" alt="{caption}" />
357 {data-uri#}{icons#}<img alt="{caption}" src="data:image/png;base64,
358 {data-uri#}{icons#}{sys:python -uc "import base64,sys; base64.encode(sys.stdin,sys.stdout)" < "{eval:os.path.join("{indir={outdir}}","{icon={iconsdir}/{name}.png}")}"}" />
359 {icons%}<div class="title">{caption}</div>
360 </td>
361 <td class="content">
362 <div class="title">{title}</div>
363 |
364 </td>
365 </tr></table>
366 </div>
367
368 # Tables.
369 [tabletags-default]
370 colspec=<col{autowidth-option! width="{colpcwidth}%"} />
371 bodyrow=<tr>|</tr>
372 headdata=<th {colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" }align="{halign}" valign="{valign}">|</th>
373 bodydata=<td {colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" }align="{halign}" valign="{valign}">|</td>
374 paragraph=<p class="table">|</p>
375
376 [tabletags-header]
377 paragraph=<p class="table header">|</p>
378
379 [tabletags-emphasis]
380 paragraph=<p class="table"><em>|</em></p>
381
382 [tabletags-strong]
383 paragraph=<p class="table"><strong>|</strong></p>
384
385 [tabletags-monospaced]
386 paragraph=<p class="table"><tt>|</tt></p>
387
388 [tabletags-verse]
389 bodydata=<td {colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" }align="{halign}" valign="{valign}"><div class="verse">|</div></td>
390 paragraph=
391
392 [tabletags-literal]
393 bodydata=<td {colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" }align="{halign}" valign="{valign}"><div class="literal"><pre><tt>|</tt></pre></div></td>
394 paragraph=
395
396 [tabletags-asciidoc]
397 bodydata=<td {colspan@1::colspan="{colspan}" }{rowspan@1::rowspan="{rowspan}" }align="{halign}" valign="{valign}"><div>|</div></td>
398 paragraph=
399
400 [table]
401 <div class="tableblock{role? {role}}"{id? id="{id}"}>
402 <table rules="{grid=all}"
403 style="margin-left:{align@left:0}{align@center|right:auto}; margin-right:{align@left|center:auto}{align@right:0};"
404 style="float:{float};"
405 {autowidth-option%}width="{tablepcwidth}%"
406 {autowidth-option#}{width#width="{tablepcwidth}%"}
407 frame="{frame%border}"
408 frame="{frame@topbot:hsides}{frame@all:border}{frame@none:void}{frame@sides:vsides}"
409 cellspacing="0" cellpadding="4">
410 <caption class="title">{caption={table-caption} {counter:table-number}. }{title}</caption>
411 {colspecs}
412 {headrows#}<thead>
413 {headrows}
414 {headrows#}</thead>
415 {footrows#}<tfoot>
416 {footrows}
417 {footrows#}</tfoot>
418 <tbody>
419 {bodyrows}
420 </tbody>
421 </table>
422 </div>
423
424 #--------------------------------------------------------------------
425 # Deprecated old table definitions.
426 #
427
428 [miscellaneous]
429 # Screen width in pixels.
430 pagewidth=800
431 pageunits=
432
433 [old_tabledef-default]
434 template=old_table
435 colspec=<col width="{colwidth}{pageunits}" />
436 bodyrow=<tr>|</tr>
437 headdata=<th align="{colalign}">|</th>
438 footdata=<td align="{colalign}">|</td>
439 bodydata=<td align="{colalign}">|</td>
440
441 [old_table]
442 <div class="tableblock"{id? id="{id}"}>
443 <table rules="{grid=none}"
444 frame="{frame%hsides}"
445 frame="{frame@topbot:hsides}{frame@all:border}{frame@none:void}{frame@sides:vsides}"
446 cellspacing="0" cellpadding="4">
447 <caption class="title">{caption={table-caption}}{title}</caption>
448 {colspecs}
449 {headrows#}<thead>
450 {headrows}
451 {headrows#}</thead>
452 {footrows#}<tfoot>
453 {footrows}
454 {footrows#}</tfoot>
455 <tbody valign="top">
456 {bodyrows}
457 </tbody>
458 </table>
459 </div>
460
461 # End of deprecated old table definitions.
462 #--------------------------------------------------------------------
463
464 [floatingtitle]
465 <h{level@0:1}{level@1:2}{level@2:3}{level@3:4}{level@4:5}{id? id="{id}"} class="float">{title}</h{level@0:1}{level@1:2}{level@2:3}{level@3:4}{level@4:5}>
466
467 [preamble]
468 # Untitled elements between header and first section title.
469 <div id="preamble">
470 <div class="sectionbody">
471 |
472 </div>
473 </div>
474
475 # Document sections.
476 [sect0]
477 <h1{id? id="{id}"}>{title}</h1>
478 |
479
480 [sect1]
481 <div class="sect1{style? {style}}{role? {role}}">
482 <h2{id? id="{id}"}>{numbered?{sectnum} }{title}</h2>
483 <div class="sectionbody">
484 |
485 </div>
486 </div>
487
488 [sect2]
489 <div class="sect2{style? {style}}{role? {role}}">
490 <h3{id? id="{id}"}>{numbered?{sectnum} }{title}</h3>
491 |
492 </div>
493
494 [sect3]
495 <div class="sect3{style? {style}}{role? {role}}">
496 <h4{id? id="{id}"}>{numbered?{sectnum} }{title}</h4>
497 |
498 </div>
499
500 [sect4]
501 <div class="sect4{style? {style}}{role? {role}}">
502 <h5{id? id="{id}"}>{title}</h5>
503 |
504 </div>
505
506 [appendix]
507 <div class="sect1{style? {style}}{role? {role}}">
508 <h2{id? id="{id}"}>{numbered?{sectnum} }{appendix-caption} {counter:appendix-number:A}: {title}</h2>
509 <div class="sectionbody">
510 |
511 </div>
512 </div>
513
514 [toc]
515 <div id="toc">
516 <div id="toctitle">{toc-title}</div>
517 <noscript><p><b>JavaScript must be enabled in your browser to display the table of contents.</b></p></noscript>
518 </div>
519
520 [header]
521 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
522 "https://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
523 <html xmlns="https://www.w3.org/1999/xhtml" xml:lang="{lang=en}">
524 <head>
525 <link rel="icon" type="image/png" href="/favicon.png">
526 <meta http-equiv="Content-Type" content="{quirks=application/xhtml+xml}{quirks?text/html}; charset={encoding}" />
527 <meta name="generator" content="AsciiDoc {asciidoc-version}" />
528 <meta name="description" content="{description}" />
529 <meta name="keywords" content="{keywords}" />
530 <title>i3: {title}</title>
531 {title%}<title>i3: {doctitle=}</title>
532 <link rel="stylesheet" href="{stylesdir=.}/style.css" type="text/css" />
533 ifdef::linkcss[]
534 <link rel="stylesheet" href="{stylesdir=.}/{theme={backend}}.css" type="text/css" />
535 {doctype-manpage}<link rel="stylesheet" href="{stylesdir=.}/{theme={backend}}-manpage.css" type="text/css" />
536 ifdef::quirks[]
537 <link rel="stylesheet" href="{stylesdir=.}/{theme={backend}}-quirks.css" type="text/css" />
538 endif::quirks[]
539 <link rel="stylesheet" href="{stylesdir=.}/{stylesheet}" type="text/css" />
540 ifdef::pygments[<link rel="stylesheet" href="{stylesdir=.}/pygments.css" type="text/css" />]
541 endif::linkcss[]
542 ifndef::linkcss[]
543 <style type="text/css">
544 include1::{stylesdir=./stylesheets}/{theme={backend}}.css[]
545 ifdef::doctype-manpage[]
546 include1::{stylesdir=./stylesheets}/{theme={backend}}-manpage.css[]
547 endif::doctype-manpage[]
548 ifdef::quirks[]
549 include1::{stylesdir=./stylesheets}/{theme={backend}}-quirks.css[]
550 endif::quirks[]
551 include1::{stylesheet}[]
552 ifdef::pygments[]
553 include1::{stylesdir=./stylesheets}/pygments.css[]
554 endif::pygments[]
555 </style>
556 endif::linkcss[]
557 ifndef::disable-javascript[]
558 ifdef::linkcss[]
559 <script type="text/javascript">
560 # Escape as CDATA to pass validators.
561 /*<![CDATA[*/
562 document.addEventListener("DOMContentLoaded", function()\{asciidoc.footnotes();{toc? asciidoc.toc({toclevels});}\}, false);
563 /*]]>*/
564 </script>
565 <script type="text/javascript" src="{scriptsdir=.}/asciidoc-xhtml11.js"></script>
566 endif::linkcss[]
567 ifndef::linkcss[]
568 <script type="text/javascript">
569 # Escape as CDATA to pass validators.
570 /*<![CDATA[*/
571 document.addEventListener("DOMContentLoaded", function()\{asciidoc.footnotes();{toc? asciidoc.toc({toclevels});}\}, false);
572 include1::{scriptsdir=./javascripts}/asciidoc-xhtml11.js[]
573 /*]]>*/
574 </script>
575 endif::linkcss[]
576 endif::disable-javascript[]
577 ifdef::asciimath[]
578 ifdef::linkcss[]
579 <script type="text/javascript" src="{scriptsdir=.}/ASCIIMathML.js"></script>
580 endif::linkcss[]
581 ifndef::linkcss[]
582 <script type="text/javascript">
583 # Escape as CDATA to pass validators.
584 /*<![CDATA[*/
585 include1::{scriptsdir=./javascripts}/ASCIIMathML.js[]
586 /*]]>*/
587 </script>
588 endif::linkcss[]
589 endif::asciimath[]
590 ifdef::latexmath[]
591 ifdef::linkcss[]
592 <script type="text/javascript" src="{scriptsdir=.}/LaTeXMathML.js"></script>
593 endif::linkcss[]
594 ifndef::linkcss[]
595 <script type="text/javascript">
596 # Escape as CDATA to pass validators.
597 /*<![CDATA[*/
598 include1::{scriptsdir=./javascripts}/LaTeXMathML.js[]
599 /*]]>*/
600 </script>
601 endif::linkcss[]
602 endif::latexmath[]
603 {docinfo1,docinfo2#}{include:{docdir}/docinfo.html}
604 {docinfo,docinfo2#}{include:{docdir}/{docname}-docinfo.html}
605 </head>
606 <body class="{doctype}"{max-width? style="max-width:{max-width}"}>
607
608 <div id="main">
609 <a href="/"><h1 id="title">i3 - improved tiling WM</h1></a>
610 <ul id="nav">
611 <li style=" background-color: #FFD000; font-size: 2em;padding: 0.25em;-webkit-border-radius: 0.25em;border: 4px dashed black;color: #000000;">latest git docs</li>
612 </ul>
613 <br style="clear: both">
614 <div id="content">
615 # Article, book header.
616 ifndef::doctype-manpage[]
617 <div id="header">
618 ifndef::notitle[<h1>{doctitle}</h1>]
619 ifdef::doctitle[]
620 <span id="author">{author}</span><br />
621 <span id="email"><tt>&lt;<a href="mailto:{email}">{email}</a>&gt;</tt></span><br />
622 <span id="revnumber">version {revnumber}{revdate?,}</span>
623 <span id="revdate">{revdate}</span>
624 <br /><span id="revremark">{revremark}</span>
625 endif::doctitle[]
626 ifdef::toc[{template:toc}]
627 </div>
628 endif::doctype-manpage[]
629 # Man page header.
630 ifdef::doctype-manpage[]
631 <div id="header">
632 <h1>
633 {doctitle} Manual Page
634 </h1>
635 ifdef::toc[{template:toc}]
636 <h2>{manname-title}</h2>
637 <div class="sectionbody">
638 <p>{manname} -
639 {manpurpose}
640 </p>
641 </div>
642 </div>
643 endif::doctype-manpage[]
644
645 [footer]
646 </div>
647 {disable-javascript%<div id="footnotes"><hr /></div>}
648 <div id="footer" lang="de">
649 © 2009 Michael Stapelberg, <a href="https://i3wm.org/impress.html">Impressum</a>
650 </div>
651 </body>
652 </html>
653
654 ifdef::doctype-manpage[]
655 [synopsis]
656 template::[sect1]
657 endif::doctype-manpage[]
658
659 ifdef::quirks[]
660 include::{backend}-quirks.conf[]
661 endif::quirks[]
Binary diff not shown
Binary diff not shown
0 Debugging i3: How To
1 ====================
2 Michael Stapelberg <[email protected]>
3 January 2014
4
5 This document describes how to debug i3 to send us useful bug
6 reports, even if you have no knowledge of C programming.
7
8 Thank you for being interested in debugging i3. It really means
9 something to us to get your bug fixed. If you have any questions about the
10 process and/or need further help, do not hesitate to contact us!
11
12 == Verify you are using i3 ≥ 4.10
13
14 Only the latest major version of i3 is supported. To verify which version
15 you are running, use:
16
17 ---------------
18 $ i3 --moreversion 2>&- || i3 --version
19 Binary i3 version: 4.7 (2013-12-22, branch "tags/4.7")
20 Running i3 version: 4.7-84-gac74a63 (2014-01-01, branch "next") (pid 1995)
21 ---------------
22
23 Your version can look like this:
24
25 4.7 (release version)::
26 You are using a release version. In many cases, bugs are already
27 fixed in the development version of i3. Even if the bug is not a known fixed
28 one, we will still ask you to reproduce your error with the most recent
29 development version of i3. Therefore, please upgrade to a development version
30 if you can.
31
32 4.7-85-g9c15b95 (development version)::
33 Your version is 85 commits newer than 4.7, and the git revision of your
34 version is +9c15b95+. Go to https://github.com/i3/i3/commits/next and see if
35 the most recent commit starts with the same revision. If so, you are using the
36 latest version.
37
38 Development versions of i3 have logging enabled by default and are compiled
39 with debug symbols.
40
41 == Enabling logging
42
43 If you are using a development version (see previous section), you don’t need
44 to do anything -- skip to section 3.
45
46 If you are using a release version with a custom +~/.xsession+ (or xinitrc)
47 file, execute i3 with a line like this:
48
49 ----------------------------------
50 # Use 25 MiB of RAM for debug logs
51 exec i3 --shmlog-size=26214400
52 ----------------------------------
53
54 If you are *NOT* using an +~/.xsession+ file but you just chose "i3" from the
55 list of sessions in your desktop manager (gdm, lxdm, …), edit
56 +/usr/share/xsessions/i3.desktop+ and replace the +Exec=i3+ line with:
57
58 ------------------------------
59 Exec=i3 --shmlog-size=26214400
60 ------------------------------
61
62 If you cannot restart i3 for some reason, you can enable debug logging on the
63 fly:
64
65 ---------------------------------------
66 i3-msg 'debuglog on; shmlog on; reload'
67 ---------------------------------------
68
69 == Reproducing the problem
70
71 Before submitting an issue, please make sure to close down on the problem as
72 much as you can yourself. Here are some steps you should consider:
73
74 * Find a deterministic, reliable way to reproduce the problem and provide it
75 with your bug report.
76 * Try using the default i3 config to reproduce the problem. If the issue does
77 not appear with the default config, gradually adapt it to track down what
78 change(s) to the config introduce the problem.
79 * Reproduce the problem with a minimal setup, i.e., only use as few applications,
80 windows and steps as necessary.
81 * In addition, try to stick to applications that are common and, even more
82 importantly, free / open source.
83 * Before obtaining the log file, restart i3 in-place, execute the steps to
84 reproduce the problem and then save the logs. This keeps the log file as
85 small as possible and necessary.
86
87 Please be aware that we cannot support compatibility issues with closed-source
88 software, as digging into compatibility problems without having access to the
89 source code is too time-consuming. Additionally, experience has shown that
90 often, the software in question is responsible for the issue. Please raise an
91 issue with the software in question, not i3.
92
93 == Obtaining the debug logfile
94
95 [CAUTION]
96 ================================================================================
97 Logs may contain sensitive information, so please inspect the log before
98 submitting it. Logs may be viewed by anyone, once posted. If you choose to
99 redact the log, make an effort not to discard information which may be relevant
100 to the issue you are reporting.
101
102 The best way to avoid submitting such information is to only run the necessary
103 steps to reproduce the behavior when saving the log file. This will also make
104 analyzing the log file easier.
105 ================================================================================
106
107 No matter whether i3 misbehaved in some way without crashing or whether it just
108 crashed, the logfile provides all information necessary to debug the problem.
109
110 To upload a compressed version of the logfile (for a bugreport), use:
111 -------------------------------------------------------------------------------
112 DISPLAY=:0 i3-dump-log | bzip2 -c | curl --data-binary @- https://logs.i3wm.org
113 -------------------------------------------------------------------------------
114
115 This command does not depend on i3 (it also works while i3 displays
116 the crash dialog), but it requires a working X11 connection.
117
118 After running it, you will get a URL to the logfile. Please include that URL in
119 your bug report.
120
121 == On crashes: Obtaining a backtrace
122
123 When i3 crashes, it will display a dialog stating “i3 just crashed”, offering
124 you to save a backtrace to a text file.
125
126 To actually get useful backtraces, you should make sure that your version of i3
127 is compiled with debug symbols:
128
129 ------------------------------------------------------------------------------
130 $ file `which i3`
131 /usr/bin/i3: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically
132 linked (uses shared libs), for GNU/Linux 2.6.18, not stripped
133 ------------------------------------------------------------------------------
134
135 Notice the +not stripped+, which is the important part. If you have a version
136 which is stripped, please check whether your distribution provides debug
137 symbols (package +i3-wm-dbg+ on Debian for example) or if you can turn off
138 stripping. If nothing helps, please build i3 from source.
139
140 Once you have made sure that your i3 is compiled with debug symbols and the C
141 debugger +gdb+ is installed on your machine, you can let i3 generate a
142 backtrace in the crash dialog.
143
144 After pressing "b" in the crash dialog, you will get a file called
145 +/tmp/i3-backtrace.%d.%d.txt+ where the first +%d+ is replaced by i3’s process
146 id (PID) and the second one is incremented each time you generate a backtrace,
147 starting at 0.
148
149 == Sending bug reports/debugging on IRC
150
151 When sending bug reports, please attach the *whole* log file. Even if you think
152 you found the section which clearly highlights the problem, additional
153 information might be necessary to completely diagnose the problem.
154
155 When debugging with us in IRC, be prepared to use a so-called nopaste service
156 such as https://pastebin.com because pasting large amounts of text in IRC
157 sometimes leads to incomplete lines (servers have line length limitations) or
158 flood kicks.
159
160 == Debugging i3bar
161
162 To debug i3bar problems, use the +--verbose+ commandline parameter,
163 or add +verbose yes+ to all +bar {}+ blocks in your i3
164 config, reload your config and then restart all i3bar instances like this:
165
166 ---------------------------------------------------------------------
167 $ i3 reload
168 $ killall i3bar
169 $ for c in $(i3-msg -t get_bar_config | python -c \
170 'import json,sys;print("\n".join(json.load(sys.stdin)))'); do \
171 (i3bar --bar_id=$c >i3bar.$c.log 2>&1) & \
172 done;
173 ---------------------------------------------------------------------
174
175 There will now be +i3bar.*.log+ files in your current directory that you can provide
176 in your bug report.
0 Hacking i3: How To
1 ==================
2 Michael Stapelberg <[email protected]>
3 February 2013
4
5 This document is intended to be the first thing you read before looking and/or
6 touching i3’s source code. It should contain all important information to help
7 you understand why things are like they are. If it does not mention something
8 you find necessary, please do not hesitate to contact me.
9
10 == Building i3
11
12 You can build i3 like you build any other software package which uses autotools.
13 Here’s a memory refresher:
14
15 $ autoreconf -fi
16 $ mkdir -p build && cd build
17 $ ../configure
18 $ make -j8
19
20 (The autoreconf -fi step is unnecessary if you are building from a release tarball,
21 but shouldn’t hurt either.)
22
23 === Build system features
24
25 * We use the AX_ENABLE_BUILDDIR macro to enforce builds happening in a separate
26 directory. This is a prerequisite for the AX_EXTEND_SRCDIR macro and building
27 in a separate directory is common practice anyway. In case this causes any
28 trouble when packaging i3 for your distribution, please open an issue.
29
30 * “make check” runs the i3 testsuite. See docs/testsuite for details.
31
32 * “make distcheck” (runs testsuite on “make dist” result, tiny bit quicker
33 feedback cycle than waiting for the travis build to catch the issue).
34
35 * “make uninstall” (occasionally requested by users who compile from source)
36
37 * “make” will build manpages/docs by default if the tools are installed.
38 Conversely, manpages/docs are not tried to be built for users who don’t want
39 to install all these dependencies to get started hacking on i3.
40
41 * non-release builds will enable address sanitizer by default. Use the
42 --disable-sanitizers configure option to turn off all sanitizers, and see
43 --help for available sanitizers.
44
45 * Support for pre-compiled headers (PCH) has been dropped for now in the
46 interest of simplicity. If you need support for PCH, please open an issue.
47
48 * Coverage reports are now generated using “make check-code-coverage”, which
49 requires specifying --enable-code-coverage when calling configure.
50
51 == Using git / sending patches
52
53 For a short introduction into using git, see
54 https://web.archive.org/web/20121024222556/http://www.spheredev.org/wiki/Git_for_the_lazy
55 or, for more documentation, see https://git-scm.com/documentation
56
57 Please talk to us before working on new features to see whether they will be
58 accepted. A good way for this is to open an issue and asking for opinions on it.
59 Even for accepted features, this can be a good way to refine an idea upfront. However,
60 we don't want to see certain features in i3, e.g., switching window focus in an
61 Alt+Tab like way.
62
63 When working on bugfixes, please make sure you mention that you are working on
64 it in the corresponding bug report at https://github.com/i3/i3/issues. In case
65 there is no bug report yet, please create one.
66
67 After you are done, please submit your work for review as a pull request at
68 https://github.com/i3/i3.
69
70 Do not send emails to the mailing list or any author directly, and don’t submit
71 them in the bugtracker, since all reviews should be done in public at
72 https://github.com/i3/i3. In order to make your review go as fast as possible, you
73 could have a look at previous reviews and see what the common mistakes are.
74
75 === Which branch to use?
76
77 Work on i3 generally happens in two branches: “master” and “next” (the latter
78 being the default branch, the one that people get when they check out the git
79 repository).
80
81 The contents of “master” are always stable. That is, it contains the source code
82 of the latest release, plus any bugfixes that were applied since that release.
83
84 New features are only found in the “next” branch. Therefore, if you are working
85 on a new feature, use the “next” branch. If you are working on a bugfix, use the
86 “next” branch, too, but make sure your code also works on “master”.
87
88 == Window Managers
89
90 A window manager is not necessarily needed to run X, but it is usually used in
91 combination with X to facilitate some things. The window manager's job is to
92 take care of the placement of windows, to provide the user with some mechanisms
93 to change the position/size of windows and to communicate with clients to a
94 certain extent (for example handle fullscreen requests of clients such as
95 MPlayer).
96
97 There are no different contexts in which X11 clients run, so a window manager
98 is just another client, like all other X11 applications. However, it handles
99 some events which normal clients usually don’t handle.
100
101 In the case of i3, the tasks (and order of them) are the following:
102
103 . Grab the key bindings (events will be sent upon keypress/keyrelease)
104 . Iterate through all existing windows (if the window manager is not started as
105 the first client of X) and manage them (reparent them, create window
106 decorations, etc.)
107 . When new windows are created, manage them
108 . Handle the client’s `_WM_STATE` property, but only `_WM_STATE_FULLSCREEN` and
109 `_NET_WM_STATE_DEMANDS_ATTENTION`
110 . Handle the client’s `WM_NAME` property
111 . Handle the client’s size hints to display them proportionally
112 . Handle the client’s urgency hint
113 . Handle enter notifications (focus follows mouse)
114 . Handle button (as in mouse buttons) presses for focus/raise on click
115 . Handle expose events to re-draw own windows such as decorations
116 . React to the user’s commands: Change focus, Move windows, Switch workspaces,
117 Change the layout mode of a container (default/stacking/tabbed), start a new
118 application, restart the window manager
119
120 In the following chapters, each of these tasks and their implementation details
121 will be discussed.
122
123 === Tiling window managers
124
125 Traditionally, there are two approaches to managing windows: The most common
126 one nowadays is floating, which means the user can freely move/resize the
127 windows. The other approach is called tiling, which means that your window
128 manager distributes windows to use as much space as possible while not
129 overlapping each other.
130
131 The idea behind tiling is that you should not need to waste your time
132 moving/resizing windows while you usually want to get some work done. After
133 all, most users sooner or later tend to lay out their windows in a way which
134 corresponds to tiling or stacking mode in i3. Therefore, why not let i3 do this
135 for you? Certainly, it’s faster than you could ever do it.
136
137 The problem with most tiling window managers is that they are too inflexible.
138 In my opinion, a window manager is just another tool, and similar to vim which
139 can edit all kinds of text files (like source code, HTML, …) and is not limited
140 to a specific file type, a window manager should not limit itself to a certain
141 layout (like dwm, awesome, …) but provide mechanisms for you to easily create
142 the layout you need at the moment.
143
144 === The layout tree
145
146 The data structure which i3 uses to keep track of your windows is a tree. Every
147 node in the tree is a container (type +Con+). Some containers represent actual
148 windows (every container with a +window != NULL+), some represent split
149 containers and a few have special purposes: they represent workspaces, outputs
150 (like VGA1, LVDS1, …) or the X11 root window.
151
152 So, when you open a terminal and immediately open another one, they reside in
153 the same split container, which uses the default layout. In case of an empty
154 workspace, the split container we are talking about is the workspace.
155
156 To get an impression of how different layouts are represented, just play around
157 and look at the data structures -- they are exposed as a JSON hash. See
158 https://i3wm.org/docs/ipc.html#_tree_reply for documentation on that and an
159 example.
160
161 == Files
162
163 include/atoms.xmacro::
164 A file containing all X11 atoms which i3 uses. This file will be included
165 various times (for defining, requesting and receiving the atoms), each time
166 with a different definition of xmacro().
167
168 include/data.h::
169 Contains data definitions used by nearly all files. You really need to read
170 this first.
171
172 include/*.h::
173 Contains forward definitions for all public functions, as well as
174 doxygen-compatible comments (so if you want to get a bit more of the big
175 picture, either browse all header files or use doxygen if you prefer that).
176
177 src/config_parser.c::
178 Contains a custom configuration parser. See src/command_parser.c for rationale
179 on why we use a custom parser.
180
181 src/click.c::
182 Contains all functions which handle mouse button clicks (right mouse button
183 clicks initiate resizing and thus are relatively complex).
184
185 src/command_parser.c::
186 Contains a hand-written parser to parse commands (commands are what
187 you bind on keys and what you can send to i3 using the IPC interface, like
188 'move left' or 'workspace 4').
189
190 src/con.c::
191 Contains all functions which deal with containers directly (creating
192 containers, searching containers, getting specific properties from containers,
193 …).
194
195 src/config.c::
196 Contains all functions handling the configuration file (calling the parser
197 src/config_parser.c) with the correct path, switching key bindings mode).
198
199 src/ewmh.c::
200 Functions to get/set certain EWMH properties easily.
201
202 src/floating.c::
203 Contains functions for floating mode (mostly resizing/dragging).
204
205 src/handlers.c::
206 Contains all handlers for all kinds of X events (new window title, new hints,
207 unmapping, key presses, button presses, …).
208
209 src/ipc.c::
210 Contains code for the IPC interface.
211
212 src/load_layout.c::
213 Contains code for loading layouts from JSON files.
214
215 src/log.c::
216 Contains the logging functions.
217
218 src/main.c::
219 Initializes the window manager.
220
221 src/manage.c::
222 Looks at existing or new windows and decides whether to manage them. If so, it
223 reparents the window and inserts it into our data structures.
224
225 src/match.c::
226 A "match" is a data structure which acts like a mask or expression to match
227 certain windows or not. For example, when using commands, you can specify a
228 command like this: [title="*Firefox*"] kill. The title member of the match
229 data structure will then be filled and i3 will check each window using
230 match_matches_window() to find the windows affected by this command.
231
232 src/move.c::
233 Contains code to move a container in a specific direction.
234
235 src/output.c::
236 Functions to handle CT_OUTPUT cons.
237
238 src/randr.c::
239 The RandR API is used to get (and re-query) the configured outputs (monitors,
240 …).
241
242 src/render.c::
243 Renders the tree data structure by assigning coordinates to every node. These
244 values will later be pushed to X11 in +src/x.c+.
245
246 src/resize.c::
247 Contains the functions to resize containers.
248
249 src/restore_layout.c::
250 Everything for restored containers that is not pure state parsing (which can be
251 found in load_layout.c).
252
253 src/sighandler.c::
254 Handles +SIGSEGV+, +SIGABRT+ and +SIGFPE+ by showing a dialog that i3 crashed.
255 You can chose to let it dump core, to restart it in-place or to restart it
256 in-place but forget about the layout.
257
258 src/tree.c::
259 Contains functions which open or close containers in the tree, change focus or
260 cleanup ("flatten") the tree. See also +src/move.c+ for another similar
261 function, which was moved into its own file because it is so long.
262
263 src/util.c::
264 Contains useful functions which are not really dependent on anything.
265
266 src/window.c::
267 Handlers to update X11 window properties like +WM_CLASS+, +_NET_WM_NAME+,
268 +CLIENT_LEADER+, etc.
269
270 src/workspace.c::
271 Contains all functions related to workspaces (displaying, hiding, renaming…)
272
273 src/x.c::
274 Transfers our in-memory tree (see +src/render.c+) to X11.
275
276 src/xcb.c::
277 Contains wrappers to use xcb more easily.
278
279 src/xcursor.c::
280 XCursor functions (for cursor themes).
281
282 src/xinerama.c::
283 Legacy support for Xinerama. See +src/randr.c+ for the preferred API.
284
285 == Data structures
286
287
288 See include/data.h for documented data structures. The most important ones are
289 explained right here.
290
291 /////////////////////////////////////////////////////////////////////////////////
292 // TODO: update image
293
294 image:bigpicture.png[The Big Picture]
295
296 /////////////////////////////////////////////////////////////////////////////////
297
298 So, the hierarchy is:
299
300 . *X11 root window*, the root container
301 . *Output container* (LVDS1 in this example)
302 . *Content container* (there are also containers for dock windows)
303 . *Workspaces* (Workspace 1 in this example, with horizontal orientation)
304 . *Split container* (vertically split)
305 . *X11 window containers*
306
307 The data type is +Con+, in all cases.
308
309 === X11 root window
310
311 The X11 root window is a single window per X11 display (a display is identified
312 by +:0+ or +:1+ etc.). The root window is what you draw your background image
313 on. It spans all the available outputs, e.g. +VGA1+ is a specific part of the
314 root window and +LVDS1+ is a specific part of the root window.
315
316 === Output container
317
318 Every active output obtained through RandR is represented by one output
319 container. Outputs are considered active when a mode is configured (meaning
320 something is actually displayed on the output) and the output is not a clone.
321
322 For example, if your notebook has a screen resolution of 1280x800 px and you
323 connect a video projector with a resolution of 1024x768 px, set it up in clone
324 mode (+xrandr \--output VGA1 \--mode 1024x768 \--same-as LVDS1+), i3 will
325 reduce the resolution to the lowest common resolution and disable one of the
326 cloned outputs afterwards.
327
328 However, if you configure it using +xrandr \--output VGA1 \--mode 1024x768
329 \--right-of LVDS1+, i3 will set both outputs active. For each output, a new
330 workspace will be assigned. New workspaces are created on the output you are
331 currently on.
332
333 === Content container
334
335 Each output has multiple children. Two of them are dock containers which hold
336 dock clients. The other one is the content container, which holds the actual
337 content (workspaces) of this output.
338
339 === Workspace
340
341 A workspace is identified by its name. Basically, you could think of
342 workspaces as different desks in your office, if you like the desktop
343 metaphor. They just contain different sets of windows and are completely
344 separate of each other. Other window managers also call this ``Virtual
345 desktops''.
346
347 === Split container
348
349 A split container is a container which holds an arbitrary amount of split
350 containers or X11 window containers. It has an orientation (horizontal or
351 vertical) and a layout.
352
353 Split containers (and X11 window containers, which are a subtype of split
354 containers) can have different border styles.
355
356 === X11 window container
357
358 An X11 window container holds exactly one X11 window. These are the leaf nodes
359 of the layout tree, they cannot have any children.
360
361 == List/queue macros
362
363 i3 makes heavy use of the list macros defined in BSD operating systems. To
364 ensure that the operating system on which i3 is compiled has all the expected
365 features, i3 comes with `include/queue.h`. On BSD systems, you can use man
366 `queue(3)`. On Linux, you have to use google (or read the source).
367
368 The lists used are +SLIST+ (single linked lists), +CIRCLEQ+ (circular
369 queues) and +TAILQ+ (tail queues). Usually, only forward traversal is necessary,
370 so an `SLIST` works fine. If inserting elements at arbitrary positions or at
371 the end of a list is necessary, a +TAILQ+ is used instead. However, for the
372 windows inside a container, a +CIRCLEQ+ is necessary to go from the currently
373 selected window to the window above/below.
374
375 == Naming conventions
376
377 There is a row of standard variables used in many events. The following names
378 should be chosen for those:
379
380 * ``conn'' is the xcb_connection_t
381 * ``event'' is the event of the particular type
382 * ``con'' names a container
383 * ``current'' is a loop variable when using +TAILQ_FOREACH+ etc.
384
385 == Startup (src/mainx.c, main())
386
387 * Establish the xcb connection
388 * Check for XKB extension on the separate X connection, load Xcursor
389 * Check for RandR screens (with a fall-back to Xinerama)
390 * Grab the keycodes for which bindings exist
391 * Manage all existing windows
392 * Enter the event loop
393
394 == Keybindings
395
396 === Grabbing the bindings
397
398 Grabbing the bindings is quite straight-forward. You pass X your combination of
399 modifiers and the keycode you want to grab and whether you want to grab them
400 actively or passively. Most bindings (everything except for bindings using
401 Mode_switch) are grabbed passively, that is, just the window manager gets the
402 event and cannot replay it.
403
404 We need to grab bindings that use Mode_switch actively because of a bug in X.
405 When the window manager receives the keypress/keyrelease event for an actively
406 grabbed keycode, it has to decide what to do with this event: It can either
407 replay it so that other applications get it or it can prevent other
408 applications from receiving it.
409
410 So, why do we need to grab keycodes actively? Because X does not set the
411 state-property of keypress/keyrelease events properly. The Mode_switch bit is
412 not set and we need to get it using XkbGetState. This means we cannot pass X
413 our combination of modifiers containing Mode_switch when grabbing the key and
414 therefore need to grab the keycode itself without any modifiers. This means,
415 if you bind Mode_switch + keycode 38 ("a"), i3 will grab keycode 38 ("a") and
416 check on each press of "a" if the Mode_switch bit is set using XKB. If yes, it
417 will handle the event, if not, it will replay the event.
418
419 === Handling a keypress
420
421 As mentioned in "Grabbing the bindings", upon a keypress event, i3 first gets
422 the correct state.
423
424 Then, it looks through all bindings and gets the one which matches the received
425 event.
426
427 The bound command is parsed by the cmdparse lexer/parser, see +parse_cmd+ in
428 +src/cmdparse.y+.
429
430 == Manage windows (src/main.c, manage_window() and reparent_window())
431
432 `manage_window()` does some checks to decide whether the window should be
433 managed at all:
434
435 * Windows have to be mapped, that is, visible on screen
436 * The override_redirect must not be set. Windows with override_redirect shall
437 not be managed by a window manager
438
439 Afterwards, i3 gets the initial geometry and reparents the window (see
440 `reparent_window()`) if it wasn’t already managed.
441
442 Reparenting means that for each window which is reparented, a new window,
443 slightly larger than the original one, is created. The original window is then
444 reparented to the bigger one (called "frame").
445
446 After reparenting, the window type (`_NET_WM_WINDOW_TYPE`) is checked to see
447 whether this window is a dock (`_NET_WM_WINDOW_TYPE_DOCK`), like dzen2 for
448 example. Docks are handled differently, they don’t have decorations and are not
449 assigned to a specific container. Instead, they are positioned at the bottom
450 or top of the screen (in the appropriate dock area containers). To get the
451 height which needs to be reserved for the window, the `_NET_WM_STRUT_PARTIAL`
452 property is used.
453
454 Furthermore, the list of assignments (to other workspaces, which may be on
455 other screens) is checked. If the window matches one of the user’s criteria,
456 it may either be put in floating mode or moved to a different workspace. If the
457 target workspace is not visible, the window will not be mapped.
458
459 == What happens when an application is started?
460
461 i3 does not care about applications. All it notices is when new windows are
462 mapped (see `src/handlers.c`, `handle_map_request()`). The window is then
463 reparented (see section "Manage windows").
464
465 After reparenting the window, `render_tree()` is called which renders the
466 internal layout table. The new window has been placed in the currently focused
467 container and therefore the new window and the old windows (if any) need to be
468 moved/resized so that the currently active layout (default/stacking/tabbed mode)
469 is rendered correctly. To move/resize windows, a window is ``configured'' in
470 X11-speak.
471
472 Some applications, such as MPlayer obviously assume the window manager is
473 stupid and try to configure their windows by themselves. This generates an
474 event called configurerequest. i3 handles these events and tells the window the
475 size it had before the configurerequest (with the exception of not yet mapped
476 windows, which get configured like they want to, and floating windows, which
477 can reconfigure themselves).
478
479 == _NET_WM_STATE
480
481 Only the _NET_WM_STATE_FULLSCREEN and _NET_WM_STATE_DEMANDS_ATTENTION atoms
482 are handled.
483
484 The former calls ``toggle_fullscreen()'' for the specific client which just
485 configures the client to use the whole screen on which it currently is.
486 Also, it is set as fullscreen_client for the i3Screen.
487
488 The latter is used to set, read and display urgency hints.
489
490 == WM_NAME
491
492 When the WM_NAME property of a window changes, its decoration (containing the
493 title) is re-rendered. Note that WM_NAME is in COMPOUND_TEXT encoding which is
494 totally uncommon and cumbersome. Therefore, the _NET_WM_NAME atom will be used
495 if present.
496
497 == _NET_WM_NAME
498
499 Like WM_NAME, this atom contains the title of a window. However, _NET_WM_NAME
500 is encoded in UTF-8. i3 will recode it to UCS-2 in order to be able to pass it
501 to X. Using an appropriate font (ISO-10646), you can see most special
502 characters (every special character contained in your font).
503
504 == Size hints
505
506 Size hints specify the minimum/maximum size for a given window as well as its
507 aspect ratio. This is important for clients like mplayer, who only set the
508 aspect ratio and resize their window to be as small as possible (but only with
509 some video outputs, for example in Xv, while when using x11, mplayer does the
510 necessary centering for itself).
511
512 So, when an aspect ratio was specified, i3 adjusts the height of the window
513 until the size maintains the correct aspect ratio. For the code to do this, see
514 src/layout.c, function resize_client().
515
516 == Rendering (src/layout.c, render_layout() and render_container())
517
518 Rendering in i3 version 4 is the step which assigns the correct sizes for
519 borders, decoration windows, child windows and the stacking order of all
520 windows. In a separate step (+x_push_changes()+), these changes are pushed to
521 X11.
522
523 Keep in mind that all these properties (+rect+, +window_rect+ and +deco_rect+)
524 are temporary, meaning they will be overwritten by calling +render_con+.
525 Persistent position/size information is kept in +geometry+.
526
527 The entry point for every rendering operation (except for the case of moving
528 floating windows around) currently is +tree_render()+ which will re-render
529 everything that’s necessary (for every output, only the currently displayed
530 workspace is rendered). This behavior is expected to change in the future,
531 since for a lot of updates, re-rendering everything is not actually necessary.
532 Focus was on getting it working correct, not getting it work very fast.
533
534 What +tree_render()+ actually does is calling +render_con()+ on the root
535 container and then pushing the changes to X11. The following sections talk
536 about the different rendering steps, in the order of "top of the tree" (root
537 container) to the bottom.
538
539 === Rendering the root container
540
541 The i3 root container (`con->type == CT_ROOT`) represents the X11 root window.
542 It contains one child container for every output (like LVDS1, VGA1, …), which
543 is available on your computer.
544
545 Rendering the root will first render all tiling windows and then all floating
546 windows. This is necessary because a floating window can be positioned in such
547 a way that it is visible on two different outputs. Therefore, by first
548 rendering all the tiling windows (of all outputs), we make sure that floating
549 windows can never be obscured by tiling windows.
550
551 Essentially, though, this code path will just call +render_con()+ for every
552 output and +x_raise_con(); render_con()+ for every floating window.
553
554 In the special case of having a "global fullscreen" window (fullscreen mode
555 spanning all outputs), a shortcut is taken and +x_raise_con(); render_con()+ is
556 only called for the global fullscreen window.
557
558 === Rendering an output
559
560 Output containers (`con->layout == L_OUTPUT`) represent a hardware output like
561 LVDS1, VGA1, etc. An output container has three children (at the moment): One
562 content container (having workspaces as children) and the top/bottom dock area
563 containers.
564
565 The rendering happens in the function +render_l_output()+ in the following
566 steps:
567
568 1. Find the content container (`con->type == CT_CON`)
569 2. Get the currently visible workspace (+con_get_fullscreen_con(content,
570 CF_OUTPUT)+).
571 3. If there is a fullscreened window on that workspace, directly render it and
572 return, thus ignoring the dock areas.
573 4. Sum up the space used by all the dock windows (they have a variable height
574 only).
575 5. Set the workspace rects (x/y/width/height) based on the position of the
576 output (stored in `con->rect`) and the usable space
577 (`con->rect.{width,height}` without the space used for dock windows).
578 6. Recursively raise and render the output’s child containers (meaning dock
579 area containers and the content container).
580
581 === Rendering a workspace or split container
582
583 From here on, there really is no difference anymore. All containers are of
584 `con->type == CT_CON` (whether workspace or split container) and some of them
585 have a `con->window`, meaning they represent an actual window instead of a
586 split container.
587
588 ==== Default layout
589
590 In default layout, containers are placed horizontally or vertically next to
591 each other (depending on the `con->orientation`). If a child is a leaf node (as
592 opposed to a split container) and has border style "normal", appropriate space
593 will be reserved for its window decoration.
594
595 ==== Stacked layout
596
597 In stacked layout, only the focused window is actually shown (this is achieved
598 by calling +x_raise_con()+ in reverse focus order at the end of +render_con()+).
599
600 The available space for the focused window is the size of the container minus
601 the height of the window decoration for all windows inside this stacked
602 container.
603
604 If border style is "1pixel" or "none", no window decoration height will be
605 reserved (or displayed later on), unless there is more than one window inside
606 the stacked container.
607
608 ==== Tabbed layout
609
610 Tabbed layout works precisely like stacked layout, but the window decoration
611 position/size is different: They are placed next to each other on a single line
612 (fixed height).
613
614 ==== Dock area layout
615
616 This is a special case. Users cannot choose the dock area layout, but it will be
617 set for the dock area containers. In the dockarea layout (at the moment!),
618 windows will be placed above each other.
619
620 === Rendering a window
621
622 A window’s size and position will be determined in the following way:
623
624 1. Subtract the border if border style is not "none" (but "normal" or "1pixel").
625 2. Subtract the X11 border, if the window has an X11 border > 0.
626 3. Obey the aspect ratio of the window (think MPlayer).
627 4. Obey the height- and width-increments of the window (think terminal emulator
628 which can only be resized in one-line or one-character steps).
629
630 == Pushing updates to X11 / Drawing
631
632 A big problem with i3 before version 4 was that we just sent requests to X11
633 anywhere in the source code. This was bad because nobody could understand the
634 entirety of our interaction with X11, it lead to subtle bugs and a lot of edge
635 cases which we had to consider all over again.
636
637 Therefore, since version 4, we have a single file, +src/x.c+, which is
638 responsible for repeatedly transferring parts of our tree datastructure to X11.
639
640 +src/x.c+ consists of multiple parts:
641
642 1. The state pushing: +x_push_changes()+, which calls +x_push_node()+.
643 2. State modification functions: +x_con_init+, +x_reinit+,
644 +x_reparent_child+, +x_move_win+, +x_con_kill+, +x_raise_con+, +x_set_name+
645 and +x_set_warp_to+.
646 3. Expose event handling (drawing decorations): +x_deco_recurse()+ and
647 +x_draw_decoration()+.
648
649 === Pushing state to X11
650
651 In general, the function +x_push_changes+ should be called to push state
652 changes. Only when the scope of the state change is clearly defined (for
653 example only the title of a window) and its impact is known beforehand, one can
654 optimize this and call +x_push_node+ on the appropriate con directly.
655
656 +x_push_changes+ works in the following steps:
657
658 1. Clear the eventmask for all mapped windows. This leads to not getting
659 useless ConfigureNotify or EnterNotify events which are caused by our
660 requests. In general, we only want to handle user input.
661 2. Stack windows above each other, in reverse stack order (starting with the
662 most obscured/bottom window). This is relevant for floating windows which
663 can overlap each other, but also for tiling windows in stacked or tabbed
664 containers. We also update the +_NET_CLIENT_LIST_STACKING+ hint which is
665 necessary for tab drag and drop in Chromium.
666 3. +x_push_node+ will be called for the root container, recursively calling
667 itself for the container’s children. This function actually pushes the
668 state, see the next paragraph.
669 4. If the pointer needs to be warped to a different position (for example when
670 changing focus to a different output), it will be warped now.
671 5. The eventmask is restored for all mapped windows.
672 6. Window decorations will be rendered by calling +x_deco_recurse+ on the root
673 container, which then recursively calls itself for the children.
674 7. If the input focus needs to be changed (because the user focused a different
675 window), it will be updated now.
676 8. +x_push_node_unmaps+ will be called for the root container. This function
677 only pushes UnmapWindow requests. Separating the state pushing is necessary
678 to handle fullscreen windows (and workspace switches) in a smooth fashion:
679 The newly visible windows should be visible before the old windows are
680 unmapped.
681
682 +x_push_node+ works in the following steps:
683
684 1. Update the window’s +WM_NAME+, if changed (the +WM_NAME+ is set on i3
685 containers mainly for debugging purposes).
686 2. Reparents a child window into the i3 container if the container was created
687 for a specific managed window.
688 3. If the size/position of the i3 container changed (due to opening a new
689 window or switching layouts for example), the window will be reconfigured.
690 Also, the pixmap which is used to draw the window decoration/border on is
691 reconfigured (pixmaps are size-dependent).
692 4. Size/position for the child window is adjusted.
693 5. The i3 container is mapped if it should be visible and was not yet mapped.
694 When mapping, +WM_STATE+ is set to +WM_STATE_NORMAL+. Also, the eventmask of
695 the child window is updated and the i3 container’s contents are copied from
696 the pixmap.
697 6. +x_push_node+ is called recursively for all children of the current
698 container.
699
700 +x_push_node_unmaps+ handles the remaining case of an i3 container being
701 unmapped if it should not be visible anymore. +WM_STATE+ will be set to
702 +WM_STATE_WITHDRAWN+.
703
704
705 === Drawing window decorations/borders/backgrounds
706
707 +x_draw_decoration+ draws window decorations. It is run for every leaf
708 container (representing an actual X11 window) and for every non-leaf container
709 which is in a stacked/tabbed container (because stacked/tabbed containers
710 display a window decoration for split containers, which consists of a representation
711 of the child container's names.
712
713 Then, parameters are collected to be able to determine whether this decoration
714 drawing is actually necessary or was already done. This saves a substantial
715 number of redraws (depending on your workload, but far over 50%).
716
717 Assuming that we need to draw this decoration, we start by filling the empty
718 space around the child window (think of MPlayer with a specific aspect ratio)
719 in the user-configured client background color.
720
721 Afterwards, we draw the appropriate border (in case of border styles "normal"
722 and "1pixel") and the top bar (in case of border style "normal").
723
724 The last step is drawing the window title on the top bar.
725
726
727 /////////////////////////////////////////////////////////////////////////////////
728
729 == Resizing containers
730
731 By clicking and dragging the border of a container, you can resize the whole
732 column (respectively row) which this container is in. This is necessary to keep
733 the table layout working and consistent.
734
735 The resizing works similarly to the resizing of floating windows or movement of
736 floating windows:
737
738 * A new, invisible window with the size of the root window is created
739 (+grabwin+)
740 * Another window, 2px width and as high as your screen (or vice versa for
741 horizontal resizing) is created. Its background color is the border color and
742 it is only there to inform the user how big the container will be (it
743 creates the impression of dragging the border out of the container).
744 * The +drag_pointer+ function of +src/floating.c+ is called to grab the pointer
745 and enter its own event loop which will pass all events (expose events) but
746 motion notify events. This function then calls the specified callback
747 (+resize_callback+) which does some boundary checking and moves the helper
748 window. As soon as the mouse button is released, this loop will be
749 terminated.
750 * The new width_factor for each involved column (respectively row) will be
751 calculated.
752
753 /////////////////////////////////////////////////////////////////////////////////
754
755 == User commands (parser-specs/commands.spec)
756
757 In the configuration file and when using i3 interactively (with +i3-msg+, for
758 example), you use commands to make i3 do things, like focus a different window,
759 set a window to fullscreen, and so on. An example command is +floating enable+,
760 which enables floating mode for the currently focused window. See the
761 appropriate section in the link:userguide.html[User’s Guide] for a reference of
762 all commands.
763
764 In earlier versions of i3, interpreting these commands was done using lex and
765 yacc, but experience has shown that lex and yacc are not well suited for our
766 command language. Therefore, starting from version 4.2, we use a custom parser
767 for user commands and the configuration file.
768 The input specification for this parser can be found in the file
769 +parser-specs/*.spec+. Should you happen to use Vim as an editor, use
770 :source parser-specs/highlighting.vim to get syntax highlighting for this file
771 (highlighting files for other editors are welcome).
772
773 .Excerpt from commands.spec
774 -----------------------------------------------------------------------
775 state INITIAL:
776 '[' -> call cmd_criteria_init(); CRITERIA
777 'move' -> MOVE
778 'exec' -> EXEC
779 'workspace' -> WORKSPACE
780 'exit' -> call cmd_exit()
781 'restart' -> call cmd_restart()
782 'reload' -> call cmd_reload()
783 -----------------------------------------------------------------------
784
785 The input specification is written in an extremely simple format. The
786 specification is then converted into C code by the Perl script
787 generate-commands-parser.pl (the output file names begin with GENERATED and the
788 files are stored in the +include+ directory). The parser implementation
789 +src/commands_parser.c+ includes the generated C code at compile-time.
790
791 The above excerpt from commands.spec illustrates nearly all features of our
792 specification format: You describe different states and what can happen within
793 each state. State names are all-caps; the state in the above excerpt is called
794 INITIAL. A list of tokens and their actions (separated by an ASCII arrow)
795 follows. In the excerpt, all tokens are literals, that is, simple text strings
796 which will be compared with the input. An action is either the name of a state
797 in which the parser will transition into, or the keyword 'call', followed by
798 the name of a function (and optionally a state).
799
800 === Example: The WORKSPACE state
801
802 Let’s have a look at the WORKSPACE state, which is a good example of all
803 features. This is its definition:
804
805 .WORKSPACE state (commands.spec)
806 ----------------------------------------------------------------
807 # workspace next|prev|next_on_output|prev_on_output
808 # workspace back_and_forth
809 # workspace <name>
810 # workspace number <number>
811 state WORKSPACE:
812 direction = 'next_on_output', 'prev_on_output', 'next', 'prev'
813 -> call cmd_workspace($direction)
814 'back_and_forth'
815 -> call cmd_workspace_back_and_forth()
816 'number'
817 -> WORKSPACE_NUMBER
818 workspace = string
819 -> call cmd_workspace_name($workspace)
820 ----------------------------------------------------------------
821
822 As you can see from the commands, there are multiple different valid variants
823 of the workspace command:
824
825 workspace <direction>::
826 The word 'workspace' can be followed by any of the tokens 'next',
827 'prev', 'next_on_output' or 'prev_on_output'. This command will
828 switch to the next or previous workspace (optionally on the same
829 output). +
830 There is one function called +cmd_workspace+, which is defined
831 in +src/commands.c+. It will handle this kind of command. To know which
832 direction was specified, the direction token is stored on the stack
833 with the name "direction", which is what the "direction = " means in
834 the beginning. +
835
836 NOTE: Note that you can specify multiple literals in the same line. This has
837 exactly the same effect as if you specified `direction =
838 'next_on_output' -> call cmd_workspace($direction)` and so forth. +
839
840 NOTE: Also note that the order of literals is important here: If 'next' were
841 ordered before 'next_on_output', then 'next_on_output' would never
842 match.
843
844 workspace back_and_forth::
845 This is a very simple case: When the literal 'back_and_forth' is found
846 in the input, the function +cmd_workspace_back_and_forth+ will be
847 called without parameters and the parser will return to the INITIAL
848 state (since no other state was specified).
849 workspace <name>::
850 In this case, the workspace command is followed by an arbitrary string,
851 possibly in quotes, for example "workspace 3" or "workspace bleh". +
852 This is the first time that the token is actually not a literal (not in
853 single quotes), but just called string. Other possible tokens are word
854 (the same as string, but stops matching at a whitespace) and end
855 (matches the end of the input).
856 workspace number <number>::
857 The workspace command has to be followed by the keyword +number+. It
858 then transitions into the state +WORKSPACE_NUMBER+, where the actual
859 parameter will be read.
860
861 === Introducing a new command
862
863 The following steps have to be taken in order to properly introduce a new
864 command (or possibly extend an existing command):
865
866 1. Define a function beginning with +cmd_+ in the file +src/commands.c+. Copy
867 the prototype of an existing function.
868 2. After adding a comment on what the function does, copy the comment and
869 function definition to +include/commands.h+. Make the comment in the header
870 file use double asterisks to make doxygen pick it up.
871 3. Write a test case (or extend an existing test case) for your feature, see
872 link:testsuite.html[i3 testsuite]. For now, it is sufficient to simply call
873 your command in all the various possible ways.
874 4. Extend the parser specification in +parser-specs/commands.spec+. Run the
875 testsuite and see if your new function gets called with the appropriate
876 arguments for the appropriate input.
877 5. Actually implement the feature.
878 6. Document the feature in the link:userguide.html[User’s Guide].
879
880 == Moving containers
881
882 The movement code is pretty delicate. You need to consider all cases before
883 making any changes or before being able to fully understand how it works.
884
885 === Case 1: Moving inside the same container
886
887 The reference layout for this case is a single workspace in horizontal
888 orientation with two containers on it. Focus is on the left container (1).
889
890
891 [width="15%",cols="^,^"]
892 |========
893 | 1 | 2
894 |========
895
896 When moving the left window to the right (command +move right+), tree_move will
897 look for a container with horizontal orientation and finds the parent of the
898 left container, that is, the workspace. Afterwards, it runs the code branch
899 commented with "the easy case": it calls TAILQ_NEXT to get the container right
900 of the current one and swaps both containers.
901
902 === Case 2: Move a container into a split container
903
904 The reference layout for this case is a horizontal workspace with two
905 containers. The right container is a v-split with two containers. Focus is on
906 the left container (1).
907
908 [width="15%",cols="^,^"]
909 |========
910 1.2+^.^| 1 | 2
911 | 3
912 |========
913
914 When moving to the right (command +move right+), i3 will work like in case 1
915 ("the easy case"). However, as the right container is not a leaf container, but
916 a v-split, the left container (1) will be inserted at the right position (below
917 2, assuming that 2 is focused inside the v-split) by calling +insert_con_into+.
918
919 +insert_con_into+ detaches the container from its parent and inserts it
920 before/after the given target container. Afterwards, the on_remove_child
921 callback is called on the old parent container which will then be closed, if
922 empty.
923
924 Afterwards, +con_focus+ will be called to fix the focus stack and the tree will
925 be flattened.
926
927 === Case 3: Moving to non-existent top/bottom
928
929 Like in case 1, the reference layout for this case is a single workspace in
930 horizontal orientation with two containers on it. Focus is on the left
931 container:
932
933 [width="15%",cols="^,^"]
934 |========
935 | 1 | 2
936 |========
937
938 This time however, the command is +move up+ or +move down+. tree_move will look
939 for a container with vertical orientation. As it will not find any,
940 +same_orientation+ is NULL and therefore i3 will perform a forced orientation
941 change on the workspace by creating a new h-split container, moving the
942 workspace contents into it and then changing the workspace orientation to
943 vertical. Now it will again search for parent containers with vertical
944 orientation and it will find the workspace.
945
946 This time, the easy case code path will not be run as we are not moving inside
947 the same container. Instead, +insert_con_into+ will be called with the focused
948 container and the container above/below the current one (on the level of
949 +same_orientation+).
950
951 Now, +con_focus+ will be called to fix the focus stack and the tree will be
952 flattened.
953
954 === Case 4: Moving to existent top/bottom
955
956 The reference layout for this case is a vertical workspace with two containers.
957 The bottom one is a h-split containing two containers (1 and 2). Focus is on
958 the bottom left container (1).
959
960 [width="15%",cols="^,^"]
961 |========
962 2+| 3
963 | 1 | 2
964 |========
965
966 This case is very much like case 3, only this time the forced workspace
967 orientation change does not need to be performed because the workspace already
968 is in vertical orientation.
969
970 === Case 5: Moving in one-child h-split
971
972 The reference layout for this case is a horizontal workspace with two
973 containers having a v-split on the left side with a one-child h-split on the
974 bottom. Focus is on the bottom left container (2(h)):
975
976 [width="15%",cols="^,^"]
977 |========
978 | 1 1.2+^.^| 3
979 | 2(h)
980 |========
981
982 In this case, +same_orientation+ will be set to the h-split container around
983 the focused container. However, when trying the easy case, the next/previous
984 container +swap+ will be NULL. Therefore, i3 will search again for a
985 +same_orientation+ container, this time starting from the parent of the h-split
986 container.
987
988 After determining a new +same_orientation+ container (if it is NULL, the
989 orientation will be force-changed), this case is equivalent to case 2 or case
990 4.
991
992
993 === Case 6: Floating containers
994
995 The reference layout for this case is a horizontal workspace with two
996 containers plus one floating h-split container. Focus is on the floating
997 container.
998
999 TODO: nice illustration. table not possible?
1000
1001 When moving up/down, the container needs to leave the floating container and it
1002 needs to be placed on the workspace (at workspace level). This is accomplished
1003 by calling the function +attach_to_workspace+.
1004
1005 == Click handling
1006
1007 Without much ado, here is the list of cases which need to be considered:
1008
1009 * click to focus (tiling + floating) and raise (floating)
1010 * click to focus/raise when in stacked/tabbed mode
1011 * floating_modifier + left mouse button to drag a floating con
1012 * floating_modifier + right mouse button to resize a floating con
1013 * click on decoration in a floating con to either initiate a resize (if there
1014 is more than one child in the floating con) or to drag the
1015 floating con (if it’s the one at the top).
1016 * click on border in a floating con to resize the floating con
1017 * floating_modifier + right mouse button to resize a tiling con
1018 * click on border/decoration to resize a tiling con
1019
1020 == Gotchas
1021
1022 * Forgetting to call `xcb_flush(conn);` after sending a request. This usually
1023 leads to code which looks like it works fine but which does not work under
1024 certain conditions.
1025
1026 * Forgetting to call `floating_fix_coordinates(con, old_rect, new_rect)` after
1027 moving workspaces across outputs. Coordinates for floating containers are
1028 not relative to workspace boundaries, so you must correct their coordinates
1029 or those containers will show up in the wrong workspace or not at all.
1030
1031 == Thought experiments
1032
1033 In this section, we collect thought experiments, so that we don’t forget our
1034 thoughts about specific topics. They are not necessary to get into hacking i3,
1035 but if you are interested in one of the topics they cover, you should read them
1036 before asking us why things are the way they are or why we don’t implement
1037 things.
1038
1039 === Using cgroups per workspace
1040
1041 cgroups (control groups) are a linux-only feature which provides the ability to
1042 group multiple processes. For each group, you can individually set resource
1043 limits, like allowed memory usage. Furthermore, and more importantly for our
1044 purposes, they serve as a namespace, a label which you can attach to processes
1045 and their children.
1046
1047 One interesting use for cgroups is having one cgroup per workspace (or
1048 container, doesn’t really matter). That way, you could set different priorities
1049 and have a workspace for important stuff (say, writing a LaTeX document or
1050 programming) and a workspace for unimportant background stuff (say,
1051 JDownloader). Both tasks can obviously consume a lot of I/O resources, but in
1052 this example it doesn’t really matter if JDownloader unpacks the download a
1053 minute earlier or not. However, your compiler should work as fast as possible.
1054 Having one cgroup per workspace, you would assign more resources to the
1055 programming workspace.
1056
1057 Another interesting feature is that an inherent problem of the workspace
1058 concept could be solved by using cgroups: When starting an application on
1059 workspace 1, then switching to workspace 2, you will get the application’s
1060 window(s) on workspace 2 instead of the one you started it on. This is because
1061 the window manager does not have any mapping between the process it starts (or
1062 gets started in any way) and the window(s) which appear.
1063
1064 Imagine for example using dmenu: The user starts dmenu by pressing Mod+d, dmenu
1065 gets started with PID 3390. The user then decides to launch Firefox, which
1066 takes a long time. So they enter firefox into dmenu and press enter. Firefox
1067 gets started with PID 4001. When it finally finishes loading, it creates an X11
1068 window and uses MapWindow to make it visible. This is the first time i3
1069 actually gets in touch with Firefox. It decides to map the window, but it has
1070 no way of knowing that this window (even though it has the _NET_WM_PID property
1071 set to 4001) belongs to the dmenu the user started before.
1072
1073 How do cgroups help with this? Well, when pressing Mod+d to launch dmenu, i3
1074 would create a new cgroup, let’s call it i3-3390-1. It launches dmenu in that
1075 cgroup, which gets PID 3390. As before, the user enters firefox and Firefox
1076 gets launched with PID 4001. This time, though, the Firefox process with PID
1077 4001 is *also* member of the cgroup i3-3390-1 (because fork()ing in a cgroup
1078 retains the cgroup property). Therefore, when mapping the window, i3 can look
1079 up in which cgroup the process is and can establish a mapping between the
1080 workspace and the window.
1081
1082 There are multiple problems with this approach:
1083
1084 . Every application has to properly set +_NET_WM_PID+. This is acceptable and
1085 patches can be written for the few applications which don’t set the hint yet.
1086 . It does only work on Linux, since cgroups are a Linux-only feature. Again,
1087 this is acceptable.
1088 . The main problem is that some applications create X11 windows completely
1089 independent of UNIX processes. An example for this is Chromium (or
1090 gnome-terminal), which, when being started a second time, communicates with
1091 the first process and lets the first process open a new window. Therefore, if
1092 you have a Chromium window on workspace 2 and you are currently working on
1093 workspace 3, starting +chromium+ does not lead to the desired result (the
1094 window will open on workspace 2).
1095
1096 Therefore, my conclusion is that the only proper way of fixing the "window gets
1097 opened on the wrong workspace" problem is in the application itself. Most
1098 modern applications support freedesktop startup-notifications which can be
1099 used for this.
0 #!/usr/bin/env perl
1 # vim:ts=4:sw=4:expandtab
2
3 use strict;
4 use warnings;
5 use Pod::Simple::HTML;
6 use Getopt::Long;
7 use v5.10;
8
9 my $stylesurl = '';
10
11 GetOptions("stylesurl=s" => \$stylesurl)
12 or die "parsing flags";
13
14 $Pod::Simple::HTML::Tagmap{'Verbatim'} = '<pre><tt>';
15 $Pod::Simple::HTML::Tagmap{'VerbatimFormatted'} = '<pre><tt>';
16 $Pod::Simple::HTML::Tagmap{'/Verbatim'} = '</tt></pre>';
17 $Pod::Simple::HTML::Tagmap{'/VerbatimFormatted'} = '</tt></pre>';
18
19 if (@ARGV < 2) {
20 say STDERR "Syntax: i3-pod2html <pod-input-path> <html-output-path>";
21 exit 1;
22 }
23
24 open(my $in, '<', $ARGV[0]) or die "Couldn’t open $ARGV[0] for reading: $!\n";
25 open(my $out, '>', $ARGV[1]) or die "Couldn’t open $ARGV[1] for writing: $!\n";
26
27 my $parser = Pod::Simple::HTML->new();
28
29 $parser->index(1);
30 if ($stylesurl ne '') {
31 $parser->html_header_before_title(
32 <<EOF
33 <!doctype html>
34 <html lang="en">
35 <head>
36 <link rel="icon" type="image/png" href="/favicon.png">
37 <meta charset="utf-8">
38 <meta name="generator" content="Pod::Simple::HTML">
39 <meta name="description" content="i3 Perl documentation">
40 <link rel="stylesheet" href="$stylesurl/style.css" type="text/css" />
41 <style type="text/css">
42 .pod pre {
43 background: #333;
44 border: 1px solid #555;
45 border-left: 5px solid #555;
46 padding: 0.5em;
47 padding-left: 0;
48 padding-right: 0.5em;
49 white-space: pre;
50 color: white;
51 }
52
53 .pod ul {
54 list-style-type: none;
55 }
56 .pod li {
57 margin-bottom: 0 !important;
58 }
59
60 tt {
61 font-family: 'Droid Sans Mono', sans-serif;
62 font-size: inherit;
63 }
64
65 .pod h1 a, .pod h2 a, .pod h3 a, .pod h4 a {
66 text-decoration: none;
67 color: white;
68 }
69 </style>
70 <title>
71 EOF
72 );
73 }
74 $parser->html_header_after_title(
75 <<'EOF'
76 </title>
77 </head>
78 <body>
79
80 <div id="main">
81 <a href="/"><h1 id="title">i3 - improved tiling WM</h1></a>
82 <ul id="nav">
83 <li><a style="border-bottom: 2px solid #fff" href="/docs">Docs</a></li>
84 <li><a href="/screenshots">Screens</a></li>
85 <li><a href="https://www.reddit.com/r/i3wm/">FAQ</a></li>
86 <li><a href="/contact">Contact</a></li>
87 <li><a href="https://bugs.i3wm.org/">Bugs</a></li>
88 </ul>
89 <br style="clear: both">
90 <div id="content" class="pod">
91 <h1>i3 Perl documentation</h1>
92
93 EOF
94 );
95
96 $parser->output_fh($out);
97 $parser->parse_file($in);
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 i3bar input protocol
1 ====================
2 Michael Stapelberg <[email protected]>
3 August 2012
4
5 This document explains the protocol in which i3bar expects its input. It
6 provides support for colors, urgency, shortening and easy manipulation.
7
8 == Rationale for choosing JSON
9
10 Before describing the protocol, let’s cover why JSON is a building block of
11 this protocol.
12
13 1. Other bar display programs such as dzen2 or xmobar are using in-band
14 signaling: they recognize certain sequences (like ^fg(#330000) in your input
15 text). We would like to avoid that and separate information from
16 meta-information. By information, we mean the actual output, like the IP
17 address of your ethernet adapter and by meta-information, we mean in which
18 color it should be displayed right now.
19 2. It is easy to write a simple script which manipulates part(s) of the input.
20 Each block of information (like a block for the disk space indicator, a block
21 for the current IP address, etc.) can be identified specifically and modified
22 in whichever way you like.
23 3. It remains easy to write a simple script which just suffixes (or prefixes) a
24 status line input, because tools like i3status will output their JSON in
25 such a way that each line array will be terminated by a newline. Therefore,
26 you are not required to use a streaming JSON parser, but you can use any
27 JSON parser and write your script in any programming language. In fact, you
28 can decide to not bother with the JSON parsing at all and just inject your
29 output at a specific position (beginning or end).
30 4. Relying on JSON does not introduce any new dependencies. In fact, the IPC
31 interface of i3 also uses JSON, therefore i3bar already depends on JSON.
32
33 The only point against using JSON is computational complexity. If that really
34 bothers you, just use the plain text input format (which i3bar will continue to
35 support).
36
37 == The protocol
38
39 The first message of the protocol is a header block, which contains (at least)
40 the version of the protocol to be used. In case there are significant changes
41 (not only additions), the version will be incremented. i3bar will still
42 understand the old protocol version, but in order to use the new one, you need
43 to provide the correct version. The header block is terminated by a newline and
44 consists of a single JSON hash:
45
46 *Minimal example*:
47 ------------------------------
48 { "version": 1 }
49 ------------------------------
50
51 *All features example*:
52 ------------------------------
53 { "version": 1, "stop_signal": 10, "cont_signal": 12, "click_events": true }
54 ------------------------------
55
56 (Note that before i3 v4.3 the precise format had to be +{"version":1}+,
57 byte-for-byte.)
58
59 What follows is an infinite array (so it should be parsed by a streaming JSON
60 parser, but as described above you can go for a simpler solution), whose
61 elements are one array per status line. A status line is one unit of
62 information which should be displayed at a time. i3bar will not display any
63 input until the status line is complete. In each status line, every block will
64 be represented by a JSON hash:
65
66 *Example*:
67 ------
68 [
69
70 [
71 {
72 "full_text": "E: 10.0.0.1 (1000 Mbit/s)",
73 "color": "#00ff00"
74 },
75 {
76 "full_text": "2012-01-05 20:00:01"
77 }
78 ],
79
80 [
81 {
82 "full_text": "E: 10.0.0.1 (1000 Mbit/s)",
83 "color": "#00ff00"
84 },
85 {
86 "full_text": "2012-01-05 20:00:02"
87 }
88 ],
89
90 ------
91
92 Please note that this example was pretty printed for human consumption.
93 i3status and others will output single statuslines in one line, separated by
94 \n.
95
96 You can find an example of a shell script which can be used as your
97 +status_command+ in the bar configuration at
98 https://github.com/i3/i3/blob/next/contrib/trivial-bar-script.sh
99
100 === Header in detail
101
102 version::
103 The version number (as an integer) of the i3bar protocol you will use.
104 stop_signal::
105 Specify to i3bar the signal (as an integer) to send to stop your
106 processing.
107 The default value (if none is specified) is SIGSTOP.
108 cont_signal::
109 Specify to i3bar the signal (as an integer) to send to continue your
110 processing.
111 The default value (if none is specified) is SIGCONT.
112 click_events::
113 If specified and true i3bar will write an infinite array (same as above)
114 to your stdin.
115
116 === Blocks in detail
117
118 full_text::
119 The +full_text+ will be displayed by i3bar on the status line. This is the
120 only required key. If +full_text+ is an empty string, the block will be
121 skipped.
122 short_text::
123 Where appropriate, the +short_text+ (string) entry should also be
124 provided. It will be used in case the status line needs to be shortened
125 because it uses more space than your screen provides. For example, when
126 displaying an IPv6 address, the prefix is usually (!) more relevant
127 than the suffix, because the latter stays constant when using autoconf,
128 while the prefix changes. When displaying the date, the time is more
129 important than the date (it is more likely that you know which day it
130 is than what time it is).
131 color::
132 To make the current state of the information easy to spot, colors can
133 be used. For example, the wireless block could be displayed in red
134 (using the +color+ (string) entry) if the card is not associated with
135 any network and in green or yellow (depending on the signal strength)
136 when it is associated.
137 Colors are specified in hex (like in HTML), starting with a leading
138 hash sign. For example, +#ff0000+ means red.
139 background::
140 Overrides the background color for this particular block.
141 border::
142 Overrides the border color for this particular block.
143 border_top::
144 Defines the width (in pixels) of the top border of this block. Defaults
145 to 1.
146 border_right::
147 Defines the width (in pixels) of the right border of this block. Defaults
148 to 1.
149 border_bottom::
150 Defines the width (in pixels) of the bottom border of this block. Defaults
151 to 1.
152 border_left::
153 Defines the width (in pixels) of the left border of this block. Defaults
154 to 1.
155 min_width::
156 The minimum width (in pixels) of the block. If the content of the
157 +full_text+ key take less space than the specified min_width, the block
158 will be padded to the left and/or the right side, according to the +align+
159 key. This is useful when you want to prevent the whole status line to shift
160 when value take more or less space between each iteration.
161 The value can also be a string. In this case, the width of the text given
162 by +min_width+ determines the minimum width of the block. This is useful
163 when you want to set a sensible minimum width regardless of which font you
164 are using, and at what particular size.
165 align::
166 Align text on the +center+, +right+ or +left+ (default) of the block, when
167 the minimum width of the latter, specified by the +min_width+ key, is not
168 reached.
169 name and instance::
170 Every block should have a unique +name+ (string) entry so that it can
171 be easily identified in scripts which process the output. i3bar
172 completely ignores the name and instance fields. Make sure to also
173 specify an +instance+ (string) entry where appropriate. For example,
174 the user can have multiple disk space blocks for multiple mount points.
175 urgent::
176 A boolean which specifies whether the current value is urgent. Examples
177 are battery charge values below 1 percent or no more available disk
178 space (for non-root users). The presentation of urgency is up to i3bar.
179 separator::
180 A boolean which specifies whether a separator line should be drawn
181 after this block. The default is true, meaning the separator line will
182 be drawn. Note that if you disable the separator line, there will still
183 be a gap after the block, unless you also use +separator_block_width+.
184 separator_block_width::
185 The amount of pixels to leave blank after the block. In the middle of
186 this gap, a separator line will be drawn unless +separator+ is
187 disabled. Normally, you want to set this to an odd value (the default
188 is 9 pixels), since the separator line is drawn in the middle.
189 markup::
190 A string that indicates how the text of the block should be parsed. Set to
191 +"pango"+ to use https://developer.gnome.org/pango/stable/pango-Markup.html[Pango markup].
192 Set to +"none"+ to not use any markup (default). Pango markup only works
193 if you use a pango font.
194
195 If you want to put in your own entries into a block, prefix the key with an
196 underscore (_). i3bar will ignore all keys it doesn’t understand, and prefixing
197 them with an underscore makes it clear in every script that they are not part
198 of the i3bar protocol.
199
200 *Example*:
201 ------------------------------------------
202 {
203 "full_text": "E: 10.0.0.1 (1000 Mbit/s)",
204 "_ethernet_vendor": "Intel"
205 }
206 ------------------------------------------
207
208 In the following example, the longest (widest) possible value of the block is
209 used to set the minimum width:
210
211 ------------------------------------------
212 {
213 "full_text": "CPU 4%",
214 "min_width": "CPU 100%",
215 "align": "left"
216 }
217 ------------------------------------------
218
219 An example of a block which uses all possible entries follows:
220
221 *Example*:
222 ------------------------------------------
223 {
224 "full_text": "E: 10.0.0.1 (1000 Mbit/s)",
225 "short_text": "10.0.0.1",
226 "color": "#00ff00",
227 "background": "#1c1c1c",
228 "border": "#ee0000",
229 "border_top": 1,
230 "border_right": 0,
231 "border_bottom": 3,
232 "border_left": 1,
233 "min_width": 300,
234 "align": "right",
235 "urgent": false,
236 "name": "ethernet",
237 "instance": "eth0",
238 "separator": true,
239 "separator_block_width": 9,
240 "markup": "none"
241 }
242 ------------------------------------------
243
244 === Click events
245
246 If enabled i3bar will send you notifications if the user clicks on a block and
247 looks like this:
248
249 name::
250 Name of the block, if set
251 instance::
252 Instance of the block, if set
253 x, y::
254 X11 root window coordinates where the click occurred
255 button::
256 X11 button ID (for example 1 to 3 for left/middle/right mouse button)
257 relative_x, relative_y::
258 Coordinates where the click occurred, with respect to the top left corner
259 of the block
260 width, height::
261 Width and height (in px) of the block
262 modifiers::
263 An array of the modifiers active when the click occurred. The order in which
264 modifiers are listed is not guaranteed.
265
266 *Example*:
267 ------------------------------------------
268 {
269 "name": "ethernet",
270 "instance": "eth0",
271 "button": 1,
272 "modifiers": ["Shift", "Mod1"],
273 "x": 1320,
274 "y": 1400,
275 "relative_x": 12,
276 "relative_y": 8,
277 "width": 50,
278 "height": 22
279 }
280 ------------------------------------------
0 IPC interface (interprocess communication)
1 ==========================================
2 Michael Stapelberg <[email protected]>
3 September 2017
4
5 This document describes how to interface with i3 from a separate process. This
6 is useful for example to remote-control i3 (to write test cases for example) or
7 to get various information like the current workspaces to implement an external
8 workspace bar.
9
10 The method of choice for IPC in our case is a unix socket because it has very
11 little overhead on both sides and is usually available without headaches in
12 most languages. In the default configuration file, the ipc-socket gets created
13 in +/tmp/i3-%u.XXXXXX/ipc-socket.%p+ where +%u+ is your UNIX username, +%p+ is
14 the PID of i3 and XXXXXX is a string of random characters from the portable
15 filename character set (see mkdtemp(3)). You can get the socketpath from i3 by
16 calling +i3 --get-socketpath+.
17
18 All i3 utilities, like +i3-msg+ and +i3-input+ will read the +I3_SOCKET_PATH+
19 X11 property, stored on the X11 root window.
20
21 [WARNING]
22 .Use an existing library!
23 There are existing libraries for many languages. You can have a look at
24 <<libraries>> or search the web if your language of choice is not mentioned.
25 Usually, it is not necessary to implement low-level communication with i3
26 directly.
27
28 == Establishing a connection
29
30 To establish a connection, simply open the IPC socket. The following code
31 snippet illustrates this in Perl:
32
33 -------------------------------------------------------------
34 use IO::Socket::UNIX;
35 chomp(my $path = qx(i3 --get-socketpath));
36 my $sock = IO::Socket::UNIX->new(Peer => $path);
37 -------------------------------------------------------------
38
39 == Sending messages to i3
40
41 To send a message to i3, you have to format in the binary message format which
42 i3 expects. This format specifies a magic string in the beginning to ensure
43 the integrity of messages (to prevent follow-up errors). Following the magic
44 string comes the length of the payload of the message as 32-bit integer, and
45 the type of the message as 32-bit integer (the integers are not converted, so
46 they are in native byte order).
47
48 The magic string currently is "i3-ipc" and will only be changed when a change
49 in the IPC API is done which breaks compatibility (we hope that we don’t need
50 to do that).
51
52 .Currently implemented message types
53 [options="header",cols="^10%,^20%,^20%,^50%"]
54 |======================================================
55 | Type (numeric) | Type (name) | Reply type | Purpose
56 | 0 | +RUN_COMMAND+ | <<_command_reply,COMMAND>> | Run the payload as an i3 command (like the commands you can bind to keys).
57 | 1 | +GET_WORKSPACES+ | <<_workspaces_reply,WORKSPACES>> | Get the list of current workspaces.
58 | 2 | +SUBSCRIBE+ | <<_subscribe_reply,SUBSCRIBE>> | Subscribe this IPC connection to the event types specified in the message payload. See <<events>>.
59 | 3 | +GET_OUTPUTS+ | <<_outputs_reply,OUTPUTS>> | Get the list of current outputs.
60 | 4 | +GET_TREE+ | <<_tree_reply,TREE>> | Get the i3 layout tree.
61 | 5 | +GET_MARKS+ | <<_marks_reply,MARKS>> | Gets the names of all currently set marks.
62 | 6 | +GET_BAR_CONFIG+ | <<_bar_config_reply,BAR_CONFIG>> | Gets the specified bar configuration or the names of all bar configurations if payload is empty.
63 | 7 | +GET_VERSION+ | <<_version_reply,VERSION>> | Gets the i3 version.
64 | 8 | +GET_BINDING_MODES+ | <<_binding_modes_reply,BINDING_MODES>> | Gets the names of all currently configured binding modes.
65 | 9 | +GET_CONFIG+ | <<_config_reply,CONFIG>> | Returns the last loaded i3 config.
66 | 10 | +SEND_TICK+ | <<_tick_reply,TICK>> | Sends a tick event with the specified payload.
67 | 11 | +SYNC+ | <<_sync_reply,SYNC>> | Sends an i3 sync event with the specified random value to the specified window.
68 |======================================================
69
70 So, a typical message could look like this:
71 --------------------------------------------------
72 "i3-ipc" <message length> <message type> <payload>
73 --------------------------------------------------
74
75 Or, as a hexdump:
76 ------------------------------------------------------------------------------
77 00000000 69 33 2d 69 70 63 04 00 00 00 00 00 00 00 65 78 |i3-ipc........ex|
78 00000010 69 74 |it|
79 ------------------------------------------------------------------------------
80
81 To generate and send such a message, you could use the following code in Perl:
82
83 -------------------------------------------------------------------------------
84 sub format_ipc_command {
85 my ($msg) = @_;
86 my $len;
87 # Get the real byte count (vs. amount of characters)
88 { use bytes; $len = length($msg); }
89 return "i3-ipc" . pack("LL", $len, 0) . $msg;
90 }
91
92 $sock->write(format_ipc_command("exit"));
93 -------------------------------------------------------------------------------
94
95 == Receiving replies from i3
96
97 Replies from i3 usually consist of a simple string (the length of the string
98 is the message_length, so you can consider them length-prefixed) which in turn
99 contain the JSON serialization of a data structure. For example, the
100 GET_WORKSPACES message returns an array of workspaces (each workspace is a map
101 with certain attributes).
102
103 === Reply format
104
105 The reply format is identical to the normal message format. There also is
106 the magic string, then the message length, then the message type and the
107 payload.
108
109 The following reply types are implemented:
110
111 COMMAND (0)::
112 Confirmation/Error code for the RUN_COMMAND message.
113 WORKSPACES (1)::
114 Reply to the GET_WORKSPACES message.
115 SUBSCRIBE (2)::
116 Confirmation/Error code for the SUBSCRIBE message.
117 OUTPUTS (3)::
118 Reply to the GET_OUTPUTS message.
119 TREE (4)::
120 Reply to the GET_TREE message.
121 MARKS (5)::
122 Reply to the GET_MARKS message.
123 BAR_CONFIG (6)::
124 Reply to the GET_BAR_CONFIG message.
125 VERSION (7)::
126 Reply to the GET_VERSION message.
127 BINDING_MODES (8)::
128 Reply to the GET_BINDING_MODES message.
129 GET_CONFIG (9)::
130 Reply to the GET_CONFIG message.
131 TICK (10)::
132 Reply to the SEND_TICK message.
133
134 [[_command_reply]]
135 === COMMAND reply
136
137 The reply consists of a list of serialized maps for each command that was
138 parsed. Each has the property +success (bool)+ and may also include a
139 human-readable error message in the property +error (string)+.
140
141 NOTE: When sending the `restart` command, you will get a singular reply once the
142 restart completed. All IPC connection states (e.g. subscriptions) will reset and
143 all but one socket will be closed. Libraries must be able to cope with this by
144 aligning their internal states. It is also recommended that libraries close
145 the last remaining socket(one which replied to `restart` command) to achieve
146 the full reset.
147
148 NOTE: It is easiest to always send the `restart` command alone: due to i3’s
149 state reset, the reply messages of preceding commands are lost, and following
150 commands will not be executed.
151
152 NOTE: When processing the `exit` command, i3 will immediately exit without
153 sending a reply. Expect the socket to be shut down.
154
155 *Example:*
156 -------------------
157 [{ "success": true }]
158 -------------------
159
160 [[_workspaces_reply]]
161 === WORKSPACES reply
162
163 The reply consists of a serialized list of workspaces. Each workspace has the
164 following properties:
165
166 id (integer)::
167 The internal ID (actually a C pointer value) of this container. Do not
168 make any assumptions about it. You can use it to (re-)identify and
169 address containers when talking to i3.
170 num (integer)::
171 The logical number of the workspace. Corresponds to the command
172 to switch to this workspace. For named workspaces, this will be -1.
173 name (string)::
174 The name of this workspace (by default num+1), as changed by the
175 user. Encoded in UTF-8.
176 visible (boolean)::
177 Whether this workspace is currently visible on an output (multiple
178 workspaces can be visible at the same time).
179 focused (boolean)::
180 Whether this workspace currently has the focus (only one workspace
181 can have the focus at the same time).
182 urgent (boolean)::
183 Whether a window on this workspace has the "urgent" flag set.
184 rect (map)::
185 The rectangle of this workspace (equals the rect of the output it
186 is on), consists of x, y, width, height.
187 output (string)::
188 The video output this workspace is on (LVDS1, VGA1, …).
189
190 *Example:*
191 -------------------
192 [
193 {
194 "num": 0,
195 "name": "1",
196 "visible": true,
197 "focused": true,
198 "urgent": false,
199 "rect": {
200 "x": 0,
201 "y": 0,
202 "width": 1280,
203 "height": 800
204 },
205 "output": "LVDS1"
206 },
207 {
208 "num": 1,
209 "name": "2",
210 "visible": false,
211 "focused": false,
212 "urgent": false,
213 "rect": {
214 "x": 0,
215 "y": 0,
216 "width": 1280,
217 "height": 800
218 },
219 "output": "LVDS1"
220 }
221 ]
222 -------------------
223
224 [[_subscribe_reply]]
225 === SUBSCRIBE reply
226
227 The reply consists of a single serialized map. The only property is
228 +success (bool)+, indicating whether the subscription was successful (the
229 default) or whether a JSON parse error occurred.
230
231 *Example:*
232 -------------------
233 { "success": true }
234 -------------------
235
236 [[_outputs_reply]]
237 === OUTPUTS reply
238
239 The reply consists of a serialized list of outputs. Each output has the
240 following properties:
241
242 name (string)::
243 The name of this output (as seen in +xrandr(1)+). Encoded in UTF-8.
244 active (boolean)::
245 Whether this output is currently active (has a valid mode).
246 primary (boolean)::
247 Whether this output is currently the primary output.
248 current_workspace (string)::
249 The name of the current workspace that is visible on this output. +null+ if
250 the output is not active.
251 rect (map)::
252 The rectangle of this output (equals the rect of the output it
253 is on), consists of x, y, width, height.
254
255 *Example:*
256 -------------------
257 [
258 {
259 "name": "LVDS1",
260 "active": true,
261 "current_workspace": "4",
262 "rect": {
263 "x": 0,
264 "y": 0,
265 "width": 1280,
266 "height": 800
267 }
268 },
269 {
270 "name": "VGA1",
271 "active": true,
272 "current_workspace": "1",
273 "rect": {
274 "x": 1280,
275 "y": 0,
276 "width": 1280,
277 "height": 1024
278 }
279 }
280 ]
281 -------------------
282
283 [[_tree_reply]]
284 === TREE reply
285
286 The reply consists of a serialized tree. Each node in the tree (representing
287 one container) has at least the properties listed below. While the nodes might
288 have more properties, please do not use any properties which are not documented
289 here. They are not yet finalized and will probably change!
290
291 id (integer)::
292 The internal ID (actually a C pointer value) of this container. Do not
293 make any assumptions about it. You can use it to (re-)identify and
294 address containers when talking to i3.
295 name (string)::
296 The internal name of this container. For all containers which are part
297 of the tree structure down to the workspace contents, this is set to a
298 nice human-readable name of the container.
299 For containers that have an X11 window, the content is the title
300 (_NET_WM_NAME property) of that window.
301 For all other containers, the content is not defined (yet).
302 type (string)::
303 Type of this container. Can be one of "root", "output", "con",
304 "floating_con", "workspace" or "dockarea".
305 border (string)::
306 Can be either "normal", "none" or "pixel", depending on the
307 container’s border style.
308 current_border_width (integer)::
309 Number of pixels of the border width.
310 layout (string)::
311 Can be either "splith", "splitv", "stacked", "tabbed", "dockarea" or
312 "output".
313 Other values might be possible in the future, should we add new
314 layouts.
315 orientation (string)::
316 Can be either "none" (for non-split containers), "horizontal" or
317 "vertical".
318 THIS FIELD IS OBSOLETE. It is still present, but your code should not
319 use it. Instead, rely on the layout field.
320 percent (float)::
321 The percentage which this container takes in its parent. A value of
322 +null+ means that the percent property does not make sense for this
323 container, for example for the root container.
324 rect (map)::
325 The absolute display coordinates for this container. Display
326 coordinates means that when you have two 1600x1200 monitors on a single
327 X11 Display (the standard way), the coordinates of the first window on
328 the second monitor are +{ "x": 1600, "y": 0, "width": 1600, "height":
329 1200 }+.
330 window_rect (map)::
331 The coordinates of the *actual client window* inside its container.
332 These coordinates are relative to the container and do not include the
333 window decoration (which is actually rendered on the parent container).
334 So, when using the +default+ layout, you will have a 2 pixel border on
335 each side, making the window_rect +{ "x": 2, "y": 0, "width": 632,
336 "height": 366 }+ (for example).
337 deco_rect (map)::
338 The coordinates of the *window decoration* inside its container. These
339 coordinates are relative to the container and do not include the actual
340 client window.
341 geometry (map)::
342 The original geometry the window specified when i3 mapped it. Used when
343 switching a window to floating mode, for example.
344 window (integer)::
345 The X11 window ID of the *actual client window* inside this container.
346 This field is set to null for split containers or otherwise empty
347 containers. This ID corresponds to what xwininfo(1) and other
348 X11-related tools display (usually in hex).
349 window_properties (map)::
350 This optional field contains all available X11 window properties from the
351 following list: *title*, *instance*, *class*, *window_role* and *transient_for*.
352 window_type (string)::
353 The window type (_NET_WM_WINDOW_TYPE). Possible values are undefined, normal,
354 dialog, utility, toolbar, splash, menu, dropdown_menu, popup_menu, tooltip and
355 notification.
356 urgent (bool)::
357 Whether this container (window, split container, floating container or
358 workspace) has the urgency hint set, directly or indirectly. All parent
359 containers up until the workspace container will be marked urgent if they
360 have at least one urgent child.
361 marks (array of string)::
362 List of marks assigned to container
363 focused (bool)::
364 Whether this container is currently focused.
365 focus (array of integer)::
366 List of child node IDs (see +nodes+, +floating_nodes+ and +id+) in focus
367 order. Traversing the tree by following the first entry in this array
368 will result in eventually reaching the one node with +focused+ set to
369 true.
370 fullscreen_mode (integer)::
371 Whether this container is in fullscreen state or not.
372 Possible values are
373 +0+ (no fullscreen),
374 +1+ (fullscreened on output) or
375 +2+ (fullscreened globally).
376 Note that all workspaces are considered fullscreened on their respective output.
377
378 nodes (array of node)::
379 The tiling (i.e. non-floating) child containers of this node.
380 floating_nodes (array of node)::
381 The floating child containers of this node. Only non-empty on nodes with
382 type +workspace+.
383
384 Please note that in the following example, I have left out some keys/values
385 which are not relevant for the type of the node. Otherwise, the example would
386 be by far too long (it already is quite long, despite showing only 1 window and
387 one dock window).
388
389 It is useful to have an overview of the structure before taking a look at the
390 JSON dump:
391
392 * root
393 ** LVDS1
394 *** topdock
395 *** content
396 **** workspace 1
397 ***** window 1
398 *** bottomdock
399 **** dock window 1
400 ** VGA1
401
402 *Example:*
403 -----------------------
404 {
405 "id": 6875648,
406 "name": "root",
407 "rect": {
408 "x": 0,
409 "y": 0,
410 "width": 1280,
411 "height": 800
412 },
413 "nodes": [
414
415 {
416 "id": 6878320,
417 "name": "LVDS1",
418 "layout": "output",
419 "rect": {
420 "x": 0,
421 "y": 0,
422 "width": 1280,
423 "height": 800
424 },
425 "nodes": [
426
427 {
428 "id": 6878784,
429 "name": "topdock",
430 "layout": "dockarea",
431 "orientation": "vertical",
432 "rect": {
433 "x": 0,
434 "y": 0,
435 "width": 1280,
436 "height": 0
437 }
438 },
439
440 {
441 "id": 6879344,
442 "name": "content",
443 "rect": {
444 "x": 0,
445 "y": 0,
446 "width": 1280,
447 "height": 782
448 },
449 "nodes": [
450
451 {
452 "id": 6880464,
453 "name": "1",
454 "orientation": "horizontal",
455 "rect": {
456 "x": 0,
457 "y": 0,
458 "width": 1280,
459 "height": 782
460 },
461 "window_properties": {
462 "class": "Evince",
463 "instance": "evince",
464 "title": "Properties",
465 "transient_for": 52428808
466 },
467 "floating_nodes": [],
468 "nodes": [
469
470 {
471 "id": 6929968,
472 "name": "#aa0000",
473 "border": "normal",
474 "percent": 1,
475 "rect": {
476 "x": 0,
477 "y": 18,
478 "width": 1280,
479 "height": 782
480 }
481 }
482
483 ]
484 }
485
486 ]
487 },
488
489 {
490 "id": 6880208,
491 "name": "bottomdock",
492 "layout": "dockarea",
493 "orientation": "vertical",
494 "rect": {
495 "x": 0,
496 "y": 782,
497 "width": 1280,
498 "height": 18
499 },
500 "nodes": [
501
502 {
503 "id": 6931312,
504 "name": "#00aa00",
505 "percent": 1,
506 "rect": {
507 "x": 0,
508 "y": 782,
509 "width": 1280,
510 "height": 18
511 }
512 }
513
514 ]
515 }
516 ]
517 }
518 ]
519 }
520 -----------------------
521
522 [[_marks_reply]]
523 === MARKS reply
524
525 The reply consists of a single array of strings for each container that has a
526 mark. A mark can only be set on one container, so the array is unique.
527 The order of that array is undefined.
528
529 If no window has a mark the response will be the empty array [].
530
531 [[_bar_config_reply]]
532 === BAR_CONFIG reply
533
534 This can be used by third-party workspace bars (especially i3bar, but others
535 are free to implement compatible alternatives) to get the +bar+ block
536 configuration from i3.
537
538 Depending on the input, the reply is either:
539
540 empty input::
541 An array of configured bar IDs
542 Bar ID::
543 A JSON map containing the configuration for the specified bar.
544
545 Each bar configuration has the following properties:
546
547 id (string)::
548 The ID for this bar. Included in case you request multiple
549 configurations and want to differentiate the different replies.
550 mode (string)::
551 Either +dock+ (the bar sets the dock window type) or +hide+ (the bar
552 does not show unless a specific key is pressed).
553 position (string)::
554 Either +bottom+ or +top+ at the moment.
555 status_command (string)::
556 Command which will be run to generate a statusline. Each line on stdout
557 of this command will be displayed in the bar. At the moment, no
558 formatting is supported.
559 font (string)::
560 The font to use for text on the bar.
561 workspace_buttons (boolean)::
562 Display workspace buttons or not? Defaults to true.
563 binding_mode_indicator (boolean)::
564 Display the mode indicator or not? Defaults to true.
565 verbose (boolean)::
566 Should the bar enable verbose output for debugging? Defaults to false.
567 colors (map)::
568 Contains key/value pairs of colors. Each value is a color code in hex,
569 formatted #rrggbb (like in HTML).
570
571 The following colors can be configured at the moment:
572
573 background::
574 Background color of the bar.
575 statusline::
576 Text color to be used for the statusline.
577 separator::
578 Text color to be used for the separator.
579 focused_background::
580 Background color of the bar on the currently focused monitor output.
581 focused_statusline::
582 Text color to be used for the statusline on the currently focused
583 monitor output.
584 focused_separator::
585 Text color to be used for the separator on the currently focused
586 monitor output.
587 focused_workspace_text/focused_workspace_bg/focused_workspace_border::
588 Text/background/border color for a workspace button when the workspace
589 has focus.
590 active_workspace_text/active_workspace_bg/active_workspace_border::
591 Text/background/border color for a workspace button when the workspace
592 is active (visible) on some output, but the focus is on another one.
593 You can only tell this apart from the focused workspace when you are
594 using multiple monitors.
595 inactive_workspace_text/inactive_workspace_bg/inactive_workspace_border::
596 Text/background/border color for a workspace button when the workspace
597 does not have focus and is not active (visible) on any output. This
598 will be the case for most workspaces.
599 urgent_workspace_text/urgent_workspace_bg/urgent_workspace_border::
600 Text/background/border color for workspaces which contain at least one
601 window with the urgency hint set.
602 binding_mode_text/binding_mode_bg/binding_mode_border::
603 Text/background/border color for the binding mode indicator.
604
605
606 *Example of configured bars:*
607 --------------
608 ["bar-bxuqzf"]
609 --------------
610
611 *Example of bar configuration:*
612 --------------
613 {
614 "id": "bar-bxuqzf",
615 "mode": "dock",
616 "position": "bottom",
617 "status_command": "i3status",
618 "font": "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1",
619 "workspace_buttons": true,
620 "binding_mode_indicator": true,
621 "verbose": false,
622 "colors": {
623 "background": "#c0c0c0",
624 "statusline": "#00ff00",
625 "focused_workspace_text": "#ffffff",
626 "focused_workspace_bg": "#000000"
627 }
628 }
629 --------------
630
631 [[_version_reply]]
632 === VERSION reply
633
634 The reply consists of a single JSON dictionary with the following keys:
635
636 major (integer)::
637 The major version of i3, such as +4+.
638 minor (integer)::
639 The minor version of i3, such as +2+. Changes in the IPC interface (new
640 features) will only occur with new minor (or major) releases. However,
641 bugfixes might be introduced in patch releases, too.
642 patch (integer)::
643 The patch version of i3, such as +1+ (when the complete version is
644 +4.2.1+). For versions such as +4.2+, patch will be set to +0+.
645 human_readable (string)::
646 A human-readable version of i3 containing the precise git version,
647 build date and branch name. When you need to display the i3 version to
648 your users, use the human-readable version whenever possible (since
649 this is what +i3 --version+ displays, too).
650 loaded_config_file_name (string)::
651 The current config path.
652
653 *Example:*
654 -------------------
655 {
656 "human_readable" : "4.2-169-gf80b877 (2012-08-05, branch \"next\")",
657 "loaded_config_file_name" : "/home/hwangcc23/.i3/config",
658 "minor" : 2,
659 "patch" : 0,
660 "major" : 4
661 }
662 -------------------
663
664 [[_binding_modes_reply]]
665 === BINDING_MODES reply
666
667 The reply consists of an array of all currently configured binding modes.
668
669 *Example:*
670 ---------------------
671 ["default", "resize"]
672 ---------------------
673
674 [[_config_reply]]
675 === CONFIG reply
676
677 The config reply is a map which currently only contains the "config" member,
678 which is a string containing the config file as loaded by i3 most recently.
679
680 *Example:*
681 -------------------
682 { "config": "font pango:monospace 8\nbindsym Mod4+q exit\n" }
683 -------------------
684
685 [[_tick_reply]]
686 === TICK reply
687
688 The reply is a map containing the "success" member. After the reply was
689 received, the tick event has been written to all IPC connections which subscribe
690 to tick events. UNIX sockets are usually buffered, but you can be certain that
691 once you receive the tick event you just triggered, you must have received all
692 events generated prior to the +SEND_TICK+ message (happened-before relation).
693
694 *Example:*
695 -------------------
696 { "success": true }
697 -------------------
698
699 [[_sync_reply]]
700 === SYNC reply
701
702 The reply is a map containing the "success" member. After the reply was
703 received, the https://i3wm.org/docs/testsuite.html#i3_sync[i3 sync message] was
704 responded to.
705
706 *Example:*
707 -------------------
708 { "success": true }
709 -------------------
710
711 == Events
712
713 [[events]]
714
715 To get informed when certain things happen in i3, clients can subscribe to
716 events. Events consist of a name (like "workspace") and an event reply type
717 (like I3_IPC_EVENT_WORKSPACE). Events sent by i3 follow a format similar to
718 replies but with the highest bit of the message type set to 1 to indicate an
719 event reply instead of a normal reply. Note that event types and reply types
720 do not follow the same enumeration scheme (e.g. event type 0 corresponds to the
721 workspace event however reply type 0 corresponds to the COMMAND reply).
722
723 Caveat: As soon as you subscribe to an event, it is not guaranteed any longer
724 that the requests to i3 are processed in order. This means, the following
725 situation can happen: You send a GET_WORKSPACES request but you receive a
726 "workspace" event before receiving the reply to GET_WORKSPACES. If your
727 program does not want to cope which such kinds of race conditions (an
728 event based library may not have a problem here), I suggest you create a
729 separate connection to receive events.
730
731 If an event message needs to be sent and the socket is not writeable (write
732 returns EAGAIN, happens when the socket doesn't have enough buffer space for
733 writing new data) then i3 uses a queue system to store outgoing messages for
734 each client. This is combined with a timer: if the message queue for a client is
735 not empty and no data where successfully written in the past 10 seconds, the
736 connection is killed. Practically, this means that your client should try to
737 always read events from the socket to avoid having its connection closed.
738
739 === Subscribing to events
740
741 By sending a message of type SUBSCRIBE with a JSON-encoded array as payload
742 you can register to an event.
743
744 *Example:*
745 ---------------------------------
746 type: SUBSCRIBE
747 payload: [ "workspace", "output" ]
748 ---------------------------------
749
750
751 === Available events
752
753 The numbers in parenthesis is the event type (keep in mind that you need to
754 strip the highest bit first).
755
756 workspace (0)::
757 Sent when the user switches to a different workspace, when a new
758 workspace is initialized or when a workspace is removed (because the
759 last client vanished).
760 output (1)::
761 Sent when RandR issues a change notification (of either screens,
762 outputs, CRTCs or output properties).
763 mode (2)::
764 Sent whenever i3 changes its binding mode.
765 window (3)::
766 Sent when a client's window is successfully reparented (that is when i3
767 has finished fitting it into a container), when a window received input
768 focus or when certain properties of the window have changed.
769 barconfig_update (4)::
770 Sent when the hidden_state or mode field in the barconfig of any bar
771 instance was updated and when the config is reloaded.
772 binding (5)::
773 Sent when a configured command binding is triggered with the keyboard or
774 mouse
775 shutdown (6)::
776 Sent when the ipc shuts down because of a restart or exit by user command
777 tick (7)::
778 Sent when the ipc client subscribes to the tick event (with +"first":
779 true+) or when any ipc client sends a SEND_TICK message (with +"first":
780 false+).
781
782 *Example:*
783 --------------------------------------------------------------------
784 # the appropriate 4 bytes read from the socket are stored in $input
785
786 # unpack a 32-bit unsigned integer
787 my $message_type = unpack("L", $input);
788
789 # check if the highest bit is 1
790 my $is_event = (($message_type >> 31) == 1);
791
792 # use the other bits
793 my $event_type = ($message_type & 0x7F);
794
795 if ($is_event) {
796 say "Received event of type $event_type";
797 }
798 --------------------------------------------------------------------
799
800 === workspace event
801
802 This event consists of a single serialized map containing a property
803 +change (string)+ which indicates the type of the change ("focus", "init",
804 "empty", "urgent", "reload", "rename", "restored", "move"). A
805 +current (object)+ property will be present with the affected workspace
806 whenever the type of event affects a workspace (otherwise, it will be +null+).
807
808 When the change is "focus", an +old (object)+ property will be present with the
809 previous workspace. When the first switch occurs (when i3 focuses the
810 workspace visible at the beginning) there is no previous workspace, and the
811 +old+ property will be set to +null+. Also note that if the previous is empty
812 it will get destroyed when switching, but will still be present in the "old"
813 property.
814
815 *Example:*
816 ---------------------
817 {
818 "change": "focus",
819 "current": {
820 "id": 28489712,
821 "type": "workspace",
822 ...
823 }
824 "old": {
825 "id": 28489715,
826 "type": "workspace",
827 ...
828 }
829 }
830 ---------------------
831
832 === output event
833
834 This event consists of a single serialized map containing a property
835 +change (string)+ which indicates the type of the change (currently only
836 "unspecified").
837
838 *Example:*
839 ---------------------------
840 { "change": "unspecified" }
841 ---------------------------
842
843 === mode event
844
845 This event consists of a single serialized map containing a property
846 +change (string)+ which holds the name of current mode in use. The name
847 is the same as specified in config when creating a mode. The default
848 mode is simply named default. It contains a second property, +pango_markup+, which
849 defines whether pango markup shall be used for displaying this mode.
850
851 *Example:*
852 ---------------------------
853 {
854 "change": "default",
855 "pango_markup": true
856 }
857 ---------------------------
858
859 === window event
860
861 This event consists of a single serialized map containing a property
862 +change (string)+ which indicates the type of the change
863
864 * +new+ – the window has become managed by i3
865 * +close+ – the window has closed
866 * +focus+ – the window has received input focus
867 * +title+ – the window's title has changed
868 * +fullscreen_mode+ – the window has entered or exited fullscreen mode
869 * +move+ – the window has changed its position in the tree
870 * +floating+ – the window has transitioned to or from floating
871 * +urgent+ – the window has become urgent or lost its urgent status
872 * +mark+ – a mark has been added to or removed from the window
873
874 Additionally a +container (object)+ field will be present, which consists
875 of the window's parent container. Be aware that for the "new" event, the
876 container will hold the initial name of the newly reparented window (e.g.
877 if you run urxvt with a shell that changes the title, you will still at
878 this point get the window title as "urxvt").
879
880 *Example:*
881 ---------------------------
882 {
883 "change": "new",
884 "container": {
885 "id": 35569536,
886 "type": "con",
887 ...
888 }
889 }
890 ---------------------------
891
892 === barconfig_update event
893
894 This event consists of a single serialized map reporting on options from the
895 barconfig of the specified bar_id that were updated in i3. This event is the
896 same as a +GET_BAR_CONFIG+ reply for the bar with the given id.
897
898 === binding event
899
900 This event consists of a single serialized map reporting on the details of a
901 binding that ran a command because of user input. The +change (string)+ field
902 indicates what sort of binding event was triggered (right now it will always be
903 +"run"+ but may be expanded in the future).
904
905 The +binding (object)+ field contains details about the binding that was run:
906
907 command (string)::
908 The i3 command that is configured to run for this binding.
909 event_state_mask (array of strings)::
910 The group and modifier keys that were configured with this binding.
911 input_code (integer)::
912 If the binding was configured with +bindcode+, this will be the key code
913 that was given for the binding. If the binding is a mouse binding, it will be
914 the number of the mouse button that was pressed. Otherwise it will be 0.
915 symbol (string or null)::
916 If this is a keyboard binding that was configured with +bindsym+, this
917 field will contain the given symbol. Otherwise it will be +null+.
918 input_type (string)::
919 This will be +"keyboard"+ or +"mouse"+ depending on whether or not this was
920 a keyboard or a mouse binding.
921
922 *Example:*
923 ---------------------------
924 {
925 "change": "run",
926 "binding": {
927 "command": "nop",
928 "event_state_mask": [
929 "shift",
930 "ctrl"
931 ],
932 "input_code": 0,
933 "symbol": "t",
934 "input_type": "keyboard"
935 }
936 }
937 ---------------------------
938
939 === shutdown event
940
941 This event is triggered when the connection to the ipc is about to shutdown
942 because of a user action such as a +restart+ or +exit+ command. The +change
943 (string)+ field indicates why the ipc is shutting down. It can be either
944 +"restart"+ or +"exit"+.
945
946 *Example:*
947 ---------------------------
948 {
949 "change": "restart"
950 }
951 ---------------------------
952
953 === tick event
954
955 This event is triggered by a subscription to tick events or by a +SEND_TICK+
956 message.
957
958 *Example (upon subscription):*
959 --------------------------------------------------------------------------------
960 {
961 "first": true,
962 "payload": ""
963 }
964 --------------------------------------------------------------------------------
965
966 *Example (upon +SEND_TICK+ with a payload of +arbitrary string+):*
967 --------------------------------------------------------------------------------
968 {
969 "first": false,
970 "payload": "arbitrary string"
971 }
972 --------------------------------------------------------------------------------
973
974 == See also (existing libraries)
975
976 [[libraries]]
977
978 For some languages, libraries are available (so you don’t have to implement
979 all this on your own). This list names some (if you wrote one, please let me
980 know):
981
982 C::
983 * i3 includes a headerfile +i3/ipc.h+ which provides you all constants.
984 * https://github.com/acrisci/i3ipc-glib
985 C++::
986 * https://github.com/Iskustvo/i3-ipcpp[i3-ipc++]
987 * https://github.com/drmgc/i3ipcpp
988 Go::
989 * https://github.com/mdirkse/i3ipc-go
990 * https://github.com/i3/go-i3
991 JavaScript::
992 * https://github.com/acrisci/i3ipc-gjs
993 Lua::
994 * https://github.com/acrisci/i3ipc-lua
995 Perl::
996 * https://metacpan.org/module/AnyEvent::I3
997 Python::
998 * https://github.com/acrisci/i3ipc-python
999 * https://github.com/whitelynx/i3ipc (not maintained)
1000 * https://github.com/ziberna/i3-py (not maintained)
1001 Ruby::
1002 * https://github.com/veelenga/i3ipc-ruby
1003 * https://github.com/badboy/i3-ipc (not maintained)
1004 Rust::
1005 * https://github.com/tmerr/i3ipc-rs
1006 OCaml::
1007 * https://github.com/Armael/ocaml-i3ipc
1008
1009 == Appendix A: Detecting byte order in memory-safe languages
1010
1011 Some programming languages such as Go don’t offer a way to serialize data in the
1012 native byte order of the machine they’re running on without resorting to tricks
1013 involving the +unsafe+ package.
1014
1015 The following technique can be used (and will not be broken by changes to i3) to
1016 detect the byte order i3 is using:
1017
1018 1. The byte order dependent fields of an IPC message are message type and
1019 payload length.
1020
1021 * The message type +RUN_COMMAND+ (0) is the same in big and little endian, so
1022 we can use it in either byte order to elicit a reply from i3.
1023
1024 * The payload length 65536 + 256 (+0x00 01 01 00+) is the same in big and
1025 little endian, and also small enough to not worry about memory allocations
1026 of that size. We must use payloads of length 65536 + 256 in every message
1027 we send, so that i3 will be able to read the entire message regardless of
1028 the byte order it uses.
1029
1030 2. Send a big endian encoded message of type +SUBSCRIBE+ (2) with payload `[]`
1031 followed by 65536 + 256 - 2 +SPACE+ (ASCII 0x20) bytes.
1032
1033 * If i3 is running in big endian, this message is treated as a noop,
1034 resulting in a +SUBSCRIBE+ reply with payload `{"success":true}`
1035 footnote:[A small payload is important: that way, we circumvent dealing
1036 with UNIX domain socket buffer sizes, whose size depends on the
1037 implementation/operating system. Exhausting such a buffer results in an i3
1038 deadlock unless you concurrently read and write, which — depending on the
1039 programming language — makes the technique much more complicated.].
1040
1041 * If i3 is running in little endian, this message is read in its entirety due
1042 to the byte order independent payload length, then
1043 https://github.com/i3/i3/blob/d726d09d496577d1c337a4b97486f2c9fbc914f1/src/ipc.c#L1188[silently
1044 discarded] due to the unknown message type.
1045
1046 3. Send a byte order independent message, i.e. type +RUN_COMMAND+ (0) with
1047 payload +nop byte order detection. padding:+, padded to 65536 + 256 bytes
1048 with +a+ (ASCII 0x61) bytes. i3 will reply to this message with a reply of
1049 type +COMMAND+ (0).
1050
1051 * The human-readable prefix is in there to not confuse readers of the i3 log.
1052
1053 * This messages serves as a synchronization primitive so that we know whether
1054 i3 discarded the +SUBSCRIBE+ message or didn’t answer it yet.
1055
1056 4. Receive a message header from i3, decoding the message type as big endian.
1057
1058 * If the message’s reply type is +COMMAND+ (0), i3 is running in little
1059 endian (because the +SUBSCRIBE+ message was discarded). Decode the message
1060 payload length as little endian, receive the message payload.
1061
1062 * If the message’s reply type is anything else, i3 is running in big endian
1063 (because our big endian encoded +SUBSCRIBE+ message was answered). Decode
1064 the message payload length in big endian, receive the message
1065 payload. Then, receive the pending +COMMAND+ message reply in big endian.
1066
1067 5. From here on out, send/receive all messages using the detected byte order.
1068
1069 Find an example implementation of this technique in
1070 https://github.com/i3/go-i3/blob/master/byteorder.go
Binary diff not shown
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="900"
12 height="300"
13 id="svg2"
14 sodipodi:version="0.32"
15 inkscape:version="0.48.1 r9760"
16 version="1.0"
17 sodipodi:docname="keyboard-layer1.svg"
18 inkscape:export-filename="/home/michael/i3/keyboard.png"
19 inkscape:export-xdpi="90"
20 inkscape:export-ydpi="90">
21 <defs
22 id="defs4">
23 <inkscape:perspective
24 sodipodi:type="inkscape:persp3d"
25 inkscape:vp_x="0 : 150 : 1"
26 inkscape:vp_y="0 : 1000 : 0"
27 inkscape:vp_z="900 : 150 : 1"
28 inkscape:persp3d-origin="450 : 100 : 1"
29 id="perspective174" />
30 <marker
31 inkscape:stockid="Arrow1Lend"
32 orient="auto"
33 refY="0.0"
34 refX="0.0"
35 id="Arrow1Lend"
36 style="overflow:visible;">
37 <path
38 id="path5387"
39 d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
40 style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
41 transform="scale(0.8) rotate(180)" />
42 </marker>
43 <marker
44 inkscape:stockid="Arrow1Lstart"
45 orient="auto"
46 refY="0.0"
47 refX="0.0"
48 id="Arrow1Lstart"
49 style="overflow:visible">
50 <path
51 id="path5390"
52 d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
53 style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
54 transform="scale(0.8)" />
55 </marker>
56 <marker
57 inkscape:stockid="Tail"
58 orient="auto"
59 refY="0.0"
60 refX="0.0"
61 id="Tail"
62 style="overflow:visible">
63 <g
64 id="g5342"
65 transform="scale(-1.2)">
66 <path
67 id="path5344"
68 d="M -3.8048674,-3.9585227 L 0.54352094,-0.00068114835"
69 style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
70 <path
71 id="path5346"
72 d="M -1.2866832,-3.9585227 L 3.0617053,-0.00068114835"
73 style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
74 <path
75 id="path5348"
76 d="M 1.3053582,-3.9585227 L 5.6537466,-0.00068114835"
77 style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
78 <path
79 id="path5350"
80 d="M -3.8048674,4.1775838 L 0.54352094,0.21974226"
81 style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
82 <path
83 id="path5352"
84 d="M -1.2866832,4.1775838 L 3.0617053,0.21974226"
85 style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
86 <path
87 id="path5354"
88 d="M 1.3053582,4.1775838 L 5.6537466,0.21974226"
89 style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
90 </g>
91 </marker>
92 <marker
93 inkscape:stockid="Arrow2Mend"
94 orient="auto"
95 refY="0.0"
96 refX="0.0"
97 id="Arrow2Mend"
98 style="overflow:visible;">
99 <path
100 id="path5363"
101 style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
102 d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
103 transform="scale(0.6) rotate(180) translate(-5,0)" />
104 </marker>
105 <marker
106 inkscape:stockid="Arrow2Lend"
107 orient="auto"
108 refY="0.0"
109 refX="0.0"
110 id="Arrow2Lend"
111 style="overflow:visible;">
112 <path
113 id="path5369"
114 style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
115 d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
116 transform="scale(1.1) rotate(180) translate(-5,0)" />
117 </marker>
118 <marker
119 inkscape:stockid="Arrow1Send"
120 orient="auto"
121 refY="0.0"
122 refX="0.0"
123 id="Arrow1Send"
124 style="overflow:visible;">
125 <path
126 id="path5375"
127 d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
128 style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
129 transform="scale(0.2) rotate(180)" />
130 </marker>
131 <marker
132 inkscape:stockid="Arrow2Send"
133 orient="auto"
134 refY="0.0"
135 refX="0.0"
136 id="Arrow2Send"
137 style="overflow:visible;">
138 <path
139 id="path5357"
140 style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
141 d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
142 transform="scale(0.3) rotate(180) translate(-5,0)" />
143 </marker>
144 <marker
145 inkscape:stockid="Arrow1Mend"
146 orient="auto"
147 refY="0.0"
148 refX="0.0"
149 id="Arrow1Mend"
150 style="overflow:visible;">
151 <path
152 id="path5381"
153 d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
154 style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
155 transform="scale(0.4) rotate(180)" />
156 </marker>
157 <marker
158 inkscape:stockid="Arrow2Lstart"
159 orient="auto"
160 refY="0.0"
161 refX="0.0"
162 id="Arrow2Lstart"
163 style="overflow:visible">
164 <path
165 id="path5372"
166 style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
167 d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
168 transform="scale(1.1) translate(-5,0)" />
169 </marker>
170 </defs>
171 <sodipodi:namedview
172 id="base"
173 pagecolor="#ffffff"
174 bordercolor="#666666"
175 borderopacity="1.0"
176 inkscape:pageopacity="0.0"
177 inkscape:pageshadow="2"
178 inkscape:zoom="1.0437869"
179 inkscape:cx="366.05395"
180 inkscape:cy="149.64675"
181 inkscape:document-units="px"
182 inkscape:current-layer="layer1"
183 inkscape:grid-points="true"
184 showgrid="true"
185 gridtolerance="15px"
186 showborder="false"
187 inkscape:window-width="956"
188 inkscape:window-height="1126"
189 inkscape:window-x="1600"
190 inkscape:window-y="54"
191 showguides="true"
192 inkscape:guide-bbox="true"
193 inkscape:snap-smooth-nodes="true"
194 inkscape:snap-to-guides="false"
195 inkscape:snap-grids="false"
196 inkscape:window-maximized="0">
197 <inkscape:grid
198 id="GridFromPre046Settings"
199 type="xygrid"
200 originx="0px"
201 originy="0px"
202 spacingx="7.5px"
203 spacingy="7.5px"
204 color="#0000ff"
205 empcolor="#0000ff"
206 opacity="0.12156863"
207 empopacity="0.25098039"
208 empspacing="4" />
209 </sodipodi:namedview>
210 <metadata
211 id="metadata7">
212 <rdf:RDF>
213 <cc:Work
214 rdf:about="">
215 <dc:format>image/svg+xml</dc:format>
216 <dc:type
217 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
218 </cc:Work>
219 </rdf:RDF>
220 </metadata>
221 <g
222 inkscape:label="Layer 1"
223 inkscape:groupmode="layer"
224 id="layer1">
225 <path
226 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
227 d="M 0,0 L 60,0 L 60,60 L 0,60 L 0,0 z "
228 id="rect2186" />
229 <path
230 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
231 d="M 60,0 L 120,0 L 120,60 L 60,60 L 60,0 z "
232 id="rect2218" />
233 <path
234 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
235 d="M 120,0 L 180,0 L 180,60 L 120,60 L 120,0 z "
236 id="rect2222" />
237 <path
238 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
239 d="M 180,0 L 240,0 L 240,60 L 180,60 L 180,0 z "
240 id="rect2228" />
241 <path
242 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
243 d="M 240,0 L 300,0 L 300,60 L 240,60 L 240,0 z "
244 id="rect2230" />
245 <path
246 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
247 d="M 300,0 L 360,0 L 360,60 L 300,60 L 300,0 z "
248 id="rect2232" />
249 <path
250 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
251 d="M 360,0 L 420,0 L 420,60 L 360,60 L 360,0 z "
252 id="rect2234" />
253 <path
254 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
255 d="M 420,0 L 480,0 L 480,60 L 420,60 L 420,0 z "
256 id="rect2236" />
257 <path
258 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
259 d="M 480,0 L 540,0 L 540,60 L 480,60 L 480,0 z "
260 id="rect2238" />
261 <path
262 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
263 d="M 540,0 L 600,0 L 600,60 L 540,60 L 540,0 z "
264 id="rect2240" />
265 <path
266 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
267 d="M 600,0 L 660,0 L 660,60 L 600,60 L 600,0 z "
268 id="rect2242" />
269 <path
270 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
271 d="M 660,0 L 720,0 L 720,60 L 660,60 L 660,0 z "
272 id="rect2244" />
273 <path
274 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
275 d="M 720,0 L 780,0 L 780,60 L 720,60 L 720,0 z "
276 id="rect2246" />
277 <path
278 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
279 d="M 780,0 L 900,0 L 900,60 L 780,60 L 780,0 z "
280 id="rect2248" />
281 <path
282 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
283 d="M 0,60 L 90,60 L 90,120 L 0,120 L 0,60 z "
284 id="rect2250" />
285 <path
286 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
287 d="M 90,60 L 150,60 L 150,120 L 90,120 L 90,60 z "
288 id="rect2252" />
289 <path
290 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
291 d="M 150,60 L 210,60 L 210,120 L 150,120 L 150,60 z "
292 id="rect2254" />
293 <path
294 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
295 d="M 210,60 L 270,60 L 270,120 L 210,120 L 210,60 z "
296 id="rect2256" />
297 <path
298 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
299 d="M 270,60 L 330,60 L 330,120 L 270,120 L 270,60 z "
300 id="rect2258" />
301 <path
302 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0"
303 d="m 330,60 60,0 0,60 -60,0 0,-60 z"
304 id="rect2262" />
305 <path
306 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
307 d="M 390,60 L 450,60 L 450,120 L 390,120 L 390,60 z "
308 id="rect2264" />
309 <path
310 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
311 d="M 450,60 L 510,60 L 510,120 L 450,120 L 450,60 z "
312 id="rect2266" />
313 <path
314 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
315 d="M 510,60 L 570,60 L 570,120 L 510,120 L 510,60 z "
316 id="rect2270" />
317 <path
318 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
319 d="M 570,60 L 630,60 L 630,120 L 570,120 L 570,60 z "
320 id="rect2272" />
321 <path
322 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
323 d="M 630,60 L 690,60 L 690,120 L 630,120 L 630,60 z "
324 id="rect2274" />
325 <path
326 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
327 d="M 690,60 L 750,60 L 750,120 L 690,120 L 690,60 z "
328 id="rect2278" />
329 <path
330 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
331 d="M 750,60 L 810,60 L 810,120 L 750,120 L 750,60 z "
332 id="rect2280" />
333 <path
334 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
335 d="M 810,60 L 900,60 L 900,120 L 810,120 L 810,60 z "
336 id="rect2284" />
337 <path
338 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
339 d="M 0,120 L 105,120 L 105,180 L 0,180 L 0,120 z "
340 id="rect2286" />
341 <path
342 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
343 d="M 105,120 L 165,120 L 165,180 L 105,180 L 105,120 z "
344 id="rect2292" />
345 <path
346 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
347 d="M 165,120 L 225,120 L 225,180 L 165,180 L 165,120 z "
348 id="rect2296" />
349 <path
350 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
351 d="M 225,120 L 285,120 L 285,180 L 225,180 L 225,120 z "
352 id="rect2298" />
353 <path
354 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
355 d="M 285,120 L 345,120 L 345,180 L 285,180 L 285,120 z "
356 id="rect2300" />
357 <path
358 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
359 d="M 345,120 L 405,120 L 405,180 L 345,180 L 345,120 z "
360 id="rect2302" />
361 <path
362 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
363 d="M 405,120 L 465,120 L 465,180 L 405,180 L 405,120 z "
364 id="rect2306" />
365 <path
366 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
367 d="M 465,120 L 525,120 L 525,180 L 465,180 L 465,120 z "
368 id="rect2308" />
369 <path
370 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
371 d="M 525,120 L 585,120 L 585,180 L 525,180 L 525,120 z "
372 id="rect2312" />
373 <path
374 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
375 d="M 585,120 L 645,120 L 645,180 L 585,180 L 585,120 z "
376 id="rect2314" />
377 <path
378 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
379 d="M 645,120 L 705,120 L 705,180 L 645,180 L 645,120 z "
380 id="rect2316" />
381 <path
382 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
383 d="M 705,120 L 765,120 L 765,180 L 705,180 L 705,120 z "
384 id="rect2318" />
385 <path
386 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
387 d="M 765,120 L 900,120 L 900,180 L 765,180 L 765,120 z "
388 id="rect2320" />
389 <path
390 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
391 d="M 0,180 L 135,180 L 135,240 L 0,240 L 0,180 z "
392 id="rect2322" />
393 <path
394 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
395 d="M 135,180 L 195,180 L 195,240 L 135,240 L 135,180 z "
396 id="rect2324" />
397 <path
398 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
399 d="M 195,180 L 255,180 L 255,240 L 195,240 L 195,180 z "
400 id="rect2326" />
401 <path
402 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
403 d="M 255,180 L 315,180 L 315,240 L 255,240 L 255,180 z "
404 id="rect2330" />
405 <path
406 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
407 d="M 315,180 L 375,180 L 375,240 L 315,240 L 315,180 z "
408 id="rect2334" />
409 <path
410 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
411 d="M 375,180 L 435,180 L 435,240 L 375,240 L 375,180 z "
412 id="rect2336" />
413 <path
414 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
415 d="M 435,180 L 495,180 L 495,240 L 435,240 L 435,180 z "
416 id="rect2338" />
417 <path
418 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
419 d="M 495,180 L 555,180 L 555,240 L 495,240 L 495,180 z "
420 id="rect2340" />
421 <path
422 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
423 d="M 555,180 L 615,180 L 615,240 L 555,240 L 555,180 z "
424 id="rect2342" />
425 <path
426 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
427 d="M 615,180 L 675,180 L 675,240 L 615,240 L 615,180 z "
428 id="rect2344" />
429 <path
430 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
431 d="M 675,180 L 735,180 L 735,240 L 675,240 L 675,180 z "
432 id="rect2346" />
433 <path
434 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
435 d="M 735,180 L 900,180 L 900,240 L 735,240 L 735,180 z "
436 id="rect2348" />
437 <path
438 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
439 d="M 0,240 L 90,240 L 90,300 L 0,300 L 0,240 z "
440 id="rect2350" />
441 <path
442 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
443 d="M 810,240 L 900,240 L 900,300 L 810,300 L 810,240 z "
444 id="rect2352" />
445 <path
446 style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
447 d="M 150,240 L 240,240 L 240,300 L 150,300 L 150,240 z "
448 id="rect2354" />
449 <path
450 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
451 d="M 600,240 L 690,240 L 690,300 L 600,300 L 600,240 z "
452 id="rect2360" />
453 <path
454 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
455 d="M 240,240 L 600,240 L 600,300 L 240,300 L 240,240 z "
456 id="rect2362" />
457 <path
458 style="fill:#efefef;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
459 d="M 90,240 L 150,240 L 150,300 L 90,300 L 90,240 z "
460 id="rect2364" />
461 <path
462 style="fill:#efefef;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
463 d="M 690,240 L 750,240 L 750,300 L 690,300 L 690,240 z "
464 id="rect2366" />
465 <path
466 style="fill:#efefef;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
467 d="M 750,240 L 810,240 L 810,300 L 750,300 L 750,240 z "
468 id="rect2368" />
469 <path
470 style=""
471 d=""
472 id="flowRoot4146" />
473 <path
474 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
475 d="M 75.351563,18.826172 L 74.4375,11.056641 L 74.4375,6.3691406 L 78.046875,6.3691406 L 78.046875,11.056641 L 77.132813,18.826172 L 75.351563,18.826172 M 74.484375,23.630859 L 74.484375,20.173828 L 77.964844,20.173828 L 77.964844,23.630859 L 74.484375,23.630859 M 75.351563,53.630859 L 75.351563,42.158203 L 71.34375,42.158203 L 71.34375,39.802734 L 71.601563,39.802734 C 73.062496,39.802748 74.124995,39.576186 74.789063,39.123047 C 75.460931,38.669937 75.855462,37.912125 75.972656,36.849609 L 78.65625,36.849609 L 78.65625,53.630859 L 75.351563,53.630859"
476 id="text5091" />
477 <path
478 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
479 d="M 23.34375,14.220703 L 23.34375,16.810547 C 22.531233,17.365241 21.761702,17.775396 21.035156,18.041016 C 20.316391,18.298833 19.605455,18.42774 18.902344,18.427734 C 18.542956,18.42774 18.183581,18.39649 17.824219,18.333984 C 17.464832,18.27149 17.105457,18.181646 16.746094,18.064453 C 16.558583,18.001959 16.281239,17.904303 15.914063,17.771484 C 14.203116,17.185553 12.902336,16.892585 12.011719,16.892578 C 11.34765,16.892585 10.652339,17.041022 9.9257813,17.337891 C 9.2070275,17.626959 8.3984345,18.091802 7.5,18.732422 L 7.5,16.142578 C 8.3359346,15.580086 9.1328088,15.162118 9.890625,14.888672 C 10.648432,14.607431 11.363275,14.466806 12.035156,14.466797 C 12.949211,14.466806 14.085929,14.693368 15.445313,15.146484 C 15.46874,15.154305 15.484365,15.158212 15.492188,15.158203 C 15.632802,15.205087 15.847646,15.279305 16.136719,15.380859 C 17.347644,15.810555 18.285143,16.025398 18.949219,16.025391 C 19.613267,16.025398 20.29686,15.880867 21,15.591797 C 21.703109,15.302743 22.484358,14.845712 23.34375,14.220703 M 11.988281,35.033203 L 15.011719,35.033203 L 17.320313,39.369141 L 15.65625,39.369141 L 11.988281,35.033203"
480 id="text5103" />
481 <path
482 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
483 d="M 136.47578,20.443359 C 136.04608,21.099612 135.54999,21.583986 134.9875,21.896484 C 134.42499,22.201173 133.76093,22.353517 132.99532,22.353516 C 131.76093,22.353517 130.81953,22.01758 130.1711,21.345703 C 129.53047,20.673831 129.21015,19.681645 129.21016,18.369141 C 129.21015,16.50196 129.75312,14.935556 130.83907,13.669922 C 131.93281,12.404308 133.27656,11.771496 134.87032,11.771484 C 135.4953,11.771496 136.03827,11.900402 136.49922,12.158203 C 136.96015,12.416027 137.33905,12.798839 137.63594,13.306641 L 138.25703,12.158203 L 140.34297,12.158203 L 138.62032,19.166016 C 138.59686,19.251958 138.57733,19.341801 138.56172,19.435547 C 138.54608,19.521488 138.53827,19.591801 138.53828,19.646484 C 138.53827,19.919926 138.63202,20.126957 138.81953,20.267578 C 139.00702,20.400394 139.28436,20.4668 139.65157,20.466797 C 139.95624,20.4668 140.27264,20.388675 140.60078,20.232422 C 140.9367,20.076175 141.2492,19.857426 141.53828,19.576172 C 142.21014,18.951177 142.71795,18.220709 143.06172,17.384766 C 143.41326,16.548835 143.58904,15.630867 143.58907,14.630859 C 143.58904,12.75587 142.86248,11.216809 141.40938,10.013672 C 139.96405,8.8027492 138.09686,8.1972811 135.80782,8.1972656 C 134.70624,8.1972811 133.6789,8.3300934 132.72578,8.5957031 C 131.78046,8.8613429 130.92109,9.2558737 130.14766,9.7792969 C 128.81953,10.669935 127.79609,11.783215 127.07735,13.119141 C 126.36641,14.455087 126.01094,15.91993 126.01094,17.513672 C 126.01094,19.912113 126.81953,21.83008 128.43672,23.267578 C 130.0539,24.697265 132.21406,25.412108 134.91719,25.412109 C 136.1828,25.412108 137.41718,25.220702 138.62032,24.837891 C 139.83124,24.455077 140.95623,23.90039 141.99532,23.173828 L 142.95625,24.544922 C 141.76092,25.443358 140.49139,26.119138 139.14766,26.572266 C 137.81171,27.025387 136.41718,27.25195 134.96407,27.251953 C 133.46405,27.25195 132.08515,27.060543 130.82735,26.677734 C 129.56953,26.302732 128.45234,25.744139 127.47578,25.001953 C 126.26484,24.05664 125.35859,22.966798 124.75703,21.732422 C 124.15547,20.49805 123.85469,19.099614 123.85469,17.537109 C 123.85469,16.232429 124.05781,14.990243 124.46407,13.810547 C 124.87813,12.623058 125.48359,11.544934 126.28047,10.576172 C 127.43672,9.1621238 128.82734,8.0918124 130.45235,7.3652344 C 132.07734,6.6386889 133.88593,6.275408 135.87813,6.2753906 C 137.19843,6.275408 138.43671,6.4550953 139.59297,6.8144531 C 140.75702,7.1660321 141.76873,7.6660316 142.62813,8.3144531 C 143.68279,9.1347801 144.46795,10.072279 144.9836,11.126953 C 145.50701,12.17384 145.76873,13.357432 145.76875,14.677734 C 145.76873,15.966805 145.51092,17.15821 144.99532,18.251953 C 144.48748,19.337895 143.75311,20.267581 142.79219,21.041016 C 142.2453,21.478518 141.64764,21.814455 140.99922,22.048828 C 140.35858,22.275392 139.69061,22.388673 138.99532,22.388672 C 138.16718,22.388673 137.54218,22.224611 137.12032,21.896484 C 136.70624,21.568361 136.4914,21.083987 136.47578,20.443359 M 137.06172,15.427734 C 136.96015,14.794931 136.73358,14.314462 136.38203,13.986328 C 136.03827,13.650401 135.58124,13.482432 135.01094,13.482422 C 134.1203,13.482432 133.34687,13.966807 132.69063,14.935547 C 132.03437,15.904305 131.70624,17.068366 131.70625,18.427734 C 131.70624,19.146489 131.86249,19.693363 132.175,20.068359 C 132.49531,20.443363 132.95624,20.630862 133.55782,20.630859 C 134.20624,20.630862 134.79608,20.384769 135.32735,19.892578 C 135.8664,19.400395 136.23358,18.75977 136.42891,17.970703 L 137.06172,15.427734 M 128.56563,53.630859 C 128.58125,52.130861 128.90156,50.861331 129.52657,49.822266 C 130.15156,48.775395 131.26094,47.716803 132.85469,46.646484 C 133.09687,46.482429 133.44844,46.255867 133.90938,45.966797 C 136.01875,44.615243 137.07343,43.314463 137.07344,42.064453 C 137.07343,41.322278 136.85078,40.736341 136.40547,40.306641 C 135.96015,39.876967 135.35078,39.662123 134.57735,39.662109 C 133.73359,39.662123 133.08125,39.927748 132.62032,40.458984 C 132.16719,40.982435 131.94062,41.732434 131.94063,42.708984 L 131.94063,42.849609 L 128.84688,42.849609 C 128.84688,40.927747 129.3625,39.44728 130.39375,38.408203 C 131.425,37.369157 132.89375,36.849626 134.8,36.849609 C 136.52656,36.849626 137.90546,37.322282 138.93672,38.267578 C 139.96796,39.205093 140.48358,40.455091 140.4836,42.017578 C 140.48358,43.134776 140.21405,44.103525 139.675,44.923828 C 139.13593,45.744149 138.09296,46.677741 136.5461,47.724609 C 136.21796,47.951178 135.76484,48.248052 135.18672,48.615234 C 133.71797,49.560551 132.88984,50.2793 132.70235,50.771484 L 140.31953,50.771484 L 140.31953,53.630859 L 128.56563,53.630859"
484 id="text5127" />
485 <path
486 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
487 d="M 195.28125,13.693359 L 194.25,16.552734 L 197.19141,16.552734 L 198.19922,13.693359 L 195.28125,13.693359 M 195.28125,6.4746094 L 197.87109,6.4746094 L 196.16016,11.337891 L 198.99609,11.337891 L 200.73047,6.4746094 L 203.32031,6.4746094 L 201.58594,11.337891 L 204.90234,11.337891 L 204.03516,13.693359 L 200.75391,13.693359 L 199.76953,16.529297 L 203.16797,16.529297 L 202.33594,18.873047 L 198.92578,18.873047 L 197.19141,23.748047 L 194.60156,23.748047 L 196.33594,18.873047 L 193.47656,18.873047 L 191.73047,23.748047 L 189.15234,23.748047 L 190.86328,18.873047 L 187.5,18.873047 L 188.39063,16.529297 L 191.69531,16.529297 L 192.70313,13.693359 L 189.19922,13.693359 L 190.06641,11.337891 L 193.54688,11.337891 L 195.28125,6.4746094 M 190.07813,48.521484 L 193.30078,48.521484 C 193.30859,49.458989 193.53515,50.166019 193.98047,50.642578 C 194.42578,51.111331 195.08593,51.345705 195.96094,51.345703 C 196.80468,51.345705 197.45312,51.126956 197.90625,50.689453 C 198.36718,50.244144 198.59765,49.607426 198.59766,48.779297 C 198.59765,47.951178 198.32812,47.326178 197.78906,46.904297 C 197.2578,46.474617 196.46484,46.259773 195.41016,46.259766 C 195.35546,46.259773 195.26953,46.263679 195.15234,46.271484 C 195.04296,46.279304 194.96093,46.28321 194.90625,46.283203 L 194.90625,43.962891 L 195.26953,43.962891 C 196.23827,43.9629 196.95312,43.7754 197.41406,43.400391 C 197.8828,43.017589 198.11718,42.435558 198.11719,41.654297 C 198.11718,41.005872 197.91796,40.494154 197.51953,40.119141 C 197.1289,39.736342 196.59374,39.544936 195.91406,39.544922 C 195.17187,39.544936 194.59765,39.763686 194.19141,40.201172 C 193.78515,40.638685 193.58203,41.259778 193.58203,42.064453 L 193.58203,42.205078 L 190.41797,42.205078 C 190.45703,40.486341 190.96094,39.169936 191.92969,38.255859 C 192.90625,37.334001 194.28125,36.873064 196.05469,36.873047 C 197.73437,36.873064 199.0664,37.283219 200.05078,38.103516 C 201.03514,38.923843 201.52733,40.02931 201.52734,41.419922 C 201.52733,42.154308 201.35936,42.798839 201.02344,43.353516 C 200.68749,43.908213 200.18358,44.365244 199.51172,44.724609 C 200.37108,45.099618 201.01952,45.619149 201.45703,46.283203 C 201.90233,46.93946 202.12499,47.724615 202.125,48.638672 C 202.12499,50.318363 201.57421,51.650393 200.47266,52.634766 C 199.37108,53.619141 197.86718,54.111328 195.96094,54.111328 C 194.07812,54.111328 192.625,53.634766 191.60156,52.681641 C 190.58594,51.720705 190.07812,50.357425 190.07813,48.591797 L 190.07813,48.521484"
488 id="text5139" />
489 <path
490 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
491 d="M 254.46094,21.451172 C 255.10155,21.365237 255.58984,21.134768 255.92578,20.759766 C 256.26171,20.384769 256.42968,19.884769 256.42969,19.259766 C 256.42968,18.705083 256.26952,18.248052 255.94922,17.888672 C 255.63671,17.52149 255.14062,17.236335 254.46094,17.033203 L 254.46094,21.451172 M 253.06641,13.435547 L 253.06641,9.4511719 C 252.45703,9.529311 251.99218,9.7402483 251.67188,10.083984 C 251.35156,10.419935 251.1914,10.87306 251.19141,11.443359 C 251.1914,11.919934 251.33984,12.318371 251.63672,12.638672 C 251.9414,12.958995 252.41796,13.22462 253.06641,13.435547 M 253.06641,26.267578 L 253.06641,24.017578 C 251.30078,23.908203 249.98047,23.396485 249.10547,22.482422 C 248.23047,21.568361 247.79297,20.24805 247.79297,18.521484 L 250.93359,18.521484 C 250.97265,19.365239 251.16796,20.033207 251.51953,20.525391 C 251.8789,21.009768 252.39453,21.318362 253.06641,21.451172 L 253.06641,16.599609 C 251.2539,16.138679 249.96484,15.537117 249.19922,14.794922 C 248.43359,14.052744 248.05078,13.03712 248.05078,11.748047 C 248.05078,10.318373 248.5039,9.1660301 249.41016,8.2910156 C 250.32422,7.4160318 251.54296,6.959001 253.06641,6.9199219 L 253.06641,5.4199219 L 254.46094,5.4199219 L 254.46094,6.9199219 C 255.98437,6.9980635 257.17186,7.4590005 258.02344,8.3027344 C 258.87499,9.1386864 259.34374,10.318373 259.42969,11.841797 L 256.24219,11.841797 C 256.18749,11.115247 256.01171,10.56056 255.71484,10.177734 C 255.42577,9.7871232 255.0078,9.5683734 254.46094,9.5214844 L 254.46094,13.787109 C 256.39062,14.388681 257.74999,15.07618 258.53906,15.849609 C 259.32811,16.623054 259.72264,17.642584 259.72266,18.908203 C 259.72264,20.400394 259.26171,21.591799 258.33984,22.482422 C 257.42577,23.373047 256.1328,23.892578 254.46094,24.041016 L 254.46094,26.267578 L 253.06641,26.267578 M 254.64844,47.419922 L 254.64844,40.236328 L 250.08984,47.419922 L 254.64844,47.419922 M 254.57813,53.630859 L 254.57813,50.009766 L 247.5,50.009766 L 247.5,47.056641 L 253.6875,37.330078 L 257.84766,37.330078 L 257.84766,47.337891 L 259.79297,47.337891 L 259.79297,50.009766 L 257.84766,50.009766 L 257.84766,53.630859 L 254.57813,53.630859"
492 id="text5145" />
493 <path
494 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
495 d="M 320.42578,19.740234 C 320.42577,20.263675 320.60155,20.705081 320.95313,21.064453 C 321.30467,21.416018 321.73827,21.591799 322.25391,21.591797 C 322.75389,21.591799 323.18358,21.412112 323.54297,21.052734 C 323.90233,20.68555 324.08201,20.24805 324.08203,19.740234 C 324.08201,19.240239 323.90233,18.814458 323.54297,18.462891 C 323.19139,18.103521 322.7617,17.923834 322.25391,17.923828 C 321.73827,17.923834 321.30467,18.099615 320.95313,18.451172 C 320.60155,18.794927 320.42577,19.224614 320.42578,19.740234 M 317.88281,19.740234 C 317.8828,18.521489 318.30468,17.494147 319.14844,16.658203 C 319.99217,15.822273 321.02733,15.404305 322.25391,15.404297 C 323.45701,15.404305 324.48045,15.830086 325.32422,16.681641 C 326.17576,17.525397 326.60154,18.544927 326.60156,19.740234 C 326.60154,20.943362 326.17576,21.974611 325.32422,22.833984 C 324.47264,23.685547 323.4492,24.111328 322.25391,24.111328 C 321.02733,24.111328 319.99217,23.689453 319.14844,22.845703 C 318.30468,22.001955 317.8828,20.9668 317.88281,19.740234 M 311.07422,24.111328 L 321.08203,6.8496094 L 322.96875,6.8496094 L 312.96094,24.111328 L 311.07422,24.111328 M 310.04297,11.220703 C 310.04297,11.73634 310.21484,12.169933 310.55859,12.521484 C 310.91015,12.873058 311.34375,13.048839 311.85938,13.048828 C 312.36718,13.048839 312.79687,12.873058 313.14844,12.521484 C 313.50781,12.162121 313.68749,11.728528 313.6875,11.220703 C 313.68749,10.720716 313.50781,10.294935 313.14844,9.9433594 C 312.79687,9.5839984 312.36718,9.4043111 311.85938,9.4042969 C 311.34375,9.4043111 310.91015,9.5800922 310.55859,9.9316406 C 310.21484,10.275404 310.04297,10.705091 310.04297,11.220703 M 307.5,11.220703 C 307.5,10.001967 307.92187,8.9707178 308.76563,8.1269531 C 309.60937,7.275407 310.64062,6.8496262 311.85938,6.8496094 C 313.06249,6.8496262 314.08593,7.2793132 314.92969,8.1386719 C 315.78124,8.990249 316.20702,10.017592 316.20703,11.220703 C 316.20702,12.423839 315.78124,13.451182 314.92969,14.302734 C 314.08593,15.146493 313.06249,15.568367 311.85938,15.568359 C 310.63281,15.568367 309.59765,15.150399 308.75391,14.314453 C 307.91797,13.478526 307.5,12.447277 307.5,11.220703 M 310.85156,49.119141 L 314.13281,49.119141 C 314.1875,49.853519 314.43359,50.423831 314.87109,50.830078 C 315.30859,51.228518 315.89453,51.427737 316.62891,51.427734 C 317.53515,51.427737 318.22655,51.162112 318.70313,50.630859 C 319.18749,50.099613 319.42968,49.337895 319.42969,48.345703 C 319.42968,47.416022 319.18358,46.685554 318.69141,46.154297 C 318.19921,45.615242 317.51952,45.345711 316.65234,45.345703 C 316.16796,45.345711 315.74218,45.443368 315.375,45.638672 C 315.00781,45.833992 314.69531,46.123054 314.4375,46.505859 L 311.41406,46.330078 L 312.50391,37.330078 L 322.14844,37.330078 L 322.14844,40.166016 L 314.87109,40.166016 L 314.4375,43.529297 C 314.80468,43.240245 315.22656,43.025401 315.70313,42.884766 C 316.17968,42.736339 316.71093,42.66212 317.29688,42.662109 C 318.96874,42.66212 320.3164,43.169932 321.33984,44.185547 C 322.37108,45.20118 322.88671,46.53321 322.88672,48.181641 C 322.88671,49.986332 322.3203,51.427737 321.1875,52.505859 C 320.05468,53.576172 318.53515,54.111328 316.62891,54.111328 C 314.89453,54.111328 313.51172,53.669922 312.48047,52.787109 C 311.45703,51.896486 310.91406,50.673831 310.85156,49.119141"
496 id="text5151" />
497 <path
498 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
499 d="M 373.13672,6.5214844 L 376.08984,6.5214844 L 381.72656,13.095703 L 378.97266,13.095703 L 374.625,8.7480469 L 370.25391,13.095703 L 367.5,13.095703 L 373.13672,6.5214844 M 372.15234,48.298828 C 372.15234,49.25977 372.39062,50.021488 372.86719,50.583984 C 373.35156,51.146487 374.00781,51.427737 374.83594,51.427734 C 375.60937,51.427737 376.21484,51.154299 376.65234,50.607422 C 377.08983,50.06055 377.30858,49.298832 377.30859,48.322266 C 377.30858,47.423834 377.08202,46.724616 376.62891,46.224609 C 376.17577,45.724617 375.53905,45.474618 374.71875,45.474609 C 373.91406,45.474618 373.28515,45.724617 372.83203,46.224609 C 372.3789,46.724616 372.15234,47.416022 372.15234,48.298828 M 372.10547,43.916016 C 372.48828,43.525401 372.94921,43.232432 373.48828,43.037109 C 374.02734,42.833995 374.6289,42.732433 375.29297,42.732422 C 376.93358,42.732433 378.24608,43.232432 379.23047,44.232422 C 380.22264,45.23243 380.71874,46.56446 380.71875,48.228516 C 380.71874,49.994144 380.17968,51.419924 379.10156,52.505859 C 378.02343,53.591797 376.60155,54.134765 374.83594,54.134766 C 372.79687,54.134765 371.24609,53.431641 370.18359,52.025391 C 369.1289,50.619144 368.60156,48.560552 368.60156,45.849609 C 368.60156,42.935558 369.16797,40.708997 370.30078,39.169922 C 371.43359,37.623063 373.0664,36.849626 375.19922,36.849609 C 376.68358,36.849626 377.8789,37.236345 378.78516,38.009766 C 379.69921,38.783218 380.19921,39.830092 380.28516,41.150391 L 376.88672,41.150391 C 376.80858,40.611341 376.59765,40.205092 376.25391,39.931641 C 375.91015,39.658217 375.42968,39.521498 374.8125,39.521484 C 373.96874,39.521498 373.32031,39.888686 372.86719,40.623047 C 372.41406,41.349622 372.16015,42.447277 372.10547,43.916016"
500 id="text5157" />
501 <path
502 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
503 d="M 432.85547,16.095703 L 431.96484,16.740234 C 431.60546,16.990241 431.33593,17.291022 431.15625,17.642578 C 430.97656,17.994146 430.88671,18.388677 430.88672,18.826172 C 430.88671,19.490239 431.11328,20.048832 431.56641,20.501953 C 432.01953,20.955081 432.58593,21.181643 433.26563,21.181641 C 433.76562,21.181643 434.24218,21.080081 434.69531,20.876953 C 435.15624,20.666019 435.58202,20.361331 435.97266,19.962891 L 432.85547,16.095703 M 433.79297,12.404297 L 434.20313,12.111328 C 434.57812,11.853527 434.85546,11.564465 435.03516,11.244141 C 435.21483,10.923841 435.30468,10.556654 435.30469,10.142578 C 435.30468,9.7441545 435.17968,9.4277486 434.92969,9.1933594 C 434.68749,8.958999 434.35546,8.8418117 433.93359,8.8417969 C 433.5039,8.8418117 433.16406,8.9629053 432.91406,9.2050781 C 432.66406,9.4394673 432.53906,9.7597795 432.53906,10.166016 C 432.53906,10.384779 432.59765,10.62306 432.71484,10.880859 C 432.83984,11.138684 433.01562,11.412122 433.24219,11.701172 L 433.79297,12.404297 M 431.15625,13.962891 L 430.47656,13.072266 C 430.125,12.603527 429.87109,12.166027 429.71484,11.759766 C 429.5664,11.345715 429.49218,10.912122 429.49219,10.458984 C 429.49218,9.2089988 429.89062,8.2168123 430.6875,7.4824219 C 431.49218,6.7402513 432.58203,6.3691579 433.95703,6.3691406 C 435.27733,6.3691579 436.3203,6.7090013 437.08594,7.3886719 C 437.85155,8.0683749 438.23436,8.9863428 438.23438,10.142578 C 438.23436,11.017591 438.0078,11.802746 437.55469,12.498047 C 437.10936,13.185557 436.40624,13.833994 435.44531,14.443359 L 437.91797,17.490234 C 438.15233,17.107428 438.33593,16.677741 438.46875,16.201172 C 438.60936,15.724617 438.70702,15.193368 438.76172,14.607422 L 441.80859,14.607422 C 441.72264,15.623055 441.5117,16.56446 441.17578,17.431641 C 440.83983,18.298833 440.37889,19.091801 439.79297,19.810547 L 442.93359,23.630859 L 438.94922,23.630859 L 437.77734,22.189453 C 437.08983,22.822266 436.33202,23.302735 435.50391,23.630859 C 434.68359,23.951172 433.82421,24.111328 432.92578,24.111328 C 431.33203,24.111328 430.02734,23.638672 429.01172,22.693359 C 428.0039,21.748049 427.5,20.541019 427.5,19.072266 C 427.5,17.978521 427.78125,17.037116 428.34375,16.248047 C 428.90625,15.458993 429.84375,14.697275 431.15625,13.962891 M 434.66016,53.630859 L 431.15625,53.630859 C 431.28125,51.341799 431.83203,49.07227 432.80859,46.822266 C 433.79296,44.572275 435.19531,42.361339 437.01563,40.189453 L 428.76563,40.189453 L 428.76563,37.330078 L 440.66016,37.330078 L 440.66016,39.849609 C 438.8164,41.880871 437.39843,44.029306 436.40625,46.294922 C 435.42187,48.560552 434.83984,51.005862 434.66016,53.630859"
504 id="text5163" />
505 <path
506 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
507 d="M 493.5,13.212891 L 491.4375,16.119141 L 489.44531,14.724609 L 491.69531,11.900391 L 488.41406,10.986328 L 489.17578,8.6074219 L 492.32813,9.7324219 L 492.32813,6.3691406 L 494.64844,6.3691406 L 494.64844,9.7324219 L 497.80078,8.6308594 L 498.58594,11.009766 L 495.30469,11.900391 L 497.53125,14.701172 L 495.49219,16.166016 L 493.5,13.212891 M 490.875,48.755859 C 490.875,49.576176 491.10156,50.208988 491.55469,50.654297 C 492.01562,51.099612 492.67187,51.322268 493.52344,51.322266 C 494.33593,51.322268 494.97265,51.095706 495.43359,50.642578 C 495.90233,50.189457 496.13671,49.560551 496.13672,48.755859 C 496.13671,47.982428 495.89843,47.361334 495.42188,46.892578 C 494.9453,46.423835 494.31249,46.189461 493.52344,46.189453 C 492.73437,46.189461 492.09374,46.427742 491.60156,46.904297 C 491.11718,47.380866 490.875,47.998053 490.875,48.755859 M 491.14453,41.560547 C 491.14453,42.208996 491.34765,42.708995 491.75391,43.060547 C 492.16015,43.404307 492.74218,43.576182 493.5,43.576172 C 494.2578,43.576182 494.83984,43.400401 495.24609,43.048828 C 495.66015,42.697277 495.86718,42.201183 495.86719,41.560547 C 495.86718,40.93556 495.65624,40.443373 495.23438,40.083984 C 494.81249,39.724623 494.23437,39.544936 493.5,39.544922 C 492.78124,39.544936 492.20703,39.72853 491.77734,40.095703 C 491.35546,40.462904 491.14453,40.951185 491.14453,41.560547 M 489.9375,44.818359 C 489.23437,44.427744 488.72656,43.970713 488.41406,43.447266 C 488.10156,42.923839 487.94531,42.255871 487.94531,41.443359 C 487.94531,40.005873 488.4375,38.876968 489.42188,38.056641 C 490.40625,37.236345 491.76562,36.826189 493.5,36.826172 C 495.24999,36.826189 496.61718,37.236345 497.60156,38.056641 C 498.59374,38.869155 499.08983,39.998061 499.08984,41.443359 C 499.08983,42.216808 498.92186,42.888683 498.58594,43.458984 C 498.24999,44.021494 497.74608,44.474619 497.07422,44.818359 C 497.89452,45.20118 498.51171,45.73243 498.92578,46.412109 C 499.33983,47.083991 499.54686,47.904303 499.54688,48.873047 C 499.54686,50.505862 499.0078,51.787111 497.92969,52.716797 C 496.85936,53.646484 495.3828,54.111328 493.5,54.111328 C 491.59375,54.111328 490.11328,53.650391 489.05859,52.728516 C 488.0039,51.806642 487.47656,50.521487 487.47656,48.873047 C 487.47656,47.912115 487.67187,47.107428 488.0625,46.458984 C 488.46094,45.802742 489.08594,45.255868 489.9375,44.818359"
508 id="text5169" />
509 <path
510 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
511 d="M 557.85938,6.3691406 C 556.78124,8.1347811 555.98046,9.9316543 555.45703,11.759766 C 554.93359,13.587901 554.67187,15.505868 554.67188,17.513672 C 554.67187,19.513676 554.93359,21.427737 555.45703,23.255859 C 555.98046,25.083983 556.78124,26.880856 557.85938,28.646484 L 555.38672,28.646484 C 554.01953,26.779294 552.98046,24.904296 552.26953,23.021484 C 551.5664,21.130862 551.21484,19.294926 551.21484,17.513672 C 551.21484,15.73243 551.5664,13.896494 552.26953,12.005859 C 552.98046,10.115248 554.01953,8.2363435 555.38672,6.3691406 L 557.85938,6.3691406 M 556.06641,42.685547 C 556.0664,41.724621 555.82421,40.96681 555.33984,40.412109 C 554.86327,39.849623 554.21093,39.568373 553.38281,39.568359 C 552.60156,39.568373 551.99218,39.837904 551.55469,40.376953 C 551.125,40.916028 550.91015,41.669934 550.91016,42.638672 C 550.91015,43.544932 551.13671,44.251963 551.58984,44.759766 C 552.04296,45.267586 552.67968,45.521492 553.5,45.521484 C 554.30468,45.521492 554.93359,45.271493 555.38672,44.771484 C 555.83983,44.271494 556.0664,43.576182 556.06641,42.685547 M 556.125,47.056641 C 555.73437,47.447272 555.27343,47.74024 554.74219,47.935547 C 554.21093,48.130865 553.61327,48.228521 552.94922,48.228516 C 551.30078,48.228521 549.98047,47.732428 548.98828,46.740234 C 547.99609,45.748055 547.5,44.419931 547.5,42.755859 C 547.5,40.990247 548.03906,39.564467 549.11719,38.478516 C 550.19531,37.392594 551.61718,36.849626 553.38281,36.849609 C 555.42968,36.849626 556.98436,37.556657 558.04688,38.970703 C 559.11718,40.376966 559.65233,42.431652 559.65234,45.134766 C 559.65233,48.041021 559.08202,50.267581 557.94141,51.814453 C 556.80077,53.361328 555.16015,54.134765 553.01953,54.134766 C 551.54296,54.134765 550.35156,53.751953 549.44531,52.986328 C 548.53906,52.212892 548.04297,51.162112 547.95703,49.833984 L 551.34375,49.845703 C 551.42187,50.384769 551.63281,50.787112 551.97656,51.052734 C 552.32031,51.318362 552.80468,51.451174 553.42969,51.451172 C 554.27343,51.451174 554.91796,51.083987 555.36328,50.349609 C 555.80858,49.615238 556.06249,48.517583 556.125,47.056641"
512 id="text5175" />
513 <path
514 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
515 d="M 609.375,6.3691406 L 611.87109,6.3691406 C 613.23046,8.228531 614.26171,10.103529 614.96484,11.994141 C 615.66796,13.876963 616.01952,15.716805 616.01953,17.513672 C 616.01952,19.302739 615.66796,21.142581 614.96484,23.033203 C 614.26171,24.923827 613.23046,26.794919 611.87109,28.646484 L 609.375,28.646484 C 610.46094,26.873044 611.26562,25.072264 611.78906,23.244141 C 612.32031,21.408205 612.58593,19.498051 612.58594,17.513672 C 612.58593,15.521492 612.32031,13.611338 611.78906,11.783203 C 611.26562,9.9550918 610.46094,8.1504061 609.375,6.3691406 M 610.98047,45.474609 C 610.98046,47.513678 611.18359,48.994145 611.58984,49.916016 C 612.0039,50.837893 612.66015,51.29883 613.55859,51.298828 C 614.45702,51.29883 615.11327,50.833987 615.52734,49.904297 C 615.9414,48.974614 616.14843,47.498053 616.14844,45.474609 C 616.14843,43.44337 615.9414,41.966809 615.52734,41.044922 C 615.11327,40.12306 614.45702,39.662123 613.55859,39.662109 C 612.66015,39.662123 612.0039,40.12306 611.58984,41.044922 C 611.18359,41.958996 610.98046,43.435557 610.98047,45.474609 M 607.5,45.474609 C 607.5,42.591808 608,40.43556 609,39.005859 C 610.00781,37.568375 611.52734,36.849626 613.55859,36.849609 C 615.58202,36.849626 617.09765,37.572282 618.10547,39.017578 C 619.12108,40.455091 619.62889,42.615245 619.62891,45.498047 C 619.62889,48.380865 619.12499,50.533206 618.11719,51.955078 C 617.11718,53.376953 615.59765,54.08789 613.55859,54.087891 C 611.52734,54.08789 610.00781,53.373047 609,51.943359 C 608,50.513675 607.5,48.357427 607.5,45.474609"
516 id="text5181" />
517 <path
518 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
519 d="M 667.5,26.900391 L 679.5,26.900391 L 679.5,29.291016 L 667.5,29.291016 L 667.5,26.900391 M 670.20703,48.849609 L 670.20703,45.638672 L 676.79297,45.638672 L 676.79297,48.849609 L 670.20703,48.849609"
520 id="text5187" />
521 <path
522 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
523 d="M 733.33594,9.3222656 L 735.70313,9.3222656 L 735.70313,15.298828 L 741.53906,15.298828 L 741.53906,17.630859 L 735.70313,17.630859 L 735.70313,23.630859 L 733.33594,23.630859 L 733.33594,17.630859 L 727.5,17.630859 L 727.5,15.298828 L 733.33594,15.298828 L 733.33594,9.3222656 M 727.5,47.818359 L 741.53906,47.818359 L 741.53906,50.150391 L 727.5,50.150391 L 727.5,47.818359 M 727.5,42.779297 L 741.53906,42.779297 L 741.53906,45.111328 L 727.5,45.111328 L 727.5,42.779297"
524 id="text5201" />
525 <path
526 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
527 d="M 11.070313,95.601563 L 11.070313,86.148438 L 7.65625,86.148438 L 7.65625,84.09375 L 16.828125,84.09375 L 16.828125,86.148438 L 13.4375,86.148438 L 13.4375,95.601563 L 11.070313,95.601563 M 22.859375,94.546875 C 22.572911,94.989584 22.197911,95.328125 21.734375,95.5625 C 21.270829,95.791666 20.731767,95.90625 20.117188,95.90625 C 19.294269,95.90625 18.658853,95.671875 18.210938,95.203125 C 17.768228,94.734376 17.546874,94.06771 17.546875,93.203125 C 17.546874,92.401045 17.768228,91.789066 18.210938,91.367188 C 18.658853,90.945317 19.395831,90.656255 20.421875,90.5 C 20.656246,90.463547 20.963538,90.42188 21.34375,90.375 C 22.307286,90.250005 22.789057,89.97136 22.789063,89.539063 C 22.789057,89.195319 22.682286,88.950527 22.46875,88.804688 C 22.255203,88.653653 21.898433,88.578132 21.398438,88.578125 C 20.9401,88.578132 20.588538,88.669278 20.34375,88.851563 C 20.098955,89.033861 19.97656,89.294277 19.976563,89.632813 L 19.976563,89.757813 L 17.851563,89.757813 L 17.851563,89.601563 C 17.851562,88.731778 18.158853,88.049487 18.773438,87.554688 C 19.388018,87.054696 20.236976,86.804696 21.320313,86.804688 C 22.507807,86.804696 23.41666,87.010425 24.046875,87.421875 C 24.682284,87.833341 24.999992,88.427091 25,89.203125 L 25,94.03125 C 24.999992,94.385418 25.03645,94.651043 25.109375,94.828125 C 25.182283,95.000001 25.304679,95.130209 25.476563,95.21875 L 25.476563,95.601563 L 23.109375,95.601563 C 23.031244,95.455729 22.971348,95.294271 22.929688,95.117188 C 22.888015,94.940105 22.864577,94.750001 22.859375,94.546875 M 22.820313,91.421875 C 22.450515,91.593754 22.023432,91.731775 21.539063,91.835938 C 21.059892,91.940108 20.812496,91.994795 20.796875,92 C 20.39583,92.114587 20.11458,92.257816 19.953125,92.429688 C 19.796872,92.601566 19.718747,92.838544 19.71875,93.140625 C 19.718747,93.453127 19.82031,93.703127 20.023438,93.890625 C 20.226559,94.072918 20.499997,94.164064 20.84375,94.164063 C 21.458329,94.164064 21.940099,93.992189 22.289063,93.648438 C 22.643224,93.299481 22.820307,92.825524 22.820313,92.226563 L 22.820313,91.421875 M 27.039063,84.09375 L 29.25,84.09375 L 29.25,88.164063 C 29.531246,87.721362 29.882809,87.388029 30.304688,87.164063 C 30.731766,86.934905 31.216141,86.820321 31.757813,86.820313 C 32.783847,86.820321 33.622388,87.2448 34.273438,88.09375 C 34.92447,88.937507 35.249991,90.036464 35.25,91.390625 C 35.249991,92.734378 34.92447,93.820314 34.273438,94.648438 C 33.622388,95.476563 32.773431,95.890625 31.726563,95.890625 C 31.179682,95.890625 30.70312,95.776041 30.296875,95.546875 C 29.895829,95.317709 29.531246,94.953126 29.203125,94.453125 L 29.203125,95.601563 L 27.039063,95.601563 L 27.039063,84.09375 M 32.992188,91.296875 C 32.992181,90.51563 32.828118,89.903652 32.5,89.460938 C 32.171869,89.013027 31.721348,88.789069 31.148438,88.789063 C 30.544266,88.789069 30.075517,89.007819 29.742188,89.445313 C 29.414059,89.87761 29.249997,90.494797 29.25,91.296875 C 29.249997,92.161462 29.406247,92.817711 29.71875,93.265625 C 30.036454,93.713544 30.497391,93.937502 31.101563,93.9375 C 31.71614,93.937502 32.18489,93.713544 32.507813,93.265625 C 32.830722,92.812503 32.992181,92.156253 32.992188,91.296875"
528 id="text5427" />
529 <path
530 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
531 d="M 789.76563,44.369141 L 792.57031,44.369141 C 793.23176,44.369143 793.71353,44.249351 794.01563,44.009766 C 794.3177,43.770185 794.46874,43.392581 794.46875,42.876953 C 794.46874,42.340499 794.3203,41.955083 794.02344,41.720703 C 793.72656,41.481125 793.23697,41.361333 792.55469,41.361328 L 789.76563,41.361328 L 789.76563,44.369141 M 789.76563,39.392578 L 792.46875,39.392578 C 793.05208,39.392585 793.47916,39.293627 793.75,39.095703 C 794.02083,38.892586 794.15624,38.574878 794.15625,38.142578 C 794.15624,37.720712 794.02343,37.416025 793.75781,37.228516 C 793.49739,37.035817 793.06249,36.939463 792.45313,36.939453 L 789.76563,36.939453 L 789.76563,39.392578 M 787.5,46.447266 L 787.5,34.939453 L 792.92188,34.939453 C 794.09895,34.939465 794.99478,35.189464 795.60938,35.689453 C 796.22916,36.184255 796.53905,36.905609 796.53906,37.853516 C 796.53905,38.436857 796.42447,38.923836 796.19531,39.314453 C 795.96614,39.705085 795.62239,40.007168 795.16406,40.220703 C 795.7578,40.460292 796.20051,40.806646 796.49219,41.259766 C 796.78905,41.707687 796.93749,42.267582 796.9375,42.939453 C 796.93749,44.059247 796.57291,44.92383 795.84375,45.533203 C 795.11457,46.142578 794.08072,46.447266 792.74219,46.447266 L 787.5,46.447266 M 803.45313,45.392578 C 803.16666,45.835287 802.79166,46.173828 802.32813,46.408203 C 801.86458,46.63737 801.32552,46.751953 800.71094,46.751953 C 799.88802,46.751953 799.2526,46.517578 798.80469,46.048828 C 798.36198,45.580079 798.14062,44.913413 798.14063,44.048828 C 798.14062,43.246748 798.36198,42.634769 798.80469,42.212891 C 799.2526,41.79102 799.98958,41.501958 801.01563,41.345703 C 801.25,41.30925 801.55729,41.267583 801.9375,41.220703 C 802.90104,41.095708 803.38281,40.817063 803.38281,40.384766 C 803.38281,40.041022 803.27604,39.796231 803.0625,39.650391 C 802.84895,39.499356 802.49218,39.423835 801.99219,39.423828 C 801.53385,39.423835 801.18229,39.514981 800.9375,39.697266 C 800.69271,39.879564 800.57031,40.13998 800.57031,40.478516 L 800.57031,40.603516 L 798.44531,40.603516 L 798.44531,40.447266 C 798.44531,39.577481 798.7526,38.89519 799.36719,38.400391 C 799.98177,37.900399 800.83073,37.650399 801.91406,37.650391 C 803.10156,37.650399 804.01041,37.856128 804.64063,38.267578 C 805.27603,38.679044 805.59374,39.272794 805.59375,40.048828 L 805.59375,44.876953 C 805.59374,45.231121 805.6302,45.496746 805.70313,45.673828 C 805.77603,45.845704 805.89843,45.975912 806.07031,46.064453 L 806.07031,46.447266 L 803.70313,46.447266 C 803.62499,46.301432 803.5651,46.139974 803.52344,45.962891 C 803.48176,45.785808 803.45833,45.595704 803.45313,45.392578 M 803.41406,42.267578 C 803.04427,42.439457 802.61718,42.577478 802.13281,42.681641 C 801.65364,42.785811 801.40625,42.840498 801.39063,42.845703 C 800.98958,42.96029 800.70833,43.103519 800.54688,43.275391 C 800.39062,43.447269 800.3125,43.684248 800.3125,43.986328 C 800.3125,44.29883 800.41406,44.54883 800.61719,44.736328 C 800.82031,44.918621 801.09375,45.009767 801.4375,45.009766 C 802.05208,45.009767 802.53385,44.837892 802.88281,44.494141 C 803.23697,44.145185 803.41406,43.671227 803.41406,43.072266 L 803.41406,42.267578 M 812.71875,43.244141 L 814.96094,43.244141 C 814.86718,44.322268 814.47395,45.173829 813.78125,45.798828 C 813.08854,46.423828 812.19791,46.736328 811.10938,46.736328 C 809.875,46.736328 808.90625,46.335287 808.20313,45.533203 C 807.50521,44.725913 807.15625,43.611331 807.15625,42.189453 C 807.15625,40.772792 807.51302,39.663418 808.22656,38.861328 C 808.94531,38.054045 809.93229,37.650399 811.1875,37.650391 C 812.28645,37.650399 813.16666,37.942066 813.82813,38.525391 C 814.49478,39.108731 814.86718,39.92123 814.94531,40.962891 L 812.6875,40.962891 C 812.62499,40.509772 812.46614,40.163418 812.21094,39.923828 C 811.95572,39.684252 811.61979,39.56446 811.20313,39.564453 C 810.64062,39.56446 810.21875,39.785814 809.9375,40.228516 C 809.66146,40.67123 809.52343,41.335292 809.52344,42.220703 C 809.52343,43.038415 809.66666,43.668623 809.95313,44.111328 C 810.24479,44.54883 810.66145,44.76758 811.20313,44.767578 C 811.62499,44.76758 811.96354,44.639976 812.21875,44.384766 C 812.47395,44.12956 812.64062,43.749352 812.71875,43.244141 M 816.44531,46.447266 L 816.44531,34.939453 L 818.65625,34.939453 L 818.65625,40.978516 L 821.35938,37.955078 L 824.09375,37.955078 L 821.13281,41.103516 L 824.27344,46.447266 L 821.54688,46.447266 L 819.51563,42.830078 L 818.65625,43.759766 L 818.65625,46.447266 L 816.44531,46.447266 M 824.79688,43.681641 L 827.0625,43.681641 C 827.08333,44.113935 827.23958,44.436851 827.53125,44.650391 C 827.82291,44.858726 828.26041,44.962892 828.84375,44.962891 C 829.28645,44.962892 829.6276,44.889976 829.86719,44.744141 C 830.11197,44.593101 830.23437,44.382164 830.23438,44.111328 C 830.23437,43.725914 829.78124,43.436852 828.875,43.244141 C 828.5052,43.166019 828.21093,43.098311 827.99219,43.041016 C 826.88802,42.759769 826.11979,42.426436 825.6875,42.041016 C 825.26042,41.655604 825.04687,41.134771 825.04688,40.478516 C 825.04687,39.608731 825.35937,38.921231 825.98438,38.416016 C 826.61458,37.905608 827.46614,37.650399 828.53906,37.650391 C 829.67447,37.650399 830.5651,37.903003 831.21094,38.408203 C 831.86197,38.913419 832.20833,39.624356 832.25,40.541016 L 830.03906,40.541016 C 830.02343,40.181647 829.88541,39.903001 829.625,39.705078 C 829.36979,39.507168 829.01302,39.40821 828.55469,39.408203 C 828.12239,39.40821 827.79948,39.473314 827.58594,39.603516 C 827.3776,39.733731 827.27343,39.929043 827.27344,40.189453 C 827.27343,40.528001 827.83854,40.82748 828.96875,41.087891 C 829.22916,41.145188 829.43489,41.192063 829.58594,41.228516 C 830.71614,41.494146 831.48697,41.814458 831.89844,42.189453 C 832.3151,42.564457 832.52343,43.093102 832.52344,43.775391 C 832.52343,44.738934 832.18228,45.473308 831.5,45.978516 C 830.82291,46.483724 829.83593,46.736328 828.53906,46.736328 C 827.36718,46.736328 826.45052,46.473307 825.78906,45.947266 C 825.1276,45.421225 824.79687,44.697267 824.79688,43.775391 L 824.79688,43.681641 M 840.02344,42.251953 C 840.02343,41.397792 839.86197,40.74675 839.53906,40.298828 C 839.21614,39.84571 838.74739,39.619147 838.13281,39.619141 C 837.52864,39.619147 837.0677,39.843106 836.75,40.291016 C 836.4375,40.738938 836.28125,41.392583 836.28125,42.251953 C 836.28125,43.05404 836.44531,43.673831 836.77344,44.111328 C 837.10677,44.54883 837.57552,44.76758 838.17969,44.767578 C 838.7526,44.76758 839.20312,44.543622 839.53125,44.095703 C 839.85937,43.647789 840.02343,43.033207 840.02344,42.251953 M 834.07031,49.853516 L 834.07031,37.955078 L 836.23438,37.955078 L 836.23438,39.103516 C 836.5625,38.603523 836.92708,38.23894 837.32813,38.009766 C 837.73437,37.780608 838.21093,37.666024 838.75781,37.666016 C 839.80468,37.666024 840.65364,38.080086 841.30469,38.908203 C 841.95572,39.731127 842.28124,40.814459 842.28125,42.158203 C 842.28124,43.517581 841.95572,44.621747 841.30469,45.470703 C 840.65364,46.314453 839.8151,46.736328 838.78906,46.736328 C 838.24739,46.736328 837.76302,46.621745 837.33594,46.392578 C 836.91406,46.163412 836.5625,45.830079 836.28125,45.392578 L 836.28125,49.853516 L 834.07031,49.853516 M 848.70313,45.392578 C 848.41666,45.835287 848.04166,46.173828 847.57813,46.408203 C 847.11458,46.63737 846.57552,46.751953 845.96094,46.751953 C 845.13802,46.751953 844.5026,46.517578 844.05469,46.048828 C 843.61198,45.580079 843.39062,44.913413 843.39063,44.048828 C 843.39062,43.246748 843.61198,42.634769 844.05469,42.212891 C 844.5026,41.79102 845.23958,41.501958 846.26563,41.345703 C 846.5,41.30925 846.80729,41.267583 847.1875,41.220703 C 848.15104,41.095708 848.63281,40.817063 848.63281,40.384766 C 848.63281,40.041022 848.52604,39.796231 848.3125,39.650391 C 848.09895,39.499356 847.74218,39.423835 847.24219,39.423828 C 846.78385,39.423835 846.43229,39.514981 846.1875,39.697266 C 845.94271,39.879564 845.82031,40.13998 845.82031,40.478516 L 845.82031,40.603516 L 843.69531,40.603516 L 843.69531,40.447266 C 843.69531,39.577481 844.0026,38.89519 844.61719,38.400391 C 845.23177,37.900399 846.08073,37.650399 847.16406,37.650391 C 848.35156,37.650399 849.26041,37.856128 849.89063,38.267578 C 850.52603,38.679044 850.84374,39.272794 850.84375,40.048828 L 850.84375,44.876953 C 850.84374,45.231121 850.8802,45.496746 850.95313,45.673828 C 851.02603,45.845704 851.14843,45.975912 851.32031,46.064453 L 851.32031,46.447266 L 848.95313,46.447266 C 848.87499,46.301432 848.8151,46.139974 848.77344,45.962891 C 848.73176,45.785808 848.70833,45.595704 848.70313,45.392578 M 848.66406,42.267578 C 848.29427,42.439457 847.86718,42.577478 847.38281,42.681641 C 846.90364,42.785811 846.65625,42.840498 846.64063,42.845703 C 846.23958,42.96029 845.95833,43.103519 845.79688,43.275391 C 845.64062,43.447269 845.5625,43.684248 845.5625,43.986328 C 845.5625,44.29883 845.66406,44.54883 845.86719,44.736328 C 846.07031,44.918621 846.34375,45.009767 846.6875,45.009766 C 847.30208,45.009767 847.78385,44.837892 848.13281,44.494141 C 848.48697,44.145185 848.66406,43.671227 848.66406,43.072266 L 848.66406,42.267578 M 857.96875,43.244141 L 860.21094,43.244141 C 860.11718,44.322268 859.72395,45.173829 859.03125,45.798828 C 858.33854,46.423828 857.44791,46.736328 856.35938,46.736328 C 855.125,46.736328 854.15625,46.335287 853.45313,45.533203 C 852.75521,44.725913 852.40625,43.611331 852.40625,42.189453 C 852.40625,40.772792 852.76302,39.663418 853.47656,38.861328 C 854.19531,38.054045 855.18229,37.650399 856.4375,37.650391 C 857.53645,37.650399 858.41666,37.942066 859.07813,38.525391 C 859.74478,39.108731 860.11718,39.92123 860.19531,40.962891 L 857.9375,40.962891 C 857.87499,40.509772 857.71614,40.163418 857.46094,39.923828 C 857.20572,39.684252 856.86979,39.56446 856.45313,39.564453 C 855.89062,39.56446 855.46875,39.785814 855.1875,40.228516 C 854.91146,40.67123 854.77343,41.335292 854.77344,42.220703 C 854.77343,43.038415 854.91666,43.668623 855.20313,44.111328 C 855.49479,44.54883 855.91145,44.76758 856.45313,44.767578 C 856.87499,44.76758 857.21354,44.639976 857.46875,44.384766 C 857.72395,44.12956 857.89062,43.749352 857.96875,43.244141 M 866.88281,43.869141 L 869.14844,43.869141 C 868.91926,44.764976 868.45572,45.4681 867.75781,45.978516 C 867.0651,46.483724 866.21874,46.736328 865.21875,46.736328 C 863.98958,46.736328 863.01562,46.32487 862.29688,45.501953 C 861.57812,44.67383 861.21875,43.554039 861.21875,42.142578 C 861.21875,40.751959 861.57292,39.655606 862.28125,38.853516 C 862.98958,38.051441 863.95833,37.650399 865.1875,37.650391 C 866.48958,37.650399 867.49478,38.046232 868.20313,38.837891 C 868.91145,39.624356 869.26562,40.74675 869.26563,42.205078 C 869.26562,42.366541 869.26301,42.488936 869.25781,42.572266 C 869.2578,42.650394 869.2526,42.725915 869.24219,42.798828 L 863.57031,42.798828 C 863.60156,43.465498 863.76302,43.968101 864.05469,44.306641 C 864.35156,44.645184 864.77604,44.814455 865.32813,44.814453 C 865.71874,44.814455 866.03906,44.738934 866.28906,44.587891 C 866.53906,44.431643 866.73697,44.19206 866.88281,43.869141 M 863.57031,41.306641 L 866.91406,41.306641 C 866.89322,40.73373 866.73958,40.298834 866.45313,40.001953 C 866.17187,39.699877 865.76562,39.548835 865.23438,39.548828 C 864.73958,39.548835 864.34895,39.699877 864.0625,40.001953 C 863.78125,40.304043 863.61718,40.738938 863.57031,41.306641"
532 id="text5207" />
533 <path
534 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
535 d="M 840,17.646484 L 797.02608,17.646484"
536 id="path5439" />
537 <path
538 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
539 d="M 802.5,25.146484 L 802.5,10.146484 L 787.5,17.646484 L 802.5,25.146484 z "
540 id="path5441" />
541 <g
542 id="g5459"
543 transform="translate(0,7.5)">
544 <path
545 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:3.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
546 d="M 82.50003,75 L 54.020182,75"
547 id="path5453" />
548 <path
549 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
550 d="M 60,82.5 L 60,67.5 L 45,75 L 60,82.5 z "
551 id="path5455" />
552 <path
553 id="path5457"
554 d="M 45,67.5 C 45,82.5 45,82.5 45,82.5"
555 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
556 </g>
557 <g
558 id="g5464"
559 transform="matrix(-1,9.581637e-17,-9.581637e-17,-1,127.5,172.5)">
560 <path
561 id="path5466"
562 d="M 82.50003,75 L 54.020182,75"
563 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:3.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
564 <path
565 id="path5468"
566 d="M 60,82.5 L 60,67.5 L 45,75 L 60,82.5 z "
567 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
568 <path
569 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
570 d="M 45,67.5 C 45,82.5 45,82.5 45,82.5"
571 id="path5470" />
572 </g>
573 <path
574 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
575 d="M 107.0625,80.560547 L 105.23438,78.779297 L 107.17969,76.763672 L 109.05469,78.591797 C 109.30467,78.123052 109.49608,77.587897 109.62891,76.986328 C 109.7617,76.384773 109.82811,75.728524 109.82813,75.017578 C 109.82811,73.119151 109.40233,71.646496 108.55078,70.599609 C 107.69921,69.544936 106.5078,69.017593 104.97656,69.017578 C 103.46093,69.017593 102.28124,69.54103 101.4375,70.587891 C 100.59374,71.634778 100.17187,73.111339 100.17188,75.017578 C 100.17187,76.916022 100.59374,78.392583 101.4375,79.447266 C 102.28124,80.494144 103.46093,81.017581 104.97656,81.017578 C 105.36718,81.017581 105.73436,80.978518 106.07813,80.900391 C 106.42968,80.822268 106.7578,80.708987 107.0625,80.560547 M 109.55859,82.916016 C 108.97264,83.306641 108.28905,83.603516 107.50781,83.806641 C 106.73436,84.009765 105.89061,84.111328 104.97656,84.111328 C 102.39843,84.111328 100.34765,83.291016 98.824219,81.650391 C 97.308592,80.009769 96.55078,77.798834 96.550781,75.017578 C 96.55078,72.228527 97.308592,70.017592 98.824219,68.384766 C 100.34765,66.744158 102.39843,65.923846 104.97656,65.923828 C 107.55468,65.923846 109.60545,66.744158 111.12891,68.384766 C 112.66014,70.025404 113.42576,72.23634 113.42578,75.017578 C 113.42576,76.236336 113.26951,77.353522 112.95703,78.369141 C 112.64451,79.376957 112.18358,80.259769 111.57422,81.017578 L 113.44922,82.810547 L 111.52734,84.826172 L 109.55859,82.916016"
576 id="text5474" />
577 <path
578 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
579 d="M 407.06836,83.630859 L 403.51758,83.630859 L 403.51758,77.197266 L 397.24805,66.369141 L 401.5957,66.369141 L 405.28711,73.810547 L 408.69727,66.369141 L 412.75195,66.369141 L 407.06836,77.197266 L 407.06836,83.630859"
580 id="text5518" />
581 <path
582 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
583 d="M 458.08594,66.105469 L 461.67188,66.105469 L 461.67188,76.933594 C 461.67187,78.269536 461.93749,79.246098 462.46875,79.863281 C 462.99999,80.472659 463.84374,80.777346 465,80.777344 C 466.17187,80.777346 467.02343,80.472659 467.55469,79.863281 C 468.09374,79.25391 468.36327,78.277349 468.36328,76.933594 L 468.36328,66.105469 L 471.91406,66.105469 L 471.91406,77.320313 C 471.91405,79.437504 471.3203,81.062502 470.13281,82.195313 C 468.95311,83.328125 467.24999,83.894531 465.02344,83.894531 C 462.78124,83.894531 461.0625,83.332031 459.86719,82.207031 C 458.67969,81.074221 458.08594,79.445316 458.08594,77.320313 L 458.08594,66.105469"
584 id="text5522" />
585 <path
586 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
587 d="M 523.22461,83.630859 L 523.22461,66.369141 L 526.77539,66.369141 L 526.77539,83.630859 L 523.22461,83.630859"
588 id="text5526" />
589 <path
590 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
591 d="M 580.18359,75 C 580.18359,76.898444 580.60546,78.375005 581.44922,79.429688 C 582.29296,80.476566 583.47265,81.000003 584.98828,81 C 586.51952,81.000003 587.71093,80.476566 588.5625,79.429688 C 589.41405,78.375005 589.83983,76.898444 589.83984,75 C 589.83983,73.101573 589.41405,71.628918 588.5625,70.582031 C 587.71093,69.527358 586.51952,69.000015 584.98828,69 C 583.47265,69.000015 582.29296,69.523452 581.44922,70.570313 C 580.60546,71.617199 580.18359,73.093761 580.18359,75 M 576.5625,75 C 576.5625,72.210949 577.32031,70.000014 578.83594,68.367188 C 580.35937,66.726579 582.41015,65.906268 584.98828,65.90625 C 587.56639,65.906268 589.61717,66.726579 591.14063,68.367188 C 592.67186,70.007826 593.43748,72.218761 593.4375,75 C 593.43748,77.781256 592.67186,79.992191 591.14063,81.632813 C 589.61717,83.273438 587.56639,84.09375 584.98828,84.09375 C 582.41015,84.09375 580.35937,83.273438 578.83594,81.632813 C 577.32031,79.992191 576.5625,77.781256 576.5625,75"
592 id="text5530" />
593 <path
594 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
595 d="M 641.97656,74.361328 L 645.41016,74.361328 C 646.33983,74.361337 647.01561,74.166025 647.4375,73.775391 C 647.85936,73.376963 648.0703,72.740245 648.07031,71.865234 C 648.0703,71.044934 647.86327,70.423841 647.44922,70.001953 C 647.03515,69.580092 646.41796,69.369155 645.59766,69.369141 L 641.97656,69.369141 L 641.97656,74.361328 M 641.95313,77.490234 L 641.95313,83.630859 L 638.40234,83.630859 L 638.40234,66.369141 L 646.07813,66.369141 C 647.89061,66.369158 649.26171,66.841814 650.19141,67.787109 C 651.12889,68.724624 651.59764,70.103529 651.59766,71.923828 C 651.59764,73.705088 651.14061,75.080087 650.22656,76.048828 C 649.31249,77.009772 648.0078,77.490241 646.3125,77.490234 L 641.95313,77.490234"
596 id="text5534" />
597 <path
598 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
599 d="M 709.24805,63.919922 L 709.24805,66.369141 C 709.17772,66.369155 709.08007,66.365249 708.95508,66.357422 C 708.83007,66.349624 708.74413,66.345718 708.69727,66.345703 C 707.90819,66.345718 707.37304,66.498062 707.0918,66.802734 C 706.81835,67.099624 706.68163,67.732435 706.68164,68.701172 L 706.68164,71.513672 C 706.68163,72.66993 706.50585,73.490242 706.1543,73.974609 C 705.80273,74.458991 705.16992,74.806647 704.25586,75.017578 C 705.16992,75.228522 705.80273,75.572271 706.1543,76.048828 C 706.50585,76.525395 706.68163,77.341801 706.68164,78.498047 L 706.68164,81.322266 C 706.68163,82.283202 706.81835,82.912108 707.0918,83.208984 C 707.36523,83.505857 707.90038,83.654294 708.69727,83.654297 C 708.74413,83.654294 708.83007,83.650388 708.95508,83.642578 C 709.08007,83.634763 709.17772,83.630857 709.24805,83.630859 L 709.24805,86.080078 C 709.13866,86.080073 708.98632,86.08398 708.79102,86.091797 C 708.59569,86.099605 708.45116,86.103511 708.35742,86.103516 C 707.57616,86.103511 706.92382,86.056636 706.40039,85.962891 C 705.87695,85.869136 705.43163,85.724605 705.06445,85.529297 C 704.61913,85.263668 704.30273,84.904293 704.11523,84.451172 C 703.93554,84.005857 703.8457,83.228514 703.8457,82.119141 L 703.8457,79.166016 C 703.8457,78.095706 703.64648,77.337895 703.24805,76.892578 C 702.84961,76.439458 702.17773,76.212896 701.23242,76.212891 C 701.18554,76.212896 701.10742,76.216802 700.99805,76.224609 C 700.88867,76.232427 700.80664,76.236333 700.75195,76.236328 L 700.75195,73.787109 C 700.80664,73.787117 700.88867,73.791023 700.99805,73.798828 C 701.10742,73.806648 701.18554,73.810554 701.23242,73.810547 C 702.16992,73.810554 702.83789,73.583992 703.23633,73.130859 C 703.64257,72.677743 703.8457,71.912119 703.8457,70.833984 L 703.8457,67.904297 C 703.8457,66.787124 703.93554,66.001968 704.11523,65.548828 C 704.30273,65.095719 704.61913,64.736345 705.06445,64.470703 C 705.43163,64.275408 705.87695,64.130876 706.40039,64.037109 C 706.92382,63.943377 707.57616,63.896502 708.35742,63.896484 C 708.45116,63.896502 708.59569,63.900408 708.79102,63.908203 C 708.98632,63.916033 709.13866,63.919939 709.24805,63.919922 M 703.0957,93.966797 L 709.01367,93.966797 L 709.01367,96.462891 L 706.25977,96.462891 L 706.25977,113.8418 L 709.01367,113.8418 L 709.01367,116.33789 L 703.0957,116.33789 L 703.0957,93.966797"
600 id="text5546" />
601 <path
602 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
603 d="M 760.75195,63.908203 L 761.54883,63.908203 C 762.4082,63.90822 763.09961,63.955095 763.62305,64.048828 C 764.14648,64.142595 764.58398,64.291033 764.93555,64.494141 C 765.38085,64.744157 765.69335,65.103532 765.87305,65.572266 C 766.06054,66.033218 766.15429,66.806655 766.1543,67.892578 L 766.1543,70.845703 C 766.15429,71.916025 766.35351,72.677743 766.75195,73.130859 C 767.15038,73.57618 767.82226,73.798836 768.76758,73.798828 C 768.81444,73.798836 768.89257,73.794929 769.00195,73.787109 C 769.11132,73.779304 769.19335,73.775398 769.24805,73.775391 L 769.24805,76.224609 L 768.81445,76.224609 C 767.83788,76.224614 767.15038,76.443364 766.75195,76.880859 C 766.35351,77.318363 766.15429,78.076175 766.1543,79.154297 L 766.1543,82.107422 C 766.15429,83.224607 766.06054,84.009763 765.87305,84.462891 C 765.69335,84.916012 765.38085,85.267574 764.93555,85.517578 C 764.56835,85.712886 764.12304,85.857417 763.59961,85.951172 C 763.07617,86.044917 762.42382,86.091792 761.64258,86.091797 C 761.54883,86.091792 761.40429,86.087886 761.20898,86.080078 C 761.01367,86.072261 760.86133,86.068355 760.75195,86.068359 L 760.75195,83.619141 C 760.82226,83.619138 760.91992,83.623044 761.04492,83.630859 C 761.16992,83.638669 761.25586,83.642576 761.30273,83.642578 C 762.09179,83.642576 762.62304,83.490232 762.89648,83.185547 C 763.17773,82.88867 763.31836,82.263671 763.31836,81.310547 L 763.31836,78.509766 C 763.31836,77.337895 763.49414,76.513677 763.8457,76.037109 C 764.19726,75.55274 764.83007,75.20899 765.74414,75.005859 C 764.83007,74.794928 764.19726,74.447272 763.8457,73.962891 C 763.49414,73.478523 763.31836,72.658212 763.31836,71.501953 L 763.31836,68.666016 C 763.31836,67.712904 763.17773,67.087905 762.89648,66.791016 C 762.62304,66.486343 762.09179,66.333999 761.30273,66.333984 C 761.25586,66.333999 761.16992,66.337906 761.04492,66.345703 C 760.91992,66.35353 760.82226,66.357437 760.75195,66.357422 L 760.75195,63.908203 M 767.00977,93.955078 L 767.00977,116.32617 L 761.08008,116.32617 L 761.08008,113.83008 L 763.8457,113.83008 L 763.8457,96.451172 L 761.08008,96.451172 L 761.08008,93.955078 L 767.00977,93.955078"
604 id="text5554" />
605 <path
606 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
607 d="M 823.79883,62.876953 L 826.21289,62.876953 L 826.21289,86.876953 L 823.79883,86.876953 L 823.79883,62.876953 M 827.10352,113.44336 L 821.29102,93.509766 L 822.87305,93.509766 L 828.70898,113.44336 L 827.10352,113.44336"
608 id="text5564" />
609 <g
610 id="g5770"
611 transform="translate(0,3.75)">
612 <text
613 sodipodi:linespacing="125%"
614 id="text5570"
615 y="139.30469"
616 x="52.152344"
617 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
618 xml:space="preserve"><tspan
619 y="139.30469"
620 x="52.152344"
621 id="tspan5572"
622 sodipodi:role="line">Caps Lock</tspan></text>
623 <path
624 id="path5584"
625 d="M 26.25,142.5 L 15,157.5 L 22.5,157.5 L 22.5,165 L 30,165 L 30,157.5 L 37.5,157.5 L 26.25,142.5 z M 25.21875,146.71875 L 27.25,146.71875 L 30.375,155.34375 L 28.5,155.34375 L 27.90625,153.5625 L 24.5625,153.5625 L 24,155.34375 L 22.125,155.34375 L 25.21875,146.71875 z M 26.25,148.4375 L 25.03125,152.09375 L 27.4375,152.09375 L 26.25,148.4375 z "
626 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
627 </g>
628 <path
629 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
630 d="M 365.17969,141.57422 C 364.53905,142.44141 363.80858,143.07813 362.98828,143.48438 C 362.17577,143.89062 361.21874,144.09375 360.11719,144.09375 C 357.70312,144.09375 355.74609,143.25781 354.24609,141.58594 C 352.7539,139.90625 352.00781,137.70313 352.00781,134.97656 C 352.00781,132.22657 352.7539,130.02736 354.24609,128.37891 C 355.73828,126.73049 357.72656,125.90627 360.21094,125.90625 C 362.37499,125.90627 364.14061,126.4258 365.50781,127.46484 C 366.87498,128.49611 367.68748,129.91798 367.94531,131.73047 L 364.32422,131.73047 C 364.10546,130.83204 363.65624,130.14845 362.97656,129.67969 C 362.30468,129.21095 361.42577,128.97658 360.33984,128.97656 C 358.89452,128.97658 357.75781,129.50783 356.92969,130.57031 C 356.10937,131.62501 355.69921,133.08595 355.69922,134.95313 C 355.69921,136.82813 356.1289,138.29688 356.98828,139.35938 C 357.84765,140.42188 359.02734,140.95313 360.52734,140.95313 C 361.65233,140.95313 362.59374,140.6211 363.35156,139.95703 C 364.10936,139.29297 364.57811,138.38282 364.75781,137.22656 L 360.84375,137.22656 L 360.84375,134.27344 L 367.99219,134.27344 L 367.99219,143.61328 L 365.61328,143.61328 L 365.17969,141.57422"
631 id="text5657" />
632 <path
633 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
634 d="M 143.15039,203.63086 L 143.15039,200.63086 L 152.53711,189.49805 L 143.33789,189.49805 L 143.33789,186.36914 L 156.84961,186.36914 L 156.84961,189.36914 L 147.43945,200.51367 L 156.63867,200.51367 L 156.63867,203.63086 L 143.15039,203.63086"
635 id="text5679" />
636 <path
637 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
638 d="M 202.37109,203.63086 L 207.79688,194.81836 L 202.37109,186.36914 L 206.47266,186.36914 L 210,192.4043 L 213.50391,186.36914 L 217.62891,186.36914 L 212.20313,194.79492 L 217.62891,203.63086 L 213.52734,203.63086 L 210,197.6543 L 206.47266,203.63086 L 202.37109,203.63086"
639 id="text5683" />
640 <path
641 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
642 d="M 277.875,197.68359 C 277.74217,199.64454 276.98436,201.20313 275.60156,202.35938 C 274.22655,203.51563 272.42968,204.09375 270.21094,204.09375 C 267.65624,204.09375 265.66796,203.29688 264.24609,201.70313 C 262.83203,200.10938 262.125,197.87501 262.125,195 C 262.125,192.06251 262.84765,189.81251 264.29297,188.25 C 265.73828,186.68752 267.8164,185.90627 270.52734,185.90625 C 272.73046,185.90627 274.46874,186.44533 275.74219,187.52344 C 277.02342,188.59377 277.72655,190.10939 277.85156,192.07031 L 274.34766,192.07031 C 274.19921,191.09376 273.80077,190.35158 273.15234,189.84375 C 272.50389,189.32814 271.6289,189.07033 270.52734,189.07031 C 268.96484,189.07033 267.77734,189.57423 266.96484,190.58203 C 266.15234,191.58986 265.74609,193.06251 265.74609,195 C 265.74609,196.87501 266.14843,198.32422 266.95313,199.34766 C 267.76562,200.3711 268.91796,200.88282 270.41016,200.88281 C 271.48827,200.88282 272.37108,200.60938 273.05859,200.0625 C 273.74608,199.50782 274.19139,198.71485 274.39453,197.68359 L 277.875,197.68359"
643 id="text5687" />
644 <path
645 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
646 d="M 386.32031,200.51367 L 390.52734,200.51367 C 391.51952,200.51367 392.24218,200.33399 392.69531,199.97461 C 393.14843,199.61524 393.37499,199.04883 393.375,198.27539 C 393.37499,197.47071 393.15233,196.89258 392.70703,196.54102 C 392.26171,196.18165 391.52733,196.00196 390.50391,196.00195 L 386.32031,196.00195 L 386.32031,200.51367 M 386.32031,193.04883 L 390.375,193.04883 C 391.24999,193.04884 391.89061,192.9004 392.29688,192.60352 C 392.70311,192.29884 392.90624,191.82228 392.90625,191.17383 C 392.90624,190.54103 392.70702,190.084 392.30859,189.80273 C 391.91796,189.51369 391.26561,189.36915 390.35156,189.36914 L 386.32031,189.36914 L 386.32031,193.04883 M 382.92188,203.63086 L 382.92188,186.36914 L 391.05469,186.36914 C 392.8203,186.36916 394.16405,186.74416 395.08594,187.49414 C 396.01561,188.23634 396.48045,189.31837 396.48047,190.74023 C 396.48045,191.61525 396.30858,192.34571 395.96484,192.93164 C 395.62108,193.51759 395.10545,193.97071 394.41797,194.29102 C 395.30858,194.6504 395.97264,195.16993 396.41016,195.84961 C 396.85545,196.52149 397.07811,197.36133 397.07813,198.36914 C 397.07811,200.04883 396.53123,201.34571 395.4375,202.25977 C 394.34374,203.17383 392.79296,203.63086 390.78516,203.63086 L 382.92188,203.63086"
647 id="text5695" />
648 <path
649 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
650 d="M 442.88672,203.63086 L 442.88672,186.36914 L 446.60156,186.36914 L 453.60938,198.22852 L 453.60938,186.36914 L 457.11328,186.36914 L 457.11328,203.63086 L 453.44531,203.63086 L 446.39063,191.77148 L 446.39063,203.63086 L 442.88672,203.63086"
651 id="text5699" />
652 <path
653 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
654 d="M 501.32813,203.63086 L 501.32813,186.36914 L 506.57813,186.36914 L 510.01172,199.50586 L 513.39844,186.36914 L 518.67188,186.36914 L 518.67188,203.63086 L 515.34375,203.63086 L 515.34375,189.70898 L 511.83984,203.63086 L 508.20703,203.63086 L 504.65625,189.70898 L 504.65625,203.63086 L 501.32813,203.63086"
655 id="text5703" />
656 <path
657 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
658 d="M 720.78516,126.7793 L 723.03516,126.7793 L 723.03516,133.33008 L 720.78516,133.33008 L 720.78516,126.7793 M 716.96484,126.7793 L 719.21484,126.7793 L 719.21484,133.33008 L 716.96484,133.33008 L 716.96484,126.7793 M 718.88672,156.7793 L 721.13672,156.7793 L 721.13672,163.33008 L 718.88672,163.33008 L 718.88672,156.7793"
659 id="text5731" />
660 <g
661 id="g5790">
662 <text
663 xml:space="preserve"
664 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
665 x="31.8125"
666 y="201.19531"
667 id="text5753"
668 sodipodi:linespacing="125%"><tspan
669 sodipodi:role="line"
670 id="tspan5755"
671 x="31.8125"
672 y="201.19531">Shift</tspan></text>
673 <path
674 style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
675 d="M 27.25,207.125 L 16,222.125 L 23.5,222.125 L 23.5,229.625 L 31,229.625 L 31,222.125 L 38.5,222.125 L 27.25,207.125 z "
676 id="path5757" />
677 </g>
678 <g
679 id="g5795"
680 transform="translate(727.5,0)">
681 <text
682 sodipodi:linespacing="125%"
683 id="text5797"
684 y="201.19531"
685 x="31.8125"
686 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
687 xml:space="preserve"><tspan
688 y="201.19531"
689 x="31.8125"
690 id="tspan5799"
691 sodipodi:role="line">Shift</tspan></text>
692 <path
693 id="path5801"
694 d="M 27.25,207.125 L 16,222.125 L 23.5,222.125 L 23.5,229.625 L 31,229.625 L 31,222.125 L 38.5,222.125 L 27.25,207.125 z "
695 style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
696 </g>
697 <path
698 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
699 d="M 576.90234,189.63867 L 576.90234,192.20508 L 566.4375,196.48242 L 576.90234,200.74805 L 576.90234,203.31445 L 563.09766,197.63086 L 563.09766,195.29883 L 576.90234,189.63867 M 568.21875,237.68555 L 568.21875,236.31445 C 568.875,236.12695 569.35937,235.83789 569.67188,235.44727 C 569.98437,235.05664 570.14062,234.54883 570.14063,233.92383 L 570.14063,233.63086 L 568.21875,233.63086 L 568.21875,230.10352 L 571.76953,230.10352 L 571.76953,233.49023 C 571.76953,234.6543 571.46875,235.59179 570.86719,236.30273 C 570.27343,237.01367 569.39062,237.47461 568.21875,237.68555"
700 id="text5803" />
701 <path
702 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
703 d="M 623.09766,189.63867 L 636.90234,195.29883 L 636.90234,197.63086 L 623.09766,203.31445 L 623.09766,200.74805 L 633.58594,196.48242 L 623.09766,192.20508 L 623.09766,189.63867 M 628.21875,233.63086 L 628.21875,230.10352 L 631.74609,230.10352 L 631.74609,233.63086 L 628.21875,233.63086"
704 id="text5813" />
705 <path
706 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
707 d="M 688.44727,198.61523 C 688.44726,198.5293 688.44335,198.41602 688.43555,198.27539 C 688.42773,198.12696 688.42382,198.01758 688.42383,197.94727 C 688.42382,197.25977 688.49804,196.68946 688.64648,196.23633 C 688.79492,195.7754 689.0332,195.34571 689.36133,194.94727 C 689.61132,194.6504 689.98242,194.31056 690.47461,193.92773 C 690.9746,193.54493 691.29882,193.26759 691.44727,193.0957 C 691.75976,192.74415 691.9746,192.42775 692.0918,192.14648 C 692.20898,191.86525 692.26757,191.55665 692.26758,191.2207 C 692.26757,190.47853 692.06054,189.9004 691.64648,189.48633 C 691.23241,189.07228 690.65429,188.86525 689.91211,188.86523 C 689.16992,188.86525 688.58398,189.11525 688.1543,189.61523 C 687.73242,190.10744 687.50195,190.80275 687.46289,191.70117 L 684.1582,191.70117 L 684.1582,191.33789 C 684.1582,189.68947 684.67773,188.37697 685.7168,187.40039 C 686.76367,186.41603 688.16992,185.92385 689.93555,185.92383 C 691.74023,185.92385 693.17382,186.38869 694.23633,187.31836 C 695.30663,188.24025 695.84178,189.47853 695.8418,191.0332 C 695.84178,191.58009 695.77928,192.07228 695.6543,192.50977 C 695.5371,192.93946 695.3535,193.33399 695.10352,193.69336 C 694.78319,194.14649 694.2871,194.63868 693.61523,195.16992 C 692.95116,195.69337 692.54882,196.01759 692.4082,196.14258 C 692.11132,196.43165 691.89648,196.73634 691.76367,197.05664 C 691.63866,197.37696 691.57616,197.75977 691.57617,198.20508 C 691.57616,198.24415 691.58007,198.31055 691.58789,198.4043 C 691.59569,198.49805 691.5996,198.56836 691.59961,198.61523 L 688.44727,198.61523 M 688.2832,203.63086 L 688.2832,200.19727 L 691.74023,200.19727 L 691.74023,203.63086 L 688.2832,203.63086 M 686.31445,235.85742 L 692.12695,215.92383 L 693.73242,215.92383 L 687.89648,235.85742 L 686.31445,235.85742"
708 id="text5819" />
709 <path
710 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
711 d="M 18,271.78906 C 17.911447,273.09636 17.406239,274.13542 16.484375,274.90625 C 15.5677,275.67708 14.369784,276.0625 12.890625,276.0625 C 11.187496,276.0625 9.8619761,275.53125 8.9140625,274.46875 C 7.971353,273.40625 7.4999993,271.91667 7.5,270 C 7.4999993,268.04167 7.9817696,266.54168 8.9453125,265.5 C 9.9088511,264.45834 11.294266,263.93751 13.101563,263.9375 C 14.570305,263.93751 15.729158,264.29689 16.578125,265.01563 C 17.432281,265.72918 17.901031,266.73959 17.984375,268.04688 L 15.648438,268.04688 C 15.54947,267.39584 15.283846,266.90105 14.851563,266.5625 C 14.419263,266.21876 13.83593,266.04688 13.101563,266.04688 C 12.059891,266.04688 11.268225,266.38282 10.726563,267.05469 C 10.184892,267.72657 9.9140594,268.70834 9.9140625,270 C 9.9140594,271.25 10.182288,272.21615 10.71875,272.89844 C 11.260412,273.58073 12.028641,273.92188 13.023438,273.92188 C 13.742181,273.92188 14.330722,273.73959 14.789063,273.375 C 15.247387,273.00521 15.544262,272.47657 15.679688,271.78906 L 18,271.78906 M 23.46875,275.80469 C 23.260412,275.8099 23.010412,275.81771 22.71875,275.82813 C 22.432288,275.84375 22.249996,275.85156 22.171875,275.85156 C 21.302081,275.85156 20.705727,275.6901 20.382813,275.36719 C 20.065103,275.03906 19.906249,274.39583 19.90625,273.4375 L 19.90625,268.84375 L 18.78125,268.84375 L 18.78125,267.25 L 19.90625,267.25 L 19.90625,264.92969 L 22.15625,264.92969 L 22.15625,267.25 L 23.46875,267.25 L 23.46875,268.84375 L 22.15625,268.84375 L 22.15625,273.54688 C 22.156247,273.77084 22.205726,273.91927 22.304688,273.99219 C 22.403642,274.0599 22.606767,274.09375 22.914063,274.09375 L 23.46875,274.09375 L 23.46875,275.80469 M 24.789063,275.74219 L 24.789063,267.25 L 26.898438,267.25 L 26.898438,268.70313 C 27.195309,268.1198 27.541663,267.69272 27.9375,267.42188 C 28.333329,267.14584 28.804682,267.00782 29.351563,267.00781 C 29.440099,267.00782 29.507807,267.01043 29.554688,267.01563 C 29.606765,267.01563 29.648432,267.01824 29.679688,267.02344 L 29.6875,269.32813 L 28.929688,269.32813 C 28.309891,269.32813 27.843746,269.48959 27.53125,269.8125 C 27.218747,270.13542 27.062497,270.61459 27.0625,271.25 L 27.0625,275.74219 L 24.789063,275.74219 M 31.023438,275.74219 L 31.023438,264.23438 L 33.296875,264.23438 L 33.296875,275.74219 L 31.023438,275.74219"
712 id="text5827" />
713 <path
714 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
715 d="M 612.96875,266.53906 L 611.375,271.4375 L 614.57031,271.4375 L 612.96875,266.53906 M 611.59375,264.23438 L 614.32813,264.23438 L 618.47656,275.74219 L 615.99219,275.74219 L 615.21094,273.375 L 610.75,273.375 L 609.99219,275.74219 L 607.5,275.74219 L 611.59375,264.23438 M 619.53906,275.74219 L 619.53906,264.23438 L 621.8125,264.23438 L 621.8125,275.74219 L 619.53906,275.74219 M 627.64063,275.80469 C 627.43229,275.8099 627.18229,275.81771 626.89063,275.82813 C 626.60416,275.84375 626.42187,275.85156 626.34375,275.85156 C 625.47396,275.85156 624.8776,275.6901 624.55469,275.36719 C 624.23698,275.03906 624.07812,274.39583 624.07813,273.4375 L 624.07813,268.84375 L 622.95313,268.84375 L 622.95313,267.25 L 624.07813,267.25 L 624.07813,264.92969 L 626.32813,264.92969 L 626.32813,267.25 L 627.64063,267.25 L 627.64063,268.84375 L 626.32813,268.84375 L 626.32813,273.54688 C 626.32812,273.77084 626.3776,273.91927 626.47656,273.99219 C 626.57552,274.0599 626.77864,274.09375 627.08594,274.09375 L 627.64063,274.09375 L 627.64063,275.80469"
716 id="text5835"
717 sodipodi:nodetypes="cccccccccccccccccccsssccccccccccccsccc" />
718 <path
719 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
720 d="M 828,271.78906 C 827.91145,273.09636 827.40624,274.13542 826.48438,274.90625 C 825.5677,275.67708 824.36978,276.0625 822.89063,276.0625 C 821.1875,276.0625 819.86198,275.53125 818.91406,274.46875 C 817.97135,273.40625 817.5,271.91667 817.5,270 C 817.5,268.04167 817.98177,266.54168 818.94531,265.5 C 819.90885,264.45834 821.29427,263.93751 823.10156,263.9375 C 824.5703,263.93751 825.72916,264.29689 826.57813,265.01563 C 827.43228,265.72918 827.90103,266.73959 827.98438,268.04688 L 825.64844,268.04688 C 825.54947,267.39584 825.28385,266.90105 824.85156,266.5625 C 824.41926,266.21876 823.83593,266.04688 823.10156,266.04688 C 822.05989,266.04688 821.26822,266.38282 820.72656,267.05469 C 820.18489,267.72657 819.91406,268.70834 819.91406,270 C 819.91406,271.25 820.18229,272.21615 820.71875,272.89844 C 821.26041,273.58073 822.02864,273.92188 823.02344,273.92188 C 823.74218,273.92188 824.33072,273.73959 824.78906,273.375 C 825.24739,273.00521 825.54426,272.47657 825.67969,271.78906 L 828,271.78906 M 833.46875,275.80469 C 833.26041,275.8099 833.01041,275.81771 832.71875,275.82813 C 832.43229,275.84375 832.25,275.85156 832.17188,275.85156 C 831.30208,275.85156 830.70573,275.6901 830.38281,275.36719 C 830.0651,275.03906 829.90625,274.39583 829.90625,273.4375 L 829.90625,268.84375 L 828.78125,268.84375 L 828.78125,267.25 L 829.90625,267.25 L 829.90625,264.92969 L 832.15625,264.92969 L 832.15625,267.25 L 833.46875,267.25 L 833.46875,268.84375 L 832.15625,268.84375 L 832.15625,273.54688 C 832.15625,273.77084 832.20573,273.91927 832.30469,273.99219 C 832.40364,274.0599 832.60677,274.09375 832.91406,274.09375 L 833.46875,274.09375 L 833.46875,275.80469 M 834.78906,275.74219 L 834.78906,267.25 L 836.89844,267.25 L 836.89844,268.70313 C 837.19531,268.1198 837.54166,267.69272 837.9375,267.42188 C 838.33333,267.14584 838.80468,267.00782 839.35156,267.00781 C 839.4401,267.00782 839.50781,267.01043 839.55469,267.01563 C 839.60677,267.01563 839.64843,267.01824 839.67969,267.02344 L 839.6875,269.32813 L 838.92969,269.32813 C 838.30989,269.32813 837.84375,269.48959 837.53125,269.8125 C 837.21875,270.13542 837.0625,270.61459 837.0625,271.25 L 837.0625,275.74219 L 834.78906,275.74219 M 841.02344,275.74219 L 841.02344,264.23438 L 843.29688,264.23438 L 843.29688,275.74219 L 841.02344,275.74219"
721 id="text5839" />
722 <path
723 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
724 d="M 108.94531,264.01953 L 105.64844,252.51172 L 108.10156,252.51172 L 110.07031,260.62891 L 111.73438,252.51172 L 114.25781,252.51172 L 115.92188,260.62891 L 117.89063,252.51172 L 120.32031,252.51172 L 117.03125,264.01953 L 114.77344,264.01953 L 112.99219,255.20703 L 111.20313,264.01953 L 108.94531,264.01953 M 121.5,254.58203 L 121.5,252.51172 L 123.77344,252.51172 L 123.77344,254.58203 L 121.5,254.58203 M 121.5,264.01953 L 121.5,255.52734 L 123.77344,255.52734 L 123.77344,264.01953 L 121.5,264.01953 M 125.79688,264.01953 L 125.79688,255.52734 L 128.02344,255.52734 L 128.02344,256.53516 C 128.34114,256.12371 128.71614,255.81641 129.14844,255.61328 C 129.58072,255.40496 130.06249,255.30079 130.59375,255.30078 C 131.53124,255.30079 132.23176,255.54558 132.69531,256.03516 C 133.16405,256.51954 133.39843,257.25131 133.39844,258.23047 L 133.39844,264.01953 L 131.125,264.01953 L 131.125,258.88672 C 131.12499,258.27735 131.02083,257.84245 130.8125,257.58203 C 130.60937,257.32162 130.27604,257.19141 129.8125,257.19141 C 129.27604,257.19141 128.85156,257.35287 128.53906,257.67578 C 128.22656,257.9935 128.07031,258.42839 128.07031,258.98047 L 128.07031,264.01953 L 125.79688,264.01953 M 106.64844,284.01953 L 106.64844,272.51172 L 109.01563,272.51172 L 109.01563,277.23828 L 113.50781,272.51172 L 116.46875,272.51172 L 111.875,277.16797 L 116.88281,284.01953 L 113.99219,284.01953 L 110.24219,278.75391 L 109.01563,279.97266 L 109.01563,284.01953 L 106.64844,284.01953 M 122.9375,281.44141 L 125.20313,281.44141 C 124.97395,282.33724 124.51041,283.04037 123.8125,283.55078 C 123.11979,284.05599 122.27343,284.30859 121.27344,284.30859 C 120.04427,284.30859 119.07031,283.89714 118.35156,283.07422 C 117.63281,282.2461 117.27344,281.1263 117.27344,279.71484 C 117.27344,278.32422 117.6276,277.22787 118.33594,276.42578 C 119.04427,275.62371 120.01302,275.22267 121.24219,275.22266 C 122.54427,275.22267 123.54947,275.6185 124.25781,276.41016 C 124.96614,277.19662 125.3203,278.31902 125.32031,279.77734 C 125.3203,279.93881 125.3177,280.0612 125.3125,280.14453 C 125.31249,280.22266 125.30728,280.29818 125.29688,280.37109 L 119.625,280.37109 C 119.65625,281.03776 119.81771,281.54037 120.10938,281.87891 C 120.40625,282.21745 120.83073,282.38672 121.38281,282.38672 C 121.77343,282.38672 122.09374,282.3112 122.34375,282.16016 C 122.59374,282.00391 122.79166,281.76433 122.9375,281.44141 M 119.625,278.87891 L 122.96875,278.87891 C 122.94791,278.306 122.79426,277.8711 122.50781,277.57422 C 122.22656,277.27214 121.82031,277.1211 121.28906,277.12109 C 120.79427,277.1211 120.40364,277.27214 120.11719,277.57422 C 119.83593,277.87631 119.67187,278.3112 119.625,278.87891 M 127.16406,287.42578 L 127.16406,285.58984 C 127.23698,285.60026 127.3125,285.60807 127.39063,285.61328 C 127.46875,285.61849 127.57031,285.62109 127.69531,285.62109 C 128.14323,285.62109 128.47916,285.51432 128.70313,285.30078 C 128.92708,285.09245 129.03906,284.77734 129.03906,284.35547 C 129.03906,284.32422 129.03385,284.28516 129.02344,284.23828 C 129.01302,284.19141 129.0026,284.15234 128.99219,284.12109 L 125.92969,275.52734 L 128.42969,275.52734 L 130.21875,281.65234 L 131.96094,275.52734 L 134.35156,275.52734 L 130.85938,285.54297 C 130.59895,286.29297 130.27343,286.80338 129.88281,287.07422 C 129.49218,287.35026 128.90625,287.48828 128.125,287.48828 C 127.98437,287.48828 127.83333,287.48307 127.67188,287.47266 C 127.51041,287.46224 127.34114,287.44661 127.16406,287.42578"
725 id="text5872" />
726 <path
727 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
728 d="M 708.94531,264.01953 L 705.64844,252.51172 L 708.10156,252.51172 L 710.07031,260.62891 L 711.73438,252.51172 L 714.25781,252.51172 L 715.92188,260.62891 L 717.89063,252.51172 L 720.32031,252.51172 L 717.03125,264.01953 L 714.77344,264.01953 L 712.99219,255.20703 L 711.20313,264.01953 L 708.94531,264.01953 M 721.5,254.58203 L 721.5,252.51172 L 723.77344,252.51172 L 723.77344,254.58203 L 721.5,254.58203 M 721.5,264.01953 L 721.5,255.52734 L 723.77344,255.52734 L 723.77344,264.01953 L 721.5,264.01953 M 725.79688,264.01953 L 725.79688,255.52734 L 728.02344,255.52734 L 728.02344,256.53516 C 728.34114,256.12371 728.71614,255.81641 729.14844,255.61328 C 729.58072,255.40496 730.06249,255.30079 730.59375,255.30078 C 731.53124,255.30079 732.23176,255.54558 732.69531,256.03516 C 733.16405,256.51954 733.39843,257.25131 733.39844,258.23047 L 733.39844,264.01953 L 731.125,264.01953 L 731.125,258.88672 C 731.12499,258.27735 731.02083,257.84245 730.8125,257.58203 C 730.60937,257.32162 730.27604,257.19141 729.8125,257.19141 C 729.27604,257.19141 728.85156,257.35287 728.53906,257.67578 C 728.22656,257.9935 728.07031,258.42839 728.07031,258.98047 L 728.07031,264.01953 L 725.79688,264.01953 M 706.64844,284.01953 L 706.64844,272.51172 L 709.01563,272.51172 L 709.01563,277.23828 L 713.50781,272.51172 L 716.46875,272.51172 L 711.875,277.16797 L 716.88281,284.01953 L 713.99219,284.01953 L 710.24219,278.75391 L 709.01563,279.97266 L 709.01563,284.01953 L 706.64844,284.01953 M 722.9375,281.44141 L 725.20313,281.44141 C 724.97395,282.33724 724.51041,283.04037 723.8125,283.55078 C 723.11979,284.05599 722.27343,284.30859 721.27344,284.30859 C 720.04427,284.30859 719.07031,283.89714 718.35156,283.07422 C 717.63281,282.2461 717.27344,281.1263 717.27344,279.71484 C 717.27344,278.32422 717.6276,277.22787 718.33594,276.42578 C 719.04427,275.62371 720.01302,275.22267 721.24219,275.22266 C 722.54427,275.22267 723.54947,275.6185 724.25781,276.41016 C 724.96614,277.19662 725.3203,278.31902 725.32031,279.77734 C 725.3203,279.93881 725.3177,280.0612 725.3125,280.14453 C 725.31249,280.22266 725.30728,280.29818 725.29688,280.37109 L 719.625,280.37109 C 719.65625,281.03776 719.81771,281.54037 720.10938,281.87891 C 720.40625,282.21745 720.83073,282.38672 721.38281,282.38672 C 721.77343,282.38672 722.09374,282.3112 722.34375,282.16016 C 722.59374,282.00391 722.79166,281.76433 722.9375,281.44141 M 719.625,278.87891 L 722.96875,278.87891 C 722.94791,278.306 722.79426,277.8711 722.50781,277.57422 C 722.22656,277.27214 721.82031,277.1211 721.28906,277.12109 C 720.79427,277.1211 720.40364,277.27214 720.11719,277.57422 C 719.83593,277.87631 719.67187,278.3112 719.625,278.87891 M 727.16406,287.42578 L 727.16406,285.58984 C 727.23698,285.60026 727.3125,285.60807 727.39063,285.61328 C 727.46875,285.61849 727.57031,285.62109 727.69531,285.62109 C 728.14323,285.62109 728.47916,285.51432 728.70313,285.30078 C 728.92708,285.09245 729.03906,284.77734 729.03906,284.35547 C 729.03906,284.32422 729.03385,284.28516 729.02344,284.23828 C 729.01302,284.19141 729.0026,284.15234 728.99219,284.12109 L 725.92969,275.52734 L 728.42969,275.52734 L 730.21875,281.65234 L 731.96094,275.52734 L 734.35156,275.52734 L 730.85938,285.54297 C 730.59895,286.29297 730.27343,286.80338 729.88281,287.07422 C 729.49218,287.35026 728.90625,287.48828 728.125,287.48828 C 727.98437,287.48828 727.83333,287.48307 727.67188,287.47266 C 727.51041,287.46224 727.34114,287.44661 727.16406,287.42578"
729 id="text5878" />
730 <path
731 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
732 d="M 759.98438,275.60938 L 759.98438,264.10156 L 763.48438,264.10156 L 765.77344,272.85938 L 768.03125,264.10156 L 771.54688,264.10156 L 771.54688,275.60938 L 769.32813,275.60938 L 769.32813,266.32813 L 766.99219,275.60938 L 764.57031,275.60938 L 762.20313,266.32813 L 762.20313,275.60938 L 759.98438,275.60938 M 778.99219,273.03125 L 781.25781,273.03125 C 781.02864,273.92709 780.5651,274.63021 779.86719,275.14063 C 779.17447,275.64583 778.32812,275.89844 777.32813,275.89844 C 776.09896,275.89844 775.125,275.48698 774.40625,274.66406 C 773.6875,273.83594 773.32812,272.71615 773.32813,271.30469 C 773.32812,269.91407 773.68229,268.81772 774.39063,268.01563 C 775.09896,267.21355 776.06771,266.81251 777.29688,266.8125 C 778.59895,266.81251 779.60416,267.20834 780.3125,268 C 781.02083,268.78647 781.37499,269.90886 781.375,271.36719 C 781.37499,271.52865 781.37239,271.65105 781.36719,271.73438 C 781.36718,271.8125 781.36197,271.88802 781.35156,271.96094 L 775.67969,271.96094 C 775.71093,272.62761 775.87239,273.13021 776.16406,273.46875 C 776.46093,273.80729 776.88541,273.97656 777.4375,273.97656 C 777.82812,273.97656 778.14843,273.90104 778.39844,273.75 C 778.64843,273.59375 778.84635,273.35417 778.99219,273.03125 M 775.67969,270.46875 L 779.02344,270.46875 C 779.0026,269.89584 778.84895,269.46094 778.5625,269.16406 C 778.28124,268.86199 777.87499,268.71094 777.34375,268.71094 C 776.84895,268.71094 776.45833,268.86199 776.17188,269.16406 C 775.89062,269.46615 775.72656,269.90105 775.67969,270.46875 M 782.88281,275.60938 L 782.88281,267.11719 L 785.10938,267.11719 L 785.10938,268.125 C 785.42708,267.71355 785.80208,267.40626 786.23438,267.20313 C 786.66666,266.9948 787.14843,266.89063 787.67969,266.89063 C 788.61718,266.89063 789.3177,267.13543 789.78125,267.625 C 790.24999,268.10938 790.48437,268.84115 790.48438,269.82031 L 790.48438,275.60938 L 788.21094,275.60938 L 788.21094,270.47656 C 788.21093,269.86719 788.10676,269.4323 787.89844,269.17188 C 787.69531,268.91147 787.36197,268.78126 786.89844,268.78125 C 786.36197,268.78126 785.9375,268.94272 785.625,269.26563 C 785.3125,269.58334 785.15625,270.01823 785.15625,270.57031 L 785.15625,275.60938 L 782.88281,275.60938 M 800.01563,267.11719 L 800.01563,275.60938 L 797.78906,275.60938 L 797.78906,274.60156 C 797.46614,275.01302 797.08854,275.32292 796.65625,275.53125 C 796.22916,275.73437 795.74739,275.83594 795.21094,275.83594 C 794.27864,275.83594 793.57812,275.59115 793.10938,275.10156 C 792.64583,274.61198 792.41406,273.88021 792.41406,272.90625 L 792.41406,267.11719 L 794.6875,267.11719 L 794.6875,272.25 C 794.6875,272.85417 794.78906,273.28646 794.99219,273.54688 C 795.19531,273.80209 795.53125,273.92969 796,273.92969 C 796.53124,273.92969 796.95312,273.77084 797.26563,273.45313 C 797.58333,273.13021 797.74218,272.69271 797.74219,272.14063 L 797.74219,267.11719 L 800.01563,267.11719"
733 id="text5884" />
734 <text
735 xml:space="preserve"
736 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
737 x="314.20523"
738 y="144.79591"
739 id="text2980"><tspan
740 sodipodi:role="line"
741 id="tspan2982"
742 x="314.20523"
743 y="144.79591"
744 style="font-size:14px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold">full</tspan><tspan
745 sodipodi:role="line"
746 x="314.20523"
747 y="162.29591"
748 id="tspan2984"
749 style="font-size:14px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold">screen</tspan></text>
750 <text
751 xml:space="preserve"
752 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
753 x="180"
754 y="86"
755 id="text2986"><tspan
756 sodipodi:role="line"
757 id="tspan2988"
758 x="180"
759 y="86"
760 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold">tabbed</tspan><tspan
761 sodipodi:role="line"
762 x="180"
763 y="102.25"
764 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold"
765 id="tspan3030">layout</tspan></text>
766 <text
767 xml:space="preserve"
768 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
769 x="240"
770 y="86"
771 id="text2990"><tspan
772 sodipodi:role="line"
773 id="tspan2992"
774 x="240"
775 y="86"
776 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold">default</tspan><tspan
777 sodipodi:role="line"
778 x="240"
779 y="102.25"
780 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold"
781 id="tspan3028">layout</tspan></text>
782 <text
783 xml:space="preserve"
784 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
785 x="230.73412"
786 y="154.28845"
787 id="text2994"><tspan
788 sodipodi:role="line"
789 id="tspan2996"
790 x="230.73412"
791 y="154.28845"
792 style="font-size:13px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">dmenu</tspan></text>
793 <text
794 xml:space="preserve"
795 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
796 x="428.51135"
797 y="272.48416"
798 id="text2998"><tspan
799 sodipodi:role="line"
800 x="428.51135"
801 y="272.48416"
802 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold"
803 id="tspan3004">focus floating/tiling</tspan></text>
804 <text
805 xml:space="preserve"
806 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
807 x="480"
808 y="154"
809 id="text3006"><tspan
810 sodipodi:role="line"
811 id="tspan3008"
812 x="480"
813 y="154"
814 style="font-size:13px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">left</tspan></text>
815 <text
816 xml:space="preserve"
817 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
818 x="540"
819 y="154"
820 id="text3010"><tspan
821 sodipodi:role="line"
822 id="tspan3012"
823 x="540"
824 y="154"
825 style="font-size:13px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">down</tspan></text>
826 <text
827 xml:space="preserve"
828 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
829 x="600"
830 y="154"
831 id="text3014"><tspan
832 sodipodi:role="line"
833 id="tspan3016"
834 x="600"
835 y="154"
836 style="font-size:13px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">up</tspan></text>
837 <text
838 xml:space="preserve"
839 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
840 x="660"
841 y="154"
842 id="text3018"><tspan
843 sodipodi:role="line"
844 id="tspan3020"
845 x="660"
846 y="154"
847 style="font-size:13px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">right</tspan></text>
848 <text
849 xml:space="preserve"
850 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
851 x="434.21317"
852 y="146.87415"
853 id="text3022"><tspan
854 sodipodi:role="line"
855 x="434.21317"
856 y="146.87415"
857 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold"
858 id="tspan3026">split</tspan><tspan
859 sodipodi:role="line"
860 x="434.21317"
861 y="163.12415"
862 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold"
863 id="tspan3397">horiz.</tspan></text>
864 <text
865 xml:space="preserve"
866 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
867 x="164.78459"
868 y="277.00677"
869 id="text2996"><tspan
870 sodipodi:role="line"
871 id="tspan2998"
872 x="164.78459"
873 y="277.00677"
874 style="font-size:18px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">Mod1</tspan></text>
875 <text
876 xml:space="preserve"
877 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
878 x="830.84515"
879 y="144.03874"
880 id="text3022-6"><tspan
881 sodipodi:role="line"
882 x="830.84515"
883 y="144.03874"
884 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold"
885 id="tspan3026-2">open</tspan><tspan
886 sodipodi:role="line"
887 x="830.84515"
888 y="160.28874"
889 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold"
890 id="tspan3385">terminal</tspan></text>
891 <text
892 xml:space="preserve"
893 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
894 x="345.9798"
895 y="205.08424"
896 id="text3022-4"><tspan
897 sodipodi:role="line"
898 x="345.9798"
899 y="205.08424"
900 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold"
901 id="tspan3026-5">split</tspan><tspan
902 sodipodi:role="line"
903 x="345.9798"
904 y="221.33424"
905 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold"
906 id="tspan3397-1">vert.</tspan></text>
907 <text
908 xml:space="preserve"
909 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
910 x="194.07654"
911 y="146.9129"
912 id="text2986-0"><tspan
913 sodipodi:role="line"
914 id="tspan2988-3"
915 x="194.07654"
916 y="146.9129"
917 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold">stacked</tspan><tspan
918 sodipodi:role="line"
919 x="194.07654"
920 y="163.1629"
921 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold"
922 id="tspan3030-7">layout</tspan></text>
923 <text
924 xml:space="preserve"
925 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
926 x="135.30087"
927 y="145.95485"
928 id="text2986-0-8"><tspan
929 sodipodi:role="line"
930 x="135.30087"
931 y="145.95485"
932 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold"
933 id="tspan3030-7-6">focus</tspan><tspan
934 sodipodi:role="line"
935 x="135.30087"
936 y="162.20485"
937 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold"
938 id="tspan3477">parent</tspan></text>
939 <text
940 xml:space="preserve"
941 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
942 x="278.85074"
943 y="86.411041"
944 id="text2994-0"><tspan
945 sodipodi:role="line"
946 id="tspan2996-4"
947 x="278.85074"
948 y="86.411041"
949 style="font-size:13px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">resize</tspan><tspan
950 sodipodi:role="line"
951 x="278.85074"
952 y="102.66104"
953 style="font-size:13px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold"
954 id="tspan3500">mode</tspan></text>
955 <text
956 xml:space="preserve"
957 style="font-size:14px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Sans Bold"
958 x="340.89798"
959 y="83.480705"
960 id="text3755"
961 sodipodi:linespacing="125%"><tspan
962 sodipodi:role="line"
963 id="tspan3757"
964 x="340.89798"
965 y="83.480705"
966 style="font-size:22px">T</tspan></text>
967 </g>
968 </svg>
Binary diff not shown
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="900"
12 height="300"
13 id="svg2"
14 sodipodi:version="0.32"
15 inkscape:version="0.47 r22583"
16 version="1.0"
17 sodipodi:docname="keyboard-layer2.svg">
18 <defs
19 id="defs4">
20 <inkscape:perspective
21 sodipodi:type="inkscape:persp3d"
22 inkscape:vp_x="0 : 150 : 1"
23 inkscape:vp_y="0 : 1000 : 0"
24 inkscape:vp_z="900 : 150 : 1"
25 inkscape:persp3d-origin="450 : 100 : 1"
26 id="perspective3385" />
27 <marker
28 inkscape:stockid="Arrow1Lend"
29 orient="auto"
30 refY="0.0"
31 refX="0.0"
32 id="Arrow1Lend"
33 style="overflow:visible;">
34 <path
35 id="path5387"
36 d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
37 style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
38 transform="scale(0.8) rotate(180)" />
39 </marker>
40 <marker
41 inkscape:stockid="Arrow1Lstart"
42 orient="auto"
43 refY="0.0"
44 refX="0.0"
45 id="Arrow1Lstart"
46 style="overflow:visible">
47 <path
48 id="path5390"
49 d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
50 style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
51 transform="scale(0.8)" />
52 </marker>
53 <marker
54 inkscape:stockid="Tail"
55 orient="auto"
56 refY="0.0"
57 refX="0.0"
58 id="Tail"
59 style="overflow:visible">
60 <g
61 id="g5342"
62 transform="scale(-1.2)">
63 <path
64 id="path5344"
65 d="M -3.8048674,-3.9585227 L 0.54352094,-0.00068114835"
66 style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
67 <path
68 id="path5346"
69 d="M -1.2866832,-3.9585227 L 3.0617053,-0.00068114835"
70 style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
71 <path
72 id="path5348"
73 d="M 1.3053582,-3.9585227 L 5.6537466,-0.00068114835"
74 style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
75 <path
76 id="path5350"
77 d="M -3.8048674,4.1775838 L 0.54352094,0.21974226"
78 style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
79 <path
80 id="path5352"
81 d="M -1.2866832,4.1775838 L 3.0617053,0.21974226"
82 style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
83 <path
84 id="path5354"
85 d="M 1.3053582,4.1775838 L 5.6537466,0.21974226"
86 style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.8;marker-start:none;marker-end:none;stroke-linecap:round" />
87 </g>
88 </marker>
89 <marker
90 inkscape:stockid="Arrow2Mend"
91 orient="auto"
92 refY="0.0"
93 refX="0.0"
94 id="Arrow2Mend"
95 style="overflow:visible;">
96 <path
97 id="path5363"
98 style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
99 d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
100 transform="scale(0.6) rotate(180) translate(-5,0)" />
101 </marker>
102 <marker
103 inkscape:stockid="Arrow2Lend"
104 orient="auto"
105 refY="0.0"
106 refX="0.0"
107 id="Arrow2Lend"
108 style="overflow:visible;">
109 <path
110 id="path5369"
111 style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
112 d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
113 transform="scale(1.1) rotate(180) translate(-5,0)" />
114 </marker>
115 <marker
116 inkscape:stockid="Arrow1Send"
117 orient="auto"
118 refY="0.0"
119 refX="0.0"
120 id="Arrow1Send"
121 style="overflow:visible;">
122 <path
123 id="path5375"
124 d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
125 style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
126 transform="scale(0.2) rotate(180)" />
127 </marker>
128 <marker
129 inkscape:stockid="Arrow2Send"
130 orient="auto"
131 refY="0.0"
132 refX="0.0"
133 id="Arrow2Send"
134 style="overflow:visible;">
135 <path
136 id="path5357"
137 style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
138 d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
139 transform="scale(0.3) rotate(180) translate(-5,0)" />
140 </marker>
141 <marker
142 inkscape:stockid="Arrow1Mend"
143 orient="auto"
144 refY="0.0"
145 refX="0.0"
146 id="Arrow1Mend"
147 style="overflow:visible;">
148 <path
149 id="path5381"
150 d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
151 style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
152 transform="scale(0.4) rotate(180)" />
153 </marker>
154 <marker
155 inkscape:stockid="Arrow2Lstart"
156 orient="auto"
157 refY="0.0"
158 refX="0.0"
159 id="Arrow2Lstart"
160 style="overflow:visible">
161 <path
162 id="path5372"
163 style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round"
164 d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
165 transform="scale(1.1) translate(-5,0)" />
166 </marker>
167 </defs>
168 <sodipodi:namedview
169 id="base"
170 pagecolor="#ffffff"
171 bordercolor="#666666"
172 borderopacity="1.0"
173 inkscape:pageopacity="0.0"
174 inkscape:pageshadow="2"
175 inkscape:zoom="1.0437869"
176 inkscape:cx="412.7029"
177 inkscape:cy="149.32256"
178 inkscape:document-units="px"
179 inkscape:current-layer="layer1"
180 inkscape:grid-points="true"
181 showgrid="true"
182 gridtolerance="15px"
183 showborder="false"
184 inkscape:window-width="956"
185 inkscape:window-height="958"
186 inkscape:window-x="1600"
187 inkscape:window-y="221"
188 showguides="true"
189 inkscape:guide-bbox="true"
190 inkscape:window-maximized="0">
191 <inkscape:grid
192 id="GridFromPre046Settings"
193 type="xygrid"
194 originx="0px"
195 originy="0px"
196 spacingx="7.5px"
197 spacingy="7.5px"
198 color="#0000ff"
199 empcolor="#0000ff"
200 opacity="0.12156863"
201 empopacity="0.25098039"
202 empspacing="4" />
203 </sodipodi:namedview>
204 <metadata
205 id="metadata7">
206 <rdf:RDF>
207 <cc:Work
208 rdf:about="">
209 <dc:format>image/svg+xml</dc:format>
210 <dc:type
211 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
212 </cc:Work>
213 </rdf:RDF>
214 </metadata>
215 <g
216 inkscape:label="Layer 1"
217 inkscape:groupmode="layer"
218 id="layer1">
219 <path
220 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
221 d="M 0,0 L 60,0 L 60,60 L 0,60 L 0,0 z "
222 id="rect2186" />
223 <path
224 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
225 d="M 60,0 L 120,0 L 120,60 L 60,60 L 60,0 z "
226 id="rect2218" />
227 <path
228 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
229 d="M 120,0 L 180,0 L 180,60 L 120,60 L 120,0 z "
230 id="rect2222" />
231 <path
232 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
233 d="M 180,0 L 240,0 L 240,60 L 180,60 L 180,0 z "
234 id="rect2228" />
235 <path
236 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
237 d="M 240,0 L 300,0 L 300,60 L 240,60 L 240,0 z "
238 id="rect2230" />
239 <path
240 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
241 d="M 300,0 L 360,0 L 360,60 L 300,60 L 300,0 z "
242 id="rect2232" />
243 <path
244 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
245 d="M 360,0 L 420,0 L 420,60 L 360,60 L 360,0 z "
246 id="rect2234" />
247 <path
248 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
249 d="M 420,0 L 480,0 L 480,60 L 420,60 L 420,0 z "
250 id="rect2236" />
251 <path
252 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
253 d="M 480,0 L 540,0 L 540,60 L 480,60 L 480,0 z "
254 id="rect2238" />
255 <path
256 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
257 d="M 540,0 L 600,0 L 600,60 L 540,60 L 540,0 z "
258 id="rect2240" />
259 <path
260 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
261 d="M 600,0 L 660,0 L 660,60 L 600,60 L 600,0 z "
262 id="rect2242" />
263 <path
264 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
265 d="M 660,0 L 720,0 L 720,60 L 660,60 L 660,0 z "
266 id="rect2244" />
267 <path
268 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
269 d="M 720,0 L 780,0 L 780,60 L 720,60 L 720,0 z "
270 id="rect2246" />
271 <path
272 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
273 d="M 780,0 L 900,0 L 900,60 L 780,60 L 780,0 z "
274 id="rect2248" />
275 <path
276 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
277 d="M 0,60 L 90,60 L 90,120 L 0,120 L 0,60 z "
278 id="rect2250" />
279 <path
280 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
281 d="M 90,60 L 150,60 L 150,120 L 90,120 L 90,60 z "
282 id="rect2252" />
283 <path
284 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
285 d="M 150,60 L 210,60 L 210,120 L 150,120 L 150,60 z "
286 id="rect2254" />
287 <path
288 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
289 d="M 210,60 L 270,60 L 270,120 L 210,120 L 210,60 z "
290 id="rect2256" />
291 <path
292 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
293 d="M 270,60 L 330,60 L 330,120 L 270,120 L 270,60 z "
294 id="rect2258" />
295 <path
296 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
297 d="M 330,60 L 390,60 L 390,120 L 330,120 L 330,60 z "
298 id="rect2262" />
299 <path
300 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
301 d="M 390,60 L 450,60 L 450,120 L 390,120 L 390,60 z "
302 id="rect2264" />
303 <path
304 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
305 d="M 450,60 L 510,60 L 510,120 L 450,120 L 450,60 z "
306 id="rect2266" />
307 <path
308 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
309 d="M 510,60 L 570,60 L 570,120 L 510,120 L 510,60 z "
310 id="rect2270" />
311 <path
312 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
313 d="M 570,60 L 630,60 L 630,120 L 570,120 L 570,60 z "
314 id="rect2272" />
315 <path
316 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
317 d="M 630,60 L 690,60 L 690,120 L 630,120 L 630,60 z "
318 id="rect2274" />
319 <path
320 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
321 d="M 690,60 L 750,60 L 750,120 L 690,120 L 690,60 z "
322 id="rect2278" />
323 <path
324 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
325 d="M 750,60 L 810,60 L 810,120 L 750,120 L 750,60 z "
326 id="rect2280" />
327 <path
328 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
329 d="M 810,60 L 900,60 L 900,120 L 810,120 L 810,60 z "
330 id="rect2284" />
331 <path
332 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
333 d="M 0,120 L 105,120 L 105,180 L 0,180 L 0,120 z "
334 id="rect2286" />
335 <path
336 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
337 d="M 105,120 L 165,120 L 165,180 L 105,180 L 105,120 z "
338 id="rect2292" />
339 <path
340 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
341 d="M 165,120 L 225,120 L 225,180 L 165,180 L 165,120 z "
342 id="rect2296" />
343 <path
344 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
345 d="M 225,120 L 285,120 L 285,180 L 225,180 L 225,120 z "
346 id="rect2298" />
347 <path
348 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
349 d="M 285,120 L 345,120 L 345,180 L 285,180 L 285,120 z "
350 id="rect2300" />
351 <path
352 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
353 d="M 345,120 L 405,120 L 405,180 L 345,180 L 345,120 z "
354 id="rect2302" />
355 <path
356 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
357 d="M 405,120 L 465,120 L 465,180 L 405,180 L 405,120 z "
358 id="rect2306" />
359 <path
360 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
361 d="M 465,120 L 525,120 L 525,180 L 465,180 L 465,120 z "
362 id="rect2308" />
363 <path
364 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
365 d="M 525,120 L 585,120 L 585,180 L 525,180 L 525,120 z "
366 id="rect2312" />
367 <path
368 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
369 d="M 585,120 L 645,120 L 645,180 L 585,180 L 585,120 z "
370 id="rect2314" />
371 <path
372 style="fill:#00adff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
373 d="M 645,120 L 705,120 L 705,180 L 645,180 L 645,120 z "
374 id="rect2316" />
375 <path
376 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
377 d="M 705,120 L 765,120 L 765,180 L 705,180 L 705,120 z "
378 id="rect2318" />
379 <path
380 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
381 d="M 765,120 L 900,120 L 900,180 L 765,180 L 765,120 z "
382 id="rect2320" />
383 <path
384 style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
385 d="M 0,180 L 135,180 L 135,240 L 0,240 L 0,180 z "
386 id="rect2322" />
387 <path
388 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
389 d="M 135,180 L 195,180 L 195,240 L 135,240 L 135,180 z "
390 id="rect2324" />
391 <path
392 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
393 d="M 195,180 L 255,180 L 255,240 L 195,240 L 195,180 z "
394 id="rect2326" />
395 <path
396 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
397 d="M 255,180 L 315,180 L 315,240 L 255,240 L 255,180 z "
398 id="rect2330" />
399 <path
400 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
401 d="M 315,180 L 375,180 L 375,240 L 315,240 L 315,180 z "
402 id="rect2334" />
403 <path
404 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
405 d="M 375,180 L 435,180 L 435,240 L 375,240 L 375,180 z "
406 id="rect2336" />
407 <path
408 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
409 d="M 435,180 L 495,180 L 495,240 L 435,240 L 435,180 z "
410 id="rect2338" />
411 <path
412 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
413 d="M 495,180 L 555,180 L 555,240 L 495,240 L 495,180 z "
414 id="rect2340" />
415 <path
416 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
417 d="M 555,180 L 615,180 L 615,240 L 555,240 L 555,180 z "
418 id="rect2342" />
419 <path
420 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
421 d="M 615,180 L 675,180 L 675,240 L 615,240 L 615,180 z "
422 id="rect2344" />
423 <path
424 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
425 d="M 675,180 L 735,180 L 735,240 L 675,240 L 675,180 z "
426 id="rect2346" />
427 <path
428 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
429 d="M 735,180 L 900,180 L 900,240 L 735,240 L 735,180 z "
430 id="rect2348" />
431 <path
432 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
433 d="M 0,240 L 90,240 L 90,300 L 0,300 L 0,240 z "
434 id="rect2350" />
435 <path
436 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
437 d="M 810,240 L 900,240 L 900,300 L 810,300 L 810,240 z "
438 id="rect2352" />
439 <path
440 style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
441 d="M 150,240 L 240,240 L 240,300 L 150,300 L 150,240 z "
442 id="rect2354" />
443 <path
444 style="fill:#dfdfdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
445 d="M 600,240 L 690,240 L 690,300 L 600,300 L 600,240 z "
446 id="rect2360" />
447 <path
448 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
449 d="M 240,240 L 600,240 L 600,300 L 240,300 L 240,240 z "
450 id="rect2362" />
451 <path
452 style="fill:#efefef;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
453 d="M 90,240 L 150,240 L 150,300 L 90,300 L 90,240 z "
454 id="rect2364" />
455 <path
456 style="fill:#efefef;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
457 d="M 690,240 L 750,240 L 750,300 L 690,300 L 690,240 z "
458 id="rect2366" />
459 <path
460 style="fill:#efefef;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
461 d="M 750,240 L 810,240 L 810,300 L 750,300 L 750,240 z "
462 id="rect2368" />
463 <path
464 style=""
465 d=""
466 id="flowRoot4146" />
467 <path
468 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
469 d="M 75.351563,18.826172 L 74.4375,11.056641 L 74.4375,6.3691406 L 78.046875,6.3691406 L 78.046875,11.056641 L 77.132813,18.826172 L 75.351563,18.826172 M 74.484375,23.630859 L 74.484375,20.173828 L 77.964844,20.173828 L 77.964844,23.630859 L 74.484375,23.630859 M 75.351563,53.630859 L 75.351563,42.158203 L 71.34375,42.158203 L 71.34375,39.802734 L 71.601563,39.802734 C 73.062496,39.802748 74.124995,39.576186 74.789063,39.123047 C 75.460931,38.669937 75.855462,37.912125 75.972656,36.849609 L 78.65625,36.849609 L 78.65625,53.630859 L 75.351563,53.630859"
470 id="text5091" />
471 <path
472 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
473 d="M 23.34375,14.220703 L 23.34375,16.810547 C 22.531233,17.365241 21.761702,17.775396 21.035156,18.041016 C 20.316391,18.298833 19.605455,18.42774 18.902344,18.427734 C 18.542956,18.42774 18.183581,18.39649 17.824219,18.333984 C 17.464832,18.27149 17.105457,18.181646 16.746094,18.064453 C 16.558583,18.001959 16.281239,17.904303 15.914063,17.771484 C 14.203116,17.185553 12.902336,16.892585 12.011719,16.892578 C 11.34765,16.892585 10.652339,17.041022 9.9257813,17.337891 C 9.2070275,17.626959 8.3984345,18.091802 7.5,18.732422 L 7.5,16.142578 C 8.3359346,15.580086 9.1328088,15.162118 9.890625,14.888672 C 10.648432,14.607431 11.363275,14.466806 12.035156,14.466797 C 12.949211,14.466806 14.085929,14.693368 15.445313,15.146484 C 15.46874,15.154305 15.484365,15.158212 15.492188,15.158203 C 15.632802,15.205087 15.847646,15.279305 16.136719,15.380859 C 17.347644,15.810555 18.285143,16.025398 18.949219,16.025391 C 19.613267,16.025398 20.29686,15.880867 21,15.591797 C 21.703109,15.302743 22.484358,14.845712 23.34375,14.220703 M 11.988281,35.033203 L 15.011719,35.033203 L 17.320313,39.369141 L 15.65625,39.369141 L 11.988281,35.033203"
474 id="text5103" />
475 <path
476 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
477 d="M 136.47578,20.443359 C 136.04608,21.099612 135.54999,21.583986 134.9875,21.896484 C 134.42499,22.201173 133.76093,22.353517 132.99532,22.353516 C 131.76093,22.353517 130.81953,22.01758 130.1711,21.345703 C 129.53047,20.673831 129.21015,19.681645 129.21016,18.369141 C 129.21015,16.50196 129.75312,14.935556 130.83907,13.669922 C 131.93281,12.404308 133.27656,11.771496 134.87032,11.771484 C 135.4953,11.771496 136.03827,11.900402 136.49922,12.158203 C 136.96015,12.416027 137.33905,12.798839 137.63594,13.306641 L 138.25703,12.158203 L 140.34297,12.158203 L 138.62032,19.166016 C 138.59686,19.251958 138.57733,19.341801 138.56172,19.435547 C 138.54608,19.521488 138.53827,19.591801 138.53828,19.646484 C 138.53827,19.919926 138.63202,20.126957 138.81953,20.267578 C 139.00702,20.400394 139.28436,20.4668 139.65157,20.466797 C 139.95624,20.4668 140.27264,20.388675 140.60078,20.232422 C 140.9367,20.076175 141.2492,19.857426 141.53828,19.576172 C 142.21014,18.951177 142.71795,18.220709 143.06172,17.384766 C 143.41326,16.548835 143.58904,15.630867 143.58907,14.630859 C 143.58904,12.75587 142.86248,11.216809 141.40938,10.013672 C 139.96405,8.8027492 138.09686,8.1972811 135.80782,8.1972656 C 134.70624,8.1972811 133.6789,8.3300934 132.72578,8.5957031 C 131.78046,8.8613429 130.92109,9.2558737 130.14766,9.7792969 C 128.81953,10.669935 127.79609,11.783215 127.07735,13.119141 C 126.36641,14.455087 126.01094,15.91993 126.01094,17.513672 C 126.01094,19.912113 126.81953,21.83008 128.43672,23.267578 C 130.0539,24.697265 132.21406,25.412108 134.91719,25.412109 C 136.1828,25.412108 137.41718,25.220702 138.62032,24.837891 C 139.83124,24.455077 140.95623,23.90039 141.99532,23.173828 L 142.95625,24.544922 C 141.76092,25.443358 140.49139,26.119138 139.14766,26.572266 C 137.81171,27.025387 136.41718,27.25195 134.96407,27.251953 C 133.46405,27.25195 132.08515,27.060543 130.82735,26.677734 C 129.56953,26.302732 128.45234,25.744139 127.47578,25.001953 C 126.26484,24.05664 125.35859,22.966798 124.75703,21.732422 C 124.15547,20.49805 123.85469,19.099614 123.85469,17.537109 C 123.85469,16.232429 124.05781,14.990243 124.46407,13.810547 C 124.87813,12.623058 125.48359,11.544934 126.28047,10.576172 C 127.43672,9.1621238 128.82734,8.0918124 130.45235,7.3652344 C 132.07734,6.6386889 133.88593,6.275408 135.87813,6.2753906 C 137.19843,6.275408 138.43671,6.4550953 139.59297,6.8144531 C 140.75702,7.1660321 141.76873,7.6660316 142.62813,8.3144531 C 143.68279,9.1347801 144.46795,10.072279 144.9836,11.126953 C 145.50701,12.17384 145.76873,13.357432 145.76875,14.677734 C 145.76873,15.966805 145.51092,17.15821 144.99532,18.251953 C 144.48748,19.337895 143.75311,20.267581 142.79219,21.041016 C 142.2453,21.478518 141.64764,21.814455 140.99922,22.048828 C 140.35858,22.275392 139.69061,22.388673 138.99532,22.388672 C 138.16718,22.388673 137.54218,22.224611 137.12032,21.896484 C 136.70624,21.568361 136.4914,21.083987 136.47578,20.443359 M 137.06172,15.427734 C 136.96015,14.794931 136.73358,14.314462 136.38203,13.986328 C 136.03827,13.650401 135.58124,13.482432 135.01094,13.482422 C 134.1203,13.482432 133.34687,13.966807 132.69063,14.935547 C 132.03437,15.904305 131.70624,17.068366 131.70625,18.427734 C 131.70624,19.146489 131.86249,19.693363 132.175,20.068359 C 132.49531,20.443363 132.95624,20.630862 133.55782,20.630859 C 134.20624,20.630862 134.79608,20.384769 135.32735,19.892578 C 135.8664,19.400395 136.23358,18.75977 136.42891,17.970703 L 137.06172,15.427734 M 128.56563,53.630859 C 128.58125,52.130861 128.90156,50.861331 129.52657,49.822266 C 130.15156,48.775395 131.26094,47.716803 132.85469,46.646484 C 133.09687,46.482429 133.44844,46.255867 133.90938,45.966797 C 136.01875,44.615243 137.07343,43.314463 137.07344,42.064453 C 137.07343,41.322278 136.85078,40.736341 136.40547,40.306641 C 135.96015,39.876967 135.35078,39.662123 134.57735,39.662109 C 133.73359,39.662123 133.08125,39.927748 132.62032,40.458984 C 132.16719,40.982435 131.94062,41.732434 131.94063,42.708984 L 131.94063,42.849609 L 128.84688,42.849609 C 128.84688,40.927747 129.3625,39.44728 130.39375,38.408203 C 131.425,37.369157 132.89375,36.849626 134.8,36.849609 C 136.52656,36.849626 137.90546,37.322282 138.93672,38.267578 C 139.96796,39.205093 140.48358,40.455091 140.4836,42.017578 C 140.48358,43.134776 140.21405,44.103525 139.675,44.923828 C 139.13593,45.744149 138.09296,46.677741 136.5461,47.724609 C 136.21796,47.951178 135.76484,48.248052 135.18672,48.615234 C 133.71797,49.560551 132.88984,50.2793 132.70235,50.771484 L 140.31953,50.771484 L 140.31953,53.630859 L 128.56563,53.630859"
478 id="text5127" />
479 <path
480 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
481 d="M 195.28125,13.693359 L 194.25,16.552734 L 197.19141,16.552734 L 198.19922,13.693359 L 195.28125,13.693359 M 195.28125,6.4746094 L 197.87109,6.4746094 L 196.16016,11.337891 L 198.99609,11.337891 L 200.73047,6.4746094 L 203.32031,6.4746094 L 201.58594,11.337891 L 204.90234,11.337891 L 204.03516,13.693359 L 200.75391,13.693359 L 199.76953,16.529297 L 203.16797,16.529297 L 202.33594,18.873047 L 198.92578,18.873047 L 197.19141,23.748047 L 194.60156,23.748047 L 196.33594,18.873047 L 193.47656,18.873047 L 191.73047,23.748047 L 189.15234,23.748047 L 190.86328,18.873047 L 187.5,18.873047 L 188.39063,16.529297 L 191.69531,16.529297 L 192.70313,13.693359 L 189.19922,13.693359 L 190.06641,11.337891 L 193.54688,11.337891 L 195.28125,6.4746094 M 190.07813,48.521484 L 193.30078,48.521484 C 193.30859,49.458989 193.53515,50.166019 193.98047,50.642578 C 194.42578,51.111331 195.08593,51.345705 195.96094,51.345703 C 196.80468,51.345705 197.45312,51.126956 197.90625,50.689453 C 198.36718,50.244144 198.59765,49.607426 198.59766,48.779297 C 198.59765,47.951178 198.32812,47.326178 197.78906,46.904297 C 197.2578,46.474617 196.46484,46.259773 195.41016,46.259766 C 195.35546,46.259773 195.26953,46.263679 195.15234,46.271484 C 195.04296,46.279304 194.96093,46.28321 194.90625,46.283203 L 194.90625,43.962891 L 195.26953,43.962891 C 196.23827,43.9629 196.95312,43.7754 197.41406,43.400391 C 197.8828,43.017589 198.11718,42.435558 198.11719,41.654297 C 198.11718,41.005872 197.91796,40.494154 197.51953,40.119141 C 197.1289,39.736342 196.59374,39.544936 195.91406,39.544922 C 195.17187,39.544936 194.59765,39.763686 194.19141,40.201172 C 193.78515,40.638685 193.58203,41.259778 193.58203,42.064453 L 193.58203,42.205078 L 190.41797,42.205078 C 190.45703,40.486341 190.96094,39.169936 191.92969,38.255859 C 192.90625,37.334001 194.28125,36.873064 196.05469,36.873047 C 197.73437,36.873064 199.0664,37.283219 200.05078,38.103516 C 201.03514,38.923843 201.52733,40.02931 201.52734,41.419922 C 201.52733,42.154308 201.35936,42.798839 201.02344,43.353516 C 200.68749,43.908213 200.18358,44.365244 199.51172,44.724609 C 200.37108,45.099618 201.01952,45.619149 201.45703,46.283203 C 201.90233,46.93946 202.12499,47.724615 202.125,48.638672 C 202.12499,50.318363 201.57421,51.650393 200.47266,52.634766 C 199.37108,53.619141 197.86718,54.111328 195.96094,54.111328 C 194.07812,54.111328 192.625,53.634766 191.60156,52.681641 C 190.58594,51.720705 190.07812,50.357425 190.07813,48.591797 L 190.07813,48.521484"
482 id="text5139" />
483 <path
484 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
485 d="M 254.46094,21.451172 C 255.10155,21.365237 255.58984,21.134768 255.92578,20.759766 C 256.26171,20.384769 256.42968,19.884769 256.42969,19.259766 C 256.42968,18.705083 256.26952,18.248052 255.94922,17.888672 C 255.63671,17.52149 255.14062,17.236335 254.46094,17.033203 L 254.46094,21.451172 M 253.06641,13.435547 L 253.06641,9.4511719 C 252.45703,9.529311 251.99218,9.7402483 251.67188,10.083984 C 251.35156,10.419935 251.1914,10.87306 251.19141,11.443359 C 251.1914,11.919934 251.33984,12.318371 251.63672,12.638672 C 251.9414,12.958995 252.41796,13.22462 253.06641,13.435547 M 253.06641,26.267578 L 253.06641,24.017578 C 251.30078,23.908203 249.98047,23.396485 249.10547,22.482422 C 248.23047,21.568361 247.79297,20.24805 247.79297,18.521484 L 250.93359,18.521484 C 250.97265,19.365239 251.16796,20.033207 251.51953,20.525391 C 251.8789,21.009768 252.39453,21.318362 253.06641,21.451172 L 253.06641,16.599609 C 251.2539,16.138679 249.96484,15.537117 249.19922,14.794922 C 248.43359,14.052744 248.05078,13.03712 248.05078,11.748047 C 248.05078,10.318373 248.5039,9.1660301 249.41016,8.2910156 C 250.32422,7.4160318 251.54296,6.959001 253.06641,6.9199219 L 253.06641,5.4199219 L 254.46094,5.4199219 L 254.46094,6.9199219 C 255.98437,6.9980635 257.17186,7.4590005 258.02344,8.3027344 C 258.87499,9.1386864 259.34374,10.318373 259.42969,11.841797 L 256.24219,11.841797 C 256.18749,11.115247 256.01171,10.56056 255.71484,10.177734 C 255.42577,9.7871232 255.0078,9.5683734 254.46094,9.5214844 L 254.46094,13.787109 C 256.39062,14.388681 257.74999,15.07618 258.53906,15.849609 C 259.32811,16.623054 259.72264,17.642584 259.72266,18.908203 C 259.72264,20.400394 259.26171,21.591799 258.33984,22.482422 C 257.42577,23.373047 256.1328,23.892578 254.46094,24.041016 L 254.46094,26.267578 L 253.06641,26.267578 M 254.64844,47.419922 L 254.64844,40.236328 L 250.08984,47.419922 L 254.64844,47.419922 M 254.57813,53.630859 L 254.57813,50.009766 L 247.5,50.009766 L 247.5,47.056641 L 253.6875,37.330078 L 257.84766,37.330078 L 257.84766,47.337891 L 259.79297,47.337891 L 259.79297,50.009766 L 257.84766,50.009766 L 257.84766,53.630859 L 254.57813,53.630859"
486 id="text5145" />
487 <path
488 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
489 d="M 320.42578,19.740234 C 320.42577,20.263675 320.60155,20.705081 320.95313,21.064453 C 321.30467,21.416018 321.73827,21.591799 322.25391,21.591797 C 322.75389,21.591799 323.18358,21.412112 323.54297,21.052734 C 323.90233,20.68555 324.08201,20.24805 324.08203,19.740234 C 324.08201,19.240239 323.90233,18.814458 323.54297,18.462891 C 323.19139,18.103521 322.7617,17.923834 322.25391,17.923828 C 321.73827,17.923834 321.30467,18.099615 320.95313,18.451172 C 320.60155,18.794927 320.42577,19.224614 320.42578,19.740234 M 317.88281,19.740234 C 317.8828,18.521489 318.30468,17.494147 319.14844,16.658203 C 319.99217,15.822273 321.02733,15.404305 322.25391,15.404297 C 323.45701,15.404305 324.48045,15.830086 325.32422,16.681641 C 326.17576,17.525397 326.60154,18.544927 326.60156,19.740234 C 326.60154,20.943362 326.17576,21.974611 325.32422,22.833984 C 324.47264,23.685547 323.4492,24.111328 322.25391,24.111328 C 321.02733,24.111328 319.99217,23.689453 319.14844,22.845703 C 318.30468,22.001955 317.8828,20.9668 317.88281,19.740234 M 311.07422,24.111328 L 321.08203,6.8496094 L 322.96875,6.8496094 L 312.96094,24.111328 L 311.07422,24.111328 M 310.04297,11.220703 C 310.04297,11.73634 310.21484,12.169933 310.55859,12.521484 C 310.91015,12.873058 311.34375,13.048839 311.85938,13.048828 C 312.36718,13.048839 312.79687,12.873058 313.14844,12.521484 C 313.50781,12.162121 313.68749,11.728528 313.6875,11.220703 C 313.68749,10.720716 313.50781,10.294935 313.14844,9.9433594 C 312.79687,9.5839984 312.36718,9.4043111 311.85938,9.4042969 C 311.34375,9.4043111 310.91015,9.5800922 310.55859,9.9316406 C 310.21484,10.275404 310.04297,10.705091 310.04297,11.220703 M 307.5,11.220703 C 307.5,10.001967 307.92187,8.9707178 308.76563,8.1269531 C 309.60937,7.275407 310.64062,6.8496262 311.85938,6.8496094 C 313.06249,6.8496262 314.08593,7.2793132 314.92969,8.1386719 C 315.78124,8.990249 316.20702,10.017592 316.20703,11.220703 C 316.20702,12.423839 315.78124,13.451182 314.92969,14.302734 C 314.08593,15.146493 313.06249,15.568367 311.85938,15.568359 C 310.63281,15.568367 309.59765,15.150399 308.75391,14.314453 C 307.91797,13.478526 307.5,12.447277 307.5,11.220703 M 310.85156,49.119141 L 314.13281,49.119141 C 314.1875,49.853519 314.43359,50.423831 314.87109,50.830078 C 315.30859,51.228518 315.89453,51.427737 316.62891,51.427734 C 317.53515,51.427737 318.22655,51.162112 318.70313,50.630859 C 319.18749,50.099613 319.42968,49.337895 319.42969,48.345703 C 319.42968,47.416022 319.18358,46.685554 318.69141,46.154297 C 318.19921,45.615242 317.51952,45.345711 316.65234,45.345703 C 316.16796,45.345711 315.74218,45.443368 315.375,45.638672 C 315.00781,45.833992 314.69531,46.123054 314.4375,46.505859 L 311.41406,46.330078 L 312.50391,37.330078 L 322.14844,37.330078 L 322.14844,40.166016 L 314.87109,40.166016 L 314.4375,43.529297 C 314.80468,43.240245 315.22656,43.025401 315.70313,42.884766 C 316.17968,42.736339 316.71093,42.66212 317.29688,42.662109 C 318.96874,42.66212 320.3164,43.169932 321.33984,44.185547 C 322.37108,45.20118 322.88671,46.53321 322.88672,48.181641 C 322.88671,49.986332 322.3203,51.427737 321.1875,52.505859 C 320.05468,53.576172 318.53515,54.111328 316.62891,54.111328 C 314.89453,54.111328 313.51172,53.669922 312.48047,52.787109 C 311.45703,51.896486 310.91406,50.673831 310.85156,49.119141"
490 id="text5151" />
491 <path
492 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
493 d="M 373.13672,6.5214844 L 376.08984,6.5214844 L 381.72656,13.095703 L 378.97266,13.095703 L 374.625,8.7480469 L 370.25391,13.095703 L 367.5,13.095703 L 373.13672,6.5214844 M 372.15234,48.298828 C 372.15234,49.25977 372.39062,50.021488 372.86719,50.583984 C 373.35156,51.146487 374.00781,51.427737 374.83594,51.427734 C 375.60937,51.427737 376.21484,51.154299 376.65234,50.607422 C 377.08983,50.06055 377.30858,49.298832 377.30859,48.322266 C 377.30858,47.423834 377.08202,46.724616 376.62891,46.224609 C 376.17577,45.724617 375.53905,45.474618 374.71875,45.474609 C 373.91406,45.474618 373.28515,45.724617 372.83203,46.224609 C 372.3789,46.724616 372.15234,47.416022 372.15234,48.298828 M 372.10547,43.916016 C 372.48828,43.525401 372.94921,43.232432 373.48828,43.037109 C 374.02734,42.833995 374.6289,42.732433 375.29297,42.732422 C 376.93358,42.732433 378.24608,43.232432 379.23047,44.232422 C 380.22264,45.23243 380.71874,46.56446 380.71875,48.228516 C 380.71874,49.994144 380.17968,51.419924 379.10156,52.505859 C 378.02343,53.591797 376.60155,54.134765 374.83594,54.134766 C 372.79687,54.134765 371.24609,53.431641 370.18359,52.025391 C 369.1289,50.619144 368.60156,48.560552 368.60156,45.849609 C 368.60156,42.935558 369.16797,40.708997 370.30078,39.169922 C 371.43359,37.623063 373.0664,36.849626 375.19922,36.849609 C 376.68358,36.849626 377.8789,37.236345 378.78516,38.009766 C 379.69921,38.783218 380.19921,39.830092 380.28516,41.150391 L 376.88672,41.150391 C 376.80858,40.611341 376.59765,40.205092 376.25391,39.931641 C 375.91015,39.658217 375.42968,39.521498 374.8125,39.521484 C 373.96874,39.521498 373.32031,39.888686 372.86719,40.623047 C 372.41406,41.349622 372.16015,42.447277 372.10547,43.916016"
494 id="text5157" />
495 <path
496 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
497 d="M 432.85547,16.095703 L 431.96484,16.740234 C 431.60546,16.990241 431.33593,17.291022 431.15625,17.642578 C 430.97656,17.994146 430.88671,18.388677 430.88672,18.826172 C 430.88671,19.490239 431.11328,20.048832 431.56641,20.501953 C 432.01953,20.955081 432.58593,21.181643 433.26563,21.181641 C 433.76562,21.181643 434.24218,21.080081 434.69531,20.876953 C 435.15624,20.666019 435.58202,20.361331 435.97266,19.962891 L 432.85547,16.095703 M 433.79297,12.404297 L 434.20313,12.111328 C 434.57812,11.853527 434.85546,11.564465 435.03516,11.244141 C 435.21483,10.923841 435.30468,10.556654 435.30469,10.142578 C 435.30468,9.7441545 435.17968,9.4277486 434.92969,9.1933594 C 434.68749,8.958999 434.35546,8.8418117 433.93359,8.8417969 C 433.5039,8.8418117 433.16406,8.9629053 432.91406,9.2050781 C 432.66406,9.4394673 432.53906,9.7597795 432.53906,10.166016 C 432.53906,10.384779 432.59765,10.62306 432.71484,10.880859 C 432.83984,11.138684 433.01562,11.412122 433.24219,11.701172 L 433.79297,12.404297 M 431.15625,13.962891 L 430.47656,13.072266 C 430.125,12.603527 429.87109,12.166027 429.71484,11.759766 C 429.5664,11.345715 429.49218,10.912122 429.49219,10.458984 C 429.49218,9.2089988 429.89062,8.2168123 430.6875,7.4824219 C 431.49218,6.7402513 432.58203,6.3691579 433.95703,6.3691406 C 435.27733,6.3691579 436.3203,6.7090013 437.08594,7.3886719 C 437.85155,8.0683749 438.23436,8.9863428 438.23438,10.142578 C 438.23436,11.017591 438.0078,11.802746 437.55469,12.498047 C 437.10936,13.185557 436.40624,13.833994 435.44531,14.443359 L 437.91797,17.490234 C 438.15233,17.107428 438.33593,16.677741 438.46875,16.201172 C 438.60936,15.724617 438.70702,15.193368 438.76172,14.607422 L 441.80859,14.607422 C 441.72264,15.623055 441.5117,16.56446 441.17578,17.431641 C 440.83983,18.298833 440.37889,19.091801 439.79297,19.810547 L 442.93359,23.630859 L 438.94922,23.630859 L 437.77734,22.189453 C 437.08983,22.822266 436.33202,23.302735 435.50391,23.630859 C 434.68359,23.951172 433.82421,24.111328 432.92578,24.111328 C 431.33203,24.111328 430.02734,23.638672 429.01172,22.693359 C 428.0039,21.748049 427.5,20.541019 427.5,19.072266 C 427.5,17.978521 427.78125,17.037116 428.34375,16.248047 C 428.90625,15.458993 429.84375,14.697275 431.15625,13.962891 M 434.66016,53.630859 L 431.15625,53.630859 C 431.28125,51.341799 431.83203,49.07227 432.80859,46.822266 C 433.79296,44.572275 435.19531,42.361339 437.01563,40.189453 L 428.76563,40.189453 L 428.76563,37.330078 L 440.66016,37.330078 L 440.66016,39.849609 C 438.8164,41.880871 437.39843,44.029306 436.40625,46.294922 C 435.42187,48.560552 434.83984,51.005862 434.66016,53.630859"
498 id="text5163" />
499 <path
500 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
501 d="M 493.5,13.212891 L 491.4375,16.119141 L 489.44531,14.724609 L 491.69531,11.900391 L 488.41406,10.986328 L 489.17578,8.6074219 L 492.32813,9.7324219 L 492.32813,6.3691406 L 494.64844,6.3691406 L 494.64844,9.7324219 L 497.80078,8.6308594 L 498.58594,11.009766 L 495.30469,11.900391 L 497.53125,14.701172 L 495.49219,16.166016 L 493.5,13.212891 M 490.875,48.755859 C 490.875,49.576176 491.10156,50.208988 491.55469,50.654297 C 492.01562,51.099612 492.67187,51.322268 493.52344,51.322266 C 494.33593,51.322268 494.97265,51.095706 495.43359,50.642578 C 495.90233,50.189457 496.13671,49.560551 496.13672,48.755859 C 496.13671,47.982428 495.89843,47.361334 495.42188,46.892578 C 494.9453,46.423835 494.31249,46.189461 493.52344,46.189453 C 492.73437,46.189461 492.09374,46.427742 491.60156,46.904297 C 491.11718,47.380866 490.875,47.998053 490.875,48.755859 M 491.14453,41.560547 C 491.14453,42.208996 491.34765,42.708995 491.75391,43.060547 C 492.16015,43.404307 492.74218,43.576182 493.5,43.576172 C 494.2578,43.576182 494.83984,43.400401 495.24609,43.048828 C 495.66015,42.697277 495.86718,42.201183 495.86719,41.560547 C 495.86718,40.93556 495.65624,40.443373 495.23438,40.083984 C 494.81249,39.724623 494.23437,39.544936 493.5,39.544922 C 492.78124,39.544936 492.20703,39.72853 491.77734,40.095703 C 491.35546,40.462904 491.14453,40.951185 491.14453,41.560547 M 489.9375,44.818359 C 489.23437,44.427744 488.72656,43.970713 488.41406,43.447266 C 488.10156,42.923839 487.94531,42.255871 487.94531,41.443359 C 487.94531,40.005873 488.4375,38.876968 489.42188,38.056641 C 490.40625,37.236345 491.76562,36.826189 493.5,36.826172 C 495.24999,36.826189 496.61718,37.236345 497.60156,38.056641 C 498.59374,38.869155 499.08983,39.998061 499.08984,41.443359 C 499.08983,42.216808 498.92186,42.888683 498.58594,43.458984 C 498.24999,44.021494 497.74608,44.474619 497.07422,44.818359 C 497.89452,45.20118 498.51171,45.73243 498.92578,46.412109 C 499.33983,47.083991 499.54686,47.904303 499.54688,48.873047 C 499.54686,50.505862 499.0078,51.787111 497.92969,52.716797 C 496.85936,53.646484 495.3828,54.111328 493.5,54.111328 C 491.59375,54.111328 490.11328,53.650391 489.05859,52.728516 C 488.0039,51.806642 487.47656,50.521487 487.47656,48.873047 C 487.47656,47.912115 487.67187,47.107428 488.0625,46.458984 C 488.46094,45.802742 489.08594,45.255868 489.9375,44.818359"
502 id="text5169" />
503 <path
504 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
505 d="M 557.85938,6.3691406 C 556.78124,8.1347811 555.98046,9.9316543 555.45703,11.759766 C 554.93359,13.587901 554.67187,15.505868 554.67188,17.513672 C 554.67187,19.513676 554.93359,21.427737 555.45703,23.255859 C 555.98046,25.083983 556.78124,26.880856 557.85938,28.646484 L 555.38672,28.646484 C 554.01953,26.779294 552.98046,24.904296 552.26953,23.021484 C 551.5664,21.130862 551.21484,19.294926 551.21484,17.513672 C 551.21484,15.73243 551.5664,13.896494 552.26953,12.005859 C 552.98046,10.115248 554.01953,8.2363435 555.38672,6.3691406 L 557.85938,6.3691406 M 556.06641,42.685547 C 556.0664,41.724621 555.82421,40.96681 555.33984,40.412109 C 554.86327,39.849623 554.21093,39.568373 553.38281,39.568359 C 552.60156,39.568373 551.99218,39.837904 551.55469,40.376953 C 551.125,40.916028 550.91015,41.669934 550.91016,42.638672 C 550.91015,43.544932 551.13671,44.251963 551.58984,44.759766 C 552.04296,45.267586 552.67968,45.521492 553.5,45.521484 C 554.30468,45.521492 554.93359,45.271493 555.38672,44.771484 C 555.83983,44.271494 556.0664,43.576182 556.06641,42.685547 M 556.125,47.056641 C 555.73437,47.447272 555.27343,47.74024 554.74219,47.935547 C 554.21093,48.130865 553.61327,48.228521 552.94922,48.228516 C 551.30078,48.228521 549.98047,47.732428 548.98828,46.740234 C 547.99609,45.748055 547.5,44.419931 547.5,42.755859 C 547.5,40.990247 548.03906,39.564467 549.11719,38.478516 C 550.19531,37.392594 551.61718,36.849626 553.38281,36.849609 C 555.42968,36.849626 556.98436,37.556657 558.04688,38.970703 C 559.11718,40.376966 559.65233,42.431652 559.65234,45.134766 C 559.65233,48.041021 559.08202,50.267581 557.94141,51.814453 C 556.80077,53.361328 555.16015,54.134765 553.01953,54.134766 C 551.54296,54.134765 550.35156,53.751953 549.44531,52.986328 C 548.53906,52.212892 548.04297,51.162112 547.95703,49.833984 L 551.34375,49.845703 C 551.42187,50.384769 551.63281,50.787112 551.97656,51.052734 C 552.32031,51.318362 552.80468,51.451174 553.42969,51.451172 C 554.27343,51.451174 554.91796,51.083987 555.36328,50.349609 C 555.80858,49.615238 556.06249,48.517583 556.125,47.056641"
506 id="text5175" />
507 <path
508 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
509 d="M 609.375,6.3691406 L 611.87109,6.3691406 C 613.23046,8.228531 614.26171,10.103529 614.96484,11.994141 C 615.66796,13.876963 616.01952,15.716805 616.01953,17.513672 C 616.01952,19.302739 615.66796,21.142581 614.96484,23.033203 C 614.26171,24.923827 613.23046,26.794919 611.87109,28.646484 L 609.375,28.646484 C 610.46094,26.873044 611.26562,25.072264 611.78906,23.244141 C 612.32031,21.408205 612.58593,19.498051 612.58594,17.513672 C 612.58593,15.521492 612.32031,13.611338 611.78906,11.783203 C 611.26562,9.9550918 610.46094,8.1504061 609.375,6.3691406 M 610.98047,45.474609 C 610.98046,47.513678 611.18359,48.994145 611.58984,49.916016 C 612.0039,50.837893 612.66015,51.29883 613.55859,51.298828 C 614.45702,51.29883 615.11327,50.833987 615.52734,49.904297 C 615.9414,48.974614 616.14843,47.498053 616.14844,45.474609 C 616.14843,43.44337 615.9414,41.966809 615.52734,41.044922 C 615.11327,40.12306 614.45702,39.662123 613.55859,39.662109 C 612.66015,39.662123 612.0039,40.12306 611.58984,41.044922 C 611.18359,41.958996 610.98046,43.435557 610.98047,45.474609 M 607.5,45.474609 C 607.5,42.591808 608,40.43556 609,39.005859 C 610.00781,37.568375 611.52734,36.849626 613.55859,36.849609 C 615.58202,36.849626 617.09765,37.572282 618.10547,39.017578 C 619.12108,40.455091 619.62889,42.615245 619.62891,45.498047 C 619.62889,48.380865 619.12499,50.533206 618.11719,51.955078 C 617.11718,53.376953 615.59765,54.08789 613.55859,54.087891 C 611.52734,54.08789 610.00781,53.373047 609,51.943359 C 608,50.513675 607.5,48.357427 607.5,45.474609"
510 id="text5181" />
511 <path
512 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
513 d="M 667.5,26.900391 L 679.5,26.900391 L 679.5,29.291016 L 667.5,29.291016 L 667.5,26.900391 M 670.20703,48.849609 L 670.20703,45.638672 L 676.79297,45.638672 L 676.79297,48.849609 L 670.20703,48.849609"
514 id="text5187" />
515 <path
516 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
517 d="M 733.33594,9.3222656 L 735.70313,9.3222656 L 735.70313,15.298828 L 741.53906,15.298828 L 741.53906,17.630859 L 735.70313,17.630859 L 735.70313,23.630859 L 733.33594,23.630859 L 733.33594,17.630859 L 727.5,17.630859 L 727.5,15.298828 L 733.33594,15.298828 L 733.33594,9.3222656 M 727.5,47.818359 L 741.53906,47.818359 L 741.53906,50.150391 L 727.5,50.150391 L 727.5,47.818359 M 727.5,42.779297 L 741.53906,42.779297 L 741.53906,45.111328 L 727.5,45.111328 L 727.5,42.779297"
518 id="text5201" />
519 <path
520 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
521 d="M 11.070313,95.601563 L 11.070313,86.148438 L 7.65625,86.148438 L 7.65625,84.09375 L 16.828125,84.09375 L 16.828125,86.148438 L 13.4375,86.148438 L 13.4375,95.601563 L 11.070313,95.601563 M 22.859375,94.546875 C 22.572911,94.989584 22.197911,95.328125 21.734375,95.5625 C 21.270829,95.791666 20.731767,95.90625 20.117188,95.90625 C 19.294269,95.90625 18.658853,95.671875 18.210938,95.203125 C 17.768228,94.734376 17.546874,94.06771 17.546875,93.203125 C 17.546874,92.401045 17.768228,91.789066 18.210938,91.367188 C 18.658853,90.945317 19.395831,90.656255 20.421875,90.5 C 20.656246,90.463547 20.963538,90.42188 21.34375,90.375 C 22.307286,90.250005 22.789057,89.97136 22.789063,89.539063 C 22.789057,89.195319 22.682286,88.950527 22.46875,88.804688 C 22.255203,88.653653 21.898433,88.578132 21.398438,88.578125 C 20.9401,88.578132 20.588538,88.669278 20.34375,88.851563 C 20.098955,89.033861 19.97656,89.294277 19.976563,89.632813 L 19.976563,89.757813 L 17.851563,89.757813 L 17.851563,89.601563 C 17.851562,88.731778 18.158853,88.049487 18.773438,87.554688 C 19.388018,87.054696 20.236976,86.804696 21.320313,86.804688 C 22.507807,86.804696 23.41666,87.010425 24.046875,87.421875 C 24.682284,87.833341 24.999992,88.427091 25,89.203125 L 25,94.03125 C 24.999992,94.385418 25.03645,94.651043 25.109375,94.828125 C 25.182283,95.000001 25.304679,95.130209 25.476563,95.21875 L 25.476563,95.601563 L 23.109375,95.601563 C 23.031244,95.455729 22.971348,95.294271 22.929688,95.117188 C 22.888015,94.940105 22.864577,94.750001 22.859375,94.546875 M 22.820313,91.421875 C 22.450515,91.593754 22.023432,91.731775 21.539063,91.835938 C 21.059892,91.940108 20.812496,91.994795 20.796875,92 C 20.39583,92.114587 20.11458,92.257816 19.953125,92.429688 C 19.796872,92.601566 19.718747,92.838544 19.71875,93.140625 C 19.718747,93.453127 19.82031,93.703127 20.023438,93.890625 C 20.226559,94.072918 20.499997,94.164064 20.84375,94.164063 C 21.458329,94.164064 21.940099,93.992189 22.289063,93.648438 C 22.643224,93.299481 22.820307,92.825524 22.820313,92.226563 L 22.820313,91.421875 M 27.039063,84.09375 L 29.25,84.09375 L 29.25,88.164063 C 29.531246,87.721362 29.882809,87.388029 30.304688,87.164063 C 30.731766,86.934905 31.216141,86.820321 31.757813,86.820313 C 32.783847,86.820321 33.622388,87.2448 34.273438,88.09375 C 34.92447,88.937507 35.249991,90.036464 35.25,91.390625 C 35.249991,92.734378 34.92447,93.820314 34.273438,94.648438 C 33.622388,95.476563 32.773431,95.890625 31.726563,95.890625 C 31.179682,95.890625 30.70312,95.776041 30.296875,95.546875 C 29.895829,95.317709 29.531246,94.953126 29.203125,94.453125 L 29.203125,95.601563 L 27.039063,95.601563 L 27.039063,84.09375 M 32.992188,91.296875 C 32.992181,90.51563 32.828118,89.903652 32.5,89.460938 C 32.171869,89.013027 31.721348,88.789069 31.148438,88.789063 C 30.544266,88.789069 30.075517,89.007819 29.742188,89.445313 C 29.414059,89.87761 29.249997,90.494797 29.25,91.296875 C 29.249997,92.161462 29.406247,92.817711 29.71875,93.265625 C 30.036454,93.713544 30.497391,93.937502 31.101563,93.9375 C 31.71614,93.937502 32.18489,93.713544 32.507813,93.265625 C 32.830722,92.812503 32.992181,92.156253 32.992188,91.296875"
522 id="text5427" />
523 <path
524 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
525 d="M 789.76563,44.369141 L 792.57031,44.369141 C 793.23176,44.369143 793.71353,44.249351 794.01563,44.009766 C 794.3177,43.770185 794.46874,43.392581 794.46875,42.876953 C 794.46874,42.340499 794.3203,41.955083 794.02344,41.720703 C 793.72656,41.481125 793.23697,41.361333 792.55469,41.361328 L 789.76563,41.361328 L 789.76563,44.369141 M 789.76563,39.392578 L 792.46875,39.392578 C 793.05208,39.392585 793.47916,39.293627 793.75,39.095703 C 794.02083,38.892586 794.15624,38.574878 794.15625,38.142578 C 794.15624,37.720712 794.02343,37.416025 793.75781,37.228516 C 793.49739,37.035817 793.06249,36.939463 792.45313,36.939453 L 789.76563,36.939453 L 789.76563,39.392578 M 787.5,46.447266 L 787.5,34.939453 L 792.92188,34.939453 C 794.09895,34.939465 794.99478,35.189464 795.60938,35.689453 C 796.22916,36.184255 796.53905,36.905609 796.53906,37.853516 C 796.53905,38.436857 796.42447,38.923836 796.19531,39.314453 C 795.96614,39.705085 795.62239,40.007168 795.16406,40.220703 C 795.7578,40.460292 796.20051,40.806646 796.49219,41.259766 C 796.78905,41.707687 796.93749,42.267582 796.9375,42.939453 C 796.93749,44.059247 796.57291,44.92383 795.84375,45.533203 C 795.11457,46.142578 794.08072,46.447266 792.74219,46.447266 L 787.5,46.447266 M 803.45313,45.392578 C 803.16666,45.835287 802.79166,46.173828 802.32813,46.408203 C 801.86458,46.63737 801.32552,46.751953 800.71094,46.751953 C 799.88802,46.751953 799.2526,46.517578 798.80469,46.048828 C 798.36198,45.580079 798.14062,44.913413 798.14063,44.048828 C 798.14062,43.246748 798.36198,42.634769 798.80469,42.212891 C 799.2526,41.79102 799.98958,41.501958 801.01563,41.345703 C 801.25,41.30925 801.55729,41.267583 801.9375,41.220703 C 802.90104,41.095708 803.38281,40.817063 803.38281,40.384766 C 803.38281,40.041022 803.27604,39.796231 803.0625,39.650391 C 802.84895,39.499356 802.49218,39.423835 801.99219,39.423828 C 801.53385,39.423835 801.18229,39.514981 800.9375,39.697266 C 800.69271,39.879564 800.57031,40.13998 800.57031,40.478516 L 800.57031,40.603516 L 798.44531,40.603516 L 798.44531,40.447266 C 798.44531,39.577481 798.7526,38.89519 799.36719,38.400391 C 799.98177,37.900399 800.83073,37.650399 801.91406,37.650391 C 803.10156,37.650399 804.01041,37.856128 804.64063,38.267578 C 805.27603,38.679044 805.59374,39.272794 805.59375,40.048828 L 805.59375,44.876953 C 805.59374,45.231121 805.6302,45.496746 805.70313,45.673828 C 805.77603,45.845704 805.89843,45.975912 806.07031,46.064453 L 806.07031,46.447266 L 803.70313,46.447266 C 803.62499,46.301432 803.5651,46.139974 803.52344,45.962891 C 803.48176,45.785808 803.45833,45.595704 803.45313,45.392578 M 803.41406,42.267578 C 803.04427,42.439457 802.61718,42.577478 802.13281,42.681641 C 801.65364,42.785811 801.40625,42.840498 801.39063,42.845703 C 800.98958,42.96029 800.70833,43.103519 800.54688,43.275391 C 800.39062,43.447269 800.3125,43.684248 800.3125,43.986328 C 800.3125,44.29883 800.41406,44.54883 800.61719,44.736328 C 800.82031,44.918621 801.09375,45.009767 801.4375,45.009766 C 802.05208,45.009767 802.53385,44.837892 802.88281,44.494141 C 803.23697,44.145185 803.41406,43.671227 803.41406,43.072266 L 803.41406,42.267578 M 812.71875,43.244141 L 814.96094,43.244141 C 814.86718,44.322268 814.47395,45.173829 813.78125,45.798828 C 813.08854,46.423828 812.19791,46.736328 811.10938,46.736328 C 809.875,46.736328 808.90625,46.335287 808.20313,45.533203 C 807.50521,44.725913 807.15625,43.611331 807.15625,42.189453 C 807.15625,40.772792 807.51302,39.663418 808.22656,38.861328 C 808.94531,38.054045 809.93229,37.650399 811.1875,37.650391 C 812.28645,37.650399 813.16666,37.942066 813.82813,38.525391 C 814.49478,39.108731 814.86718,39.92123 814.94531,40.962891 L 812.6875,40.962891 C 812.62499,40.509772 812.46614,40.163418 812.21094,39.923828 C 811.95572,39.684252 811.61979,39.56446 811.20313,39.564453 C 810.64062,39.56446 810.21875,39.785814 809.9375,40.228516 C 809.66146,40.67123 809.52343,41.335292 809.52344,42.220703 C 809.52343,43.038415 809.66666,43.668623 809.95313,44.111328 C 810.24479,44.54883 810.66145,44.76758 811.20313,44.767578 C 811.62499,44.76758 811.96354,44.639976 812.21875,44.384766 C 812.47395,44.12956 812.64062,43.749352 812.71875,43.244141 M 816.44531,46.447266 L 816.44531,34.939453 L 818.65625,34.939453 L 818.65625,40.978516 L 821.35938,37.955078 L 824.09375,37.955078 L 821.13281,41.103516 L 824.27344,46.447266 L 821.54688,46.447266 L 819.51563,42.830078 L 818.65625,43.759766 L 818.65625,46.447266 L 816.44531,46.447266 M 824.79688,43.681641 L 827.0625,43.681641 C 827.08333,44.113935 827.23958,44.436851 827.53125,44.650391 C 827.82291,44.858726 828.26041,44.962892 828.84375,44.962891 C 829.28645,44.962892 829.6276,44.889976 829.86719,44.744141 C 830.11197,44.593101 830.23437,44.382164 830.23438,44.111328 C 830.23437,43.725914 829.78124,43.436852 828.875,43.244141 C 828.5052,43.166019 828.21093,43.098311 827.99219,43.041016 C 826.88802,42.759769 826.11979,42.426436 825.6875,42.041016 C 825.26042,41.655604 825.04687,41.134771 825.04688,40.478516 C 825.04687,39.608731 825.35937,38.921231 825.98438,38.416016 C 826.61458,37.905608 827.46614,37.650399 828.53906,37.650391 C 829.67447,37.650399 830.5651,37.903003 831.21094,38.408203 C 831.86197,38.913419 832.20833,39.624356 832.25,40.541016 L 830.03906,40.541016 C 830.02343,40.181647 829.88541,39.903001 829.625,39.705078 C 829.36979,39.507168 829.01302,39.40821 828.55469,39.408203 C 828.12239,39.40821 827.79948,39.473314 827.58594,39.603516 C 827.3776,39.733731 827.27343,39.929043 827.27344,40.189453 C 827.27343,40.528001 827.83854,40.82748 828.96875,41.087891 C 829.22916,41.145188 829.43489,41.192063 829.58594,41.228516 C 830.71614,41.494146 831.48697,41.814458 831.89844,42.189453 C 832.3151,42.564457 832.52343,43.093102 832.52344,43.775391 C 832.52343,44.738934 832.18228,45.473308 831.5,45.978516 C 830.82291,46.483724 829.83593,46.736328 828.53906,46.736328 C 827.36718,46.736328 826.45052,46.473307 825.78906,45.947266 C 825.1276,45.421225 824.79687,44.697267 824.79688,43.775391 L 824.79688,43.681641 M 840.02344,42.251953 C 840.02343,41.397792 839.86197,40.74675 839.53906,40.298828 C 839.21614,39.84571 838.74739,39.619147 838.13281,39.619141 C 837.52864,39.619147 837.0677,39.843106 836.75,40.291016 C 836.4375,40.738938 836.28125,41.392583 836.28125,42.251953 C 836.28125,43.05404 836.44531,43.673831 836.77344,44.111328 C 837.10677,44.54883 837.57552,44.76758 838.17969,44.767578 C 838.7526,44.76758 839.20312,44.543622 839.53125,44.095703 C 839.85937,43.647789 840.02343,43.033207 840.02344,42.251953 M 834.07031,49.853516 L 834.07031,37.955078 L 836.23438,37.955078 L 836.23438,39.103516 C 836.5625,38.603523 836.92708,38.23894 837.32813,38.009766 C 837.73437,37.780608 838.21093,37.666024 838.75781,37.666016 C 839.80468,37.666024 840.65364,38.080086 841.30469,38.908203 C 841.95572,39.731127 842.28124,40.814459 842.28125,42.158203 C 842.28124,43.517581 841.95572,44.621747 841.30469,45.470703 C 840.65364,46.314453 839.8151,46.736328 838.78906,46.736328 C 838.24739,46.736328 837.76302,46.621745 837.33594,46.392578 C 836.91406,46.163412 836.5625,45.830079 836.28125,45.392578 L 836.28125,49.853516 L 834.07031,49.853516 M 848.70313,45.392578 C 848.41666,45.835287 848.04166,46.173828 847.57813,46.408203 C 847.11458,46.63737 846.57552,46.751953 845.96094,46.751953 C 845.13802,46.751953 844.5026,46.517578 844.05469,46.048828 C 843.61198,45.580079 843.39062,44.913413 843.39063,44.048828 C 843.39062,43.246748 843.61198,42.634769 844.05469,42.212891 C 844.5026,41.79102 845.23958,41.501958 846.26563,41.345703 C 846.5,41.30925 846.80729,41.267583 847.1875,41.220703 C 848.15104,41.095708 848.63281,40.817063 848.63281,40.384766 C 848.63281,40.041022 848.52604,39.796231 848.3125,39.650391 C 848.09895,39.499356 847.74218,39.423835 847.24219,39.423828 C 846.78385,39.423835 846.43229,39.514981 846.1875,39.697266 C 845.94271,39.879564 845.82031,40.13998 845.82031,40.478516 L 845.82031,40.603516 L 843.69531,40.603516 L 843.69531,40.447266 C 843.69531,39.577481 844.0026,38.89519 844.61719,38.400391 C 845.23177,37.900399 846.08073,37.650399 847.16406,37.650391 C 848.35156,37.650399 849.26041,37.856128 849.89063,38.267578 C 850.52603,38.679044 850.84374,39.272794 850.84375,40.048828 L 850.84375,44.876953 C 850.84374,45.231121 850.8802,45.496746 850.95313,45.673828 C 851.02603,45.845704 851.14843,45.975912 851.32031,46.064453 L 851.32031,46.447266 L 848.95313,46.447266 C 848.87499,46.301432 848.8151,46.139974 848.77344,45.962891 C 848.73176,45.785808 848.70833,45.595704 848.70313,45.392578 M 848.66406,42.267578 C 848.29427,42.439457 847.86718,42.577478 847.38281,42.681641 C 846.90364,42.785811 846.65625,42.840498 846.64063,42.845703 C 846.23958,42.96029 845.95833,43.103519 845.79688,43.275391 C 845.64062,43.447269 845.5625,43.684248 845.5625,43.986328 C 845.5625,44.29883 845.66406,44.54883 845.86719,44.736328 C 846.07031,44.918621 846.34375,45.009767 846.6875,45.009766 C 847.30208,45.009767 847.78385,44.837892 848.13281,44.494141 C 848.48697,44.145185 848.66406,43.671227 848.66406,43.072266 L 848.66406,42.267578 M 857.96875,43.244141 L 860.21094,43.244141 C 860.11718,44.322268 859.72395,45.173829 859.03125,45.798828 C 858.33854,46.423828 857.44791,46.736328 856.35938,46.736328 C 855.125,46.736328 854.15625,46.335287 853.45313,45.533203 C 852.75521,44.725913 852.40625,43.611331 852.40625,42.189453 C 852.40625,40.772792 852.76302,39.663418 853.47656,38.861328 C 854.19531,38.054045 855.18229,37.650399 856.4375,37.650391 C 857.53645,37.650399 858.41666,37.942066 859.07813,38.525391 C 859.74478,39.108731 860.11718,39.92123 860.19531,40.962891 L 857.9375,40.962891 C 857.87499,40.509772 857.71614,40.163418 857.46094,39.923828 C 857.20572,39.684252 856.86979,39.56446 856.45313,39.564453 C 855.89062,39.56446 855.46875,39.785814 855.1875,40.228516 C 854.91146,40.67123 854.77343,41.335292 854.77344,42.220703 C 854.77343,43.038415 854.91666,43.668623 855.20313,44.111328 C 855.49479,44.54883 855.91145,44.76758 856.45313,44.767578 C 856.87499,44.76758 857.21354,44.639976 857.46875,44.384766 C 857.72395,44.12956 857.89062,43.749352 857.96875,43.244141 M 866.88281,43.869141 L 869.14844,43.869141 C 868.91926,44.764976 868.45572,45.4681 867.75781,45.978516 C 867.0651,46.483724 866.21874,46.736328 865.21875,46.736328 C 863.98958,46.736328 863.01562,46.32487 862.29688,45.501953 C 861.57812,44.67383 861.21875,43.554039 861.21875,42.142578 C 861.21875,40.751959 861.57292,39.655606 862.28125,38.853516 C 862.98958,38.051441 863.95833,37.650399 865.1875,37.650391 C 866.48958,37.650399 867.49478,38.046232 868.20313,38.837891 C 868.91145,39.624356 869.26562,40.74675 869.26563,42.205078 C 869.26562,42.366541 869.26301,42.488936 869.25781,42.572266 C 869.2578,42.650394 869.2526,42.725915 869.24219,42.798828 L 863.57031,42.798828 C 863.60156,43.465498 863.76302,43.968101 864.05469,44.306641 C 864.35156,44.645184 864.77604,44.814455 865.32813,44.814453 C 865.71874,44.814455 866.03906,44.738934 866.28906,44.587891 C 866.53906,44.431643 866.73697,44.19206 866.88281,43.869141 M 863.57031,41.306641 L 866.91406,41.306641 C 866.89322,40.73373 866.73958,40.298834 866.45313,40.001953 C 866.17187,39.699877 865.76562,39.548835 865.23438,39.548828 C 864.73958,39.548835 864.34895,39.699877 864.0625,40.001953 C 863.78125,40.304043 863.61718,40.738938 863.57031,41.306641"
526 id="text5207" />
527 <path
528 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
529 d="M 840,17.646484 L 797.02608,17.646484"
530 id="path5439" />
531 <path
532 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
533 d="M 802.5,25.146484 L 802.5,10.146484 L 787.5,17.646484 L 802.5,25.146484 z "
534 id="path5441" />
535 <g
536 id="g5459"
537 transform="translate(0,7.5)">
538 <path
539 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:3.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
540 d="M 82.50003,75 L 54.020182,75"
541 id="path5453" />
542 <path
543 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
544 d="M 60,82.5 L 60,67.5 L 45,75 L 60,82.5 z "
545 id="path5455" />
546 <path
547 id="path5457"
548 d="M 45,67.5 C 45,82.5 45,82.5 45,82.5"
549 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
550 </g>
551 <g
552 id="g5464"
553 transform="matrix(-1,9.581637e-17,-9.581637e-17,-1,127.5,172.5)">
554 <path
555 id="path5466"
556 d="M 82.50003,75 L 54.020182,75"
557 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:3.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
558 <path
559 id="path5468"
560 d="M 60,82.5 L 60,67.5 L 45,75 L 60,82.5 z "
561 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
562 <path
563 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
564 d="M 45,67.5 C 45,82.5 45,82.5 45,82.5"
565 id="path5470" />
566 </g>
567 <path
568 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
569 d="M 158.94141,83.630859 L 153.99609,66.369141 L 157.67578,66.369141 L 160.62891,78.544922 L 163.125,66.369141 L 166.91016,66.369141 L 169.40625,78.544922 L 172.35938,66.369141 L 176.00391,66.369141 L 171.07031,83.630859 L 167.68359,83.630859 L 165.01172,70.412109 L 162.32813,83.630859 L 158.94141,83.630859"
570 id="text5482" />
571 <path
572 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
573 d="M 343.24219,83.630859 L 343.24219,69.451172 L 338.12109,69.451172 L 338.12109,66.369141 L 351.87891,66.369141 L 351.87891,69.451172 L 346.79297,69.451172 L 346.79297,83.630859 L 343.24219,83.630859"
574 id="text5504" />
575 <path
576 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
577 d="M 407.06836,83.630859 L 403.51758,83.630859 L 403.51758,77.197266 L 397.24805,66.369141 L 401.5957,66.369141 L 405.28711,73.810547 L 408.69727,66.369141 L 412.75195,66.369141 L 407.06836,77.197266 L 407.06836,83.630859"
578 id="text5518" />
579 <path
580 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
581 d="M 458.08594,66.105469 L 461.67188,66.105469 L 461.67188,76.933594 C 461.67187,78.269536 461.93749,79.246098 462.46875,79.863281 C 462.99999,80.472659 463.84374,80.777346 465,80.777344 C 466.17187,80.777346 467.02343,80.472659 467.55469,79.863281 C 468.09374,79.25391 468.36327,78.277349 468.36328,76.933594 L 468.36328,66.105469 L 471.91406,66.105469 L 471.91406,77.320313 C 471.91405,79.437504 471.3203,81.062502 470.13281,82.195313 C 468.95311,83.328125 467.24999,83.894531 465.02344,83.894531 C 462.78124,83.894531 461.0625,83.332031 459.86719,82.207031 C 458.67969,81.074221 458.08594,79.445316 458.08594,77.320313 L 458.08594,66.105469"
582 id="text5522" />
583 <path
584 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
585 d="M 523.22461,83.630859 L 523.22461,66.369141 L 526.77539,66.369141 L 526.77539,83.630859 L 523.22461,83.630859"
586 id="text5526" />
587 <path
588 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
589 d="M 580.18359,75 C 580.18359,76.898444 580.60546,78.375005 581.44922,79.429688 C 582.29296,80.476566 583.47265,81.000003 584.98828,81 C 586.51952,81.000003 587.71093,80.476566 588.5625,79.429688 C 589.41405,78.375005 589.83983,76.898444 589.83984,75 C 589.83983,73.101573 589.41405,71.628918 588.5625,70.582031 C 587.71093,69.527358 586.51952,69.000015 584.98828,69 C 583.47265,69.000015 582.29296,69.523452 581.44922,70.570313 C 580.60546,71.617199 580.18359,73.093761 580.18359,75 M 576.5625,75 C 576.5625,72.210949 577.32031,70.000014 578.83594,68.367188 C 580.35937,66.726579 582.41015,65.906268 584.98828,65.90625 C 587.56639,65.906268 589.61717,66.726579 591.14063,68.367188 C 592.67186,70.007826 593.43748,72.218761 593.4375,75 C 593.43748,77.781256 592.67186,79.992191 591.14063,81.632813 C 589.61717,83.273438 587.56639,84.09375 584.98828,84.09375 C 582.41015,84.09375 580.35937,83.273438 578.83594,81.632813 C 577.32031,79.992191 576.5625,77.781256 576.5625,75"
590 id="text5530" />
591 <path
592 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
593 d="M 641.97656,74.361328 L 645.41016,74.361328 C 646.33983,74.361337 647.01561,74.166025 647.4375,73.775391 C 647.85936,73.376963 648.0703,72.740245 648.07031,71.865234 C 648.0703,71.044934 647.86327,70.423841 647.44922,70.001953 C 647.03515,69.580092 646.41796,69.369155 645.59766,69.369141 L 641.97656,69.369141 L 641.97656,74.361328 M 641.95313,77.490234 L 641.95313,83.630859 L 638.40234,83.630859 L 638.40234,66.369141 L 646.07813,66.369141 C 647.89061,66.369158 649.26171,66.841814 650.19141,67.787109 C 651.12889,68.724624 651.59764,70.103529 651.59766,71.923828 C 651.59764,73.705088 651.14061,75.080087 650.22656,76.048828 C 649.31249,77.009772 648.0078,77.490241 646.3125,77.490234 L 641.95313,77.490234"
594 id="text5534" />
595 <path
596 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
597 d="M 709.24805,63.919922 L 709.24805,66.369141 C 709.17772,66.369155 709.08007,66.365249 708.95508,66.357422 C 708.83007,66.349624 708.74413,66.345718 708.69727,66.345703 C 707.90819,66.345718 707.37304,66.498062 707.0918,66.802734 C 706.81835,67.099624 706.68163,67.732435 706.68164,68.701172 L 706.68164,71.513672 C 706.68163,72.66993 706.50585,73.490242 706.1543,73.974609 C 705.80273,74.458991 705.16992,74.806647 704.25586,75.017578 C 705.16992,75.228522 705.80273,75.572271 706.1543,76.048828 C 706.50585,76.525395 706.68163,77.341801 706.68164,78.498047 L 706.68164,81.322266 C 706.68163,82.283202 706.81835,82.912108 707.0918,83.208984 C 707.36523,83.505857 707.90038,83.654294 708.69727,83.654297 C 708.74413,83.654294 708.83007,83.650388 708.95508,83.642578 C 709.08007,83.634763 709.17772,83.630857 709.24805,83.630859 L 709.24805,86.080078 C 709.13866,86.080073 708.98632,86.08398 708.79102,86.091797 C 708.59569,86.099605 708.45116,86.103511 708.35742,86.103516 C 707.57616,86.103511 706.92382,86.056636 706.40039,85.962891 C 705.87695,85.869136 705.43163,85.724605 705.06445,85.529297 C 704.61913,85.263668 704.30273,84.904293 704.11523,84.451172 C 703.93554,84.005857 703.8457,83.228514 703.8457,82.119141 L 703.8457,79.166016 C 703.8457,78.095706 703.64648,77.337895 703.24805,76.892578 C 702.84961,76.439458 702.17773,76.212896 701.23242,76.212891 C 701.18554,76.212896 701.10742,76.216802 700.99805,76.224609 C 700.88867,76.232427 700.80664,76.236333 700.75195,76.236328 L 700.75195,73.787109 C 700.80664,73.787117 700.88867,73.791023 700.99805,73.798828 C 701.10742,73.806648 701.18554,73.810554 701.23242,73.810547 C 702.16992,73.810554 702.83789,73.583992 703.23633,73.130859 C 703.64257,72.677743 703.8457,71.912119 703.8457,70.833984 L 703.8457,67.904297 C 703.8457,66.787124 703.93554,66.001968 704.11523,65.548828 C 704.30273,65.095719 704.61913,64.736345 705.06445,64.470703 C 705.43163,64.275408 705.87695,64.130876 706.40039,64.037109 C 706.92382,63.943377 707.57616,63.896502 708.35742,63.896484 C 708.45116,63.896502 708.59569,63.900408 708.79102,63.908203 C 708.98632,63.916033 709.13866,63.919939 709.24805,63.919922 M 703.0957,93.966797 L 709.01367,93.966797 L 709.01367,96.462891 L 706.25977,96.462891 L 706.25977,113.8418 L 709.01367,113.8418 L 709.01367,116.33789 L 703.0957,116.33789 L 703.0957,93.966797"
598 id="text5546" />
599 <path
600 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
601 d="M 760.75195,63.908203 L 761.54883,63.908203 C 762.4082,63.90822 763.09961,63.955095 763.62305,64.048828 C 764.14648,64.142595 764.58398,64.291033 764.93555,64.494141 C 765.38085,64.744157 765.69335,65.103532 765.87305,65.572266 C 766.06054,66.033218 766.15429,66.806655 766.1543,67.892578 L 766.1543,70.845703 C 766.15429,71.916025 766.35351,72.677743 766.75195,73.130859 C 767.15038,73.57618 767.82226,73.798836 768.76758,73.798828 C 768.81444,73.798836 768.89257,73.794929 769.00195,73.787109 C 769.11132,73.779304 769.19335,73.775398 769.24805,73.775391 L 769.24805,76.224609 L 768.81445,76.224609 C 767.83788,76.224614 767.15038,76.443364 766.75195,76.880859 C 766.35351,77.318363 766.15429,78.076175 766.1543,79.154297 L 766.1543,82.107422 C 766.15429,83.224607 766.06054,84.009763 765.87305,84.462891 C 765.69335,84.916012 765.38085,85.267574 764.93555,85.517578 C 764.56835,85.712886 764.12304,85.857417 763.59961,85.951172 C 763.07617,86.044917 762.42382,86.091792 761.64258,86.091797 C 761.54883,86.091792 761.40429,86.087886 761.20898,86.080078 C 761.01367,86.072261 760.86133,86.068355 760.75195,86.068359 L 760.75195,83.619141 C 760.82226,83.619138 760.91992,83.623044 761.04492,83.630859 C 761.16992,83.638669 761.25586,83.642576 761.30273,83.642578 C 762.09179,83.642576 762.62304,83.490232 762.89648,83.185547 C 763.17773,82.88867 763.31836,82.263671 763.31836,81.310547 L 763.31836,78.509766 C 763.31836,77.337895 763.49414,76.513677 763.8457,76.037109 C 764.19726,75.55274 764.83007,75.20899 765.74414,75.005859 C 764.83007,74.794928 764.19726,74.447272 763.8457,73.962891 C 763.49414,73.478523 763.31836,72.658212 763.31836,71.501953 L 763.31836,68.666016 C 763.31836,67.712904 763.17773,67.087905 762.89648,66.791016 C 762.62304,66.486343 762.09179,66.333999 761.30273,66.333984 C 761.25586,66.333999 761.16992,66.337906 761.04492,66.345703 C 760.91992,66.35353 760.82226,66.357437 760.75195,66.357422 L 760.75195,63.908203 M 767.00977,93.955078 L 767.00977,116.32617 L 761.08008,116.32617 L 761.08008,113.83008 L 763.8457,113.83008 L 763.8457,96.451172 L 761.08008,96.451172 L 761.08008,93.955078 L 767.00977,93.955078"
602 id="text5554" />
603 <path
604 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
605 d="M 823.79883,62.876953 L 826.21289,62.876953 L 826.21289,86.876953 L 823.79883,86.876953 L 823.79883,62.876953 M 827.10352,113.44336 L 821.29102,93.509766 L 822.87305,93.509766 L 828.70898,113.44336 L 827.10352,113.44336"
606 id="text5564" />
607 <g
608 id="g5770"
609 transform="translate(0,3.75)">
610 <text
611 sodipodi:linespacing="125%"
612 id="text5570"
613 y="139.30469"
614 x="52.152344"
615 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
616 xml:space="preserve"><tspan
617 y="139.30469"
618 x="52.152344"
619 id="tspan5572"
620 sodipodi:role="line">Caps Lock</tspan></text>
621 <path
622 id="path5584"
623 d="M 26.25,142.5 L 15,157.5 L 22.5,157.5 L 22.5,165 L 30,165 L 30,157.5 L 37.5,157.5 L 26.25,142.5 z M 25.21875,146.71875 L 27.25,146.71875 L 30.375,155.34375 L 28.5,155.34375 L 27.90625,153.5625 L 24.5625,153.5625 L 24,155.34375 L 22.125,155.34375 L 25.21875,146.71875 z M 26.25,148.4375 L 25.03125,152.09375 L 27.4375,152.09375 L 26.25,148.4375 z "
624 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
625 </g>
626 <path
627 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
628 d="M 119.9707,129.82617 L 117.58008,137.17383 L 122.37305,137.17383 L 119.9707,129.82617 M 117.9082,126.36914 L 122.00977,126.36914 L 128.23242,143.63086 L 124.50586,143.63086 L 123.33398,140.08008 L 116.64258,140.08008 L 115.50586,143.63086 L 111.76758,143.63086 L 117.9082,126.36914"
629 id="text5641" />
630 <path
631 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
632 d="M 172.98047,138.29297 L 176.48438,138.29297 C 176.61718,139.23829 177.0039,139.94141 177.64453,140.40234 C 178.28515,140.85547 179.21093,141.08203 180.42188,141.08203 C 181.45312,141.08203 182.23046,140.89844 182.75391,140.53125 C 183.27733,140.16407 183.53905,139.6211 183.53906,138.90234 C 183.53905,137.85547 182.03515,136.98829 179.02734,136.30078 C 178.98827,136.29298 178.95312,136.28516 178.92188,136.27734 C 178.84374,136.26173 178.72265,136.23438 178.55859,136.19531 C 176.94921,135.84376 175.80078,135.44923 175.11328,135.01172 C 174.5039,134.6211 174.03906,134.09767 173.71875,133.44141 C 173.39844,132.77735 173.23828,131.99611 173.23828,131.09766 C 173.23828,129.41798 173.80859,128.13283 174.94922,127.24219 C 176.08984,126.34377 177.73828,125.89455 179.89453,125.89453 C 181.91015,125.89455 183.48436,126.37111 184.61719,127.32422 C 185.7578,128.27736 186.35936,129.62111 186.42188,131.35547 L 183.01172,131.35547 C 182.94921,130.51954 182.6289,129.88283 182.05078,129.44531 C 181.47265,129.00783 180.64843,128.78908 179.57813,128.78906 C 178.64843,128.78908 177.92968,128.97267 177.42188,129.33984 C 176.92187,129.69923 176.67187,130.21486 176.67188,130.88672 C 176.67187,131.80079 177.65234,132.48439 179.61328,132.9375 C 180.14452,133.06251 180.55859,133.16017 180.85547,133.23047 C 182.11327,133.55079 183.0039,133.80079 183.52734,133.98047 C 184.05858,134.16017 184.51952,134.35938 184.91016,134.57813 C 185.61327,134.96876 186.14061,135.48829 186.49219,136.13672 C 186.84374,136.77735 187.01952,137.54688 187.01953,138.44531 C 187.01952,140.24219 186.41405,141.63672 185.20313,142.62891 C 183.99218,143.61328 182.28515,144.10547 180.08203,144.10547 C 177.91015,144.10547 176.20703,143.60156 174.97266,142.59375 C 173.73828,141.58594 173.07422,140.15235 172.98047,138.29297"
633 id="text5645" />
634 <path
635 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
636 d="M 236.16211,140.51367 L 239.00977,140.51367 C 240.65819,140.51367 241.8496,140.08399 242.58398,139.22461 C 243.32616,138.35743 243.69725,136.95508 243.69727,135.01758 C 243.69725,133.0879 243.3535,131.66993 242.66602,130.76367 C 241.9785,129.85744 240.90429,129.40431 239.44336,129.4043 L 236.16211,129.4043 L 236.16211,140.51367 M 232.68164,143.63086 L 232.68164,126.36914 L 239.44336,126.36914 C 242.09179,126.36916 244.06444,127.084 245.36133,128.51367 C 246.666,129.94337 247.31834,132.11134 247.31836,135.01758 C 247.31834,136.59571 247.07616,137.98633 246.5918,139.18945 C 246.11522,140.39258 245.41991,141.36133 244.50586,142.0957 C 243.81835,142.64258 243.0371,143.03711 242.16211,143.2793 C 241.2871,143.51367 240.06054,143.63086 238.48242,143.63086 L 232.68164,143.63086"
637 id="text5649" />
638 <path
639 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
640 d="M 293.97656,143.63086 L 293.97656,126.36914 L 306.02344,126.36914 L 306.02344,129.36914 L 297.48047,129.36914 L 297.48047,133.2832 L 304.96875,133.2832 L 304.96875,136.2832 L 297.48047,136.2832 L 297.48047,143.63086 L 293.97656,143.63086"
641 id="text5653" />
642 <path
643 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
644 d="M 365.17969,141.57422 C 364.53905,142.44141 363.80858,143.07813 362.98828,143.48438 C 362.17577,143.89062 361.21874,144.09375 360.11719,144.09375 C 357.70312,144.09375 355.74609,143.25781 354.24609,141.58594 C 352.7539,139.90625 352.00781,137.70313 352.00781,134.97656 C 352.00781,132.22657 352.7539,130.02736 354.24609,128.37891 C 355.73828,126.73049 357.72656,125.90627 360.21094,125.90625 C 362.37499,125.90627 364.14061,126.4258 365.50781,127.46484 C 366.87498,128.49611 367.68748,129.91798 367.94531,131.73047 L 364.32422,131.73047 C 364.10546,130.83204 363.65624,130.14845 362.97656,129.67969 C 362.30468,129.21095 361.42577,128.97658 360.33984,128.97656 C 358.89452,128.97658 357.75781,129.50783 356.92969,130.57031 C 356.10937,131.62501 355.69921,133.08595 355.69922,134.95313 C 355.69921,136.82813 356.1289,138.29688 356.98828,139.35938 C 357.84765,140.42188 359.02734,140.95313 360.52734,140.95313 C 361.65233,140.95313 362.59374,140.6211 363.35156,139.95703 C 364.10936,139.29297 364.57811,138.38282 364.75781,137.22656 L 360.84375,137.22656 L 360.84375,134.27344 L 367.99219,134.27344 L 367.99219,143.61328 L 365.61328,143.61328 L 365.17969,141.57422"
645 id="text5657" />
646 <path
647 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
648 d="M 412.86328,143.63086 L 412.86328,126.36914 L 416.4375,126.36914 L 416.4375,132.80273 L 423.5625,132.80273 L 423.5625,126.36914 L 427.13672,126.36914 L 427.13672,143.63086 L 423.5625,143.63086 L 423.5625,135.97852 L 416.4375,135.97852 L 416.4375,143.63086 L 412.86328,143.63086"
649 id="text5661" />
650 <path
651 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
652 d="M 143.15039,203.63086 L 143.15039,200.63086 L 152.53711,189.49805 L 143.33789,189.49805 L 143.33789,186.36914 L 156.84961,186.36914 L 156.84961,189.36914 L 147.43945,200.51367 L 156.63867,200.51367 L 156.63867,203.63086 L 143.15039,203.63086"
653 id="text5679" />
654 <path
655 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
656 d="M 202.37109,203.63086 L 207.79688,194.81836 L 202.37109,186.36914 L 206.47266,186.36914 L 210,192.4043 L 213.50391,186.36914 L 217.62891,186.36914 L 212.20313,194.79492 L 217.62891,203.63086 L 213.52734,203.63086 L 210,197.6543 L 206.47266,203.63086 L 202.37109,203.63086"
657 id="text5683" />
658 <path
659 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
660 d="M 277.875,197.68359 C 277.74217,199.64454 276.98436,201.20313 275.60156,202.35938 C 274.22655,203.51563 272.42968,204.09375 270.21094,204.09375 C 267.65624,204.09375 265.66796,203.29688 264.24609,201.70313 C 262.83203,200.10938 262.125,197.87501 262.125,195 C 262.125,192.06251 262.84765,189.81251 264.29297,188.25 C 265.73828,186.68752 267.8164,185.90627 270.52734,185.90625 C 272.73046,185.90627 274.46874,186.44533 275.74219,187.52344 C 277.02342,188.59377 277.72655,190.10939 277.85156,192.07031 L 274.34766,192.07031 C 274.19921,191.09376 273.80077,190.35158 273.15234,189.84375 C 272.50389,189.32814 271.6289,189.07033 270.52734,189.07031 C 268.96484,189.07033 267.77734,189.57423 266.96484,190.58203 C 266.15234,191.58986 265.74609,193.06251 265.74609,195 C 265.74609,196.87501 266.14843,198.32422 266.95313,199.34766 C 267.76562,200.3711 268.91796,200.88282 270.41016,200.88281 C 271.48827,200.88282 272.37108,200.60938 273.05859,200.0625 C 273.74608,199.50782 274.19139,198.71485 274.39453,197.68359 L 277.875,197.68359"
661 id="text5687" />
662 <path
663 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
664 d="M 328.33594,203.63086 L 322.38281,186.36914 L 326.32031,186.36914 L 329.98828,199.2832 L 333.72656,186.36914 L 337.61719,186.36914 L 331.73438,203.63086 L 328.33594,203.63086"
665 id="text5691" />
666 <path
667 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
668 d="M 386.32031,200.51367 L 390.52734,200.51367 C 391.51952,200.51367 392.24218,200.33399 392.69531,199.97461 C 393.14843,199.61524 393.37499,199.04883 393.375,198.27539 C 393.37499,197.47071 393.15233,196.89258 392.70703,196.54102 C 392.26171,196.18165 391.52733,196.00196 390.50391,196.00195 L 386.32031,196.00195 L 386.32031,200.51367 M 386.32031,193.04883 L 390.375,193.04883 C 391.24999,193.04884 391.89061,192.9004 392.29688,192.60352 C 392.70311,192.29884 392.90624,191.82228 392.90625,191.17383 C 392.90624,190.54103 392.70702,190.084 392.30859,189.80273 C 391.91796,189.51369 391.26561,189.36915 390.35156,189.36914 L 386.32031,189.36914 L 386.32031,193.04883 M 382.92188,203.63086 L 382.92188,186.36914 L 391.05469,186.36914 C 392.8203,186.36916 394.16405,186.74416 395.08594,187.49414 C 396.01561,188.23634 396.48045,189.31837 396.48047,190.74023 C 396.48045,191.61525 396.30858,192.34571 395.96484,192.93164 C 395.62108,193.51759 395.10545,193.97071 394.41797,194.29102 C 395.30858,194.6504 395.97264,195.16993 396.41016,195.84961 C 396.85545,196.52149 397.07811,197.36133 397.07813,198.36914 C 397.07811,200.04883 396.53123,201.34571 395.4375,202.25977 C 394.34374,203.17383 392.79296,203.63086 390.78516,203.63086 L 382.92188,203.63086"
669 id="text5695" />
670 <path
671 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
672 d="M 442.88672,203.63086 L 442.88672,186.36914 L 446.60156,186.36914 L 453.60938,198.22852 L 453.60938,186.36914 L 457.11328,186.36914 L 457.11328,203.63086 L 453.44531,203.63086 L 446.39063,191.77148 L 446.39063,203.63086 L 442.88672,203.63086"
673 id="text5699" />
674 <path
675 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
676 d="M 501.32813,203.63086 L 501.32813,186.36914 L 506.57813,186.36914 L 510.01172,199.50586 L 513.39844,186.36914 L 518.67188,186.36914 L 518.67188,203.63086 L 515.34375,203.63086 L 515.34375,189.70898 L 511.83984,203.63086 L 508.20703,203.63086 L 504.65625,189.70898 L 504.65625,203.63086 L 501.32813,203.63086"
677 id="text5703" />
678 <path
679 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
680 d="M 720.78516,126.7793 L 723.03516,126.7793 L 723.03516,133.33008 L 720.78516,133.33008 L 720.78516,126.7793 M 716.96484,126.7793 L 719.21484,126.7793 L 719.21484,133.33008 L 716.96484,133.33008 L 716.96484,126.7793 M 718.88672,156.7793 L 721.13672,156.7793 L 721.13672,163.33008 L 718.88672,163.33008 L 718.88672,156.7793"
681 id="text5731" />
682 <path
683 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
684 d="M 772.5,140.60938 L 772.5,129.10156 L 780.85156,129.10156 L 780.85156,131.10156 L 774.83594,131.10156 L 774.83594,133.55469 L 780.33594,133.55469 L 780.33594,135.52344 L 774.83594,135.52344 L 774.83594,138.48438 L 781.13281,138.48438 L 781.13281,140.60938 L 772.5,140.60938 M 782.74219,140.60938 L 782.74219,132.11719 L 784.96875,132.11719 L 784.96875,133.125 C 785.28645,132.71355 785.66145,132.40626 786.09375,132.20313 C 786.52604,131.9948 787.00781,131.89063 787.53906,131.89063 C 788.47656,131.89063 789.17708,132.13543 789.64063,132.625 C 790.10937,133.10938 790.34374,133.84115 790.34375,134.82031 L 790.34375,140.60938 L 788.07031,140.60938 L 788.07031,135.47656 C 788.07031,134.86719 787.96614,134.4323 787.75781,134.17188 C 787.55468,133.91147 787.22135,133.78126 786.75781,133.78125 C 786.22135,133.78126 785.79687,133.94271 785.48438,134.26563 C 785.17187,134.58334 785.01562,135.01823 785.01563,135.57031 L 785.01563,140.60938 L 782.74219,140.60938 M 796.07813,140.67188 C 795.86979,140.67708 795.61979,140.6849 795.32813,140.69531 C 795.04166,140.71094 794.85937,140.71875 794.78125,140.71875 C 793.91146,140.71875 793.3151,140.55729 792.99219,140.23438 C 792.67448,139.90625 792.51562,139.26302 792.51563,138.30469 L 792.51563,133.71094 L 791.39063,133.71094 L 791.39063,132.11719 L 792.51563,132.11719 L 792.51563,129.79688 L 794.76563,129.79688 L 794.76563,132.11719 L 796.07813,132.11719 L 796.07813,133.71094 L 794.76563,133.71094 L 794.76563,138.41406 C 794.76562,138.63802 794.8151,138.78646 794.91406,138.85938 C 795.01302,138.92709 795.21614,138.96094 795.52344,138.96094 L 796.07813,138.96094 L 796.07813,140.67188 M 802.63281,138.03125 L 804.89844,138.03125 C 804.66926,138.92709 804.20572,139.63021 803.50781,140.14063 C 802.8151,140.64583 801.96874,140.89844 800.96875,140.89844 C 799.73958,140.89844 798.76562,140.48698 798.04688,139.66406 C 797.32812,138.83594 796.96875,137.71615 796.96875,136.30469 C 796.96875,134.91407 797.32292,133.81772 798.03125,133.01563 C 798.73958,132.21355 799.70833,131.81251 800.9375,131.8125 C 802.23958,131.81251 803.24478,132.20834 803.95313,133 C 804.66145,133.78647 805.01562,134.90886 805.01563,136.36719 C 805.01562,136.52865 805.01301,136.65105 805.00781,136.73438 C 805.0078,136.8125 805.0026,136.88802 804.99219,136.96094 L 799.32031,136.96094 C 799.35156,137.62761 799.51302,138.13021 799.80469,138.46875 C 800.10156,138.80729 800.52604,138.97656 801.07813,138.97656 C 801.46874,138.97656 801.78906,138.90104 802.03906,138.75 C 802.28906,138.59375 802.48697,138.35417 802.63281,138.03125 M 799.32031,135.46875 L 802.66406,135.46875 C 802.64322,134.89584 802.48958,134.46094 802.20313,134.16406 C 801.92187,133.86199 801.51562,133.71094 800.98438,133.71094 C 800.48958,133.71094 800.09895,133.86199 799.8125,134.16406 C 799.53125,134.46615 799.36718,134.90105 799.32031,135.46875 M 806.52344,140.60938 L 806.52344,132.11719 L 808.63281,132.11719 L 808.63281,133.57031 C 808.92968,132.98699 809.27604,132.5599 809.67188,132.28906 C 810.0677,132.01303 810.53906,131.87501 811.08594,131.875 C 811.17447,131.87501 811.24218,131.87761 811.28906,131.88281 C 811.34114,131.88282 811.38281,131.88543 811.41406,131.89063 L 811.42188,134.19531 L 810.66406,134.19531 C 810.04427,134.19532 809.57812,134.35678 809.26563,134.67969 C 808.95312,135.00261 808.79687,135.48178 808.79688,136.11719 L 808.79688,140.60938 L 806.52344,140.60938"
685 id="text5737" />
686 <path
687 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
688 d="M 787.5,172.5 L 787.5,157.5 L 772.5,165 L 787.5,172.5 z "
689 id="path5745" />
690 <path
691 style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1"
692 d="M 810,150 L 810,165 L 780,165"
693 id="path5747" />
694 <g
695 id="g5790">
696 <text
697 xml:space="preserve"
698 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
699 x="31.8125"
700 y="201.19531"
701 id="text5753"
702 sodipodi:linespacing="125%"><tspan
703 sodipodi:role="line"
704 id="tspan5755"
705 x="31.8125"
706 y="201.19531">Shift</tspan></text>
707 <path
708 style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
709 d="M 27.25,207.125 L 16,222.125 L 23.5,222.125 L 23.5,229.625 L 31,229.625 L 31,222.125 L 38.5,222.125 L 27.25,207.125 z "
710 id="path5757" />
711 </g>
712 <g
713 id="g5795"
714 transform="translate(727.5,0)">
715 <text
716 sodipodi:linespacing="125%"
717 id="text5797"
718 y="201.19531"
719 x="31.8125"
720 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
721 xml:space="preserve"><tspan
722 y="201.19531"
723 x="31.8125"
724 id="tspan5799"
725 sodipodi:role="line">Shift</tspan></text>
726 <path
727 id="path5801"
728 d="M 27.25,207.125 L 16,222.125 L 23.5,222.125 L 23.5,229.625 L 31,229.625 L 31,222.125 L 38.5,222.125 L 27.25,207.125 z "
729 style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
730 </g>
731 <path
732 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
733 d="M 576.90234,189.63867 L 576.90234,192.20508 L 566.4375,196.48242 L 576.90234,200.74805 L 576.90234,203.31445 L 563.09766,197.63086 L 563.09766,195.29883 L 576.90234,189.63867 M 568.21875,237.68555 L 568.21875,236.31445 C 568.875,236.12695 569.35937,235.83789 569.67188,235.44727 C 569.98437,235.05664 570.14062,234.54883 570.14063,233.92383 L 570.14063,233.63086 L 568.21875,233.63086 L 568.21875,230.10352 L 571.76953,230.10352 L 571.76953,233.49023 C 571.76953,234.6543 571.46875,235.59179 570.86719,236.30273 C 570.27343,237.01367 569.39062,237.47461 568.21875,237.68555"
734 id="text5803" />
735 <path
736 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
737 d="M 623.09766,189.63867 L 636.90234,195.29883 L 636.90234,197.63086 L 623.09766,203.31445 L 623.09766,200.74805 L 633.58594,196.48242 L 623.09766,192.20508 L 623.09766,189.63867 M 628.21875,233.63086 L 628.21875,230.10352 L 631.74609,230.10352 L 631.74609,233.63086 L 628.21875,233.63086"
738 id="text5813" />
739 <path
740 style="font-size:24px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
741 d="M 688.44727,198.61523 C 688.44726,198.5293 688.44335,198.41602 688.43555,198.27539 C 688.42773,198.12696 688.42382,198.01758 688.42383,197.94727 C 688.42382,197.25977 688.49804,196.68946 688.64648,196.23633 C 688.79492,195.7754 689.0332,195.34571 689.36133,194.94727 C 689.61132,194.6504 689.98242,194.31056 690.47461,193.92773 C 690.9746,193.54493 691.29882,193.26759 691.44727,193.0957 C 691.75976,192.74415 691.9746,192.42775 692.0918,192.14648 C 692.20898,191.86525 692.26757,191.55665 692.26758,191.2207 C 692.26757,190.47853 692.06054,189.9004 691.64648,189.48633 C 691.23241,189.07228 690.65429,188.86525 689.91211,188.86523 C 689.16992,188.86525 688.58398,189.11525 688.1543,189.61523 C 687.73242,190.10744 687.50195,190.80275 687.46289,191.70117 L 684.1582,191.70117 L 684.1582,191.33789 C 684.1582,189.68947 684.67773,188.37697 685.7168,187.40039 C 686.76367,186.41603 688.16992,185.92385 689.93555,185.92383 C 691.74023,185.92385 693.17382,186.38869 694.23633,187.31836 C 695.30663,188.24025 695.84178,189.47853 695.8418,191.0332 C 695.84178,191.58009 695.77928,192.07228 695.6543,192.50977 C 695.5371,192.93946 695.3535,193.33399 695.10352,193.69336 C 694.78319,194.14649 694.2871,194.63868 693.61523,195.16992 C 692.95116,195.69337 692.54882,196.01759 692.4082,196.14258 C 692.11132,196.43165 691.89648,196.73634 691.76367,197.05664 C 691.63866,197.37696 691.57616,197.75977 691.57617,198.20508 C 691.57616,198.24415 691.58007,198.31055 691.58789,198.4043 C 691.59569,198.49805 691.5996,198.56836 691.59961,198.61523 L 688.44727,198.61523 M 688.2832,203.63086 L 688.2832,200.19727 L 691.74023,200.19727 L 691.74023,203.63086 L 688.2832,203.63086 M 686.31445,235.85742 L 692.12695,215.92383 L 693.73242,215.92383 L 687.89648,235.85742 L 686.31445,235.85742"
742 id="text5819" />
743 <path
744 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
745 d="M 18,271.78906 C 17.911447,273.09636 17.406239,274.13542 16.484375,274.90625 C 15.5677,275.67708 14.369784,276.0625 12.890625,276.0625 C 11.187496,276.0625 9.8619761,275.53125 8.9140625,274.46875 C 7.971353,273.40625 7.4999993,271.91667 7.5,270 C 7.4999993,268.04167 7.9817696,266.54168 8.9453125,265.5 C 9.9088511,264.45834 11.294266,263.93751 13.101563,263.9375 C 14.570305,263.93751 15.729158,264.29689 16.578125,265.01563 C 17.432281,265.72918 17.901031,266.73959 17.984375,268.04688 L 15.648438,268.04688 C 15.54947,267.39584 15.283846,266.90105 14.851563,266.5625 C 14.419263,266.21876 13.83593,266.04688 13.101563,266.04688 C 12.059891,266.04688 11.268225,266.38282 10.726563,267.05469 C 10.184892,267.72657 9.9140594,268.70834 9.9140625,270 C 9.9140594,271.25 10.182288,272.21615 10.71875,272.89844 C 11.260412,273.58073 12.028641,273.92188 13.023438,273.92188 C 13.742181,273.92188 14.330722,273.73959 14.789063,273.375 C 15.247387,273.00521 15.544262,272.47657 15.679688,271.78906 L 18,271.78906 M 23.46875,275.80469 C 23.260412,275.8099 23.010412,275.81771 22.71875,275.82813 C 22.432288,275.84375 22.249996,275.85156 22.171875,275.85156 C 21.302081,275.85156 20.705727,275.6901 20.382813,275.36719 C 20.065103,275.03906 19.906249,274.39583 19.90625,273.4375 L 19.90625,268.84375 L 18.78125,268.84375 L 18.78125,267.25 L 19.90625,267.25 L 19.90625,264.92969 L 22.15625,264.92969 L 22.15625,267.25 L 23.46875,267.25 L 23.46875,268.84375 L 22.15625,268.84375 L 22.15625,273.54688 C 22.156247,273.77084 22.205726,273.91927 22.304688,273.99219 C 22.403642,274.0599 22.606767,274.09375 22.914063,274.09375 L 23.46875,274.09375 L 23.46875,275.80469 M 24.789063,275.74219 L 24.789063,267.25 L 26.898438,267.25 L 26.898438,268.70313 C 27.195309,268.1198 27.541663,267.69272 27.9375,267.42188 C 28.333329,267.14584 28.804682,267.00782 29.351563,267.00781 C 29.440099,267.00782 29.507807,267.01043 29.554688,267.01563 C 29.606765,267.01563 29.648432,267.01824 29.679688,267.02344 L 29.6875,269.32813 L 28.929688,269.32813 C 28.309891,269.32813 27.843746,269.48959 27.53125,269.8125 C 27.218747,270.13542 27.062497,270.61459 27.0625,271.25 L 27.0625,275.74219 L 24.789063,275.74219 M 31.023438,275.74219 L 31.023438,264.23438 L 33.296875,264.23438 L 33.296875,275.74219 L 31.023438,275.74219"
746 id="text5827" />
747 <path
748 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
749 d="M 612.96875,266.53906 L 611.375,271.4375 L 614.57031,271.4375 L 612.96875,266.53906 M 611.59375,264.23438 L 614.32813,264.23438 L 618.47656,275.74219 L 615.99219,275.74219 L 615.21094,273.375 L 610.75,273.375 L 609.99219,275.74219 L 607.5,275.74219 L 611.59375,264.23438 M 619.53906,275.74219 L 619.53906,264.23438 L 621.8125,264.23438 L 621.8125,275.74219 L 619.53906,275.74219 M 627.64063,275.80469 C 627.43229,275.8099 627.18229,275.81771 626.89063,275.82813 C 626.60416,275.84375 626.42187,275.85156 626.34375,275.85156 C 625.47396,275.85156 624.8776,275.6901 624.55469,275.36719 C 624.23698,275.03906 624.07812,274.39583 624.07813,273.4375 L 624.07813,268.84375 L 622.95313,268.84375 L 622.95313,267.25 L 624.07813,267.25 L 624.07813,264.92969 L 626.32813,264.92969 L 626.32813,267.25 L 627.64063,267.25 L 627.64063,268.84375 L 626.32813,268.84375 L 626.32813,273.54688 C 626.32812,273.77084 626.3776,273.91927 626.47656,273.99219 C 626.57552,274.0599 626.77864,274.09375 627.08594,274.09375 L 627.64063,274.09375 L 627.64063,275.80469"
750 id="text5835"
751 sodipodi:nodetypes="cccccccccccccccccccsssccccccccccccsccc" />
752 <path
753 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
754 d="M 828,271.78906 C 827.91145,273.09636 827.40624,274.13542 826.48438,274.90625 C 825.5677,275.67708 824.36978,276.0625 822.89063,276.0625 C 821.1875,276.0625 819.86198,275.53125 818.91406,274.46875 C 817.97135,273.40625 817.5,271.91667 817.5,270 C 817.5,268.04167 817.98177,266.54168 818.94531,265.5 C 819.90885,264.45834 821.29427,263.93751 823.10156,263.9375 C 824.5703,263.93751 825.72916,264.29689 826.57813,265.01563 C 827.43228,265.72918 827.90103,266.73959 827.98438,268.04688 L 825.64844,268.04688 C 825.54947,267.39584 825.28385,266.90105 824.85156,266.5625 C 824.41926,266.21876 823.83593,266.04688 823.10156,266.04688 C 822.05989,266.04688 821.26822,266.38282 820.72656,267.05469 C 820.18489,267.72657 819.91406,268.70834 819.91406,270 C 819.91406,271.25 820.18229,272.21615 820.71875,272.89844 C 821.26041,273.58073 822.02864,273.92188 823.02344,273.92188 C 823.74218,273.92188 824.33072,273.73959 824.78906,273.375 C 825.24739,273.00521 825.54426,272.47657 825.67969,271.78906 L 828,271.78906 M 833.46875,275.80469 C 833.26041,275.8099 833.01041,275.81771 832.71875,275.82813 C 832.43229,275.84375 832.25,275.85156 832.17188,275.85156 C 831.30208,275.85156 830.70573,275.6901 830.38281,275.36719 C 830.0651,275.03906 829.90625,274.39583 829.90625,273.4375 L 829.90625,268.84375 L 828.78125,268.84375 L 828.78125,267.25 L 829.90625,267.25 L 829.90625,264.92969 L 832.15625,264.92969 L 832.15625,267.25 L 833.46875,267.25 L 833.46875,268.84375 L 832.15625,268.84375 L 832.15625,273.54688 C 832.15625,273.77084 832.20573,273.91927 832.30469,273.99219 C 832.40364,274.0599 832.60677,274.09375 832.91406,274.09375 L 833.46875,274.09375 L 833.46875,275.80469 M 834.78906,275.74219 L 834.78906,267.25 L 836.89844,267.25 L 836.89844,268.70313 C 837.19531,268.1198 837.54166,267.69272 837.9375,267.42188 C 838.33333,267.14584 838.80468,267.00782 839.35156,267.00781 C 839.4401,267.00782 839.50781,267.01043 839.55469,267.01563 C 839.60677,267.01563 839.64843,267.01824 839.67969,267.02344 L 839.6875,269.32813 L 838.92969,269.32813 C 838.30989,269.32813 837.84375,269.48959 837.53125,269.8125 C 837.21875,270.13542 837.0625,270.61459 837.0625,271.25 L 837.0625,275.74219 L 834.78906,275.74219 M 841.02344,275.74219 L 841.02344,264.23438 L 843.29688,264.23438 L 843.29688,275.74219 L 841.02344,275.74219"
755 id="text5839" />
756 <path
757 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
758 d="M 108.94531,264.01953 L 105.64844,252.51172 L 108.10156,252.51172 L 110.07031,260.62891 L 111.73438,252.51172 L 114.25781,252.51172 L 115.92188,260.62891 L 117.89063,252.51172 L 120.32031,252.51172 L 117.03125,264.01953 L 114.77344,264.01953 L 112.99219,255.20703 L 111.20313,264.01953 L 108.94531,264.01953 M 121.5,254.58203 L 121.5,252.51172 L 123.77344,252.51172 L 123.77344,254.58203 L 121.5,254.58203 M 121.5,264.01953 L 121.5,255.52734 L 123.77344,255.52734 L 123.77344,264.01953 L 121.5,264.01953 M 125.79688,264.01953 L 125.79688,255.52734 L 128.02344,255.52734 L 128.02344,256.53516 C 128.34114,256.12371 128.71614,255.81641 129.14844,255.61328 C 129.58072,255.40496 130.06249,255.30079 130.59375,255.30078 C 131.53124,255.30079 132.23176,255.54558 132.69531,256.03516 C 133.16405,256.51954 133.39843,257.25131 133.39844,258.23047 L 133.39844,264.01953 L 131.125,264.01953 L 131.125,258.88672 C 131.12499,258.27735 131.02083,257.84245 130.8125,257.58203 C 130.60937,257.32162 130.27604,257.19141 129.8125,257.19141 C 129.27604,257.19141 128.85156,257.35287 128.53906,257.67578 C 128.22656,257.9935 128.07031,258.42839 128.07031,258.98047 L 128.07031,264.01953 L 125.79688,264.01953 M 106.64844,284.01953 L 106.64844,272.51172 L 109.01563,272.51172 L 109.01563,277.23828 L 113.50781,272.51172 L 116.46875,272.51172 L 111.875,277.16797 L 116.88281,284.01953 L 113.99219,284.01953 L 110.24219,278.75391 L 109.01563,279.97266 L 109.01563,284.01953 L 106.64844,284.01953 M 122.9375,281.44141 L 125.20313,281.44141 C 124.97395,282.33724 124.51041,283.04037 123.8125,283.55078 C 123.11979,284.05599 122.27343,284.30859 121.27344,284.30859 C 120.04427,284.30859 119.07031,283.89714 118.35156,283.07422 C 117.63281,282.2461 117.27344,281.1263 117.27344,279.71484 C 117.27344,278.32422 117.6276,277.22787 118.33594,276.42578 C 119.04427,275.62371 120.01302,275.22267 121.24219,275.22266 C 122.54427,275.22267 123.54947,275.6185 124.25781,276.41016 C 124.96614,277.19662 125.3203,278.31902 125.32031,279.77734 C 125.3203,279.93881 125.3177,280.0612 125.3125,280.14453 C 125.31249,280.22266 125.30728,280.29818 125.29688,280.37109 L 119.625,280.37109 C 119.65625,281.03776 119.81771,281.54037 120.10938,281.87891 C 120.40625,282.21745 120.83073,282.38672 121.38281,282.38672 C 121.77343,282.38672 122.09374,282.3112 122.34375,282.16016 C 122.59374,282.00391 122.79166,281.76433 122.9375,281.44141 M 119.625,278.87891 L 122.96875,278.87891 C 122.94791,278.306 122.79426,277.8711 122.50781,277.57422 C 122.22656,277.27214 121.82031,277.1211 121.28906,277.12109 C 120.79427,277.1211 120.40364,277.27214 120.11719,277.57422 C 119.83593,277.87631 119.67187,278.3112 119.625,278.87891 M 127.16406,287.42578 L 127.16406,285.58984 C 127.23698,285.60026 127.3125,285.60807 127.39063,285.61328 C 127.46875,285.61849 127.57031,285.62109 127.69531,285.62109 C 128.14323,285.62109 128.47916,285.51432 128.70313,285.30078 C 128.92708,285.09245 129.03906,284.77734 129.03906,284.35547 C 129.03906,284.32422 129.03385,284.28516 129.02344,284.23828 C 129.01302,284.19141 129.0026,284.15234 128.99219,284.12109 L 125.92969,275.52734 L 128.42969,275.52734 L 130.21875,281.65234 L 131.96094,275.52734 L 134.35156,275.52734 L 130.85938,285.54297 C 130.59895,286.29297 130.27343,286.80338 129.88281,287.07422 C 129.49218,287.35026 128.90625,287.48828 128.125,287.48828 C 127.98437,287.48828 127.83333,287.48307 127.67188,287.47266 C 127.51041,287.46224 127.34114,287.44661 127.16406,287.42578"
759 id="text5872" />
760 <path
761 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
762 d="M 708.94531,264.01953 L 705.64844,252.51172 L 708.10156,252.51172 L 710.07031,260.62891 L 711.73438,252.51172 L 714.25781,252.51172 L 715.92188,260.62891 L 717.89063,252.51172 L 720.32031,252.51172 L 717.03125,264.01953 L 714.77344,264.01953 L 712.99219,255.20703 L 711.20313,264.01953 L 708.94531,264.01953 M 721.5,254.58203 L 721.5,252.51172 L 723.77344,252.51172 L 723.77344,254.58203 L 721.5,254.58203 M 721.5,264.01953 L 721.5,255.52734 L 723.77344,255.52734 L 723.77344,264.01953 L 721.5,264.01953 M 725.79688,264.01953 L 725.79688,255.52734 L 728.02344,255.52734 L 728.02344,256.53516 C 728.34114,256.12371 728.71614,255.81641 729.14844,255.61328 C 729.58072,255.40496 730.06249,255.30079 730.59375,255.30078 C 731.53124,255.30079 732.23176,255.54558 732.69531,256.03516 C 733.16405,256.51954 733.39843,257.25131 733.39844,258.23047 L 733.39844,264.01953 L 731.125,264.01953 L 731.125,258.88672 C 731.12499,258.27735 731.02083,257.84245 730.8125,257.58203 C 730.60937,257.32162 730.27604,257.19141 729.8125,257.19141 C 729.27604,257.19141 728.85156,257.35287 728.53906,257.67578 C 728.22656,257.9935 728.07031,258.42839 728.07031,258.98047 L 728.07031,264.01953 L 725.79688,264.01953 M 706.64844,284.01953 L 706.64844,272.51172 L 709.01563,272.51172 L 709.01563,277.23828 L 713.50781,272.51172 L 716.46875,272.51172 L 711.875,277.16797 L 716.88281,284.01953 L 713.99219,284.01953 L 710.24219,278.75391 L 709.01563,279.97266 L 709.01563,284.01953 L 706.64844,284.01953 M 722.9375,281.44141 L 725.20313,281.44141 C 724.97395,282.33724 724.51041,283.04037 723.8125,283.55078 C 723.11979,284.05599 722.27343,284.30859 721.27344,284.30859 C 720.04427,284.30859 719.07031,283.89714 718.35156,283.07422 C 717.63281,282.2461 717.27344,281.1263 717.27344,279.71484 C 717.27344,278.32422 717.6276,277.22787 718.33594,276.42578 C 719.04427,275.62371 720.01302,275.22267 721.24219,275.22266 C 722.54427,275.22267 723.54947,275.6185 724.25781,276.41016 C 724.96614,277.19662 725.3203,278.31902 725.32031,279.77734 C 725.3203,279.93881 725.3177,280.0612 725.3125,280.14453 C 725.31249,280.22266 725.30728,280.29818 725.29688,280.37109 L 719.625,280.37109 C 719.65625,281.03776 719.81771,281.54037 720.10938,281.87891 C 720.40625,282.21745 720.83073,282.38672 721.38281,282.38672 C 721.77343,282.38672 722.09374,282.3112 722.34375,282.16016 C 722.59374,282.00391 722.79166,281.76433 722.9375,281.44141 M 719.625,278.87891 L 722.96875,278.87891 C 722.94791,278.306 722.79426,277.8711 722.50781,277.57422 C 722.22656,277.27214 721.82031,277.1211 721.28906,277.12109 C 720.79427,277.1211 720.40364,277.27214 720.11719,277.57422 C 719.83593,277.87631 719.67187,278.3112 719.625,278.87891 M 727.16406,287.42578 L 727.16406,285.58984 C 727.23698,285.60026 727.3125,285.60807 727.39063,285.61328 C 727.46875,285.61849 727.57031,285.62109 727.69531,285.62109 C 728.14323,285.62109 728.47916,285.51432 728.70313,285.30078 C 728.92708,285.09245 729.03906,284.77734 729.03906,284.35547 C 729.03906,284.32422 729.03385,284.28516 729.02344,284.23828 C 729.01302,284.19141 729.0026,284.15234 728.99219,284.12109 L 725.92969,275.52734 L 728.42969,275.52734 L 730.21875,281.65234 L 731.96094,275.52734 L 734.35156,275.52734 L 730.85938,285.54297 C 730.59895,286.29297 730.27343,286.80338 729.88281,287.07422 C 729.49218,287.35026 728.90625,287.48828 728.125,287.48828 C 727.98437,287.48828 727.83333,287.48307 727.67188,287.47266 C 727.51041,287.46224 727.34114,287.44661 727.16406,287.42578"
763 id="text5878" />
764 <path
765 style="font-size:16px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:center;line-height:125%;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Swis721 BT"
766 d="M 759.98438,275.60938 L 759.98438,264.10156 L 763.48438,264.10156 L 765.77344,272.85938 L 768.03125,264.10156 L 771.54688,264.10156 L 771.54688,275.60938 L 769.32813,275.60938 L 769.32813,266.32813 L 766.99219,275.60938 L 764.57031,275.60938 L 762.20313,266.32813 L 762.20313,275.60938 L 759.98438,275.60938 M 778.99219,273.03125 L 781.25781,273.03125 C 781.02864,273.92709 780.5651,274.63021 779.86719,275.14063 C 779.17447,275.64583 778.32812,275.89844 777.32813,275.89844 C 776.09896,275.89844 775.125,275.48698 774.40625,274.66406 C 773.6875,273.83594 773.32812,272.71615 773.32813,271.30469 C 773.32812,269.91407 773.68229,268.81772 774.39063,268.01563 C 775.09896,267.21355 776.06771,266.81251 777.29688,266.8125 C 778.59895,266.81251 779.60416,267.20834 780.3125,268 C 781.02083,268.78647 781.37499,269.90886 781.375,271.36719 C 781.37499,271.52865 781.37239,271.65105 781.36719,271.73438 C 781.36718,271.8125 781.36197,271.88802 781.35156,271.96094 L 775.67969,271.96094 C 775.71093,272.62761 775.87239,273.13021 776.16406,273.46875 C 776.46093,273.80729 776.88541,273.97656 777.4375,273.97656 C 777.82812,273.97656 778.14843,273.90104 778.39844,273.75 C 778.64843,273.59375 778.84635,273.35417 778.99219,273.03125 M 775.67969,270.46875 L 779.02344,270.46875 C 779.0026,269.89584 778.84895,269.46094 778.5625,269.16406 C 778.28124,268.86199 777.87499,268.71094 777.34375,268.71094 C 776.84895,268.71094 776.45833,268.86199 776.17188,269.16406 C 775.89062,269.46615 775.72656,269.90105 775.67969,270.46875 M 782.88281,275.60938 L 782.88281,267.11719 L 785.10938,267.11719 L 785.10938,268.125 C 785.42708,267.71355 785.80208,267.40626 786.23438,267.20313 C 786.66666,266.9948 787.14843,266.89063 787.67969,266.89063 C 788.61718,266.89063 789.3177,267.13543 789.78125,267.625 C 790.24999,268.10938 790.48437,268.84115 790.48438,269.82031 L 790.48438,275.60938 L 788.21094,275.60938 L 788.21094,270.47656 C 788.21093,269.86719 788.10676,269.4323 787.89844,269.17188 C 787.69531,268.91147 787.36197,268.78126 786.89844,268.78125 C 786.36197,268.78126 785.9375,268.94272 785.625,269.26563 C 785.3125,269.58334 785.15625,270.01823 785.15625,270.57031 L 785.15625,275.60938 L 782.88281,275.60938 M 800.01563,267.11719 L 800.01563,275.60938 L 797.78906,275.60938 L 797.78906,274.60156 C 797.46614,275.01302 797.08854,275.32292 796.65625,275.53125 C 796.22916,275.73437 795.74739,275.83594 795.21094,275.83594 C 794.27864,275.83594 793.57812,275.59115 793.10938,275.10156 C 792.64583,274.61198 792.41406,273.88021 792.41406,272.90625 L 792.41406,267.11719 L 794.6875,267.11719 L 794.6875,272.25 C 794.6875,272.85417 794.78906,273.28646 794.99219,273.54688 C 795.19531,273.80209 795.53125,273.92969 796,273.92969 C 796.53124,273.92969 796.95312,273.77084 797.26563,273.45313 C 797.58333,273.13021 797.74218,272.69271 797.74219,272.14063 L 797.74219,267.11719 L 800.01563,267.11719"
767 id="text5884" />
768 <text
769 xml:space="preserve"
770 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
771 x="362"
772 y="272"
773 id="text3387"><tspan
774 sodipodi:role="line"
775 id="tspan3389"
776 x="362"
777 y="272"
778 style="font-size:13px;font-weight:bold;-inkscape-font-specification:Bitstream Vera Sans Bold">toggle tiling/floating</tspan></text>
779 <text
780 xml:space="preserve"
781 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
782 x="119.03223"
783 y="86"
784 id="text3391"><tspan
785 sodipodi:role="line"
786 id="tspan3393"
787 x="119.03223"
788 y="86"
789 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold">kill</tspan><tspan
790 sodipodi:role="line"
791 x="119.03223"
792 y="102.25"
793 id="tspan3395"
794 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold">window</tspan></text>
795 <text
796 xml:space="preserve"
797 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
798 x="239.79933"
799 y="86.438766"
800 id="text3397"><tspan
801 sodipodi:role="line"
802 id="tspan3399"
803 x="239.79933"
804 y="86.438766"
805 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold">exit</tspan><tspan
806 sodipodi:role="line"
807 x="239.79933"
808 y="102.68877"
809 id="tspan3401"
810 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold">i3</tspan></text>
811 <text
812 xml:space="preserve"
813 style="font-size:40px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans"
814 x="299.31445"
815 y="86"
816 id="text3403"><tspan
817 sodipodi:role="line"
818 id="tspan3405"
819 x="299.31445"
820 y="86"
821 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold">restart</tspan><tspan
822 sodipodi:role="line"
823 x="299.31445"
824 y="102.25"
825 id="tspan3407"
826 style="font-size:13px;font-weight:bold;text-align:center;text-anchor:middle;-inkscape-font-specification:Bitstream Vera Sans Bold">i3</tspan></text>
827 <text
828 xml:space="preserve"
829 style="font-size:13px;font-style:normal;font-weight:bold;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
830 x="491.81522"
831 y="146.5442"
832 id="text3430"><tspan
833 sodipodi:role="line"
834 id="tspan3432"
835 x="491.81522"
836 y="146.5442">move</tspan><tspan
837 sodipodi:role="line"
838 x="491.81522"
839 y="162.7942"
840 id="tspan3448">left</tspan></text>
841 <text
842 xml:space="preserve"
843 style="font-size:13px;font-style:normal;font-weight:bold;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
844 x="552.34015"
845 y="146.5442"
846 id="text3434"><tspan
847 sodipodi:role="line"
848 id="tspan3436"
849 x="552.34015"
850 y="146.5442">move</tspan><tspan
851 sodipodi:role="line"
852 x="552.34015"
853 y="162.7942"
854 id="tspan3450">down</tspan></text>
855 <text
856 xml:space="preserve"
857 style="font-size:13px;font-style:normal;font-weight:bold;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
858 x="611.90704"
859 y="145.83786"
860 id="text3438"><tspan
861 sodipodi:role="line"
862 id="tspan3440"
863 x="611.90704"
864 y="145.83786">move</tspan><tspan
865 sodipodi:role="line"
866 x="611.90704"
867 y="162.08786"
868 id="tspan3452">up</tspan></text>
869 <text
870 xml:space="preserve"
871 style="font-size:13px;font-style:normal;font-weight:bold;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
872 x="672.34808"
873 y="146.5442"
874 id="text3442"><tspan
875 sodipodi:role="line"
876 id="tspan3444"
877 x="672.34808"
878 y="146.5442">move</tspan><tspan
879 sodipodi:role="line"
880 x="672.34808"
881 y="162.7942"
882 id="tspan3446">right</tspan></text>
883 <text
884 xml:space="preserve"
885 style="font-size:13px;font-style:normal;font-weight:bold;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;-inkscape-font-specification:Bitstream Vera Sans"
886 x="194.95703"
887 y="276"
888 id="text4572"><tspan
889 sodipodi:role="line"
890 id="tspan4574"
891 x="194.95703"
892 y="276"
893 style="font-size:18">Mod1</tspan></text>
894 </g>
895 </svg>
0 Layout saving in i3
1 ===================
2 Michael Stapelberg <[email protected]>
3 April 2014
4
5 Layout saving/restoring is a feature that was introduced in i3 v4.8.
6
7 Layout saving/restoring allows you to load a JSON layout file so that you can
8 have a base layout to start working with after powering on your computer.
9 Dynamic use-cases also come to mind: if you frequently (but not always!) need a
10 grid layout of terminals with ping/traceroute commands to diagnose network
11 issues, you can easily automate opening these windows in just the right layout.
12
13 == Saving the layout
14
15 You can save the layout of either a single workspace or an entire output (e.g.
16 LVDS1). Of course, you can repeat this step multiple times if you want to
17 save/restore multiple workspaces/outputs.
18
19 +i3-save-tree(1)+ is a tool to save the layout. It will print a JSON
20 representation of i3’s internal layout data structures to stdout. Typically,
21 you may want to take a quick look at the output, then save it to a file and
22 tweak it a little bit:
23
24 ---------------------------------------------------
25 i3-save-tree --workspace 1 > ~/.i3/workspace-1.json
26 ---------------------------------------------------
27
28 Please note that the output of +i3-save-tree(1)+ is *NOT useful* until you
29 manually modify it — you need to tell i3 how to match/distinguish windows (for
30 example based on their WM_CLASS, title, etc.). By default, all the different
31 window properties are included in the output, but commented out. This is partly
32 to avoid relying on heuristics and partly to make you aware how i3 works so
33 that you can easily solve layout restoring problems.
34
35 How to modify the file manually is described in <<EditingLayoutFiles>>.
36
37 == Restoring the layout
38
39 After restoring the example layout from <<EditingLayoutFiles>>, i3 will open
40 placeholder windows for all the windows that were specified in the layout file.
41 You can recognize the placeholder windows by the watch symbol
42 footnote:[Depending on the font you are using, a placeholder symbol may show up
43 instead of the watch symbol.] in the center of the window, and by the swallow
44 criteria specification at the top of the window:
45
46 image:layout-saving-1.png["Restored layout",width=400,link="layout-saving-1.png"]
47
48 When an application opens a window that matches the specified swallow criteria,
49 it will be placed in the corresponding placeholder window. We say it gets
50 *swallowed* by the placeholder container, hence the term.
51
52 Note: Swallowing windows into unsatisfied placeholder windows takes precedence
53 over
54 link:https://i3wm.org/docs/userguide.html#_automatically_putting_clients_on_specific_workspaces[assignment
55 rules]. For example, if you assign all Emacs windows to workspace 1 in your i3
56 configuration file, but there is a placeholder window on workspace 2 which
57 matches Emacs as well, your newly started Emacs window will end up in the
58 placeholder window on workspace 2.
59
60 The placeholder windows are just regular windows, so feel free to move them
61 around or close them, for example.
62
63 === append_layout command
64
65 The +append_layout+ command is used to load a layout file into i3. It accepts a
66 path (relative to i3’s current working directory or absolute) to a JSON file.
67
68 *Syntax*:
69 --------------------------------------------------------------------------------
70 append_layout <path>
71 --------------------------------------------------------------------------------
72
73 *Examples*:
74 --------------------------------------------------------------------------------
75 # From a terminal or script:
76 i3-msg "workspace 1; append_layout /home/michael/.i3/workspace-1.json"
77
78 # In your i3 configuration file, you can autostart i3-msg like this:
79 # (Note that those lines will quickly become long, so typically you would store
80 # them in a script with proper indentation.)
81 exec --no-startup-id "i3-msg 'workspace 1; append_layout /home/michael/.i3/workspace-1.json'"
82 --------------------------------------------------------------------------------
83
84 == Editing layout files
85
86 [[EditingLayoutFiles]]
87
88 === Anatomy of a layout file
89
90 Here is an example layout file that we’ll discuss:
91
92 --------------------------------------------------------------------------------
93 {
94 // splitv split container with 2 children
95 "layout": "splitv",
96 "percent": 0.4,
97 "type": "con",
98 "nodes": [
99 {
100 "border": "none",
101 "name": "irssi",
102 "percent": 0.5,
103 "type": "con",
104 "swallows": [
105 {
106 "class": "^URxvt$",
107 "instance": "^irssi$"
108 }
109 ]
110 },
111 {
112 // stacked split container with 2 children
113 "layout": "stacked",
114 "percent": 0.5,
115 "type": "con",
116 "nodes": [
117 {
118 "name": "notmuch",
119 "percent": 0.5,
120 "type": "con",
121 "swallows": [
122 {
123 "class": "^Emacs$",
124 "instance": "^notmuch$"
125 }
126 ]
127 },
128 {
129 "name": "midna: ~",
130 "percent": 0.5,
131 "type": "con"
132 }
133 ]
134 }
135 ]
136 }
137
138 {
139 // stacked split container with 1 children
140 "layout": "stacked",
141 "percent": 0.6,
142 "type": "con",
143 "nodes": [
144 {
145 "name": "chrome",
146 "type": "con",
147 "swallows": [
148 {
149 "class": "^Google-chrome$"
150 }
151 ]
152 }
153 ]
154 }
155 --------------------------------------------------------------------------------
156
157 In this layout, the screen is divided into two columns. In the left column,
158 which covers 40% of the screen, there is a terminal emulator running irssi on
159 the top, and a stacked split container with an Emacs window and a terminal
160 emulator on the bottom. In the right column, there is a stacked container with
161 a Chrome window:
162
163 image:layout-saving-1.png["Restored layout",width=400,link="layout-saving-1.png"]
164
165 The structure of this JSON file looks a lot like the +TREE+ reply, see
166 https://build.i3wm.org/docs/ipc.html#_tree_reply for documentation on that. Some
167 properties are excluded because they are not relevant when restoring a layout.
168
169 Most importantly, look at the "swallows" section of each window. This is where
170 you need to be more or less specific. As an example, remember the section about
171 the Emacs window:
172
173 --------------------------------------------------------------------------------
174 "swallows": [
175 {
176 "class": "^Emacs$",
177 "instance": "^notmuch$"
178 }
179 ]
180 --------------------------------------------------------------------------------
181
182 Here you can see that i3 will require both the class and the instance to match.
183 Therefore, if you just start Emacs via dmenu, it will not get swallowed by that
184 container. Only if you start Emacs with the proper instance name (+emacs24
185 --name notmuch+), it will get swallowed.
186
187 You can match on "class", "instance", "window_role" and "title". All values are
188 case-sensitive regular expressions (PCRE). Use +xprop(1)+ and click into a
189 window to see its properties:
190
191 --------------------------------------------------------------------------------
192 $ xprop
193 WM_WINDOW_ROLE(STRING) = "gimp-toolbox-color-dialog"
194 WM_CLASS(STRING) = "gimp-2.8", "Gimp-2.8"
195 _NET_WM_NAME(UTF8_STRING) = "Change Foreground Color"
196 --------------------------------------------------------------------------------
197
198 The first part of +WM_CLASS+ is the "instance" (gimp-2.8 in this case), the
199 second part is the "class" (Gimp-2.8 in this case). "title" matches against
200 +_NET_WM_NAME+ and "window_role" matches against +WM_WINDOW_ROLE+.
201
202 In general, you should try to be as specific as possible in your swallow
203 criteria. Try to use criteria that match one window and only one window, to
204 have a reliable startup procedure.
205
206 If you specify multiple swallow criteria, the placeholder will be replaced by
207 the window which matches any of the criteria. As an example:
208
209 --------------------------------------------------------------------------------
210 // Matches either Emacs or Gvim, whichever one is started first.
211 "swallows": [
212 {"class": "^Emacs$"},
213 {"class": "^Gvim$"}
214 ]
215 --------------------------------------------------------------------------------
216
217 === JSON standard non-compliance
218
219 A layout file as generated by +i3-save-tree(1)+ is not strictly valid JSON:
220
221 1. Layout files contain multiple “JSON texts” at the top level. The JSON
222 standard doesn't prohibit this, but in practice most JSON parsers only
223 allow precisely one “text” per document/file, and will mark multiple texts
224 as invalid JSON.
225
226 2. Layout files contain comments which are not allowed by the JSON standard,
227 but are understood by many parsers.
228
229 Both of these deviations from the norm are to make manual editing by humans
230 easier. In case you are writing a more elaborate tool for manipulating these
231 layouts, you can either use a JSON parser that supports these deviations (for
232 example libyajl), transform the layout file to a JSON-conforming file, or
233 link:https://github.com/i3/i3/blob/next/.github/CONTRIBUTING.md[submit a patch]
234 to make +i3-save-tree(1)+ optionally output standard-conforming JSON.
235
236 == Troubleshooting
237
238 === Restoring a vertically split workspace
239
240 When using +i3-save-tree+ with the +--workspace+ switch, only the *contents* of
241 the workspace will be dumped. This means that properties of the workspace
242 itself will be lost.
243
244 This is relevant for, e.g., a vertically split container as the base container of
245 a workspace. Since the split mode is a property of the workspace, it will not be
246 stored. In this case, you will have to manually wrap your layout in such a
247 container:
248
249 --------------------------------------------------------------------------------
250 // vim:ts=4:sw=4:et
251 {
252 // this is a manually added container to restore the vertical split
253 "layout": "splitv",
254 "percent": 0.5,
255 "type": "con",
256 "nodes": [
257
258 // the dumped workspace layout goes here
259
260 ]
261 }
262 --------------------------------------------------------------------------------
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 The multi-monitor situation
1 ===========================
2 Michael Stapelberg <[email protected]>
3 April 2013
4
5 Please upgrade your nVidia driver to version 302.17 or newer and i3 will just
6 work. This document is kept around for historic reasons only.
7
8 == The quick fix
9
10 If you are using the nVidia binary graphics driver (also known as 'blob')
11 before version 302.17, you need to use the +--force-xinerama+ flag (in your
12 .xsession) when starting i3, like so:
13
14 .Example:
15 ----------------------------------------------
16 exec i3 --force-xinerama -V >>~/.i3/i3log 2>&1
17 ----------------------------------------------
18
19 …or use +force_xinerama yes+ in your configuration file.
20
21 == The explanation
22
23 Starting with version 3.ε, i3 uses the RandR (Rotate and Resize) API instead
24 of Xinerama. The reason for this, is that RandR provides more information
25 about your outputs and connected screens than Xinerama does. To be specific,
26 the code which handled on-the-fly screen reconfiguration (meaning without
27 restarting the X server) was a very messy heuristic and most of the time did
28 not work correctly -- that is just not possible with the little information
29 Xinerama offers (just a list of screen resolutions, no identifiers for the
30 screens or any additional information). Xinerama simply was not designed
31 for dynamic configuration.
32
33 So RandR came along, as a more powerful alternative (RandR 1.2 to be specific).
34 It offers all of Xinerama’s possibilities and lots more. Using the RandR API
35 made our code much more robust and clean. Also, you can now reliably assign
36 workspaces to output names instead of some rather unreliable screen identifier
37 (position inside the list of screens, which could change, and so on…).
38
39 As RandR has been around for about three years as of this writing, it seemed
40 like a very good idea to us, and it still is a very good one. What we did not
41 expect, however, was the nVidia binary driver. It still does not support RandR
42 (as of March 2010), even though nVidia has announced that it will support RandR
43 eventually. What does this mean for you, if you are stuck with the binary
44 driver for some reason (say the free drivers don’t work with your card)? First
45 of all, you are stuck with TwinView and cannot use +xrandr+. While this ruins
46 the user experience, the more grave problem is that the nVidia driver not only
47 does not support dynamic configuration using RandR, it also does not expose
48 correct multi-monitor information via the RandR API. So, in some setups, i3
49 will not find any screens; in others, it will find one large screen which
50 actually contains both of your physical screens (but it will not know that
51 these are two screens).
52
53 For this very reason, we decided to implement the following workaround: As
54 long as the nVidia driver does not support RandR, an option called
55 +--force-xinerama+ is available in i3 (alternatively, you can use the
56 +force_xinerama+ configuration file directive). This option gets the list of
57 screens *once* when starting, and never updates it. As the nVidia driver cannot
58 do dynamic configuration anyways, this is not a big deal.
59
60 Also note that your output names are not descriptive (like +HDMI1+) when using
61 Xinerama, instead they are counted up, starting at 0: +xinerama-0+, +xinerama-1+, …
62
63 == See also
64
65 For more information on how to use multi-monitor setups, see the i3 User’s
66 Guide.
0 <!DOCTYPE html>
1 <html>
2 <head>
3 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
4 <title>i3 Reference Card</title>
5 <link rel="stylesheet" href="refcard_style.css" />
6 <style type="text/css">
7 * { margin: 0; padding: 0; vertical-align: middle; }
8 html { font-family: LinuxLibertine, Linux Libertine O, Linux Libertine, serif; font-size: 15px; /* column-count: 3; column-gap: 10px; -moz-column-count: 3; -moz-column-gap: 10px; -webkit-column-count: 3; -webkit-column-gap: 10px; */ }
9 body > div { display: inline-block; width: 33%; margin: 0.25%; vertical-align: top; }
10 body > div:first-child { margin-left: 0; }
11 body > div:last-child { margin-right: 0; }
12 #logo { float: left; width: 40px; margin: 7px; }
13 header { font-size: 1.1em; text-align: center; }
14 h1 { font-size: 1.1em; }
15 header a { font-size: 0.7em; }
16 header p { margin: 5px 0; font-size: 0.8em; text-align: left; }
17 kbd { font-family: LinuxBiolinumKeyboard, Linux Biolinum Keyboard O, Linux Biolinum Keyboard, DejaVu Sans Mono, monospace; font-size: 0.9em; }
18 code { font-family: DejaVu Sans Mono, monospace; font-size: 0.8em; }
19 section { break-inside: avoid-column; -moz-break-inside: -moz-avoid-column; -webkit-break-inside: avoid-column; }
20 h2 { margin: 7px 0 2px; padding: 2px 4px; font-size: 1.1em; font-family: LinuxBiolinum, Linux Biolinum O, Linux Biolinum, sans; background-color: #b3b3b3; }
21 table { width: 100%; }
22 .i3mod { width: 15px; }
23 td:last-child { text-align: right; }
24 .ref { font-size: 0.8em; }
25 #copyright { margin: 20px 0 15px; font-size: 0.7em; text-align: center; }
26 #licence { max-width: 70%; margin: 3px auto; font-size: 0.6em; text-align: right; }
27 </style>
28 <style type="text/css" media="print">
29 html { font-size: 13px; }
30 </style>
31 </head>
32 <body><div>
33 <header>
34 <img id="logo" src="logo-30.png" alt="" />
35 <h1>i3 Reference Card</h1>
36 <a href="https://i3wm.org/docs/userguide.html">https://i3wm.org/docs/userguide.html</a>
37 <p>
38 Throughout this guide, the i3 logo will be used to refer to the configured modifier.
39 This is the <kbd></kbd> key (<code>Mod1</code>) by default,
40 with super/<kbd></kbd> (<code>Mod4</code>) being a popular alternative.
41 </p>
42 </header>
43
44
45 <section>
46 <h2>Basics</h2>
47 <table>
48 <tr>
49 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd></kbd>
50 <td>open new terminal
51 <tr>
52 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd>j</kbd>
53 <td>focus left
54
55 <tr>
56 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd>k</kbd>
57 <td>focus down
58
59 <tr>
60 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd>l</kbd>
61 <td>focus up
62
63 <tr>
64 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd>;</kbd>
65 <td>focus right
66 <tr>
67 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd></kbd>
68 <td>toggle focus mode
69 </table>
70 </section>
71
72 <section>
73 <h2>Moving windows</h2>
74 <table>
75 <tr>
76 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd></kbd> + <kbd>j</kbd>
77 <td>move window left
78 <tr>
79 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd></kbd> + <kbd>k</kbd>
80 <td>move window down
81 <tr>
82 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd></kbd> + <kbd>l</kbd>
83 <td>move window up
84 <tr>
85 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd></kbd> + <kbd>;</kbd>
86 <td>move window right
87 </table>
88 </section>
89
90 </div><div>
91
92 <section>
93 <h2>Modifying windows</h2>
94 <table>
95 <tr>
96 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd>f</kbd>
97 <td>toggle fullscreen
98 <tr>
99 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd>v</kbd>
100 <td>split a window vertically
101 <tr>
102 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd>h</kbd>
103 <td>split a window horizontally
104 <tr>
105 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd>r</kbd>
106 <td>resize mode
107 </table>
108 <p class="ref">Look at the “Resizing containers / windows” section of the user guide.</p>
109 </section>
110
111 <section>
112 <h2>Changing the container layout</h2>
113 <table>
114 <tr>
115 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd>e</kbd>
116 <td>default
117
118 <tr>
119 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd>s</kbd>
120 <td>stacking
121
122 <tr>
123 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd>w</kbd>
124 <td>tabbed
125 </table>
126 </section>
127
128 <section>
129 <h2>Floating</h2>
130 <table>
131 <tr>
132 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd></kbd> + <kbd></kbd>
133 <td>toggle floating
134 <tr>
135 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd></kbd>
136 <td>drag floating
137 </table>
138 </section>
139
140
141 <section>
142 <h2>Using workspaces</h2>
143 <table>
144 <tr>
145 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd>0</kbd>-<kbd>9</kbd>
146 <td>switch to another workspace
147 <tr>
148 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd></kbd> + <kbd>0</kbd>-<kbd>9</kbd>
149 <td>move a window to another workspace
150 </table>
151 </section>
152
153 </div><div>
154
155 <section>
156 <h2>Opening applications / Closing windows</h2>
157 <table>
158 <tr>
159 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd>d</kbd>
160 <td>open application launcher (dmenu)
161 <tr>
162 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd></kbd> + <kbd>q</kbd>
163 <td>kill a window
164 </table>
165 </section>
166
167 <section>
168 <h2>Restart / Exit</h2>
169 <table>
170 <tr>
171 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd></kbd> + <kbd>c</kbd>
172 <td>reload the configuration file
173 <tr>
174 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd></kbd> + <kbd>r</kbd>
175 <td>restart i3 inplace
176
177 <tr>
178 <td><img class="i3mod" src="logo-30.png" alt="" /> + <kbd></kbd> + <kbd>e</kbd>
179 <td>exit i3
180 </section>
181 </table>
182
183
184 <!-- footer -->
185 <p id="copyright">
186 Copyright © 2012, Michael Stapelberg
187 <br />
188 All rights reserved
189 <br />
190 Designed by Zeus Panchenko, updated by Moritz Bandemer
191 </p>
192 <p id="licence">
193 Permission is granted to copy, distribute and/or modify this document provided
194 the copyright notice and this permission notice are preserved on all copies.
195 </p>
196 </div></body>
197 </html>
0 /* Generated by Font Squirrel (http://www.fontsquirrel.com) on April 12, 2012 */
1
2
3
4 @font-face {
5 /* This declaration targets Internet Explorer */
6 font-family: 'LinuxLibertine';
7 src: url('linlibertine_r-webfont.eot');
8 }
9
10 @font-face {
11 /* This declaration targets everything else */
12 font-family: 'LinuxLibertine';
13 src: url(//:) format('no404'), url(data:font/woff;charset=utf-8;base64,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) format('woff'), url(data:font/truetype;charset=utf-8;base64,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AGUAcgAgAFQAZQByAG0AcwAgAG8AZgAgAGYAbwBsAGwAbwB3AGkAbgBnACAARgByAGUAZQAgAFMAbwBmAHQAdwBhAHIAZQAgAEwAaQBjAGUAbgBzAGUAcwA6AAoARwBQAEwAIAAoAEcAZQBuAGUAcgBhAGwAIABQAHUAYgBsAGkAYwAgAEwAaQBjAGUAbgBzAGUAKQAgAHcAaQB0AGgAIABmAG8AbgB0AC0AZQB4AGMAZQBwAHQAaQBvAG4AIABhAG4AZAAgAE8ARgBMACAAKABPAHAAZQBuACAARgBvAG4AdAAgAEwAaQBjAGUAbgBzAGUAKQAuAAoAQwByAGUAYQB0AGUAZAAgAHcAaQB0AGgAIABGAG8AbgB0AEYAbwByAGcAZQAgACgAaAB0AHQAcAA6AC8ALwBmAG8AbgB0AGYAbwByAGcAZQAuAHMAZgAuAG4AZQB0ACkACgBTAGUAcAB0ACAAMgAwADAAMwAsACAAMgAwADAANAAsACAAMgAwADAANQAsACAAMgAwADAANgAsACAAMgAwADAANwAsACAAMgAwADAAOAAsACAAMgAwADAAOQAsACAAMgAwADEAMAAsACAAMgAwADEAMQBMAGkAbgB1AHgAIABMAGkAYgBlAHIAdABpAG4AZQBSAGUAZwB1AGwAYQByAHcAZQBiAGYAbwBuAHQATABpAG4AdQB4ACAATABpAGIAZQByAHQAaQBuAGUAIABSAGUAZwB1AGwAYQByAFYAZQByAHMAaQBvAG4AIAA1AC4AMQAuADMAIABMAGkAbgBMAGkAYgBlAHIAdABpAG4AZQBUAGgAaQBzACAAZgBvAG4AdAAgAHcAYQBzACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIAB0AGgAZQAgAEYAbwBuAHQAIABTAHEAdQBpAHIAcgBlAGwAIABHAGUAbgBlAHIAYQB0AG8AcgAuAAAAAgAAAAAAAP8PAFEAAAAAAAAAAAAAAAAAAAAAAAAAAAB6AAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQA+AD8AQABBAEIAQwBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0AXgBfAGAAYQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERALIAswESARMBFAEVARYBFwd1bmkwMEEwB3VuaTAwQUQHdW5pMjAwMAd1bmkyMDAxB3VuaTIwMDIHdW5pMjAwMwd1bmkyMDA0B3VuaTIwMDUHdW5pMjAwNgd1bmkyMDA3B3VuaTIwMDgHdW5pMjAwOQd1bmkyMDBBB3VuaTIwMTAHdW5pMjAxMQpmaWd1cmVkYXNoB3VuaTIwMkYHdW5pMjA1Rgd1bmlFMDAwB3VuaUUxMzgHdW5pRTE4OAd1bmlFMTg5AAAAuAH/hbABjQBLsAhQWLEBAY5ZsUYGK1ghsBBZS7AUUlghsIBZHbAGK1xYALAEIEWwAytEsAUgRbIEZwIrsAMrRAGwBiBFsAMrRLAHIEWyBmQCK7EDRnYrRLAIIEW6AAZ//wACK7EDRnYrRFmwFCsAAA==) format('truetype'), url('linlibertine_r-webfont.svg#LinuxLibertineRegular') format('svg');
14 font-weight: normal;
15 font-style: normal;
16 }
17
18 @font-face {
19 /* This declaration targets Internet Explorer */
20 font-family: 'LinuxBiolinumKeyboard';
21 src: url('linbiolinum_k-webfont.eot');
22 }
23
24 @font-face {
25 /* This declaration targets everything else */
26 font-family: 'LinuxBiolinumKeyboard';
27 src: url(//:) format('no404'), url(data:font/woff;charset=utf-8;base64,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) format('woff'), url(data:font/truetype;charset=utf-8;base64,AAEAAAASAQAABAAgRkZUTWDiM/IAAAEsAAAAHEdERUYExgQ+AAABSAAAAFhHUE9TROkiwQAAAaAAAAXaR1NVQpM8gksAAAd8AAAAUE9TLzJRXqYxAAAHzAAAAFZjbWFwmufhUwAACCQAAAHKY3Z0IATeBToAAAnwAAAAIGZwZ20PtC+nAAAKEAAAAmVnYXNwAAAAEAAADHgAAAAIZ2x5Zla+OecAAAyAAAEnwGhlYWQUeKd1AAE0QAAAADZoaGVhI/cdTAABNHgAAAAkaG10eGkLmqUAATScAAAC0GxvY2Fue7WgAAE3bAAAAXhtYXhwAeYHFwABOOQAAAAgbmFtZVsEa0sAATkEAAADvnBvc3Sv4ffyAAE8xAAABFNwcmVwyCV/bAABQRgAAABuAAAAAQAAAADJiW8xAAAAAMusYlwAAAAAy6xiZAABAAAADgAAAEgAUAAAAAIACQABABEAAQASABIAAgATAIEAAQCCAJoAAgCbAJsAAQCcAJ4AAgCfAJ8AAQCgAKcAAgCoALoAAQAEAAAAAgAAAAEAAAABAAAAAQAAAAoAgACaAARERkxUABpjeXJsAChncmVrADZsYXRuAEQABAAAAAD//wACAAAAAQAEAAAAAP//AAIAAAABAAQAAAAA//8AAgAAAAEAKAAGQVpFIAAoQ1JUIAAoREVVIAAoTU9MIAAoUk9NIAAoVFJLIAAoAAD//wACAAAAAQACY3BzcAAOa2VybgAUAAAAAQAAAAAAAQABAAIABgAOAAEAAAABABAAAgAAAAEAHAABAAoABQAEAAgAAgABACQAPQAAAAIEtgAEAAADMAP0ABQAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2ALYAtgAtAAAAAACHAAAAAAAAAAAAAABzAEYAAACHAAAAAAAAAAAALQAtAC3/9v+m/8EAAP+m/4v/i/+m/6YAAAAA/5EAAABGAC3/uAAAAC0ALQAt/7r/rv/TAAD/jf+u/43/pv+mAAAAAP+mAAAALQAt/7gAAAAtAC0ALf/B/6b/0wAA/zH/XP+m/67/uAAAAAD/pgAAAC0ALf/TAAAAAAAtAC3/0/+cAAAAAAAAAAD/2//jAAAAAAAA/9MAAAAtAEYAAAAA//b/wf/TAAoAEgASAAD/y//LAAoACgAA/+4AAAAAAAAAAAAAAAAAAP+4/+z/0wASAB0AEgAA/6b/kf/2AAAABP/fAAAAAAAAAAAAAAAEAAAAAP/s/9MAAAAAABIAAAAAAAD/4//2AAAAAAAAAAAAAAAAAAAAAAAA/8v/uv+uAAD/9v/2/9v/2//bAAoAAAAA//YAAAAAAAAAAAAAAAAAAP+m/5z/nAAA//L/8v/T/+7/7gAOAAoAAP/2AAAAAAAAAAAAAAAAAAAAAP+mAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4v/ef8x/8H/wQAA/3kAAAAA/+z/7AAA/+wAAP+6AAD/kQAA/8EAAP+N/3n/ef/uAAAAAP8fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/pv+m/6YAAAAAAAAAAP+6AAAAAAAAAAD/7gAAAAAAAAAAAAAAAAAAAAAAAAAA/+7/3wAAAAD/0wAA/9//7AAAAAAAh/+6ABQAFAAUAAAAAABGAC0ALQAAAAAAAAAA/5H/0wAAAAAAAAAAAAAAAAAAAC0ALQAAAAAARgAtAC0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtAC0AAAAAAAAAAAAtAAAAAAAAAC3/kf/TAAAAAAAAAAoAAAAAABQAWgA1AAAAAAAAAAAAAAAAAAAAAAAA/6b/pv/TAAAAAAAAAAAAAAAAAAAAAAAAAAEAAwBfAA0AAAATAAAAAAAAAAAAEwAPAAAAEwAOAA0ADgANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAOAA4AAAAGAAwAAAAAAAYAAAASAAAAEQARAAAABQALAAAAEQAGABIABgAAAAAAAgAQAAQABAAFAAMAAAAPAAAAAAAAAA0AAAAAAAkAAAAAAAoAAQAIAAAAAAAAAAgAAAAAAAAACgAKAAAABwAAAAAAAAAHAAcACAAHAAAADwAAAAAADgABAAQAXgAQAAcAAAAAAAAAAAAHAAAADQAHAA8ACQAPAAkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPAA8ADwAQAAAACAASAAQAEgASABIABAASABIADgASABIAAAASAAQAEgAEABIAAAABABEAAwADAAAAAgAAAAAAAAANAAAAAAAAAAsAEAAKAAsACgAAAAwAEAAAAA4AEAAQAAwADAAKAAwACgAMAAwAAAATAAUABQAGAAYADAAAAAAADQAPAAEALgADAAUACgALAA0ADgAPABAAEQAfACAAIQAjACQAJwApACsALAAuAC8AMQAyADMANAA3ADgAOQA6ADsAPAA+AEIARQBIAEkASgBOAFIAUwBVAFkAWgBbAFwAXgBhAAAAAQAAAAoATABOAARERkxUABpjeXJsACRncmVrAC5sYXRuADgABAAAAAD//wAAAAQAAAAA//8AAAAEAAAAAP//AAAABAAAAAD//wAAAAAAAAABB6sCvAAFAAAFMwWZAAABHgUzBZkAAAPXAGYCEggPAgAFAwAAAAAAAAAACOcQAOGgAAAAIAAAAABQZkVkACAAIOGuBmb+ZgAABgkCGkAAAbsAAAAAAAAAAAADAAAAAwAAABwAAQAAAAAAxAADAAEAAAAcAAQAqAAAACYAIAAEAAYAfgCgAK0gCiAUIC8gX+AA4TXhOuE94WjhbuGM4Y7hluGb4a7//wAAACAAoACtIAAgECAvIF/gAOEx4TjhPOFo4W7hcOGO4ZDhmOGg////4//C/7bgZOBf4EXgFiB2H0YfRB9DHxkfFB8THxIfER8QHwwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBgAAAQAAAAAAAAABAgAAAAIAAAAAAAAAAAAAAAAAAAABAAADBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGIAAAAAAHJzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmwBKAMUASQDFAG4AZgBWALcAaABOAWIBVgG9AFSwACywABNLsCpQWLBKdlmwACM/GLAGK1g9WUuwKlBYfVkg1LABEy4YLbABLCDasAwrLbACLEtSWEUjWSEtsAMsaRggsEBQWCGwQFktsAQssAYrWCEjIXpY3RvNWRtLUlhY/RvtWRsjIbAFK1iwRnZZWN0bzVlZWRgtsAUsDVxaLbAGLLEiAYhQWLAgiFxcG7AAWS2wByyxJAGIUFiwQIhcXBuwAFktsAgsEhEgOS8tsAksIH2wBitYxBvNWSCwAyVJIyCwBCZKsABQWIplimEgsABQWDgbISFZG4qKYSCwAFJYOBshIVlZGC2wCiywBitYIRAbECFZLbALLCDSsAwrLbAMLCAvsAcrXFggIEcjRmFqIFggZGI4GyEhWRshWS2wDSwSESAgOS8giiBHikZhI4ogiiNKsABQWCOwAFJYsEA4GyFZGyOwAFBYsEBlOBshWVktsA4ssAYrWD3WGCEhGyDWiktSWCCKI0kgsABVWDgbISFZGyEhWVktsA8sIyDWIC+wBytcWCMgWEtTGyGwAVlYirAEJkkjiiMgikmKI2E4GyEhISFZGyEhISEhWS2wECwg2rASKy2wESwg0rASKy2wEiwgL7AHK1xYICBHI0ZhaoogRyNGI2FqYCBYIGRiOBshIVkbISFZLbATLCCKIIqHILADJUpkI4oHsCBQWDwbwFktsBQsswBAAUBCQgFLuBAAYwBLuBAAYyCKIIpVWCCKIIpSWCNiILAAI0IbYiCwASNCWSCwQFJYsgAgAENjQrIBIAFDY0KwIGOwGWUcIVkbISFZLbAVLLABQ2MjsABDYyMtAAAAAAEAAf//AA8ABQB/ALIDgQTjAAMABgAJAAwADwB4ALAAL7EHAumwCS+0CwEASQQrsAovsQEC6QGwEC+wANaxBATpsAQQsQUBK7QNBAAuBCuwDRCxDgErsQME6bERASuxBQQRErEHCjk5sA0RsQkLOTmwDhKxDAg5OQCxCQcRErEEDjk5sAsRsQUNOTmwChKxBg85OTAxNxEhESUJARMhCQMDARF/AwL9TAEG/votAgz++v76AQYBBtkBBrIEMfvPkgGHAYf8rgGFAg7+fQGD/jj+eQMOAAAAAAQA9v5OCAAGCAAPAB0AKgA/AFsAsA0vsRIB6bAoL7QhAQAsBCuwGi+xBALpAbBAL7AA1rEQBOmwEBCxHgErsCsysSUD6bAxMrAlELEWASuxCQPpsUEBK7ElHhESsS4zOTkAsRohERKxLjg5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATU2NzMWFxUGByMuAQM0NjMyFhUUBgcGBwYjIjU0JicuAfaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwKzG0MERhgdQQQpKQQ5IyU5JQYEFgQVFxIIBiWsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7pAZCGhtBBkwQCCkDXjc4OjU5wy0Z/x8UCNNIMbsAAAAEAPb+TggABggADwAdACkANQCYALANL7ESAemwJi+yKDI0MzMztCEBAA0EK7AtMrAaL7EEAukBsDYvsADWsRAE6bAQELEeASu0JQMALwQrsyglHggrtCYEAKIEK7AlELEqASu0MQMALwQrszQxKggrtDIEAL4EK7AxELEWASuxCQPpsTcBK7EmKBESsCE5sTI0ERKwLTkAsSYSERKxJzM5ObAhEbEeKjk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUFNDYzMh4BFQMHJyY3NDYzMh4BFQMHJyb2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCODUvHx8GOCkWMek2Lx8eBjcpFzGsBax/iYOF+lSNeX3Iqk5cBW2+YlzLHzUSFRL+6woG9gofNRIVEv7rCgb2AAAABAD2/k4IAAYIAA8AHQBCAEcCEgCwDS+xEgHpsB4vszY8PUIkFzO0HwIAYAQrsTNEMjKyHh8KK7NAHkEJK7E6OzIysCMvsyIyRUYkFzO0JAIAXQQrsyUpKi8kFzKyJCMKK7NAJCgJK7InLS4yMjKwGi+xBALpAbBIL7AA1rEQBOmwEBCxQQErtEAEACYEK7BAELEnASu0KAQAJgQrsCgQsS0BK7QuBAAoBCuwLhCxFgErsQkD6bFJASuwNhq6P3r32AAVKwqwJxCwQsAOsCgQsD/Auj9F9lwAFSsKBbAtELA7wLAuELA6wLBCELMiQicTK7MlQicTK7A/ELMpPygTK7A7ELMqOy0TK7o/PPYjABUrC7MrOy0TK7MsOy0TKwWwOhCzLzouEyuzMjouEyuzMzouEyuzNjouEyu6Pzb1/gAVKwuzNzouEyuzODouEyuzOTouEysFsDsQszw7LRMrsD8Qsz0/KBMruj8z9ecAFSsLsz4/KBMrBbA7ELNEOy0TK7NFOy0TK7A/ELNGPygTK7I+PyggiiCKIwYOERI5sis7LRESObAsObI4Oi4REjmwOTmwNzkAtissNzg5Pj8uLi4uLi4uAUAXIiUpKi8yMzY6Ozw9QkRFRissNzg5Pj8uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLrBAGgGxQRARErMeHyMkJBc5sEARsCA5sSgnERKwQzmxFi4RErMwMTQ1JBc5ADAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATczNjcjNzM2NzMDMz4BNzMDMwcjBzMHIw4CByMTIw4BByMTNzM3Iwb2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMByw2JEgaJDooUFW4tbwYbCGgnlA2VGZYMlgQSDwZmKW8GGwhtJ3tvGGwKrAWsf4mDhfpUjXl9yKpOXAVtvmJc/IFWXDxYe4X/ACeuK/8AWJhWHWpWJQECJbAtAQJWmEIAAAAABQD2/k4IAAYIAA8AHQBOAFMAWQDCALJIAAArsA0vsRIB6bBKL7BGM7EkAumwVDKwUi+wPTOxLQLpsDAysi1SCiuzQC0uCSuwGi+xBALpAbBaL7AA1rEQBOmwEBCxKgErtE8DACUEK7BPELFIASuyJC1RMjIysUcE6bIvPVQyMjKwRxCxVgErtEMDAC8EK7BDELEWASuxCQPpsVsBK7EqEBESsR5OOTmwTxGxICE5ObFDVhESsTo3OTkAsSRKERKwHjmwUhG1ICo5Q1FZJBc5sC0SsDc5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNjczHgEXES4DNTQ2NzUzFR4DHwIGByMuAScRHgMVFAYHFSM1IyImLwETBhcRBhM2NTQmJ/aLfQTRj6Jth/ryi31JvwSTXE6q+21cYwHmEggNHJJDN05bMKNtQipNMicJCAQSCA8ZZzw4S2I0o3ZCBESIIyOmAXFxs202N6wFrH+Jg4X6VI15fciqTlwFbb5iXPukSlg7XgMBThYnQFMyYnYLVlQBDhEQBgUEPWM4Vgv+0xUjPlc1ZIwScmwfDxACfWM1ARUQ/SYYcUZFGQAGAPb+TggABggADwAdADUAQABLAFYA9gCwDS+xEgHpsEkvsCkztE8CAEUEK7BUL7REAgBFBCuwNC+0OQIAKgQrsC0vsSUC6bA+L7QhAgBFBCuwGi+xBALpAbBXL7AA1rEQBOmwEBCxHgErtDYEACcEK7A2ELE8ASuxMQTpsDEQsUEBK7RMBAAnBCuwTBCxUgErtEYEAKIEK7BGELEWASuxCQPpsVgBK7E2HhESsCo5sDwRsik0ITk5ObAxErAjObBBEbElLTk5sVJMERK0JyhESSskFzkAsU9JERKwKjmwVBGxRkE5ObEtORESsx4xNjwkFzmwJRGxKy85ObEhPhESsSMoOTmwGhGwJzkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE0NjMyFxYzMjcXAScBBiMiJxYVFAYjIjcUFjMyNjU0IyIGATQ2MzIVFAYjIiY3FBYzMjY1NCMiBvaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwGCdlxMG1JSoEdI/YlUAjNcSjk5BHdei2odFDNQOzVEAYNxYo1yWkZOaR4XN0w+L0usBax/iYOF+lSNeX3Iqk5cBW2+Ylz902SQHydOIfyeEgMCJSEMFWimkSs1lElWif3oYpGLdZ1eNSs1k0hYjQAFAPb+TggABggADwAdAE0AWABjALMAsA0vsRIB6bBLL7BGM7RRAgBhBCu0PwIAQgQrsGEvtCYCAH0EK7AaL7EEAukBsGQvsADWsRAE6bAQELEeASuxTgPpsE4QsSMBK7RZAwAaBCuwWRCxXwErsFQytCkDABoEK7A3MrApELEWASuxCQPpsWUBK7FZIxESsyFLUVYkFzmwXxGxJiw5ObApErEuSTk5sBYRszA0Q0YkFzkAsWE/ERJACh4jKUJDSU5UVlskFzkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE0NjcmNTQ2MzIWFRQGBxYXNjcWFzI3BgIHHgYzMjY3Fw4BIyImJwYjIiY3FBYzMjY3JicOARMUFz4CNTQjIgb2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBUn2qXpZ6anJ/ZSl/cRIQREgOF8YSBhgPFhMUFQojLxoyMVk7OVA1fZ6TrbVaPT9jNbQnVD+uPystK1wrO6wFrH+Jg4X6VI15fciqTlwFbb5iXPw7WJBikV9MgV1YOYk6S7CwpgQBBSX+mxwKKhgjFBUKIzUjWjk3UId2nmB1P0z2PjVrAdVGWCMlPx2DRQAAAAMA9v5OCAAGCAAPAB0AKQBZALANL7ESAemwGi+xBALpAbAqL7AA1rEQBOmwEBCxHgErtCUDAC8EK7MoJR4IK7QmBAC+BCuwJRCxFgErsQkD6bErASuxJigRErAhOQCxGhIRErEhJzk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUFNDYzMh4BFQMHJyb2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCojYvHx4GNykXMawFrH+Jg4X6VI15fciqTlwFbb5iXMsfNRIVEv7rCgb2AAMA9v5OCAAGCAAPAB0AKgBOALANL7ESAemwGi+xBALpAbArL7AA1rEQBOmwEBCxHgErsSQD6bAkELEWASuxCQPpsSwBK7EWJBESsyEiJickFzkAsRoSERKxISc5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATQSNxcGERAXByYCJvaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwJA0ZEx2dkxh6oxrAWsf4mDhfpUjXl9yKpOXAVtvmJc/QS6AYR8K/T+Zf5o+yl1ASbNAAAAAAMA9v5OCAAGCAAPAB0AKgBOALANL7ESAemwGi+xBALpAbArL7AA1rEQBOmwEBCxIAErsSYD6bAmELEWASuxCQPpsSwBK7EgEBESsx4iIyokFzkAsRoSERKxIyo5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATYRECc3FhIVFAYCB/aLfQTRj6Jth/ryi31JvwSTXE6q+21cYwJ72dkykdExqoesBax/iYOF+lSNeX3Iqk5cBW2+Ylz6cfwBlwGc8yt9/n26VM3+2XQAAwD2/k4IAAYIAA8AHQBTAJQAsA0vsRIB6bBRL7A3M7QhAgAnBCuwMjKwGi+xBALpAbBUL7AA1rEQBOmwEBCxJwErtCwEACIEK7AsELEWASuxCQPpsVUBK7EnEBEStB4hSEtRJBc5sCwRtyMkLzlDRk5PJBc5sBYStTI1Nzs9QCQXOQCxURIRErFAUjk5sCERtB4kLi81JBc5sBoSsicpLDk5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATQ2MzIWFy4BNTQ2MhYVFAYHPgEzMhYVFAciBx4CFRQGIyIuAScOAiMiJjU0PgE3JiMGJvaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwIyGhkdWBwEKyUtJyUCIU4aHx1rNxsSSCkgESMiHQwMFSEpEhsnRhI7AjNKrAWsf4mDhfpUjXl9yKpOXAVtvmJc/scSH0QMIVgSGSUfGRRnFgxIIxI9AQQUJScjEhsvWBUXWisZEiUnJBcGDhkAAAAAAwD2/k4IAAYIAA8AHQApAHwAsA0vsRIB6bAeL7AlM7QfAgAkBCuwIzKyHh8KK7NAHigJK7IfHgors0AfIQkrsBovsQQC6QGwKi+wANaxEATpsBAQsSgBK7AgMrQnBAAkBCuwIjKyJygKK7NAJyUJK7IoJwors0AoHgkrsCcQsRYBK7EJA+mxKwErADAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATUhNTMVIRUhFSM19ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAdUBB3IBBv76cqwFrH+Jg4X6VI15fciqTlwFbb5iXPyicvz8cvr6AAADAPb+TggABggADwAdADAAYgCyIwAAK7QpAQA7BCuwDS+xEgHpsBovsQQC6QGwMS+wANaxEATpsBAQsSEBK7EsBOmyISwKK7NAISYJK7AsELEWASuxCQPpsTIBK7EhEBESsjAqLzk5OQCxIxIRErAvOTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVAT4BNTQjLgEnNTY3MxYHFAYHJvaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwKmPVMxKSgKGUIIbQF5URKsBax/iYOF+lSNeX3Iqk5cBW2+Ylz6PxBZHy0IHycIPxsph1R7Dg4AAwD2/k4IAAYIAA8AHQApAEAAsA0vsRIB6bAoL7QhAgAlBCuwGi+xBALpAbAqL7AA1rEQBOmwEBCxFgErsQkD6bErASuxFhARErEeIzk5ADAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATQ2MyEyBxQGIyEi9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAhUbDAGeFwEdDv5pGawFrH+Jg4X6VI15fciqTlwFbb5iXPz2FEAhED4AAAAAAwD2/k4IAAYIAA8AHQAqAEEAsA0vsRIB6bAoL7QhAQAsBCuwGi+xBALpAbArL7AA1rEQBOmwEBCxHgErsSUD6bAlELEWASuxCQPpsSwBKwAwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE1NjczFhcVBgcjLgH2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCbxtDBEYZHUIEKSmsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7ogZCGhtBBkwQCCkAAAMA9v5OCAAGCAAPAB0AIQBAALANL7ESAemwGi+xBALpAbAiL7AA1rEQBOmwEBCxFgErsQkD6bEjASuxFhARErEeIDk5ALEaEhESsR4fOTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQkBMwH2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCIQFtXP6TrAWsf4mDhfpUjXl9yKpOXAVtvmJc+zsEPPvEAAAABAD2/k4IAAYIAA8AHQApADcAagCwDS+xEgHpsCcvtCwCAH0EK7AzL7QhAgCYBCuwGi+xBALpAbA4L7AA1rEQBOmwEBCxHgErsSoD6bAqELEuASuxJAPpsCQQsRYBK7EJA+mxOQErsS4qERKxJyE5OQCxMywRErEeJDk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNBIzMhYVFAYjIgI3EDMyEzQuAiMiDgL2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBtcSBg73BhZyjtI2PAQkYPi0fLC0ZrAWsf4mDhfpUjXl9yKpOXAVtvmJc/RTZAQv+1/jlAQq0/oMBuExve0EgVLcAAAADAPb+TggABggADwAdADMAigCwDS+xEgHpsDMvtB4CAH0EK7IeMwors0AeIAkrsBovsQQC6QGwNC+wANaxEATpsBAQsS4BK7ElA+myJS4KK7NAJSIJK7AlELEWASuxCQPpsTUBK7EuEBESsR4rOTmwJRGwKjmwFhKyICcoOTk5ALEzEhESsycoKiskFzmwHhGwMTmwGhKwIjkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2JTIXBgcRFBcHJiMHNTY1ETQnIgf2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMB/G0BEgoBEAETBDM4aBAdUlSsBax/iYOF+lSNeX3Iqk5cBW2+Ylz+hRlaBqRW/n2qdwQEBARivwF0ZAEKAAAAAAMA9v5OCAAGCAAPAB0ARQB7ALANL7ESAemwQi+xOgHpsCgvsTAC6bAaL7EEAukBsEYvsADWsRAE6bAQELElASuxMwPpsTxAMjKwMxCxFgErsQkD6bFHASuxJRARErUeLDA3OUIkFzmwMxGxNj45OQCxQhIRErAeObA6EbA+ObAoErQhKi0zPCQXOTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATQ2PwE+ATU0JiMiByMnNz4BMzIWFRQGDwEGBzMyNwYVFBcmIyIEI/aLfQTRj6Jth/ryi31JvwSTXE6q+21cYwGeWHtzPSFWLXdKJCEEI59MkbVEUJlmAX9qsQgIrFxE/wArrAWsf4mDhfpUjXl9yKpOXAVtvmJc+1Q/e39xP3NaQlqBeQYdN3l3UGhMk2AjDCk7HykGBgAAAAMA9v5OCAAGCAAPAB0ASwCQALANL7ESAemwSS+xJALpsC0vsS4C6bA0L7E9AumwGi+xBALpAbBML7AA1rEQBOmwEBCxKQErsUYD6bAxINYRsUAD6bIxQAors0AxLgkrsEYQsRYBK7EJA+mxTQErsTEQERK3HiQrOT1CQ0kkFzkAsS0kERKzHiApRiQXObAuEbFCRDk5sDQSsjc6QDk5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVAT8BHgIzMj4CNTQjIgc1PgE1NCYjIgYHLwE3PgEzMhYVFAcVHgEVFAYjIif2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBqiMlIxlFNxkxOiKoKRJvZEItTEkrJR8EI5xQd522XoPbnJFmrAWsf4mDhfpUjXl9yKpOXAVtvmJc+6B5AjsoJREnWD+yAkYGXmE7UjtMAnkGHTdeZbovBghxZ5OPVgAABAD2/k4IAAYIAA8AHQA/AEIAkwCwDS+xEgHpsDwvsDEztEACACkEK7ArMrAaL7EEAukBsEMvsADWsRAE6bAQELE7ASuwQTKxMgPpsCoysjI7CiuzQDIuCSuwMhCxFgErsQkD6bFEASuxOxARErQeITg5QCQXObAyEbIkIzc5OTmwFhKzJyg0NSQXOQCxPBIRErA1ObBAEbAgObAaErIhJEI5OTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE0NzYANzUWMzcXBgcRMzIVFAYrARQXByYjByc2NSEjIiY3IRH2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBXRBCAQRDEjpmBRABbxQcD1gRBS83aAIS/scNKB10AResBax/iYOF+lSNeX3Iqk5cBW2+Ylz8SjEWWAGQcwQEBAR7a/6UHxA2ZnsEBAQEhVwGXwG4AAADAPb+TggABggADwAdAEIAuQCwDS+xEgHpsEAvsSMC6bApL7Q6AgBEBCuwNS+wNzOxLwHpsC0ysBovsQQC6QGwQy+wANaxEATpsBAQsSYBK7E9A+mwPRCxFgErsQkD6bFEASuwNhq6P6r5bwAVKwqwLS4OsCzABbE3CPkOsDjAALEsOC4uAbMsLTc4Li4uLrBAGgGxJhARErMeNTpAJBc5sD0RsjEyMzk5OQCxKSMRErMeICs9JBc5sS81ERKwMzmwGhGxMTI5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVAT8BHgEzMjY1NCYjIgcnExYXMjcXBwYjIicHNjMyFhUUBiMiJ/aLfQTRj6Jth/ryi31JvwSTXE6q+21cYwGoHyUpUj87V05GTlggMYUnarALGVRqTGYXQkt9qL+PkWasBax/iYOF+lSNeX3Iqk5cBW2+Ylz7oHkCSkJtaGZ1JAoBzQoBEQSYCAzfGahzkapWAAAAAAQA9v5OCAAGCAAPAB0ANQBFAHwAsA0vsRIB6bAyL7E5AumwQi+xLALpsCQvtCMCAEUEK7AaL7EEAukBsEYvsADWsRAE6bAQELEeASuxNgPpsDYQsTwBK7EvA+mwLxCxFgErsQkD6bFHASuxPDYRErIsMio5OTmwLxGxIyQ5OQCxQjkRErAvObAsEbAqOTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATQ+AjMXDgQHNjMyFhUUBiMiJyY3FBYzMjY1NC4DIyIHBvaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwGeTI3wkQQrP3dSUBI9UqKPnZp3SZG6VEktRgIQHTooRjUErAWsf4mDhfpUjXl9yKpOXAVtvmJc/MdavqxtNwQLLUaNYCmkcW+xL1r0uIJraB8rQykhKyUAAwD2/k4IAAYIAA8AHQAwAFwAsA0vsRIB6bAvL7QmAQA8BCuwGi+xBALpAbAxL7AA1rEQBOmwEBCxFgErsQkD6bEyASuxFhARErEeKTk5ALEvEhESsh4rLDk5ObAmEbEhKTk5sBoSsSQoOTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE0NjU0JjUWBTI3FwIDByc2EyL2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMByQgIUAF7NS0Vz4uGBGvdk6wFrH+Jg4X6VI15fciqTlwFbb5iXP5SAkIODD4ECgENH/4M/mUHDfECIwAAAAUA9v5OCAAGCAAPAB0ANgBDAEwAqwCwDS+xEgHpsDUvtDoCAEUEK7BLL7QnAgBhBCuwGi+xBALpAbBNL7AA1rEQBOmwEBCxHgErtDcDAC8EK7A3ELBEINYRtCQDACUEK7AkL7REAwAlBCuwNxCxPQErtDEDADoEK7BJINYRtCoDACUEK7AxELEWASuxCQPpsU4BK7FENxESsDU5sEkRtSchOkEtSyQXObA9ErA0OQCxSzoRErUeJCoxQUckFzkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE0NjcnJjU0NjMyFhUUBgcXHgEVFAcGICY3FBYzMjY1NCYvAQ4BExQfATY1NCMi9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAblwbxuTj5B/i15jYT1Se1D+9rSsWDdKVDNISEIoKV4vVnNxrAWsf4mDhfpUjXl9yKpOXAVtvmJc/DNSeTkPWn9kdWlYSF4nPSl7P4lML31wUGJGZEJPKysvagHEVjsdQlqRAAAAAAQA9v5OCAAGCAAPAB0APQBQAIAAsA0vsRIB6bAtL7QuAgBFBCuwOC+xRALpsE4vsSUC6bAaL7EEAukBsFEvsADWsRAE6bAQELEfASuxPgPpsD4QsUgBK7EpA+mwKRCxFgErsQkD6bFSASuxPh8RErEtLjk5sEgRsiU4Njk5OQCxRDgRErA2ObBOEbIeHyk5OTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQA0PgQzMhcWFRQHBgUnPgY3BiMiLgM3FB4DMzI3NjU0LgMjIgb2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBsQ8fNENcNnhJkYKx/tkEHihSO003Mg09UzlfQTAbsQMPHTopRTYEEhwrKhstRqwFrH+Jg4X6VI15fciqTlwFbb5iXP21QUJBOSsZL1v3uqDVAjcDBRQcOElxRSkXKjU/aiAqRCkgKyUgTnRDKA1sAAAEAPb+TggABggADwAdACoANwBRALANL7ESAemwKC+0IQEAHwQrsDUvtC4BAB8EK7AaL7EEAukBsDgvsADWsRAE6bAQELEeASuwKzKxJQPpsDEysCUQsRYBK7EJA+mxOQErADAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATU2NzMWFxUGByMuAQM1NjczFhcVBgcjLgH2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCphtIBEoYHUUEKywMG0gEShgdRQQrLKwFrH+Jg4X6VI15fciqTlwFbb5iXPumBkYaG0UGUBAILQHdBkYaG0UGUBAILQAAAAAEAPb+TggABggADwAdADAAPAB6ALANL7ESAemwIy+0KQEALAQrsDsvtDQBAB8EK7AaL7EEAukBsD0vsADWsRAE6bAQELEmASuwMTKxLAPpsDcysCwQsSEE6bAhL7AsELEWASuxCQPpsT4BK7EmEBESsTAeOTmwIRGzKi81OiQXOQCxIxIRErEsLzk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBPgE1NCMuASc1NjczFhUUBgcmEzU2NzMWFxUGByMm9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAnc/WTMrKgoZRghzglMUFhtHBEoYHUUES6wFrH+Jg4X6VI15fciqTlwFbb5iXPqTElshLwghKQhEHC2NWIEPEALgBkYaG0UGUhAQAAAAAwD2/k4IAAYIAA8AHQAkAEAAsA0vsRIB6bAaL7EEAukBsCUvsADWsRAE6bAQELEWASuxCQPpsSYBK7EWEBESsR4gOTkAsRoSERKxICQ5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATUlFQ0BFfaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwGaApH+GQHnrAWsf4mDhfpUjXl9yKpOXAVtvmJc/MtB8mCys2AABAD2/k4IAAYIAA8AHQAhACUATQCwDS+xEgHpsB4vtB8CAGAEK7AiL7QjAgBgBCuwGi+xBALpAbAmL7AA1rEQBOmwEBCxFgErsQkD6bEnASuxFhARErMeICIkJBc5ADAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATUhFSU1IRX2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBwQKc/WQCnKwFrH+Jg4X6VI15fciqTlwFbb5iXPxSVla+VlYAAAMA9v5OCAAGCAAPAB0AJABAALANL7ESAemwGi+xBALpAbAlL7AA1rEQBOmwEBCxFgErsQkD6bEmASuxFhARErEeIzk5ALEaEhESsR4iOTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE1LQE1BRX2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMB7AHl/hsCkawFrH+Jg4X6VI15fciqTlwFbb5iXPvVYLKzYPJDAAQA9v5OCAAGCAAPAB0APgBLAJ4AsA0vsRIB6bBJL7RCAQAsBCuwOy+xIQLpsjshCiuzADsxCSuwGi+xBALpAbBML7AA1rEQBOmwEBCxMwErsS4E6bMQMz8OK7FGA+mwLhCxOQErtCQDAC8EK7AkELEWASuxCQPpsU0BK7E/EBESsh4fPTk5ObEuMxESsztCQ0gkFzmwRhGxITY5ObA5ErEqNzk5ALE7QhESsR89OTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE3NjMyFhUUDgQHBh0BFAYiJj0BNDc+ATU0IyIHJxM1NjczFhcVBgcjLgH2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCFQR3fXejFBkzGkAGXBkUGXUrFHttTxRkG0MERhgdQQQpKawFrH+Jg4X6VI15fciqTlwFbb5iXP7nB16BZx03Jy8WKwZEeTsIEREIPY1rJ0g/oo8C/TMGQhobQQZMEAgpAAQA9v5OCAAGCAAPAB0AVgBkAL8AsA0vsRIB6bBUL7RNAgBFBCuwJy+0PQIAYQQrsCwg1hG0WQIAmAQrsGEvtDQCAEUEK7BFL7QhAgBFBCuwGi+xBALpAbBlL7AA1rEQBOmwEBCxHgErtEgDABoEK7BIELExASu0VwMAGgQrsFcQsUABK7QkBAAgBCuwJBCxFgErsQkD6bFmASuxQFcREkAJIScsNEVNUVReJBc5ALEnTRESsU9ROTmxYVkRErYkMSo7QEg2JBc5sDQRsTc4OTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFRM0ACEgABUUBiMiJjUGIyIuAjU0NjMyFzcXAwYVFDMyNjU0LgIjIgAVFB4CMzI3FhcOASMgACUUMzI2NzY1NCYjIgcG9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjpgFtARsBAAFB6ZpIP0xWP1QlDeSJYDE4K1wTGz2kXJCZSMP+2jl1z4e0jRkIVqiD/u7+nQHuVilgHSstH0Q3YKwFrH+Jg4X6VI15fciqTlwFbb5iXPzd+AFv/t3dovo3IUgpRjcfouk7MxD+clgMF7WRecBtOf7Z/Fq0pGZzCCVCPwFDro1eWporJzc7ZgAABAD2/k4IAAYIAA8AHQA0AD4AfACwDS+xEgHpsC0vsTgC6bAaL7EEAukBsD8vsADWsRAE6bAQELEeASu0MQMAGgQrsDEQsSkBK7QlAwAjBCuwJRCxFgErsQkD6bFAASuxKTERErMhIDU7JBc5sCURsCM5ALEtEhESsR4lOTmwOBGwIzmwGhKyICE9OTk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBEhMzFhoBFyYjIgcmJyYjIgcGByYjIgEyFjMyNjcmJwL2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBD93nbTW/jyEbYlIbI09lM1txWiASM0QBJxZyGBlDJD5Pb6wFrH+Jg4X6VI15fciqTlwFbb5iXPtQAd8CF3/+Kf6jQwQEgNUDBN52BAGoBAEBorX/AAAAAAAFAPb+TggABggADwAdADgAQwBOAKgAsA0vsRIB6bA0L7E8AumwQy+xRALpsEsvsSkC6bAaL7EEAukBsE8vsADWsRAE6bAQELEgASuxOQPpsEQysDkQsT8BK7ExA+mwSCDWEbEsA+mwMRCxFgErsQkD6bFQASuxIBARErMeIyQ4JBc5sDkRsSY3OTmwSBKyKTQ8OTk5sD8RsC85ALE8NBESsB45sEMRsDE5sEQSsC85sEsRsCw5sCkSsCM5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNjURNCc3FjMyNjMyFhUUBgcWFRQGIyImIwc3FBYzMjY1NCYrATUzMjY1NCYjIgYV9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAYgODgI7My+WFsGqUj3p0dNIhy1u0TFMj1hgfYduYkxOS1grrAWsf4mDhfpUjXl9yKpOXAVtvmJc+1Rg0wF3z2QGBgaPYD1xHUTKc64GBpknIFJedX1RRF5tQxorAAAAAwD2/k4IAAYIAA8AHQA6AIkAsA0vsRIB6bA4L7QxAgAmBCuwKy+0IQIAWwQrsBovsQQC6QGwOy+wANaxEATpsBAQsR4BK7QuAwAuBCuwLhCxKQErtCgEADEEK7AoELEWASuxCQPpsTwBK7EpLhESsiExODk5ObEWKBESsyUmNDUkFzkAsSsxERK0HigpNDUkFzmwIRGwJjkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE0ADMyFh8CBg8BJiciBhUUFjMyNjcXDgEjIgD2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBFwEx4VKwLy4EGwQlXNlxrJiZcaZOI0zmcvD+/KwFrH+Jg4X6VI15fciqTlwFbb5iXP1K5QEXIRIRBmZhArgBwdW27ERWOmJsASAABAD2/k4IAAYIAA8AHQA1AEEAhACwDS+xEgHpsDEvsTkC6bA+L7EpAumwGi+xBALpAbBCL7AA1rEQBOmwEBCxIAErsTYD6bA2ELE8ASu0LAMALgQrsCwQsRYBK7EJA+mxQwErsSAQERKzHiMkNSQXObA2EbEmNDk5sDwSsSkxOTkAsTkxERKwHjmwPhGwLDmwKRKwIzkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NRE0JzcWMzI2MzIAFRQOAiMiJiMHNxQWMzI2NRAhIgYV9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAToQEAQ6NTmsN98BVmiorlpUrDlx0zlvtrL+cUI/rAWsf4mDhfpUjXl9yKpOXAVtvmJc+1RtxgF3wXIGBgb+ydOHxWQtBAaRJxaN2QHdGCUAAAAAAwD2/k4IAAYIAA8AHQBQAKgAsA0vsRIB6bBQL7RCAgBABCuwRTKwPy+xNQLpsDIvtCcCAF0EK7AaL7EEAukBsFEvsADWsRAE6bAQELEhASuxQAPpsDQysEAQsRYBK7EJA+mxUgErsSEQERKxHiU5ObBAEbBQObAWErQqKzhHTSQXOQCxUBIRErBMObBCEbBJObA/ErM8PUZHJBc5sDURsDo5sDISsy8wNzgkFzmwJxGyJCstOTk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNTY1ETQnNxYzITI3FwYVFBcHJiMGHQEyNxcGFRQXByYjFRQXMjY/ARcUBhQWFQcmIyH2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBjg4OAjszAbU3JQQEBATTzwyD0wYGBgaorgxc2T8+AgICAiU3/jusBax/iYOF+lSNeX3Iqk5cBW2+Ylz7TgZg0wF3z2QGBgYGKQwXGAYSLa53DwUXGh8UBBCypi0IBgUGBigQJQoGBgAAAwD2/k4IAAYIAA8AHQBFAJIAsA0vsRIB6bA+L7E0AumwMS+0JgIAXQQrsBovsQQC6QGwRi+wANaxEATpsBAQsSABK7E/A+mwMzKwPxCxFgErsQkD6bFHASuxIBARErMeIyRFJBc5sD8RsEQ5sBYStCkqN0FCJBc5ALE+EhESsx47PEIkFzmwNBGwOTmwMRKzLi82NyQXObAmEbIjKiw5OTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NxE0JzcWMyEyNxcGFRQXByYjBgcVMjcXBhUUFwcmIxUUFwcmIwf2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBohABEQQ5NgGwOyUEBAQE1cwMAYPTBgYGBqiuEQQ5NnGsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VG3GAXfBcgYGBgYpDBcYBhItrncPBRcaHxQEELLBcgYGBgAAAwD2/k4IAAYIAA8AHQBEAI8AsA0vsRIB6bBCL7QxAgB6BCuwLC+0IQIAegQrsBovsQQC6QGwRS+wANaxEATpsBAQsR4BK7QvAwA4BCuwLxCxNAErsT0D6bA9ELEWASuxCQPpsUYBK7E0LxEStCEsNjdCJBc5sD0RsiUpJjk5ObAWErI6P0A5OTkAsSwxERK0HigpN0AkFzmwIRGwJjkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE0ADMyFh8CBg8BLgEjIgYVECEyNzU0JzcWMzcVBgcUFxUGISIA9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjARsBKfpSuDIzBBsEJy+qa42iAUyRPA4COzNxDgEPpP7h/P72rAWsf4mDhfpUjXl9yKpOXAVtvmJc/T/4AQ8hEhEGZmECXmHgyP5QOTW8ZwYGBgZcqD8VBIkBJAADAPb+TggABggADwAdAEkAngCwDS+xEgHpsEIvsSsC6bAaL7EEAukBsEovsADWsRAE6bAQELEgASuxQwPpsCoysEMQsUABK7AsMrE3A+mwNxCxFgErsQkD6bFLASuxIBARErMeIyRJJBc5sEMRsEg5sEAStycoLzA9PkVGJBc5sDcRsDw5sBYSszM0OTokFzkAsUISERKzHjk6RiQXObEaKxEStSMkMDIzNCQXOTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY3ETQnNxYzNxcGBxUhNTQnNxYzNxcGFREUFwcmIwcnNj0BIRUUFwcmIwf2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBUBABEQQ5NnECEAEBrhAEOTZwAhAQBDk1cQIQ/lIRBDk2cawFrH+Jg4X6VI15fciqTlwFbb5iXPtUbcYBd8FyBgYGBmrJfX3BcgYGBgZqyf6JwXIGBgYGbcaqqsFyBgYGAAADAPb+TggABggADwAdADEAXwCwDS+xEgHpsBovsQQC6QGwMi+wANaxEATpsBAQsSABK7ErA+mwKxCxFgErsQkD6bEzASuxIBARErMeIyQxJBc5sCsRsDA5sBYSsycoLS4kFzkAsRoSERKxJC45OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY1ETQnNxYzNxcGFREUFwcmIwf2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCjBAQBDk1cQIQEAQ5NnCsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VG3GAXfBcgYGBgZqyf6JwXIGBgYAAwD2/k4IAAYIAA8AHQA8AHUAsA0vsRIB6bA4L7QjAgAoBCuwPCDWEbEgAemwGi+xBALpAbA9L7AA1rEQBOmwEBCxKAErsTMD6bAzELEWASuxCQPpsT4BK7EoEBESsx4rLDwkFzmxFjMRErEvMDk5ALEjPBESsB45sRogERKyKywzOTk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNj8BFjMyPgI1ETQnNxYzNxcGBxEUBgcGIyIjIif2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBtwwSLiUzKzkWBw8COzRxAhABHERJpQICZDGsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7ZBd3AkYtXE8/ATnNZgQEBARtxv7nlnpESxgAAAADAPb+TggABggADwAdAEwAYwCwDS+xEgHpsBovsQQC6QGwTS+wANaxEATpsBAQsSABK7FGA+mwKjKwRhCxFgErsQkD6bFOASuxIBARErMeIyRMJBc5sEYRsEs5sBYStCcoO0hJJBc5ALEaEhESsSQ7OTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NRE0JzcWMzcXBh0BPgE3PgM3FjMyNwAHFQEmIyIHLgInJicVFBcHJiMH9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAW0QEAQ5NnACEAYKBS9yTI0dEmdUGP7FmAHkH2BzGjG5gRsGChAEOTVxrAWsf4mDhfpUjXl9yKpOXAVtvmJc+1ZtxgF3wXIGBgYGasmQAgUEKXlWpCIGBv7ssAL93QYGPfCkGgQFu8FyBgYGAAADAPb+TggABggADwAdADsAfACwDS+xEgHpsDUvtCgCAEAEK7ArMrAaL7EEAukBsDwvsADWsRAE6bAQELE5ASuxJgPpsCYQsRYBK7EJA+mxPQErsTkQERKyHh82OTk5sCYRsDU5sBYStSIjLS8xMiQXOQCxNRIRErAxObAoEbAvObAaErMeHywtJBc5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUFNxYzNxcGFREUFzI2PwEXBhUUFwcmIyEHNTY1ETT2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMB2AI9M3ECEAxc2T8+AgICAiU3/jtwDqwFrH+Jg4X6VI15fciqTlwFbb5iXM8GBgYGasn+iaYtCAYFBgwoJRQGBgYGYNMBd8EAAAADAPb+TggABggADwAdADgArgCwDS+xEgHpsBovsQQC6QGwOS+wANaxEATpsBAQsS0BK7EpA+mwKRCxFgErsQkD6bE6ASuwNhq6wD36gQAVKwoEsC0uDrAvwASxKQn5DrAmwLAmELMnJikTK7MoJikTK7InJikgiiCKIwYOERI5sCg5ALUpLS8mJyguLi4uLi4Bsy8mJyguLi4usEAaAbEtEBESsR4kOTmwKRGwJTkAsRoSERK0HiAjJCskFzkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFRMSEzMSEwEzFhoBFyYjIgcCJwAHIyYBAgcmIvaLfQTRj6Jth/ryi31JvwSTXE6q+21cY69sH2qi1QGLYw4tJxQXRUQYKRz+9Gc+Qv7xOwMQc6wFrH+Jg4X6VI15fciqTlwFbb5iXPtQAs8BL/6w/nQC3Hv+Vv68lQQEAfbl/hLpjwIT/gqwBAAAAAADAPb+TggABggADwAdAE0AsQCwDS+xEgHpsD4vtCwBABEEK7AzL7EmNjMztDQCACoEK7AkMrAaL7EEAukBsE4vsADWsRAE6bAQELEgASu0RwQAJQQrsEcQsTABK7Q7BAAlBCuwOxCxFgErsQkD6bFPASuxIBARErMeIyRNJBc5sEcRsURMOTmwMBKzJzRJSiQXObA7EbA+ObAWErA4OQCxLD4RErMeO0lKJBc5sDMRtCM4OkRFJBc5sBoSsSc3OTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NRE0JzcWMzcBFhcWMzI1NjURNC8BFjM3FwYVERQGIyImJwEmJyMXERQXByYjB/aLfQTRj6Jth/ryi31JvwSTXE6q+21cYwFEEBAEOTQzAhALEyEKAgUQGz0lKSEQKxM7SjX+HxIOAwYQBB8kRqwFrH+Jg4X6VI15fciqTlwFbb5iXPtUbcYBeb51BAQC/VYPGC4BByYBnL51BAQEBG3G/XUUHSZEAmAXF0b+kcFyBAQEAAQA9v5OCAAGCAAPAB0AKQA0AGoAsA0vsRIB6bAnL7EtAumwMi+xIQLpsBovsQQC6QGwNS+wANaxEATpsBAQsR4BK7QqAwAuBCuwKhCxLwErtCQDAC4EK7AkELEWASuxCQPpsTYBK7EvKhESsSchOTkAsTItERKxHiQ5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATQAMzIAFRQAIyIANxQWMyARNCYjIgb2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBBQEi6PQBHP7k9OX+29+4kgESoKZ7m6wFrH+Jg4X6VI15fciqTlwFbb5iXP0x4wEy/u3l6f7hARLy1d0BmezXyQAEAPb+TggABggADwAdADgARACjALANL7ESAemwLy+0OwIAmAQrsi87CiuzQC83CSuwQS+0KQIAfQQrsCQysBovsQQC6QGwRS+wANaxEATpsBAQsSABK7EyA+mwOTKwMhCxPgErsSwD6bAsELEWASuxCQPpsUYBK7EgEBESsx4jJDgkFzmwMhGxJjc5ObA+ErMvKTQ1JBc5ALEvEhESsh40NTk5ObFBOxESsCw5sCkRsSMmOTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NxE0JzcWMzI2MzIWFRQGIyInFRQXByYjBxMWMzI2NTQmIyIGFfaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwGkEAERBDc0GbwSvrnLvkIxEQQ5Nm3PHU5vS1BaTi2sBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VHHCAXm+dQQECqVZdcQOjb51BAQEAgYOXH+HUh8lAAAEAPb+TggABggADwAdADgAQwCQALANL7ESAemwNi+xPALpsEEvsSEC6bAaL7EEAukBsEQvsADWsRAE6bAQELEeASuxOQPpsDkQsT4BK7EkA+mwJBCxFgErsQkD6bFFASuxPjkRErI0NiE5OTmwJBGyJiozOTk5sBYSsisuMTk5OQCxNhIRErIrMTM5OTmwPBGyKCo0OTk5sEESsh4mJDk5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVEzQAMzIAFRAHHgYXFQYHLgEnBiMiADcUFjMgETQmIyIG9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxj4gEc6PIBGLYCRxRCKD87Hx10TKVdYHXj/t/ZuJIBEqCme5usBax/iYOF+lSNeX3Iqk5cBW2+Ylz9MeUBMP7t5f7vjgEqCyYTHhgKCg5XK3syIwES8tXfAZvs2csAAAQA9v5OCAAGCAAPAB0ASwBYAKsAsA0vsRIB6bBEL7FMAumwVS+xKQLpsCQysBovsQQC6QGwWS+wANaxEATpsBAQsSABK7FFA+mwTDKwRRCxUAErsSsD6bArELEWASuxCQPpsVoBK7EgEBESsx4jJEskFzmwRRGxJko5ObBQErQpOC5HSCQXObArEbE0Njk5sBYSsjAxMjk5OQCxRBIRErQeMDI/SCQXObBMEbAuObBVErArObApEbEjJjk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNjURNCc3FjMyNjMgERQGBxYAFwcmIyIHJicuBicOAiMVFBcHJiMHEzMyNjU0LgIjIgYV9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAY4QEAQ5NRm0EwF9fWsiAQgsBB9RSh8ZiwoRExIUExQJECQeEQ4COzRw00p7YBczMylOMawFrH+Jg4X6VI15fciqTlwFbb5iXPtUccIBeb51BAQK/vZxfxwt/owyBAQETMYOGBsZGRgXCwEBAYXNZgQEBAIMUIdCUCQLHyUAAAADAPb+TggABggADwAdAE4AjgCwDS+xEgHpsEovsSQC6bA9L7EyAumwGi+xBALpAbBPL7AA1rEQBOmwEBCxLwErsUAD6bBAELEmASuxRwPpsEcQsRYBK7EJA+mxUAErsS8QERKxHk45ObBAEbEgITk5sCYStSQqMj1DSiQXObBHEbI2Nzo5OTkAsSRKERKwHjmwPRG1ICEvNzlHJBc5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNj8BHgEzMjU0JicuBDU0NjMyFh8CBgcjLgEjIgYVFBceAxUUBiMiJi8B9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAW8UERAjt1qwQlA5UmtDL8+VWpgfHgIXDA4lk1ZGTr9EXnI+1cFcqigorAWsf4mDhfpUjXl9yKpOXAVtvmJc+489dgJIaahaWRwUITo7WDF3kiESEQY7dUxkUEaHPRcrR2k/fa4gEhEAAAAAAwD2/k4IAAYIAA8AHQBBAHoAsA0vsRIB6bA9L7AuM7QkAgAoBCuwGi+xBALpAbBCL7AA1rEQBOmwEBCxOgErsTED6bAxELEWASuxCQPpsUMBK7E6EBESsh4iNzk5ObAxEbA2ObAWErMnKDM0JBc5ALE9EhEStB4rLDRBJBc5sCQRsx8hKCokFzkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NCc3FjMhMjcXBhQXByYnBgcRFBcHJiMHNTY3ETQnIgYPAfaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwFEAwMEJTUClDUlBAMDBGbPDAEPAjs0cQ4BDVyZICCsBax/iYOF+lSNeX3Iqk5cBW2+Ylz+vBU7JQYGBgYlOhYGEgEtqv6Vz2QGBgYGYNMBa6otCwQEAAMA9v5OCAAGCAAPAB0ARgB8ALANL7ESAemwPy+0LAIAQwQrsBovsQQC6QGwRy+wANaxEATpsBAQsUQBK7EmA+mwJhCxMgErtD0EACAEK7A9ELEWASuxCQPpsUgBK7FEEBESsR4fOTmxMiYRErQiIzU2PyQXObEWPRESsDk5ALEaLBESsx82PUQkFzkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQU3FjM3FwYVERQeAzMyPgM1ETQnNxYzNxcGHQEQISIuAjURNPaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwFbAjszcQIQBBgtXEBEYjUfCBAEKSVNAg7+WkR8fUysBax/iYOF+lSNeX3Iqk5cBW2+YlzLBAQEBG3G/vIvRGpCMyk/Y1g7AQK+dQQEBARg0+f+KyBMoG8BQc0AAAMA9v5OCAAGCAAPAB0AMABAALANL7ESAemwGi+xBALpAbAxL7AA1rEQBOmwEBCxFgErsQkD6bEyASuxFhARErEeKjk5ALEaEhESsR4sOTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQUWFzI3EhMSNxYXMjcAAyMmCgH2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBLhthWhtJvugyElslEv7lqkwzwo6sBax/iYOF+lSNeX3Iqk5cBW2+Yly8BAEF/vL+PAIUvgQBBf2a/nJ5Ad8BVgADAPb+TggABggADwAdAD4AYgCwDS+xEgHpsBovsQQC6QGwPy+wANaxEATpsBAQsR4BK7QiAwAuBCuwIhCxMAErtDQDACUEK7A0ELEWASuxCQPpsUABK7EiHhESsD05sDARsTY7OTkAsRoSERKxHjY5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVFxYXMjcSExI3AicWFzI3EhMSExYXMjcCAyMmCwEjJgoB9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjSBtYUhpM1HgzdSkZWFwZcZCDTRI8QhKkz0ItpfBKNb+PrAWsf4mDhfpUjXl9yKpOXAVtvmJcvAQBBf7m/hYBFHwBIFQEAQX+kP6aAXoBXAQBBf5Y/bRqAZn9/X8B1wFaAAADAPb+TggABggADwAdAD0AQACwDS+xEgHpsBovsQQC6QGwPi+wANaxEATpsBAQsRYBK7EJA+mxPwErsRYQERKxHiw5OQCxGhIRErEeLDk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUFFjMyNxYTNjcWMzI3CQEmIyIHLgInDgIHJiMiBwH2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBAxtmXh4t4Jp2ElczEv6FAaQfYGYfI1x3Hh11XiUSM1gVAYGsBax/iYOF+lSNeX3Iqk5cBW2+YlzJBgZI/uistAYG/kT90wYGPX+cKymahTsGBgHjAAADAPb+TggABggADwAdADwAXwCwDS+xEgHpsBovsQQC6QGwPS+wANaxEATpsBAQsTsBK7EzA+mwMxCxFgErsQkD6bE+ASuxOxARErIeITk5OTmwMxGxIzc5ObAWErIlKTU5OTkAsRoSERKxHjU5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVBRYyNxYTNjcWMzI3DggHEhcmIyIHNhEC9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjATwZvBo3x5ljEFErFBw9LTIlJh4dGAoDCRlYVhgKsqwFrH+Jg4X6VI15fciqTlwFbb5iXMkGBm3+sPDNBgYrXUZLOTwxMCsU/qhjBgZiAUoBNwAAAAADAPb+TggABggADwAdAEMAiQCwDS+xEgHpsEEvtDkCACUEK7Q4AgBABCuwJC+0LAIAJQQrsCwQtCECAD8EK7AaL7EEAukBsEQvsADWsRAE6bAQELEWASuxCQPpsUUBK7EWEBESsR4xOTkAsUESERKwPjmwOBGxHjw5ObA5ErE2Ojk5sSEkERKwJTmwLBGxJyk5ObAaErAvOTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY3AQYEByc2NTQnNxYXITI3MhcUBwEGBwYVJRcGFRQXByYjIQf2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBHwofAlhf/oNLBAQEBDEuAhBgYgoBL/3ABAMBAmYEBAQEMTv9tMesBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VgwtA0EBDQEGGRgOLAUEAQkJEkH85AYEAQQRBBkZDi0EBAQAAAMA9v5OCAAGCAAPAB0AKQBcALANL7ESAemwKS+0KAIARQQrsCEvtCACAEUEK7AaL7EEAukBsCovsADWsRAE6bAQELEeASu0JQMAJQQrsiUeCiuzQCUhCSuwKDKwJRCxFgErsQkD6bErASsAMDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBESEVDgEVERQWFxX2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCSgGDmkdImawFrH+Jg4X6VI15fciqTlwFbb5iXPpcBV47DDpm/HFmOg46AAADAPb+TggABggADwAdACEAdwCwDS+xEgHpsBovsQQC6QGwIi+wANaxEATpsBAQsR4BK7QfBAAmBCuwHxCxIQErtCAEACYEK7AgELEWASuxCQPpsSMBK7A2GrrC2e0gABUrCgSwHi6wIC6wHhCxHwr5sCAQsSEK+QKzHh8gIS4uLi6wQBoBADAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVBTMBI/aLfQTRj6Jth/ryi31JvwSTXE6q+21cYwJCbQFibawFrH+Jg4X6VI15fciqTlwFbb5iXHv7hQAAAAADAPb+TggABggADwAdACkAXACwDS+xEgHpsCkvtB4CAEUEK7AlL7QmAgBFBCuwGi+xBALpAbAqL7AA1rEQBOmwEBCxIQErtCgDACUEK7IhKAors0AhJQkrsB4ysCgQsRYBK7EJA+mxKwErADAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVAT4BNRE0Jic1IREh9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAoKaR0iZAYP+fawFrH+Jg4X6VI15fciqTlwFbb5iXPqWDjlnA49mOgw7+qIAAwD2/k4IAAYIAA8AHQAkAEAAsA0vsRIB6bAaL7EEAukBsCUvsADWsRAE6bAQELEWASuxCQPpsSYBK7EWEBESsR4hOTkAsRoSERKxHh85OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVARMzEyMLAfaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwIwwkLAWIuJrAWsf4mDhfpUjXl9yKpOXAVtvmJc/VwB0/4tAVb+qgAAAAMA9v5OCAAGCAAPAB0AIQA/ALIeAAArsR8C6bANL7ESAemwGi+xBALpAbAiL7AA1rEQBOmwEBCxFgErsQkD6bEjASuxFhARErEeIDk5ADAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATUhFfaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwHBAtusBax/iYOF+lSNeX3Iqk5cBW2+Ylz621BQAAMA9v5OCAAGCAAPAB0AKgBAALANL7ESAemwGi+xBALpAbArL7AA1rEQBOmwEBCxFgErsQkD6bEsASuxFhARErEeJjk5ALEaEhESsSEnOTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE3NjMyHwEWFRQnIif2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCcQIrRhMMagwYEiasBax/iYOF+lSNeX3Iqk5cBW2+Ylz+3RExBL0ZEBkBHgAAAAAEAPb+TggABggADwAdAEUAUADkALANL7ESAemwPS+wQzO0NgIAPwQrsEkysCcvtC8CAHoEK7AaL7EEAukBsFEvsADWsRAE6bAQELEeASuxRgPpsEYQsSQBK7BOMrQxAwAvBCuwMRCxFgErsQkD6bFSASuwNhq6DzLB1QAVKwoEsE4uDrBPwLEiC/mwIMCwIBCzISAiEyuyISAiIIogiiMGDhESOQCzISJOTy4uLi4BsiEiTy4uLrBAGgGxRh4RErEpKzk5sCQRsycvQEMkFzmwMRKwPTmwFhGxNjs5OQCxNj0RErE7QDk5sCcRtR4pKzQ4OSQXOTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATQ2PwEyNzQmIyIHLwE3PgEzIBcUAhUUMzI3FxYXBiMiJicjBiMiJjcUFjMyNzY9AQcG9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAb+ccocIATo/ZkgjKQYlk0oBFAEHJQouBBARRmcxPwoCZHFWb7gnIS9UG3tqrAWsf4mDhfpUjXl9yKpOXAVtvmJc+/BMfhshElZKeQJlBiE/+gT++BsvIQQIIVYzJ1pWXiM1QRcSmiEdAAAABAD2/k4IAAYIAA8AHQA5AEYArQCwDS+xEgHpsC4vsDMzsTwC6bBEL7QoAgBABCuwGi+xBALpAbBHL7AA1rEQBOmwEBCxNwErsToD6bAlMrI6Nwors0A6Iwkrsjc6CiuzQDceCSuwOhCxQQErsSsD6bArELEWASuxCQPpsUgBK7E3EBESsR81OTmwOhGyITAzOTk5sEESsSguOTkAsTwuERKyMDI1OTk5sEQRsCs5sCgSsCY5sBoRsh4hIzk5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVBTc2NzIXBh0BNjMyFhUUBiMiJw4BByInNjURNBMWMzIzMjY1NCYjIgf2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBuwJ7Rw4BD0p1b8LwhVpBCDoIRg4ItjQ9AQFoWU5GYj6sBax/iYOF+lSNeX3Iqk5cBW2+YlyeBAwbDm+yslKoharZOQYpDAYvSgJ3xfzgR4uLb3lAAAAAAAMA9v5OCAAGCAAPAB0AOQB2ALANL7ESAemwNy+0LwIAKQQrsi83CiuzQC8xCSuwKS+0IQIAegQrsBovsQQC6QGwOi+wANaxEATpsBAQsR4BK7EsA+mwLBCxFgErsQkD6bE7ASuxFiwRErMhJDQ3JBc5ALEpLxESsx4lJjQkFzmwIRGwJDkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE0NjMyHwEPAS4BIyIGFRQWMzI3MxYXDgEjIib2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBmtegf14CIxohWCtSZnRYaE0EHwEfi1SmvqwFrH+Jg4X6VI15fciqTlwFbb5iXPyaoMIxBJwCN0h3cHmaXhIVQlm4AAAAAAQA9v5OCAAGCAAPAB0APwBLALAAsA0vsRIB6bA9L7RDAgAoBCuwSi+xIQLpsBovsQQC6QGwTC+wANaxEATpsBAQsR4BK7FAA+mwQBCxRQErsCMysS4D6bIuRQors0AuKwkrskUuCiuzQEUmCSuwLhCxFgErsQkD6bFNASuxRUARErMhJzk9JBc5sC4RsDM5sBYSsikwMTk5OQCxQz0RErMwMTUzJBc5sEoRsh45ODk5ObAhErAjObAaEbImKSw5OTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE0NjMyFzU0Jzc2NzIXBgcRFBcHJiMiByIvASMGIyIjIiY3FBYzMjcRLgIjIvaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwFM7psxQhAEeUkOARABGwQlOykpDgEIAld0AQF9sr1WQ1hOFxovI7ysBax/iYOF+lSNeX3Iqk5cBW2+Ylz8j5rRIWTHWAYIHxB9pP4nno0EBAQEYnLAqId7XgFEIyAZAAAABAD2/k4IAAYIAA8AHQAzAD0AhwCwDS+xEgHpsDEvtCoCACgEK7AnL7E0AumwOi+xIQLpsBovsQQC6QGwPi+wANaxEATpsBAQsR4BK7EnA+mwNDKwJxCxNwErsSQD6bAkELEWASuxCQPpsT8BK7E3JxESsiEqMTk5ObAkEbAsObAWErAuOQCxJyoRErIeLC45OTmwNBGwJDkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE0NjMyFhUUJyEUFjMyNxYVDgEjIiYTMzI1NCYjIg4B9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAa/de4+TGv5id1CNUCEtnlKmxMbbFzEvGTE+rAWsf4mDhfpUjXl9yKpOXAVtvmJc/Iuiz6ZtGwGTilYSIz1MuAEQFU47Ek0AAwD2/k4IAAYIAA8AHQBOAJ4AsA0vsRIB6bBNL7BAM7EhAumwOjKwMy+0KQIAKAQrsBovsQQC6QGwTy+wANaxEATpsBAQsUsBK7AiMrFCA+mwNjKyQksKK7NAQj4JK7JLQgors0BLHgkrsEIQsRYBK7EJA+mxUAErsUsQERKxSEk5ObBCEbBHObAWErQpKzNERSQXOQCxTRIRErBFObEzIRESsTAxOTmwKRGwLDkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE1NDsBNTQ2Nz4BMzIXFQ4CDwEmIyIGFRQWHQEzMh0BFCsBERQXByYjByc2NxEjIvaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwHHI0oxNzGaSC0YCA4RAhIlMz1CBqYMI48QBDE1aQIQAWcGrAWsf4mDhfpUjXl9yKpOXAVtvmJc/aYrHy1UbTkzQQwGDDhMCgJGUEIQbxQOCzMU/unPZAQEBARe1QEXAAAAAAYA9v5OCAAGCAAPAB0AUwBhAGoAbAEZALANL7ESAemwUS+0VwIAYQQrsGAvtGsCACoEK7BrL7BcM7RHAQAhBCuwSjKwPi+0ZAIAmAQrsGkvsDgzsSsC6bAaL7EEAukBsG0vsADWsRAE6bAQELEoASuwIzK0YgMAJQQrsB4g1hG0VAMAJQQrsCgQtEMEACMEK7BiELFnASu0OwMAJQQrs1o7ZwgrtE4DABoEK7A7ELEWASuxCQPpsW4BK7FUKBESsSAlOTmwYhGwQTmwZxJACy0rR0lRV1xgPmtsJBc5sFoRsDg5sU47ERKyLzYxOTk5ALFgVxESsk4eWjk5ObBHEbAgObA+ErEjQzk5sGQRsSVBOTmwaRKyNTY7OTk5sCsRsS0uOTmwGhKyLzAxOTk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNDcuATU0NycmJzQ2MzIXPgE3FwYHFBcHJiceARUUBiMiLwEGFRQeATM3NjcyHgEVFAQjIiY3FBYzMjY1NCMiDgEjBhMUMzI2NTQnIhMz9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAaKHJTFACD8BonsrL0K8FAcGAQcHCaMlLZOBUiUMGR8dHC1GG1CDZv7no2alplw0ZI/RCCIsE0kpeS8+f2YhAawFrH+Jg4X6VI15fciqTlwFbb5iXPrPZFYKPi9kOgoxb2KHDgQWAgQUHRkUBAEOG1csYoIXBic1HyEEBAgBIWBKdY9UeUZIXEZzAwM6Aim2RU6yAf2CAAMA9v5OCAAGCAAPAB0ATQCrALANL7ESAemwPi+0LQIAKQQrsBovsQQC6QGwTi+wANaxEATpsBAQsSABK7FHA+mwKjKyRyAKK7NARygJK7IgRwors0AgIwkrsEcQsToBK7ExA+mwMRCxFgErsQkD6bFPASuxIBARErIeJE05OTmwRxGwTDmwOhK0Ji03SUokFzmwMRGwNjmwFhKxMzQ5OQCxPhIRErQeKzA0SiQXObEaLRESsiMmKTk5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY1ETQnNzY3MhcGBxU2MzIWHQEUFwcmIwc1Nj0BNCYjIg4FBxUUFwcmIwf2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBsQ4OAnVPDAEOAXlmWooOAjM1aQ8wQwoRFg8cDScKDwIzNGisBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VGC9Ac7VTAYIHQ6DnNl5f2+ftmcEBAQEYbyTWjwEDQoZDicIuLZnBAQEAAAEAPb+TggABggADwAdADEAOQCJALANL7ESAemwLi+0JgEABwQrsDkvtDUBAB0EK7AaL7EEAukBsDovsADWsRAE6bAQELEzASuxHiMyMrE3A+mxKC0yMrMgNzMIK7ErA+mwNxCxFgErsQkD6bE7ASuxMxARErEkMTk5sSsgERK0MDQ1ODkkFzmwNxGxJi45OQCxLhIRErEeLTk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNj0BNCc3NjcyFwYHFRQXByYjBxI0NjIWFAYi9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAoYQEAR5SQ4BEAERBDM0aAI9Wj4+WqwFrH+Jg4X6VI15fciqTlwFbb5iXPtacaZUtFoECB8QfZRsonUEBAQDpFY/P1ZAAAQA9v5OCAAGCAAPAB0APwBHALMAsiIAACuwDS+xEgHpsD0vtCcCACUEK7BHL7RDAQAdBCuwGi+xBALpAbBIL7AA1rEQBOmwEBCxIQErtCIEADEEK7AiELEtASuxOAPpu4AAAC0AQQAOK7AwM7FFA+mwNTKwOBCxFgErsQkD6bFJASuxIRARErEePzk5sUEiERKyJzE9OTk5sTgtERKzQkNGRyQXObBFEbAzOQCxJz0RErAeObAiEbAgObBHErIpMzg5OTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE+AT8BFB4CMzI1NC4BPQE0Jzc2NzIXBgcRFAYHBiMiJxI0NjIWFAYi9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAd4KCgQfFAkYD2wCAhAEeUkOARABIS1GsTEf1T1aPj5arAWsf4mDhfpUjXl9yKpOXAVtvmJc+kIOgQ4CAicIEIUGL2dJ1bZZBggfEX2V/n1MWEBiDATTVkBAVj8AAAADAPb+TggABggADwAdAE0AfQCwDS+xEgHpsBovsQQC6QGwTi+wANaxEATpsBAQsSMBK7AeMrEoA+mwSTKzRygjCCuxIAPpsCAvsUcD6bAqMrAoELEWASuxCQPpsU8BK7EgIxESsSRNOTmwRxGwTDmwKBKxJko5ObAWEbIwOUA5OTkAsRoSERKxJjo5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY1ETQnNzY3MhUGFRE2Nz4BNzI3Fw4CBxYXByYjIgcuBCcmJxUUFwcmIwf2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBvRAQBHNQDhASFC+OM7gdAitvdBHHeQIdZE4tFEYbMSsdDRUQBDE2aKwFrH+Jg4X6VI15fciqTlwFbb5iXPtgXtUBsclXBggdDn2k/nQDEiOgSAQEJ3F/EO5/BAQEG2YjPzIeCwMKz2QEBAQAAAAAAwD2/k4IAAYIAA8AHQAxAHAAsA0vsRIB6bAaL7EEAukBsDIvsADWsRAE6bAQELEjASuwHjKxKAPpsC0ysysoIwgrsSAD6bAgL7ErA+mwKBCxFgErsQkD6bEzASuxICMRErEkMTk5sCsRsDA5sCgSsSYuOTkAsRoSERKxJi45OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY1ETQnNzY3MhUGFREUFwcmIwf2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCkhAQBHNQDhAQBDE2aKwFrH+Jg4X6VI15fciqTlwFbb5iXPtUXtUBuMlYBggdDn2k/ivPZAQEBAADAPb+TggABggADwAdAGcA2ACwDS+xEgHpsFYvsEQztC4CACgEK7EmNDIysBovsQQC6QGwaC+wANaxEATpsBAQsSMBK7AeMrEoA+mwYzKzYSgjCCuxIAPpsCAvsWED6bApMrAoELFTASuxSgPpsEoQsUABK7E3A+mwNxCxFgErsQkD6bFpASuxICMRErEkZzk5sGERsiYqZjk5ObAoErFfZDk5sFMRsi5QUTk5ObBKErExTzk5sEARtD00PkxNJBc5sDcSsDw5sBYRsTk6OTkAsVYSERK3HikqMTY6TWQkFzmwLhGwIzkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFRM2NzU0Jzc2NzIVBzM+AjMyFhc+ATMyHQEUFwcmIwcnNj0BNCYjIg4BBx0BFBcHJiMHJzY3NTQnIg4BBwYPAQ4BBxUUFwcmIwf2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGP4EAERBHVKDg4CLylMLUSHCERZPt8QBDE1aAIQJzsfLxsxEAQxNWkCEAFgDBMXBwcOEwYlChAEMTVprAWsf4mDhfpUjXl9yKpOXAVtvmJc+1RgvVS2WAQIHxBrMyUjSjFIM/aXuGUEBAQEcaydUDobGzcvi7hlBAQEBGC9mY0BBQoEAw4UBicKuLhlBAQEAAADAPb+TggABggADwAdAEgAlACwDS+xEgHpsD8vtC4CACgEK7AnMrAaL7EEAukBsEkvsADWsRAE6bAQELEhASuxQwPpsCkysEMQsTsBK7EyA+mwMhCxFgErsQkD6bFKASuxIRARErEeJTk5sEMRsicrSDk5ObA7ErQuODlFRiQXObAyEbA3ObAWErE0NTk5ALE/EhEStB4qKzE1JBc5sC4RsCQ5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNTY9ATQnNzY3MhUHMz4BMzIWHQEUFwcmIwcnNj0BNCYjIgYHFRQXByYj9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAccODgJ1Sg4OBEZTQGaBDwIzNmYCDic5MTw9DgIzM6wFrH+Jg4X6VI15fciqTlwFbb5iXPtQBGK7VMNLBAgfEG9SLYtpmbZnBAQEBFTJh1hIK0i0tmcEBAAABAD2/k4IAAYIAA8AHQApADcAZwCwDS+xEgHpsCcvsSwC6bAuMrAzL7EhAumwGi+xBALpAbA4L7AA1rEQBOmwEBCxHgErsSoD6bAqELEwASuxJAPpsCQQsRYBK7EJA+mxOQErsTAqERKxISc5OQCxMywRErEeJDk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNDYzMhYVFAYjIiY3EDMwMzI1NCYjIg4C9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAai/pLKouKaku8WtAYVEXi89GwqsBax/iYOF+lSNeX3Iqk5cBW2+Ylz8k6DJz4uH0cKs/uDhqI0lTEsAAAAABAD2/k4IAAYIAA8AHQA9AEsAvQCwDS+xEgHpsDQvsUAC6bBIL7QsAgApBCuwJjKwGi+xBALpAbBML7AA1rEQBOmwEBCxIAErsTcD6bEpPjIysDcQu4AAADcAKAAOK7EjA+mwIy+wHjOxKAPpsDkysDcQsUYBK7ExA+mwMRCxFgErsQkD6bFNASuxICMRErEkPTk5sDcRsSY8OTmwKBKxKjo5ObBGEbFASDk5ALE0EhESsh45Ojk5ObBAEbA2ObBIErIqMSk5OTmwLBGwIzkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NRE0Jzc2NzIVBzM2MzIzMhYVFAYjIicVFBcHJiMHExYzMj4DNTQjIgYH9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAaYREQR3SgwOBFF0AQFzwNuYSEEQBDE1acM3SC9EJRIEjSleGawFrH+Jg4X6VI15fciqTlwFbb5iXPoOX9UBmbZYBQgeEGh4wneg2SFB0WMGBgYB7kIfK0o7L/5GOQAAAAAEAPb+TggABggADwAdADgARgCaALANL7ESAemwNi+0PAIAPgQrsEMvsSEC6bAmMrAaL7EEAukBsEcvsADWsRAE6bAQELEeASuxOQPpsDkQsTMBK7A+MrEqA+mwKhCxFgErsQkD6bFIASuxMzkRErMwITE2JBc5sCoRsSMvOTmwFhKxLC05OQCxNhIRErQqLS8wMSQXObA8EbA0ObBDErEeOTk5sCERsSkjOTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE0NjMyFzc2MzIWFREUFwcmIwcnNj0BBgciJjcUFjMyNxEmIzQjIgcG9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAX/akZhFFxAjDBUQBDE1aQIQPV6cx89lVEwqQlgBVh8frAWsf4mDhfpUjXl9yKpOXAVtvmJc/LCWzj0lHRcO/U7PZQQEBARtx1QzAdeWnmwgAXVoATk6AAMA9v5OCAAGCAAPAB0AQACFALANL7ESAemwLy+xKAHpsCEysBovsQQC6QGwQS+wANaxEATpsBAQsT4BK7E1A+mwIzKyPjUKK7NAPh4JK7A1ELEWASuxCQPpsUIBK7E+EBESsR87OTmwNRGyISU6OTk5sBYSsis3ODk5OQCxLxIRErQsLTg6OyQXObAoEbIeJCs5OTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE3NjcyFwczPgEzMh8BDwEmIyIOAh0BFBcHJiMHNTY3NTT2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCFwJxSw4BBAQhbDEZJwYfDBs9DiMxHw4COzNjDgGsBax/iYOF+lSNeX3Iqk5cBW2+Ylz90wQIHxBzM1AMBJAEFwkWOSmGsGYEBAQEYrRbkQAAAwD2/k4IAAYIAA8AHQBDAJcAsA0vsRIB6bBCL7EjAumwNS+xLQLpsBovsQQC6QGwRC+wANaxEATpsBAQsSsBK7Q4AwAlBCuwOBCxJgErtD8DADoEK7A/ELEWASuxCQPpsUUBK7ErEBESsR4fOTmwOBGwIDmwJhK0Iyk1O0IkFzmwPxGyLzAyOTk5ALEjQhESsB45sDURtR8gKzEyPyQXObAtErAwOTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVAT8BHgEzMjY1NCYnJjU0JTIfAQ8BLgEjIgYVFBceAxUUBiMi9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAdwYFRl8My82MUDLARtgXgIcFRRaMy80ZS9BSieWiX+sBax/iYOF+lSNeX3Iqk5cBW2+Ylz7c5cCMUo+Ny81GUxwvAExBJQCLVgvKVYjEB8xRitKgAADAPb+TggABggADwAdAEkAogCwDS+xEgHpsD4vtDgCACgEK7BIL7AxM7EhAumwKzKwGi+xBALpAbBKL7AA1rEQBOmwEBCxRgErsSJDMjKxMwPpsSk2MjKyM0YKK7NAMy8JK7JGMwors0BGHgkrsDMQsRYBK7EJA+mxSwErsUYQERKwJTmwMxGyJz5AOTk5sBYSsjg7PDk5OQCxOD4RErA8ObBIEbE6Qzk5sRohERKwJzkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE0NjsBNCc3NjcyFQYVMzIdARQrARUUBhUUMzI3FgcGIyIjIiY1NDY9ASMi9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAcsVDFQKAjd/DgimDCSOBDM5MB0BVYECAUZNBGAUrAWsf4mDhfpUjXl9yKpOXAVtvmJc/awQK2hCBQQxD3VgCjMUoDOUEm8dEiZNWjsSxTOxAAADAPb+TggABggADwAdAFAAkgCwDS+xEgHpsEsvtCgCAD8EK7AaL7EEAukBsFEvsADWsRAE6bAQELFOASuxJgPpsCYQsTIBK7E9A+mwPRCxFgErsQkD6bFSASuxThARErEeHzk5sTImERK1IiM1NkhLJBc5sD0RsEI5sBYSszk6P0AkFzkAsShLERKzP0BCRCQXObAaEbcfNjg5OkdITiQXOTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATcWFzcXBgcVFDMyPgc3NTQnNxYXNxcGBxUUFwcmIyIHIi8BIw4BIyImPQE09ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAbMCMzNpAg4BYwoWFRAVDBcGFgIOAjMzaQIOARkCH0MzHw4BBgQ/VDFtg6wFrH+Jg4X6VI15fciqTlwFbb5iXP3pBwYBBwdQwouiBAoJFAgbBh0Cuq5kBwYBBwdQwlikgwYGBgZiRC59VL6uAAADAPb+TggABggADwAdADIAQACwDS+xEgHpsBovsQQC6QGwMy+wANaxEATpsBAQsRYBK7EJA+mxNAErsRYQERKxHis5OQCxGhIRErEeLTk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBFjMyNxIXMzYTFjMyNwIHJiMiBwL2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBTBlOXhRYbQQ3kg5EOQ7bPw5QZRCPrAWsf4mDhfpUjXl9yKpOXAVtvmJc/fIGBv7p/nkBnAYG/hC0BgYBeQAAAwD2/k4IAAYIAA8AHQBPAGMAsA0vsRIB6bBEL7BMM7QzAQBJBCuwJjKwGi+xBALpAbBQL7AA1rEQBOmwEBCxFgErsQkD6bFRASuxFhARErEePTk5ALFEEhESsUpOOTmxGjMREkAJHiIkKy45Oz1IJBc5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUTFjMyFzI3EhczPgM3JicWMjcSFzM+AzcWMzI3DgMHJiMiByYnBgcmIyIHAvaLfQTRj6Jth/ryi31JvwSTXE6q+21cY6IZVgYFTBFvUgoQISEgETAsGawUXGUMGTknPQ4ORjMPGWQ5TB0ObUYOTDIgWQ5vQhCWrAWsf4mDhfpUjXl9yKpOXAVtvmJc/fAGAQf+qr0jTlFUK3JiBgb+1+o1km6zKwYGNeCDulAGBsd/UfcGBgGJAAMA9v5OCAAGCAAPAB0APgBAALANL7ESAemwGi+xBALpAbA/L7AA1rEQBOmwEBCxFgErsQkD6bFAASuxFhARErEeLjk5ALEaEhESsR4uOTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQEWMzI3Fhc2NxYzMjcDFxYXJiMiBy4BJwYHJiMiBxM3J/aLfQTRj6Jth/ryi31JvwSTXE6q+21cYwGGGV1WGTVbZTgQRjMR/BZ5iRdTXhkmUSyKHQ41Rg78BAisBax/iYOF+lSNeX3Iqk5cBW2+Ylz98gYGV3+DUwYG/tocsLIGBj17PsosBgYBQwcIAAMA9v5OCAAGCAAPAB0ANwBAALANL7ESAemwGi+xBALpAbA4L7AA1rEQBOmwEBCxFgErsQkD6bE5ASuxFhARErEeLDk5ALEaEhESsR4vOTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQEWMzI3FhM+AjcWMzI3BgAHJiMiBzY3JwL2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMBmhRZVBQwgx5ANRoOSjMPTv62JBkzOxdiSgZnrAWsf4mDhfpUjXl9yKpOXAVtvmJc/hsEBJX+xUakl08EBKL9GnoGBqKrCwEXAAAAAwD2/k4IAAYIAA8AHQBCAIIAsA0vsRIB6bBBL7Q0AgBbBCuwIS+0KwIAQgQrsCsQtCICACYEK7AaL7EEAukBsEMvsADWsRAE6bAQELEWASuxCQPpsUQBK7EWEBESsR4xOTkAsUESERKwPTmwNBGxHjs5ObAiErE4OTk5sCERsCM5sCsSsiUnMTk5ObAaEbAvOTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY3AQUnNjU0JzcWMyEyPgEzMhUGBwEyNj8BFwYVFBcHJiMhB/aLfQTRj6Jth/ryi31JvwSTXE6q+21cYwF9BhsBYP6qAgICAjElAXUUOisCCAIr/qpSujY1AgICAjEl/qS2rAWsf4mDhfpUjXl9yKpOXAVtvmJc+1YIJwIMEAYMKR0VBAQEBgoCQP4CCgQFBwwpHRQEBAQAAAADAPb+TggABggADwAdADkAegCwDS+xEgHpsDQvtDMCACoEK7AlL7QkAgAqBCuwGi+xBALpAbA6L7AA1rEQBOmwEBCxNwErsCEytDADAC8EK7AoMrIwNwors0AwNAkrsCQysDAQsRYBK7EJA+mxOwErsTcQERKwHjmwMBGwLDkAsSUzERKxIjc5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATU2NRE0JRUOARURFAYHHgEdARQWMxUuAT0BNPaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwIVbwEUMzc+QUQ7OTGDkawFrH+Jg4X6VI15fciqTlwFbb5iXP0jJR+TARTjCS8OUV7+/mBYHR1qYuZWbC8CbIz+nAADAPb+TggABggADwAdACEARACwDS+xEgHpsBovsQQC6QGwIi+wANaxEATpsBAQsR4BK7QhBAAuBCuwIRCxFgErsQkD6bEjASsAsRoSERKxHh85OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVAREzEfaLfQTRj6Jth/ryi31JvwSTXE6q+21cYwLmWqwFrH+Jg4X6VI15fciqTlwFbb5iXPonBZX6awAAAAMA9v5OCAAGCAAPAB0AOQCCALANL7ESAemwOS+0HgIAKgQrsCwvtC0CACoEK7AaL7EEAukBsDovsADWsRAE6bAQELEhASuwKDK0NgMALwQrsC8ysiE2CiuzQCE5CSuwLDKwNhCxFgErsQkD6bE7ASuxNiERErAlObAWEbEyMzk5ALEsHhESsS82OTmwLRGwLjkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQEyNj0BNDY3LgE1ETQmJzUEFxEUFxUGFxUUBgf2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCojE6O0RCPTgzARQBbm8BkoOsBax/iYOF+lSNeX3Iqk5cBW2+Ylz6fWxW5mJrHB1YYAECXlAPLwjk/uyTHyUZm/6LbQIAAAMA9v5OCAAGCAAPAB0AMwBzALANL7ESAemwLC+0JAEAIQQrszAkLAgrtCEBAC8EK7AaL7EEAukBsDQvsADWsRAE6bAQELEeASu0MwQAMQQrsDMQsRYBK7EJA+mxNQErsRYzERKxISc5OQCxLBIRErAzObAwEbAeObEhJBESsSYnOTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE+ATMyFjMyNxcOAyMiJyYnIgYH9ot9BNGPom2H+vKLfUm/BJNcTqr7bVxjAdwQd0UlpCVmKykQNzwrEi1MSi8rWh2sBax/iYOF+lSNeX3Iqk5cBW2+Ylz851SMa1wWO1UkDTMzAUA1AAADAPb+TggABggADwAdACkAQACwDS+xEgHpsCgvtCECACUEK7AaL7EEAukBsCovsADWsRAE6bAQELEWASuxCQPpsSsBK7EWEBESsR4jOTkAMDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNDYzITIHFAYjISL2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCFRsMAZ4XAR0O/mkZrAWsf4mDhfpUjXl9yKpOXAVtvmJc/PYUQCEQPgAAAAADAPb+TggABggADwAdACkAQACwDS+xEgHpsCgvtCECACUEK7AaL7EEAukBsCovsADWsRAE6bAQELEWASuxCQPpsSsBK7EWEBESsR4jOTkAMDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNDYzITIHFAYjISL2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCFRsMAZ4XAR0O/mkZrAWsf4mDhfpUjXl9yKpOXAVtvmJc/PYUQCEQPgAAAAADAPb+TggABggADwAdACkAQACwDS+xEgHpsCgvtCECACUEK7AaL7EEAukBsCovsADWsRAE6bAQELEWASuxCQPpsSsBK7EWEBESsR4jOTkAMDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNDYzITIHFAYjISL2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCFRsMAZ4XAR0O/mkZrAWsf4mDhfpUjXl9yKpOXAVtvmJc/PYUQCEQPgAAAAADAPb+TggABggADwAdACkAQACwDS+xEgHpsCgvtCECACUEK7AaL7EEAukBsCovsADWsRAE6bAQELEWASuxCQPpsSsBK7EWEBESsR4jOTkAMDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNDYzITIHFAYjISL2i30E0Y+ibYf68ot9Sb8Ek1xOqvttXGMCFRsMAZ4XAR0O/mkZrAWsf4mDhfpUjXl9yKpOXAVtvmJc/PYUQCEQPgAAAAADAPb+TgT2BggADwAdACkARgCwDS+xEgHpsCgvtCECACUEK7AaL7EEAukBsCovsADWtBAEADEEK7AQELEWASu0CQQAJQQrsSsBK7EWEBESsR4jOTkAMDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNDY7ATIHFAYrASL2T0cCvVFcPk39IU9HKW0CmTUsYf1nNDkBLxAH6w0BEAjnD6wFrH+Jg4X6VI15fciqTlwFbb5iXPz2FEAhED4AAAAAAwD2/k4I9gYIAA8AHQApAEYAsA0vsRIB6bAoL7QhAgAlBCuwGi+xBALpAbAqL7AA1rQQBABKBCuwEBCxFgErtAkDAC4EK7ErASuxFhARErEeIzk5ADAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATQ2MyEyBxQGIyEi9p6OBXmjuHyZ+kGejlPZBTNoWcH6zWlwAl4eDgHXGgEhEP4xHKwFrH+Jg4X6VI15fciqTlwFbb5iXPz2FEAhED4AAAEAAAAABgkGCQADAAARIREhBgn59wYJ+fcAAAAJAPL+FAePBgMAFwArADIAOAA8AEAAXABjAGoBLgCwEi+xHgHpsCwvsTliMzOxMwLpsT1kMjKwNi+xP2kzM7EwAumxOl0yMrAoL7QGAgBFBCuyBigKK7NABgQJK7AIMrBNL7FOAumzUU5NCCuxSgLpsEEysE4QsFUg1hGxRgLpAbBrL7AA1rQYBABLBCuwGBCxLAErsTME6bAzELE0ASu0MgQAaQQrsDIQsTkBK7Q9BABpBCuwPRCxQQErsUIE6bBCELE+ASu0PAQAaQQrsDwQsWMBK7RkBABpBCuwZBCxZQErsWIE6bBiELEjASu0DQQASwQrsWwBK7FBPRESsQYFOTmwQhGxHhI5ObA+ErEHCDk5sDwRsFc5sWRjERKwVTmwZRGwVDmxDSMRErIOSlE5OTkAsR4SERKwFDmwLBGwHDmxVU4RErBZOTAxFxE0NjMhFzM3ITIWFREOAyMiLgM3FB4DMzI+AjURNCYjISIGFRMRNDY7ARElIREjIhEBESERJTMRIxMzNDc2OwEyFjMyNjM1IgYjIiYrASImDgIHBhMzHgEVESE3IRE0JisB8uWcAR4tTisBGaD1CH/f8ZqFv9WFXkxSfMOsc4fV0XK6jf03jbJNloNo/sMBBBLyAWYBXf7d6elORSMZqpUX8TE1mAYdkyMd7y2VCFAhPikOPf5we5j+fzkBBHd3FkoEH4/qKSnbjPvPfaxWIw0xWJ6+XIVKKwwaSJRsA5qJx7mX/i8BiYG2/UBOAiv+7f6cAr79QkwCKwEpHxoQRSlJKUQCAgQOCy7+2AKyff5zTAEMiZYAAAAIAPL+FAePBgMAFwArADIANgA6AFYAXQBkAR8AsBIvsR4B6bAzL7EsXDMzsTcC6bBeMrA6L7BjM7E0AumxMFcyMrAoL7QGAgBFBCuyBigKK7NABgQJK7AIMrBHL7FIAumzS0hHCCuxRALpsDsysEgQsE8g1hGxQALpAbBlL7AA1rQYBABLBCuwGBCxLAErtDIDAAsEK7AyELEzASu0NwQAaQQrsDcQsTsBK7E8BOmwPBCxOAErtDYEAGkEK7A2ELFdASu0XgQAaQQrsF4QsV8BK7FcBOmwXBCxIwErtA0EAEsEK7FmASuxOzcRErEGBTk5sDwRsR4SOTmwOBKxBwg5ObA2EbBRObFeXRESsE85sF8RsE45sQ0jERKyDkRLOTk5ALEeEhESsBQ5sDMRsBw5sU9IERKwUzkwMRcRNDYzIRczNyEyFhURDgMjIi4DNxQeAzMyPgI1ETQmIyEiBhUTETQ2OwERNxEhESUzESMTMzQ3NjsBMhYzMjYzNSIGIyImKwEiJg4CBwYTMx4BFREhNyERNCYrAfLlnAEeLU4rARmg9Qh/3/Gahb/VhV5MUnzDrHOH1dFyuo39N42yTZaDaCkBXf7d6elORSMZqpUX8TE1mAYdkyMd7y2VCFAhPikOPf5we5j+fzkBBHd3FkoEH4/qKSnbjPvPfaxWIw0xWJ6+XIVKKwwaSJRsA5qJx7mX/i8BiYG2/UACAr79QkwCKwEpHxoQRSlJKUQCAgQOCy7+2AKyff5zTAEMiZYAAAAIAPL+FAePBgMAFwArADIAOAA8AFgAXwBmARcAsBIvsR4B6bAsL7E5XjMzsTMC6bBgMrA2L7BlM7EwAumxOlkyMrAoL7QGAgBFBCuyBigKK7NABgQJK7AIMrBJL7FKAumzTUpJCCuxRgLpsD0ysEoQsFEg1hGxQgLpAbBnL7AA1rQYBABLBCuwGBCxLAErsTME6bAzELE0ASu0MgQAaQQrsDIQsTkBK7Q8AwAMBCuzPTw5CCuxPgTpsDwQsV8BK7RgBABpBCuwYBCxYQErsV4E6bBeELEjASu0DQQASwQrsWgBK7E9ORESsQYFOTmwPhGxHhI5ObA8ErIHCFM5OTmxYF8RErBRObBhEbBQObENIxESsg5GTTk5OQCxHhIRErAUObAsEbAcObFRShESsFU5MDEXETQ2MyEXMzchMhYVEQ4DIyIuAzcUHgMzMj4CNRE0JiMhIgYVExE0NjsBESUhESMiEQERIREDMzQ3NjsBMhYzMjYzNSIGIyImKwEiJg4CBwYTMx4BFREhNyERNCYrAfLlnAEeLU4rARmg9Qh/3/Gahb/VhV5MUnzDrHOH1dFyuo39N42yTZaDaP7DAQQS8gFmAV3VRSMZqpUX8TE1mAYdkyMd7y2VCFAhPikOPf5we5j+fzkBBHd3FkoEH4/qKSnbjPvPfaxWIw0xWJ6+XIVKKwwaSJRsA5qJx7mX/i8BiYG2/UBOAiv+7f6cAr79QgOgHxoQRSlJKUQCAgQOCy7+2AKyff5zTAEMiZYAAAAIAPL+FAePBgMAFwArADIAOAA8AEAAXABjARsAsBIvsR4B6bA5L7EsYjMzsT0C6bAzMrA2L7A/M7EwAumxOl0yMrAoL7QGAgBFBCuyBigKK7NABgQJK7AIMrBNL7FOAumzUU5NCCuxSgLpsEEysE4QsFUg1hGxRgLpAbBkL7AA1rQYBABLBCuwGBCxLAErsTME6bAzELE0ASu0MgQAaQQrsDIQsTkBK7Q9BABpBCuwPRCxQQErsUIE6bBCELE+ASu0PAQAaQQrsDwQsWMBK7RiAwALBCuwYhCxIwErtA0EAEsEK7FlASuxQT0RErEGBTk5sEIRsR4SOTmwPhKxBwg5ObA8EbBXObFiYxESsVVUOTmxDSMRErIOSlE5OTkAsR4SERKwFDmwORGwHDmxVU4RErBZOTAxFxE0NjMhFzM3ITIWFREOAyMiLgM3FB4DMzI+AjURNCYjISIGFRMRNDY7ARElIREjIhEBESERJTMRIxMzNDc2OwEyFjMyNjM1IgYjIiYrASImDgIHBhMzHgEVESHy5ZwBHi1OKwEZoPUIf9/xmoW/1YVeTFJ8w6xzh9XRcrqN/TeNsk2Wg2j+wwEEEvIBZgFd/t3p6U5FIxmqlRfxMTWYBh2TIx3vLZUIUCE+KQ49/nB7mP5/SgQfj+opKduM+899rFYjDTFYnr5chUorDBpIlGwDmonHuZf+LwGJgbb9QE4CK/7t/pwCvv1CTAIrASkfGhBFKUkpRAICBA4LLv7YArJ9/nMAAAcA8v4UB48GAwAXACsAMgA2ADoAVgBdAQoAsBIvsR4B6bAzL7EsXDMzsTcC6bA6L7E0AumxMFcyMrAoL7QGAgBFBCuyBigKK7NABgQJK7AIMrBHL7FIAumzS0hHCCuxRALpsDsysEgQsE8g1hGxQALpAbBeL7AA1rQYBABLBCuwGBCxLAErtDIDAAsEK7AyELEzASu0NwQAaQQrsDcQsTsBK7E8BOmwPBCxOAErtDYEAGkEK7A2ELFdASu0XAMACwQrsFwQsSMBK7QNBABLBCuxXwErsTs3ERKxBgU5ObA8EbEeEjk5sDgSsQcIOTmwNhGwUTmxXF0RErFPTjk5sQ0jERKyDkRLOTk5ALEeEhESsBQ5sDMRsBw5sU9IERKwUzkwMRcRNDYzIRczNyEyFhURDgMjIi4DNxQeAzMyPgI1ETQmIyEiBhUTETQ2OwERNxEhESUzESMTMzQ3NjsBMhYzMjYzNSIGIyImKwEiJg4CBwYTMx4BFREh8uWcAR4tTisBGaD1CH/f8ZqFv9WFXkxSfMOsc4fV0XK6jf03jbJNloNoKQFd/t3p6U5FIxmqlRfxMTWYBh2TIx3vLZUIUCE+KQ49/nB7mP5/SgQfj+opKduM+899rFYjDTFYnr5chUorDBpIlGwDmonHuZf+LwGJgbb9QAICvv1CTAIrASkfGhBFKUkpRAICBA4LLv7YArJ9/nMAAAAAAwF5/g4HdQYDABIAJQBBAJ8AsBAvsRkB6bAiL7QGAgBFBCuwMi+xMwLpszYzMggrsS8C6bAmMrAzELA6INYRsSsC6QGwQi+wANa0EwQASwQrsBMQsSYBK7EnBOmwJxCxHgErtA0EAEsEK7FDASuxEwARErESAjk5sCYRsQYFOTmwJxKyEBkiOTk5sB4RswcIOTwkFzmwDRKxCw45OQCxLwYRErAKObE6MxESsD45MDEFET4BPwEXMzcXHgEXEQYEISAkExQeAzMyPgI1ETQkISIEFQEzNDc2OwEyFjMyNjM1IgYjIiYrASImDgIHBgF5COOWexh3F3TdsQgI/sL+/P74/q5KL1CNkW+Dqo1C/v7+9uf+6wHdSCAZrJMZ8jE1lgYdkSMd8S6TCFAhPSkPP1oEL5zRBAQNDQQIq6z70c/b0QEfVntIJwwXQ4hqA7i8kqKsAbshGBBFKUkpRAICBA4LLgAHANX+DgbRBgMAEgAlACwAMgBOAFUAXAD9ALAQL7EZAemwJi+wVDOxLQLpsFYysDAvsFszsSoC6bBPMrAiL7QGAgBFBCuwPy+xQALps0NAPwgrsTwC6bAzMrBAELBHINYRsTgC6QGwXS+wANa0EwQASwQrsBMQsSYBK7EtBOmwLRCxLgErtCwEAGkEK7AzMrAsELFVASuwNDK0VgQAaQQrsFYQsVcBK7FUBOmwVBCxHgErtA0EAEsEK7FeASuxEwARErESAjk5sSwuERKxBQY5ObBVEbIQGSI5OTmwVhKxBwg5ObBXEbFJRzk5sFQSsEY5sQ0eERKxCw45OQCxJhkRErAXObE8BhESsAo5sUdAERKwSzkwMRcRPgE/ARczNxceARcRBgQhICQTFB4DMzI+AjURNCQhIgQVExE0NjsBESUhESMiEQEzNDc2OwEyFjMyNjM1IgYjIiYrASImDgIHBhMzMhYVESE3IRE0JisB1QjklXsYdxd13bAICP7C/vz++P6uSi9QjZJug6qOQf7+/vbn/utMlYNz/rgBDx3yAU5IIRmrlBnxMTWWBh2RIx3xLZQIUCE9KQ5ATHt7l/51OQEPd3chWgQvnNEEBA0NBAirrPvRz9vRAR9We0gnDBdDiGoDuLySoqz+IwGJgbf9P04CK/7tAjIhGBBFKUkpRAICBA4LLv7jtX3+c0wBDImWAAAABgDV/g4G0QYDABIAJQAsAEgATwBWAPUAsBAvsRkB6bBPL7AmM7FQAumwVi+xSQLpsCoysCIvtAYCAEUEK7A5L7E6AumzPTo5CCuxNgLpsC0ysDoQsEEg1hGxMgLpAbBXL7AA1rQTBABLBCuwExCxJgErtCwDAAsEK7AsELEtASuxLgTpsC4QsU8BK7RQBABpBCuwUBCxUQErsU4E6bBOELEeASu0DQQASwQrsVgBK7ETABESsRICOTmxLCYRErEGBTk5sS4tERKyEBkiOTk5sVBPERKxBwg5ObBREbFDQTk5sE4SsEA5sQ0eERKxCw45OQCxTxkRErAXObE2BhESsAo5sUE6ERKwRTkwMRcRPgE/ARczNxceARcRBgQhICQTFB4DMzI+AjURNCQhIgQVExE0NjsBERMzNDc2OwEyFjMyNjM1IgYjIiYrASImDgIHBhMzMhYVESE3IRE0JisB1QjklXsYdxd13bAICP7C/vz++P6uSi9QjZJug6qOQf7+/vbn/utMlYNzBkghGauUGfExNZYGHZEjHfEtlAhQIT0pDkBMe3uX/nU5AQ93dyFaBC+c0QQEDQ0ECKus+9HP29EBH1Z7SCcMF0OIagO4vJKirP4jAYmBt/0/A5ghGBBFKUkpRAICBA4LLv7jtX3+c0wBDImWAAAABgDV/g4G0QYDABIAJQAsADIATgBVAOoAsBAvsRkB6bAmL7BUM7EtAumwMC+xKgLpsE8ysCIvtAYCAEUEK7A/L7FAAumzQ0A/CCuxPALpsDMysEAQsEcg1hGxOALpAbBWL7AA1rQTBABLBCuwExCxJgErsS0E6bAtELEuASu0LAQAaQQrsCwQsTMBK7E0BOmwNBCxVQErtFQDAAsEK7BUELEeASu0DQQASwQrsVcBK7ETABESsRICOTmxLC4RErEFBjk5sTQzERKyEBkiOTk5sVRVERKzB0YISSQXObENHhESsQsOOTkAsSYZERKwFzmxPAYRErAKObFHQBESsEs5MDEXET4BPwEXMzcXHgEXEQYEISAkExQeAzMyPgI1ETQkISIEFRMRNDY7ARElIREjIhEBMzQ3NjsBMhYzMjYzNSIGIyImKwEiJg4CBwYTMzIWFREh1QjklXsYdxd13bAICP7C/vz++P6uSi9QjZJug6qOQf7+/vbn/utMlYNz/rgBDx3yAU5IIRmrlBnxMTWWBh2RIx3xLZQIUCE9KQ5ATHt7l/51WgQvnNEEBA0NBAirrPvRz9vRAR9We0gnDBdDiGoDuLySoqz+IwGJgbf9P04CK/7tAjIhGBBFKUkpRAICBA4LLv7jtX3+cwAABQDV/g4G0QYDABIAJQAsAEgATwDbALAQL7EZAemwJi+wTjO0KgEABwQrsEkysCIvtAYCAEUEK7A5L7E6AumzPTo5CCuxNgLpsC0ysDoQsEEg1hGxMgLpAbBQL7AA1rQTBABLBCuwExCxJgErtCwDAAsEK7AsELEtASuxLgTpsC4QsU8BK7ROAwALBCuwThCxHgErtA0EAEsEK7FRASuxEwARErESAjk5sSwmERKxBgU5ObEuLRESshAZIjk5ObFOTxESswdACEMkFzmxDR4RErELDjk5ALEmGRESsBc5sTYGERKwCjmxQToRErBFOTAxFxE+AT8BFzM3Fx4BFxEGBCEgJBMUHgMzMj4CNRE0JCEiBBUTETQ2OwEREzM0NzY7ATIWMzI2MzUiBiMiJisBIiYOAgcGEzMyFhURIdUI5JV7GHcXdd2wCAj+wv78/vj+rkovUI2SboOqjkH+/v725/7rTJWDcwZIIRmrlBnxMTWWBh2RIx3xLZQIUCE9KQ5ATHt7l/51WgQvnNEEBA0NBAirrPvRz9vRAR9We0gnDBdDiGoDuLySoqz+IwGJgbf9PwOYIRgQRSlJKUQCAgQOCy7+47V9/nMABgD2/k4K9gYIAA8AHQAhACUAKQAtAWsAsA0vsRIB6bApL7AhL7AtL7AfL7ArL7AjL7AaL7EEAukBsC4vsADWsRAE6bAQELEeASuxIgErsSYBK7EkASuxKAErsSwBK7EWASuxCQPpsS8BK7A2GrAmGgGxIR4uyQCxHiEuyQGxIyQuyQCxJCMuybA2GrAmGgGxKSguyQCxKCkuybA2Grr2P8C/ABUrCgWwHhCxHwz5sCYaAbEtLC7JALEsLS7JsDYauvY3wMEAFSsKsC0QsCLAuj3R728AFSsKsCkQsSYO+QWwK8C6PgzwTgAVKwuwIRCzICEkEyuxISQIsB8QsyAfKBMruj4M8E4AFSsLsCEQsyUhJBMrsSEkCLAiELMlIi0TK7r2HMDFABUrC7AfELMnHygTK7EfKAiwJhCzJyYrEyu69jLAwQAVKwuwIhCzKiItEyuxIi0IsCYQsyomKxMrALUgIiUmJyouLi4uLi4BtR8gJScqKy4uLi4uLrBAGgEAMDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBEwUDARMFCwETBQMBEwUD9ot9B8ePom2H9/yLfUm/B4lcTqr4d1xjAihiAbla/rJcAbFUIl0BumL+uVYBwFqsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7+wFYRP6mAeoBTEP+sf5SAVtJ/qoB6AFMRP6zAAAAAAMA9v5ODo8GCAAPAB0AJABUALANL7ESAemwIy+0IAIAWwQrsBovsQQC6QGwJS+wANaxEATpsBAQsRYBK7EJA+mxJgErsRYQERKxHiE5OQCxIxIRErAkObAgEbAeObAaErAfOTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVEyUHIRUhF/aLfQtgj6Jsh/Rii31JvwsjXE6q9N1cY94B5wYGHfnjBqwFrH+Jg4X6VI15fciqTlwFbb5iXP1e9MdaxAAACQD2/k4OzQYIAA8AHQBOAHgAmwDSAOEA6gDtAAAXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNj8BHgEzMjU0JicuBDU0NjMyFh8CBgcjLgEjIgYVFBceAxUUBiMiJi8BATQ2OwE0Jzc2NzIXBhUzMhcVFAcjFRQGFRQzMjcWFQYnIiY1NDY9ASMiJTc2NzIVBzM+ATMyHwEPASYjIg4CHQEUFwcmIwc1Nj0BNAE0Ny4BNTQ3JyY1NDYzMhc+ATcXBhUUFwcmJx4CFRQGIyIvAQYVFB4BMzc2NzIeARUUBCMiJjcUFjMyNjU0IyIOASMOARMUMzI2NTQnIhMzI/aLfQuej6Jth/Qli31JvwtgXE6q9KBcYwEDFBARI7ZasEFSOVNqRC/RllqXHx8CFwwOJZRWRk2+RF5zPdXAXKwoKAMrFAxUCgI3fw4BCKUMASWNBDM5Lx1Wg0ZOBGAUAnQCcUwOBAQhbDIZJgYeDRs9DiMxHw8DOzNiDgIEhyUxQAk/onsrL0K6FgYGBgYJpBgmFZOBUiUMGR8cHS1GGlCDZ/7npGakplwzZJDRCCIsEykgKXkvPX9mIQIBrAWsf4mDhfpUjXl9yKpOXAVtvmJc+7g9dQNIaahaWRwUITo7WDF3kiESEQY7dUxkUEaHPRcrR2k/fa4gEhECIxAraEIEBDIPdWAKMxQBnzOUEm8dEiZOAVo7EsUzsD4ECB8QczNQDASQBBcJFjkpf7BnBAQEBGK1VJH9UmRWCj4vZDoKMW9ihw4EFgMFFB0XFgQBDhIzPB1ighcGKTMfIQQECAEhYEp1j1R5RkhcRnMDAyE6Akq2RU6yAf2CAAAAAAYAzf5ODAAGCAAPAB0ANAA+AFIAfAEvALANL7ESAemwcy+1HiUpMU9SJBcztG0CACgEK7AtL7E4Aumwey+wZjOxVgLpsGAysBovsQQC6QGwfS+wANaxEATpsBAQsR4BK7QxAwAaBCuwMRCxKQErtCUDACMEK7AlELFEASuwPzKxSQPpsE4ys0xJRAgrsUED6bBBL7FMA+mwSRCxeQErsVd2MjKxaAPpsV5rMjKyaHkKK7NAaGQJK7J5aAors0B5UwkrsGgQsRYBK7EJA+mxfgErsSkxERKzISA1OyQXObAlEbAjObFBRBESsUVSOTmwTBGwUTmwSRKxR085ObB5EbBaObBoErFcczk5sBYRsm1wcTk5OQCxbXMRErUnMz9OUXEkFzmwLRGya292OTk5sDgSsCM5sRpWERK2ICE9REdJXCQXOTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVExITMxYaARcmIyIHJicmIyIHBgcmIyIBMhYzMjY3JicCATY1ETQnNzY3MhUGFREUFwcmIwcBNDY7ATQnNzY3MhUGFTMyHQEUKwEVFAYVFDMyNxYHBiMiJjU0Nj0BIyLNi30I+o+ibYf2yYt9Sr4IvFxOqvdEXGLl3ehsNb+PIRtiUhsjT2UzW3FaHxI0RAEnFnIYGUMkPk9vAt4REQRzUA4QEAQxNWkBdRUMVAoCN38OCKYMJY0EMzkwHQFWg0ZNBGAUrAWsf4mDhfpUjXl9yKpOXAVtvmJc+1AB3wIXf/4p/qNDBASA1QME3nYEAagEAQGitf8A/gNe1QGwyVgGCB0OfaT+M89kBAQEAmAQLGhCBAQxDnVgCzMUoDOUEm8dEiVOWjsSxTOxAAAACADN/k4SmgYIAA8AHQA0AD8AUwB9AKMAxgIMALANL7ESAemwoS+2HiUpMVBTdCQXM7SQAgB6BCu0bgIAKAQrsC0vsTkC6bB8L7BnM7FXAumwYTKwVxCzFFeuDiuwpzOxtQHpsIsvtIECAHoEK7AgMrAaL7EEAukBsMcvsADWsRAE6bAQELEeASu0MQMAGgQrsDEQsSkBK7QlAwAkBCuwJRCxQgErsU0D6bJNQgors0BNSgkrskJNCiuzQEJFCSuwTRCxegErsVh3MjKxaQPpsV9sMjKyaXoKK7NAaWUJK7J6aQors0B6VAkrsGkQsX4BK7SOAwA4BCuwjhCxkwErsZwD6bOInJMIK7SJBAAxBCuwiS+0iAQAMQQrsJwQscQBK7G7A+mwqTKyxLsKK7NAxKQJK7C7ELEWASuxCQPpscgBK7EpMRESsyEgNTwkFzmwJRGwIzmwQhKyQEZTOTk5sE0RsFI5sHoSs0hPUFskFzmwaRGxXXQ5ObB+ErFucjk5sZOOERKzgZWWoSQXObGciBESsYWGOTmwxBG0mZ6fpcEkFzmwuxKyp6vAOTk5sBYRsrG9vjk5OQCxkKEREkAKJzNAT1Jyvb7AwSQXObEtbhEStWxwd5KenyQXObA5EbAjObC1Erd+jpWWmJmysyQXObB8EbGqqzk5sFcSsaSmOTmwrhGwsTmwixK1Wl1fiD6JJBc5sIERsUuGOTmwGhKyRUhKOTk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUTEhMzFhoBFyYjIgcmJyYjIgcGByYjIgEyHgEzMjY3JicCATY1ETQnNzY3MhcGBxEUFwcmIwcBNDY7ATQnNzY3MhcGFTMyFxUUKwEVFAYVFDMyNxYVBiMiJjU0Nj0BIyIFNAAzMhYfAgYPASYnIgYVECEyNzU0JzcWMzcVBgcUFxUGISIAATc2NzIXBzM+ATMyHwEPASYjIg4CHQEUFwcmIwc1Nj0BNM2LfQ+Tj6Nth/Avi31Kvg9WXE6q8KpcYtDd6G01vpAgG2JSGiNPZTNccVofEjREASgUPjoUGUIlP09vAt8QEARzTw4BEAERBDE2aAF1FAxUCgI3fw4BCKUMASWNBTQ5Lx1Wg0ZOBGAUAo0BKfpSuDIyBBsDJ2DkjaIBTJE8DwI7NHEOAQ+k/uH8/vYEpgJxSw4BBAQhbDEXKQYfDBs9DiQxHg4COzRiDqwFrH+Jg4X6VI15fciqTlwFbb5iXPtQAd8CF3/+Kf6jQwQEgNUDBN52BAGoAgIBAaK1/wD+A17VAbDJWAYIHQ59pP4zz2QEBAQCYBAsaEIEBDEOdWALMxSgM5QSbx0SJU5aOxLFM7Fb+AEPIRIRBmZhAr4B4Mj+UDk1vGcGBgYGXqY/FQSJASQBbQQIHxBzM1AMBJAEFwgXOSl/sGcEBAQEYrVUkQAAAAYA9v5OEmYGCAAPAB0AOgBkAIcAmwGSALANL7ESAemwOC+wWzO0MQIAJgQrsFUysGMvsE4zsT4C6bBIMrA+ELMUPm8OK7BoM7F2AemwKy+0IQIAWwQrsBovsQQC6QGwnC+wANaxEATpsBAQsR4BK7QuAwAuBCuwLhCxKQErtCgEADEEK7AoELFhASuxP14yMrFQA+mxRlMyMrJQYQors0BQTAkrsmFQCiuzQGE7CSuwUBCxhQErsXwD6bBqMrB8ELFlA+mwZS+wfBCxjQErsIgysZID6bCXMrOVko0IK7GKA+mwii+xlQPpsJIQsRYBK7EJA+mxnQErsSkuERKyITE4OTk5sWEoERK0JSY0NUIkFzmwUBGwRDmwZRKxVVk5ObCFEbFmgjk5sHwSsmhsgTk5ObCNEbJyfn85OTmwihKxjps5ObCVEbCaObCSErGQmDk5ALExOBESt1l+f4GCiJeYJBc5sHYRQAkuHjQ1U1dec3QkFzmwYxKxa2w5ObA+EbFlZzk5sG8SsHI5sCsRtCgpQURHJBc5sCESsCY5sBoRso2Qkjk5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATQAMzIWHwIGDwEmJyIGFRQWMzI2NxcOASMiAAE0NjsBNCc3NjcyFwYHMzIXFRQrARUUBhUUMzI3FhUGJyImNTQ2PQEjIiU3NjcyFQczPgEzMh8BDwEmIyIOAh0BFBcHJiMHNTY3NTQBNjURNCc3NjcyFQYVERQXByYjB/aLfQ83j6Jsh/CLi31Jvw76XE6q8QZcYwEXATHhUrAvLgQbBCVc2XGsmJlxpk4jTOZy8P78BBAVDFQKAjd/DgEIAaYMASWOBDM5MB1WhEZNBGAUAsYCcUwOBAQhbDEZJwYfDBs9DiMxHw4COzNjDgECZBAQBHNQDhAQBDE2aKwFrH+Jg4X6VI15fciqTlwFbb5iXP1K5QEXIRIRBmZhArgBwdW27ERWOmJsASABRhAraEIFBDEPdWAKMxSgM5QSbx0SJk4BWjsSxTOxPQQIHxBzM1AMBJAEFwkWOSmGsGYEBAQEYrRbkf3+XtUBuMlYBggdDn2k/ivPZAQEBAAEAPb+Tgr2BggADwAdACQAKwCEALANL7ESAemwIy+xJwLpsCQvsCAzsSUC6bApMrAaL7EEAukBsCwvsADWsRAE6bAQELEjASu0JwQASwQrsCcQsSgBK7QiBABLBCuwIhCxFgErsQkD6bEtASuxIxARErEeJTk5sSgnERKxHys5ObEWIhESsSAqOTkAsRolERKxHys5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVEwkBIREhESczESERMwH2i30Hx4+ibYf3/It9Sb8HiVxOqvh3XGPgAgoCCv7Z/jp7zQEiz/6grAWsf4mDhfpUjXl9yKpOXAVtvmJc/HcCuP1I/tcBKVL+1wEpAdsAAAAEAPb+Tgr2BggADwAdACkANQC4ALANL7ESAemwKi+xKwLpsiorCiuzQCoyCSuyKyoKK7NAKy8JK7AmL7EjAumyJiMKK7NAJh4JK7IjJgors0AjHwkrsBovsQQC6QGwNi+wANaxEATpsBAQsR4BK7QpBABLBCuwIDKwKRCxMgErsC4ytDEEAEsEK7AxELEWASuxCQPpsTcBK7EyKRESsSQqOTkAsSoSERKwNDmwKxGxLjM5ObAmErEnLTk5sCMRsSEoOTmwGhKwIjkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFRMRMxUlByEVIRclFRM1IScFNTMRIzUFN/aLfQfHj6Jth/f8i31JvweJXE6q+HdcY6ZSAXUGAqb9Wgb+i20CpgYBdFJS/owGrAWsf4mDhfpUjXl9yKpOXAVtvmJc/dUBnru7plKmurr91VKkubn+Zri4pAADAPb+Tgr2BggAFwAsADUAlQCwDS+xIQHpsBUvsRoB6bA0L7QvAgBbBCuyLzQKK7NALzEJK7ApL7EEAukBsDYvsADWsRgE6bAYELEQASuxHwTpsB8QsTABK7QzBAAuBCuwMxCxJQErsQkD6bE3ASuxEBgRErQVGy0vNCQXObAfEbEuNTk5ALEVIRESsRAeOTmxNBoRErA1ObAvEbAtObApErAuOTAxExE0NjMhMhYVERQGIyEiJj0BNCYjISImNxQzITIWHQEUMyEyNjURNCMhIgYVEyUHIREzESEX9ot9B8ePom2H+waLfUpg/qh5j0m/AU6Jdb4Ef1xOqvh3XGPeAecGA0ha/F4GAWgDmH+Jg4X6VI15fYlQQirPibx9ixGqTlwFbb5iXP3Z9McBuP3uxQAAAAQA9v5ODcMGCAAPAB0AJAArAIQAsA0vsRIB6bAlL7AnM7EfAumwIjKwKi+xIALpsBovsQQC6QGwLC+wANaxEATpsBAQsR8BK7QrBABLBCuwKxCxKAErtCIEAEsEK7AiELEWASuxCQPpsS0BK7EfEBESsR4lOTmxKCsRErEmJDk5sRYiERKxIyc5OQCxJRIRErEkJjk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUTIREhESEJAyMRIRH2i30Kk4+jbYf1L4t9Sb8KVlxOqvWqXGPgAScBxgEn/fb+oAFgAV7N/t6sBax/iYOF+lSNeX3Iqk5cBW2+Ylz+BgEp/tf9SAJm/iUB2wEp/tcAAAQA9v5OCewGCAAPAB0ARQBbAN8AsA0vsRIB6bA+L7E0AumwWy+0RgIAfQQrskZbCiuzQEZICSuwMS+0JgIAXQQrsBovsQQC6QGwXC+wANaxEATpsBAQsSABK7E/A+mwMzKwPxCxVgErsU0D6bJNVgors0BNSgkrsE0QsRYBK7EJA+mxXQErsSAQERKzHiMkRSQXObA/EbBEObBWErYpKjdBQkZTJBc5sE0RsFI5sBYSskhPUDk5OQCxPhIRErceOzxCT1BSUyQXObA0EbA5ObBbErE2Nzk5sEYRsFk5sDESsS4vOTmwJhGzIyosSiQXOTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY3ETQnNxYzITI3FwYVFBcHJiMGBxUyNxcGFRQXByYjFRQXByYjBwE2JTIVBhURFBcHJiMHNTY1ETQnIgf2i30GvI+jbYf5Bot9Sb8Gf1xOqvmBXGMBeRABEQQ5NgGcOyUEBAQEwcwMAW/TBgYGBqiaEQQ5NnEDEW0BEgoQEgQzOGgQHFJUrAWsf4mDhfpUjXl9yKpOXAVtvmJc+1RtxgF3wXIGBgYGKQwXGAYSLa53DwUXGh8UBBCywXIGBgYDNxlaBqRW/n2qdwQEBARivwF0ZAEKAAAABAD2/k4J7AYIAA8AHQBFAG0A5QCwDS+xEgHpsGovsEIzsWIB6bA+L7E0AumwMS+0JgIAXQQrs1gmMQgrsVAC6bAaL7EEAukBsG4vsADWsRAE6bAQELEgASuxPwPpsDMysD8QsU0BK7FbA+mxZGgyMrBbELEWASuxCQPpsW8BK7EgEBESsx4jJEUkFzmwPxGwRDmwTRJACykqN0FCRlRYX2FqJBc5sFsRsV5mOTkAsWoSERKyHkFGOTk5sGIRsGY5sD4StTs8SUpeZCQXObA0EbE5Szk5sFAStTY3TVJVWyQXObAxEbEuLzk5sSZYERKyIyosOTk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNjcRNCc3FjMhMjcXBhUUFwcmIwYHFTI3FwYVFBcHJiMVFBcHJiMHJTQ2PwE+ATU0JiMiByMnNz4BMzIWFRQGDwEGFTMyNwYVFBcmIyIGI/aLfQa8j6Nth/kGi31JvwZ/XE6q+YFcYwF5EAERBDk2AZw7JQQEBATBzAwBb9MGBgYGqJoRBDk2cQKzWHpzPSFWLXdJJSEEI6BMkbRDUJpmf2qwCAisXET/K6wFrH+Jg4X6VI15fciqTlwFbb5iXPtUbcYBd8FyBgYGBikMFxgGEi2udw8FFxofFAQQssFyBgYGBj97f3E/c1pCWoF5Bh03eXdQaEyTYCMMKTsfKQYGAAAEAPb+TgnsBggADwAdAEUAcwD7ALANL7ESAemwcS+xTALpsD4vsTQC6bNWND4IK7FVAumwMS+0JgIAXQQrs2UmMQgrsVwC6bAaL7EEAukBsHQvsADWsRAE6bAQELEgASuxPwPpsDMysD8QsVEBK7FuA+mwWSDWEbFoA+myWWgKK7NAWVYJK7BuELEWASuxCQPpsXUBK7EgEBESsx4jJEUkFzmwPxGwRDmwWRJADSkqN0FCRkxTYWVqa3EkFzkAsUxxERKyQR5COTk5sFURs0ZIUW4kFzmwPhKxOzw5ObBWEbFqbDk5sDQSsDk5sFwRtTY3WV9iaCQXObAxErEuLzk5sSZlERKyIyosOTk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNjcRNCc3FjMhMjcXBhUUFwcmIwYHFTI3FwYVFBcHJiMVFBcHJiMHJT8BHgIzMj4CNTQjIgc1PgE1NCYjIgYHLwE3PgEzMhYVFAcVHgEVFAYjIif2i30GvI+jbYf5Bot9Sb8Gf1xOqvmBXGMBeRABEQQ5NgGcOyUEBAQEwcwMAW/TBgYGBqiaEQQ5NnEC0yMlIxhGNxkxOSOoKRJvZEItTEkrJR8EI5xQd522XoPbnJFnrAWsf4mDhfpUjXl9yKpOXAVtvmJc+1RtxgF3wXIGBgYGKQwXGAYSLa53DwUXGh8UBBCywXIGBgZSeQI7KCURJ1g/sgJGBl5hO1I7TAJ5Bh03XmW6LwYIcWeTj1YAAAUA9v5OCewGCAAPAB0ARQBnAGoA7wCwDS+xEgHpsGQvsFkztGgCACkEK7BTMrA+L7E0AumwMS+0JgIAXQQrsBovsQQC6QGway+wANaxEATpsBAQsSABK7E/A+mwMzKwPxCxYwErsGkysVoD6bBSMrJaYwors0BaVgkrsFoQsRYBK7EJA+mxbAErsSAQERKzHiMkRSQXObA/EbBEObBjEkAKKSo3QUJGSWBhaCQXObBaEbJMS185OTmwFhKzT1BcXSQXOQCxZBIRErMeQUJdJBc5sGgRsEg5sD4Ssjs8STk5ObA0EbA5ObAxErQuLzY3aiQXObAmEbcjKixLTE5PUCQXOTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY3ETQnNxYzITI3FwYVFBcHJiMGBxUyNxcGFRQXByYjFRQXByYjByU0NzYANzUWMzcXBhURMzIVFAYrARQXByYjByc2NSEjIiY3IRH2i30GvI+jbYf5Bot9Sb8Gf1xOqvmBXGMBeRABEQQ5NgGcOyUEBAQEwcwMAW/TBgYGBqiaEQQ5NnEChRFCAQRDEjpmBBBvFB0OWBAELzdpAhP+xgwoHXQBF6wFrH+Jg4X6VI15fciqTlwFbb5iXPtUbcYBd8FyBgYGBikMFxgGEi2udw8FFxofFAQQssFyBgYG/DEWWAGQcwQEBAR7a/6UHxA2ZnsEBAQEg14GXwG4AAAEAPb+TgnsBggADwAdAEUAagEeALANL7ESAemwaC+xSwLpsFEvsD4ztGICAEQEK7A2MrE0AumwYDKwXS+wXzOxVwHpsFUyszFXXQgrtCYCAF0EK7AaL7EEAukBsGsvsADWsRAE6bAQELEgASuxPwPpsDMysD8QsU4BK7FlA+mwZRCxFgErsQkD6bFsASuwNhq6P6r5bwAVKwqwVS6wYC6wVRCxXwj5DrBgELFUCPkAsFQuAbNUVV9gLi4uLrBAGgGxIBARErMeIyRFJBc5sD8RsEQ5sE4SQAkpKjdBQkZdYmgkFzmwZRGyWVpbOTk5ALFLaBESskEeQjk5ObBREbY7PEhOU2VqJBc5sDQSsDk5sGIRsDc5sTFdERKyLi9bOTk5sSZXERK0IyosWVokFzkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NxE0JzcWMyEyNxcGFRQXByYjBgcVMjcXBhUUFwcmIxUUFwcmIwclPwEeATMyNjU0JiMiBycTFhcyNxcHBiMiJwc2MzIWFRQGIyIn9ot9BryPo22H+QaLfUm/Bn9cTqr5gVxjAXkQAREEOTYBnDslBAQEBMHMDAFv0wYGBgaomhEEOTZxAuYeJSlSQDtWTkVOWCExhSdqsQoZVGpMZhdCTH2nvo+RZ6wFrH+Jg4X6VI15fciqTlwFbb5iXPtUbcYBd8FyBgYGBikMFxgGEi2udw8FFxofFAQQssFyBgYGUnkCSkJtaGZ1JAoBzQoBEQSYCAzfGahzkapWAAAFAPb+TgnsBggADwAdAEUAXQBtAOkAsA0vsRIB6bBaL7FhAumwai+wPjOxVALpsDQysDEvtCYCAF0EK7BMINYRsC8ztEsCAEUEK7AaL7EEAukBsG4vsADWsRAE6bAQELEgASuxPwPpsDMysD8QsUYBK7FeA+mwXhCxZAErsVcD6bBXELEWASuxCQPpsW8BK7EgEBESsx4jJEUkFzmwPxGwRDmwRhK0KSo3QUIkFzmxZF4RErJUWlI5OTmwVxGxS0w5OQCxYVoRErJBHkI5OTmwahGzO0ZXPCQXObBUErE5Ujk5sEwRsTY3OTmwMRKwLjmxJksRErIjKiw5OTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NxE0JzcWMyEyNxcGFRQXByYjBgcVMjcXBhUUFwcmIxUUFwcmIwcBND4CMxcOBAc2MzIWFRQGIyInJjcUFjMyNjU0LgMjIgcG9ot9BryPo22H+QaLfUm/Bn9cTqr5gVxjAXkQAREEOTYBnDslBAQEBMHMDAFv0wYGBgaomhEEOTZxAtxLju+SBCtAd1FREj1Too+emndJkbpUSi1FAhAdOSlGNQSsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VG3GAXfBcgYGBgYpDBcYBhItrncPBRcaHxQEELLBcgYGBgF5Wr6sbTcECy1GjWAppHFvsS9a9LiCa2gfK0MpISslAAAEAPb+TgnsBggADwAdAEUAWACyALANL7ESAemwPi+xNALpsDEvtCYCAF0EK7NOJjEIK7RXAQA8BCuwGi+xBALpAbBZL7AA1rEQBOmwEBCxIAErsT8D6bAzMrA/ELEWASuxCQPpsVoBK7EgEBESsx4jJEUkFzmwPxGwRDmwFhK2KSo3QUJGUSQXOQCxPhIRErYeOzxCU1RVJBc5sDQRsDk5sFcSsjY3Rjk5ObAxEbMuL0lRJBc5sSZOERK0IyosTFAkFzkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NxE0JzcWMyEyNxcGFRQXByYjBgcVMjcXBhUUFwcmIxUUFwcmIwcBNDY1NCY1FgUyNxcCAwcnNhMi9ot9BryPo22H+QaLfUm/Bn9cTqr5gVxjAXkQAREEOTYBnDslBAQEBMHMDAFv0wYGBgaomhEEOTZxAxsICFABezUtFc+MhQRr3ZOsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VG3GAXfBcgYGBgYpDBcYBhItrncPBRcaHxQEELLBcgYGBgMEAkIODD4ECgENH/4M/mUHDfECIwAAAAYA9v5OCewGCAAPAB0ARQBeAGsAdAEdALANL7ESAemwXS+0YgIARQQrsD4vsTQC6bAxL7QmAgBdBCuwcyDWEbRPAgBhBCuwGi+xBALpAbB1L7AA1rEQBOmwEBCxIAErsT8D6bAzMrA/ELFGASu0XwMALwQrsF8QsGwg1hG0TAMAJQQrsEwvtGwDACUEK7BfELFlASu0WQMAOgQrsHEg1hG0UgMAJQQrsFkQsRYBK7EJA+mxdgErsSAQERKzHiMkRSQXObA/EbBEObBGErQpKjdBQiQXObFsXxESsF05sHERtU9JYmlVcyQXObBlErBcOQCxYl0RErJBHkI5OTmwPhG1OzxGSVlpJBc5sDQSsTlVOTmwcxG0NjdMUm8kFzmwMRKxLi85ObEmTxESsiMqLDk5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY3ETQnNxYzITI3FwYVFBcHJiMGBxUyNxcGFRQXByYjFRQXByYjByU0NjcnJjU0NjMyFhUUBgcXHgEVFAcGICY3FBYzMjY1NCYvAQ4BExQfATY1NCMi9ot9BryPo22H+QaLfUm/Bn9cTqr5gVxjAXkQAREEOTYBnDslBAQEBMHMDAFv0wYGBgaomhEEOTZxAuJwbxuTj5B/i15jYT1Se1D+9rSsWDdKVDNISEIoKV4vVnNxrAWsf4mDhfpUjXl9yKpOXAVtvmJc+1RtxgF3wXIGBgYGKQwXGAYSLa53DwUXGh8UBBCywXIGBgblUnk5D1p/ZHVpWEheJz0pez+JTC99cFBiRmRCTysrL2oBxFY7HUJakQAFAPb+TgnsBggADwAdAEUAZAB2APQAsA0vsRIB6bBVL7RWAgBFBCuwYC+xawLpsD4vsTQC6bAxL7QmAgBdBCuzTSYxCCuxdALpsBovsQQC6QGwdy+wANaxEATpsBAQsSABK7E/A+mwMzKwPxCxRgErsWUD6bBlELFvASuxUQPpsFEQsRYBK7EJA+mxeAErsSAQERKzHiMkRSQXObA/EbBEObBGErQpKjdBQiQXObBlEbFVVjk5sG8Ssk1gXjk5OQCxVlURErJBHkI5OTmxa2ARErBeObA+EbI7PG05OTmwNBKyOVFvOTk5sHQRszY3RmUkFzmwMRKxLi85ObEmTRESsiMqLDk5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY3ETQnNxYzITI3FwYVFBcHJiMGBxUyNxcGFRQXByYjFRQXByYjBwE0PgQzMhcWFRQHBgUnPgY3BiMiLgI3FB4DMzI3NjU0LgIjIgb2i30GvI+jbYf5Bot9Sb8Gf1xOqvmBXGMBeRABEQQ5NgGcOyUEBAQEwcwMAW/TBgYGBqiaEQQ5NnEC2g8fNEJdNnhJkYKx/tkEHihRPE03MQ09UlV9QR6+Aw8dOilFNgQZMDIjLUasBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VG3GAXfBcgYGBgYpDBcYBhItrncPBRcaHxQEELLBcgYGBgKHIUJBOSsZL1v3uqDVAjcDBRQcOElxRSkyVFw9ICpEKSArJSBhgz4YbAAAAAAGAPb+TgwABggADwAdAEUAWwBnAHUBIQCwDS+xEgHpsGUvtGoCAH0EK7A+L7E0AumwWy+0RgIAfQQrsDEvtCYCAF0EK7NfJjEIK7BIM7RxAgCYBCuwGi+xBALpAbB2L7AA1rEQBOmwEBCxIAErsT8D6bAzMrA/ELFWASuxTQPpsk1WCiuzQE1KCSuwTRCxXAErsWgD6bBoELFsASuxYgPpsGIQsRYBK7EJA+mxdwErsSAQERKzHiMkRSQXObA/EbBEObBWErYpKjdBQkZTJBc5sE0RsFI5sFwSskhPUDk5ObFsaBESsWVfOTkAsWplERK1QR5CT1NQJBc5sD4RtDs8XGJoJBc5sDQSsTlsOTmwWxGxNjc5ObBGErBZObExcRESsS4vOTmwXxGwSjmwJhKyIyosOTk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNjcRNCc3FjMhMjcXBhUUFwcmIwYHFTI3FwYVFBcHJiMVFBcHJiMHATYlMhUGFREUFwcmIwc1NjURNCciBwE0EjMyFhUUBiMiAjcQMzIRNC4CIyIOAvaLfQjRj6Jth/byi31JvwiTXE6q921cYwF5EAERBDk2AZw7JQQEBATBzAwBb9MGBgYGqJoRBDk2cQMRbQESChASBDM4aBAcUlQB9MSBg73BhZyjtI2PCBg+LR8tLRisBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VG3GAXfBcgYGBgYpDBcYBhItrncPBRcaHxQEELLBcgYGBgM3GVoGpFb+fap3BAQEBGK/AXRkAQr+0NkBC/7X+OUBCrT+gwG4TG97QSBUtwAFAPb+TgwABggADwAdAEUAWwBxARoAsA0vsRIB6bA+L7E0AumwWy+wcTO0RgIAfQQrsFwyskZbCiuzQEZICSuwXjKwMS+0JgIAXQQrsBovsQQC6QGwci+wANaxEATpsBAQsSABK7E/A+mwMzKwPxCxVgErsU0D6bJNVgors0BNSgkrsE0QsWwBK7FjA+myY2wKK7NAY2AJK7BjELEWASuxCQPpsXMBK7EgEBESsx4jJEUkFzmwPxGwRDmwVhK2KSo3QUJGUyQXObBNEbBSObBsErRIT1BcaSQXObBjEbBoObAWErJeZWY5OTkAsT4SERJADB47PEJPUFJTZWZoaSQXObA0EbA5ObBbErE2Nzk5sEYRsllhbzk5ObAxErEuLzk5sCYRtCMqLEpgJBc5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNjcRNCc3FjMhMjcXBhUUFwcmIwYHFTI3FwYVFBcHJiMVFBcHJiMHATYlMhUGFREUFwcmIwc1NjURNCciByU2JTIVBgcRFBcHJiMHNTY1ETQnIgf2i30I0Y+ibYf28ot9Sb8Ik1xOqvdtXGMBeRABEQQ5NgGcOyUEBAQEwcwMAW/TBgYGBqiaEQQ5NnEDEW0BEgoQEgQzOGgQHFJUAkxtARIKEAETBDM4aBAcUlSsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VG3GAXfBcgYGBgYpDBcYBhItrncPBRcaHxQEELLBcgYGBgM3GVoGpFb+fap3BAQEBGK/AXRkAQpBGVoGpFb+fap3BAQEBGK/AXRkAQoAAAUA9v5ODAAGCAAPAB0ARQBbAIMBLwCwDS+xEgHpsIAvsUJQMzOxeAHpsD4vsTQC6bBbL7RGAgB9BCuwMS+0JgIAXQQrs24mMQgrsEgzsWYC6bAaL7EEAukBsIQvsADWsRAE6bAQELEgASuxPwPpsDMysD8QsVYBK7FNA+myTVYKK7NATUoJK7BNELFjASuxcQPpsXp+MjKwcRCxFgErsQkD6bGFASuxIBARErMeIyRFJBc5sD8RsEQ5sFYStikqN0FCRlMkFzmwTRGwUjmwYxJACUhPUFxqbnV3gCQXObBxEbF0fDk5ALGAEhESsx5BT1wkFzmweBGwfDmwPhK1OzxfYHR6JBc5sDQRsTlhOTmwWxK1NjdjaGlxJBc5sEYRsFk5sGYSsWprOTmwMRGxLi85ObBuErBKObAmEbIjKiw5OTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NxE0JzcWMyEyNxcGFRQXByYjBgcVMjcXBhUUFwcmIxUUFwcmIwcBNiUyFQYVERQXByYjBzU2NRE0JyIHATQ2PwE+ATU0JiMiByMnNz4BMzIWFRQGDwEGFTMyNwYVFBcmIyIEI/aLfQjRj6Jth/byi31JvwiTXE6q921cYwF5EAERBDk2AZw7JQQEBATBzAwBb9MGBgYGqJoRBDk2cQMRbQESChASBDM4aBAcUlQCGlh7cz0hVi13SSUhBCOgS5G1Q1CaZn9qsAgIrFxE/wArrAWsf4mDhfpUjXl9yKpOXAVtvmJc+1RtxgF3wXIGBgYGKQwXGAYSLa53DwUXGh8UBBCywXIGBgYDNxlaBqRW/n2qdwQEBARivwF0ZAEK/RA/e39xP3NaQlqBeQYdN3l3UGhMk2AjDCk7HykGBgAAAAAFAPb+TgwABggADwAdAEUAWwCJAUUAsA0vsRIB6bCHL7FiAumwPi+xNALps2w0PggrsWsC6bBbL7RGAgB9BCuwMS+0JgIAXQQrs3smMQgrsEgzsXIC6bAaL7EEAukBsIovsADWsRAE6bAQELEgASuxPwPpsDMysD8QsVYBK7FNA+myTVYKK7NATUoJK7BNELFnASuxhAPpsG8g1hGxfgPpsm9+CiuzQG9sCSuwhBCxFgErsQkD6bGLASuxIBARErMeIyRFJBc5sD8RsEQ5sFYStikqN0FCRlMkFzmwTRGwUjmwbxJAC0hPUFxiaXd7gIGHJBc5ALFihxEStUEeQk9TUCQXObBrEbNcXmeEJBc5sD4SsTs8OTmwbBGxgII5ObA0ErA5ObBbEbU2N291dn4kFzmwRhKwWTmwchGxd3g5ObAxErEuLzk5sHsRsEo5sCYSsiMqLDk5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY3ETQnNxYzITI3FwYVFBcHJiMGBxUyNxcGFRQXByYjFRQXByYjBwE2JTIVBhURFBcHJiMHNTY1ETQnIgcBPwEeAjMyPgI1NCMiBzU+ATU0JiMiBgcvATc+ATMyFhUUBxUeARUUBiMiJ/aLfQjRj6Jth/byi31JvwiTXE6q921cYwF5EAERBDk2AZw7JQQEBATBzAwBb9MGBgYGqJoRBDk2cQMRbQESChASBDM4aBAcUlQB8SMlIxlFNxkxOiKoKRJvZEItTEkrJR8EI5xQd522XoPbnJFmrAWsf4mDhfpUjXl9yKpOXAVtvmJc+1RtxgF3wXIGBgYGKQwXGAYSLa53DwUXGh8UBBCywXIGBgYDNxlaBqRW/n2qdwQEBARivwF0ZAEK/Vx5AjsoJREnWD+yAkYGXmE7UjtMAnkGHTdeZbovBghxZ5OPVgAGAPb+TgwABggADwAdAEUAWwB9AIABPQCwDS+xEgHpsHovsG8ztH4CACkEK7BpMrA+L7E0AumwWy+0RgIAfQQrskZbCiuzQEZICSuwZDKwMS+0JgIAXQQrsBovsQQC6QGwgS+wANaxEATpsBAQsSABK7E/A+mwMzKwPxCxVgErsU0D6bJNVgors0BNSgkrsE0QsXkBK7B/MrFwA+mwaDKycHkKK7NAcGwJK7BwELEWASuxCQPpsYIBK7EgEBESsx4jJEUkFzmwPxGwRDmwVhK2KSo3QUJGUyQXObBNEbBSObB5ErdIT1BcX3Z3fiQXObBwEbJiYXU5OTmwFhKzZWZycyQXOQCxehIRErceQUJPUFJTcyQXObB+EbBeObA+ErI7PF85OTmwNBGwOTmwWxKxNjc5ObBGEbFZgDk5sDESsS4vOTmwJhG2IyosSmFiZiQXOTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY3ETQnNxYzITI3FwYVFBcHJiMGBxUyNxcGFRQXByYjFRQXByYjBwE2JTIVBhURFBcHJiMHNTY1ETQnIgcBNDc2ADc1FjM3FwYHETMyFRQGKwEUFwcmIwcnNjUhIyImNyER9ot9CNGPom2H9vKLfUm/CJNcTqr3bVxjAXkQAREEOTYBnDslBAQEBMHMDAFv0wYGBgaomhEEOTZxAxFtARIKEBIEMzhoEBxSVAHXEEIBBEMSOmcEEAFvFBwPWBEELzhoAhL+xw0oHXUBFqwFrH+Jg4X6VI15fciqTlwFbb5iXPtUbcYBd8FyBgYGBikMFxgGEi2udw8FFxofFAQQssFyBgYGAzcZWgakVv59qncEBAQEYr8BdGQBCv4GMRZYAZBzBAQEBHtr/pQfEDZmewQEBASFXAZfAbgAAAAABQD2/k4MAAYIAA8AHQBFAFsAgAFvALANL7ESAemwfi+xYQLpsGcvsD4ztHgCAEQEK7A2MrE0AumwdjKwMS+0JgIAXQQrs20mMQgrsXMB6bFZdTIysm1zCiuzQG1ICSuwcxCwWyDWEbRGAgB9BCuwcxCxbwHpsGsysBovsQQC6QGwgS+wANaxEATpsBAQsSABK7E/A+mwMzKwPxCxVgErsU0D6bJNVgors0BNSgkrsE0QsWQBK7F7A+mwexCxFgErsQkD6bGCASuwNhq6P7H5twAVKwqway6wdi6waxCxdQ/5DrB2ELFqD/kAsGouAbNqa3V2Li4uLrBAGgGxIBARErMeIyRFJBc5sD8RsEQ5sFYStikqN0FCRlMkFzmwTRGwUjmwZBK2SE9QXHN4fiQXObB7EbJvcHE5OTkAsWF+ERK1QR5CT1NQJBc5sGcRtjs8XmRpe4AkFzmwNBKwOTmweBGwNzmxMUYRErEuLzk5sW9tERKxSnA5ObAmEbIjKiw5OTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NxE0JzcWMyEyNxcGFRQXByYjBgcVMjcXBhUUFwcmIxUUFwcmIwcBNiUyFQYVERQXByYjBzU2NRE0JyIHAT8BHgEzMjY1NCYjIgcnExYXMjcXBwYjIicHNjMyFhUUBiMiJ/aLfQjRj6Jth/byi31JvwiTXE6q921cYwF5EAERBDk2AZw7JQQEBATBzAwBb9MGBgYGqJoRBDk2cQMRbQESChASBDM4aBAcUlQCPR8lKVI/O1dORk5YITKFJ2qwCxlUa0xmFkJLfai/j5FnrAWsf4mDhfpUjXl9yKpOXAVtvmJc+1RtxgF3wXIGBgYGKQwXGAYSLa53DwUXGh8UBBCywXIGBgYDNxlaBqRW/n2qdwQEBARivwF0ZAEK/Vx5AkpCbWhmdSQKAc0KAREEmAgM3xmoc5GqVgAABgD2/k4MAAYIAA8AHQBFAFsAcwCDASwAsA0vsRIB6bBwL7F3AumwgC+wPjOxagLpsDQysFsvtEYCAH0EK7AxL7QmAgBdBCuwYiDWEbAvM7RhAgBFBCuwSDKwGi+xBALpAbCEL7AA1rEQBOmwEBCxIAErsT8D6bAzMrA/ELFWASuxTQPpsk1WCiuzQE1KCSuwTRCxXAErsXQD6bB0ELF6ASuxbQPpsG0QsRYBK7EJA+mxhQErsSAQERKzHiMkRSQXObA/EbBEObBWErYpKjdBQkZTJBc5sE0RsFI5sFwSskhPUDk5ObF6dBESsmpwaDk5ObBtEbFhYjk5ALF3cBEStUEeQk9TUCQXObCAEbI7bTw5OTmwahKxOWg5ObBbEbE2Nzk5sEYSsFk5sTFiERKwLjmwYRGwSjmwJhKyIyosOTk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNjcRNCc3FjMhMjcXBhUUFwcmIwYHFTI3FwYVFBcHJiMVFBcHJiMHATYlMhUGFREUFwcmIwc1NjURNCciBwE0PgIzFw4EBzYzMhYVFAYjIicmNxQWMzI2NTQuAyMiBwb2i30I0Y+ibYf28ot9Sb8Ik1xOqvdtXGMBeRABEQQ5NgGcOyUEBAQEwcwMAW/TBgYGBqiaEQQ5NnEDEW0BEgoQEgQzOGgQHFJUAhpMju+SBCtAd1JQEj1SopCemndJkbpUSS1GAhAdOSlGNQSsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VG3GAXfBcgYGBgYpDBcYBhItrncPBRcaHxQEELLBcgYGBgM3GVoGpFb+fap3BAQEBGK/AXRkAQr+g1q+rG03BAstRo1gKaRxb7EvWvS4gmtoHytDKSErJQAEAPb+TgnsBggADwAdAEUAcAD2ALANL7ESAemwPi+xNALpsGcvtFYCACgEK7BPMrAxL7QmAgBdBCuwGi+xBALpAbBxL7AA1rEQBOmwEBCxIAErsT8D6bAzMrA/ELFJASuxawPpsFEysGsQsWMBK7FaA+mwWhCxFgErsQkD6bFyASuxIBARErMeIyRFJBc5sD8RsEQ5sEkStikqN0FCRk0kFzmwaxGzT1JTcCQXObBjErRWYGFtbiQXObBaEbBfObAWErFcXTk5ALE+EhESQAseOzxCRlldX2BhaiQXObA0EbI5UlM5OTmwZxKxNjc5ObBWEbBMObAxErEuLzk5sCYRsiMqLDk5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY3ETQnNxYzITI3FwYVFBcHJiMGBxUyNxcGFRQXByYjFRQXByYjByU1Nj0BNCc3NjcyFwczPgEzMhYdARQXByYjByc2NzU0JiMiBgcVFBcHJiP2i30GvI+jbYf5Bot9Sb8Gf1xOqvmBXGMBeRABEQQ5NgGcOyUEBAQEwcwMAW/TBgYGBqiaEQQ5NnECmA4OAnVJDgEPBUZTQGaBDgIzNWcCDgEnOTE8PQ4CMzSsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VG3GAXfBcgYGBgYpDBcYBhItrncPBRcaHxQEELLBcgYGBgIEYrtUw0sECB8Qb1Iti2mZtmcEBAQEVMmHWEgrSLS2ZwQEAAgA9v5OEuEGCAAPAB0ASQBVAGEAqgDAAMoAABcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NxE0JzcWMzcXBgcVITU0JzcWMzcXBhURFBcHJiMHJzY9ASEVFBcHJiMHATQ2MzIWFRQGIyImNxA3MjU0JiMiDgIBNj0BNCc3NjcyFQczPgIzMhYXPgEzMh0BFBcHJiMHJzY9ATQmIyIOAQcdARQXByYjByc2PQE0JyIOAg8BDgEHFRQXByYjBwE0NjMyFhUUJyEUFjMyNxYHDgEjIiYTMzI1NCYjIg4B9ot9D7KPomyH8BCLfUm/D3VcTqrwi1xjAVAQAREEOTZxAhABAa4QBDk2cAIQEAQ5NXECEP5SEQQ5NnEDx7+jsqi4pqS6xa6FRF4vPRsKAmIQEAR1Sg4OAi8pSy1EhwhEWj7fEAQxNWkCESc8Hy8aMRAEMTVpAhBgDBMWDg4TBiUKEAQxNmgEtN17j5Qa/mJ3T45QIQEtnVKmxcfbFzIvGTA+rAWsf4mDhfpUjXl9yKpOXAVtvmJc+1RtxgF3wXIGBgYGasl9fcFyBgYGBmrJ/onBcgYGBgZtxqqqwXIGBgYBRaDJz4uH0cKs/t8B4aiNJUxL/mJgvVS2WAQIHxBrMyUjSjFIM/aXuGUEBAQEcaydUDobGzcvi7hlBAQEBGC9mY0BBQoIDRQGJwq4uGUEBAQBO6LPpm0bAZOKVhIjPUy4ARAVTjsSTQAHAPb+Tg0KBggADwAdADUAQQBXAGEAdQErALANL7ESAemwMS+xVXIzM7E5Aum0TgIAKAQrsEsvsVgC6bBeL7FFAumwPi+xKQLpsBovsQQC6QGwdi+wANaxEATpsBAQsSABK7E2A+mwNhCxPAErtCwDAC4EK7AsELFCASuxSwPpsFgysEsQsVsBK7FIA+mwSBCxZwErsGIysWwD6bBxMrNvbGcIK7FkA+mwZC+xbwPpsGwQsRYBK7EJA+mxdwErsSAQERKzHiMkNSQXObA2EbEmNDk5sDwSsSkxOTmxW0sRErJFTlU5OTmwSBGwUDmwZxKwUjmwZBGxaHU5ObBvErB0ObBsEbFqcjk5ALE5MRESsh5icTk5ObFLThESskJQUjk5ObBYEbE8SDk5sF4SsCw5sSk+ERKwIzmwGhGyZ2psOTk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNjURNCc3FjMyNjMyABUUDgIjIiYjBzcUFjMyNjUQISIGFQE0NjMyFhUUJyEUFjMyNxYVDgEjIiYTMzI1NCYjIg4BATY1ETQnNzY3MhUGFREUFwcmIwf2i30J24+ibIf154t9Sb8JnlxOqvZiXGMBOhAQBDo1Oaw33wFWaKiuWlSsOXHTOW+2sv5xQj8Dd917j5Ma/mJ3UI1QIS2eUqbExtsXMS8ZMT4CPBAQBHNQDhAQBDE2aKwFrH+Jg4X6VI15fciqTlwFbb5iXPtUbcYBd8FyBgYG/snTh8VkLQQGkScWjdkB3Rgl/eOiz6ZtGwGTilYSIz1MuAEQFU47Ek3+A17VAbjJWAYIHQ59pP4rz2QEBAQAAAUA9v5OCx8GCAAPAB0AMQBcAIIBRACwDS+xEgHpsIEvtS4xMklMWiQXM7FiAumwUy+0QgIAKAQrsTtsMjKwQhCxdALpsBovsQQC6QGwgy+wANaxEATpsBAQsSABK7ErA+mwKxCxNQErsVcD6bA9MrBXELE4A+mwOC+wMjOwVxCxTwErsUYD6bBGELFqASu0dwMAJQQrsHcQsWUBK7R+AwA6BCuwfhCxFgErsQkD6bGEASuxIBARErMeIyQxJBc5sCsRsDA5sDgSsycoLS4kFzmwNRGwOTmwVxKyOz9cOTk5sE8RtEJMTVNaJBc5sEYSsEs5sGoRs0hJXV4kFzmwdxKwXzmwZRG0Ymh0eoEkFzmwfhKybm9xOTk5ALFigRESQAktHjBIS01ZXF0kFzmwUxFADD9FRj5WXl9qcHF3fiQXObFCdBESsThvOTmwGhG0IyQmJygkFzkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NRE0JzcWMzcXBhURFBcHJiMHJTU2NzU0Jzc2NzIVBzM+ATMyFh0BFBcHJiMHJzY9ATQmIyIGBxUUFwcmIyU/AR4BMzI2NTQmJyY1NCUyHwEPAS4BIyIGFRQXHgMVFAYjIvaLfQfwj6Jth/fTi31JvweyXE6q+E5cYwEbEBAEOTZwAhAQBDk1cQG0DgEPAnVKDg4ERlQ/ZoIOAjM2ZgIOJzkxPD0OAjMzAskYFRl8My82MUDLARtgXgIcFRRaNC8zZS9BSieWiX+sBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VG3GAXfBcgYGBgZqyf6JwXIGBgYCBGK7VMNLBAgfEG9SLYtpmbZnBAQEBFTJh1hIK0i0tmcEBB+XAjFKPjcvNRlMcLwBMQSUAi1YLylWIxAfMUYrSoAAAAACAM3+Th3sBggADwAdACwAsA0vsRIB6bAaL7EEAukBsB4vsADWsRAE6bAQELEWASuxCQPpsR8BKwAwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFc2LfRrlj6Nth+Tdi31KvhqoXE6q5VhcYqwFrH+Jg4X6VI15fciqTlwFbb5iXAAABgD2/k4NmgYIAA8AHQBQAHsAmwCmAYYAsA0vsRIB6bBQL7GPkzMztEICAEAEK7BFMrA/L7E1AumwpS+xfwLpsVphMjKwfxC0cgIAKAQrsDIvtCcCAF0EK7AaL7EEAukBsKcvsADWsRAE6bAQELEhASuxQAPpsDQysEAQsVQBK7F2A+mwXDKwdhCxbgErsWUD6bBlELF8ASuxnAPpsJwQsaABK7CBMrGMA+myjKAKK7NAjIkJK7KgjAors0CghAkrsIwQsRYBK7EJA+mxqAErsSEQERKxHiU5ObBAEbBQObBUErYqKzhHTVFYJBc5sHYRslpeezk5ObBuErRha2x4eSQXObBlEbBqObB8ErFnaDk5saCcERKyf4WXOTk5sIwRsJE5sBYSsoeOjzk5OQCxUBIRErJMmJk5OTmwQhFAC0lRZ2hqa2x4jpGeJBc5sD8SQAw8PUZHZGV1fJaXnKAkFzmwNRGzOl1eoSQXObByErE3ODk5sX+lERKxV4E5ObAyEbEvMDk5sCcSsyQrLYokFzmwGhGyhIeJOTk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNTY1ETQnNxYzITI3FwYVFBcHJiMGHQEyNxcGFRQXByYjFRQXMjY/ARcUBhQWFQcmIyElNTY9ATQnNzY3MhUHMz4BMzIWHQEUFwcmIwcnNj0BNCYjIgYHFRQXByYjATQ2MzIXNTQnNzY3MhcGBxEUFwcmIyIHIi8BIwYnIiY3FDMyNxEuAiMi9ot9CmqPo22H9ViLfUm/Ci1cTqr101xjATwODgI7NAG0NyUEBAQE088Mg9MGBgYGqK4MXNk/PgICAgIlN/48ApUODgJ1Sg4OBEZTQGaBDgIzNWYCDic5MTw9DgIzMwKf7psxQhAEeUkOARABGwQlOykpDgEIAlh1fbK9mVhOFxovI7ysBax/iYOF+lSNeX3Iqk5cBW2+Ylz7TgZg0wF3z2QGBgYGKQwXGAYSLa53DwUUHR8UBBCypi0IBgUGBigQJQoGBgIEYrVUw0sECB8Qb1Iti2mZsGcEBAQEVMOHWEgrSLSwZwQEATWa0SFkx1gGCB8QfaT+J5qNBAQEBGJzAbyo/l4BQCMgGQAAAAATAPb+Tgr2BggADwAdAYQCIQPOA/sELAQ0BDUENgROBIAEhQSKBIsEngSlBPIFAAAAFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVEyY3Njc2MzIfAR4BMzI3FgYHIiYHBgcOARceATMyNz4BNzYzMhceARc+ATc2FxYXFhcWFxY2NzQ2NTQnJicmJyYjIgYjBicmJxYzMj4DNzYXFhcWFxYXFgcGBwYHFBYXFjc2FxYGBwYjIiciJicuAicmJxQWFxYVFhUWMxY/ARYfARYXFAcGBwYHHgEXHgEXFhUUBwYHFgcGBw4BIyIHBgcGFx4BFRYHBgcOAQcGFx4BFxY3FAYPAjY3BgcGBzIWMwYnJi8BJicWFyIGJyYnLgEnHgEXFSYnJicmJyY2NQYHBhc0JjUmNz4BNycuBCceARcWBwYHBiIHBh8BJi8BLgE1NDc+ATM2NCcuAScmJyY3PgE3NiciJicmNCcuAScmJyY3Njc2NzYnJiIuBCMGJy4EPQEnBgcGFhceAhcmJyY3IgcGJyYHBiY3Njc+ATc+Az0CJicmNxYXFhcnNQcnBycHNwc3IzcnNyc3JzcnNyc/BRc3FzcfAQcnBysBByMPAxcHFwcXBx8BNxc3Njc+Azc2Fx4DFxUUFxYXHgEXFhcWBxY2Jy4BJyY3Nj8BNicmJxYXFRQeARcjJjUmNicmIyIHJyYnJiMiBw4BBwYnIiYnJj4BNzY3NhYzMjcGIyIuAScmIyIHBgcGEzYzFjc+ATM2NzY3DgEVBgcGFxYGHgIGFjIXHgIUFjIXFgcOAQcGFxYXFjIXFhcWFRQHBhceARc1Nj8CFQYXMjcGFQYXFhceARcVFBceAhcuATU0Nz4BNzY3ND8BFgc2NxYVNjc2NzYnLgEnNSYHIgYiJiM+ATc2OwE2NzYnJgciBiMiJyYnLgEnJic3Fh8BFhcWFxYXFjc2FzI3NicuAScmLwE+ATM2NzY3NjU0JyYnJgYjBwYnJicuAScmJzQmNSY3Njc2FgcUBwYHMxYXJisBFAYHFAYHFTY7ATY3NiYnLgInJic0JyY1JiM2NzYnJicuASc+AjM2FxYXHgEXFhceAR8BNxc/ASc3JzcnNy8DIycHLwEHJz8BFzcXNx8FBxcHFwcXBxcHFyMXJxcnBycHJxUUBhc2NzY3NjQnJicmJyYjIgcOAQcGJxYXFjcyNjMyFxYXFhcWFRQHBicmJyYnJicmBgcWFxYXFhUUBwYHBhceARcWBgcGJzYnNCcuAicmJyIHDgEHBiYHIyIHBgcGBxUUBgcOARUOAQcOAgE0Njc2MzI3Njc2NzYWMzY3NjQzNxQWBwYHDgEjNj0CJgcGFA4BBw4BBycmFzU2NzY7ATI2MzQnJgcvATYXFhUWFx4BFw8BIxYVFCMGJzUGBxYXFhcWNyIGIyInJhU0NzQWMxQHExE3FjI/ARYXFh8BJi8BLgEnIyI0IycmJyYTNDc2NzYXHgEXFhceARcmJyYnLgEnJiMiBwYWFTYXMh8BJgcOAR0BFAYVIicVNCYnJjcUFzQmFxYVBiY3EzYzMhcWFxYXByYnIxYVFAcGJjceARc0NyIfATMyNzI2NzI2Mw4BBx4BFxYfAR4BFxYXHgEXFjc2NwYnLgInJicuAScuAScmJyYnBgcGFx4BFxYHBgcXFhcWFSIvASYjFhUGByImFxYXHgEXNCcmJwYHDgH2i30Hx4+ibYf3/It9Sb8HiVxOqvh3XGPLBicrUkxgTCsbEhYJGQ0CNS8UTBdtJhkKAgIvFRIhCosTMUIrJxIvCgYZBjk8KS8jPyslGSkEBgYEExkmLxcOKQpUFRICChAIERIIHwotVjc2KSclDhcXGTstQwICCAwGCAYIDA4VJw4IGwoMFx0GBg4IAgIEDAMKEBMKBg4IAQcGDBkWAgQEAhMCBgYIJQYGBgkGHwQGFA4DAgICCQMDBAcEGAIMAQIZCgoZBAMHBiMOBh8QDQIGAhIXBgcRCwYGBQILAhAKBA8EAgIEDAwIERICAgQGBwwCDgQSAggCBwUIBAwFFAIQAgIIAg4CEwIGBhEKCQUDBAICFQIKDAQrCQgEAgYCDwICDQISBAICBBkECAQEBAIEAgIGBAIXCAIECAoCBgUCBAQOBAklLQQEEQw1JTOBKRoEEA0IFBkSChUCBBkXAwgGBwQCaEBCBwg9O2UMGQwVCh8LKRIlFR8YJiAgGBYYCBQHGBUnFCcjJyshFB8aEx8cFSkOJwIbCRcTExcEHggjFRw5MgolFyQVPT4OHQwfBgYICwwlBg4GBg4IDQICDwIEBAIQDxIIDDwICwYIAgYQAgIGEhMEEQwtEx8wQikSigwlFhk3AgICEBMvbh1ODEoMBhsKFicIJ0heQFYpJ6oUFQwhCj4CPyo1DgISHykDCQQGBA4FAggUAgQEBQgSBAoEAggCBgYCFwQWBgwJCAgKCggIBAIODRMEEAoQDAQKAhsEDgIJAggKAgIMDgYlBhAFBQUCDBcFAgoHDgIEBAIMAhsGBBkMDgQIKQorKyUGBAgIPxEKNQ4zGRsWBhUECgYCBB4DAwEpHAgfF1IZOB0KBAQCEAIEBQMECAIOChAHCAYEDgQPBAoKAh8IBBMGEjIIAwkIDwoVBAsIAhUMBAoNDgQCCAIZDBoMAgICAgQIDAQGBAQDEh8QAwQLChAEGQYEDg0GKy8dFggtCS0ECh8EFhUfBhoEFRERFQgWBCEMJRMYGxAXGhIbJyAhIw4jExQGFQoWFBYdHSMXHRMfECULGwoTChYLBEItPRMICAopNRs3ZyEgEDoODAsKGRA3CCwSIycrGBAHCAYUPCcxPSElLykpIxAJFCEZFw4GEgcCDQIGBAgXEhcBEAYXEgkOCgwTBB8GHTFLFBMLKSk5KQQICg0CEgYCDwIBMQUCBgYCBAIGCgkEEgIEAQECExACDBkEDgIMEA0CBAoCBAwCAgJmCB8QBhcCEAIKDhsCAhcWCggFAgQCAgIbChgXCBcMDA0QCA0SAQYBHxIfAggCBFAKFAkFBQwNAgQGAQYHAhMCDgICBgYCBxMYFA0jGQgUBggVBAgCGQEGFQQUBRQQIQ8EAgoVAwUCDAwEBAQEBwwCBgwCAQECAQErAgQdCgoMBRIGCAwbCgIGDhlzAggCCg4SBwwIAgIKBAINBAQIAgIKAgQJDgQYCBcQCBkIHRgdAhkKAgIIEhQNBAoFBBQCHSMCLRACBAwCFwQICAMOCAYHBAYCCwgCAgISAg0PFwMCEQIIBQgGBAIMrAWsf4mDhfpUjXl9yKpOXAVtvmJc/mhxSlArJxcQCwwKJxYCEAQURCkxKyM1FgacESkPBicGBBMEKQQCJx9YPQsILxkCIwobGhIhKRUUCgYUEhcKBhAFEgQSCAYcFzExOmRWUjkrDQQOBBcEBAgEGgcGAg8CAgwVBAIGBBMECA4MBQwCBAQEBg4UGRYPDg0ZDAIIBAQIBQgIDAoKERsaGQQCAgYUBQgIBBUEDAwQBwQOAggJCh8EBgoECAMHBgwQFBkMCA0CBwIECgYEFAINAgIHAgwCAgwEDQMKBhASBwQOAgQGDAYBBAEQGwQIBAcFBgkUCA8EIQYMDQIKAgQKCxYEDAUDBgQSAwQKCg0IAhsKCA4GDQQQBAgFAgICDgQEAgIGEQ4NBAMBAgYEAggXBAICCA4GLQ0CDBEcNRkHMWk5KVAnNWBsRo0UEAYIDAgKDiEODCkKBgsGCgMMDhBQVGRmTEgOHS8hKyIzGykEGyQHIg0eGxUeHyUULQ0iBR4CFQgMBhMMDAwZIg0nFiMnIR4PLwglBBoaHTMMKxkfDCELAg4MGwYKCCUdBggLBAgKDAsCEQgECgIGDQgLCxQaHRoGGykEBgQCCgIGHQgbBAwpCA4lEJ4IGQE/JxsnKSBQDAQOIwQKGQQUIjFISP3LEBAhCg4XLzktBi8OMSEcHAolDAQMJQ0CAgoEEAUCBBAEDAUMCgYIAgUIDhAFChAUCwgEBisIBgYTFxkCCRcEEBECFAQEAx4QCwQEBgICFgYQDwYRBAwMAgIDDhkMEAIOCgQKBwoMBBUCHAYBDw8CFgIGAgsSJQYCDhAQJQgyBhIGBwIwBAQCRAwCBgISBgQRDAYECQIECAYCGQoIEAsOExsNCgUCBgICBBIMCCwKH0MCEwYcGx8GBAgKAgsICgQMCgIRAgICBBYKEAYEIQQKCQoEBh8ECAQCAhALFxASDQQOBAIGBAgcEBkKOgozAgYPAhgYBCMILQ8cISMjFCUMIRkCAgoMDBAJDwsVAh0EIA0rEiUdHhMYIQgjBiEbBCcZLyMrHisEFAQIKz1IIW4jLTo5ECEMBiEGBAQUCQQEChYZJxsaJRQbGEwIBkZYHCEEBBAdBAQIHRkUDhcOBA4LAgYCBBsEDhIECwgIAgYJBgojBgINAgYMGAQMJS+YGA8QBwgvAgQICAINCgE1AhECBg4ECw4CAgICAwECBgQSBh8OAgUMAxwJBBsCCgQEAgINAgICQxoGBwQEHQgICAMDCAQEAgwhAgkCAgIIDhkCExQCChIHCAIDAwgICukWAgIIBgT+FQLCtAoEBCkWBAQGAQEDBh0GCQICAgb+vh8OCgMGDAQRAgQQAhUCEgIECwIOAggMAg4CCgQJAwQGAgkFBwIIAgYOAgQCEJgBAgIBAwICAQN4/ukKBggEEhcCGwwCBQwCBhj0BAwEChApDAIIAgQCCgIGGQYEBAYCFQQKAgIMAgQEBBAEGQQYDRYbGAglCQoaAikRAgoGBgwNAhYJFB8IDgQDCgYQAgoEBg4MBQIcIQgCDQQCGQwhBgICAgAACAD2/k4O9gYIAA8AHQA4AEQAUABcAIIAmAGRALANL7ESAemwgS+0NThOjZAkFzOxYgLpsFMysC8vtDsCAJgEK7BYL7B0M7FIAumwbDKwmC+0gwIAfQQrsoOYCiuzQIOFCSuwQS+0KQIAfQQrsCQysBovsQQC6QGwmS+wANaxEATpsBAQsSABK7EyA+mwOTKwMhCxPgErsSwD6bAsELFFCyuxUQPpsFEQsVUBK7FLA+mwSxCxagErtHcDACUEK7B3ELFlASu0fgMAOgQrsH4QsZMBK7GKA+myipMKK7NAiocJK7CKELEWASuxCQPpsZoBK7EgEBESsx4jJDgkFzmwMhGxJjc5ObA+ErMvKTQ1JBc5sVVRERKxSE45ObFqSxESsV1eOTmwdxGwXzmwZRK0Ymh0eoEkFzmwfhGybm9xOTk5sJMSsYOQOTmwihGwjzmwFhKyhYyNOTk5ALFigREStTQeN12MjyQXObAvEUAJRUtRVV5faXl+JBc5sDsSsXBxOTmwWBGwdzmwSBKwbzmwmBGxLD45ObCDErCWObBBEbCHObApErEjJjk5MDEXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUBNjcRNCc3FjMyNjMyFhUUBiMiJxUUFwcmIwcTFjMyNjU0JiMiBhUBNDYzMhYVFAYjIiY3EDcyNTQmIyIOAgE/AR4BMzI2NTQmJyY3NCUyHwEPAS4BIyIGFRQXHgMVFAYjIgE2JTIXBgcRFBcHJiMHNTY1ETQnIgf2i30Lx4+ibYfz/It9Sb8LiVxOqvR3XGMBKRABEQU3Mxm8Er65y75CMREEOTZtzx1Ob0tQWk4tAgC/pLKouaWku8WuhUReLz0bCgJQGBUZfDQvNTFAywEBGmBfAh0UFFszLzRlL0FKJ5WKfwJYbQESCgEQARMEMzhoEB1SVKwFrH+Jg4X6VI15fciqTlwFbb5iXPtUccIBeb51BAQKpVl1xA6NvnUEBAQCBg5cf4dSHyX926DJz4uH0cKs/t8B4aiNJUxL/oGXAjFKPjcvNRlMcLwBMQSUAi1YLylWIxAfMUYrSoADOxlaBqRW/n2qdwQEBARivwF0ZAEKAAAAAAYA9v5ODvYGCAAPAB0AUAB7AKUA1gAAFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATU2NRE0JzcWMyEyNxcGFRQXByYjBh0BMjcXBhUUFwcmIxUUFzI2PwEXFAYUFhUHJiMhJTU2PQE0Jzc2NzIVBzM+ATMyFh0BFBcHJiMHJzY9ATQmIyIGBxUUFwcmIwE0NjsBNCc3NjcyFwYHMzIXFRQrARUUBhUUMzI3FhUGJyImNTQ2PQEjIiU1NDsBNTQ2Nz4BMzIXFQ4CDwEmIyIGFRQWHQEzMhcVFCsBERQXByYjByc2NREjIvaLfQvHj6Jth/P8i31JvwuJXE6q9HdcYwE8Dg4COzQBtDclBAQEBNPPDIPTBgYGBqiuDFzZPz4CAgICJTf+PAKVDg4CdUoODgRGU0BmgQ4CMzVmAg4nOTE8PQ4CMzMCehUMVAoCN38OAQgBpgwBJY4EMzkwHVaERk0EYBQCOSNJMjcxmUgtGQgPEAITJTM9QgelDAEjjxAEMTZoAhBmBqwFrH+Jg4X6VI15fciqTlwFbb5iXPtOBmDTAXfPZAYGBgYpDBcYBhItrncPBRQdHxQEELKmLQgGBQYGKBAlCgYGAgRitVTDSwQIHxBvUi2LaZmwZwQEBARUw4dYSCtItLBnBAQCUhAraEIFBDEPdWAKMxSgM5QSbx0SJk4BWjsSxTOxECsfLVRtOTNBDAYMOEwKAkZQQhBvFA4LMxT+8c9kBAQEBF7VAQ8AAAAHAPb+Tg72BggADwAdAFAAZABsAJcAyAAAFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATU2NRE0JzcWMyEyNxcGFRQXByYjBh0BMjcXBhUUFwcmIxUUFzI2PwEXFAYUFhUHJiMhJTY9ATQnNzY3MhcGBxUUFwcmIwcSNDYyFhQGIgE1Nj0BNCc3NjcyFQczPgEzMhYdARQXByYjByc2PQE0JiMiBgcVFBcHJiMBNTQ7ATU0Njc+ATMyFxUOAg8BJiMiBhUUFh0BMzIXFRQrAREUFwcmIwcnNjURIyL2i30Lx4+ibYfz/It9Sb8LiVxOqvR3XGMBPA4OAjs0AbQ3JQQEBATTzwyD0wYGBgaorgxc2T8+AgICAiU3/jwC2RAQBHlJDgEQAREEMzRoAj1aPj5aAXsODgJ1Sg4OBEZTQGaBDgIzNWYCDic5MTw9DgIzMwK0I0kyNzGZSC0ZCA8QAhMlMz1CB6UMASOPEAQxNmgCEGYGrAWsf4mDhfpUjXl9yKpOXAVtvmJc+04GYNMBd89kBgYGBikMFxgGEi2udw8FFB0fFAQQsqYtCAYFBgYoECUKBgYGcaZUtFoECB8QfZRsonUEBAQDpFY/P1ZA/JwEYrVUw0sECB8Qb1Iti2mZsGcEBAQEVMOHWEgrSLSwZwQEAkwrHy1UbTkzQQwGDDhMCgJGUEIQbxQOCzMU/vHPZAQEBARe1QEPAAAACgD2/k4X1wYIAA8AHQA7AFEAWwBxAHsAngDDANAAABcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQU3FjM3FwYHERQXMjY/ARcGFRQXByYjIQc1NjURNAE0NjMyFhUUJyEUFjMyNxYVDgEjIiYTMzInNCYjIg4BBTQ2MzIWFRQnIRQWMzI3FhUOASMiJhMzMjU0JiMiDgElNzY3MhcHMz4BMzIfAQ8BJiMiDgIdARQXByYjBzU2PQE0ATY3AQUnNjc0JzcWMyEyPgEzMhUGBwEyNj8BFwYVFBcHJiMhByU1NjczFhcVBgcjLgH2i30UqI+ibYfrG4t9Sb8UalxOquuWXGMEAAM9M3ECEAENXNk+PwICAgIlN/47cA4C+t17j5Qb/mJ3UI1QIS2eUqbExtwXATEvGTE+AiXee4+TGv5id1CNUCEtnlKmxcfbFzEvGTE+AjwCcUsOAQUFIWwxGScGHwwbPQ4kMR4OAjs0Yg4CCAYbAWH+qgMCAQMDMSUBdBQ6KwIIAiv+qlK7NTUCAgICMSX+pLYDOxtHBEoZHUYEKyusBax/iYOF+lSNeX3Iqk5cBW2+YlzPBgYGBmrJ/ommLQgGBQYMKCUUBgYGBmDTAXfB/cyiz6ZtGwGTilYSIz1MuAEQFU47Ek3Gos+mbRsBk4pWEiM9TLgBEBVOOxJNggQIHxBzM1AMBJAEFwkWOSl/sGcEBAQEYrVUkf4GCCcCBhAGDCkdFQQEBAYKAkD+CAoFBAYMKh0UBAQETAZGGhtFBlAQCC0ABQD2/k4MZgYIAA8AHQBQAHYAkgE+ALANL7ESAemwUC+xdZAzM7RCAgBABCuwRTKxVgLpslZQCiuzQFaKCSuwPy+xNQLpsGgvsIIzsWAC6bB6MrAyL7QnAgBdBCuwGi+xBALpAbCTL7AA1rEQBOmwEBCxIQErsUAD6bA0MrBAELFeASu0awMAJQQrsGsQsVkBK7RyAwA6BCuwchCxdwErsYUD6bCFELEWASuxCQPpsZQBK7EhEBESsR4lOTmwQBGwUDmwXhK2Kis4R01RUiQXObBrEbBTObBZErRWXGhudSQXObByEbJiY2U5OTmxFoURErN6fY2QJBc5ALFWUBESsUpROTmwQhGxSYg5ObA/EkARPD1GR1JTWVxkZW1yd35/hY0kFzmwNRGyOl5rOTk5sGgSsTc4OTmwYBGxY305ObAyErEvMDk5sCcRsiQrLTk5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATU2NRE0JzcWMyEyNxcGFRQXByYjBh0BMjcXBhUUFwcmIxUUFzI2PwEXFAYUFhUHJiMhJT8BHgEzMjY1NCYnJjU0JTIfAQ8BLgEjIgYVFBceAxUUBiMiATQ2MzIfAQ8BLgEjIgYVFBYzMjczFhcOASMiJvaLfQk3j6Jsh/aLi31Jvwj6XE6q9wZcYwE8Dg4COzQBtDclBAQEBNPPDIPTBgYGBqiuDFzZPz4CAgICJTf+PAKqGBUZfDMvNjI/ywEbYF4CHBUUWjQvM2QvQkonlol/Ah/XoH9eAiMbIVcrUmd1WGhMBB8CH4tUpr6sBax/iYOF+lSNeX3Iqk5cBW2+Ylz7TgZg0wF3z2QGBgYGKQwXGAYSLa53DwUUHR8UBBCypi0IBgUGBigQJQoGBh+XAjFKPjcvNRlMcLwBMQSUAi1YLylWIxAfMUYrSoABUKDCMQScAjdId3B5ml4SFUJZuAAAAAgA9v5OEBQGCAAPAB0AUAB7AJsApgC8AMYB1gCwDS+xEgHpsFAvsY+TMzO0QgIAQAQrsEUysLAvsb0C6bA/L7E1AumwpS+wwzOxfwLpslphqjIyMrB/ELRyAgAoBCuwMi+0JwIAXQQrsBovsQQC6QGwxy+wANaxEATpsBAQsSEBK7FAA+mwNDKwQBCxVAErsXYD6bBcMrB2ELFuASuxZQPpsGUQsXwBK7GcA+mwnBCxoAErsIEysYwD6bKMoAors0CMiQkrsqCMCiuzQKCECSuwjBCxpwErsbAD6bC9MrCwELHAASuxrQPpsK0QsRYBK7EJA+mxyAErsSEQERKxHiU5ObBAEbBQObBUErYqKzhHTVFYJBc5sHYRslpeezk5ObBuErRha2x4eSQXObBlEbBqObB8ErFnaDk5saCcERKyf4WXOTk5sIwRsJE5sKcSsoeOjzk5ObHAsBESsqqzujk5ObCtEbC1ObAWErC3OQCxUBIRErNMmJm6JBc5sEIRQAxJUWdoamtseI6RnrMkFzmwsBJAC0ZHZXyWl5ygp7W3JBc5sL0RsWStOTmwPxKyPD11OTk5sDURszpdXqEkFzmwchKxNzg5ObF/pRESsVeBOTmwMhGxLzA5ObAnErMkKy2KJBc5sBoRsoSHiTk5OTAxFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATU2NRE0JzcWMyEyNxcGFRQXByYjBh0BMjcXBhUUFwcmIxUUFzI2PwEXFAYUFhUHJiMhJTU2PQE0Jzc2NzIVBzM+ATMyFh0BFBcHJiMHJzY9ATQmIyIGBxUUFwcmIwE0NjMyFzU0Jzc2NzIXBgcRFBcHJiMiByIvASMGJyImNxQzMjcRLgIjIgE0NjMyFhUUJyEUFjMyNxYVDgEjIiYTMzInNCYjIg4B9ot9DOWPomyH8t2LfUm/DKhcTqrzWFxjATwODgI7NAG0NyUEBAQE088Mg9MGBgYGqK4MXNk/PgICAgIlN/48ApUODgJ1Sg4OBEZTQGaBDgIzNWYCDic5MTw9DgIzMwKf7psxQhAEeUkOARABGwQlOykpDgEIAlh1fbK9mVhOFxovI7wCh917j5Qb/mJ3UI1QIS2eUqbEx9sXATEvGTE9rAWsf4mDhfpUjXl9yKpOXAVtvmJc+04GYNMBd89kBgYGBikMFxgGEi2udw8FFB0fFAQQsqYtCAYFBgYoECUKBgYCBGK1VMNLBAgfEG9SLYtpmbBnBAQEBFTDh1hIK0i0sGcEBAE1mtEhZMdYBggfEH2k/ieajQQEBARicwG8qP5eAUAjIBn+46LPpm0bAZOKVhIjPUy4ARAVTjsSTQALAPb+ThBmBggADwAdADgAQwBOAGIAagB+AJ4AqgCxAfoAsrAAACuwDS+xEgHpsDQvsXuSMzOxPALpsKIysDwQtJwCACgEK7BDL7FEAumwqS+xggLpsFcysEsvsSkC6bMUS2oOK7RmAQAdBCuxc4oyMrAaL7EEAukBsLIvsADWsRAE6bAQELEgASuxOQPpsEQysDkQsT8BK7ExA+mwSCDWEbEsA+mwMRCxZAErsU9UMjKxaAPpsVleMjKzUWhkCCuxXAPpsGgQsW0BK7F4A+myeG0KK7NAeHUJK7JteAors0BtcAkrsHgQsX8BK7GfA+mwnxCxpAErsIQysY8D6bKPpAors0CPjAkrsqSPCiuzQKSHCSuwjxCxsAErtK8EAC4EK7CvELEWASuxCQPpsbMBK7EgEBESsx4jJDgkFzmwORGxJjc5ObBIErIpNDw5OTmwPxGwLzmxZDERErFVYjk5sVxRERK0YWVmaWokFzmwaBGxV185ObBtErJrcX45OTmweBGwfTmwfxKyc3p7OTk5saSfERKygoiaOTk5sI8RsJQ5sLASs4qRkqskFzmwrxGwrDmwFhKwrTkAsTw0ERK2Hk9eX2t6kSQXObBDEbY/MX+Zmp+kJBc5sEQSsS+lOTmxgqkRErdUVlmEq62usSQXObBqEbFILDk5sSlLERKzI2NojSQXObBmEbVkZ3B1h4wkFzmwGhKwrDkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NRE0JzcWMzI2MzIWFRQGBxYVFAYjIiYjBzcUFjMyNjU0JisBNTMyNjU0JiMiBhUBNjc1NCc3NjcyFQYdARQXByYjBxI0NjIWFAYiATY1ETQnNzY3MhUGFREUFwcmIwcBNDYzMhc1NCc3NjcyFwYHERQXByYjIgciLwEjBiciJjcUFjMyNxEuAiMiJRsBJxEjEfaLfQ03j6Jsh/KLi31Jvwz6XE6q8wZcYwENDg4COzMvlhfBqVI96dHTSIctbtExTI9YYH2HbmJMTUxYKwLAEAERBHlKDhAQBDMzaQI+Wj09WgE7EREEc1AOEBAEMTVpAVbumzFCEAR5SQ4BEAEbBCU7KSkOAQgCWHV9sr1WQ1hOFxovI7wDZvLzxlqsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VGDTAXfPZAYGBo9gPXEdRMpzrgYGmScgUl51fVFEXm1DGiv8unGmVLRaBAgfEH2UbKJ1BAQEA6RWPz9WQPyaXtUBuMlYBggdDn2k/ivPZAQEBAE/mtEhZMdYBggfEH2k/ieejQQEBARicwHAqId7XgFEIyAZSgHn/hkG/QADAAAAAAALAPb+ThBmBggADwAdADgAQwBOAGIAagB+AJ4AqgCxAgAAsA0vsRIB6bA0L7F7kjMzsTwC6bCiMrA8ELScAgAoBCuwQy+xRALpsKkvsYIC6bBXMrBLL7EpAumzFEtqDiu0ZgEAHQQrsXOKMjKwGi+xBALpAbCyL7AA1rEQBOmwEBCxIAErsTkD6bBEMrA5ELE/ASuxMQPpsEgg1hGxLAPpsDEQsWQBK7FPVDIysWgD6bFZXjIys1FoZAgrsVwD6bBoELFtASuxeAPpsnhtCiuzQHh1CSuybXgKK7NAbXAJK7B4ELF/ASuxnwPpsJ8QsaQBK7CEMrGPA+myj6QKK7NAj4wJK7Kkjwors0CkhwkrsI8QsawBK7SvBAAuBCuwrxCxFgErsQkD6bGzASuxIBARErMeIyQ4JBc5sDkRsSY3OTmwSBKyKTQ8OTk5sD8RsC85sWQxERKxVWI5ObFcUREStGFlZmlqJBc5sGgRsVdfOTmwbRKya3F+OTk5sHgRsH05sH8SsnN6ezk5ObGknxESsoKImjk5ObCPEbCUObCsErOKkZKrJBc5sK8RsLE5sBYSsLA5ALGcEhESsLE5sTw0ERK2Hk9eX2t6kSQXObBDEUALPzF/mZqfpKusr7AkFzmwRBKxL6U5ObGCqRESs1RWWYQkFzmwahGxSCw5ObEpSxESsyNjaI0kFzmwZhG1ZGdwdYeMJBc5sBoSsa2uOTkwMRcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NRE0JzcWMzI2MzIWFRQGBxYVFAYjIiYjBzcUFjMyNjU0JisBNTMyNjU0JiMiBhUBNjc1NCc3NjcyFQYdARQXByYjBxI0NjIWFAYiATY1ETQnNzY3MhUGFREUFwcmIwcBNDYzMhc1NCc3NjcyFwYHERQXByYjIgciLwEjBiciJjcUFjMyNxEuAiMiARcRMxE3A/aLfQ03j6Jsh/KLi31Jvwz6XE6q8wZcYwENDg4COzMvlhfBqVI96dHTSIctbtExTI9YYH2HbmJMTUxYKwLAEAERBHlKDhAQBDMzaQI+Wj09WgE7EREEc1AOEBAEMTVpAVbumzFCEAR5SQ4BEAEbBCU7KSkOAQgCWHV9sr1WQ1hOFxovI7wDZsdaxPGsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VGDTAXfPZAYGBo9gPXEdRMpzrgYGmScgUl51fVFEXm1DGiv8unGmVLRaBAgfEH2UbKJ1BAQEA6RWPz9WQPyaXtUBuMlYBggdDn2k/ivPZAQEBAE/mtEhZMdYBggfEH2k/ieejQQEBARicwHAqId7XgFEIyAZ/uUGA1L8rgb+GQAADQD2/k4SFAYIAA8AHQA4AEQAbAB3AK4AvQDGAMgA3gDoAO8AABcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFQE2NxE0JzcWMzI2MzIWFRQGIyInFRQXByYjBxMWMzI2NTQmIyIGFQE0Nj8BMjU0JiMiBy8BNz4BMyAVFAIVFDMyNxcWFwYjIiYnIwYjIiY3FBYzMjc2JzUHBgE0Ny4BNTQ3JyYnNDYzMhc+ATcXBhUUFwcmJx4CFRQGIyIvAQYVFB4BMzc2NzIeARUUBCMiJjcUFjMyNjU0IyIOASMOARMUMzI2NTQnIhMzATQ2MzIWFRQnIRQWMzI3FhUOASMiJhMzMic0JiMiDgElGwEnESMR9ot9DuWPomyH8N2LfUm/DqhcTqrxWFxjAaQQAREENzQZvBK+ucu+QjERBDk2bc8dTm9LUFpOLQHum3OHCDk/ZkgjKQYlk0oBFAYlCi0FEBBGZjE/CwJkcVZuuCchL1QbAXpqAiiHJTFACD8BonsrL0K6FgYGBgYJpBgmFZOBUiUMGR8cHS1GGlCDZ/7npGakul0zZJDRCCIsEykhFXkvPX9mNgEBy917j5Qb/mN2UI1QIS2eUqbEx9sXATEvGTE9AmDy37JarAWsf4mDhfpUjXl9yKpOXAVtvmJc+1RxwgF5vnUEBAqlWXXEDo2+dQQEBAIGDlx/h1IfJf04TH4bIRJWSnkCZQYhP/oE/vgbLyEECCFWMydaVl4jNUEXEpohHf5jZFYKPi9kOgoxb2KHDgQWAgQXGhkUBAEOEjM8HWKCFwYnNR8hBAQIASFgSnWPVHlGSFxGcwMDIToCSrZFTrIB/YIBG6LPpm0bAZOKVhIjPUy4ARAVTjsSTaEB5/4ZBv0AAwAAAAANAPb+ThIUBggADwAdADgARABsAHcArgC9AMYAyADeAOgA7wAAFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVATY3ETQnNxYzMjYzMhYVFAYjIicVFBcHJiMHExYzMjY1NCYjIgYVATQ2PwEyNTQmIyIHLwE3PgEzIBUUAhUUMzI3FxYXBiMiJicjBiMiJjcUFjMyNzYnNQcGATQ3LgE1NDcnJic0NjMyFz4BNxcGFRQXByYnHgIVFAYjIi8BBhUUHgEzNzY3Mh4BFRQEIyImNxQWMzI2NTQjIg4BIw4BExQzMjY1NCciEzMBNDYzMhYVFCchFBYzMjcWFQ4BIyImEzMyJzQmIyIOAQUXETMRNwP2i30O5Y+ibIfw3Yt9Sb8OqFxOqvFYXGMBpBABEQQ3NBm8Er65y75CMREEOTZtzx1Ob0tQWk4tAe6bc4cIOT9mSCMpBiWTSgEUBiUKLQUQEEZmMT8LAmRxVm64JyEvVBsBemoCKIclMUAIPwGieysvQroWBgYGBgmkGCYVk4FSJQwZHxwdLUYaUINn/uekZqS6XTNkkNEIIiwTKSEVeS89f2Y2AQHL3XuPlBv+Y3ZQjVAhLZ5SpsTH2xcBMS8ZMT0CYLJaxfKsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7VHHCAXm+dQQECqVZdcQOjb51BAQEAgYOXH+HUh8l/ThMfhshElZKeQJlBiE/+gT++BsvIQQIIVYzJ1pWXiM1QRcSmiEd/mNkVgo+L2Q6CjFvYocOBBYCBBcaGRQEAQ4SMzwdYoIXBic1HyEEBAgBIWBKdY9UeUZIXEZzAwMhOgJKtkVOsgH9ggEbos+mbRsBk4pWEiM9TLgBEBVOOxJNxAYDUvyuBv4ZAAAAAAoA9v5ODs0GCAAPAB0ARABSAIwAmQDBANMA3wDtAAAXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUTNjURNCYnNxYzMjYzMh4FFRQOAiMiLgEnFRQXByIuASMHExYzMjY1NCYjIg4CFQE0Nj8BMjY1NC4EIyIGBy8BNz4BMzIeAxUUDgIVFBYzMj4BNxceARcOASMiLgEnIwYjIiY3FB4CMzI3Nj0BBwYlND4BMzIWFzU0Jzc+AjcyHgEVBgcRFBcHLgEjIgcmLwEjDgEjIiY3FB4BMxY3ES4BIyIOBSU0EjMyFhUUBiMiAjcQMzIRNC4CIyIOAvaLfQuej6Jth/Qli31JvwtgXE6q9KBcY6cOBwcDMCwVpBAzWEE1IhcKKE6IVhgiGREPBAYSMxVdshlEX0JFTiMsFQcBdodjdQMEBQwRGBwSLE8cHiQGH4BAJkI/LRsBAgITDQgQFgIDCQwIHk4pHC4bBgFXYkpgoAgPGA8qRxdqXAHcYpxWFDcZDwQaQjwQBAYDDgEYBAs6DiYhCwIHASReMG2ZoyY5Jk1DHCsrEBojHBsTDAM3xYGDvcGFnKS1jY8IGD4tHy0tGKwFrH+Jg4X6VI15fciqTlwFbb5iXPuXYKoBRk+ENwMDCREbJSgrJhItW1M0AwUEeqNnAwECAwHADFBtdUcHEBMQ/ZBBbRgdCAgZKB8WDQc6LwJXBRw3Cx8vTTIESFRSDRMVCRECBAUQDiYlFiMVTkpSDhoWDjkTEIUcGRdXklEQDVetSwUCCw4HAwcEboz+Z4d8AwECAwECVS80ppJQZygBUgEYLSMDCxMhLENm2QEK/tf45QEKtP6DAblMbntBIFS3AAAAAAkA9v5ODs0GCAAPAB0ARABSAIwAmQDBANMA6QAAFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVEzY1ETQmJzcWMzI2MzIeBRUUDgIjIi4BJxUUFwciLgEjBxMWMzI2NTQmIyIOAhUBNDY/ATI2NTQuBCMiBgcvATc+ATMyHgMVFA4CFRQWMzI+ATcXHgEXDgEjIi4BJyMGIyImNxQeAjMyNzY9AQcGJTQ+ATMyFhc1NCc3PgI3Mh4BFQYHERQXBy4BIyIHJi8BIw4BIyImNxQeATMWNxEuASMiDgUBNiUyFQYVERQXByYjBzU2NxE0IyIH9ot9C56Pom2H9CWLfUm/C2BcTqr0oFxjpw4HBwMwLBWkEDNYQTUiFwooTohWGCIZEQ8EBhIzFV2yGURfQkVOIywVBwF2h2N1AwQFDBEYHBIsTxweJAYfgEAmQj8tGwECAhMNCBAWAgMJDAgeTikcLhsGAVdiSmCgCA8YDypHF2pcAdxinFYUNxkPBBpCPBAEBgMOARgECzoOJiELAgcBJF4wbZmjJjkmTUMcKysQGiMcGxMMA1RtARIKEBIEMzdpEAEdUlSsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7l2CqAUZPhDcDAwkRGyUoKyYSLVtTNAMFBHqjZwMBAgMBwAxQbXVHBxATEP2QQW0YHQgIGSgfFg0HOi8CVwUcNwsfL00yBEhUUg0TFQkRAgQFEA4mJRYjFU5KUg4aFg45ExCFHBkXV5JREA1XrUsFAgsOBwMHBG6M/meHfAMBAgMBAlUvNKaSUGcoAVIBGC0jAwsTISxDAeIZWgakVv59qncEBAQEYr8BdWQKAAkA9v5ODs0GCAAPAB0ARABSAIwAmQDBANMA+wAAFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVEzY1ETQmJzcWMzI2MzIeBRUUDgIjIi4BJxUUFwciLgEjBxMWMzI2NTQmIyIOAhUBNDY/ATI2NTQuBCMiBgcvATc+ATMyHgMVFA4CFRQWMzI+ATcXHgEXDgEjIi4BJyMGIyImNxQeAjMyNzY9AQcGJTQ+ATMyFhc1NCc3PgI3Mh4BFQYHERQXBy4BIyIHJi8BIw4BIyImNxQeATMWNxEuASMiDgUBNDY/AT4BNTQmIyIHIyc3PgEzMhYVFAYPAQYVMzI3BhUUFyYjIgQj9ot9C56Pom2H9CWLfUm/C2BcTqr0oFxjpw4HBwMwLBWkEDNYQTUiFwooTohWGCIZEQ8EBhIzFV2yGURfQkVOIywVBwF2h2N1AwQFDBEYHBIsTxweJAYfgEAmQj8tGwECAhMNCBAWAgMJDAgeTikcLhsGAVdiSmCgCA8YDypHF2pcAdxinFYUNxkPBBpCPBAEBgMOARgECzoOJiELAgcBJF4wbZmjJjkmTUMcKysQGiMcGxMMAwpYe3M9IVYtd0klIQQjoEuRtURPmmZ/arAICKxcRP8AK6wFrH+Jg4X6VI15fciqTlwFbb5iXPuXYKoBRk+ENwMDCREbJSgrJhItW1M0AwUEeqNnAwECAwHADFBtdUcHEBMQ/ZBBbRgdCAgZKB8WDQc6LwJXBRw3Cx8vTTIESFRSDRMVCRECBAUQDiYlFiMVTkpSDhoWDjkTEIUcGRdXklEQDVetSwUCCw4HAwcEboz+Z4d8AwECAwECVS80ppJQZygBUgEYLSMDCxMhLEP+rT98f3A/c1pCWoF5Bh03eXdQaEyTYCMMKTsfKQYGAAAAAAkA9v5ODs0GCAAPAB0ARABSAIwAmQDBANMBAQAAFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVEzY1ETQmJzcWMzI2MzIeBRUUDgIjIi4BJxUUFwciLgEjBxMWMzI2NTQmIyIOAhUBNDY/ATI2NTQuBCMiBgcvATc+ATMyHgMVFA4CFRQWMzI+ATcXHgEXDgEjIi4BJyMGIyImNxQeAjMyNzY9AQcGJTQ+ATMyFhc1NCc3PgI3Mh4BFQYHERQXBy4BIyIHJi8BIw4BIyImNxQeATMWNxEuASMiDgUBPwEeAjMyPgI1NCMiBzU+ATU0JiMiBgcvATc+ATMyFhUUBxUeARUUBiMiJ/aLfQuej6Jth/Qli31JvwtgXE6q9KBcY6cOBwcDMCwVpBAzWEE1IhcKKE6IVhgiGREPBAYSMxVdshlEX0JFTiMsFQcBdodjdQMEBQwRGBwSLE8cHiQGH4BAJkI/LRsBAgITDQgQFgIDCQwIHk4pHC4bBgFXYkpgoAgPGA8qRxdqXAHcYpxWFDcZDwQaQjwQBAYDDgEYBAs6DiYhCwIHASReMG2ZoyY5Jk1DHCsrEBojHBsTDAMhIyUjGEY3GTE5I6gpE29kQS1MSislHgQjm1B3nrdehNybkWesBax/iYOF+lSNeX3Iqk5cBW2+Ylz7l2CqAUZPhDcDAwkRGyUoKyYSLVtTNAMFBHqjZwMBAgMBwAxQbXVHBxATEP2QQW0YHQgIGSgfFg0HOi8CVwUcNwsfL00yBEhUUg0TFQkRAgQFEA4mJRYjFU5KUg4aFg45ExCFHBkXV5JREA1XrUsFAgsOBwMHBG6M/meHfAMBAgMBAlUvNKaSUGcoAVIBGC0jAwsTISxD/vd5AjsnJRAnWECyAkUGX2A7UjtMAnkGHTdeZbovBghxZpOQVgAAAAoA9v5ODs0GCAAPAB0ARABSAIwAmQDBANMA9QD4AAAXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUTNjURNCYnNxYzMjYzMh4FFRQOAiMiLgEnFRQXByIuASMHExYzMjY1NCYjIg4CFQE0Nj8BMjY1NC4EIyIGBy8BNz4BMzIeAxUUDgIVFBYzMj4BNxceARcOASMiLgEnIwYjIiY3FB4CMzI3Nj0BBwYlND4BMzIWFzU0Jzc+AjcyHgEVBgcRFBcHLgEjIgcmLwEjDgEjIiY3FB4BMxY3ES4BIyIOBQU0NzYANzUWMzcXBhURMzIXFAYrARQXByYjByc2NSEjIiY3IRH2i30Lno+ibYf0JYt9Sb8LYFxOqvSgXGOnDgcHAzAsFaQQM1hBNSIXCihOiFYYIhkRDwQGEjMVXbIZRF9CRU4jLBUHAXaHY3UDBAUMERgcEixPHB4kBh+AQCZCPy0bAQICEw0IEBYCAwkMCB5OKRwuGwYBV2JKYKAIDxgPKkcXalwB3GKcVhQ3GQ8EGkI8EAQGAw4BGAQLOg4mIQsCBwEkXjBtmaMmOSZNQxwrKxAaIxwbEwwC1RBCAQREEjlnBBBuFAEdDlgQBC84aAIS/scNKB11ARasBax/iYOF+lSNeX3Iqk5cBW2+Ylz7l2CqAUZPhDcDAwkRGyUoKyYSLVtTNAMFBHqjZwMBAgMBwAxQbXVHBxATEP2QQW0YHQgIGSgfFg0HOi8CVwUcNwsfL00yBEhUUg0TFQkRAgQFEA4mJRYjFU5KUg4aFg45ExCFHBkXV5JREA1XrUsFAgsOBwMHBG6M/meHfAMBAgMBAlUvNKaSUGcoAVIBGC0jAwsTISxDdDEXWAGQcgQEBAR7av6THhA2ZnsEBAQEhVwGXgG5AAAACQD2/k4OzQYIAA8AHQBEAFIAjACZAMEA0wD4AAAXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUTNjURNCYnNxYzMjYzMh4FFRQOAiMiLgEnFRQXByIuASMHExYzMjY1NCYjIg4CFQE0Nj8BMjY1NC4EIyIGBy8BNz4BMzIeAxUUDgIVFBYzMj4BNxceARcOASMiLgEnIwYjIiY3FB4CMzI3Nj0BBwYlND4BMzIWFzU0Jzc+AjcyHgEVBgcRFBcHLgEjIgcmLwEjDgEjIiY3FB4BMxY3ES4BIyIOBQE/AR4BMzI2NTQmIyIHJxMWFzI3FwcGIyInBzYXMhYVFAYjIif2i30Lno+ibYf0JYt9Sb8LYFxOqvSgXGOnDgcHAzAsFaQQM1hBNSIXCihOiFYYIhkRDwQGEjMVXbIZRF9CRU4jLBUHAXaHY3UDBAUMERgcEixPHB4kBh+AQCZCPy0bAQICEw0IEBYCAwkMCB5OKRwuGwYBV2JKYKAIDxgPKkcXalwB3GKcVhQ3GQ8EGkI8EAQGAw4BGAQLOg4mIQsCBwEkXjBtmaMmOSZNQxwrKxAaIxwbEwwDMx8lKVI/O1dORk5YIDGFJ2qwCxlUakxnFkJLfai/j5FnrAWsf4mDhfpUjXl9yKpOXAVtvmJc+5dgqgFGT4Q3AwMJERslKCsmEi1bUzQDBQR6o2cDAQIDAcAMUG11RwcQExD9kEFtGB0ICBkoHxYNBzovAlcFHDcLHy9NMgRIVFINExUJEQIEBRAOJiUWIxVOSlIOGhYOORMQhRwZF1eSURANV61LBQILDgcDBwRujP5nh3wDAQIDAQJVLzSmklBnKAFSARgtIwMLEyEsQ/7peAJKQW1oZnUlCwHNCgERBJgIDN8ZAadzkatWAAoA9v5ODs0GCAAPAB0AQwBRAIsAlgC+ANAA6AD4AAAXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUTNjURNCYnNxYzMjYzMh4EFRQOAiMiLgEnFRQXByIuASMHExYzMjY1NCYjIg4CFQE0Nj8BMjY1NC4EIyIGBy8BNz4BMzIeAxUUDgIVFBYzMj4BNxceARcOASMiLgEnIwYjIiY3FBYzMjc2PQEHBiU0PgEzMhYXNTQnNz4CNzIeARUGBxEUFwcuASMiByYvASMOASMiJjcUHgEzFjcRLgEjIg4FJTQ+AjMXDgQHNjMyFhUUBiMiJyY3FBYzMjY1NC4DIyIHBvaLfQuej6Jth/Qli31JvwtgXE6q9KBcY6cOBwcDMCwVpBA7ZEU0HQ8oTohWGCIZEQ8EBhIzFV2yGURfQkVOIywVBwF2h2N1AwQFDBEYHBIsTxweJAYfgEAmQj8tGwECAhMNCBAWAgMJDAgeTikcLhsGAVdiSmCgIR0pSBdqXAHcYpxWFDcZDwQaQjwQBAYDDgEYBAs6DiYhCwIHASReMG2ZoyY5Jk1DHCsrEBojHBsTDAMpTI3wkQQrP3dSUBI9UqKPnZp3SpG6VEotRgIRHDopRTUErAWsf4mDhfpUjXl9yKpOXAVtvmJc+5dgqgFGT4Q3AwMJFiQtMy0VLVtTNAMFBHqjZwMBAgMBwAxQbXVHBxATEP2QQW0YHQgIGSgfFg0HOi8CVwUcNwsfL00yBEhUUg0TFQkRAgQFEA4mJRYjFU5KUh0vORMQhRwZF1eSURANV61LBQILDgcDBwRujP5nh3wDAQIDAQJVLzSmklBnKAFSARgtIwMLEyEsQwVav6xsNwQKLUaNYCmkcW+yL1r0uIFqaR8rQykhKyUAAAkA9v5ODs0GCAAPAB0ARABSAIwAmQDBANMA5gAAFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVEzY1ETQmJzcWMzI2MzIeBRUUDgIjIi4BJxUUFwciLgEjBxMWMzI2NTQmIyIOAhUBNDY/ATI2NTQuBCMiBgcvATc+ATMyHgMVFA4CFRQWMzI+ATcXHgEXDgEjIi4BJyMGIyImNxQeAjMyNzY9AQcGJTQ+ATMyFhc1NCc3PgI3Mh4BFQYHERQXBy4BIyIHJi8BIw4BIyImNxQeATMWNxEuASMiDgUBNDY1NCY1FgUyNxcCAwcnNhMi9ot9C56Pom2H9CWLfUm/C2BcTqr0oFxjpw4HBwMwLBWkEDNYQTUiFwooTohWGCIZEQ8EBhIzFV2yGURfQkVOIywVBwF2h2N1AwQFDBEYHBIsTxweJAYfgEAmQj8tGwECAhMNCBAWAgMJDAgeTikcLhsGAVdiSmCgCA8YDypHF2pcAdxinFYUNxkPBBpCPBAEBgMOARgECzoOJiELAgcBJF4wbZmjJjkmTUMcKysQGiMcGxMMA4EICFABezUtFc+LhgRr3ZOsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7l2CqAUZPhDcDAwkRGyUoKyYSLVtTNAMFBHqjZwMBAgMBwAxQbXVHBxATEP2QQW0YHQgIGSgfFg0HOi8CVwUcNwsfL00yBEhUUg0TFQkRAgQFEA4mJRYjFU5KUg4aFg45ExCFHBkXV5JREA1XrUsFAgsOBwMHBG6M/meHfAMBAgMBAlUvNKaSUGcoAVIBGC0jAwsTISxDAaMCQg4MPgQKAQ0f/gz+ZQYM8QIjAAAAAAsA9v5ODs0GCAAPAB0AQwBRAIsAlgC+ANAA6QD2AP8AABcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFRM2NRE0Jic3FjMyNjMyHgQVFA4CIyIuAScVFBcHIi4BIwcTFjMyNjU0JiMiDgIVATQ2PwEyNjU0LgQjIgYHLwE3PgEzMh4DFRQOAhUUFjMyPgE3Fx4BFw4BIyIuAScjBiMiJjcUFjMyNzY9AQcGJTQ+ATMyFhc1NCc3PgI3Mh4BFQYHERQXBy4BIyIHJi8BIw4BIyImNxQeATMWNxEuASMiDgUFNDY3JyYnNDYzMhYVFAYHFx4BFRQHBgQmNxQWMzI2NTQmLwEOARMUHwE2NTQjIvaLfQuej6Jth/Qli31JvwtgXE6q9KBcY6cOBwcDMCwVpBA7ZEU0HQ8oTohWGCIZEQ8EBhIzFV2yGURfQkVOIywVBwF2h2N1AwQFDBEYHBIsTxweJAYfgEAmQj8tGwECAhMNCBAWAgMJDAgeTikcLhsGAVdiSmCgIR0pSBdqXAHcYpxWFDcZDwQaQjwQBAYDDgEYBAs6DiYhCwIHASReMG2ZoyY5Jk1DHCsrEBojHBsTDAMxcW4akwGQj3+LXmJgPVJ6UP71tKxZN0pTM0hHQikpXjBWc3GsBax/iYOF+lSNeX3Iqk5cBW2+Ylz7l2CqAUZPhDcDAwkWJC0zLRUtW1M0AwUEeqNnAwECAwHADFBtdUcHEBMQ/ZBBbRgdCAgZKB8WDQc6LwJXBRw3Cx8vTTIESFRSDRMVCRECBAUQDiYlFiMVTkpSHS85ExCFHBkXV5JREA1XrUsFAgsOBwMHBG6M/meHfAMBAgMBAlUvNKaSUGcoAVIBGC0jAwsTISxDhFJ5OQ5agGR1aVhIXic9KXs/iUwvAX1xUGJGZEJPKysvagHEVjsdQlqRAAAKAPb+Tg7NBggADwAdAEMAUQCLAJYAvgDQAOgA+AAAFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVEzY1ETQmJzcWMzI2MzIeBBUUDgIjIi4BJxUUFwciLgEjBxMWMzI2NTQmIyIOAhUBNDY/ATI2NTQuBCMiBgcvATc+ATMyHgMVFA4CFRQWMzI+ATcXHgEXDgEjIi4BJyMGIyImNxQWMzI3Nj0BBwYlND4BMzIWFzU0Jzc+AjcyHgEVBgcRFBcHLgEjIgcmLwEjDgEjIiY3FB4BMxY3ES4BIyIOBQE0NjMyFxYXFA4CIyc+BDcGIyImNxQeAzMyNzY1NCYjIgb2i30Lno+ibYf0JYt9Sb8LYFxOqvSgXGOnDgcHAzAsFaQQO2RFNB0PKE6IVhgiGREPBAYSMxVdshlEX0JFTiMsFQcBdodjdQMEBQwRGBwSLE8cHiQGH4BAJkI/LRsBAgITDQgQFgIDCQwIHk4pHC4bBgFXYkpgoCEdKUgXalwB3GKcVhQ3GQ8EGkI8EAQGAw4BGAQLOg4mIQsCBwEkXjBtmaMmOSZNQxwrKxAaIxwbEwwDQp2ad0mRAUyN8JEEKz93UlASPVKij74CERw6KUU1BFNKLUasBax/iYOF+lSNeX3Iqk5cBW2+Ylz7l2CqAUZPhDcDAwkWJC0zLRUtW1M0AwUEeqNnAwECAwHADFBtdUcHEBMQ/ZBBbRgdCAgZKB8WDQc6LwJXBRw3Cx8vTTIESFRSDRMVCRECBAUQDiYlFiMVTkpSHS85ExCFHBkXV5JREA1XrUsFAgsOBwMHBG6M/meHfAMBAgMBAlUvNKaSUGcoAVIBGC0jAwsTISxDASJvsi9a+Fq/rGw3BAotRo1gKaR7HytDKSErJSG4gWoAAAAACwD2/k4OzQYIAA8AHQA4AEQAbAB3AJcAoQCvALwAygAAFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVEzY3ETQnNxYzMjYzMhYVFAYjIicVFBcHJicHExYzMjY1NCYjIgYVATQ2PwEyNTQmIyIHLwE3PgEzMgcUBhUUMzI+ATcXFhcGIicjBiMiJjcUFjMyNzY9AQcGJTQ2MzIXNTQnNzY3MhcGBxEUFwcmIyIHIjUnIwYjIiY3FDMyNxEuASMiBTQ2MyUyFhUUBiMFIiYXNTY3MxYXFQYHIy4BAzU+ATczFhcVBgcjLgH2i30Lno+ibYf0JYt9Sb8LYFxOqvSgXGOmDgEPBC8uFKQQpKCupjUvDgIzLV+zHT9gQkZORCYBdohidQgxOFo9HyMGIX9A7gEEHwgSFQIEDA87sRICWGFMXqAhHStFGWtcAdvPhyk6DwRxNwwBDgEXAiEzIyUMBgJOY22bpIVMRB0pK6QC7CQRArwMEycS/UkOEvklXwZgIyVeBjc9EBJNJQZiISVeBjc9rAWsf4mDhfpUjXl9yKpOXAVtvmJc+5hkpgFFoGsCAgiQS2StDXmgagUEAQUBwQxSbHVGGSH9kEJsGB0QSj9oAlYGHTfZBOMXKQoRAgQGH0pOTkpSHS85FA+FHBsZg7YdWKhQBggZDnOH/maDfwQEBARWZKaR31IBGC0jWhtUCB0OF1EJF/QIXiMjXghqFww8An0KL0YKI1wKaBcMOgAACQD2/k4OzQYIAA8AHQBDAFEAiwCWAL4A0ADcAAAXETQ2MyEyFhURFAYjISImNxQzITI2NRE0IyEiBhUTNjURNCYnNxYzMjYzMh4EFRQOAiMiLgEnFRQXByIuASMHExYzMjY1NCYjIg4CFQE0Nj8BMjY1NC4EIyIGBy8BNz4BMzIeAxUUDgIVFBYzMj4BNxceARcOASMiLgEnIwYjIiY3FBYzMjc2PQEHBiU0PgEzMhYXNTQnNz4CNzIeARUGBxEUFwcuASMiByYvASMOASMiJjcUHgEzFjcRLgEjIg4FJTUhETMRIRUhESMR9ot9C56Pom2H9CWLfUm/C2BcTqr0oFxjpw4HBwMwLBWkEDtkRTQdDyhOiFYYIhkRDwQGEjMVXbIZRF9CRU4jLBUHAXaHY3UDBAUMERgcEixPHB4kBh+AQCZCPy0bAQICEw0IEBYCAwkMCB5OKRwuGwYBV2JKYKAhHSlIF2pcAdxinFYUNxkPBBpCPBAEBgMOARgECzoOJiELAgcBJF4wbZmjJjkmTUMcKysQGiMcGxMMAsMBW5gBW/6lmKwFrH+Jg4X6VI15fciqTlwFbb5iXPuXYKoBRk+ENwMDCRYkLTMtFS1bUzQDBQR6o2cDAQIDAcAMUG11RwcQExD9kEFtGB0ICBkoHxYNBzovAlcFHDcLHy9NMgRIVFINExUJEQIEBRAOJiUWIxVOSlIdLzkTEIUcGRdXklEQDVetSwUCCw4HAwcEboz+Z4d8AwECAwECVS80ppJQZygBUgEYLSMDCxMhLEM6mAFN/rOY/rUBSwAAAAkA9v5ODs0GCAAPAB0ARABSAIwAmQDBANMA4QAAFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVEzY1ETQmJzcWMzI2MzIeBRUUDgIjIi4BJxUUFwciLgEjBxMWMzI2NTQmIyIOAhUBNDY/ATI2NTQuBCMiBgcvATc+ATMyHgMVFA4CFRQWMzI+ATcXHgEXDgEjIi4BJyMGIyImNxQeAjMyNzY9AQcGJTQ+ATMyFhc1NCc3PgI3Mh4BFQYHERQXBy4BIyIHJi8BIw4BIyImNxQeATMWNxEuASMiDgUlNDYzJTIWFRQGIwUiJvaLfQuej6Jth/Qli31JvwtgXE6q9KBcY6cOBwcDMCwVpBAzWEE1IhcKKE6IVhgiGREPBAYSMxVdshlEX0JFTiMsFQcBdodjdQMEBQwRGBwSLE8cHiQGH4BAJkI/LRsBAgITDQgQFgIDCQwIHk4pHC4bBgFXYkpgoAgPGA8qRxdqXAHcYpxWFDcZDwQaQjwQBAYDDgEYBAs6DiYhCwIHASReMG2ZoyY5Jk1DHCsrEBojHBsTDAKyJhIC6Q4SKRT9IA8VrAWsf4mDhfpUjXl9yKpOXAVtvmJc+5dgqgFGT4Q3AwMJERslKCsmEi1bUzQDBQR6o2cDAQIDAcAMUG11RwcQExD9kEFtGB0ICBkoHxYNBzovAlcFHDcLHy9NMgRIVFINExUJEQIEBRAOJiUWIxVOSlIOGhYOORMQhRwZF1eSURANV61LBQILDgcDBwRujP5nh3wDAQIDAQJVLzSmklBnKAFSARgtIwMLEyEsQy0eWQkgDxhWCRYAAAAJAPb+Tg7NBggADwAdAEMAUQCLAJYAvgDQANwAABcRNDYzITIWFREUBiMhIiY3FDMhMjY1ETQjISIGFRM2NRE0Jic3FjMyNjMyHgQVFA4CIyIuAScVFBcHIi4BIwcTFjMyNjU0JiMiDgIVATQ2PwEyNjU0LgQjIgYHLwE3PgEzMh4DFRQOAhUUFjMyPgE3Fx4BFw4BIyIuAScjBiMiJjcUFjMyNzY9AQcGJTQ+ATMyFhc1NCc3PgI3Mh4BFQYHERQXBy4BIyIHJi8BIw4BIyImNxQeATMWNxEuASMiDgUFNyc3FzcXBxcHJwf2i30Lno+ibYf0JYt9Sb8LYFxOqvSgXGOnDgcHAzAsFaQQO2RFNB0PKE6IVhgiGREPBAYSMxVdshlEX0JFTiMsFQcBdodjdQMEBQwRGBwSLE8cHiQGH4BAJkI/LRsBAgITDQgQFgIDCQwIHk4pHC4bBgFXYkpgoCEdKUgXalwB3GKcVhQ3GQ8EGkI8EAQGAw4BGAQLOg4mIQsCBwEkXjBtmaMmOSZNQxwrKxAaIxwbEwwDDPTqa+r0avTpa+j0rAWsf4mDhfpUjXl9yKpOXAVtvmJc+5dgqgFGT4Q3AwMJFiQtMy0VLVtTNAMFBHqjZwMBAgMBwAxQbXVHBxATEP2QQW0YHQgIGSgfFg0HOi8CVwUcNwsfL00yBEhUUg0TFQkRAgQFEA4mJRYjFU5KUh0vORMQhRwZF1eSURANV61LBQILDgcDBwRujP5nh3wDAQIDAQJVLzSmklBnKAFSARgtIwMLEyEsQ7n06mrq9Gvz6Wro9AAAAAkA9v5ODs0GCAAPAB0AQwBRAIsAlgC+ANAA2QAAFxE0NjMhMhYVERQGIyEiJjcUMyEyNjURNCMhIgYVEzY1ETQmJzcWMzI2MzIeBBUUDgIjIi4BJxUUFwciLgEjBxMWMzI2NTQmIyIOAhUBNDY/ATI2NTQuBCMiBgcvATc+ATMyHgMVFA4CFRQWMzI+ATcXHgEXDgEjIi4BJyMGIyImNxQWMzI3Nj0BBwYlND4BMzIWFzU0Jzc+AjcyHgEVBgcRFBcHLgEjIgcmLwEjDgEjIiY3FB4BMxY3ES4BIyIOBQUlByERMxEhF/aLfQuej6Jth/Qli31JvwtgXE6q9KBcY6cOBwcDMCwVpBA7ZEU0HQ8oTohWGCIZEQ8EBhIzFV2yGURfQkVOIywVBwF2h2N1AwQFDBEYHBIsTxweJAYfgEAmQj8tGwECAhMNCBAWAgMJDAgeTikcLhsGAVdiSmCgIR0pSBdqXAHcYpxWFDcZDwQaQjwQBAYDDgEYBAs6DiYhCwIHASReMG2ZoyY5Jk1DHCsrEBojHBsTDAJkAegGAXda/i8GrAWsf4mDhfpUjXl9yKpOXAVtvmJc+5dgqgFGT4Q3AwMJFiQtMy0VLVtTNAMFBHqjZwMBAgMBwAxQbXVHBxATEP2QQW0YHQgIGSgfFg0HOi8CVwUcNwsfL00yBEhUUg0TFQkRAgQFEA4mJRYjFU5KUh0vORMQhRwZF1eSURANV61LBQILDgcDBwRujP5nh3wDAQIDAQJVLzSmklBnKAFSARgtIwMLEyEsQ0v0xwJb/UvEAAAAAAEAAAAAmZny/8gSXw889QAfCAAAAAAAy6xiZAAAAADLrGJkAAD+Dh3sBgkAAQAIAAIAAAAAAAAAAQAABgn95gAAHrgAAAAAHewAAQAAAAAAAAAAAAAAAAAAAK0EAAB/AAAAAAKqAAACAAAACMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gjMAPYIzAD2CMwA9gIAAAAIzAD2AwQAAAYIAAADBAAABggAAAICAAABggAAAQEAAAEBAAAAwQAAATQAAABVAAAIzAD2CMwA9gjMAPYFwgD2CcIA9gE0AAABggAABgkAAAgQAPIIEADyCBAA8ggQAPIIEADyB4kBeQeJANUHiQDVB4kA1QeJANULwgD2D1wA9g+ZAPYMzADNE2YAzRMzAPYLwgD2C8IA9gvCAPYOjwD2CrgA9gq4APYKuAD2CrgA9gq4APYKuAD2CrgA9gq4APYKuAD2DMwA9gzMAPYMzAD2DMwA9gzMAPYMzAD2DMwA9gq4APYTrgD2DdcA9gvrAPYeuADNDmYA9gvCAPYPwgD2D8IA9g/CAPYYowD2DTMA9hDhAPYRXAD2EVwA9hMKAPYTCgD2D5kA9gD2APYA9gD2APYA9gD2APYA9gD2APYA9gD2APYAAABoAGgAaABoAPQBkgMGA+gE3gXGBjIGngcIB8gIRAi+CR4JgAnYCmAK9AuWDEgM9A2yDlIOzA+SEEIQwBFYEbISFBJuEygUFhS2FXgWFBa2F3wYKhjWGZAaChqeG0Ab1hyKHVQd2h6OHzogDiDEIWIiBCJyIwgjhiQQJLwlKiWcJgomZia6JxwoAii+KU4qEiquK2oskC1SLewuri9eL+Aw3DGMMhAy2jOMNCw02DWMNkY2tDdYN9Y4TDjyOYI52jpwOvY69jtWO1Y7VjtWO1Y7VjtWO1Y7VjtWO1Y7Vju2PBY8djzYPTo9Oj06PUg+ej+aQLpB2ELkQ5ZEoEWcRpJHdkiASORKJEtsTYpPKk+0UGJQ/FGGUnpThlSkVbRW2lfoWMRZ+FsYXFBdgF7SYDRhjGL6ZEhlYGZ2Z7JpCmlOavZyDHOsdMh12Hb+eGh6YnxaflR/ooDwgjSDcoTIhiSHeIjKihqLWIy2jgiPIpBQkYSStJPgAAEAAAC7BQEAEwAAAAAAAgABAAIAFgAAAQACEgAAAAAAAAAIAGYAAwABBAkAAAIuAAAAAwABBAkAAQAuAi4AAwABBAkAAgAOAlwAAwABBAkAAwAOAmoAAwABBAkABAA+AngAAwABBAkABQAcArYAAwABBAkABgAYAtIAAwABBAkAyABuAuoATABpAG4AdQB4ACAATABpAGIAZQByAHQAaQBuAGUAIABiAHkAIABQAGgAaQBsAGkAcABwACAASAAuACAAUABvAGwAbAAsAAoATwBwAGUAbgAgAEYAbwBuAHQAIAB1AG4AZABlAHIAIABUAGUAcgBtAHMAIABvAGYAIABmAG8AbABsAG8AdwBpAG4AZwAgAEYAcgBlAGUAIABTAG8AZgB0AHcAYQByAGUAIABMAGkAYwBlAG4AcwBlAHMAOgAKAEcAUABMACAAKABHAGUAbgBlAHIAYQBsACAAUAB1AGIAbABpAGMAIABMAGkAYwBlAG4AcwBlACkAIAB3AGkAdABoACAAZgBvAG4AdAAtAGUAeABjAGUAcAB0AGkAbwBuACAAYQBuAGQAIABPAEYATAAgACgATwBwAGUAbgAgAEYAbwBuAHQAIABMAGkAYwBlAG4AcwBlACkALgAKAEMAcgBlAGEAdABlAGQAIAB3AGkAdABoACAARgBvAG4AdABGAG8AcgBnAGUAIAAoAGgAdAB0AHAAOgAvAC8AZgBvAG4AdABmAG8AcgBnAGUALgBzAGYALgBuAGUAdAApAAoAUwBlAHAAdAAgADIAMAAwADMALAAgADIAMAAwADQALAAgADIAMAAwADUALAAgADIAMAAwADYALAAgADIAMAAwADcALAAgADIAMAAwADgALAAgADIAMAAwADkALAAgADIAMAAxADAALAAgADIAMAAxADEATABpAG4AdQB4ACAAQgBpAG8AbABpAG4AdQBtACAASwBlAHkAYgBvAGEAcgBkAFIAZQBnAHUAbABhAHIAdwBlAGIAZgBvAG4AdABMAGkAbgB1AHgAIABCAGkAbwBsAGkAbgB1AG0AIABLAGUAeQBiAG8AYQByAGQAIABSAGUAZwB1AGwAYQByAFYAZQByAHMAaQBvAG4AIAAwAC4ANgAuADEAIABMAGkAbgBCAGkAbwBsAGkAbgB1AG0ASwBUAGgAaQBzACAAZgBvAG4AdAAgAHcAYQBzACAAZwBlAG4AZQByAGEAdABlAGQAIABiAHkAIAB0AGgAZQAgAEYAbwBuAHQAIABTAHEAdQBpAHIAcgBlAGwAIABHAGUAbgBlAHIAYQB0AG8AcgAuAAAAAgAAAAAAAP8PAFEAAAAAAAAAAAAAAAAAAAAAAAAAAAC7AAAAAQACAAMABAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA7ADwAPQA+AD8AQABBAEIAQwBEAEUARgBHAEgASQBKAEsATABNAE4ATwBQAFEAUgBTAFQAVQBWAFcAWABZAFoAWwBcAF0AXgBfAGAAYQECAQMBBAEFAQYBBwEIAQkBCgELAQwBDQEOAQ8BEAERALIAswESARMBFAEVARYBFwEYARkBGgEbARwBHQEeAR8BIAEhASIBIwEkASUBJgEnASgBKQEqASsBLAEtAS4BLwEwATEBMgEzATQBNQE2ATcBOAE5AToBOwE8AT0BPgE/AUABQQFCAUMBRAFFAUYBRwFIAUkBSgFLAUwBTQFOAU8BUAFRAVIBUwFUAVUBVgFXAVgHdW5pMDBBMAd1bmkwMEFEB3VuaTIwMDAHdW5pMjAwMQd1bmkyMDAyB3VuaTIwMDMHdW5pMjAwNAd1bmkyMDA1B3VuaTIwMDYHdW5pMjAwNwd1bmkyMDA4B3VuaTIwMDkHdW5pMjAwQQd1bmkyMDEwB3VuaTIwMTEKZmlndXJlZGFzaAd1bmkyMDJGB3VuaTIwNUYHdW5pRTAwMAd1bmlFMTMxB3VuaUUxMzIHdW5pRTEzMwd1bmlFMTM0B3VuaUUxMzUHdW5pRTEzOAd1bmlFMTM5B3VuaUUxM0EHdW5pRTEzQwd1bmlFMTNEB3VuaUUxNjgHdW5pRTE2RQd1bmlFMTcwB3VuaUUxNzEHdW5pRTE3Mgd1bmlFMTczB3VuaUUxNzQHdW5pRTE3NQd1bmlFMTc2B3VuaUUxNzcHdW5pRTE3OAd1bmlFMTc5B3VuaUUxN0EHdW5pRTE3Qgd1bmlFMTdDB3VuaUUxN0QHdW5pRTE3RQd1bmlFMTdGB3VuaUUxODAHdW5pRTE4MQd1bmlFMTgyB3VuaUUxODMHdW5pRTE4NAd1bmlFMTg1B3VuaUUxODYHdW5pRTE4Nwd1bmlFMTg4B3VuaUUxODkHdW5pRTE4QQd1bmlFMThCB3VuaUUxOEMHdW5pRTE4RQd1bmlFMTkwB3VuaUUxOTEHdW5pRTE5Mgd1bmlFMTkzB3VuaUUxOTQHdW5pRTE5NQd1bmlFMTk2B3VuaUUxOTgHdW5pRTE5OQd1bmlFMTlBB3VuaUUxOUIHdW5pRTFBMAd1bmlFMUExB3VuaUUxQTIHdW5pRTFBMwd1bmlFMUE0B3VuaUUxQTUHdW5pRTFBNgd1bmlFMUE3B3VuaUUxQTgHdW5pRTFBOQd1bmlFMUFBB3VuaUUxQUIHdW5pRTFBQwd1bmlFMUFEB3VuaUUxQUUAuAH/hbABjQBLsAhQWLEBAY5ZsUYGK1ghsBBZS7AUUlghsIBZHbAGK1xYALABIEWwAytEsAIgRbIBFAIrsAMrRAGwAyBFsAMrRLAEIEWyAxACK7EDRnYrRLAFIEW6AAN//wACK7EDRnYrRFmwFCsAAA==) format('truetype'), url('linbiolinum_k-webfont.svg#LinuxBiolinumKeyboardRegular') format('svg');
28 font-weight: normal;
29 font-style: normal;
30 }
31
32 @font-face {
33 /* This declaration targets Internet Explorer */
34 font-family: 'LinuxBiolinum';
35 src: url('linbiolinum_r-webfont.eot');
36 }
37
38 @font-face {
39 /* This declaration targets everything else */
40 font-family: 'LinuxBiolinum';
41 src: url(//:) format('no404'), url(data:font/woff;charset=utf-8;base64,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) format('woff'), url(data:font/truetype;charset=utf-8;base64,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) format('truetype'), url('linbiolinum_r-webfont.svg#LinuxBiolinumRegular') format('svg');
42 font-weight: normal;
43 font-style: normal;
44 }
Binary diff not shown
0 % vim:ts=4:sw=4:expandtab
1 % © 2012 Michael Stapelberg
2 %
3 % use xelatex %<
4 %
5 \documentclass[xetex,serif,compress]{beamer}
6 \usepackage{fontspec}
7 \usepackage{xunicode} % Unicode extras!
8 \usepackage{xltxtra} % Fixes
9 \usepackage{listings}
10 \setmainfont{Trebuchet MS}
11 \setmonofont{Inconsolata}
12 \usetheme{default}
13
14 \setbeamertemplate{frametitle}{
15 \color{black}
16 \vspace*{0.5cm}
17 \hspace*{0.25cm}
18 \textbf{\insertframetitle}
19 \par
20 }
21
22 % Hide the navigation icons at the bottom of the page
23 \setbeamertemplate{navigation symbols}{}
24
25 % No margins on any side
26 \setbeamersize{text margin left=0cm,text margin right=0cm}
27
28
29 \begin{document}
30
31 % slide with bullet points
32 \newcommand{\mslide}[2]{
33 \begin{frame}{#1}
34 \begin{center}
35 \begin{list}{$\bullet$}{\itemsep=1em}
36 #2
37 \end{list}
38 \end{center}
39 \end{frame}
40 }
41
42 \frame{
43 \begin{center}
44 \vspace{1.5cm}
45 {\huge i3}\\
46 {\large improved tiling window manager}\\
47 \vspace{3cm}
48 Michael Stapelberg\\
49 \vspace{0.5cm}
50 2012-01-25\\
51 \end{center}
52 }
53
54 \begin{frame}{}
55 \begin{center}
56 \huge
57 "Interesting, what is this?"
58
59 \vspace*{1cm}
60
61 vs.
62
63 \vspace*{1cm}
64
65 "What?! \textbf{Another} window manager?"
66 \end{center}
67 \end{frame}
68
69
70 \begin{frame}{}
71 % talk about the difference between a desktop environment and a window manager:
72 % a desktop environment (like GNOME, KDE, Xfce) is a collection of
73 % programs, libraries (including a graphical toolkit) and configuration.
74 % it usually aims for a coherent look and feel and comes with a number of
75 % tools (g*, like gedit, geeqie, …)
76 % One of the programs of a DE is a window manager.
77 \begin{figure}
78 \includegraphics[width=0.97\textwidth]{Ubuntu_Linux_Jaunty_screenshot.png}
79 % source: http://en.wikipedia.org/wiki/File:Ubuntu_Linux_Jaunty_screenshot.png
80 \end{figure}
81 \end{frame}
82
83
84 \begin{frame}{}
85 \begin{center}
86 % compare this to a screenshot of i3:
87 % notice the little amount of toolbars.
88 % notice the lack of fancy window decorations
89 % notice the absence of a desktop.
90 % instead, you get to use the full screen.
91 \begin{figure}
92 \includegraphics[width=0.97\textwidth]{TdilE.jpg}
93 % source: jrd in #i3
94 \end{figure}
95 \end{center}
96 \end{frame}
97
98
99 \mslide{i3: history and features}{
100 \item started from scratch in february 2009
101 \item successor* to wmii, which we couldn’t hack
102 \item clean, readable, documented code. and documentation
103 \item proper multi-monitor support, utf-8 clean
104 \item fast and lightweight, aimed at power users
105 }
106
107 % live demo here, just like at FrOSCon
108 % include: the docs, with the keyboard layout
109 % include: the configuration file
110
111 \mslide{Inter-process communication}{
112 \item UNIX socket, JSON for serialization
113 \item i3-msg (C), AnyEvent::I3 (Perl), i3-ipc (Ruby), i3ipc (Python)
114 \item send any command, like \texttt{floating enable}
115 \item receive events (like focus change)
116 \item access the layout tree (!)
117 }
118
119 % demo: change a workspace
120 % demo: testsuite
121
122 \mslide{Example workflows}{
123 \item Urgency hint
124 \item Scratchpad
125 \item Web development (browser, editor, syslog)
126 \item Coding (C): two editors (code, test), quickly opening docs
127 }
128
129 \mslide{i3 in numbers}{
130 \item 3149 commits by 39 different people
131 \item > 600 tickets (about 60 open)
132 \item about 10.000 SLOC (mostly C, a bit of Perl)
133 \item testsuite: > 1000 test instructions in 96 files
134 \item conservative guess of > 1000 users
135 }
136
137 \mslide{Thanks for your attention}{
138 \item See \url{http://www.i3wm.org/} for everything
139 \item Ubuntu: upgrade to our repository: \url{http://i3wm.org/docs/repositories.html}
140 \item Debian: upgrade to the version in Debian testing
141 \item Any questions?
142 \item (pictures Creative Commons Attribution-Share Alike 3.0 Unported)
143 }
144
145 \end{document}
0 % vim:ts=4:sw=4:expandtab
1 % © 2012 Michael Stapelberg
2 %
3 % use xelatex %<
4 %
5 \documentclass[xetex,serif,compress]{beamer}
6 \usepackage{fontspec}
7 \usepackage{xunicode} % Unicode extras!
8 \usepackage{xltxtra} % Fixes
9 \usepackage{listings}
10 \setmainfont{Trebuchet MS}
11 \setmonofont{Inconsolata}
12 \usetheme{default}
13
14 \setbeamertemplate{frametitle}{
15 \color{black}
16 \vspace*{0.5cm}
17 \hspace*{0.25cm}
18 \textbf{\insertframetitle}
19 \par
20 }
21
22 % Hide the navigation icons at the bottom of the page
23 \setbeamertemplate{navigation symbols}{}
24
25 % No margins on any side
26 \setbeamersize{text margin left=0cm,text margin right=0cm}
27
28
29 \begin{document}
30
31 % slide with bullet points
32 \newcommand{\mslide}[2]{
33 \begin{frame}{#1}
34 \begin{center}
35 \begin{list}{$\bullet$}{\itemsep=1em}
36 #2
37 \end{list}
38 \end{center}
39 \end{frame}
40 }
41
42 \frame{
43 \begin{center}
44 \vspace{1.5cm}
45 {\huge i3}\\
46 {\large improved tiling window manager}\\
47 \vspace{3cm}
48 Michael Stapelberg\\
49 \vspace{0.5cm}
50 2012-03-16\\
51 \end{center}
52 }
53
54 \begin{frame}{}
55 \begin{center}
56 \huge
57 „Oh, interessant…“
58
59 \vspace*{1cm}
60
61 oder
62
63 \vspace*{1cm}
64
65 „Was?! \textbf{Noch ein} window manager?“
66 \end{center}
67 \end{frame}
68
69
70 \begin{frame}{}
71 % talk about the difference between a desktop environment and a window manager:
72 % a desktop environment (like GNOME, KDE, Xfce) is a collection of
73 % programs, libraries (including a graphical toolkit) and configuration.
74 % it usually aims for a coherent look and feel and comes with a number of
75 % tools (g*, like gedit, geeqie, …)
76 % One of the programs of a DE is a window manager.
77 \begin{figure}
78 \includegraphics[width=0.97\textwidth]{Ubuntu_Linux_Jaunty_screenshot.png}
79 % source: http://en.wikipedia.org/wiki/File:Ubuntu_Linux_Jaunty_screenshot.png
80 \end{figure}
81 \end{frame}
82
83
84 \begin{frame}{}
85 \begin{center}
86 % compare this to a screenshot of i3:
87 % notice the little amount of toolbars.
88 % notice the lack of fancy window decorations
89 % notice the absence of a desktop.
90 % instead, you get to use the full screen.
91 \begin{figure}
92 \includegraphics[width=0.97\textwidth]{TdilE.jpg}
93 % source: jrd in #i3
94 \end{figure}
95 \end{center}
96 \end{frame}
97
98
99 \mslide{i3: Geschichte und Merkmale}{
100 \item komplett neu geschrieben (Februar 2009)
101 \item Nachfolger* zu wmii, den wir nicht hacken konnten
102 \item sauberen, lesbaren, dokumentierten Code. und Dokumentation
103 \item ordentlichen Multi-Monitor-Unterstützung, UTF-8-Unterstützung
104 \item schnell und klein, ausgerichtet auf Power-Nutzer
105 }
106
107 % live demo here, just like at FrOSCon
108 % include: the docs, with the keyboard layout
109 % include: the configuration file
110
111 \mslide{Inter-Prozess-Kommunication}{
112 \item UNIX-Socket, JSON zur Serialisierung
113 \item i3-msg (C), AnyEvent::I3 (Perl), i3-ipc (Ruby), i3ipc (Python)
114 \item beliebige Befehle schicken, wie \texttt{floating enable}
115 \item Ereignisse empfangen (z.B. Fokusänderung)
116 \item Zugriff auf die Layout-Datenstruktur (!)
117 }
118
119 % demo: change a workspace
120 % demo: testsuite
121
122 \mslide{Workflow-Beispiele}{
123 \item Urgency hint
124 \item Scratchpad
125 \item Web-Entwicklung (browser, editor, syslog)
126 \item Programmieren (C): zwei Editoren (Code, Tests), schnell Doku aufmachen
127 }
128
129 \mslide{i3 in Zahlen}{
130 \item 3149 Commits von > 40 verschiedenen Leuten
131 \item > 600 Tickets (ca. 60 offen)
132 \item ungefähr 10.000 SLOC (größtenteils C, ein bisschen Perl)
133 \item Testsuite: > 1000 Tests in 96 Dateien
134 \item vorsichtige Schätzungen von > 1000 Nutzern
135 }
136
137 \mslide{Danke für eure Aufmerksamkeit!}{
138 \item Auf \url{http://www.i3wm.org/} findet ihr alles
139 \item Ubuntu: bitte nutze unser Repository: \url{http://i3wm.org/docs/repositories.html}
140 \item Debian: bitte nutze die Version in testing
141 \item Fragen?
142 \item (Bilder: Creative Commons Attribution-Share Alike 3.0 Unported)
143 }
144
145 \end{document}
Binary diff not shown
0 i3 testsuite
1 ============
2 Michael Stapelberg <[email protected]>
3 September 2012
4
5 This document explains how the i3 testsuite works, how to use it and extend it.
6 It is targeted at developers who not necessarily have been doing testing before
7 or have not been testing in Perl before. In general, the testsuite is not of
8 interest for end users.
9
10
11 == Introduction
12
13 The i3 testsuite is a collection of files which contain testcases for various
14 i3 features. Some of them test if a certain workflow works correctly (moving
15 windows, focus behaviour, …). Others are regression tests and contain code
16 which previously made i3 crash or lead to unexpected behaviour. They then check
17 if i3 still runs (meaning it did not crash) and if it handled everything
18 correctly.
19
20 The goal of having these tests is to automatically find problems and to
21 automatically get a feel for whether a change in the source code breaks any
22 existing feature. After every modification of the i3 sourcecode, the developer
23 should run the full testsuite. If one of the tests fails, the corresponding
24 problem should be fixed (or, in some cases, the testcase has to be modified).
25 For every bugreport, a testcase should be written to test the correct
26 behaviour. Initially, it will fail, but after fixing the bug, it will pass.
27 This ensures (or increases the chance) that bugs which have been fixed once
28 will never be found again.
29
30 Also, when implementing a new feature, a testcase might be a good way to be
31 able to easily test if the feature is working correctly. Many developers will
32 test manually if everything works. Having a testcase not only helps you with
33 that, but it will also be useful for every future change.
34
35 == Relevant documentation
36
37 Apart from this document, you should also have a look at:
38
39 1. The "Modern Perl" book, which can be found at
40 http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
41 2. The latest Perl documentation of the "i3test" (general testcase setup) and
42 "i3test::Test" (additional test instructions) modules:
43 https://build.i3wm.org/docs/lib-i3test.html respectively
44 https://build.i3wm.org/docs/lib-i3test-test.html
45 3. The latest documentation on i3’s IPC interface:
46 https://build.i3wm.org/docs/ipc.html
47
48 == Implementation
49
50 For several reasons, the i3 testsuite has been implemented in Perl:
51
52 1. Perl has a long tradition of testing. Every popular/bigger Perl module which
53 you can find on CPAN will not only come with documentation, but also with
54 tests. Therefore, the available infrastructure for tests is comprehensive.
55 See for example the excellent http://search.cpan.org/perldoc?Test::More
56 and the referenced http://search.cpan.org/perldoc?Test::Tutorial.
57
58 2. Perl is widely available and has a well-working package infrastructure.
59 3. The author is familiar with Perl :).
60 4. It is a good idea to use a different language for the tests than the
61 implementation itself.
62
63 Please do not start programming language flamewars at this point.
64
65 === Installing the dependencies
66
67 As usual with Perl programs, the testsuite ships with a +Makefile.PL+.
68 This file specifies which Perl modules the testsuite depends on and can be used
69 to install all of them.
70
71 Perl modules are distributed via CPAN, and there is the official, standard CPAN
72 client, simply called +cpan+. It comes with every Perl installation and can be
73 used to install the testsuite. Many users prefer to use the more modern
74 +cpanminus+ instead, though (because it asks no questions and just works):
75
76 The tests additionally require +Xephyr(1)+ to run a nested X server. Install
77 +xserver-xephyr+ on Debian or +xorg-server-xephyr+ on Arch Linux.
78
79 .Installing testsuite dependencies using cpanminus (preferred)
80 --------------------------------------------------------------------------------
81 $ cd ~/i3/testcases
82 $ sudo apt-get install cpanminus
83 $ sudo cpanm .
84 $ cd ~/i3/AnyEvent-I3
85 $ sudo cpanm Module::Install
86 $ sudo cpanm .
87 --------------------------------------------------------------------------------
88
89 If you don’t want to use cpanminus for some reason, the same works with cpan:
90
91 .Installing testsuite dependencies using cpan
92 --------------------------------------------------------------------------------
93 $ cd ~/i3/testcases
94 $ sudo cpan .
95 $ cd ~/i3/AnyEvent-I3
96 $ sudo cpan Module::Install
97 $ sudo cpan .
98 --------------------------------------------------------------------------------
99
100 In case you don’t have root permissions, you can also install into your home
101 directory, see https://michael.stapelberg.de/cpan/
102
103 === Mechanisms
104
105 ==== Script: complete-run
106
107 The testcases are run by a script called +complete-run.pl+. It runs all
108 testcases by default, but you can be more specific and let it only run one or
109 more testcases. Also, it takes care of starting up a separate instance of i3
110 with an appropriate configuration file and creates a folder for each run
111 containing the appropriate i3 logfile for each testcase. The latest folder can
112 always be found under the symlink +latest/+. Unless told differently, it will
113 run the tests on a separate X server instance (using Xephyr).
114
115 Xephyr will open a window where you can inspect the running test. By default,
116 tests are run under Xvfb.
117
118 .Example invocation of +complete-run.pl+
119 ---------------------------------------
120 $ cd ~/i3
121
122 $ autoreconf -fi
123
124 $ mkdir -p build && cd build
125
126 $ ../configure
127
128 $ make -j8
129 # output omitted because it is very long
130
131 $ cd testcases
132
133 $ ./complete-run.pl
134 # output omitted because it is very long
135 All tests successful.
136 Files=78, Tests=734, 27 wallclock secs ( 0.38 usr 0.48 sys + 17.65 cusr 3.21 csys = 21.72 CPU)
137 Result: PASS
138
139 $ ./complete-run.pl t/04-floating.t
140 [:3] i3 startup: took 0.07s, status = 1
141 [:3] Running t/04-floating.t with logfile testsuite-2011-09-24-16-06-04-4.0.2-226-g1eb011a/i3-log-for-04-floating.t
142 [:3] t/04-floating.t finished
143 [:3] killing i3
144 output for t/04-floating.t:
145 ok 1 - use X11::XCB::Window;
146 ok 2 - The object isa X11::XCB::Window
147 ok 3 - Window is mapped
148 ok 4 - i3 raised the width to 75
149 ok 5 - i3 raised the height to 50
150 ok 6 - i3 did not map it to (0x0)
151 ok 7 - The object isa X11::XCB::Window
152 ok 8 - i3 let the width at 80
153 ok 9 - i3 let the height at 90
154 ok 10 - i3 mapped it to x=1
155 ok 11 - i3 mapped it to y=18
156 ok 12 - The object isa X11::XCB::Window
157 ok 13 - i3 let the width at 80
158 ok 14 - i3 let the height at 90
159 1..14
160
161 All tests successful.
162 Files=1, Tests=14, 0 wallclock secs ( 0.01 usr 0.00 sys + 0.19 cusr 0.03 csys = 0.23 CPU)
163 Result: PASS
164
165 $ less latest/i3-log-for-04-floating.t
166 ----------------------------------------
167
168 If your attempt to run the tests with a bare call to ./complete-run.pl fails, try this:
169
170 ---------------------------------------------------
171 $ ./complete-run.pl --parallel=1 --keep-xserver-output
172 ---------------------------------------------------
173
174 This will show the output of Xephyr, which is the X server implementation we
175 use for testing.
176
177 ===== make command: +make check+
178 Make check runs the i3 testsuite.
179 You can still use ./testcases/complete-run.pl to get the interactive progress output.
180
181 .Example invocation of +make check+
182 ---------------------------------------
183 $ cd ~/i3
184
185 $ autoreconf -fi
186
187 $ mkdir -p build && cd build
188
189 $ ../configure
190
191 $ make -j8
192 # output omitted because it is very long
193
194 $ make check
195 # output omitted because it is very long
196 PASS: testcases/complete-run.pl
197 ============================================================================
198 Testsuite summary for i3 4.13
199 ============================================================================
200 # TOTAL: 1
201 # PASS: 1
202 # SKIP: 0
203 # XFAIL: 0
204 # FAIL: 0
205 # XPASS: 0
206 # ERROR: 0
207 ============================================================================
208
209 $ less test-suite.log
210 ----------------------------------------
211
212 ==== Coverage testing
213
214 Coverage testing is possible with +lcov+, the front-end for GCC's coverage
215 testing tool +gcov+. The testcases can generate a nice html report that tells
216 you which functions and lines were covered during a run of the tests. You can
217 use this tool to judge how effective your tests are.
218
219 To use test coverage tools, first compile with coverage enabled.
220
221 ---------------------------------------------------
222 COVERAGE=1 make
223 ---------------------------------------------------
224
225 Then run the tests with the +--coverage-testing+ flag.
226
227 ---------------------------------------------------
228 ./complete-run.pl --coverage-testing
229 ---------------------------------------------------
230
231 Then open +latest/i3-coverage/index.html+ in your web browser.
232
233 ==== IPC interface
234
235 The testsuite makes extensive use of the IPC (Inter-Process Communication)
236 interface which i3 provides. It is used for the startup process of i3, for
237 terminating it cleanly and (most importantly) for modifying and getting the
238 current state (layout tree).
239
240 See [https://i3wm.org/docs/ipc.html] for documentation on the IPC interface.
241
242 ==== X11::XCB
243
244 In order to open new windows, change attributes, get events, etc., the
245 testsuite uses X11::XCB, a new (and quite specific to i3 at the moment) Perl
246 module which uses the XCB protocol description to generate Perl bindings to
247 X11. They work in a very similar way to libxcb (which i3 uses) and provide
248 relatively high-level interfaces (objects such as +X11::XCB::Window+) as well as
249 access to the low-level interface, which is very useful when testing a window
250 manager.
251
252 === Filesystem structure
253
254 In the git root of i3, the testcases live in the folder +testcases+. This
255 folder contains the +complete-run.pl+ and a base configuration file which will
256 be used for the tests. The different testcases (their file extension is .t, not
257 .pl) themselves can be found in the conventionally named subfolder +t+:
258
259 .Filesystem structure
260 --------------------------------------------
261 ├── testcases
262 │   ├── complete-run.pl
263 │   ├── i3-test.config
264 │   ├── lib
265 │   │   ├── i3test.pm
266 │   │   ├── SocketActivation.pm
267 │   │   └── StartXDummy.pm
268 │   ├── t
269 │   │   ├── 00-load.t
270 │   │   ├── 01-tile.t
271 │   │   ├── 02-fullscreen.t
272 │   │   ├── ...
273 │   │   ├── omitted for brevity
274 │   │   ├── ...
275 │   │   └── 74-regress-focus-toggle.t
276 --------------------------------------------
277
278 == Anatomy of a testcase
279
280 Learning by example is definitely a good strategy when you are wondering how to
281 write a testcase. Let's take +t/11-goto.t+ as an easy example and go through it
282 step by step:
283
284 .t/11-goto.t: Boilerplate
285 ----------------------
286 #!perl
287 # vim:ts=4:sw=4:expandtab
288
289 use i3test;
290 use File::Temp;
291
292 my $x = X11::XCB::Connection->new;
293 -----------------------
294
295 This is what we call boilerplate. It exists at the top of every test file (to
296 some extent). The first line is the shebang, which specifies that this file is
297 a Perl script. The second line contains VIM specific settings on how to
298 edit/format this file (use spaces instead of tabs, indent using 4 spaces).
299 Afterwards, the +i3test+ module is used. This module contains i3 testsuite
300 specific functions which you are strongly encouraged to use. They make writing
301 testcases a lot easier and will make it easier for other people to read your
302 tests.
303
304 The next line uses the +File::Temp+ module. This is specific to this testcase,
305 because it needs to generate a temporary name during the test. Many testcases
306 use only the +i3test+ module.
307
308 The last line opens a connection to X11. You might or might not need this in
309 your testcase, depending on whether you are going to open windows (etc.) or
310 only use i3 commands.
311
312 .t/11-goto.t: Setup
313 ----------------------
314 my $tmp = fresh_workspace;
315
316 cmd 'split h';
317 ----------------------
318
319 The first line calls i3test's +fresh_workspace+ function which looks for a
320 currently unused workspace, switches to it, and returns its name. The variable
321 +$tmp+ will end up having a value such as +"/tmp/87kBVcHbA9"+. Note that this
322 is not (necessarily) a valid path, it's just a random workspace name.
323
324 So, now that we are on a new workspace, we ensure that the workspace uses
325 horizontal orientation by issuing the +split h+ command (see the i3 User's
326 Guide for a list of commands). This is not strictly necessary, but good style.
327 In general, the +cmd+ function executes the specified i3 command by using the
328 IPC interface and returns once i3 acknowledged the command.
329
330 .t/11-goto.t: Setup
331 ----------------------
332 #####################################################################
333 # Create two windows and make sure focus switching works
334 #####################################################################
335
336 my $top = open_window($x);
337 my $mid = open_window($x);
338 my $bottom = open_window($x);
339 ----------------------
340
341 In every major section of a testcase, you should put a comment like the one
342 above. This makes it immediately clear how the file is structured.
343
344 The +open_window+ function opens a standard window, which will then be put into
345 tiling mode by i3. If you want a floating window, use the
346 +open_floating_window+ function. These functions accept the same parameters as
347 +X11::XCB::Window->new+, see the i3test documentation at TODO.
348
349 .t/11-goto.t: Helper function
350 ----------------------
351 #
352 # Returns the input focus after sending the given command to i3 via IPC
353 # and syncing with i3
354 #
355 sub focus_after {
356 my $msg = shift;
357
358 cmd $msg;
359 sync_with_i3 $x;
360 return $x->input_focus;
361 }
362 ----------------------
363
364 This section defines a helper function which will be used over and over in this
365 testcase. If you have code which gets executed more than once or twice
366 (depending on the length of your test, use your best judgement), please put it
367 in a function. Tests should be short, concise and clear.
368
369 The +focus_after+ function executes a command and returns the X11 focus after
370 the command was executed. The +sync_with_i3+ command makes sure that i3 could
371 push its state to X11. See <<i3_sync>> to learn how this works exactly.
372
373 .t/11-goto.t: Test assumptions
374 ----------------------
375 $focus = $x->input_focus;
376 is($focus, $bottom->id, "Latest window focused");
377
378 $focus = focus_after('focus left');
379 is($focus, $mid->id, "Middle window focused");
380 ----------------------
381
382 Now, we run the first two real tests. They use +Test::More+'s +is+ function,
383 which compares two values and prints the differences if they are not the same.
384 After the arguments, we supply a short comment to indicate what we are testing
385 here. This makes it vastly more easy for the developer to spot which testcase
386 is the problem in case one fails.
387
388 The first test checks that the most recently opened window is focused.
389 Afterwards, the command +focus left+ is issued and it is verified that the
390 middle window now has focus.
391
392 Note that this is not a comprehensive test of the +focus+ command -- we would
393 have to test wrapping, focus when using a more complex layout, focusing the
394 parent/child containers, etc. But that is not the point of this testcase.
395 Instead, we just want to know if +$x->input_focus+ corresponds with what we are
396 expecting. If not, something is completely wrong with the test environment and
397 this trivial test will fail.
398
399 .t/11-goto.t: Test that the feature does not work (yet)
400 ----------------------
401 #####################################################################
402 # Now goto a mark which does not exist
403 #####################################################################
404
405 my $random_mark = mktemp('mark.XXXXXX');
406
407 $focus = focus_after(qq|[con_mark="$random_mark"] focus|);
408 is($focus, $mid->id, "focus unchanged");
409 ----------------------
410
411 Syntax hint: The qq keyword is the interpolating quote operator. It lets you
412 chose a quote character (in this case the +|+ character, a pipe). This makes
413 having double quotes in our string easy.
414
415 In this new major section, a random mark (mark is an identifier for a window,
416 see "VIM-like marks" in the i3 User’s Guide) will be generated. Afterwards, we
417 test that trying to focus that mark will not do anything. This is important: Do
418 not only test that using a feature has the expected outcome, but also test that
419 using it without properly initializing it does no harm. This command could for
420 example have changed focus anyways (a bug) or crash i3 (obviously a bug).
421
422 .t/11-goto.t: Test that the feature does work
423 ----------------------
424 cmd "mark $random_mark";
425
426 $focus = focus_after('focus left');
427 is($focus, $top->id, "Top window focused");
428
429 $focus = focus_after(qq|[con_mark="$random_mark"] focus|);
430 is($focus, $mid->id, "goto worked");
431 ----------------------
432
433 Remember: Focus was on the middle window (we verified that earlier in "Test
434 assumptions"). We now mark the middle window with our randomly generated mark.
435 Afterwards, we switch focus away from the middle window to be able to tell if
436 focusing it via its mark will work. If the test works, the goto command seems
437 to be working.
438
439 .t/11-goto.t: Test corner case
440 ----------------------
441 # check that we can specify multiple criteria
442
443 $focus = focus_after('focus left');
444 is($focus, $top->id, "Top window focused");
445
446 $focus = focus_after(qq|[con_mark="$random_mark" con_mark="$random_mark"] focus|);
447 is($focus, $mid->id, "goto worked");
448 ----------------------
449
450 Now we test the same feature, but specifying the mark twice in the command.
451 This should have no effect, but let’s be sure: test it and see if things go
452 wrong.
453
454 .t/11-goto.t: Test second code path
455 ----------------------
456 #####################################################################
457 # Check whether the focus command will switch to a different
458 # workspace if necessary
459 #####################################################################
460
461 my $tmp2 = fresh_workspace;
462
463 is(focused_ws(), $tmp2, 'tmp2 now focused');
464
465 cmd qq|[con_mark="$random_mark"] focus|;
466
467 is(focused_ws(), $tmp, 'tmp now focused');
468 ----------------------
469
470 This part of the test checks that focusing windows by mark works across
471 workspaces. It uses i3test's +focused_ws+ function to get the current
472 workspace.
473
474 .t/11-goto.t: Test second code path
475 ----------------------
476 done_testing;
477 ----------------------
478
479 The end of every testcase has to contain the +done_testing+ line. This tells
480 +complete-run.pl+ that the test was finished successfully. If it does not
481 occur, the test might have crashed during execution -- some of the reasons why
482 that could happen are bugs in the used modules, bugs in the testcase itself or
483 an i3 crash resulting in the testcase being unable to communicate with i3 via
484 IPC anymore.
485
486 [[i3_sync]]
487 == Appendix A: The i3 sync protocol
488
489 Consider the following situation: You open two windows in your testcase, then
490 you use +focus left+ and want to verify that the X11 focus has been updated
491 properly. Sounds simple, right? Let’s assume you use this straight-forward
492 implementation:
493
494 .Racey focus testcase
495 -----------
496 my $left = open_window($x);
497 my $right = open_window($x);
498 cmd 'focus left';
499 is($x->input_focus, $left->id, 'left window focused');
500 ----------
501
502 However, the test fails. Sometimes. Apparently, there is a race condition in
503 your test. If you think about it, this is because you are using two different
504 pieces of software: You tell i3 to update focus, i3 confirms that, and then you
505 ask X11 to give you the current focus. There is a certain time i3 needs to
506 update the X11 state. If the testcase gets CPU time before X11 processed i3's
507 requests, the test will fail.
508
509 image::i3-sync.png["Diagram of the race condition", title="Diagram of the race condition"]
510
511 One way to "solve" this would be to add +sleep 0.5;+ after the +cmd+ call.
512 After 0.5 seconds it should be safe to assume that focus has been updated,
513 right?
514
515 In practice, this usually works. However, it has several problems:
516
517 1. This is obviously not a clean solution, but a workaround. Ugly.
518 2. On very slow machines, this might not work. Unlikely, but in different
519 situations (a delay to wait for i3 to startup) the necessary time is much
520 harder to guess, even for fast machines.
521 3. This *wastes a lot of time*. Usually, your computer is much faster than 0.5s
522 to update the status. However, sometimes, it might take 0.4s, so we can’t
523 make it +sleep 0.1+.
524
525 To illustrate how grave the problem with wasting time actually is: Before
526 removing all sleeps from the testsuite, a typical run using 4 separate X
527 servers took around 50 seconds on my machine. After removing all the sleeps,
528 we achieved times of about 25 seconds. This is very significant and influences
529 the way you think about tests -- the faster they are, the more likely you are
530 to check whether everything still works quite often (which you should).
531
532 What I am trying to say is: Delays adds up quickly and make the test suite
533 less robust.
534
535 The real solution for this problem is a mechanism which I call "the i3 sync
536 protocol". The idea is to send a request (which does not modify state) via X11
537 to i3 which will then be answered. Due to the request's position in the event
538 queue (*after* all previous events), you can be sure that by the time you
539 receive the reply, all other events have been dealt with by i3 (and, more
540 importantly, X11).
541
542 image::i3-sync-working.png["Diagram of the i3 sync solution", title="Diagram of the i3 sync solution"]
543
544 === Implementation details
545
546 The client which wants to sync with i3 initiates the protocol by sending a
547 ClientMessage to the X11 root window:
548
549 .Send ClientMessage
550 -------------------
551 # Generate a ClientMessage, see xcb_client_message_t
552 my $msg = pack "CCSLLLLLLL",
553 CLIENT_MESSAGE, # response_type
554 32, # format
555 0, # sequence
556 $root, # destination window
557 $x->atom(name => 'I3_SYNC')->id,
558
559 $_sync_window->id, # data[0]: our own window id
560 $myrnd, # data[1]: a random value to identify the request
561 0,
562 0,
563 0;
564
565 # Send it to the root window -- since i3 uses the SubstructureRedirect
566 # event mask, it will get the ClientMessage.
567 $x->send_event(0, $root, EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
568 -------------------
569
570 i3 will then reply with the same ClientMessage, sent to the window specified in
571 +data[0]+. In the reply, +data[0]+ and +data[1]+ are exactly the same as in the
572 request. You should use a random value in +data[1]+ and check that you received
573 the same one when getting the reply.
574
575 == Appendix B: Socket activation
576
577 Socket activation is a mechanism which was made popular by systemd, an init
578 replacement. It basically describes creating a listening socket before starting
579 a program. systemd will invoke the program only when an actual connection to
580 the socket is made, hence the term socket activation.
581
582 The interesting part of this (in the i3 context) is that you can very precisely
583 detect when the program is ready (finished its initialization).
584
585 === Preparing the listening socket
586
587 +complete-run.pl+ will create a listening UNIX socket which it will then pass
588 to i3. This socket will be used by i3 as an additional IPC socket, just like
589 the one it will create on its own. Passing the socket happens implicitly
590 because children will inherit the parent’s sockets when fork()ing and sockets
591 will continue to exist after an exec() call (unless CLOEXEC is set of course).
592
593 The only explicit things +complete-run.pl+ has to do is setting the +LISTEN_FDS+
594 environment variable to the number of sockets which exist (1 in our case) and
595 setting the +LISTEN_PID+ environment variable to the current process ID. Both
596 variables are necessary so that the program (i3) knows how many sockets it
597 should use and if the environment variable is actually intended for it. i3 will
598 then start looking for sockets at file descriptor 3 (since 0, 1 and 2 are used
599 for stdin, stdout and stderr, respectively).
600
601 The actual Perl code which sets up the socket, fork()s, makes sure the socket
602 has file descriptor 3 and sets up the environment variables follows (shortened
603 a bit):
604
605
606 .Setup socket and environment
607 -----------------------------
608 my $socket = IO::Socket::UNIX->new(
609 Listen => 1,
610 Local => $args{unix_socket_path},
611 );
612
613 my $pid = fork;
614 if ($pid == 0) {
615 $ENV{LISTEN_PID} = $$;
616 $ENV{LISTEN_FDS} = 1;
617
618 # Only pass file descriptors 0 (stdin), 1 (stdout),
619 # 2 (stderr) and 3 (socket) to the child.
620 $^F = 3;
621
622 # If the socket does not use file descriptor 3 by chance
623 # already, we close fd 3 and dup2() the socket to 3.
624 if (fileno($socket) != 3) {
625 POSIX::close(3);
626 POSIX::dup2(fileno($socket), 3);
627 }
628
629 exec "/usr/bin/i3";
630 }
631 -----------------------------
632
633 === Waiting for a reply
634
635 In the parent process, we want to know when i3 is ready to answer our IPC
636 requests and handle our windows. Therefore, after forking, we immediately close
637 the listening socket (i3 will handle this side of the socket) and connect to it
638 (remember, we are talking about a named UNIX socket) as a client. This connect
639 call will immediately succeed because the kernel buffers it. Then, we send a
640 request (of type GET_TREE, but that is not really relevant). Writing data to
641 the socket will also succeed immediately because, again, the kernel buffers it
642 (only up to a certain amount of data of course).
643
644 Afterwards, we just blockingly wait until we get an answer. In the child
645 process, i3 will setup the listening socket in its event loop. Immediately
646 after actually starting the event loop, it will notice a new client connecting
647 (the parent process) and handle its request. Since all initialization has been
648 completed successfully by the time the event loop is entered, we can now assume
649 that i3 is ready.
650
651 === Timing and conclusion
652
653 A beautiful feature of this mechanism is that it does not depend on timing. It
654 does not matter when the child process gets CPU time or when the parent process
655 gets CPU time. On heavily loaded machines (or machines with multiple CPUs,
656 cores or unreliable schedulers), this makes waiting for i3 much more robust.
657
658 Before using socket activation, we typically used a +sleep(1)+ and hoped that
659 i3 was initialized by that time. Of course, this breaks on some (slow)
660 computers and wastes a lot of time on faster computers. By using socket
661 activation, we decreased the total amount of time necessary to run all tests
662 (72 files at the time of writing) from > 100 seconds to 16 seconds. This makes
663 it significantly more attractive to run the test suite more often (or at all)
664 during development.
665
666 An alternative approach to using socket activation is polling for the existence
667 of the IPC socket and connecting to it. While this might be slightly easier to
668 implement, it wastes CPU time and is considerably uglier than this solution
669 :). After all, +lib/SocketActivation.pm+ contains only 54 SLOC.
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
0 i3 User’s Guide
1 ===============
2 Michael Stapelberg <[email protected]>
3
4 This document contains all the information you need to configure and use the i3
5 window manager. If it does not, please check https://www.reddit.com/r/i3wm/
6 first, then contact us on IRC (preferred) or post your question(s) on the
7 mailing list.
8
9 == Default keybindings
10
11 For the "too long; didn’t read" people, here is an overview of the default
12 keybindings (click to see the full-size image):
13
14 *Keys to use with $mod (Alt):*
15
16 image:keyboard-layer1.png["Keys to use with $mod (Alt)",width=600,link="keyboard-layer1.png"]
17
18 *Keys to use with Shift+$mod:*
19
20 image:keyboard-layer2.png["Keys to use with Shift+$mod",width=600,link="keyboard-layer2.png"]
21
22 The red keys are the modifiers you need to press (by default), the blue keys
23 are your homerow.
24
25 Note that when starting i3 without a config file, i3-config-wizard will offer
26 you to create a config file in which the key positions (!) match what you see
27 in the image above, regardless of the keyboard layout you are using. If you
28 prefer to use a config file where the key letters match what you are seeing
29 above, just decline i3-config-wizard’s offer and base your config on
30 +/etc/i3/config+.
31
32 == Using i3
33
34 Throughout this guide, the keyword +$mod+ will be used to refer to the
35 configured modifier. This is the Alt key (+Mod1+) by default, with the Windows
36 key (+Mod4+) being a popular alternative that largely prevents conflicts with
37 application-defined shortcuts.
38
39 === Opening terminals and moving around
40
41 One very basic operation is opening a new terminal. By default, the keybinding
42 for this is +$mod+Enter+, that is Alt+Enter (+Mod1+Enter+) in the default
43 configuration. By pressing +$mod+Enter+, a new terminal will be opened. It
44 will fill the whole space available on your screen.
45
46 image:single_terminal.png[Single terminal]
47
48 If you now open another terminal, i3 will place it next to the current one,
49 splitting the screen size in half. Depending on your monitor, i3 will put the
50 created window beside the existing window (on wide displays) or below the
51 existing window (rotated displays).
52
53 image:two_terminals.png[Two terminals]
54
55 To move the focus between the two terminals, you can use the direction keys
56 which you may know from the editor +vi+. However, in i3, your homerow is used
57 for these keys (in +vi+, the keys are shifted to the left by one for
58 compatibility with most keyboard layouts). Therefore, +$mod+j+ is left, +$mod+k+
59 is down, +$mod+l+ is up and `$mod+;` is right. So, to switch between the
60 terminals, use +$mod+k+ or +$mod+l+. Of course, you can also use the arrow keys.
61
62 At the moment, your workspace is split (it contains two terminals) in a
63 specific direction (horizontal by default). Every window can be split
64 horizontally or vertically again, just like the workspace. The terminology is
65 "window" for a container that actually contains an X11 window (like a terminal
66 or browser) and "split container" for containers that consist of one or more
67 windows.
68
69 TODO: picture of the tree
70
71 To split a window vertically, press +$mod+v+ before you create the new window.
72 To split it horizontally, press +$mod+h+.
73
74 === Changing the container layout
75
76 A split container can have one of the following layouts:
77
78 splith/splitv::
79 Windows are sized so that every window gets an equal amount of space in the
80 container. splith distributes the windows horizontally (windows are right next
81 to each other), splitv distributes them vertically (windows are on top of each
82 other).
83 stacking::
84 Only the focused window in the container is displayed. You get a list of
85 windows at the top of the container.
86 tabbed::
87 The same principle as +stacking+, but the list of windows at the top is only
88 a single line which is vertically split.
89
90 To switch modes, press +$mod+e+ for splith/splitv (it toggles), +$mod+s+ for
91 stacking and +$mod+w+ for tabbed.
92
93 image:modes.png[Container modes]
94
95 === Toggling fullscreen mode for a window
96
97 To display a window in fullscreen mode or to go out of fullscreen mode again,
98 press +$mod+f+.
99
100 There is also a global fullscreen mode in i3 in which the client will span all
101 available outputs (the command is +fullscreen toggle global+).
102
103 === Opening other applications
104
105 Aside from opening applications from a terminal, you can also use the handy
106 +dmenu+ which is opened by pressing +$mod+d+ by default. Just type the name
107 (or a part of it) of the application which you want to open. The corresponding
108 application has to be in your +$PATH+ for this to work.
109
110 Additionally, if you have applications you open very frequently, you can
111 create a keybinding for starting the application directly. See the section
112 <<configuring>> for details.
113
114 === Closing windows
115
116 If an application does not provide a mechanism for closing (most applications
117 provide a menu, the escape key or a shortcut like +Control+w+ to close), you
118 can press +$mod+Shift+q+ to kill a window. For applications which support
119 the WM_DELETE protocol, this will correctly close the application (saving
120 any modifications or doing other cleanup). If the application doesn’t support
121 the WM_DELETE protocol your X server will kill the window and the behaviour
122 depends on the application.
123
124 === Using workspaces
125
126 Workspaces are an easy way to group a set of windows. By default, you are on
127 the first workspace, as the bar on the bottom left indicates. To switch to
128 another workspace, press +$mod+num+ where +num+ is the number of the workspace
129 you want to use. If the workspace does not exist yet, it will be created.
130
131 A common paradigm is to put the web browser on one workspace, communication
132 applications (+mutt+, +irssi+, ...) on another one, and the ones with which you
133 work, on the third one. Of course, there is no need to follow this approach.
134
135 If you have multiple screens, a workspace will be created on each screen at
136 startup. If you open a new workspace, it will be bound to the screen you
137 created it on. When you switch to a workspace on another screen, i3 will set
138 focus to that screen.
139
140 === Moving windows to workspaces
141
142 To move a window to another workspace, simply press +$mod+Shift+num+ where
143 +num+ is (like when switching workspaces) the number of the target workspace.
144 Similarly to switching workspaces, the target workspace will be created if
145 it does not yet exist.
146
147 === Resizing
148
149 The easiest way to resize a container is by using the mouse: Grab the border
150 and move it to the wanted size.
151
152 You can also use <<binding_modes>> to define a mode for resizing via the
153 keyboard. To see an example for this, look at the
154 https://github.com/i3/i3/blob/next/etc/config.keycodes[default config] provided
155 by i3.
156
157 === Restarting i3 inplace
158
159 To restart i3 in place (and thus get into a clean state if there is a bug, or
160 to upgrade to a newer version of i3) you can use +$mod+Shift+r+.
161
162 === Exiting i3
163
164 To cleanly exit i3 without killing your X server, you can use +$mod+Shift+e+.
165 By default, a dialog will ask you to confirm if you really want to quit.
166
167 === Floating
168
169 Floating mode is the opposite of tiling mode. The position and size of
170 a window are not managed automatically by i3, but manually by
171 you. Using this mode violates the tiling paradigm but can be useful
172 for some corner cases like "Save as" dialog windows, or toolbar
173 windows (GIMP or similar). Those windows usually set the appropriate
174 hint and are opened in floating mode by default.
175
176 You can toggle floating mode for a window by pressing +$mod+Shift+Space+. By
177 dragging the window’s titlebar with your mouse you can move the window
178 around. By grabbing the borders and moving them you can resize the window. You
179 can also do that by using the <<floating_modifier>>. Another way to resize
180 floating windows using the mouse is to right-click on the titlebar and drag.
181
182 For resizing floating windows with your keyboard, see the resizing binding mode
183 provided by the i3 https://github.com/i3/i3/blob/next/etc/config.keycodes[default config].
184
185 Floating windows are always on top of tiling windows.
186
187 == Tree
188
189 i3 stores all information about the X11 outputs, workspaces and layout of the
190 windows on them in a tree. The root node is the X11 root window, followed by
191 the X11 outputs, then dock areas and a content container, then workspaces and
192 finally the windows themselves. In previous versions of i3 we had multiple lists
193 (of outputs, workspaces) and a table for each workspace. That approach turned
194 out to be complicated to use (snapping), understand and implement.
195
196 === The tree consists of Containers
197
198 The building blocks of our tree are so-called +Containers+. A +Container+ can
199 host a window (meaning an X11 window, one that you can actually see and use,
200 like a browser). Alternatively, it could contain one or more +Containers+. A
201 simple example is the workspace: When you start i3 with a single monitor, a
202 single workspace and you open two terminal windows, you will end up with a tree
203 like this:
204
205 image::tree-layout2.png["layout2",float="right"]
206 image::tree-shot4.png["shot4",title="Two terminals on standard workspace"]
207
208 [[OrientationSplit]]
209 === Orientation and Split Containers
210
211 It is only natural to use so-called +Split Containers+ in order to build a
212 layout when using a tree as data structure. In i3, every +Container+ has an
213 orientation (horizontal, vertical or unspecified) and the orientation depends
214 on the layout the container is in (vertical for splitv and stacking, horizontal
215 for splith and tabbed). So, in our example with the workspace, the default
216 layout of the workspace +Container+ is splith (most monitors are widescreen
217 nowadays). If you change the layout to splitv (+$mod+v+ in the default config)
218 and *then* open two terminals, i3 will configure your windows like this:
219
220 image::tree-shot2.png["shot2",title="Vertical Workspace Orientation"]
221
222 An interesting new feature of i3 since version 4 is the ability to split anything:
223 Let’s assume you have two terminals on a workspace (with splith layout, that is
224 horizontal orientation), focus is on the right terminal. Now you want to open
225 another terminal window below the current one. If you would just open a new
226 terminal window, it would show up to the right due to the splith layout.
227 Instead, press +$mod+v+ to split the container with the splitv layout (to
228 open a +Horizontal Split Container+, use +$mod+h+). Now you can open a new
229 terminal and it will open below the current one:
230
231 image::tree-layout1.png["Layout",float="right"]
232 image::tree-shot1.png["shot",title="Vertical Split Container"]
233
234 unfloat::[]
235
236 You probably guessed it already: There is no limit on how deep your hierarchy
237 of splits can be.
238
239 === Focus parent
240
241 Let’s stay with our example from above. We have a terminal on the left and two
242 vertically split terminals on the right, focus is on the bottom right one. When
243 you open a new terminal, it will open below the current one.
244
245 So, how can you open a new terminal window to the *right* of the current one?
246 The solution is to use +focus parent+, which will focus the +Parent Container+ of
247 the current +Container+. In default configuration, use +$mod+a+ to navigate one
248 +Container+ up the tree (you can repeat this multiple times until you get to the
249 +Workspace Container+). In this case, you would focus the +Vertical Split Container+
250 which is *inside* the horizontally oriented workspace. Thus, now new windows will be
251 opened to the right of the +Vertical Split Container+:
252
253 image::tree-shot3.png["shot3",title="Focus parent, then open new terminal"]
254
255 === Implicit containers
256
257 In some cases, i3 needs to implicitly create a container to fulfill your
258 command.
259
260 One example is the following scenario: You start i3 with a single monitor and a
261 single workspace on which you open three terminal windows. All these terminal
262 windows are directly attached to one node inside i3’s layout tree, the
263 workspace node. By default, the workspace node’s orientation is +horizontal+.
264
265 Now you move one of these terminals down (+$mod+Shift+k+ by default). The
266 workspace node’s orientation will be changed to +vertical+. The terminal window
267 you moved down is directly attached to the workspace and appears on the bottom
268 of the screen. A new (horizontal) container was created to accommodate the
269 other two terminal windows. You will notice this when switching to tabbed mode
270 (for example). You would end up having one tab with a representation of the split
271 container (e.g., "H[urxvt firefox]") and the other one being the terminal window
272 you moved down.
273
274 [[configuring]]
275 == Configuring i3
276
277 This is where the real fun begins ;-). Most things are very dependent on your
278 ideal working environment so we can’t make reasonable defaults for them.
279
280 While not using a programming language for the configuration, i3 stays
281 quite flexible in regards to the things you usually want your window manager
282 to do.
283
284 For example, you can configure bindings to jump to specific windows,
285 you can set specific applications to start on specific workspaces, you can
286 automatically start applications, you can change the colors of i3, and you
287 can bind your keys to do useful things.
288
289 To change the configuration of i3, copy +/etc/i3/config+ to +\~/.i3/config+
290 (or +~/.config/i3/config+ if you like the XDG directory scheme) and edit it
291 with a text editor.
292
293 On first start (and on all following starts, unless you have a configuration
294 file), i3 will offer you to create a configuration file. You can tell the
295 wizard to use either Alt (+Mod1+) or Windows (+Mod4+) as modifier in the config
296 file. Also, the created config file will use the key symbols of your current
297 keyboard layout. To start the wizard, use the command +i3-config-wizard+.
298 Please note that you must not have +~/.i3/config+, otherwise the wizard will
299 exit.
300
301 Since i3 4.0, a new configuration format is used. i3 will try to automatically
302 detect the format version of a config file based on a few different keywords,
303 but if you want to make sure that your config is read with the new format,
304 include the following line in your config file:
305
306 ---------------------
307 # i3 config file (v4)
308 ---------------------
309
310 === Comments
311
312 It is possible and recommended to use comments in your configuration file to
313 properly document your setup for later reference. Comments are started with
314 a # and can only be used at the beginning of a line:
315
316 *Examples*:
317 -------------------
318 # This is a comment
319 -------------------
320
321 [[fonts]]
322 === Fonts
323
324 i3 has support for both X core fonts and FreeType fonts (through Pango) to
325 render window titles.
326
327 To generate an X core font description, you can use +xfontsel(1)+. To see
328 special characters (Unicode), you need to use a font which supports the
329 ISO-10646 encoding.
330
331 A FreeType font description is composed by a font family, a style, a weight,
332 a variant, a stretch and a size.
333 FreeType fonts support right-to-left rendering and contain often more
334 Unicode glyphs than X core fonts.
335
336 If i3 cannot open the configured font, it will output an error in the logfile
337 and fall back to a working font.
338
339 *Syntax*:
340 ------------------------------
341 font <X core font description>
342 font pango:<family list> [<style options>] <size>
343 ------------------------------
344
345 *Examples*:
346 --------------------------------------------------------------
347 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
348 font pango:DejaVu Sans Mono 10
349 font pango:DejaVu Sans Mono, Terminus Bold Semi-Condensed 11
350 font pango:Terminus 11px
351 --------------------------------------------------------------
352
353 [[keybindings]]
354 === Keyboard bindings
355
356 A keyboard binding makes i3 execute a command (see below) upon pressing a
357 specific key. i3 allows you to bind either on keycodes or on keysyms (you can
358 also mix your bindings, though i3 will not protect you from overlapping ones).
359
360 * A keysym (key symbol) is a description for a specific symbol, like "a"
361 or "b", but also more strange ones like "underscore" instead of "_". These
362 are the ones you use in Xmodmap to remap your keys. To get the current
363 mapping of your keys, use +xmodmap -pke+. To interactively enter a key and
364 see what keysym it is configured to, use +xev+.
365
366 * Keycodes do not need to have a symbol assigned (handy for custom vendor
367 hotkeys on some notebooks) and they will not change their meaning as you
368 switch to a different keyboard layout (when using +xmodmap+).
369
370 My recommendation is: If you often switch keyboard layouts but you want to keep
371 your bindings in the same physical location on the keyboard, use keycodes.
372 If you don’t switch layouts, and want a clean and simple config file, use
373 keysyms.
374
375 Some tools (such as +import+ or +xdotool+) might be unable to run upon a
376 KeyPress event, because the keyboard/pointer is still grabbed. For these
377 situations, the +--release+ flag can be used, which will execute the command
378 after the keys have been released.
379
380 *Syntax*:
381 ----------------------------------
382 bindsym [--release] [<Group>+][<Modifiers>+]<keysym> command
383 bindcode [--release] [<Group>+][<Modifiers>+]<keycode> command
384 ----------------------------------
385
386 *Examples*:
387 --------------------------------
388 # Fullscreen
389 bindsym $mod+f fullscreen toggle
390
391 # Restart
392 bindsym $mod+Shift+r restart
393
394 # Notebook-specific hotkeys
395 bindcode 214 exec --no-startup-id /home/michael/toggle_beamer.sh
396
397 # Simulate ctrl+v upon pressing $mod+x
398 bindsym --release $mod+x exec --no-startup-id xdotool key --clearmodifiers ctrl+v
399
400 # Take a screenshot upon pressing $mod+x (select an area)
401 bindsym --release $mod+x exec --no-startup-id import /tmp/latest-screenshot.png
402 --------------------------------
403
404 Available Modifiers:
405
406 Mod1-Mod5, Shift, Control::
407 Standard modifiers, see +xmodmap(1)+
408
409 Group1, Group2, Group3, Group4::
410 When using multiple keyboard layouts (e.g. with `setxkbmap -layout us,ru`), you
411 can specify in which XKB group (also called “layout”) a keybinding should be
412 active. By default, keybindings are translated in Group1 and are active in all
413 groups. If you want to override keybindings in one of your layouts, specify the
414 corresponding group. For backwards compatibility, the group “Mode_switch” is an
415 alias for Group2.
416
417 [[mousebindings]]
418 === Mouse bindings
419
420 A mouse binding makes i3 execute a command upon pressing a specific mouse
421 button in the scope of the clicked container (see <<command_criteria>>). You
422 can configure mouse bindings in a similar way to key bindings.
423
424 *Syntax*:
425 ----------------------------------------------------------------------------------------------------
426 bindsym [--release] [--border] [--whole-window] [--exclude-titlebar] [<Modifiers>+]button<n> command
427 ----------------------------------------------------------------------------------------------------
428
429 By default, the binding will only run when you click on the titlebar of the
430 window. If the +--release+ flag is given, it will run when the mouse button
431 is released.
432
433 If the +--whole-window+ flag is given, the binding will also run when any part
434 of the window is clicked, with the exception of the border. To have a bind run
435 when the border is clicked, specify the +--border+ flag.
436
437 If the +--exclude-titlebar+ flag is given, the titlebar will not be considered
438 for the keybinding.
439
440 *Examples*:
441 --------------------------------
442 # The middle button over a titlebar kills the window
443 bindsym --release button2 kill
444
445 # The middle button and a modifer over any part of the window kills the window
446 bindsym --whole-window $mod+button2 kill
447
448 # The right button toggles floating
449 bindsym button3 floating toggle
450 bindsym $mod+button3 floating toggle
451
452 # The side buttons move the window around
453 bindsym button9 move left
454 bindsym button8 move right
455 --------------------------------
456
457 [[binding_modes]]
458 === Binding modes
459
460 You can have multiple sets of bindings by using different binding modes. When
461 you switch to another binding mode, all bindings from the current mode are
462 released and only the bindings defined in the new mode are valid for as long as
463 you stay in that binding mode. The only predefined binding mode is +default+,
464 which is the mode i3 starts out with and to which all bindings not defined in a
465 specific binding mode belong.
466
467 Working with binding modes consists of two parts: defining a binding mode and
468 switching to it. For these purposes, there are one config directive and one
469 command, both of which are called +mode+. The directive is used to define the
470 bindings belonging to a certain binding mode, while the command will switch to
471 the specified mode.
472
473 It is recommended to use binding modes in combination with <<variables>> in
474 order to make maintenance easier. Below is an example of how to use a binding
475 mode.
476
477 Note that it is advisable to define bindings for switching back to the default
478 mode.
479
480 Note that it is possible to use <<pango_markup>> for binding modes, but you
481 need to enable it explicitly by passing the +--pango_markup+ flag to the mode
482 definition.
483
484 *Syntax*:
485 ----------------------------
486 # config directive
487 mode [--pango_markup] <name>
488
489 # command
490 mode <name>
491 ----------------------------
492
493 *Example*:
494 ------------------------------------------------------------------------
495 # Press $mod+o followed by either f, t, Escape or Return to launch firefox,
496 # thunderbird or return to the default mode, respectively.
497 set $mode_launcher Launch: [f]irefox [t]hunderbird
498 bindsym $mod+o mode "$mode_launcher"
499
500 mode "$mode_launcher" {
501 bindsym f exec firefox
502 bindsym t exec thunderbird
503
504 bindsym Escape mode "default"
505 bindsym Return mode "default"
506 }
507 ------------------------------------------------------------------------
508
509 [[floating_modifier]]
510 === The floating modifier
511
512 To move floating windows with your mouse, you can either grab their titlebar
513 or configure the so-called floating modifier which you can then press and
514 click anywhere in the window itself to move it. The most common setup is to
515 use the same key you use for managing windows (Mod1 for example). Then
516 you can press Mod1, click into a window using your left mouse button, and drag
517 it to the position you want.
518
519 When holding the floating modifier, you can resize a floating window by
520 pressing the right mouse button on it and moving around while holding it. If
521 you hold the shift button as well, the resize will be proportional (the aspect
522 ratio will be preserved).
523
524 *Syntax*:
525 --------------------------------
526 floating_modifier <Modifier>
527 --------------------------------
528
529 *Example*:
530 --------------------------------
531 floating_modifier Mod1
532 --------------------------------
533
534 === Constraining floating window size
535
536 The maximum and minimum dimensions of floating windows can be specified. If
537 either dimension of +floating_maximum_size+ is specified as -1, that dimension
538 will be unconstrained with respect to its maximum value. If either dimension of
539 +floating_maximum_size+ is undefined, or specified as 0, i3 will use a default
540 value to constrain the maximum size. +floating_minimum_size+ is treated in a
541 manner analogous to +floating_maximum_size+.
542
543 *Syntax*:
544 ----------------------------------------
545 floating_minimum_size <width> x <height>
546 floating_maximum_size <width> x <height>
547 ----------------------------------------
548
549 *Example*:
550 --------------------------------------
551 floating_minimum_size 75 x 50
552 floating_maximum_size -1 x -1
553 --------------------------------------
554
555 === Orientation for new workspaces
556
557 New workspaces get a reasonable default orientation: Wide-screen monitors
558 (anything wider than high) get horizontal orientation, rotated monitors
559 (anything higher than wide) get vertical orientation.
560
561 With the +default_orientation+ configuration directive, you can override that
562 behavior.
563
564 *Syntax*:
565 --------------------------------------------
566 default_orientation horizontal|vertical|auto
567 --------------------------------------------
568
569 *Example*:
570 ----------------------------
571 default_orientation vertical
572 ----------------------------
573
574 === Layout mode for new containers
575
576 This option determines in which mode new containers on workspace level will
577 start.
578
579 *Syntax*:
580 ---------------------------------------------
581 workspace_layout default|stacking|tabbed
582 ---------------------------------------------
583
584 *Example*:
585 ---------------------
586 workspace_layout tabbed
587 ---------------------
588
589 === Window title alignment
590
591 This option determines the window title's text alignment.
592 Default is +left+
593
594 *Syntax*:
595 ---------------------------------------------
596 title_align left|center|right
597 ---------------------------------------------
598
599 === Default border style for new windows
600
601 This option determines which border style new windows will have. The default is
602 +normal+. Note that default_floating_border applies only to windows which are starting out as
603 floating windows, e.g., dialog windows, but not windows that are floated later on.
604
605 Setting border style to +pixel+ eliminates title bars. The border style +normal+ allows you to
606 adjust edge border width while keeping your title bar.
607
608 *Syntax*:
609 ---------------------------------------------
610 default_border normal|none|pixel
611 default_border normal|pixel <px>
612 default_floating_border normal|none|pixel
613 default_floating_border normal|pixel <px>
614 ---------------------------------------------
615
616 Please note that +new_window+ and +new_float+ have been deprecated in favor of the above options
617 and will be removed in a future release. We strongly recommend using the new options instead.
618
619 *Example*:
620 ---------------------
621 default_border pixel
622 ---------------------
623
624 The "normal" and "pixel" border styles support an optional border width in
625 pixels:
626
627 *Example*:
628 ---------------------
629 # The same as default_border none
630 default_border pixel 0
631
632 # A 3 px border
633 default_border pixel 3
634 ---------------------
635
636
637 [[_hiding_vertical_borders]]
638 === Hiding borders adjacent to the screen edges
639
640 You can hide container borders adjacent to the screen edges using
641 +hide_edge_borders+. This is useful if you are using scrollbars, or do not want
642 to waste even two pixels in displayspace. The "smart" setting hides borders on
643 workspaces with only one window visible, but keeps them on workspaces with
644 multiple windows visible. Default is none.
645
646 *Syntax*:
647 -----------------------------------------------
648 hide_edge_borders none|vertical|horizontal|both|smart
649 -----------------------------------------------
650
651 *Example*:
652 ----------------------
653 hide_edge_borders vertical
654 ----------------------
655
656 [[for_window]]
657 === Arbitrary commands for specific windows (for_window)
658
659 With the +for_window+ directive, you can let i3 execute any command when it
660 encounters a specific window. This can be used to set windows to floating or to
661 change their border style, for example.
662
663 *Syntax*:
664 -------------------------------
665 for_window <criteria> <command>
666 -------------------------------
667
668 *Examples*:
669 ------------------------------------------------
670 # enable floating mode for all XTerm windows
671 for_window [class="XTerm"] floating enable
672
673 # Make all urxvts use a 1-pixel border:
674 for_window [class="urxvt"] border pixel 1
675
676 # A less useful, but rather funny example:
677 # makes the window floating as soon as I change
678 # directory to ~/work
679 for_window [title="x200: ~/work"] floating enable
680 ------------------------------------------------
681
682 The valid criteria are the same as those for commands, see <<command_criteria>>. Only
683 commands can be executed at runtime, not config directives, see <<list_of_commands>>.
684
685 [[no_focus]]
686 === Don't focus window upon opening
687
688 When a new window appears, it will be focused. The +no_focus+ directive allows preventing
689 this from happening and must be used in combination with <<command_criteria>>.
690
691 Note that this does not apply to all cases, e.g., when feeding data into a running application
692 causing it to request being focused. To configure the behavior in such cases, refer to
693 <<focus_on_window_activation>>.
694
695 +no_focus+ will also be ignored for the first window on a workspace as there shouldn't be
696 a reason to not focus the window in this case. This allows for better usability in
697 combination with +workspace_layout+.
698
699 *Syntax*:
700 -------------------
701 no_focus <criteria>
702 -------------------
703
704 *Example*:
705 -------------------------------
706 no_focus [window_role="pop-up"]
707 -------------------------------
708
709 [[variables]]
710 === Variables
711
712 As you learned in the section about keyboard bindings, you will have
713 to configure lots of bindings containing modifier keys. If you want to save
714 yourself some typing and be able to change the modifier you use later,
715 variables can be handy.
716
717 *Syntax*:
718 -------------------
719 set $<name> <value>
720 -------------------
721
722 *Example*:
723 ------------------------
724 set $m Mod1
725 bindsym $m+Shift+r restart
726 ------------------------
727
728 Variables are directly replaced in the file when parsing. Variables expansion
729 is not recursive so it is not possible to define a variable with a value
730 containing another variable. There is no fancy handling and there are
731 absolutely no plans to change this. If you need a more dynamic configuration
732 you should create a little script which generates a configuration file and run
733 it before starting i3 (for example in your +~/.xsession+ file).
734
735 Also see <<xresources>> to learn how to create variables based on resources
736 loaded from the X resource database.
737
738 [[xresources]]
739 === X resources
740
741 <<variables>> can also be created using a value configured in the X resource
742 database. This is useful, for example, to avoid configuring color values within
743 the i3 configuration. Instead, the values can be configured, once, in the X
744 resource database to achieve an easily maintainable, consistent color theme
745 across many X applications.
746
747 Defining a resource will load this resource from the resource database and
748 assign its value to the specified variable. This is done verbatim and the value
749 must therefore be in the format that i3 uses. A fallback must be specified in
750 case the resource cannot be loaded from the database.
751
752 *Syntax*:
753 ----------------------------------------------------
754 set_from_resource $<name> <resource_name> <fallback>
755 ----------------------------------------------------
756
757 *Example*:
758 ----------------------------------------------------------------------------
759 # The ~/.Xresources should contain a line such as
760 # *color0: #121212
761 # and must be loaded properly, e.g., by using
762 # xrdb ~/.Xresources
763 # This value is picked up on by other applications (e.g., the URxvt terminal
764 # emulator) and can be used in i3 like this:
765 set_from_resource $black i3wm.color0 #000000
766 ----------------------------------------------------------------------------
767
768 [[assign_workspace]]
769 === Automatically putting clients on specific workspaces
770
771 To automatically make a specific window show up on a specific workspace, you
772 can use an *assignment*. You can match windows by using any criteria,
773 see <<command_criteria>>. The difference between +assign+ and
774 +for_window <criteria> move to workspace+ is that the former will only be
775 executed when the application maps the window (mapping means actually displaying
776 it on the screen) but the latter will be executed whenever a window changes its
777 properties to something that matches the specified criteria.
778
779 Thus, it is recommended that you match on window classes (and instances, when
780 appropriate) instead of window titles whenever possible because some
781 applications first create their window, and then worry about setting the correct
782 title. Firefox with Vimperator comes to mind. The window starts up being named
783 Firefox, and only when Vimperator is loaded does the title change. As i3 will
784 get the title as soon as the application maps the window, you’d need to have to
785 match on 'Firefox' in this case.
786 Another known issue is with Spotify, which doesn't set the class hints when
787 mapping the window, meaning you'll have to use a +for_window+ rule to assign
788 Spotify to a specific workspace.
789 Finally, using +assign [tiling]+ and +assign [floating]+ is not supported.
790
791 You can also assign a window to show up on a specific output. You can use RandR
792 names such as +VGA1+ or names relative to the output with the currently focused
793 workspace such as +left+ and +down+.
794
795 Assignments are processed by i3 in the order in which they appear in the config
796 file. The first one which matches the window wins and later assignments are not
797 considered.
798
799 *Syntax*:
800 ------------------------------------------------------------
801 assign <criteria> [→] [workspace] [number] <workspace>
802 assign <criteria> [→] output left|right|up|down|primary|<output>
803 ------------------------------------------------------------
804
805 *Examples*:
806 ----------------------
807 # Assign URxvt terminals to workspace 2
808 assign [class="URxvt"] 2
809
810 # Same thing, but more precise (exact match instead of substring)
811 assign [class="^URxvt$"] 2
812
813 # Same thing, but with a beautiful arrow :)
814 assign [class="^URxvt$"] → 2
815
816 # Assignment to a named workspace
817 assign [class="^URxvt$"] → work
818
819 # Assign to the workspace with number 2, regardless of name
820 assign [class="^URxvt$"] → number 2
821
822 # You can also specify a number + name. If the workspace with number 2 exists,
823 # assign will skip the text part.
824 assign [class="^URxvt$"] → number "2: work"
825
826 # Start urxvt -name irssi
827 assign [class="^URxvt$" instance="^irssi$"] → 3
828
829 # Assign urxvt to the output right of the current one
830 assign [class="^URxvt$"] → output right
831
832 # Assign urxvt to the primary output
833 assign [class="^URxvt$"] → output primary
834 ----------------------
835
836 Note that you might not have a primary output configured yet. To do so, run:
837 -------------------------
838 xrandr --output <output> --primary
839 -------------------------
840
841 Also, the arrow is not required, it just looks good :-). If you decide to
842 use it, it has to be a UTF-8 encoded arrow, not `->` or something like that.
843
844 To get the class and instance, you can use +xprop+. After clicking on the
845 window, you will see the following output:
846
847 *xprop*:
848 -----------------------------------
849 WM_CLASS(STRING) = "irssi", "URxvt"
850 -----------------------------------
851
852 The first part of the WM_CLASS is the instance ("irssi" in this example), the
853 second part is the class ("URxvt" in this example).
854
855 Should you have any problems with assignments, make sure to check the i3
856 logfile first (see https://i3wm.org/docs/debugging.html). It includes more
857 details about the matching process and the window’s actual class, instance and
858 title when starting up.
859
860 Note that if you want to start an application just once on a specific
861 workspace, but you don’t want to assign all instances of it permanently, you
862 can make use of i3’s startup-notification support (see <<exec>>) in your config
863 file in the following way:
864
865 *Start iceweasel on workspace 3 (once)*:
866 -------------------------------------------------------------------------------
867 # Start iceweasel on workspace 3, then switch back to workspace 1
868 # (Being a command-line utility, i3-msg does not support startup notifications,
869 # hence the exec --no-startup-id.)
870 # (Starting iceweasel with i3’s exec command is important in order to make i3
871 # create a startup notification context, without which the iceweasel window(s)
872 # cannot be matched onto the workspace on which the command was started.)
873 exec --no-startup-id i3-msg 'workspace 3; exec iceweasel; workspace 1'
874 -------------------------------------------------------------------------------
875
876 === Automatically starting applications on i3 startup
877
878 By using the +exec+ keyword outside a keybinding, you can configure
879 which commands will be performed by i3 on initial startup. +exec+
880 commands will not run when restarting i3, if you need a command to run
881 also when restarting i3 you should use the +exec_always+
882 keyword. These commands will be run in order.
883
884 See <<command_chaining>> for details on the special meaning of +;+ (semicolon)
885 and +,+ (comma): they chain commands together in i3, so you need to use quoted
886 strings (as shown in <<exec_quoting>>) if they appear in your command.
887
888 *Syntax*:
889 ---------------------------------------
890 exec [--no-startup-id] <command>
891 exec_always [--no-startup-id] <command>
892 ---------------------------------------
893
894 *Examples*:
895 --------------------------------
896 exec chromium
897 exec_always ~/my_script.sh
898
899 # Execute the terminal emulator urxvt, which is not yet startup-notification aware.
900 exec --no-startup-id urxvt
901 --------------------------------
902
903 The flag --no-startup-id is explained in <<exec>>.
904
905 [[workspace_screen]]
906 === Automatically putting workspaces on specific screens
907
908 If you assign clients to workspaces, it might be handy to put the
909 workspaces on specific screens. Also, the assignment of workspaces to screens
910 will determine which workspace i3 uses for a new screen when adding screens
911 or when starting (e.g., by default it will use 1 for the first screen, 2 for
912 the second screen and so on).
913
914 *Syntax*:
915 -------------------------------------
916 workspace <workspace> output <output1> [output2]…
917 -------------------------------------
918
919 The 'output' is the name of the RandR output you attach your screen to. On a
920 laptop, you might have VGA1 and LVDS1 as output names. You can see the
921 available outputs by running +xrandr --current+.
922
923 If your X server supports RandR 1.5 or newer, i3 will use RandR monitor objects
924 instead of output objects. Run +xrandr --listmonitors+ to see a list. Usually,
925 a monitor object contains exactly one output, and has the same name as the
926 output; but should that not be the case, you may specify the name of either the
927 monitor or the output in i3's configuration. For example, the Dell UP2414Q uses
928 two scalers internally, so its output names might be “DP1” and “DP2”, but the
929 monitor name is “Dell UP2414Q”.
930
931 (Note that even if you specify the name of an output which doesn't span the
932 entire monitor, i3 will still use the entire area of the containing monitor
933 rather than that of just the output's.)
934
935 You can specify multiple outputs. The first available will be used.
936
937 If you use named workspaces, they must be quoted:
938
939 *Examples*:
940 ---------------------------
941 workspace 1 output LVDS1
942 workspace 2 output primary
943 workspace 5 output VGA1 LVDS1
944 workspace "2: vim" output VGA1
945 ---------------------------
946
947 === Changing colors
948
949 You can change all colors which i3 uses to draw the window decorations.
950
951 *Syntax*:
952 --------------------------------------------------------------------
953 <colorclass> <border> <background> <text> <indicator> <child_border>
954 --------------------------------------------------------------------
955
956 Where colorclass can be one of:
957
958 client.focused::
959 A client which currently has the focus.
960 client.focused_inactive::
961 A client which is the focused one of its container, but it does not have
962 the focus at the moment.
963 client.unfocused::
964 A client which is not the focused one of its container.
965 client.urgent::
966 A client which has its urgency hint activated.
967 client.placeholder::
968 Background and text color are used to draw placeholder window contents
969 (when restoring layouts). Border and indicator are ignored.
970 client.background::
971 Background color which will be used to paint the background of the
972 client window on top of which the client will be rendered. Only clients
973 which do not cover the whole area of this window expose the color. Note
974 that this colorclass only takes a single color.
975
976 Colors are in HTML hex format (#rrggbb), see the following example:
977
978 *Examples (default colors)*:
979 ----------------------------------------------------------------------
980 # class border backgr. text indicator child_border
981 client.focused #4c7899 #285577 #ffffff #2e9ef4 #285577
982 client.focused_inactive #333333 #5f676a #ffffff #484e50 #5f676a
983 client.unfocused #333333 #222222 #888888 #292d2e #222222
984 client.urgent #2f343a #900000 #ffffff #900000 #900000
985 client.placeholder #000000 #0c0c0c #ffffff #000000 #0c0c0c
986
987 client.background #ffffff
988 ----------------------------------------------------------------------
989
990 Note that for the window decorations, the color around the child window is the
991 "child_border", and "border" color is only the two thin lines around the
992 titlebar.
993
994 The indicator color is used for indicating where a new window will be opened.
995 For horizontal split containers, the right border will be painted in indicator
996 color, for vertical split containers, the bottom border. This only applies to
997 single windows within a split container, which are otherwise indistinguishable
998 from single windows outside of a split container.
999
1000 === Interprocess communication
1001
1002 i3 uses Unix sockets to provide an IPC interface. This allows third-party
1003 programs to get information from i3, such as the current workspaces
1004 (to display a workspace bar), and to control i3.
1005
1006 The IPC socket is enabled by default and will be created in
1007 +$XDG_RUNTIME_DIR/i3/ipc-socket.%p+ if the directory is available, falling back
1008 to +/tmp/i3-%u.XXXXXX/ipc-socket.%p+, where +%u+ is your UNIX username, +%p+ is
1009 the PID of i3 and XXXXXX is a string of random characters from the portable
1010 filename character set (see mkdtemp(3)).
1011
1012 You can override the default path through the environment-variable +I3SOCK+ or
1013 by specifying the +ipc-socket+ directive. This is discouraged, though, since i3
1014 does the right thing by default. If you decide to change it, it is strongly
1015 recommended to set this to a location in your home directory so that no other
1016 user can create that directory.
1017
1018 *Examples*:
1019 ----------------------------
1020 ipc-socket ~/.i3/i3-ipc.sock
1021 ----------------------------
1022
1023 You can then use the +i3-msg+ application to perform any command listed in
1024 <<list_of_commands>>.
1025
1026 === Focus follows mouse
1027
1028 By default, window focus follows your mouse movements as the mouse crosses
1029 window borders. However, if you have a setup where your mouse usually is in your
1030 way (like a touchpad on your laptop which you do not want to disable
1031 completely), you might want to disable 'focus follows mouse' and control focus
1032 only by using your keyboard. The mouse will still be useful inside the
1033 currently active window (for example to click on links in your browser window).
1034
1035 *Syntax*:
1036 --------------------------
1037 focus_follows_mouse yes|no
1038 --------------------------
1039
1040 *Example*:
1041 ----------------------
1042 focus_follows_mouse no
1043 ----------------------
1044
1045 === Mouse warping
1046
1047 By default, when switching focus to a window on a different output (e.g.
1048 focusing a window on workspace 3 on output VGA-1, coming from workspace 2 on
1049 LVDS-1), the mouse cursor is warped to the center of that window.
1050
1051 With the +mouse_warping+ option, you can control when the mouse cursor should
1052 be warped. +none+ disables warping entirely, whereas +output+ is the default
1053 behavior described above.
1054
1055 *Syntax*:
1056 -------------------------
1057 mouse_warping output|none
1058 -------------------------
1059
1060 *Example*:
1061 ------------------
1062 mouse_warping none
1063 ------------------
1064
1065 === Popups during fullscreen mode
1066
1067 When you are in fullscreen mode, some applications still open popup windows
1068 (take Xpdf for example). This is because these applications may not be aware
1069 that they are in fullscreen mode (they do not check the corresponding hint).
1070 There are three things which are possible to do in this situation:
1071
1072 1. Display the popup if it belongs to the fullscreen application only. This is
1073 the default and should be reasonable behavior for most users.
1074 2. Just ignore the popup (don’t map it). This won’t interrupt you while you are
1075 in fullscreen. However, some apps might react badly to this (deadlock until
1076 you go out of fullscreen).
1077 3. Leave fullscreen mode.
1078
1079 *Syntax*:
1080 -----------------------------------------------------
1081 popup_during_fullscreen smart|ignore|leave_fullscreen
1082 -----------------------------------------------------
1083
1084 *Example*:
1085 ------------------------------
1086 popup_during_fullscreen smart
1087 ------------------------------
1088
1089 === Focus wrapping
1090
1091 By default, when in a container with several windows or child containers, the
1092 opposite window will be focused when trying to move the focus over the edge of
1093 a container (and there are no other containers in that direction) -- the focus
1094 wraps.
1095
1096 If desired, you can disable this behavior by setting the +focus_wrapping+
1097 configuration directive to the value +no+.
1098
1099 When enabled, focus wrapping does not occur by default if there is another
1100 window or container in the specified direction, and focus will instead be set
1101 on that window or container. This is the default behavior so you can navigate
1102 to all your windows without having to use +focus parent+.
1103
1104 If you want the focus to *always* wrap and you are aware of using +focus
1105 parent+ to switch to different containers, you can instead set +focus_wrapping+
1106 to the value +force+.
1107
1108 To restrict focus inside the current workspace set +focus_wrapping+ to the
1109 value +workspace+. You will need to use +focus parent+ until a workspace is
1110 selected to switch to a different workspace using the focus commands (the
1111 +workspace+ command will still work as expected).
1112
1113 *Syntax*:
1114 ---------------------------
1115 focus_wrapping yes|no|force|workspace
1116
1117 # Legacy syntax, equivalent to "focus_wrapping force"
1118 force_focus_wrapping yes
1119 ---------------------------
1120
1121 *Examples*:
1122 -----------------
1123 # Disable focus wrapping
1124 focus_wrapping no
1125
1126 # Force focus wrapping
1127 focus_wrapping force
1128 -----------------
1129
1130 === Forcing Xinerama
1131
1132 As explained in-depth in <https://i3wm.org/docs/multi-monitor.html>, some X11
1133 video drivers (especially the nVidia binary driver) only provide support for
1134 Xinerama instead of RandR. In such a situation, i3 must be told to use the
1135 inferior Xinerama API explicitly and therefore don’t provide support for
1136 reconfiguring your screens on the fly (they are read only once on startup and
1137 that’s it).
1138
1139 For people who cannot modify their +~/.xsession+ to add the
1140 +--force-xinerama+ commandline parameter, a configuration option is provided:
1141
1142 *Syntax*:
1143 ---------------------
1144 force_xinerama yes|no
1145 ---------------------
1146
1147 *Example*:
1148 ------------------
1149 force_xinerama yes
1150 ------------------
1151
1152 Also note that your output names are not descriptive (like +HDMI1+) when using
1153 Xinerama, instead they are counted up, starting at 0: +xinerama-0+, +xinerama-1+, …
1154
1155 [[workspace_auto_back_and_forth]]
1156 === Automatic back-and-forth when switching to the current workspace
1157
1158 This configuration directive enables automatic +workspace back_and_forth+ (see
1159 <<back_and_forth>>) when switching to the workspace that is currently focused.
1160
1161 For instance: Assume you are on workspace "1: www" and switch to "2: IM" using
1162 mod+2 because somebody sent you a message. You don’t need to remember where you
1163 came from now, you can just press $mod+2 again to switch back to "1: www".
1164
1165 *Syntax*:
1166 ------------------------------------
1167 workspace_auto_back_and_forth yes|no
1168 ------------------------------------
1169
1170 *Example*:
1171 ---------------------------------
1172 workspace_auto_back_and_forth yes
1173 ---------------------------------
1174
1175 === Delaying urgency hint reset on workspace change
1176
1177 If an application on another workspace sets an urgency hint, switching to this
1178 workspace may lead to immediate focus of the application, which also means the
1179 window decoration color would be immediately reset to +client.focused+. This
1180 may make it unnecessarily hard to tell which window originally raised the
1181 event.
1182
1183 In order to prevent this, you can tell i3 to delay resetting the urgency state
1184 by a certain time using the +force_display_urgency_hint+ directive. Setting the
1185 value to 0 disables this feature.
1186
1187 The default is 500ms.
1188
1189 *Syntax*:
1190 ---------------------------------------
1191 force_display_urgency_hint <timeout> ms
1192 ---------------------------------------
1193
1194 *Example*:
1195 ---------------------------------
1196 force_display_urgency_hint 500 ms
1197 ---------------------------------
1198
1199 [[focus_on_window_activation]]
1200 === Focus on window activation
1201
1202 If a window is activated, e.g., via +google-chrome www.google.com+, it may request
1203 to take focus. Since this may not be preferable, different reactions can be configured.
1204
1205 Note that this may not affect windows that are being opened. To prevent new windows
1206 from being focused, see <<no_focus>>.
1207
1208 *Syntax*:
1209 --------------------------------------------------
1210 focus_on_window_activation smart|urgent|focus|none
1211 --------------------------------------------------
1212
1213 The different modes will act as follows:
1214
1215 smart::
1216 This is the default behavior. If the window requesting focus is on an active
1217 workspace, it will receive the focus. Otherwise, the urgency hint will be set.
1218 urgent::
1219 The window will always be marked urgent, but the focus will not be stolen.
1220 focus::
1221 The window will always be focused and not be marked urgent.
1222 none::
1223 The window will neither be focused, nor be marked urgent.
1224
1225 [[show_marks]]
1226 === Drawing marks on window decoration
1227
1228 If activated, marks (see <<vim_like_marks>>) on windows are drawn in their window
1229 decoration. However, any mark starting with an underscore in its name (+_+) will
1230 not be drawn even if this option is activated.
1231
1232 The default for this option is +yes+.
1233
1234 *Syntax*:
1235 -----------------
1236 show_marks yes|no
1237 -----------------
1238
1239 *Example*:
1240 --------------
1241 show_marks yes
1242 --------------
1243
1244 [[line_continuation]]
1245 === Line continuation
1246
1247 Config files support line continuation, meaning when you end a line in a
1248 backslash character (`\`), the line-break will be ignored by the parser. This
1249 feature can be used to create more readable configuration files.
1250 Commented lines are not continued.
1251
1252 *Examples*:
1253 -------------------
1254 bindsym Mod1+f \
1255 fullscreen toggle
1256
1257 # this line is not continued \
1258 bindsym Mod1+F fullscreen toggle
1259 -------------------
1260
1261 == Configuring i3bar
1262
1263 The bar at the bottom of your monitor is drawn by a separate process called
1264 i3bar. Having this part of "the i3 user interface" in a separate process has
1265 several advantages:
1266
1267 1. It is a modular approach. If you don’t need a workspace bar at all, or if
1268 you prefer a different one (dzen2, xmobar, maybe even gnome-panel?), you can
1269 just remove the i3bar configuration and start your favorite bar instead.
1270 2. It follows the UNIX philosophy of "Make each program do one thing well".
1271 While i3 manages your windows well, i3bar is good at displaying a bar on
1272 each monitor (unless you configure it otherwise).
1273 3. It leads to two separate, clean codebases. If you want to understand i3, you
1274 don’t need to bother with the details of i3bar and vice versa.
1275
1276 That said, i3bar is configured in the same configuration file as i3. This is
1277 because it is tightly coupled with i3 (in contrary to i3lock or i3status which
1278 are useful for people using other window managers). Therefore, it makes no
1279 sense to use a different configuration place when we already have a good
1280 configuration infrastructure in place.
1281
1282 Configuring your workspace bar starts with opening a +bar+ block. You can have
1283 multiple bar blocks to use different settings for different outputs (monitors):
1284
1285 *Example*:
1286 ---------------------------
1287 bar {
1288 status_command i3status
1289 }
1290 ---------------------------
1291
1292 === i3bar command
1293
1294 By default i3 will just pass +i3bar+ and let your shell handle the execution,
1295 searching your +$PATH+ for a correct version.
1296 If you have a different +i3bar+ somewhere or the binary is not in your +$PATH+ you can
1297 tell i3 what to execute.
1298
1299 The specified command will be passed to +sh -c+, so you can use globbing and
1300 have to have correct quoting etc.
1301
1302 *Syntax*:
1303 -----------------------
1304 i3bar_command <command>
1305 -----------------------
1306
1307 *Example*:
1308 -------------------------------------------------
1309 bar {
1310 i3bar_command /home/user/bin/i3bar
1311 }
1312 -------------------------------------------------
1313
1314 [[status_command]]
1315 === Statusline command
1316
1317 i3bar can run a program and display every line of its +stdout+ output on the
1318 right hand side of the bar. This is useful to display system information like
1319 your current IP address, battery status or date/time.
1320
1321 The specified command will be passed to +sh -c+, so you can use globbing and
1322 have to have correct quoting etc. Note that for signal handling, depending on
1323 your shell (users of dash(1) are known to be affected), you have to use the
1324 shell’s exec command so that signals are passed to your program, not to the
1325 shell.
1326
1327 *Syntax*:
1328 ------------------------
1329 status_command <command>
1330 ------------------------
1331
1332 *Example*:
1333 -------------------------------------------------
1334 bar {
1335 status_command i3status --config ~/.i3status.conf
1336
1337 # For dash(1) users who want signal handling to work:
1338 status_command exec ~/.bin/my_status_command
1339 }
1340 -------------------------------------------------
1341
1342 === Display mode
1343
1344 You can either have i3bar be visible permanently at one edge of the screen
1345 (+dock+ mode) or make it show up when you press your modifier key (+hide+ mode).
1346 It is also possible to force i3bar to always stay hidden (+invisible+
1347 mode). The modifier key can be configured using the +modifier+ option.
1348
1349 The mode option can be changed during runtime through the +bar mode+ command.
1350 On reload the mode will be reverted to its configured value.
1351
1352 The hide mode maximizes screen space that can be used for actual windows. Also,
1353 i3bar sends the +SIGSTOP+ and +SIGCONT+ signals to the statusline process to
1354 save battery power.
1355
1356 Invisible mode allows to permanently maximize screen space, as the bar is never
1357 shown. Thus, you can configure i3bar to not disturb you by popping up because
1358 of an urgency hint or because the modifier key is pressed.
1359
1360 In order to control whether i3bar is hidden or shown in hide mode, there exists
1361 the hidden_state option, which has no effect in dock mode or invisible mode. It
1362 indicates the current hidden_state of the bar: (1) The bar acts like in normal
1363 hide mode, it is hidden and is only unhidden in case of urgency hints or by
1364 pressing the modifier key (+hide+ state), or (2) it is drawn on top of the
1365 currently visible workspace (+show+ state).
1366
1367 Like the mode, the hidden_state can also be controlled through i3, this can be
1368 done by using the +bar hidden_state+ command.
1369
1370 The default mode is dock mode; in hide mode, the default modifier is Mod4 (usually
1371 the windows key). The default value for the hidden_state is hide.
1372
1373 *Syntax*:
1374 -------------------------
1375 mode dock|hide|invisible
1376 hidden_state hide|show
1377 modifier <Modifier>|none
1378 ------------------------
1379
1380 *Example*:
1381 ----------------
1382 bar {
1383 mode hide
1384 hidden_state hide
1385 modifier Mod1
1386 }
1387 ----------------
1388
1389 Available modifiers are Mod1-Mod5, Shift, Control (see +xmodmap(1)+). You can
1390 also use "none" if you don't want any modifier to trigger this behavior.
1391
1392 === Mouse button commands
1393
1394 Specifies a command to run when a button was pressed on i3bar to override the
1395 default behavior. This is useful, e.g., for disabling the scroll wheel action
1396 or running scripts that implement custom behavior for these buttons.
1397
1398 A button is always named +button<n>+, where 1 to 5 are default buttons as follows and higher
1399 numbers can be special buttons on devices offering more buttons:
1400
1401 button1::
1402 Left mouse button.
1403 button2::
1404 Middle mouse button.
1405 button3::
1406 Right mouse button.
1407 button4::
1408 Scroll wheel up.
1409 button5::
1410 Scroll wheel down.
1411 button6::
1412 Scroll wheel right.
1413 button7::
1414 Scroll wheel left.
1415
1416
1417 Please note that the old +wheel_up_cmd+ and +wheel_down_cmd+ commands are deprecated
1418 and will be removed in a future release. We strongly recommend using the more general
1419 +bindsym+ with +button4+ and +button5+ instead.
1420
1421 *Syntax*:
1422 ----------------------------
1423 bindsym [--release] button<n> <command>
1424 ----------------------------
1425
1426 *Example*:
1427 ---------------------------------------------------------
1428 bar {
1429 # disable clicking on workspace buttons
1430 bindsym button1 nop
1431 # Take a screenshot by right clicking on the bar
1432 bindsym --release button3 exec --no-startup-id import /tmp/latest-screenshot.png
1433 # execute custom script when scrolling downwards
1434 bindsym button5 exec ~/.i3/scripts/custom_wheel_down
1435 }
1436 ---------------------------------------------------------
1437
1438 === Bar ID
1439
1440 Specifies the bar ID for the configured bar instance. If this option is missing,
1441 the ID is set to 'bar-x', where x corresponds to the position of the embedding
1442 bar block in the config file ('bar-0', 'bar-1', ...).
1443
1444 *Syntax*:
1445 ---------------------
1446 id <bar_id>
1447 ---------------------
1448
1449 *Example*:
1450 ---------------------
1451 bar {
1452 id bar-1
1453 }
1454 ---------------------
1455
1456 [[i3bar_position]]
1457 === Position
1458
1459 This option determines in which edge of the screen i3bar should show up.
1460
1461 The default is bottom.
1462
1463 *Syntax*:
1464 -------------------
1465 position top|bottom
1466 -------------------
1467
1468 *Example*:
1469 ---------------------
1470 bar {
1471 position top
1472 }
1473 ---------------------
1474
1475 === Output(s)
1476
1477 You can restrict i3bar to one or more outputs (monitors). The default is to
1478 handle all outputs. Restricting the outputs is useful for using different
1479 options for different outputs by using multiple 'bar' blocks.
1480
1481 To make a particular i3bar instance handle multiple outputs, specify the output
1482 directive multiple times.
1483
1484 *Syntax*:
1485 ---------------
1486 output primary|<output>
1487 ---------------
1488
1489 *Example*:
1490 -------------------------------
1491 # big monitor: everything
1492 bar {
1493 # The display is connected either via HDMI or via DisplayPort
1494 output HDMI2
1495 output DP2
1496 status_command i3status
1497 }
1498
1499 # laptop monitor: bright colors and i3status with less modules.
1500 bar {
1501 output LVDS1
1502 status_command i3status --config ~/.i3status-small.conf
1503 colors {
1504 background #000000
1505 statusline #ffffff
1506 }
1507 }
1508
1509 # show bar on the primary monitor and on HDMI2
1510 bar {
1511 output primary
1512 output HDMI2
1513 status_command i3status
1514 }
1515
1516 -------------------------------
1517 Note that you might not have a primary output configured yet. To do so, run:
1518 -------------------------
1519 xrandr --output <output> --primary
1520 -------------------------
1521
1522 === Tray output
1523
1524 i3bar by default provides a system tray area where programs such as
1525 NetworkManager, VLC, Pidgin, etc. can place little icons.
1526
1527 You can configure on which output (monitor) the icons should be displayed or
1528 you can turn off the functionality entirely.
1529
1530 You can use multiple +tray_output+ directives in your config to specify a list
1531 of outputs on which you want the tray to appear. The first available output in
1532 that list as defined by the order of the directives will be used for the tray
1533 output.
1534
1535 *Syntax*:
1536 ---------------------------------
1537 tray_output none|primary|<output>
1538 ---------------------------------
1539
1540 *Example*:
1541 -------------------------
1542 # disable system tray
1543 bar {
1544 tray_output none
1545 }
1546
1547 # show tray icons on the primary monitor
1548 bar {
1549 tray_output primary
1550 }
1551
1552 # show tray icons on the big monitor
1553 bar {
1554 tray_output HDMI2
1555 }
1556 -------------------------
1557
1558 Note that you might not have a primary output configured yet. To do so, run:
1559 -------------------------
1560 xrandr --output <output> --primary
1561 -------------------------
1562
1563 Note that when you use multiple bar configuration blocks, either specify
1564 `tray_output primary` in all of them or explicitly specify `tray_output none`
1565 in bars which should not display the tray, otherwise the different instances
1566 might race each other in trying to display tray icons.
1567
1568 === Tray padding
1569
1570 The tray is shown on the right-hand side of the bar. By default, a padding of 2
1571 pixels is used for the upper, lower and right-hand side of the tray area and
1572 between the individual icons.
1573
1574 *Syntax*:
1575 -------------------------
1576 tray_padding <px> [px]
1577 -------------------------
1578
1579 *Example*:
1580 -------------------------
1581 # Obey Fitts's law
1582 tray_padding 0
1583 -------------------------
1584
1585 === Font
1586
1587 Specifies the font to be used in the bar. See <<fonts>>.
1588
1589 *Syntax*:
1590 ---------------------
1591 font <font>
1592 ---------------------
1593
1594 *Example*:
1595 --------------------------------------------------------------
1596 bar {
1597 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
1598 font pango:DejaVu Sans Mono 10
1599 }
1600 --------------------------------------------------------------
1601
1602 === Custom separator symbol
1603
1604 Specifies a custom symbol to be used for the separator as opposed to the vertical,
1605 one pixel thick separator.
1606
1607 *Syntax*:
1608 -------------------------
1609 separator_symbol <symbol>
1610 -------------------------
1611
1612 *Example*:
1613 ------------------------
1614 bar {
1615 separator_symbol ":|:"
1616 }
1617 ------------------------
1618
1619 === Workspace buttons
1620
1621 Specifies whether workspace buttons should be shown or not. This is useful if
1622 you want to display a statusline-only bar containing additional information.
1623
1624 The default is to show workspace buttons.
1625
1626 *Syntax*:
1627 ------------------------
1628 workspace_buttons yes|no
1629 ------------------------
1630
1631 *Example*:
1632 ------------------------
1633 bar {
1634 workspace_buttons no
1635 }
1636 ------------------------
1637
1638 === Minimal width for workspace buttons
1639
1640 By default, the width a workspace button is determined by the width of the text
1641 showing the workspace name. If the name is too short (say, one letter), then the
1642 workspace button may look too small.
1643
1644 This option specifies the minimum width for workspace buttons. If the name of
1645 a workspace is too short to cover the button, an additional padding is added on
1646 both sides of the button so that the text is centered.
1647
1648 The default value of zero means that no additional padding is added.
1649
1650 The setting also applies to the current binding mode indicator.
1651
1652 Note that the specified pixels refer to logical pixels, which may translate
1653 into more pixels on HiDPI displays.
1654
1655 *Syntax*:
1656 ------------------------
1657 workspace_min_width <px> [px]
1658 ------------------------
1659
1660 *Example*:
1661 ------------------------
1662 bar {
1663 workspace_min_width 40
1664 }
1665 ------------------------
1666
1667 === Strip workspace numbers/name
1668
1669 Specifies whether workspace numbers should be displayed within the workspace
1670 buttons. This is useful if you want to have a named workspace that stays in
1671 order on the bar according to its number without displaying the number prefix.
1672
1673 When +strip_workspace_numbers+ is set to +yes+, any workspace that has a name of
1674 the form "[n][:][NAME]" will display only the name. You could use this, for
1675 instance, to display Roman numerals rather than digits by naming your
1676 workspaces to "1:I", "2:II", "3:III", "4:IV", ...
1677
1678 When +strip_workspace_name+ is set to +yes+, any workspace that has a name of
1679 the form "[n][:][NAME]" will display only the number.
1680
1681 The default is to display the full name within the workspace button. Be aware
1682 that the colon in the workspace name is optional, so `[n][NAME]` will also
1683 have the the workspace name and number stripped correctly.
1684
1685 *Syntax*:
1686 ------------------------------
1687 strip_workspace_numbers yes|no
1688 strip_workspace_name yes|no
1689 ------------------------------
1690
1691 *Example*:
1692 ----------------------------
1693 bar {
1694 strip_workspace_numbers yes
1695 }
1696 ----------------------------
1697
1698 === Binding Mode indicator
1699
1700 Specifies whether the current binding mode indicator should be shown or not.
1701 This is useful if you want to hide the workspace buttons but still be able
1702 to see the current binding mode indicator. See <<binding_modes>> to learn what
1703 modes are and how to use them.
1704
1705 The default is to show the mode indicator.
1706
1707 *Syntax*:
1708 -----------------------------
1709 binding_mode_indicator yes|no
1710 -----------------------------
1711
1712 *Example*:
1713 -----------------------------
1714 bar {
1715 binding_mode_indicator no
1716 }
1717 -----------------------------
1718
1719 === Bar Height
1720
1721 Defines the height of the bar in pixels. If this value is not set, it is calculated automatically.
1722 Manually setting a value can be useful, e.g., when using top and/or border bottoms on status blocks.
1723
1724 *Syntax*:
1725 --------------
1726 height <px>
1727 --------------
1728
1729 *Example*:
1730 --------------
1731 bar {
1732 height 25
1733 }
1734 --------------
1735
1736 === Colors
1737
1738 As with i3, colors are in HTML hex format (#rrggbb). The following colors can
1739 be configured at the moment:
1740
1741 background::
1742 Background color of the bar.
1743 statusline::
1744 Text color to be used for the statusline.
1745 separator::
1746 Text color to be used for the separator.
1747 focused_background::
1748 Background color of the bar on the currently focused monitor output. If
1749 not used, the color will be taken from +background+.
1750 focused_statusline::
1751 Text color to be used for the statusline on the currently focused
1752 monitor output. If not used, the color will be taken from +statusline+.
1753 focused_separator::
1754 Text color to be used for the separator on the currently focused
1755 monitor output. If not used, the color will be taken from +separator+.
1756 focused_workspace::
1757 Border, background and text color for a workspace button when the workspace
1758 has focus.
1759 active_workspace::
1760 Border, background and text color for a workspace button when the workspace
1761 is active (visible) on some output, but the focus is on another one.
1762 You can only tell this apart from the focused workspace when you are
1763 using multiple monitors.
1764 inactive_workspace::
1765 Border, background and text color for a workspace button when the workspace
1766 does not have focus and is not active (visible) on any output. This
1767 will be the case for most workspaces.
1768 urgent_workspace::
1769 Border, background and text color for a workspace button when the workspace
1770 contains a window with the urgency hint set.
1771 binding_mode::
1772 Border, background and text color for the binding mode indicator. If not used,
1773 the colors will be taken from +urgent_workspace+.
1774
1775 *Syntax*:
1776 ----------------------------------------
1777 colors {
1778 background <color>
1779 statusline <color>
1780 separator <color>
1781
1782 <colorclass> <border> <background> <text>
1783 }
1784 ----------------------------------------
1785
1786 *Example (default colors)*:
1787 --------------------------------------
1788 bar {
1789 colors {
1790 background #000000
1791 statusline #ffffff
1792 separator #666666
1793
1794 focused_workspace #4c7899 #285577 #ffffff
1795 active_workspace #333333 #5f676a #ffffff
1796 inactive_workspace #333333 #222222 #888888
1797 urgent_workspace #2f343a #900000 #ffffff
1798 binding_mode #2f343a #900000 #ffffff
1799 }
1800 }
1801 --------------------------------------
1802
1803 === Transparency
1804
1805 i3bar can support transparency by passing the +--transparency+ flag in the
1806 configuration:
1807
1808 *Syntax*:
1809 --------------------------------------
1810 bar {
1811 i3bar_command i3bar --transparency
1812 }
1813 --------------------------------------
1814
1815 In the i3bar color configuration and i3bar status block color attribute you can
1816 then use colors in the RGBA format, i.e. the last two (hexadecimal) digits
1817 specify the opacity. For example, +#00000000+ will be completely transparent,
1818 while +#000000FF+ will be a fully opaque black (the same as +#000000+).
1819
1820 Please note that due to the way the tray specification works, enabling this
1821 flag will cause all tray icons to have a transparent background.
1822
1823 [[list_of_commands]]
1824 == List of commands
1825
1826 Commands are what you bind to specific keypresses. You can also issue commands
1827 at runtime without pressing a key by using the IPC interface. An easy way to
1828 do this is to use the +i3-msg+ utility:
1829
1830 *Example*:
1831 --------------------------
1832 # execute this on your shell to make the current container borderless
1833 i3-msg border none
1834 --------------------------
1835
1836 [[command_chaining]]
1837
1838 Commands can be chained by using +;+ (a semicolon). So, to move a window to a
1839 specific workspace and immediately switch to that workspace, you can configure
1840 the following keybinding:
1841
1842 *Example*:
1843 --------------------------------------------------------
1844 bindsym $mod+x move container to workspace 3; workspace 3
1845 --------------------------------------------------------
1846
1847 [[command_criteria]]
1848
1849 Furthermore, you can change the scope of a command - that is, which containers
1850 should be affected by that command, by using various criteria. The criteria
1851 are specified before any command in a pair of square brackets and are separated
1852 by space.
1853
1854 When using multiple commands, separate them by using a +,+ (a comma) instead of
1855 a semicolon. Criteria apply only until the next semicolon, so if you use a
1856 semicolon to separate commands, only the first one will be executed for the
1857 matched window(s).
1858
1859 *Example*:
1860 ------------------------------------
1861 # if you want to kill all windows which have the class Firefox, use:
1862 bindsym $mod+x [class="Firefox"] kill
1863
1864 # same thing, but case-insensitive
1865 bindsym $mod+x [class="(?i)firefox"] kill
1866
1867 # kill only the About dialog from Firefox
1868 bindsym $mod+x [class="Firefox" window_role="About"] kill
1869
1870 # enable floating mode and move container to workspace 4
1871 for_window [class="^evil-app$"] floating enable, move container to workspace 4
1872
1873 # move all floating windows to the scratchpad
1874 bindsym $mod+x [floating] move scratchpad
1875 ------------------------------------
1876
1877 The criteria which are currently implemented are:
1878
1879 class::
1880 Compares the window class (the second part of WM_CLASS). Use the
1881 special value +\_\_focused__+ to match all windows having the same window
1882 class as the currently focused window.
1883 instance::
1884 Compares the window instance (the first part of WM_CLASS). Use the
1885 special value +\_\_focused__+ to match all windows having the same window
1886 instance as the currently focused window.
1887 window_role::
1888 Compares the window role (WM_WINDOW_ROLE). Use the special value
1889 +\_\_focused__+ to match all windows having the same window role as the
1890 currently focused window.
1891 window_type::
1892 Compare the window type (_NET_WM_WINDOW_TYPE). Possible values are
1893 +normal+, +dialog+, +utility+, +toolbar+, +splash+, +menu+, +dropdown_menu+,
1894 +popup_menu+, +tooltip+ and +notification+.
1895 id::
1896 Compares the X11 window ID, which you can get via +xwininfo+ for example.
1897 title::
1898 Compares the X11 window title (\_NET_WM_NAME or WM_NAME as fallback).
1899 Use the special value +\_\_focused__+ to match all windows having the
1900 same window title as the currently focused window.
1901 urgent::
1902 Compares the urgent state of the window. Can be "latest" or "oldest".
1903 Matches the latest or oldest urgent window, respectively.
1904 (The following aliases are also available: newest, last, recent, first)
1905 workspace::
1906 Compares the workspace name of the workspace the window belongs to. Use
1907 the special value +\_\_focused__+ to match all windows in the currently
1908 focused workspace.
1909 con_mark::
1910 Compares the marks set for this container, see <<vim_like_marks>>. A
1911 match is made if any of the container's marks matches the specified
1912 mark.
1913 con_id::
1914 Compares the i3-internal container ID, which you can get via the IPC
1915 interface. Handy for scripting. Use the special value +\_\_focused__+
1916 to match only the currently focused window.
1917 floating::
1918 Only matches floating windows. This criterion requires no value.
1919 floating_from::
1920 Like +floating+ but this criterion takes two possible values: "auto"
1921 and "user". With "auto", only windows that were automatically opened as
1922 floating are matched. With "user", only windows that the user made
1923 floating are matched.
1924 tiling::
1925 Only matches tiling windows. This criterion requires no value.
1926 tiling_from::
1927 Like +tiling+ but this criterion takes two possible values: "auto" and
1928 "user". With "auto", only windows that were automatically opened as
1929 tiling are matched. With "user", only windows that the user made tiling
1930 are matched.
1931
1932 The criteria +class+, +instance+, +role+, +title+, +workspace+ and +mark+ are
1933 actually regular expressions (PCRE). See +pcresyntax(3)+ or +perldoc perlre+ for
1934 information on how to use them.
1935
1936 [[exec]]
1937 === Executing applications (exec)
1938
1939 What good is a window manager if you can’t actually start any applications?
1940 The exec command starts an application by passing the command you specify to a
1941 shell. This implies that you can use globbing (wildcards) and programs will be
1942 searched in your +$PATH+.
1943
1944 See <<command_chaining>> for details on the special meaning of +;+ (semicolon)
1945 and +,+ (comma): they chain commands together in i3, so you need to use quoted
1946 strings (as shown in <<exec_quoting>>) if they appear in your command.
1947
1948 *Syntax*:
1949 --------------------------------
1950 exec [--no-startup-id] <command>
1951 --------------------------------
1952
1953 *Example*:
1954 ------------------------------
1955 # Start the GIMP
1956 bindsym $mod+g exec gimp
1957
1958 # Start the terminal emulator urxvt which is not yet startup-notification-aware
1959 bindsym $mod+Return exec --no-startup-id urxvt
1960 ------------------------------
1961
1962 The +--no-startup-id+ parameter disables startup-notification support for this
1963 particular exec command. With startup-notification, i3 can make sure that a
1964 window appears on the workspace on which you used the exec command. Also, it
1965 will change the X11 cursor to +watch+ (a clock) while the application is
1966 launching. So, if an application is not startup-notification aware (most GTK
1967 and Qt using applications seem to be, though), you will end up with a watch
1968 cursor for 60 seconds.
1969
1970 [[exec_quoting]]
1971 If the command to be executed contains a +;+ (semicolon) and/or a +,+ (comma),
1972 the entire command must be quoted. For example, to have a keybinding for the
1973 shell command +notify-send Hello, i3+, you would add an entry to your
1974 configuration file like this:
1975
1976 *Example*:
1977 ------------------------------
1978 # Execute a command with a comma in it
1979 bindsym $mod+p exec "notify-send Hello, i3"
1980 ------------------------------
1981
1982 If however a command with a comma and/or semicolon itself requires quotes, you
1983 must escape the internal quotation marks with double backslashes, like this:
1984
1985 *Example*:
1986 ------------------------------
1987 # Execute a command with a comma, semicolon and internal quotes
1988 bindsym $mod+p exec "notify-send \\"Hello, i3; from $USER\\""
1989 ------------------------------
1990
1991 === Splitting containers
1992
1993 The split command makes the current window a split container. Split containers
1994 can contain multiple windows. Depending on the layout of the split container,
1995 new windows get placed to the right of the current one (splith) or new windows
1996 get placed below the current one (splitv).
1997
1998 If you apply this command to a split container with the same orientation,
1999 nothing will happen. If you use a different orientation, the split container’s
2000 orientation will be changed (if it does not have more than one window).
2001 The +toggle+ option will toggle the orientation of the split container if it
2002 contains a single window. Otherwise it makes the current window a split
2003 container with opposite orientation compared to the parent container.
2004 Use +layout toggle split+ to change the layout of any split container from
2005 splitv to splith or vice-versa. You can also define a custom sequence of layouts
2006 to cycle through with +layout toggle+, see <<manipulating_layout>>.
2007
2008 *Syntax*:
2009 --------------------------------
2010 split vertical|horizontal|toggle
2011 --------------------------------
2012
2013 *Example*:
2014 -------------------------------
2015 bindsym $mod+v split vertical
2016 bindsym $mod+h split horizontal
2017 bindsym $mod+t split toggle
2018 -------------------------------
2019
2020 [[manipulating_layout]]
2021 === Manipulating layout
2022
2023 Use +layout toggle split+, +layout stacking+, +layout tabbed+, +layout splitv+
2024 or +layout splith+ to change the current container layout to splith/splitv,
2025 stacking, tabbed layout, splitv or splith, respectively.
2026
2027 Specify up to four layouts after +layout toggle+ to cycle through them. Every
2028 time the command is executed, the layout specified after the currently active
2029 one will be applied. If the currently active layout is not in the list, the
2030 first layout in the list will be activated.
2031
2032 To make the current window (!) fullscreen, use +fullscreen enable+ (or
2033 +fullscreen enable global+ for the global mode), to leave either fullscreen
2034 mode use +fullscreen disable+, and to toggle between these two states use
2035 +fullscreen toggle+ (or +fullscreen toggle global+).
2036
2037 Likewise, to make the current window floating (or tiling again) use +floating
2038 enable+ respectively +floating disable+ (or +floating toggle+):
2039
2040 *Syntax*:
2041 --------------------------------------------
2042 layout default|tabbed|stacking|splitv|splith
2043 layout toggle [split|all]
2044 layout toggle [split|tabbed|stacking|splitv|splith] [split|tabbed|stacking|splitv|splith]…
2045 --------------------------------------------
2046
2047 *Examples*:
2048 --------------
2049 bindsym $mod+s layout stacking
2050 bindsym $mod+l layout toggle split
2051 bindsym $mod+w layout tabbed
2052
2053 # Toggle between stacking/tabbed/split:
2054 bindsym $mod+x layout toggle
2055
2056 # Toggle between stacking/tabbed/splith/splitv:
2057 bindsym $mod+x layout toggle all
2058
2059 # Toggle between stacking/tabbed/splith:
2060 bindsym $mod+x layout toggle stacking tabbed splith
2061
2062 # Toggle between splitv/tabbed
2063 bindsym $mod+x layout toggle splitv tabbed
2064
2065 # Toggle between last split layout/tabbed/stacking
2066 bindsym $mod+x layout toggle split tabbed stacking
2067
2068 # Toggle fullscreen
2069 bindsym $mod+f fullscreen toggle
2070
2071 # Toggle floating/tiling
2072 bindsym $mod+t floating toggle
2073 --------------
2074
2075 [[_focusing_moving_containers]]
2076 === Focusing containers
2077
2078 To change focus, you can use the +focus+ command. The following options are
2079 available:
2080
2081 <criteria>::
2082 Sets focus to the container that matches the specified criteria.
2083 See <<command_criteria>>.
2084 left|right|up|down::
2085 Sets focus to the nearest container in the given direction.
2086 parent::
2087 Sets focus to the parent container of the current container.
2088 child::
2089 The opposite of +focus parent+, sets the focus to the last focused
2090 child container.
2091 next|prev::
2092 Automatically sets focus to the adjacent container. If +sibling+ is
2093 specified, the command will focus the exact sibling container,
2094 including non-leaf containers like split containers. Otherwise, it is
2095 an automatic version of +focus left|right|up|down+ in the orientation
2096 of the parent container.
2097 floating::
2098 Sets focus to the last focused floating container.
2099 tiling::
2100 Sets focus to the last focused tiling container.
2101 mode_toggle::
2102 Toggles between floating/tiling containers.
2103 output::
2104 Followed by a direction or an output name, this will focus the
2105 corresponding output.
2106
2107 *Syntax*:
2108 ----------------------------------------------
2109 <criteria> focus
2110 focus left|right|down|up
2111 focus parent|child|floating|tiling|mode_toggle
2112 focus next|prev [sibling]
2113 focus output left|right|up|down|primary|<output>
2114 ----------------------------------------------
2115
2116 *Examples*:
2117 -------------------------------------------------
2118 # Focus firefox
2119 bindsym $mod+F1 [class="Firefox"] focus
2120
2121 # Focus container on the left, bottom, top, right
2122 bindsym $mod+j focus left
2123 bindsym $mod+k focus down
2124 bindsym $mod+l focus up
2125 bindsym $mod+semicolon focus right
2126
2127 # Focus parent container
2128 bindsym $mod+u focus parent
2129
2130 # Focus last floating/tiling container
2131 bindsym $mod+g focus mode_toggle
2132
2133 # Focus the output right to the current one
2134 bindsym $mod+x focus output right
2135
2136 # Focus the big output
2137 bindsym $mod+x focus output HDMI-2
2138
2139 # Focus the primary output
2140 bindsym $mod+x focus output primary
2141 -------------------------------------------------
2142
2143 Note that you might not have a primary output configured yet. To do so, run:
2144 -------------------------
2145 xrandr --output <output> --primary
2146 -------------------------
2147
2148 === Moving containers
2149
2150 Use the +move+ command to move a container.
2151
2152 *Syntax*:
2153 -----------------------------------------------------
2154 # Moves the container into the given direction.
2155 # The optional pixel argument specifies how far the
2156 # container should be moved if it is floating and
2157 # defaults to 10 pixels.
2158 move <left|right|down|up> [<px> px]
2159
2160 # Moves the container to the specified pos_x and pos_y
2161 # coordinates on the screen.
2162 move position <pos_x> [px] <pos_y> [px]
2163
2164 # Moves the container to the center of the screen.
2165 # If 'absolute' is used, it is moved to the center of
2166 # all outputs.
2167 move [absolute] position center
2168
2169 # Moves the container to the current position of the
2170 # mouse cursor. Only affects floating containers.
2171 move position mouse
2172 -----------------------------------------------------
2173
2174 *Examples*:
2175 -------------------------------------------------------
2176 # Move container to the left, bottom, top, right
2177 bindsym $mod+j move left
2178 bindsym $mod+k move down
2179 bindsym $mod+l move up
2180 bindsym $mod+semicolon move right
2181
2182 # Move container, but make floating containers
2183 # move more than the default
2184 bindsym $mod+j move left 20 px
2185
2186 # Move floating container to the center of all outputs
2187 bindsym $mod+c move absolute position center
2188
2189 # Move container to the current position of the cursor
2190 bindsym $mod+m move position mouse
2191 -------------------------------------------------------
2192
2193 === Swapping containers
2194
2195 Two containers can be swapped (i.e., move to each other's position) by using
2196 the +swap+ command. They will assume the position and geometry of the container
2197 they are swapped with.
2198
2199 The first container to participate in the swapping can be selected through the
2200 normal command criteria process with the focused window being the usual
2201 fallback if no criteria are specified. The second container can be selected
2202 using one of the following methods:
2203
2204 +id+:: The X11 window ID of a client window.
2205 +con_id+:: The i3 container ID of a container.
2206 +mark+:: A container with the specified mark, see <<vim_like_marks>>.
2207
2208 Note that swapping does not work with all containers. Most notably, swapping
2209 containers that have a parent-child relationship to one another does not work.
2210
2211 *Syntax*:
2212 ----------------------------------------
2213 swap container with id|con_id|mark <arg>
2214 ----------------------------------------
2215
2216 *Examples*:
2217 -----------------------------------------------------------------
2218 # Swaps the focused container with the container marked »swapee«.
2219 swap container with mark swapee
2220
2221 # Swaps container marked »A« and »B«
2222 [con_mark="^A$"] swap container with mark B
2223 -----------------------------------------------------------------
2224
2225 === Sticky floating windows
2226
2227 If you want a window to stick to the glass, i.e., have it stay on screen even
2228 if you switch to another workspace, you can use the +sticky+ command. For
2229 example, this can be useful for notepads, a media player or a video chat
2230 window.
2231
2232 Note that while any window can be made sticky through this command, it will
2233 only take effect if the window is floating.
2234
2235 *Syntax*:
2236 ----------------------------
2237 sticky enable|disable|toggle
2238 ----------------------------
2239
2240 *Examples*:
2241 ------------------------------------------------------
2242 # make a terminal sticky that was started as a notepad
2243 for_window [instance=notepad] sticky enable
2244 ------------------------------------------------------
2245
2246 === Changing (named) workspaces/moving to workspaces
2247
2248 To change to a specific workspace, use the +workspace+ command, followed by the
2249 number or name of the workspace. Pass the optional flag
2250 +--no-auto-back-and-forth+ to disable <<workspace_auto_back_and_forth>> for this
2251 specific call only.
2252
2253 To move containers to specific workspaces, use +move container to workspace+.
2254
2255 You can also switch to the next and previous workspace with the commands
2256 +workspace next+ and +workspace prev+, which is handy, for example, if you have
2257 workspace 1, 3, 4 and 9 and you want to cycle through them with a single key
2258 combination. To restrict those to the current output, use +workspace
2259 next_on_output+ and +workspace prev_on_output+. Similarly, you can use +move
2260 container to workspace next+, +move container to workspace prev+ to move a
2261 container to the next/previous workspace and +move container to workspace current+
2262 (the last one makes sense only when used with criteria).
2263
2264 +workspace next+ cycles through either numbered or named workspaces. But when it
2265 reaches the last numbered/named workspace, it looks for named workspaces after
2266 exhausting numbered ones and looks for numbered ones after exhausting named ones.
2267
2268 See <<move_to_outputs>> for how to move a container/workspace to a different
2269 RandR output.
2270
2271 Workspace names are parsed as
2272 https://developer.gnome.org/pango/stable/pango-Markup.html[Pango markup]
2273 by i3bar.
2274
2275 [[back_and_forth]]
2276 To switch back to the previously focused workspace, use +workspace
2277 back_and_forth+; likewise, you can move containers to the previously focused
2278 workspace using +move container to workspace back_and_forth+.
2279
2280 *Syntax*:
2281 --------------------------------------------------------------------------------
2282 workspace next|prev|next_on_output|prev_on_output
2283 workspace back_and_forth
2284 workspace [--no-auto-back-and-forth] <name>
2285 workspace [--no-auto-back-and-forth] number <name>
2286
2287 move [--no-auto-back-and-forth] [window|container] [to] workspace <name>
2288 move [--no-auto-back-and-forth] [window|container] [to] workspace number <name>
2289 move [window|container] [to] workspace prev|next|current
2290 --------------------------------------------------------------------------------
2291
2292 *Examples*:
2293 -------------------------
2294 bindsym $mod+1 workspace 1
2295 bindsym $mod+2 workspace 2
2296 bindsym $mod+3 workspace 3:<span foreground="red">vim</span>
2297 ...
2298
2299 bindsym $mod+Shift+1 move container to workspace 1
2300 bindsym $mod+Shift+2 move container to workspace 2
2301 ...
2302
2303 # switch between the current and the previously focused one
2304 bindsym $mod+b workspace back_and_forth
2305 bindsym $mod+Shift+b move container to workspace back_and_forth
2306
2307 # move the whole workspace to the next output
2308 bindsym $mod+x move workspace to output right
2309
2310 # move firefox to current workspace
2311 bindsym $mod+F1 [class="Firefox"] move workspace current
2312 -------------------------
2313
2314 ==== Named workspaces
2315
2316 Workspaces are identified by their name. So, instead of using numbers in the
2317 workspace command, you can use an arbitrary name:
2318
2319 *Example*:
2320 -------------------------
2321 bindsym $mod+1 workspace mail
2322 ...
2323 -------------------------
2324
2325 If you want the workspace to have a number *and* a name, just prefix the
2326 number, like this:
2327
2328 *Example*:
2329 -------------------------
2330 bindsym $mod+1 workspace 1: mail
2331 bindsym $mod+2 workspace 2: www
2332 ...
2333 -------------------------
2334
2335 Note that the workspace will really be named "1: mail". i3 treats workspace
2336 names beginning with a number in a slightly special way. Normally, named
2337 workspaces are ordered the way they appeared. When they start with a number, i3
2338 will order them numerically. Also, you will be able to use +workspace number 1+
2339 to switch to the workspace which begins with number 1, regardless of which name
2340 it has. This is useful in case you are changing the workspace’s name
2341 dynamically. To combine both commands you can use +workspace number 1: mail+ to
2342 specify a default name if there's currently no workspace starting with a "1".
2343
2344 ==== Renaming workspaces
2345
2346 You can rename workspaces. This might be useful to start with the default
2347 numbered workspaces, do your work, and rename the workspaces afterwards to
2348 reflect what’s actually on them. You can also omit the old name to rename
2349 the currently focused workspace. This is handy if you want to use the
2350 rename command with +i3-input+.
2351
2352 *Syntax*:
2353 ----------------------------------------------------
2354 rename workspace <old_name> to <new_name>
2355 rename workspace to <new_name>
2356 ----------------------------------------------------
2357
2358 *Examples*:
2359 --------------------------------------------------------------------------
2360 i3-msg 'rename workspace 5 to 6'
2361 i3-msg 'rename workspace 1 to "1: www"'
2362 i3-msg 'rename workspace "1: www" to "10: www"'
2363 i3-msg 'rename workspace to "2: mail"'
2364 bindsym $mod+r exec i3-input -F 'rename workspace to "%s"' -P 'New name: '
2365 --------------------------------------------------------------------------
2366
2367 If you want to rename workspaces on demand while keeping the navigation stable,
2368 you can use a setup like this:
2369
2370 *Example*:
2371 -------------------------
2372 bindsym $mod+1 workspace number "1: www"
2373 bindsym $mod+2 workspace number "2: mail"
2374 ...
2375 -------------------------
2376
2377 If a workspace does not exist, the command +workspace number "1: mail"+ will
2378 create workspace "1: mail".
2379
2380 If a workspace with number 1 does already exist, the command will switch to this
2381 workspace and ignore the text part. So even when the workspace has been renamed
2382 to "1: web", the above command will still switch to it.
2383
2384 === Moving workspaces to a different screen
2385
2386 See <<move_to_outputs>> for how to move a container/workspace to a different
2387 RandR output.
2388
2389 [[move_to_outputs]]
2390 === [[_moving_containers_workspaces_to_randr_outputs]]Moving containers/workspaces to RandR outputs
2391
2392 To move a container to another RandR output (addressed by names like +LVDS1+ or
2393 +VGA1+) or to a RandR output identified by a specific direction (like +left+,
2394 +right+, +up+ or +down+), there are two commands:
2395
2396 *Syntax*:
2397 ------------------------------------------------------------
2398 move container to output left|right|down|up|current|primary|<output>
2399 move workspace to output left|right|down|up|current|primary|<output>
2400 ------------------------------------------------------------
2401
2402 *Examples*:
2403 --------------------------------------------------------
2404 # Move the current workspace to the next output
2405 # (effectively toggles when you only have two outputs)
2406 bindsym $mod+x move workspace to output right
2407
2408 # Put this window on the presentation output.
2409 bindsym $mod+x move container to output VGA1
2410
2411 # Put this window on the primary output.
2412 bindsym $mod+x move container to output primary
2413 --------------------------------------------------------
2414
2415 Note that you might not have a primary output configured yet. To do so, run:
2416 -------------------------
2417 xrandr --output <output> --primary
2418 -------------------------
2419
2420 === Moving containers/windows to marks
2421
2422 To move a container to another container with a specific mark (see <<vim_like_marks>>),
2423 you can use the following command.
2424
2425 The window will be moved right after the marked container in the tree, i.e., it ends up
2426 in the same position as if you had opened a new window when the marked container was
2427 focused. If the mark is on a split container, the window will appear as a new child
2428 after the currently focused child within that container.
2429
2430 *Syntax*:
2431 ------------------------------------
2432 move window|container to mark <mark>
2433 ------------------------------------
2434
2435 *Example*:
2436 --------------------------------------------------------
2437 for_window [instance="tabme"] move window to mark target
2438 --------------------------------------------------------
2439
2440 [[resizingconfig]]
2441 === Resizing containers/windows
2442
2443 If you want to resize containers/windows using your keyboard, you can use the
2444 +resize+ command:
2445
2446 *Syntax*:
2447 -------------------------------------------------------
2448 resize grow|shrink <direction> [<px> px [or <ppt> ppt]]
2449 resize set [width] <width> [px | ppt]
2450 resize set height <height> [px | ppt]
2451 resize set [width] <width> [px | ppt] [height] <height> [px | ppt]
2452 -------------------------------------------------------
2453
2454 Direction can either be one of +up+, +down+, +left+ or +right+. Or you can be
2455 less specific and use +width+ or +height+, in which case i3 will take/give space
2456 from all the other containers. The optional pixel argument specifies by how many
2457 pixels a container should be grown or shrunk (the default is 10 pixels). The
2458 optional ppt argument means "percentage points", and if specified it indicates
2459 that a *tiling container* should be grown or shrunk by that many points, instead
2460 of by the +px+ value.
2461
2462 Note about +resize set+: a value of 0 for <width> or <height> means "do not
2463 resize in this direction".
2464
2465 It is recommended to define bindings for resizing in a dedicated binding mode.
2466 See <<binding_modes>> and the example in the i3
2467 https://github.com/i3/i3/blob/next/etc/config.keycodes[default config] for more
2468 context.
2469
2470 *Example*:
2471 ------------------------------------------------
2472 for_window [class="urxvt"] resize set 640 480
2473 ------------------------------------------------
2474
2475 === Jumping to specific windows
2476
2477 Often when in a multi-monitor environment, you want to quickly jump to a
2478 specific window. For example, while working on workspace 3 you may want to
2479 jump to your mail client to email your boss that you’ve achieved some
2480 important goal. Instead of figuring out how to navigate to your mail client,
2481 it would be more convenient to have a shortcut. You can use the +focus+ command
2482 with criteria for that.
2483
2484 *Syntax*:
2485 ----------------------------------------------------
2486 [class="class"] focus
2487 [title="title"] focus
2488 ----------------------------------------------------
2489
2490 *Examples*:
2491 ------------------------------------------------
2492 # Get me to the next open VIM instance
2493 bindsym $mod+a [class="urxvt" title="VIM"] focus
2494 ------------------------------------------------
2495
2496 [[vim_like_marks]]
2497 === VIM-like marks (mark/goto)
2498
2499 This feature is like the jump feature: It allows you to directly jump to a
2500 specific window (this means switching to the appropriate workspace and setting
2501 focus to the windows). However, you can directly mark a specific window with
2502 an arbitrary label and use it afterwards. You can unmark the label in the same
2503 way, using the unmark command. If you don't specify a label, unmark removes all
2504 marks. You do not need to ensure that your windows have unique classes or
2505 titles, and you do not need to change your configuration file.
2506
2507 As the command needs to include the label with which you want to mark the
2508 window, you cannot simply bind it to a key. +i3-input+ is a tool created
2509 for this purpose: It lets you input a command and sends the command to i3. It
2510 can also prefix this command and display a custom prompt for the input dialog.
2511
2512 The additional +--toggle+ option will remove the mark if the window already has
2513 this mark or add it otherwise. Note that you may need to use this in
2514 combination with +--add+ (see below) as any other marks will otherwise be
2515 removed.
2516
2517 The +--replace+ flag causes i3 to remove any existing marks, which is also the
2518 default behavior. You can use the +--add+ flag to put more than one mark on a
2519 window.
2520
2521 Refer to <<show_marks>> if you don't want marks to be shown in the window decoration.
2522
2523 *Syntax*:
2524 ----------------------------------------------
2525 mark [--add|--replace] [--toggle] <identifier>
2526 [con_mark="identifier"] focus
2527 unmark <identifier>
2528 ----------------------------------------------
2529
2530 You can use +i3-input+ to prompt for a mark name, then use the +mark+
2531 and +focus+ commands to create and jump to custom marks:
2532
2533 *Examples*:
2534 ---------------------------------------
2535 # read 1 character and mark the current window with this character
2536 bindsym $mod+m exec i3-input -F 'mark %s' -l 1 -P 'Mark: '
2537
2538 # read 1 character and go to the window with the character
2539 bindsym $mod+g exec i3-input -F '[con_mark="%s"] focus' -l 1 -P 'Goto: '
2540 ---------------------------------------
2541
2542 Alternatively, if you do not want to mess with +i3-input+, you could create
2543 separate bindings for a specific set of labels and then only use those labels:
2544
2545 *Example (in a terminal)*:
2546 ---------------------------------------------------------
2547 # marks the focused container
2548 mark irssi
2549
2550 # focus the container with the mark "irssi"
2551 '[con_mark="irssi"] focus'
2552
2553 # remove the mark "irssi" from whichever container has it
2554 unmark irssi
2555
2556 # remove all marks on all firefox windows
2557 [class="(?i)firefox"] unmark
2558 ---------------------------------------------------------
2559
2560 [[pango_markup]]
2561 === Window title format
2562
2563 By default, i3 will simply print the X11 window title. Using +title_format+,
2564 this can be customized by setting the format to the desired output. This
2565 directive supports
2566 https://developer.gnome.org/pango/stable/pango-Markup.html[Pango markup]
2567 and the following placeholders which will be replaced:
2568
2569 +%title+::
2570 For normal windows, this is the X11 window title (_NET_WM_NAME or WM_NAME
2571 as fallback). When used on containers without a window (e.g., a split
2572 container inside a tabbed/stacked layout), this will be the tree
2573 representation of the container (e.g., "H[xterm xterm]").
2574 +%class+::
2575 The X11 window class (second part of WM_CLASS). This corresponds to the
2576 +class+ criterion, see <<command_criteria>>.
2577 +%instance+::
2578 The X11 window instance (first part of WM_CLASS). This corresponds to the
2579 +instance+ criterion, see <<command_criteria>>.
2580
2581 Using the <<for_window>> directive, you can set the title format for any window
2582 based on <<command_criteria>>.
2583
2584 *Syntax*:
2585 ---------------------
2586 title_format <format>
2587 ---------------------
2588
2589 *Examples*:
2590 -------------------------------------------------------------------------------------
2591 # give the focused window a prefix
2592 bindsym $mod+p title_format "Important | %title"
2593
2594 # print all window titles bold
2595 for_window [class=".*"] title_format "<b>%title</b>"
2596
2597 # print window titles of firefox windows red
2598 for_window [class="(?i)firefox"] title_format "<span foreground='red'>%title</span>"
2599 -------------------------------------------------------------------------------------
2600
2601 === Changing border style
2602
2603 To change the border of the current client, you can use +border normal+ to use the normal
2604 border (including window title), +border pixel 1+ to use a 1-pixel border (no window title)
2605 and +border none+ to make the client borderless.
2606
2607 There is also +border toggle+ which will toggle the different border styles. The
2608 optional pixel argument can be used to specify the border width when switching
2609 to the normal and pixel styles.
2610
2611 Note that "pixel" refers to logical pixel. On HiDPI displays, a logical pixel
2612 may be represented by multiple physical pixels, so +pixel 1+ might not
2613 necessarily translate into a single pixel row wide border.
2614
2615 *Syntax*:
2616 -----------------------------------------------
2617 border normal|pixel|toggle [<n>]
2618 border none
2619
2620 # legacy syntax, equivalent to "border pixel 1"
2621 border 1pixel
2622 -----------------------------------------------
2623
2624 *Examples*:
2625 ----------------------------------------------
2626 # use window title, but no border
2627 bindsym $mod+t border normal 0
2628 # use no window title and a thick border
2629 bindsym $mod+y border pixel 3
2630 # use neither window title nor border
2631 bindsym $mod+u border none
2632 ----------------------------------------------
2633
2634 [[shmlog]]
2635 === Enabling shared memory logging
2636
2637 As described in https://i3wm.org/docs/debugging.html, i3 can log to a shared
2638 memory buffer, which you can dump using +i3-dump-log+. The +shmlog+ command
2639 allows you to enable or disable the shared memory logging at runtime.
2640
2641 Note that when using +shmlog <size_in_bytes>+, the current log will be
2642 discarded and a new one will be started.
2643
2644 *Syntax*:
2645 ------------------------------
2646 shmlog <size_in_bytes>
2647 shmlog on|off|toggle
2648 ------------------------------
2649
2650 *Examples*:
2651 ---------------
2652 # Enable/disable logging
2653 bindsym $mod+x shmlog toggle
2654
2655 # or, from a terminal:
2656 # increase the shared memory log buffer to 50 MiB
2657 i3-msg shmlog $((50*1024*1024))
2658 ---------------
2659
2660 === Enabling debug logging
2661
2662 The +debuglog+ command allows you to enable or disable debug logging at
2663 runtime. Debug logging is much more verbose than non-debug logging. This
2664 command does not activate shared memory logging (shmlog), and as such is most
2665 likely useful in combination with the above-described <<shmlog>> command.
2666
2667 *Syntax*:
2668 ----------------------
2669 debuglog on|off|toggle
2670 ----------------------
2671
2672 *Examples*:
2673 ------------------------
2674 # Enable/disable logging
2675 bindsym $mod+x debuglog toggle
2676 ------------------------
2677
2678 === Reloading/Restarting/Exiting
2679
2680 You can make i3 reload its configuration file with +reload+. You can also
2681 restart i3 inplace with the +restart+ command to get it out of some weird state
2682 (if that should ever happen) or to perform an upgrade without having to restart
2683 your X session. To exit i3 properly, you can use the +exit+ command,
2684 however you don’t need to (simply killing your X session is fine as well).
2685
2686 *Examples*:
2687 ----------------------------
2688 bindsym $mod+Shift+r restart
2689 bindsym $mod+Shift+w reload
2690 bindsym $mod+Shift+e exit
2691 ----------------------------
2692
2693 === Scratchpad
2694
2695 There are two commands to use any existing window as scratchpad window. +move
2696 scratchpad+ will move a window to the scratchpad workspace. This will make it
2697 invisible until you show it again. There is no way to open that workspace.
2698 Instead, when using +scratchpad show+, the window will be shown again, as a
2699 floating window, centered on your current workspace (using +scratchpad show+ on
2700 a visible scratchpad window will make it hidden again, so you can have a
2701 keybinding to toggle). Note that this is just a normal floating window, so if
2702 you want to "remove it from scratchpad", you can simple make it tiling again
2703 (+floating toggle+).
2704
2705 As the name indicates, this is useful for having a window with your favorite
2706 editor always at hand. However, you can also use this for other permanently
2707 running applications which you don’t want to see all the time: Your music
2708 player, alsamixer, maybe even your mail client…?
2709
2710 *Syntax*:
2711 ---------------
2712 move scratchpad
2713
2714 scratchpad show
2715 ---------------
2716
2717 *Examples*:
2718 ------------------------------------------------
2719 # Make the currently focused window a scratchpad
2720 bindsym $mod+Shift+minus move scratchpad
2721
2722 # Show the first scratchpad window
2723 bindsym $mod+minus scratchpad show
2724
2725 # Show the sup-mail scratchpad window, if any.
2726 bindsym mod4+s [title="^Sup ::"] scratchpad show
2727 ------------------------------------------------
2728
2729 === Nop
2730
2731 There is a no operation command +nop+ which allows you to override default
2732 behavior. This can be useful for, e.g., disabling a focus change on clicks with
2733 the middle mouse button.
2734
2735 The optional +comment+ argument is ignored, but will be printed to the log file
2736 for debugging purposes.
2737
2738 *Syntax*:
2739 ---------------
2740 nop [<comment>]
2741 ---------------
2742
2743 *Example*:
2744 ----------------------------------------------
2745 # Disable focus change for clicks on titlebars
2746 # with the middle mouse button
2747 bindsym button2 nop
2748 ----------------------------------------------
2749
2750 === i3bar control
2751
2752 There are two options in the configuration of each i3bar instance that can be
2753 changed during runtime by invoking a command through i3. The commands +bar
2754 hidden_state+ and +bar mode+ allow setting the current hidden_state
2755 respectively mode option of each bar. It is also possible to toggle between
2756 hide state and show state as well as between dock mode and hide mode. Each
2757 i3bar instance can be controlled individually by specifying a bar_id, if none
2758 is given, the command is executed for all bar instances.
2759
2760 *Syntax*:
2761 ---------------
2762 bar hidden_state hide|show|toggle [<bar_id>]
2763
2764 bar mode dock|hide|invisible|toggle [<bar_id>]
2765 ---------------
2766
2767 *Examples*:
2768 ------------------------------------------------
2769 # Toggle between hide state and show state
2770 bindsym $mod+m bar hidden_state toggle
2771
2772 # Toggle between dock mode and hide mode
2773 bindsym $mod+n bar mode toggle
2774
2775 # Set the bar instance with id 'bar-1' to switch to hide mode
2776 bindsym $mod+b bar mode hide bar-1
2777
2778 # Set the bar instance with id 'bar-1' to always stay hidden
2779 bindsym $mod+Shift+b bar mode invisible bar-1
2780 ------------------------------------------------
2781
2782 [[multi_monitor]]
2783 == Multiple monitors
2784
2785 As you can see in the goal list on the website, i3 was specifically developed
2786 with support for multiple monitors in mind. This section will explain how to
2787 handle multiple monitors.
2788
2789 When you have only one monitor, things are simple. You usually start with
2790 workspace 1 on your monitor and open new ones as you need them.
2791
2792 When you have more than one monitor, each monitor will get an initial
2793 workspace. The first monitor gets 1, the second gets 2 and a possible third
2794 would get 3. When you switch to a workspace on a different monitor, i3 will
2795 switch to that monitor and then switch to the workspace. This way, you don’t
2796 need shortcuts to switch to a specific monitor, and you don’t need to remember
2797 where you put which workspace. New workspaces will be opened on the currently
2798 active monitor. It is not possible to have a monitor without a workspace.
2799
2800 The idea of making workspaces global is based on the observation that most
2801 users have a very limited set of workspaces on their additional monitors.
2802 They are often used for a specific task (browser, shell) or for monitoring
2803 several things (mail, IRC, syslog, …). Thus, using one workspace on one monitor
2804 and "the rest" on the other monitors often makes sense. However, as you can
2805 create an unlimited number of workspaces in i3 and tie them to specific
2806 screens, you can have the "traditional" approach of having X workspaces per
2807 screen by changing your configuration (using modes, for example).
2808
2809 === Configuring your monitors
2810
2811 To help you get going if you have never used multiple monitors before, here is
2812 a short overview of the xrandr options which will probably be of interest to
2813 you. It is always useful to get an overview of the current screen configuration.
2814 Just run "xrandr" and you will get an output like the following:
2815 -------------------------------------------------------------------------------
2816 $ xrandr
2817 Screen 0: minimum 320 x 200, current 1280 x 800, maximum 8192 x 8192
2818 VGA1 disconnected (normal left inverted right x axis y axis)
2819 LVDS1 connected 1280x800+0+0 (normal left inverted right x axis y axis) 261mm x 163mm
2820 1280x800 60.0*+ 50.0
2821 1024x768 85.0 75.0 70.1 60.0
2822 832x624 74.6
2823 800x600 85.1 72.2 75.0 60.3 56.2
2824 640x480 85.0 72.8 75.0 59.9
2825 720x400 85.0
2826 640x400 85.1
2827 640x350 85.1
2828 --------------------------------------------------------------------------------------
2829
2830 Several things are important here: You can see that +LVDS1+ is connected (of
2831 course, it is the internal flat panel) but +VGA1+ is not. If you have a monitor
2832 connected to one of the ports but xrandr still says "disconnected", you should
2833 check your cable, monitor or graphics driver.
2834
2835 The maximum resolution you can see at the end of the first line is the maximum
2836 combined resolution of your monitors. By default, it is usually too low and has
2837 to be increased by editing +/etc/X11/xorg.conf+.
2838
2839 So, say you connected VGA1 and want to use it as an additional screen:
2840 -------------------------------------------
2841 xrandr --output VGA1 --auto --left-of LVDS1
2842 -------------------------------------------
2843 This command makes xrandr try to find the native resolution of the device
2844 connected to +VGA1+ and configures it to the left of your internal flat panel.
2845 When running "xrandr" again, the output looks like this:
2846 -------------------------------------------------------------------------------
2847 $ xrandr
2848 Screen 0: minimum 320 x 200, current 2560 x 1024, maximum 8192 x 8192
2849 VGA1 connected 1280x1024+0+0 (normal left inverted right x axis y axis) 338mm x 270mm
2850 1280x1024 60.0*+ 75.0
2851 1280x960 60.0
2852 1152x864 75.0
2853 1024x768 75.1 70.1 60.0
2854 832x624 74.6
2855 800x600 72.2 75.0 60.3 56.2
2856 640x480 72.8 75.0 66.7 60.0
2857 720x400 70.1
2858 LVDS1 connected 1280x800+1280+0 (normal left inverted right x axis y axis) 261mm x 163mm
2859 1280x800 60.0*+ 50.0
2860 1024x768 85.0 75.0 70.1 60.0
2861 832x624 74.6
2862 800x600 85.1 72.2 75.0 60.3 56.2
2863 640x480 85.0 72.8 75.0 59.9
2864 720x400 85.0
2865 640x400 85.1
2866 640x350 85.1
2867 -------------------------------------------------------------------------------
2868 Please note that i3 uses exactly the same API as xrandr does, so it will see
2869 only what you can see in xrandr.
2870
2871 See also <<presentations>> for more examples of multi-monitor setups.
2872
2873 === Interesting configuration for multi-monitor environments
2874
2875 There are several things to configure in i3 which may be interesting if you
2876 have more than one monitor:
2877
2878 1. You can specify which workspace should be put on which screen. This
2879 allows you to have a different set of workspaces when starting than just
2880 1 for the first monitor, 2 for the second and so on. See
2881 <<workspace_screen>>.
2882 2. If you want some applications to generally open on the bigger screen
2883 (MPlayer, Firefox, …), you can assign them to a specific workspace, see
2884 <<assign_workspace>>.
2885 3. If you have many workspaces on many monitors, it might get hard to keep
2886 track of which window you put where. Thus, you can use vim-like marks to
2887 quickly switch between windows. See <<vim_like_marks>>.
2888 4. For information on how to move existing workspaces between monitors,
2889 see <<move_to_outputs>>.
2890
2891 == i3 and the rest of your software world
2892
2893 === Displaying a status line
2894
2895 A very common thing amongst users of exotic window managers is a status line at
2896 some corner of the screen. It is an often superior replacement to the widget
2897 approach you have in the task bar of a traditional desktop environment.
2898
2899 If you don’t already have your favorite way of generating such a status line
2900 (self-written scripts, conky, …), then i3status is the recommended tool for
2901 this task. It was written in C with the goal of using as few syscalls as
2902 possible to reduce the time your CPU is woken up from sleep states. Because
2903 i3status only spits out text, you need to combine it with some other tool, like
2904 i3bar. See <<status_command>> for how to display i3status in i3bar.
2905
2906 Regardless of which application you use to display the status line, you
2907 want to make sure that it registers as a dock window using EWMH hints. i3 will
2908 position the window either at the top or at the bottom of the screen, depending
2909 on which hint the application sets. With i3bar, you can configure its position,
2910 see <<i3bar_position>>.
2911
2912 [[presentations]]
2913 === Giving presentations (multi-monitor)
2914
2915 When giving a presentation, you typically want the audience to see what you see
2916 on your screen and then go through a series of slides (if the presentation is
2917 simple). For more complex presentations, you might want to have some notes
2918 which only you can see on your screen, while the audience can only see the
2919 slides.
2920
2921 ==== Case 1: everybody gets the same output
2922 This is the simple case. You connect your computer to the video projector,
2923 turn on both (computer and video projector) and configure your X server to
2924 clone the internal flat panel of your computer to the video output:
2925 -----------------------------------------------------
2926 xrandr --output VGA1 --mode 1024x768 --same-as LVDS1
2927 -----------------------------------------------------
2928 i3 will then use the lowest common subset of screen resolutions, the rest of
2929 your screen will be left untouched (it will show the X background). So, in
2930 our example, this would be 1024x768 (my notebook has 1280x800).
2931
2932 ==== Case 2: you can see more than your audience
2933 This case is a bit harder. First of all, you should configure the VGA output
2934 somewhere near your internal flat panel, say right of it:
2935 -----------------------------------------------------
2936 xrandr --output VGA1 --mode 1024x768 --right-of LVDS1
2937 -----------------------------------------------------
2938 Now, i3 will put a new workspace (depending on your settings) on the new screen
2939 and you are in multi-monitor mode (see <<multi_monitor>>).
2940
2941 Because i3 is not a compositing window manager, there is no ability to
2942 display a window on two screens at the same time. Instead, your presentation
2943 software needs to do this job (that is, open a window on each screen).
2944
2945 [[hidpi]]
2946 === High-resolution displays (aka HIDPI displays)
2947
2948 See https://wiki.archlinux.org/index.php/HiDPI for details on how to enable
2949 scaling in various parts of the Linux desktop. i3 will read the desired DPI from
2950 the `Xft.dpi` property. The property defaults to 96 DPI, so to achieve 200%
2951 scaling, you’d set `Xft.dpi: 192` in `~/.Xresources`.
2952
2953 If you are a long-time i3 user who just got a new monitor, double-check that:
2954
2955 * You are using a scalable font (starting with “pango:”) in your i3 config.
2956
2957 * You are using a terminal emulator which supports scaling. You could
2958 temporarily switch to gnome-terminal, which is known to support scaling out of
2959 the box, until you figure out how to adjust the font size in your favorite
2960 terminal emulator.
0 External workspace bars
1 =======================
2 Michael Stapelberg <[email protected]>
3 April 2013
4
5 i3 comes with i3bar by default, a simple bar that is sufficient for most users.
6 In case you are unhappy with it, this document explains how to use a different,
7 external workspace bar. Note that we do not provide support for external
8 programs.
9
10 == Internal and external bars
11
12 The internal workspace bar of i3 is meant to be a reasonable default so that
13 you can use i3 without having too much hassle when setting it up. It is quite
14 simple and intended to stay this way.
15
16 == dock mode
17
18 You typically want to see the same workspace bar on every workspace on a
19 specific screen. Also, you don’t want to place the workspace bar somewhere
20 in your layout by hand. This is where dock mode comes in: When a program sets
21 the appropriate hint (_NET_WM_WINDOW_TYPE_DOCK), it will be managed in dock
22 mode by i3. That means it will be placed at the bottom or top of the screen
23 (while other edges of the screen are possible in the NetWM standard, this is
24 not yet implemented in i3), it will not overlap any other window and it will be
25 on every workspace for the specific screen it was placed on initially.
26
27 == The IPC interface
28
29 In the context of using an external workspace bar, the IPC interface needs to
30 provide the bar program with the current workspaces and output (as in VGA-1,
31 LVDS-1, …) configuration. In the other direction, the program has to be able
32 to switch to specific workspaces.
33
34 By default, the IPC interface is enabled and you can get the path to the socket
35 by calling +i3 --get-socketpath+.
36
37 To learn more about the protocol which is used for IPC, see +docs/ipc+.
38
39 == Output changes (on-the-fly)
40
41 i3 implements the RandR API and can handle changing outputs quite well. So, an
42 external workspace bar implementation needs to make sure that when you change
43 the resolution of any of your screens (or enable/disable an output), the bars
44 will be adjusted properly.
45
46 == i3-wsbar, an example implementation
47
48 +i3-wsbar+ used to be the reference implementation before we had +i3bar+.
49 Nowadays, it is not shipped with release tarballs, but you can still get it at
50 https://github.com/i3/i3/blob/next/contrib/i3-wsbar
51
52 === The big picture
53
54 The most common reason to use an external workspace bar is to integrate system
55 information such as what +i3status+ or +conky+ provide into the workspace bar.
56 So, we have +i3status+ or a similar program, which only provides
57 text output (formatted in some way). To display this text nicely on the screen,
58 there are programs such as dzen2, xmobar and similar. We will stick to dzen2
59 from here on. So, we have the output of i3status, which needs to go into dzen2
60 somehow. But we also want to display the list of workspaces. +i3-wsbar+ takes
61 input on stdin, combines it with a formatted workspace list and pipes it to
62 dzen2.
63
64 Please note that +i3-wsbar+ does not print its output to stdout. Instead, it
65 launches the dzen2 instances on its own. This is necessary to handle changes
66 in the available outputs (to place a new dzen2 on a new screen for example).
67
68 image:wsbar.png["Overview",link="wsbar.png"]
69
70 === Running i3-wsbar
71
72 The most simple usage of i3-wsbar looks like this:
73 -------------------------------
74 i3-wsbar -c "dzen2 -x %x -dock"
75 -------------------------------
76
77 The +%x+ in the command name will be replaced by the X position of the output
78 for which this workspace bar is running. i3 will automatically place the
79 workspace bar on the correct output when dzen2 is started in dock mode. The
80 bar which you will see should look exactly like the internal bar of i3.
81
82 To actually get a benefit, you want to give +i3-wsbar+ some input:
83 ------------------------------------------
84 i3status | i3-wsbar -c "dzen2 -x %x -dock"
85 ------------------------------------------
Binary diff not shown
Binary diff not shown
0 # i3 config file (v4)
1 #
2 # Please see https://i3wm.org/docs/userguide.html for a complete reference!
3 #
4 # This config file uses keycodes (bindsym) and was written for the QWERTY
5 # layout.
6 #
7 # To get a config file with the same key positions, but for your current
8 # layout, use the i3-config-wizard
9 #
10
11 # Font for window titles. Will also be used by the bar unless a different font
12 # is used in the bar {} block below.
13 font pango:monospace 8
14
15 # This font is widely installed, provides lots of unicode glyphs, right-to-left
16 # text rendering and scalability on retina/hidpi displays (thanks to pango).
17 #font pango:DejaVu Sans Mono 8
18
19 # The combination of xss-lock, nm-applet and pactl is a popular choice, so
20 # they are included here as an example. Modify as you see fit.
21
22 # xss-lock grabs a logind suspend inhibit lock and will use i3lock to lock the
23 # screen before suspend. Use loginctl lock-session to lock your screen.
24 exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock --nofork
25
26 # NetworkManager is the most popular way to manage wireless networks on Linux,
27 # and nm-applet is a desktop environment-independent system tray GUI for it.
28 exec --no-startup-id nm-applet
29
30 # Use pactl to adjust volume in PulseAudio.
31 set $refresh_i3status killall -SIGUSR1 i3status
32 bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +10% && $refresh_i3status
33 bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -10% && $refresh_i3status
34 bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status
35 bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status
36
37 # use these keys for focus, movement, and resize directions when reaching for
38 # the arrows is not convenient
39 set $up l
40 set $down k
41 set $left j
42 set $right semicolon
43
44 # use Mouse+Mod1 to drag floating windows to their wanted position
45 floating_modifier Mod1
46
47 # start a terminal
48 bindsym Mod1+Return exec i3-sensible-terminal
49
50 # kill focused window
51 bindsym Mod1+Shift+q kill
52
53 # start dmenu (a program launcher)
54 bindsym Mod1+d exec dmenu_run
55 # There also is the (new) i3-dmenu-desktop which only displays applications
56 # shipping a .desktop file. It is a wrapper around dmenu, so you need that
57 # installed.
58 # bindsym Mod1+d exec --no-startup-id i3-dmenu-desktop
59
60 # change focus
61 bindsym Mod1+$left focus left
62 bindsym Mod1+$down focus down
63 bindsym Mod1+$up focus up
64 bindsym Mod1+$right focus right
65
66 # alternatively, you can use the cursor keys:
67 bindsym Mod1+Left focus left
68 bindsym Mod1+Down focus down
69 bindsym Mod1+Up focus up
70 bindsym Mod1+Right focus right
71
72 # move focused window
73 bindsym Mod1+Shift+$left move left
74 bindsym Mod1+Shift+$down move down
75 bindsym Mod1+Shift+$up move up
76 bindsym Mod1+Shift+$right move right
77
78 # alternatively, you can use the cursor keys:
79 bindsym Mod1+Shift+Left move left
80 bindsym Mod1+Shift+Down move down
81 bindsym Mod1+Shift+Up move up
82 bindsym Mod1+Shift+Right move right
83
84 # split in horizontal orientation
85 bindsym Mod1+h split h
86
87 # split in vertical orientation
88 bindsym Mod1+v split v
89
90 # enter fullscreen mode for the focused container
91 bindsym Mod1+f fullscreen toggle
92
93 # change container layout (stacked, tabbed, toggle split)
94 bindsym Mod1+s layout stacking
95 bindsym Mod1+w layout tabbed
96 bindsym Mod1+e layout toggle split
97
98 # toggle tiling / floating
99 bindsym Mod1+Shift+space floating toggle
100
101 # change focus between tiling / floating windows
102 bindsym Mod1+space focus mode_toggle
103
104 # focus the parent container
105 bindsym Mod1+a focus parent
106
107 # focus the child container
108 #bindsym Mod1+d focus child
109
110 # move the currently focused window to the scratchpad
111 bindsym Mod1+Shift+minus move scratchpad
112
113 # Show the next scratchpad window or hide the focused scratchpad window.
114 # If there are multiple scratchpad windows, this command cycles through them.
115 bindsym Mod1+minus scratchpad show
116
117 # Define names for default workspaces for which we configure key bindings later on.
118 # We use variables to avoid repeating the names in multiple places.
119 set $ws1 "1"
120 set $ws2 "2"
121 set $ws3 "3"
122 set $ws4 "4"
123 set $ws5 "5"
124 set $ws6 "6"
125 set $ws7 "7"
126 set $ws8 "8"
127 set $ws9 "9"
128 set $ws10 "10"
129
130 # switch to workspace
131 bindsym Mod1+1 workspace number $ws1
132 bindsym Mod1+2 workspace number $ws2
133 bindsym Mod1+3 workspace number $ws3
134 bindsym Mod1+4 workspace number $ws4
135 bindsym Mod1+5 workspace number $ws5
136 bindsym Mod1+6 workspace number $ws6
137 bindsym Mod1+7 workspace number $ws7
138 bindsym Mod1+8 workspace number $ws8
139 bindsym Mod1+9 workspace number $ws9
140 bindsym Mod1+0 workspace number $ws10
141
142 # move focused container to workspace
143 bindsym Mod1+Shift+1 move container to workspace number $ws1
144 bindsym Mod1+Shift+2 move container to workspace number $ws2
145 bindsym Mod1+Shift+3 move container to workspace number $ws3
146 bindsym Mod1+Shift+4 move container to workspace number $ws4
147 bindsym Mod1+Shift+5 move container to workspace number $ws5
148 bindsym Mod1+Shift+6 move container to workspace number $ws6
149 bindsym Mod1+Shift+7 move container to workspace number $ws7
150 bindsym Mod1+Shift+8 move container to workspace number $ws8
151 bindsym Mod1+Shift+9 move container to workspace number $ws9
152 bindsym Mod1+Shift+0 move container to workspace number $ws10
153
154 # reload the configuration file
155 bindsym Mod1+Shift+c reload
156 # restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
157 bindsym Mod1+Shift+r restart
158 # exit i3 (logs you out of your X session)
159 bindsym Mod1+Shift+e exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'"
160
161 # resize window (you can also use the mouse for that)
162 mode "resize" {
163 # These bindings trigger as soon as you enter the resize mode
164
165 # Pressing left will shrink the window’s width.
166 # Pressing right will grow the window’s width.
167 # Pressing up will shrink the window’s height.
168 # Pressing down will grow the window’s height.
169 bindsym $left resize shrink width 10 px or 10 ppt
170 bindsym $down resize grow height 10 px or 10 ppt
171 bindsym $up resize shrink height 10 px or 10 ppt
172 bindsym $right resize grow width 10 px or 10 ppt
173
174 # same bindings, but for the arrow keys
175 bindsym Left resize shrink width 10 px or 10 ppt
176 bindsym Down resize grow height 10 px or 10 ppt
177 bindsym Up resize shrink height 10 px or 10 ppt
178 bindsym Right resize grow width 10 px or 10 ppt
179
180 # back to normal: Enter or Escape or Mod1+r
181 bindsym Return mode "default"
182 bindsym Escape mode "default"
183 bindsym Mod1+r mode "default"
184 }
185
186 bindsym Mod1+r mode "resize"
187
188 # Start i3bar to display a workspace bar (plus the system information i3status
189 # finds out, if available)
190 bar {
191 status_command i3status
192 }
193
194 #######################################################################
195 # automatically start i3-config-wizard to offer the user to create a
196 # keysym-based config which used their favorite modifier (alt or windows)
197 #
198 # i3-config-wizard will not launch if there already is a config file
199 # in ~/.config/i3/config (or $XDG_CONFIG_HOME/i3/config if set) or
200 # ~/.i3/config.
201 #
202 # Please remove the following exec line:
203 #######################################################################
204 exec i3-config-wizard
0 # WARNING
1 # WARNING: This configuration file is a template for the i3-config-wizard to
2 # WARNING: generate a config which uses keysyms in your current layout. It does
3 # WARNING: not get loaded by i3. Please do not change it.
4 # WARNING
5
6 # i3 config file (v4)
7 #
8 # Please see https://i3wm.org/docs/userguide.html for a complete reference!
9
10 set $mod Mod1
11
12 # Font for window titles. Will also be used by the bar unless a different font
13 # is used in the bar {} block below.
14 font pango:monospace 8
15
16 # This font is widely installed, provides lots of unicode glyphs, right-to-left
17 # text rendering and scalability on retina/hidpi displays (thanks to pango).
18 #font pango:DejaVu Sans Mono 8
19
20 # The combination of xss-lock, nm-applet and pactl is a popular choice, so
21 # they are included here as an example. Modify as you see fit.
22
23 # xss-lock grabs a logind suspend inhibit lock and will use i3lock to lock the
24 # screen before suspend. Use loginctl lock-session to lock your screen.
25 exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock --nofork
26
27 # NetworkManager is the most popular way to manage wireless networks on Linux,
28 # and nm-applet is a desktop environment-independent system tray GUI for it.
29 exec --no-startup-id nm-applet
30
31 # Use pactl to adjust volume in PulseAudio.
32 set $refresh_i3status killall -SIGUSR1 i3status
33 bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +10% && $refresh_i3status
34 bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -10% && $refresh_i3status
35 bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status
36 bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status
37
38 # Use Mouse+$mod to drag floating windows to their wanted position
39 floating_modifier $mod
40
41 # start a terminal
42 bindcode $mod+36 exec i3-sensible-terminal
43
44 # kill focused window
45 bindcode $mod+Shift+24 kill
46
47 # start dmenu (a program launcher)
48 bindcode $mod+40 exec dmenu_run
49 # There also is the (new) i3-dmenu-desktop which only displays applications
50 # shipping a .desktop file. It is a wrapper around dmenu, so you need that
51 # installed.
52 # bindsym $mod+d exec --no-startup-id i3-dmenu-desktop
53
54 # change focus
55 bindcode $mod+44 focus left
56 bindcode $mod+45 focus down
57 bindcode $mod+46 focus up
58 bindcode $mod+47 focus right
59
60 # alternatively, you can use the cursor keys:
61 bindcode $mod+113 focus left
62 bindcode $mod+116 focus down
63 bindcode $mod+111 focus up
64 bindcode $mod+114 focus right
65
66 # move focused window
67 bindcode $mod+Shift+44 move left
68 bindcode $mod+Shift+45 move down
69 bindcode $mod+Shift+46 move up
70 bindcode $mod+Shift+47 move right
71
72 # alternatively, you can use the cursor keys:
73 bindcode $mod+Shift+113 move left
74 bindcode $mod+Shift+116 move down
75 bindcode $mod+Shift+111 move up
76 bindcode $mod+Shift+114 move right
77
78 # split in horizontal orientation
79 bindcode $mod+43 split h
80
81 # split in vertical orientation
82 bindcode $mod+55 split v
83
84 # enter fullscreen mode for the focused container
85 bindcode $mod+41 fullscreen toggle
86
87 # change container layout (stacked, tabbed, toggle split)
88 bindcode $mod+39 layout stacking
89 bindcode $mod+25 layout tabbed
90 bindcode $mod+26 layout toggle split
91
92 # toggle tiling / floating
93 bindcode $mod+Shift+65 floating toggle
94
95 # change focus between tiling / floating windows
96 bindcode $mod+65 focus mode_toggle
97
98 # focus the parent container
99 bindcode $mod+38 focus parent
100
101 # focus the child container
102 #bindsym $mod+d focus child
103
104 # Define names for default workspaces for which we configure key bindings later on.
105 # We use variables to avoid repeating the names in multiple places.
106 set $ws1 "1"
107 set $ws2 "2"
108 set $ws3 "3"
109 set $ws4 "4"
110 set $ws5 "5"
111 set $ws6 "6"
112 set $ws7 "7"
113 set $ws8 "8"
114 set $ws9 "9"
115 set $ws10 "10"
116
117 # switch to workspace
118 bindcode $mod+10 workspace number $ws1
119 bindcode $mod+11 workspace number $ws2
120 bindcode $mod+12 workspace number $ws3
121 bindcode $mod+13 workspace number $ws4
122 bindcode $mod+14 workspace number $ws5
123 bindcode $mod+15 workspace number $ws6
124 bindcode $mod+16 workspace number $ws7
125 bindcode $mod+17 workspace number $ws8
126 bindcode $mod+18 workspace number $ws9
127 bindcode $mod+19 workspace number $ws10
128
129 # move focused container to workspace
130 bindcode $mod+Shift+10 move container to workspace number $ws1
131 bindcode $mod+Shift+11 move container to workspace number $ws2
132 bindcode $mod+Shift+12 move container to workspace number $ws3
133 bindcode $mod+Shift+13 move container to workspace number $ws4
134 bindcode $mod+Shift+14 move container to workspace number $ws5
135 bindcode $mod+Shift+15 move container to workspace number $ws6
136 bindcode $mod+Shift+16 move container to workspace number $ws7
137 bindcode $mod+Shift+17 move container to workspace number $ws8
138 bindcode $mod+Shift+18 move container to workspace number $ws9
139 bindcode $mod+Shift+19 move container to workspace number $ws10
140
141 # reload the configuration file
142 bindcode $mod+Shift+54 reload
143 # restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
144 bindcode $mod+Shift+27 restart
145 # exit i3 (logs you out of your X session)
146 bindcode $mod+Shift+26 exec "i3-nagbar -t warning -m 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' -B 'Yes, exit i3' 'i3-msg exit'"
147
148 # resize window (you can also use the mouse for that)
149 mode "resize" {
150 # These bindings trigger as soon as you enter the resize mode
151
152 # Pressing left will shrink the window’s width.
153 # Pressing right will grow the window’s width.
154 # Pressing up will shrink the window’s height.
155 # Pressing down will grow the window’s height.
156 bindcode 44 resize shrink width 10 px or 10 ppt
157 bindcode 45 resize grow height 10 px or 10 ppt
158 bindcode 46 resize shrink height 10 px or 10 ppt
159 bindcode 47 resize grow width 10 px or 10 ppt
160
161 # same bindings, but for the arrow keys
162 bindcode 113 resize shrink width 10 px or 10 ppt
163 bindcode 116 resize grow height 10 px or 10 ppt
164 bindcode 111 resize shrink height 10 px or 10 ppt
165 bindcode 114 resize grow width 10 px or 10 ppt
166
167 # back to normal: Enter or Escape or $mod+r
168 bindcode 36 mode "default"
169 bindcode 9 mode "default"
170 bindcode $mod+27 mode "default"
171 }
172
173 bindcode $mod+27 mode "resize"
174
175 # Start i3bar to display a workspace bar (plus the system information i3status
176 # finds out, if available)
177 bar {
178 status_command i3status
179 }
0 #!/usr/bin/env perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # i3 - an improved dynamic tiling window manager
4 # © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 #
6 # generate-command-parser.pl: script to generate parts of the command parser
7 # from its specification file parser-specs/commands.spec.
8 #
9 # Requires only perl >= 5.10, no modules.
10
11 use strict;
12 use warnings;
13 use Data::Dumper;
14 use Getopt::Long;
15 use v5.10;
16
17 my $input = '';
18 my $prefix = '';
19 my $result = GetOptions(
20 'input=s' => \$input,
21 'prefix=s' => \$prefix
22 );
23
24 die qq|Input file "$input" does not exist!| unless -e $input;
25
26 # reads in a whole file
27 sub slurp {
28 open my $fh, '<', shift;
29 local $/;
30 <$fh>;
31 }
32
33 # Stores the different states.
34 my %states;
35
36 my @raw_lines = split("\n", slurp($input));
37 my @lines;
38
39 # XXX: In the future, we might switch to a different way of parsing this. The
40 # parser is in many ways not good — one obvious one is that it is hand-crafted
41 # without a good reason, also it preprocesses lines and forgets about line
42 # numbers. Luckily, this is just an implementation detail and the specification
43 # for the i3 command parser is in-tree (not user input).
44 # -- michael, 2012-01-12
45
46 # First step of preprocessing:
47 # Join token definitions which are spread over multiple lines.
48 for my $line (@raw_lines) {
49 next if $line =~ /^\s*#/ || $line =~ /^\s*$/;
50
51 if ($line =~ /^\s+->/) {
52 # This is a continued token definition, append this line to the
53 # previous one.
54 $lines[$#lines] = $lines[$#lines] . $line;
55 } else {
56 push @lines, $line;
57 next;
58 }
59 }
60
61 # First step: We build up the data structure containing all states and their
62 # token rules.
63
64 my $current_state;
65
66 for my $line (@lines) {
67 if (my ($state) = ($line =~ /^state ([A-Z0-9_]+):$/)) {
68 #say "got a new state: $state";
69 $current_state = $state;
70 } else {
71 # Must be a token definition:
72 # [identifier = ] <tokens> -> <action>
73 #say "token definition: $line";
74
75 my ($identifier, $tokens, $action) =
76 ($line =~ /
77 ^\s* # skip leading whitespace
78 ([a-z_]+ \s* = \s*|) # optional identifier
79 (.*?) -> \s* # token
80 (.*) # optional action
81 /x);
82
83 # Cleanup the identifier (if any).
84 $identifier =~ s/^\s*(\S+)\s*=\s*$/$1/g;
85
86 # The default action is to stay in the current state.
87 $action = $current_state if length($action) == 0;
88
89 #say "identifier = *$identifier*, token = *$tokens*, action = *$action*";
90 for my $token (split(',', $tokens)) {
91 # Cleanup trailing/leading whitespace.
92 $token =~ s/^\s*//g;
93 $token =~ s/\s*$//g;
94 my $store_token = {
95 token => $token,
96 identifier => $identifier,
97 next_state => $action,
98 };
99 if (exists $states{$current_state}) {
100 push @{$states{$current_state}}, $store_token;
101 } else {
102 $states{$current_state} = [ $store_token ];
103 }
104 }
105 }
106 }
107
108 # Second step: Generate the enum values for all states.
109
110 # It is important to keep the order the same, so we store the keys once.
111 # We sort descendingly by length to be able to replace occurrences of the state
112 # name even when one state’s name is included in another one’s (like FOR_WINDOW
113 # is in FOR_WINDOW_COMMAND).
114 my @keys = sort { (length($b) <=> length($a)) or ($a cmp $b) } keys %states;
115
116 open(my $enumfh, '>', "GENERATED_${prefix}_enums.h");
117
118 my %statenum;
119 say $enumfh 'typedef enum {';
120 my $cnt = 0;
121 for my $state (@keys, '__CALL') {
122 say $enumfh ',' if $cnt > 0;
123 print $enumfh " $state = $cnt";
124 $statenum{$state} = $cnt;
125 $cnt++;
126 }
127 say $enumfh "\n} cmdp_state;";
128 close($enumfh);
129
130 # Third step: Generate the call function.
131 open(my $callfh, '>', "GENERATED_${prefix}_call.h");
132 my $resultname = uc(substr($prefix, 0, 1)) . substr($prefix, 1) . 'ResultIR';
133 say $callfh "static void GENERATED_call(const int call_identifier, struct $resultname *result) {";
134 say $callfh ' switch (call_identifier) {';
135 my $call_id = 0;
136 for my $state (@keys) {
137 my $tokens = $states{$state};
138 for my $token (@$tokens) {
139 next unless $token->{next_state} =~ /^call /;
140 my ($cmd) = ($token->{next_state} =~ /^call (.*)/);
141 my ($next_state) = ($cmd =~ /; ([A-Z_]+)$/);
142 $cmd =~ s/; ([A-Z_]+)$//;
143 # Go back to the INITIAL state unless told otherwise.
144 $next_state ||= 'INITIAL';
145 my $fmt = $cmd;
146 # Replace the references to identified literals (like $workspace) with
147 # calls to get_string(). Also replaces state names (like FOR_WINDOW)
148 # with their ID (useful for cfg_criteria_init(FOR_WINDOW) e.g.).
149 $cmd =~ s/$_/$statenum{$_}/g for @keys;
150 $cmd =~ s/\$([a-z_]+)/get_string("$1")/g;
151 $cmd =~ s/\&([a-z_]+)/get_long("$1")/g;
152 # For debugging/testing, we print the call using printf() and thus need
153 # to generate a format string. The format uses %d for <number>s,
154 # literal numbers or state IDs and %s for NULL, <string>s and literal
155 # strings.
156
157 # remove the function name temporarily, so that the following
158 # replacements only apply to the arguments.
159 my ($funcname) = ($fmt =~ /^(.+)\(/);
160 $fmt =~ s/^$funcname//;
161
162 $fmt =~ s/$_/%d/g for @keys;
163 $fmt =~ s/\$([a-z_]+)/%s/g;
164 $fmt =~ s/\&([a-z_]+)/%ld/g;
165 $fmt =~ s/"([a-z0-9_]+)"/%s/g;
166 $fmt =~ s/(?:-?|\b)[0-9]+\b/%d/g;
167
168 $fmt = $funcname . $fmt;
169
170 say $callfh " case $call_id:";
171 say $callfh " result->next_state = $next_state;";
172 say $callfh '#ifndef TEST_PARSER';
173 my $real_cmd = $cmd;
174 if ($real_cmd =~ /\(\)/) {
175 $real_cmd =~ s/\(/(&current_match, result/;
176 } else {
177 $real_cmd =~ s/\(/(&current_match, result, /;
178 }
179 say $callfh " $real_cmd;";
180 say $callfh '#else';
181 # debug
182 $cmd =~ s/[^(]+\(//;
183 $cmd =~ s/\)$//;
184 $cmd = ", $cmd" if length($cmd) > 0;
185 $cmd =~ s/, NULL//g;
186 say $callfh qq| fprintf(stderr, "$fmt\\n"$cmd);|;
187 # The cfg_criteria functions have side-effects which are important for
188 # testing. They are implemented as stubs in the test parser code.
189 if ($real_cmd =~ /^cfg_criteria/) {
190 say $callfh qq| $real_cmd;|;
191 }
192 say $callfh '#endif';
193 say $callfh " break;";
194 $token->{next_state} = "call $call_id";
195 $call_id++;
196 }
197 }
198 say $callfh ' default:';
199 say $callfh ' printf("BUG in the parser. state = %d\n", call_identifier);';
200 say $callfh ' assert(false);';
201 say $callfh ' }';
202 say $callfh '}';
203 close($callfh);
204
205 # Fourth step: Generate the token datastructures.
206
207 open(my $tokfh, '>', "GENERATED_${prefix}_tokens.h");
208
209 for my $state (@keys) {
210 my $tokens = $states{$state};
211 say $tokfh 'static cmdp_token tokens_' . $state . '[' . scalar @$tokens . '] = {';
212 for my $token (@$tokens) {
213 my $call_identifier = 0;
214 my $token_name = $token->{token};
215 if ($token_name =~ /^'/) {
216 # To make the C code simpler, we leave out the trailing single
217 # quote of the literal. We can do strdup(literal + 1); then :).
218 $token_name =~ s/'$//;
219 }
220 # Escape double quotes:
221 $token_name =~ s,",\\",g;
222 my $next_state = $token->{next_state};
223 if ($next_state =~ /^call /) {
224 ($call_identifier) = ($next_state =~ /^call ([0-9]+)$/);
225 $next_state = '__CALL';
226 }
227 my $identifier = $token->{identifier};
228 say $tokfh qq| { "$token_name", "$identifier", $next_state, { $call_identifier } },|;
229 }
230 say $tokfh '};';
231 }
232
233 say $tokfh 'static cmdp_token_ptr tokens[' . scalar @keys . '] = {';
234 for my $state (@keys) {
235 my $tokens = $states{$state};
236 say $tokfh ' { tokens_' . $state . ', ' . scalar @$tokens . ' },';
237 }
238 say $tokfh '};';
239
240 close($tokfh);
0 xmacro(_NET_WM_NAME)
1 xmacro(_NET_WM_WINDOW_TYPE)
2 xmacro(_NET_WM_WINDOW_TYPE_DIALOG)
3 xmacro(ATOM)
4 xmacro(CARDINAL)
5 xmacro(UTF8_STRING)
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * i3-config-wizard: Program to convert configs using keycodes to configs using
7 * keysyms.
8 *
9 */
10 #include <config.h>
11
12 #if defined(__FreeBSD__)
13 #include <sys/param.h>
14 #endif
15
16 /* For systems without getline, fall back to fgetln */
17 #if defined(__APPLE__)
18 #define USE_FGETLN
19 #elif defined(__FreeBSD__)
20 /* Defining this macro before including stdio.h is necessary in order to have
21 * a prototype for getline in FreeBSD. */
22 #define _WITH_GETLINE
23 #endif
24
25 #include <stdio.h>
26 #include <sys/types.h>
27 #include <stdlib.h>
28 #include <stdbool.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <errno.h>
33 #include <err.h>
34 #include <stdint.h>
35 #include <getopt.h>
36 #include <limits.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>
39 #include <glob.h>
40 #include <assert.h>
41
42 #include <xcb/xcb.h>
43 #include <xcb/xcb_aux.h>
44 #include <xcb/xcb_event.h>
45 #include <xcb/xcb_keysyms.h>
46
47 #include <xkbcommon/xkbcommon.h>
48 #include <xkbcommon/xkbcommon-x11.h>
49
50 #define SN_API_NOT_YET_FROZEN 1
51 #include <libsn/sn-launchee.h>
52
53 #include <X11/Xlib.h>
54 #include <X11/keysym.h>
55 #include <X11/XKBlib.h>
56
57 /* We need SYSCONFDIR for the path to the keycode config template, so raise an
58 * error if it’s not defined for whatever reason */
59 #ifndef SYSCONFDIR
60 #error "SYSCONFDIR not defined"
61 #endif
62
63 #define FREE(pointer) \
64 do { \
65 free(pointer); \
66 pointer = NULL; \
67 } while (0)
68
69 #include "xcb.h"
70 xcb_visualtype_t *visual_type = NULL;
71 #include "libi3.h"
72
73 #define TEXT_PADDING logical_px(4)
74 #define WIN_POS_X logical_px(490)
75 #define WIN_POS_Y logical_px(297)
76 #define WIN_WIDTH logical_px(300)
77 #define WIN_HEIGHT (15 * font.height + TEXT_PADDING)
78
79 #define col_x(col) \
80 (((col)-1) * char_width + TEXT_PADDING)
81 #define row_y(row) \
82 (((row)-1) * font.height + TEXT_PADDING)
83
84 enum { STEP_WELCOME,
85 STEP_GENERATE } current_step = STEP_WELCOME;
86 enum { MOD_Mod1,
87 MOD_Mod4 } modifier = MOD_Mod4;
88
89 static char *config_path;
90 static uint32_t xcb_numlock_mask;
91 xcb_connection_t *conn;
92 static xcb_key_symbols_t *keysyms;
93 xcb_screen_t *root_screen;
94 static xcb_get_modifier_mapping_reply_t *modmap_reply;
95 static i3Font font;
96 static i3Font bold_font;
97 static int char_width;
98 static char *socket_path = NULL;
99 static xcb_window_t win;
100 static surface_t surface;
101 static xcb_key_symbols_t *symbols;
102 xcb_window_t root;
103 static struct xkb_keymap *xkb_keymap;
104 static uint8_t xkb_base_event;
105 static uint8_t xkb_base_error;
106
107 static void finish(void);
108
109 #include "GENERATED_config_enums.h"
110
111 typedef struct token {
112 char *name;
113 char *identifier;
114 /* This might be __CALL */
115 cmdp_state next_state;
116 union {
117 uint16_t call_identifier;
118 } extra;
119 } cmdp_token;
120
121 typedef struct tokenptr {
122 cmdp_token *array;
123 int n;
124 } cmdp_token_ptr;
125
126 #include "GENERATED_config_tokens.h"
127
128 static cmdp_state state;
129 /* A list which contains the states that lead to the current state, e.g.
130 * INITIAL, WORKSPACE_LAYOUT.
131 * When jumping back to INITIAL, statelist_idx will simply be set to 1
132 * (likewise for other states, e.g. MODE or BAR).
133 * This list is used to process the nearest error token. */
134 static cmdp_state statelist[10] = {INITIAL};
135 /* NB: statelist_idx points to where the next entry will be inserted */
136 static int statelist_idx = 1;
137
138 struct stack_entry {
139 /* Just a pointer, not dynamically allocated. */
140 const char *identifier;
141 enum {
142 STACK_STR = 0,
143 STACK_LONG = 1,
144 } type;
145 union {
146 char *str;
147 long num;
148 } val;
149 };
150
151 /* 10 entries should be enough for everybody. */
152 static struct stack_entry stack[10];
153
154 /*
155 * Pushes a string (identified by 'identifier') on the stack. We simply use a
156 * single array, since the number of entries we have to store is very small.
157 *
158 */
159 static void push_string(const char *identifier, const char *str) {
160 for (int c = 0; c < 10; c++) {
161 if (stack[c].identifier != NULL &&
162 strcmp(stack[c].identifier, identifier) != 0)
163 continue;
164 if (stack[c].identifier == NULL) {
165 /* Found a free slot, let’s store it here. */
166 stack[c].identifier = identifier;
167 stack[c].val.str = sstrdup(str);
168 stack[c].type = STACK_STR;
169 } else {
170 /* Append the value. */
171 char *prev = stack[c].val.str;
172 sasprintf(&(stack[c].val.str), "%s,%s", prev, str);
173 free(prev);
174 }
175 return;
176 }
177
178 /* When we arrive here, the stack is full. This should not happen and
179 * means there’s either a bug in this parser or the specification
180 * contains a command with more than 10 identified tokens. */
181 fprintf(stderr, "BUG: commands_parser stack full. This means either a bug "
182 "in the code, or a new command which contains more than "
183 "10 identified tokens.\n");
184 exit(1);
185 }
186
187 static void push_long(const char *identifier, long num) {
188 for (int c = 0; c < 10; c++) {
189 if (stack[c].identifier != NULL)
190 continue;
191 /* Found a free slot, let’s store it here. */
192 stack[c].identifier = identifier;
193 stack[c].val.num = num;
194 stack[c].type = STACK_LONG;
195 return;
196 }
197
198 /* When we arrive here, the stack is full. This should not happen and
199 * means there’s either a bug in this parser or the specification
200 * contains a command with more than 10 identified tokens. */
201 fprintf(stderr, "BUG: commands_parser stack full. This means either a bug "
202 "in the code, or a new command which contains more than "
203 "10 identified tokens.\n");
204 exit(1);
205 }
206
207 static const char *get_string(const char *identifier) {
208 for (int c = 0; c < 10; c++) {
209 if (stack[c].identifier == NULL)
210 break;
211 if (strcmp(identifier, stack[c].identifier) == 0)
212 return stack[c].val.str;
213 }
214 return NULL;
215 }
216
217 static void clear_stack(void) {
218 for (int c = 0; c < 10; c++) {
219 if (stack[c].type == STACK_STR)
220 free(stack[c].val.str);
221 stack[c].identifier = NULL;
222 stack[c].val.str = NULL;
223 stack[c].val.num = 0;
224 }
225 }
226
227 /*
228 * Returns true if sym is bound to any key except for 'except_keycode' on the
229 * first four layers (normal, shift, mode_switch, mode_switch + shift).
230 *
231 */
232 static bool keysym_used_on_other_key(KeySym sym, xcb_keycode_t except_keycode) {
233 xcb_keycode_t i,
234 min_keycode = xcb_get_setup(conn)->min_keycode,
235 max_keycode = xcb_get_setup(conn)->max_keycode;
236
237 for (i = min_keycode; i && i <= max_keycode; i++) {
238 if (i == except_keycode)
239 continue;
240 for (int level = 0; level < 4; level++) {
241 if (xcb_key_symbols_get_keysym(keysyms, i, level) != sym)
242 continue;
243 return true;
244 }
245 }
246 return false;
247 }
248
249 static char *next_state(const cmdp_token *token) {
250 cmdp_state _next_state = token->next_state;
251
252 if (token->next_state == __CALL) {
253 const char *modifiers = get_string("modifiers");
254 int keycode = atoi(get_string("key"));
255 int level = 0;
256 if (modifiers != NULL &&
257 strstr(modifiers, "Shift") != NULL) {
258 /* When shift is included, we really need to use the second-level
259 * symbol (upper-case). The lower-case symbol could be on a
260 * different key than the upper-case one (unlikely for letters, but
261 * more likely for special characters). */
262 level = 1;
263
264 /* Try to use the keysym on the first level (lower-case). In case
265 * this doesn’t make it ambiguous (think of a keyboard layout
266 * having '1' on two different keys, but '!' only on keycode 10),
267 * we’ll stick with the keysym of the first level.
268 *
269 * This reduces a lot of confusion for users who switch keyboard
270 * layouts from qwerty to qwertz or other slight variations of
271 * qwerty (yes, that happens quite often). */
272 const xkb_keysym_t *syms;
273 int num = xkb_keymap_key_get_syms_by_level(xkb_keymap, keycode, 0, 0, &syms);
274 if (num == 0)
275 errx(1, "xkb_keymap_key_get_syms_by_level returned no symbols for keycode %d", keycode);
276 if (!keysym_used_on_other_key(syms[0], keycode))
277 level = 0;
278 }
279
280 const xkb_keysym_t *syms;
281 int num = xkb_keymap_key_get_syms_by_level(xkb_keymap, keycode, 0, level, &syms);
282 if (num == 0)
283 errx(1, "xkb_keymap_key_get_syms_by_level returned no symbols for keycode %d", keycode);
284 if (num > 1)
285 printf("xkb_keymap_key_get_syms_by_level (keycode = %d) returned %d symbolsinstead of 1, using only the first one.\n", keycode, num);
286
287 char str[4096];
288 if (xkb_keysym_get_name(syms[0], str, sizeof(str)) == -1)
289 errx(EXIT_FAILURE, "xkb_keysym_get_name(%u) failed", syms[0]);
290 const char *release = get_string("release");
291 char *res;
292 char *modrep = (modifiers == NULL ? sstrdup("") : sstrdup(modifiers));
293 char *comma;
294 while ((comma = strchr(modrep, ',')) != NULL) {
295 *comma = '+';
296 }
297 sasprintf(&res, "bindsym %s%s%s %s%s\n", (modifiers == NULL ? "" : modrep), (modifiers == NULL ? "" : "+"), str, (release == NULL ? "" : release), get_string("command"));
298 clear_stack();
299 free(modrep);
300 return res;
301 }
302
303 state = _next_state;
304
305 /* See if we are jumping back to a state in which we were in previously
306 * (statelist contains INITIAL) and just move statelist_idx accordingly. */
307 for (int i = 0; i < statelist_idx; i++) {
308 if (statelist[i] != _next_state)
309 continue;
310 statelist_idx = i + 1;
311 return NULL;
312 }
313
314 /* Otherwise, the state is new and we add it to the list */
315 statelist[statelist_idx++] = _next_state;
316 return NULL;
317 }
318
319 static char *rewrite_binding(const char *input) {
320 state = INITIAL;
321 statelist_idx = 1;
322
323 const char *walk = input;
324 const size_t len = strlen(input);
325 int c;
326 const cmdp_token *token;
327 char *result = NULL;
328
329 /* The "<=" operator is intentional: We also handle the terminating 0-byte
330 * explicitly by looking for an 'end' token. */
331 while ((size_t)(walk - input) <= len) {
332 /* Skip whitespace before every token, newlines are relevant since they
333 * separate configuration directives. */
334 while ((*walk == ' ' || *walk == '\t') && *walk != '\0')
335 walk++;
336
337 //printf("remaining input: %s\n", walk);
338
339 cmdp_token_ptr *ptr = &(tokens[state]);
340 for (c = 0; c < ptr->n; c++) {
341 token = &(ptr->array[c]);
342
343 /* A literal. */
344 if (token->name[0] == '\'') {
345 if (strncasecmp(walk, token->name + 1, strlen(token->name) - 1) == 0) {
346 if (token->identifier != NULL)
347 push_string(token->identifier, token->name + 1);
348 walk += strlen(token->name) - 1;
349 if ((result = next_state(token)) != NULL)
350 return result;
351 break;
352 }
353 continue;
354 }
355
356 if (strcmp(token->name, "number") == 0) {
357 /* Handle numbers. We only accept decimal numbers for now. */
358 char *end = NULL;
359 errno = 0;
360 long int num = strtol(walk, &end, 10);
361 if ((errno == ERANGE && (num == LONG_MIN || num == LONG_MAX)) ||
362 (errno != 0 && num == 0))
363 continue;
364
365 /* No valid numbers found */
366 if (end == walk)
367 continue;
368
369 if (token->identifier != NULL)
370 push_long(token->identifier, num);
371
372 /* Set walk to the first non-number character */
373 walk = end;
374 if ((result = next_state(token)) != NULL)
375 return result;
376 break;
377 }
378
379 if (strcmp(token->name, "string") == 0 ||
380 strcmp(token->name, "word") == 0) {
381 const char *beginning = walk;
382 /* Handle quoted strings (or words). */
383 if (*walk == '"') {
384 beginning++;
385 walk++;
386 while (*walk != '\0' && (*walk != '"' || *(walk - 1) == '\\'))
387 walk++;
388 } else {
389 if (token->name[0] == 's') {
390 while (*walk != '\0' && *walk != '\r' && *walk != '\n')
391 walk++;
392 } else {
393 /* For a word, the delimiters are white space (' ' or
394 * '\t'), closing square bracket (]), comma (,) and
395 * semicolon (;). */
396 while (*walk != ' ' && *walk != '\t' &&
397 *walk != ']' && *walk != ',' &&
398 *walk != ';' && *walk != '\r' &&
399 *walk != '\n' && *walk != '\0')
400 walk++;
401 }
402 }
403 if (walk != beginning) {
404 char *str = scalloc(walk - beginning + 1, 1);
405 /* We copy manually to handle escaping of characters. */
406 int inpos, outpos;
407 for (inpos = 0, outpos = 0;
408 inpos < (walk - beginning);
409 inpos++, outpos++) {
410 /* We only handle escaped double quotes to not break
411 * backwards compatibility with people using \w in
412 * regular expressions etc. */
413 if (beginning[inpos] == '\\' && beginning[inpos + 1] == '"')
414 inpos++;
415 str[outpos] = beginning[inpos];
416 }
417 if (token->identifier)
418 push_string(token->identifier, str);
419 free(str);
420 /* If we are at the end of a quoted string, skip the ending
421 * double quote. */
422 if (*walk == '"')
423 walk++;
424 if ((result = next_state(token)) != NULL)
425 return result;
426 break;
427 }
428 }
429
430 if (strcmp(token->name, "end") == 0) {
431 //printf("checking for end: *%s*\n", walk);
432 if (*walk == '\0' || *walk == '\n' || *walk == '\r') {
433 if ((result = next_state(token)) != NULL)
434 return result;
435 /* To make sure we start with an appropriate matching
436 * datastructure for commands which do *not* specify any
437 * criteria, we re-initialize the criteria system after
438 * every command. */
439 // TODO: make this testable
440 walk++;
441 break;
442 }
443 }
444 }
445 }
446
447 return NULL;
448 }
449
450 /*
451 * Having verboselog(), errorlog() and debuglog() is necessary when using libi3.
452 *
453 */
454 void verboselog(char *fmt, ...) {
455 va_list args;
456
457 va_start(args, fmt);
458 vfprintf(stdout, fmt, args);
459 va_end(args);
460 }
461
462 void errorlog(char *fmt, ...) {
463 va_list args;
464
465 va_start(args, fmt);
466 vfprintf(stderr, fmt, args);
467 va_end(args);
468 }
469
470 void debuglog(char *fmt, ...) {
471 }
472
473 static void txt(int col, int row, char *text, color_t fg, color_t bg) {
474 int x = col_x(col);
475 int y = row_y(row);
476 i3String *string = i3string_from_utf8(text);
477 draw_util_text(string, &surface, fg, bg, x, y, WIN_WIDTH - x - TEXT_PADDING);
478 i3string_free(string);
479 }
480
481 /*
482 * Handles expose events, that is, draws the window contents.
483 *
484 */
485 static int handle_expose(void) {
486 const color_t black = draw_util_hex_to_color("#000000");
487 const color_t white = draw_util_hex_to_color("#FFFFFF");
488 const color_t green = draw_util_hex_to_color("#00FF00");
489 const color_t red = draw_util_hex_to_color("#FF0000");
490
491 /* draw background */
492 draw_util_clear_surface(&surface, black);
493
494 set_font(&font);
495
496 if (current_step == STEP_WELCOME) {
497 txt(2, 2, "You have not configured i3 yet.", white, black);
498 txt(2, 3, "Do you want me to generate a config at", white, black);
499
500 char *msg;
501 sasprintf(&msg, "%s?", config_path);
502 txt(2, 4, msg, white, black);
503 free(msg);
504
505 txt(13, 6, "Yes, generate the config", white, black);
506 txt(13, 8, "No, I will use the defaults", white, black);
507
508 txt(4, 6, "<Enter>", green, black);
509
510 txt(5, 8, "<ESC>", red, black);
511 }
512
513 if (current_step == STEP_GENERATE) {
514 txt(2, 2, "Please choose either:", white, black);
515 txt(13, 4, "Win as default modifier", white, black);
516 txt(13, 5, "Alt as default modifier", white, black);
517 txt(2, 7, "Afterwards, press", white, black);
518 txt(13, 9, "to write the config", white, black);
519 txt(13, 10, "to abort", white, black);
520
521 /* the not-selected modifier */
522 if (modifier == MOD_Mod4)
523 txt(5, 5, "<Alt>", white, black);
524 else
525 txt(5, 4, "<Win>", white, black);
526
527 /* the selected modifier */
528 set_font(&bold_font);
529 if (modifier == MOD_Mod4)
530 txt(2, 4, "-> <Win>", white, black);
531 else
532 txt(2, 5, "-> <Alt>", white, black);
533
534 set_font(&font);
535 txt(4, 9, "<Enter>", green, black);
536
537 txt(5, 10, "<ESC>", red, black);
538 }
539
540 xcb_flush(conn);
541
542 return 1;
543 }
544
545 static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_t *event) {
546 printf("Keypress %d, state raw = %d\n", event->detail, event->state);
547
548 /* Remove the numlock bit, all other bits are modifiers we can bind to */
549 uint16_t state_filtered = event->state & ~(xcb_numlock_mask | XCB_MOD_MASK_LOCK);
550 /* Only use the lower 8 bits of the state (modifier masks) so that mouse
551 * button masks are filtered out */
552 state_filtered &= 0xFF;
553
554 xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, state_filtered);
555
556 printf("sym = %c (%d)\n", sym, sym);
557
558 if (sym == XK_Return || sym == XK_KP_Enter) {
559 if (current_step == STEP_WELCOME) {
560 current_step = STEP_GENERATE;
561 /* Set window title */
562 xcb_change_property(conn,
563 XCB_PROP_MODE_REPLACE,
564 win,
565 A__NET_WM_NAME,
566 A_UTF8_STRING,
567 8,
568 strlen("i3: generate config"),
569 "i3: generate config");
570 xcb_flush(conn);
571 } else
572 finish();
573 }
574
575 /* Swap between modifiers when up or down is pressed. */
576 if (sym == XK_Up || sym == XK_Down) {
577 modifier = (modifier == MOD_Mod1) ? MOD_Mod4 : MOD_Mod1;
578 handle_expose();
579 }
580
581 /* cancel any time */
582 if (sym == XK_Escape)
583 exit(0);
584
585 /* Check if this is Mod1 or Mod4. The modmap contains Shift, Lock, Control,
586 * Mod1, Mod2, Mod3, Mod4, Mod5 (in that order) */
587 xcb_keycode_t *modmap = xcb_get_modifier_mapping_keycodes(modmap_reply);
588 /* Mod1? */
589 int mask = 3;
590 for (int i = 0; i < modmap_reply->keycodes_per_modifier; i++) {
591 xcb_keycode_t code = modmap[(mask * modmap_reply->keycodes_per_modifier) + i];
592 if (code == XCB_NONE)
593 continue;
594 printf("Modifier keycode for Mod1: 0x%02x\n", code);
595 if (code == event->detail) {
596 modifier = MOD_Mod1;
597 printf("This is Mod1!\n");
598 }
599 }
600
601 /* Mod4? */
602 mask = 6;
603 for (int i = 0; i < modmap_reply->keycodes_per_modifier; i++) {
604 xcb_keycode_t code = modmap[(mask * modmap_reply->keycodes_per_modifier) + i];
605 if (code == XCB_NONE)
606 continue;
607 printf("Modifier keycode for Mod4: 0x%02x\n", code);
608 if (code == event->detail) {
609 modifier = MOD_Mod4;
610 printf("This is Mod4!\n");
611 }
612 }
613
614 handle_expose();
615 return 1;
616 }
617
618 /*
619 * Handle button presses to make clicking on "<win>" and "<alt>" work
620 *
621 */
622 static void handle_button_press(xcb_button_press_event_t *event) {
623 if (current_step != STEP_GENERATE)
624 return;
625
626 if (event->event_x < col_x(5) || event->event_x > col_x(10))
627 return;
628
629 if (event->event_y >= row_y(4) && event->event_y <= (row_y(4) + font.height)) {
630 modifier = MOD_Mod4;
631 handle_expose();
632 }
633
634 if (event->event_y >= row_y(5) && event->event_y <= (row_y(5) + font.height)) {
635 modifier = MOD_Mod1;
636 handle_expose();
637 }
638 }
639
640 /*
641 * Creates the config file and tells i3 to reload.
642 *
643 */
644 static void finish(void) {
645 printf("creating \"%s\"...\n", config_path);
646
647 struct xkb_context *xkb_context;
648
649 if ((xkb_context = xkb_context_new(0)) == NULL)
650 errx(1, "could not create xkbcommon context");
651
652 int32_t device_id = xkb_x11_get_core_keyboard_device_id(conn);
653 if ((xkb_keymap = xkb_x11_keymap_new_from_device(xkb_context, conn, device_id, 0)) == NULL)
654 errx(1, "xkb_x11_keymap_new_from_device failed");
655
656 FILE *kc_config = fopen(SYSCONFDIR "/i3/config.keycodes", "r");
657 if (kc_config == NULL)
658 err(1, "Could not open input file \"%s\"", SYSCONFDIR "/i3/config.keycodes");
659
660 FILE *ks_config = fopen(config_path, "w");
661 if (ks_config == NULL)
662 err(1, "Could not open output config file \"%s\"", config_path);
663 free(config_path);
664
665 char *line = NULL;
666 size_t len = 0;
667 #ifndef USE_FGETLN
668 ssize_t read;
669 #endif
670 bool head_of_file = true;
671
672 /* write a header about auto-generation to the output file */
673 fputs("# This file has been auto-generated by i3-config-wizard(1).\n", ks_config);
674 fputs("# It will not be overwritten, so edit it as you like.\n", ks_config);
675 fputs("#\n", ks_config);
676 fputs("# Should you change your keyboard layout some time, delete\n", ks_config);
677 fputs("# this file and re-run i3-config-wizard(1).\n", ks_config);
678 fputs("#\n", ks_config);
679
680 #ifdef USE_FGETLN
681 char *buf = NULL;
682 while ((buf = fgetln(kc_config, &len)) != NULL) {
683 /* fgetln does not return null-terminated strings */
684 FREE(line);
685 sasprintf(&line, "%.*s", len, buf);
686 #else
687 size_t linecap = 0;
688 while ((read = getline(&line, &linecap, kc_config)) != -1) {
689 len = strlen(line);
690 #endif
691 /* skip the warning block at the beginning of the input file */
692 if (head_of_file &&
693 strncmp("# WARNING", line, strlen("# WARNING")) == 0)
694 continue;
695
696 head_of_file = false;
697
698 /* Skip leading whitespace */
699 char *walk = line;
700 while (isspace(*walk) && walk < (line + len)) {
701 /* Pre-output the skipped whitespaces to keep proper indentation */
702 fputc(*walk, ks_config);
703 walk++;
704 }
705
706 /* Set the modifier the user chose */
707 if (strncmp(walk, "set $mod ", strlen("set $mod ")) == 0) {
708 if (modifier == MOD_Mod1)
709 fputs("set $mod Mod1\n", ks_config);
710 else
711 fputs("set $mod Mod4\n", ks_config);
712 continue;
713 }
714
715 /* Check for 'bindcode'. If it’s not a bindcode line, we
716 * just copy it to the output file */
717 if (strncmp(walk, "bindcode", strlen("bindcode")) != 0) {
718 fputs(walk, ks_config);
719 continue;
720 }
721 char *result = rewrite_binding(walk);
722 fputs(result, ks_config);
723 free(result);
724 }
725
726 /* sync to do our best in order to have the file really stored on disk */
727 fflush(ks_config);
728 fsync(fileno(ks_config));
729
730 #ifndef USE_FGETLN
731 free(line);
732 #endif
733
734 fclose(kc_config);
735 fclose(ks_config);
736
737 /* tell i3 to reload the config file */
738 int sockfd = ipc_connect(socket_path);
739 ipc_send_message(sockfd, strlen("reload"), 0, (uint8_t *)"reload");
740 close(sockfd);
741
742 exit(0);
743 }
744
745 int main(int argc, char *argv[]) {
746 char *xdg_config_home;
747 char *pattern = "pango:monospace 8";
748 char *patternbold = "pango:monospace bold 8";
749 int o, option_index = 0;
750 bool headless_run = false;
751
752 static struct option long_options[] = {
753 {"socket", required_argument, 0, 's'},
754 {"version", no_argument, 0, 'v'},
755 {"modifier", required_argument, 0, 'm'},
756 {"limit", required_argument, 0, 'l'},
757 {"prompt", required_argument, 0, 'P'},
758 {"prefix", required_argument, 0, 'p'},
759 {"font", required_argument, 0, 'f'},
760 {"help", no_argument, 0, 'h'},
761 {0, 0, 0, 0}};
762
763 char *options_string = "sm:vh";
764
765 while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
766 switch (o) {
767 case 's':
768 FREE(socket_path);
769 socket_path = sstrdup(optarg);
770 break;
771 case 'v':
772 printf("i3-config-wizard " I3_VERSION "\n");
773 return 0;
774 case 'm':
775 headless_run = true;
776 if (strcmp(optarg, "alt") == 0)
777 modifier = MOD_Mod1;
778 else if (strcmp(optarg, "win") == 0)
779 modifier = MOD_Mod4;
780 else
781 err(EXIT_FAILURE, "Invalid modifier key %s", optarg);
782 break;
783 case 'h':
784 printf("i3-config-wizard " I3_VERSION "\n");
785 printf("i3-config-wizard [-s <socket>] [-m win|alt] [-v] [-h]\n");
786 return 0;
787 }
788 }
789
790 char *path = get_config_path(NULL, false);
791 if (path != NULL) {
792 printf("The config file \"%s\" already exists. Exiting.\n", path);
793 free(path);
794 return 0;
795 }
796
797 /* Always write to $XDG_CONFIG_HOME/i3/config by default. */
798 if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL)
799 xdg_config_home = "~/.config";
800
801 xdg_config_home = resolve_tilde(xdg_config_home);
802 sasprintf(&config_path, "%s/i3/config", xdg_config_home);
803
804 /* Create $XDG_CONFIG_HOME/i3 if it does not yet exist */
805 char *config_dir;
806 struct stat stbuf;
807 sasprintf(&config_dir, "%s/i3", xdg_config_home);
808 if (stat(config_dir, &stbuf) != 0)
809 if (mkdirp(config_dir, DEFAULT_DIR_MODE) != 0)
810 err(EXIT_FAILURE, "mkdirp(%s) failed", config_dir);
811 free(config_dir);
812 free(xdg_config_home);
813
814 int fd;
815 if ((fd = open(config_path, O_CREAT | O_RDWR, 0644)) == -1) {
816 printf("Cannot open file \"%s\" for writing: %s. Exiting.\n", config_path, strerror(errno));
817 return 0;
818 }
819 close(fd);
820 unlink(config_path);
821
822 int screen;
823 if ((conn = xcb_connect(NULL, &screen)) == NULL ||
824 xcb_connection_has_error(conn))
825 errx(1, "Cannot open display");
826
827 if (xkb_x11_setup_xkb_extension(conn,
828 XKB_X11_MIN_MAJOR_XKB_VERSION,
829 XKB_X11_MIN_MINOR_XKB_VERSION,
830 0,
831 NULL,
832 NULL,
833 &xkb_base_event,
834 &xkb_base_error) != 1)
835 errx(EXIT_FAILURE, "Could not setup XKB extension.");
836
837 keysyms = xcb_key_symbols_alloc(conn);
838 xcb_get_modifier_mapping_cookie_t modmap_cookie;
839 modmap_cookie = xcb_get_modifier_mapping(conn);
840 symbols = xcb_key_symbols_alloc(conn);
841
842 if (headless_run) {
843 finish();
844 return 0;
845 }
846
847 /* Place requests for the atoms we need as soon as possible */
848 #define xmacro(atom) \
849 xcb_intern_atom_cookie_t atom##_cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom);
850 #include "atoms.xmacro"
851 #undef xmacro
852
853 /* Init startup notification. */
854 SnDisplay *sndisplay = sn_xcb_display_new(conn, NULL, NULL);
855 SnLauncheeContext *sncontext = sn_launchee_context_new_from_environment(sndisplay, screen);
856 sn_display_unref(sndisplay);
857
858 root_screen = xcb_aux_get_screen(conn, screen);
859 root = root_screen->root;
860
861 if (!(modmap_reply = xcb_get_modifier_mapping_reply(conn, modmap_cookie, NULL)))
862 errx(EXIT_FAILURE, "Could not get modifier mapping");
863
864 xcb_numlock_mask = get_mod_mask_for(XCB_NUM_LOCK, symbols, modmap_reply);
865
866 init_dpi();
867 font = load_font(pattern, true);
868 bold_font = load_font(patternbold, true);
869
870 /* Determine character width in the default font. */
871 set_font(&font);
872 char_width = predict_text_width(i3string_from_utf8("a"));
873
874 /* Open an input window */
875 win = xcb_generate_id(conn);
876 xcb_create_window(
877 conn,
878 XCB_COPY_FROM_PARENT,
879 win, /* the window id */
880 root, /* parent == root */
881 WIN_POS_X, WIN_POS_Y, WIN_WIDTH, WIN_HEIGHT, /* dimensions */
882 0, /* X11 border = 0, we draw our own */
883 XCB_WINDOW_CLASS_INPUT_OUTPUT,
884 XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from parent */
885 XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK,
886 (uint32_t[]){
887 0, /* back pixel: black */
888 XCB_EVENT_MASK_EXPOSURE |
889 XCB_EVENT_MASK_BUTTON_PRESS});
890 if (sncontext) {
891 sn_launchee_context_setup_window(sncontext, win);
892 }
893
894 /* Map the window (make it visible) */
895 xcb_map_window(conn, win);
896
897 /* Setup NetWM atoms */
898 #define xmacro(name) \
899 do { \
900 xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, name##_cookie, NULL); \
901 if (!reply) \
902 errx(EXIT_FAILURE, "Could not get atom " #name); \
903 \
904 A_##name = reply->atom; \
905 free(reply); \
906 } while (0);
907 #include "atoms.xmacro"
908 #undef xmacro
909
910 /* Set dock mode */
911 xcb_change_property(conn,
912 XCB_PROP_MODE_REPLACE,
913 win,
914 A__NET_WM_WINDOW_TYPE,
915 A_ATOM,
916 32,
917 1,
918 (unsigned char *)&A__NET_WM_WINDOW_TYPE_DIALOG);
919
920 /* Set window title */
921 xcb_change_property(conn,
922 XCB_PROP_MODE_REPLACE,
923 win,
924 A__NET_WM_NAME,
925 A_UTF8_STRING,
926 8,
927 strlen("i3: first configuration"),
928 "i3: first configuration");
929
930 /* Initialize drawable surface */
931 draw_util_surface_init(conn, &surface, win, get_visualtype(root_screen), WIN_WIDTH, WIN_HEIGHT);
932
933 /* Grab the keyboard to get all input */
934 xcb_flush(conn);
935
936 /* Try (repeatedly, if necessary) to grab the keyboard. We might not
937 * get the keyboard at the first attempt because of the keybinding
938 * still being active when started via a wm’s keybinding. */
939 xcb_grab_keyboard_cookie_t cookie;
940 xcb_grab_keyboard_reply_t *reply = NULL;
941
942 int count = 0;
943 while ((reply == NULL || reply->status != XCB_GRAB_STATUS_SUCCESS) && (count++ < 500)) {
944 cookie = xcb_grab_keyboard(conn, false, win, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
945 reply = xcb_grab_keyboard_reply(conn, cookie, NULL);
946 usleep(1000);
947 }
948
949 if (reply->status != XCB_GRAB_STATUS_SUCCESS) {
950 fprintf(stderr, "Could not grab keyboard, status = %d\n", reply->status);
951 exit(-1);
952 }
953
954 /* Startup complete. */
955 if (sncontext) {
956 sn_launchee_context_complete(sncontext);
957 sn_launchee_context_unref(sncontext);
958 }
959
960 xcb_flush(conn);
961
962 xcb_generic_event_t *event;
963 while ((event = xcb_wait_for_event(conn)) != NULL) {
964 if (event->response_type == 0) {
965 fprintf(stderr, "X11 Error received! sequence %x\n", event->sequence);
966 continue;
967 }
968
969 /* Strip off the highest bit (set if the event is generated) */
970 int type = (event->response_type & 0x7F);
971
972 /* TODO: handle mappingnotify */
973 switch (type) {
974 case XCB_KEY_PRESS:
975 handle_key_press(NULL, conn, (xcb_key_press_event_t *)event);
976 break;
977
978 case XCB_BUTTON_PRESS:
979 handle_button_press((xcb_button_press_event_t *)event);
980 break;
981
982 case XCB_EXPOSE:
983 if (((xcb_expose_event_t *)event)->count == 0) {
984 handle_expose();
985 }
986
987 break;
988 }
989
990 free(event);
991 }
992
993 /* Dismiss drawable surface */
994 draw_util_surface_free(conn, &surface);
995
996 return 0;
997 }
0 #pragma once
1
2 /* from X11/keysymdef.h */
3 #define XCB_NUM_LOCK 0xff7f
4
5 #define xmacro(atom) xcb_atom_t A_##atom;
6 #include "atoms.xmacro"
7 #undef xmacro
0 #!/usr/bin/env perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # © 2012 Michael Stapelberg
4 #
5 # No dependencies except for perl ≥ v5.10
6
7 use strict;
8 use warnings qw(FATAL utf8);
9 use Data::Dumper;
10 use IPC::Open2;
11 use POSIX qw(locale_h);
12 use File::Find;
13 use File::Basename qw(basename);
14 use File::Temp qw(tempfile);
15 use Getopt::Long;
16 use Pod::Usage;
17 use v5.10;
18 use utf8;
19 use open ':encoding(UTF-8)';
20
21 binmode STDOUT, ':utf8';
22 binmode STDERR, ':utf8';
23
24 # reads in a whole file
25 sub slurp {
26 my ($filename) = @_;
27 my $fh;
28 if (!open($fh, '<', $filename)) {
29 warn "Could not open $filename: $!";
30 return undef;
31 }
32 local $/;
33 my $result;
34 eval {
35 $result = <$fh>;
36 };
37 if ($@) {
38 warn "Could not read $filename: $@";
39 return undef;
40 } else {
41 return $result;
42 }
43 }
44
45 my @entry_types;
46 my $dmenu_cmd = 'dmenu -i';
47 my $result = GetOptions(
48 'dmenu=s' => \$dmenu_cmd,
49 'entry-type=s' => \@entry_types,
50 'version' => sub {
51 say "dmenu-desktop 1.5 © 2012 Michael Stapelberg";
52 exit 0;
53 },
54 'help' => sub {
55 pod2usage(-exitval => 0);
56 });
57
58 die "Could not parse command line options" unless $result;
59
60 # Filter entry types and set default type(s) if none selected
61 my $valid_types = {
62 name => 1,
63 command => 1,
64 filename => 1,
65 };
66 @entry_types = grep { exists($valid_types->{$_}) } @entry_types;
67 @entry_types = ('name', 'command') unless @entry_types;
68
69 # ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
70 # ┃ Convert LC_MESSAGES into an ordered list of suffixes to search for in the ┃
71 # ┃ .desktop files (e.g. “Name[de_DE@euro]” for LC_MESSAGES=de_DE.UTF-8@euro ┃
72 # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
73
74 # For details on how the transformation of LC_MESSAGES to a list of keys that
75 # should be looked up works, refer to “Localized values for keys” of the
76 # “Desktop Entry Specification”:
77 # https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s04.html
78 my $lc_messages = setlocale(LC_MESSAGES);
79
80 # Ignore the encoding (e.g. .UTF-8)
81 $lc_messages =~ s/\.[^@]+//g;
82
83 my @suffixes = ($lc_messages);
84
85 # _COUNTRY and @MODIFIER are present
86 if ($lc_messages =~ /_[^@]+@/) {
87 my $no_modifier = $lc_messages;
88 $no_modifier =~ s/@.*//g;
89 push @suffixes, $no_modifier;
90
91 my $no_country = $lc_messages;
92 $no_country =~ s/_[^@]+//g;
93 push @suffixes, $no_country;
94 }
95
96 # Strip _COUNTRY and @MODIFIER if present
97 $lc_messages =~ s/[_@].*//g;
98 push @suffixes, $lc_messages;
99
100 # ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
101 # ┃ Read all .desktop files and store the values in which we are interested. ┃
102 # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
103
104 my %desktops;
105 # See https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html#variables
106 my $xdg_data_home = $ENV{XDG_DATA_HOME};
107 $xdg_data_home = $ENV{HOME} . '/.local/share' if
108 !defined($xdg_data_home) ||
109 $xdg_data_home eq '' ||
110 ! -d $xdg_data_home;
111
112 my $xdg_data_dirs = $ENV{XDG_DATA_DIRS};
113 $xdg_data_dirs = '/usr/local/share/:/usr/share/' if
114 !defined($xdg_data_dirs) ||
115 $xdg_data_dirs eq '';
116
117 my @searchdirs = ("$xdg_data_home/applications/");
118 for my $dir (split(':', $xdg_data_dirs)) {
119 push @searchdirs, "$dir/applications/";
120 }
121
122 # Cleanup the paths, maybe some application does not cope with double slashes
123 # (the field code %k is replaced with the .desktop file location).
124 @searchdirs = map { s,//,/,g; $_ } @searchdirs;
125
126 # To avoid errors by File::Find’s find(), only pass existing directories.
127 @searchdirs = grep { -d $_ } @searchdirs;
128
129 find(
130 {
131 wanted => sub {
132 return unless substr($_, -1 * length('.desktop')) eq '.desktop';
133 my $relative = $File::Find::name;
134
135 # + 1 for the trailing /, which is missing in ::topdir.
136 substr($relative, 0, length($File::Find::topdir) + 1) = '';
137
138 # Don’t overwrite files with the same relative path, we search in
139 # descending order of importance.
140 return if exists($desktops{$relative});
141
142 $desktops{$relative} = $File::Find::name;
143 },
144 no_chdir => 1,
145 follow_fast => 1,
146 },
147 @searchdirs
148 );
149
150 my %apps;
151
152 for my $file (values %desktops) {
153 my $base = basename($file);
154
155 # _ is an invalid character for a key, so we can use it for our own keys.
156 $apps{$base}->{_Location} = $file;
157
158 # Extract all “Name” and “Exec” keys from the [Desktop Entry] group
159 # and store them in $apps{$base}.
160 my %names;
161 my $content = slurp($file);
162 next unless defined($content);
163 my @lines = split("\n", $content);
164 for my $line (@lines) {
165 my $first = substr($line, 0, 1);
166 next if $line eq '' || $first eq '#';
167 next unless ($line eq '[Desktop Entry]' ..
168 ($first eq '[' &&
169 substr($line, -1) eq ']' &&
170 $line ne '[Desktop Entry]'));
171 next if $first eq '[';
172
173 my ($key, $value) = ($line =~ /^
174 (
175 [A-Za-z0-9-]+ # the spec specifies these as valid key characters
176 (?:\[[^]]+\])? # possibly, there as a locale suffix
177 )
178 \s* = \s* # whitespace around = should be ignored
179 (.*) # no restrictions on the values
180 $/x);
181
182 if ($key =~ /^Name/) {
183 $names{$key} = $value;
184 } elsif ($key eq 'Exec' ||
185 $key eq 'TryExec' ||
186 $key eq 'Path' ||
187 $key eq 'Type') {
188 $apps{$base}->{$key} = $value;
189 } elsif ($key eq 'NoDisplay' ||
190 $key eq 'Hidden' ||
191 $key eq 'StartupNotify' ||
192 $key eq 'Terminal') {
193 # Values of type boolean must either be string true or false,
194 # see “Possible value types”:
195 # https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s03.html
196 $apps{$base}->{$key} = ($value eq 'true');
197 }
198 }
199
200 for my $suffix (@suffixes) {
201 next unless exists($names{"Name[$suffix]"});
202 $apps{$base}->{Name} = $names{"Name[$suffix]"};
203 last;
204 }
205
206 # Fallback to unlocalized “Name”.
207 $apps{$base}->{Name} = $names{Name} unless exists($apps{$base}->{Name});
208 }
209
210 # %apps now looks like this:
211 #
212 # %apps = {
213 # 'evince.desktop' => {
214 # 'Exec' => 'evince %U',
215 # 'Name' => 'Dokumentenbetrachter',
216 # '_Location' => '/usr/share/applications/evince.desktop'
217 # },
218 # 'gedit.desktop' => {
219 # 'Exec' => 'gedit %U',
220 # 'Name' => 'gedit',
221 # '_Location' => '/usr/share/applications/gedit.desktop'
222 # }
223 # };
224
225 # ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
226 # ┃ Turn %apps inside out to provide Name → filename lookup. ┃
227 # ┃ The Name is what we display in dmenu later. ┃
228 # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
229
230 my %choices;
231 for my $app (keys %apps) {
232 my $name = $apps{$app}->{Name};
233
234 # Don’t try to use .desktop files which don’t have Type=application
235 next if (!exists($apps{$app}->{Type}) ||
236 $apps{$app}->{Type} ne 'Application');
237
238 # Skip broken files (Type=application, but no Exec key).
239 if (!exists($apps{$app}->{Exec}) ||
240 $apps{$app}->{Exec} eq '') {
241 warn 'File ' . $apps{$app}->{_Location} . ' is broken: it contains Type=Application, but no Exec key/value pair.';
242 next;
243 }
244
245 # Don’t offer apps which have NoDisplay == true or Hidden == true.
246 # See https://wiki.xfce.org/howto/customize-menu#hide_menu_entries
247 # for the difference between NoDisplay and Hidden.
248 next if (exists($apps{$app}->{NoDisplay}) && $apps{$app}->{NoDisplay}) ||
249 (exists($apps{$app}->{Hidden}) && $apps{$app}->{Hidden});
250
251 if (exists($apps{$app}->{TryExec})) {
252 my $tryexec = $apps{$app}->{TryExec};
253 if (substr($tryexec, 0, 1) eq '/') {
254 # Skip if absolute path is not executable.
255 next unless -x $tryexec;
256 } else {
257 # Search in $PATH for the executable.
258 my $found = 0;
259 for my $path (split(':', $ENV{PATH})) {
260 next unless -x "$path/$tryexec";
261 $found = 1;
262 last;
263 }
264 next unless $found;
265 }
266 }
267
268 if ((scalar grep { $_ eq 'name' } @entry_types) > 0) {
269 if (exists($choices{$name})) {
270 # There are two .desktop files which contain the same “Name” value.
271 # I’m not sure if that is allowed to happen, but we disambiguate the
272 # situation by appending “ (2)”, “ (3)”, etc. to the name.
273 #
274 # An example of this happening is exo-file-manager.desktop and
275 # thunar-settings.desktop, both of which contain “Name=File Manager”.
276 my $inc = 2;
277 $inc++ while exists($choices{"$name ($inc)"});
278 $name = "$name ($inc)";
279 }
280
281 $choices{$name} = $app;
282 next;
283 }
284
285 if ((scalar grep { $_ eq 'command' } @entry_types) > 0) {
286 my $command = $apps{$app}->{Exec};
287
288 # Handle escape sequences (should be done for all string values, but does
289 # matter here).
290 my %escapes = (
291 '\\s' => ' ',
292 '\\n' => '\n',
293 '\\t' => '\t',
294 '\\r' => '\r',
295 '\\\\' => '\\',
296 );
297 $command =~ s/(\\[sntr\\])/$escapes{$1}/go;
298
299 # Extract executable
300 if ($command =~ m/^\s*([^\s\"]+)(?:\s|$)/) {
301 # No quotes
302 $command = $1;
303 } elsif ($command =~ m/^\s*\"([^\"\\]*(?:\\.[^\"\\]*)*)\"(?:\s|$)/) {
304 # Quoted, remove quotes and fix escaped characters
305 $command = $1;
306 $command =~ s/\\([\"\`\$\\])/$1/g;
307 } else {
308 # Invalid quotes, fallback to whitespace
309 ($command) = split(' ', $command);
310 }
311
312 # Don’t add “geany” if “Geany” is already present.
313 my @keys = map { lc } keys %choices;
314 if (!(scalar grep { $_ eq lc(basename($command)) } @keys) > 0) {
315 $choices{basename($command)} = $app;
316 }
317 next;
318 }
319
320 if ((scalar grep { $_ eq 'filename' } @entry_types) > 0) {
321 my $filename = basename($app, '.desktop');
322
323 # Don’t add “geany” if “Geany” is already present.
324 my @keys = map { lc } keys %choices;
325 next if (scalar grep { $_ eq lc($filename) } @keys) > 0;
326
327 $choices{$filename} = $app;
328 }
329 }
330
331 # %choices now looks like this:
332 #
333 # %choices = {
334 # 'Dokumentenbetrachter' => 'evince.desktop',
335 # 'gedit' => 'gedit.desktop'
336 # };
337
338 # ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
339 # ┃ Run dmenu to ask the user for their choice ┃
340 # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
341
342 # open2 will just make dmenu’s STDERR go to our own STDERR.
343 my ($dmenu_out, $dmenu_in);
344 my $pid = eval {
345 open2($dmenu_out, $dmenu_in, $dmenu_cmd);
346 } or do {
347 print STDERR "$@";
348 say STDERR "Running dmenu failed. Is dmenu installed at all? Try running dmenu -v";
349 exit 1;
350 };
351
352 binmode $dmenu_in, ':utf8';
353 binmode $dmenu_out, ':utf8';
354
355 # Feed dmenu the possible choices.
356 say $dmenu_in $_ for sort keys %choices;
357 close($dmenu_in);
358
359 waitpid($pid, 0);
360 my $status = ($? >> 8);
361
362 # Pass on dmenu’s exit status if there was an error.
363 exit $status unless $status == 0;
364
365 my $choice = <$dmenu_out>;
366 # dmenu ≥ 4.4 adds a newline after the choice
367 chomp($choice);
368 my $app;
369 # Exact match: the user chose “Avidemux (GTK+)”
370 if (exists($choices{$choice})) {
371 $app = $apps{$choices{$choice}};
372 $choice = '';
373 } else {
374 # Not an exact match: the user entered “Avidemux (GTK+) ~/movie.mp4”
375 for my $possibility (keys %choices) {
376 next unless substr($choice, 0, length($possibility)) eq $possibility;
377 $app = $apps{$choices{$possibility}};
378 substr($choice, 0, length($possibility)) = '';
379 # Remove whitespace separating the entry and arguments.
380 $choice =~ s/^\s//g;
381 last;
382 }
383 if (!defined($app)) {
384 warn "Invalid input: “$choice” does not match any application. Trying to execute nevertheless.";
385 $app->{Name} = '';
386 $app->{Exec} = $choice;
387 # We assume that the app is old and does not support startup
388 # notifications because it doesn’t ship a desktop file.
389 $app->{StartupNotify} = 0;
390 $app->{_Location} = '';
391 }
392 }
393
394 # ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
395 # ┃ Make i3 start the chosen application. ┃
396 # ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
397
398 my $name = $app->{Name};
399 my $exec = $app->{Exec};
400 my $location = $app->{_Location};
401
402 # Quote as described by “The Exec key”:
403 # https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html
404 sub quote {
405 my ($str) = @_;
406 $str =~ s/("|`|\$|\\)/\\$1/g;
407 $str = qq|"$str"| if $str ne "";
408 return $str;
409 }
410
411 $choice = quote($choice);
412 $location = quote($location);
413 $name = quote($name);
414
415 # Remove deprecated field codes, as the spec dictates.
416 $exec =~ s/%[dDnNvm]//g;
417
418 # Replace filename field codes with the rest of the command line.
419 # Note that we assume the user uses precisely one file name,
420 # not multiple file names.
421 $exec =~ s/%[fF]/$choice/g;
422
423 # If the program works with URLs,
424 # we assume the user provided a URL instead of a filename.
425 # As per the spec, there must be at most one of %f, %u, %F or %U present.
426 $exec =~ s/%[uU]/$choice/g;
427
428 # The translated name of the application.
429 $exec =~ s/%c/$name/g;
430
431 # XXX: Icons are not implemented. Is the complexity (looking up the path if
432 # only a name is given) actually worth it?
433 #$exec =~ s/%i/--icon $icon/g;
434 $exec =~ s/%i//g;
435
436 # location of .desktop file
437 $exec =~ s/%k/$location/g;
438
439 # Literal % characters are represented as %%.
440 $exec =~ s/%%/%/g;
441
442 if (exists($app->{Path}) && $app->{Path} ne '') {
443 $exec = 'cd ' . quote($app->{Path}) . ' && ' . $exec;
444 }
445
446 my $nosn = '';
447 my $cmd;
448 if (exists($app->{Terminal}) && $app->{Terminal}) {
449 # For applications which specify “Terminal=true” (e.g. htop.desktop),
450 # we need to create a temporary script that contains the full command line
451 # as the syntax for starting commands with arguments varies from terminal
452 # emulator to terminal emulator.
453 # Then, we launch that script with i3-sensible-terminal.
454 my ($fh, $filename) = tempfile();
455 binmode($fh, ':utf8');
456 say $fh <<EOT;
457 #!/bin/sh
458 rm $filename
459 exec $exec
460 EOT
461 close($fh);
462 chmod 0755, $filename;
463
464 $cmd = qq|exec i3-sensible-terminal -e "$filename"|;
465 } else {
466 # i3 executes applications by passing the argument to i3’s “exec” command
467 # as-is to $SHELL -c. The i3 parser supports quoted strings: When a string
468 # starts with a double quote ("), everything is parsed as-is until the next
469 # double quote which is NOT preceded by a backslash (\).
470 #
471 # Therefore, we escape all double quotes (") by replacing them with \"
472 $exec =~ s/"/\\"/g;
473
474 if (exists($app->{StartupNotify}) && !$app->{StartupNotify}) {
475 $nosn = '--no-startup-id';
476 }
477 $cmd = qq|exec $nosn "$exec"|;
478 }
479
480 system('i3-msg', $cmd) == 0 or die "Could not launch i3-msg: $?";
481
482 =encoding utf-8
483
484 =head1 NAME
485
486 i3-dmenu-desktop - run .desktop files with dmenu
487
488 =head1 SYNOPSIS
489
490 i3-dmenu-desktop [--dmenu='dmenu -i'] [--entry-type=name]
491
492 =head1 DESCRIPTION
493
494 i3-dmenu-desktop is a script which extracts the (localized) name from
495 application .desktop files, offers the user a choice via dmenu(1) and then
496 starts the chosen application via i3 (for startup notification support).
497 The advantage of using .desktop files instead of dmenu_run(1) is that dmenu_run
498 offers B<all> binaries in your $PATH, including non-interactive utilities like
499 "sed". Also, .desktop files contain a proper name, information about whether
500 the application runs in a terminal and whether it supports startup
501 notifications.
502
503 The .desktop files are searched in $XDG_DATA_HOME/applications (by default
504 $HOME/.local/share/applications) and in the "applications" subdirectory of each
505 entry of $XDG_DATA_DIRS (by default /usr/local/share/:/usr/share/).
506
507 Files with the same name in $XDG_DATA_HOME/applications take precedence over
508 files in $XDG_DATA_DIRS, so that you can overwrite parts of the system-wide
509 .desktop files by copying them to your local directory and making changes.
510
511 i3-dmenu-desktop displays the "Name" value in the localized version depending
512 on LC_MESSAGES as specified in the Desktop Entry Specification.
513
514 You can pass a filename or URL (%f/%F and %u/%U field codes in the .desktop
515 file respectively) by appending it to the name of the application. E.g., if you
516 want to launch "GNU Emacs 24" with the patch /tmp/foobar.txt, you would type
517 "emacs", press TAB, type " /tmp/foobar.txt" and press ENTER.
518
519 .desktop files with Terminal=true are started using i3-sensible-terminal(1).
520
521 .desktop files with NoDisplay=true or Hidden=true are skipped.
522
523 UTF-8 is supported, of course, but dmenu does not support displaying all
524 glyphs. E.g., xfce4-terminal.desktop's Name[fi]=Pääte will be displayed just
525 fine, but not its Name[ru]=Терминал.
526
527 =head1 OPTIONS
528
529 =over
530
531 =item B<--dmenu=command>
532
533 Execute command instead of 'dmenu -i'. This option can be used to pass custom
534 parameters to dmenu, or to make i3-dmenu-desktop start a custom (patched?)
535 version of dmenu.
536
537 =item B<--entry-type=type>
538
539 Display the (localized) "Name" (type = name), the command (type = command) or
540 the (*.desktop) filename (type = filename) in dmenu. This option can be
541 specified multiple times.
542
543 Examples are "GNU Image Manipulation Program" (type = name), "gimp" (type =
544 command), and "libreoffice-writer" (type = filename).
545
546 =back
547
548 =head1 VERSION
549
550 Version 1.5
551
552 =head1 AUTHOR
553
554 Michael Stapelberg, C<< <michael at i3wm.org> >>
555
556 =head1 LICENSE AND COPYRIGHT
557
558 Copyright 2012 Michael Stapelberg.
559
560 This program is free software; you can redistribute it and/or modify it
561 under the terms of the BSD license.
562
563 =cut
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * i3-dump-log/main.c: Dumps the i3 SHM log to stdout.
7 *
8 */
9 #include <config.h>
10
11 #include <stdio.h>
12 #include <stdbool.h>
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <sys/un.h>
16 #include <stdlib.h>
17 #include <unistd.h>
18 #include <string.h>
19 #include <errno.h>
20 #include <err.h>
21 #include <stdint.h>
22 #include <getopt.h>
23 #include <limits.h>
24 #include <fcntl.h>
25 #include <sys/mman.h>
26 #include <sys/stat.h>
27 #include <signal.h>
28
29 #include "libi3.h"
30 #include "shmlog.h"
31 #include <i3/ipc.h>
32
33 #if !defined(__OpenBSD__)
34 static uint32_t offset_next_write;
35 #endif
36 static uint32_t wrap_count;
37
38 static i3_shmlog_header *header;
39 static char *logbuffer,
40 *walk;
41 static int ipcfd = -1;
42
43 static volatile bool interrupted = false;
44
45 static void sighandler(int signal) {
46 interrupted = true;
47 }
48
49 static void disable_shmlog(void) {
50 const char *disablecmd = "debuglog off; shmlog off";
51 if (ipc_send_message(ipcfd, strlen(disablecmd),
52 I3_IPC_MESSAGE_TYPE_COMMAND, (uint8_t *)disablecmd) != 0)
53 err(EXIT_FAILURE, "IPC send");
54
55 /* Ensure the command was sent by waiting for the reply: */
56 uint32_t reply_length = 0;
57 uint8_t *reply = NULL;
58 if (ipc_recv_message(ipcfd, I3_IPC_REPLY_TYPE_COMMAND,
59 &reply_length, &reply) != 0) {
60 err(EXIT_FAILURE, "IPC recv");
61 }
62 free(reply);
63 }
64
65 static int check_for_wrap(void) {
66 if (wrap_count == header->wrap_count)
67 return 0;
68
69 /* The log wrapped. Print the remaining content and reset walk to the top
70 * of the log. */
71 wrap_count = header->wrap_count;
72 const int len = (logbuffer + header->offset_last_wrap) - walk;
73 swrite(STDOUT_FILENO, walk, len);
74 walk = logbuffer + sizeof(i3_shmlog_header);
75 return 1;
76 }
77
78 static void print_till_end(void) {
79 check_for_wrap();
80 const int len = (logbuffer + header->offset_next_write) - walk;
81 swrite(STDOUT_FILENO, walk, len);
82 walk += len;
83 }
84
85 void errorlog(char *fmt, ...) {
86 va_list args;
87
88 va_start(args, fmt);
89 vfprintf(stderr, fmt, args);
90 va_end(args);
91 }
92
93 int main(int argc, char *argv[]) {
94 int o, option_index = 0;
95 bool verbose = false;
96 #if !defined(__OpenBSD__)
97 bool follow = false;
98 #endif
99
100 static struct option long_options[] = {
101 {"version", no_argument, 0, 'v'},
102 {"verbose", no_argument, 0, 'V'},
103 #if !defined(__OpenBSD__)
104 {"follow", no_argument, 0, 'f'},
105 #endif
106 {"help", no_argument, 0, 'h'},
107 {0, 0, 0, 0}
108 };
109
110 #if !defined(__OpenBSD__)
111 char *options_string = "s:vfVh";
112 #else
113 char *options_string = "vVh";
114 #endif
115
116 while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
117 if (o == 'v') {
118 printf("i3-dump-log " I3_VERSION "\n");
119 return 0;
120 } else if (o == 'V') {
121 verbose = true;
122 #if !defined(__OpenBSD__)
123 } else if (o == 'f') {
124 follow = true;
125 #endif
126 } else if (o == 'h') {
127 printf("i3-dump-log " I3_VERSION "\n");
128 #if !defined(__OpenBSD__)
129 printf("i3-dump-log [-fhVv]\n");
130 #else
131 printf("i3-dump-log [-hVv]\n");
132 #endif
133 return 0;
134 }
135 }
136
137 char *shmname = root_atom_contents("I3_SHMLOG_PATH", NULL, 0);
138 if (shmname == NULL) {
139 /* Something failed. Let’s invest a little effort to find out what it
140 * is. This is hugely helpful for users who want to debug i3 but are
141 * not used to the procedure yet. */
142 xcb_connection_t *conn;
143 int screen;
144 if ((conn = xcb_connect(NULL, &screen)) == NULL ||
145 xcb_connection_has_error(conn)) {
146 fprintf(stderr, "i3-dump-log: ERROR: Cannot connect to X11.\n\n");
147 if (getenv("DISPLAY") == NULL) {
148 fprintf(stderr, "Your DISPLAY environment variable is not set.\n");
149 fprintf(stderr, "Are you running i3-dump-log via SSH or on a virtual console?\n");
150 fprintf(stderr, "Try DISPLAY=:0 i3-dump-log\n");
151 exit(1);
152 }
153 fprintf(stderr, "FYI: The DISPLAY environment variable is set to \"%s\".\n", getenv("DISPLAY"));
154 exit(1);
155 }
156 if (root_atom_contents("I3_CONFIG_PATH", conn, screen) != NULL) {
157 fprintf(stderr, "i3-dump-log: i3 is running, but SHM logging is not enabled. Enabling SHM log now while i3-dump-log is running\n\n");
158 ipcfd = ipc_connect(NULL);
159 const char *enablecmd = "debuglog on; shmlog 5242880";
160 if (ipc_send_message(ipcfd, strlen(enablecmd),
161 I3_IPC_MESSAGE_TYPE_COMMAND, (uint8_t *)enablecmd) != 0)
162 err(EXIT_FAILURE, "IPC send");
163 /* By the time we receive a reply, I3_SHMLOG_PATH is set: */
164 uint32_t reply_length = 0;
165 uint8_t *reply = NULL;
166 if (ipc_recv_message(ipcfd, I3_IPC_REPLY_TYPE_COMMAND,
167 &reply_length, &reply) != 0) {
168 err(EXIT_FAILURE, "IPC recv");
169 }
170 free(reply);
171
172 atexit(disable_shmlog);
173
174 /* Retry: */
175 shmname = root_atom_contents("I3_SHMLOG_PATH", NULL, 0);
176 if (shmname == NULL && !is_debug_build()) {
177 fprintf(stderr, "You seem to be using a release version of i3:\n %s\n\n", I3_VERSION);
178 fprintf(stderr, "Release versions do not use SHM logging by default,\ntherefore i3-dump-log does not work.\n\n");
179 fprintf(stderr, "Please follow this guide instead:\nhttps://i3wm.org/docs/debugging-release-version.html\n");
180 exit(1);
181 }
182 }
183 if (shmname == NULL) {
184 errx(EXIT_FAILURE, "Cannot get I3_SHMLOG_PATH atom contents. Is i3 running on this display?");
185 }
186 }
187
188 if (*shmname == '\0')
189 errx(EXIT_FAILURE, "Cannot dump log: SHM logging is disabled in i3.");
190
191 struct stat statbuf;
192
193 /* NB: While we must never write, we need O_RDWR for the pthread condvar. */
194 int logbuffer_shm = shm_open(shmname, O_RDWR, 0);
195 if (logbuffer_shm == -1)
196 err(EXIT_FAILURE, "Could not shm_open SHM segment for the i3 log (%s)", shmname);
197
198 if (fstat(logbuffer_shm, &statbuf) != 0)
199 err(EXIT_FAILURE, "stat(%s)", shmname);
200
201 /* NB: While we must never write, we need PROT_WRITE for the pthread condvar. */
202 logbuffer = mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, logbuffer_shm, 0);
203 if (logbuffer == MAP_FAILED)
204 err(EXIT_FAILURE, "Could not mmap SHM segment for the i3 log");
205
206 header = (i3_shmlog_header *)logbuffer;
207
208 if (verbose)
209 printf("next_write = %d, last_wrap = %d, logbuffer_size = %d, shmname = %s\n",
210 header->offset_next_write, header->offset_last_wrap, header->size, shmname);
211 free(shmname);
212 walk = logbuffer + header->offset_next_write;
213
214 /* We first need to print old content in case there was at least one
215 * wrapping already. */
216
217 if (*walk != '\0') {
218 /* In case there was a write to the buffer already, skip the first
219 * old line, it very likely is mangled. Not a problem, though, the log
220 * is chatty enough to have plenty lines left. */
221 while (*walk != '\n')
222 walk++;
223 walk++;
224 }
225
226 /* In case there was no wrapping, this is a no-op, otherwise it prints the
227 * old lines. */
228 wrap_count = 0;
229 check_for_wrap();
230
231 /* Then start from the beginning and print the newer lines */
232 walk = logbuffer + sizeof(i3_shmlog_header);
233 print_till_end();
234
235 #if !defined(__OpenBSD__)
236 if (!follow) {
237 return 0;
238 }
239
240 /* Handle SIGINT gracefully to invoke atexit handlers, if any. */
241 struct sigaction action;
242 action.sa_handler = sighandler;
243 sigemptyset(&action.sa_mask);
244 action.sa_flags = 0;
245 sigaction(SIGINT, &action, NULL);
246
247 /* Since pthread_cond_wait() expects a mutex, we need to provide one.
248 * To not lock i3 (that’s bad, mhkay?) we just define one outside of
249 * the shared memory. */
250 pthread_mutex_t dummy_mutex = PTHREAD_MUTEX_INITIALIZER;
251 pthread_mutex_lock(&dummy_mutex);
252 while (!interrupted) {
253 pthread_cond_wait(&(header->condvar), &dummy_mutex);
254 /* If this was not a spurious wakeup, print the new lines. */
255 if (header->offset_next_write != offset_next_write) {
256 offset_next_write = header->offset_next_write;
257 print_till_end();
258 }
259 }
260
261 #endif
262 exit(0);
263 return 0;
264 }
0 0000;<control>;Cc;0;BN;;;;;N;NULL;;;;
1 0001;<control>;Cc;0;BN;;;;;N;START OF HEADING;;;;
2 0002;<control>;Cc;0;BN;;;;;N;START OF TEXT;;;;
3 0003;<control>;Cc;0;BN;;;;;N;END OF TEXT;;;;
4 0004;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION;;;;
5 0005;<control>;Cc;0;BN;;;;;N;ENQUIRY;;;;
6 0006;<control>;Cc;0;BN;;;;;N;ACKNOWLEDGE;;;;
7 0007;<control>;Cc;0;BN;;;;;N;BELL;;;;
8 0008;<control>;Cc;0;BN;;;;;N;BACKSPACE;;;;
9 0009;<control>;Cc;0;S;;;;;N;CHARACTER TABULATION;;;;
10 000A;<control>;Cc;0;B;;;;;N;LINE FEED (LF);;;;
11 000B;<control>;Cc;0;S;;;;;N;LINE TABULATION;;;;
12 000C;<control>;Cc;0;WS;;;;;N;FORM FEED (FF);;;;
13 000D;<control>;Cc;0;B;;;;;N;CARRIAGE RETURN (CR);;;;
14 000E;<control>;Cc;0;BN;;;;;N;SHIFT OUT;;;;
15 000F;<control>;Cc;0;BN;;;;;N;SHIFT IN;;;;
16 0010;<control>;Cc;0;BN;;;;;N;DATA LINK ESCAPE;;;;
17 0011;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL ONE;;;;
18 0012;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL TWO;;;;
19 0013;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL THREE;;;;
20 0014;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL FOUR;;;;
21 0015;<control>;Cc;0;BN;;;;;N;NEGATIVE ACKNOWLEDGE;;;;
22 0016;<control>;Cc;0;BN;;;;;N;SYNCHRONOUS IDLE;;;;
23 0017;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION BLOCK;;;;
24 0018;<control>;Cc;0;BN;;;;;N;CANCEL;;;;
25 0019;<control>;Cc;0;BN;;;;;N;END OF MEDIUM;;;;
26 001A;<control>;Cc;0;BN;;;;;N;SUBSTITUTE;;;;
27 001B;<control>;Cc;0;BN;;;;;N;ESCAPE;;;;
28 001C;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR FOUR;;;;
29 001D;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR THREE;;;;
30 001E;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR TWO;;;;
31 001F;<control>;Cc;0;S;;;;;N;INFORMATION SEPARATOR ONE;;;;
32 0020;SPACE;Zs;0;WS;;;;;N;;;;;
33 0021;EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
34 0022;QUOTATION MARK;Po;0;ON;;;;;N;;;;;
35 0023;NUMBER SIGN;Po;0;ET;;;;;N;;;;;
36 0024;DOLLAR SIGN;Sc;0;ET;;;;;N;;;;;
37 0025;PERCENT SIGN;Po;0;ET;;;;;N;;;;;
38 0026;AMPERSAND;Po;0;ON;;;;;N;;;;;
39 0027;APOSTROPHE;Po;0;ON;;;;;N;APOSTROPHE-QUOTE;;;;
40 0028;LEFT PARENTHESIS;Ps;0;ON;;;;;Y;OPENING PARENTHESIS;;;;
41 0029;RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;CLOSING PARENTHESIS;;;;
42 002A;ASTERISK;Po;0;ON;;;;;N;;;;;
43 002B;PLUS SIGN;Sm;0;ES;;;;;N;;;;;
44 002C;COMMA;Po;0;CS;;;;;N;;;;;
45 002D;HYPHEN-MINUS;Pd;0;ES;;;;;N;;;;;
46 002E;FULL STOP;Po;0;CS;;;;;N;PERIOD;;;;
47 002F;SOLIDUS;Po;0;CS;;;;;N;SLASH;;;;
48 0030;DIGIT ZERO;Nd;0;EN;;0;0;0;N;;;;;
49 0031;DIGIT ONE;Nd;0;EN;;1;1;1;N;;;;;
50 0032;DIGIT TWO;Nd;0;EN;;2;2;2;N;;;;;
51 0033;DIGIT THREE;Nd;0;EN;;3;3;3;N;;;;;
52 0034;DIGIT FOUR;Nd;0;EN;;4;4;4;N;;;;;
53 0035;DIGIT FIVE;Nd;0;EN;;5;5;5;N;;;;;
54 0036;DIGIT SIX;Nd;0;EN;;6;6;6;N;;;;;
55 0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;;
56 0038;DIGIT EIGHT;Nd;0;EN;;8;8;8;N;;;;;
57 0039;DIGIT NINE;Nd;0;EN;;9;9;9;N;;;;;
58 003A;COLON;Po;0;CS;;;;;N;;;;;
59 003B;SEMICOLON;Po;0;ON;;;;;N;;;;;
60 003C;LESS-THAN SIGN;Sm;0;ON;;;;;Y;;;;;
61 003D;EQUALS SIGN;Sm;0;ON;;;;;N;;;;;
62 003E;GREATER-THAN SIGN;Sm;0;ON;;;;;Y;;;;;
63 003F;QUESTION MARK;Po;0;ON;;;;;N;;;;;
64 0040;COMMERCIAL AT;Po;0;ON;;;;;N;;;;;
65 0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061;
66 0042;LATIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;0062;
67 0043;LATIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;0063;
68 0044;LATIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;0064;
69 0045;LATIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;0065;
70 0046;LATIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;0066;
71 0047;LATIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;0067;
72 0048;LATIN CAPITAL LETTER H;Lu;0;L;;;;;N;;;;0068;
73 0049;LATIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;0069;
74 004A;LATIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;006A;
75 004B;LATIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;006B;
76 004C;LATIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;006C;
77 004D;LATIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;006D;
78 004E;LATIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;006E;
79 004F;LATIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;006F;
80 0050;LATIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;0070;
81 0051;LATIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;0071;
82 0052;LATIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;0072;
83 0053;LATIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;0073;
84 0054;LATIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;0074;
85 0055;LATIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0075;
86 0056;LATIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;0076;
87 0057;LATIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;0077;
88 0058;LATIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;0078;
89 0059;LATIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;0079;
90 005A;LATIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;007A;
91 005B;LEFT SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING SQUARE BRACKET;;;;
92 005C;REVERSE SOLIDUS;Po;0;ON;;;;;N;BACKSLASH;;;;
93 005D;RIGHT SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING SQUARE BRACKET;;;;
94 005E;CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;SPACING CIRCUMFLEX;;;;
95 005F;LOW LINE;Pc;0;ON;;;;;N;SPACING UNDERSCORE;;;;
96 0060;GRAVE ACCENT;Sk;0;ON;;;;;N;SPACING GRAVE;;;;
97 0061;LATIN SMALL LETTER A;Ll;0;L;;;;;N;;;0041;;0041
98 0062;LATIN SMALL LETTER B;Ll;0;L;;;;;N;;;0042;;0042
99 0063;LATIN SMALL LETTER C;Ll;0;L;;;;;N;;;0043;;0043
100 0064;LATIN SMALL LETTER D;Ll;0;L;;;;;N;;;0044;;0044
101 0065;LATIN SMALL LETTER E;Ll;0;L;;;;;N;;;0045;;0045
102 0066;LATIN SMALL LETTER F;Ll;0;L;;;;;N;;;0046;;0046
103 0067;LATIN SMALL LETTER G;Ll;0;L;;;;;N;;;0047;;0047
104 0068;LATIN SMALL LETTER H;Ll;0;L;;;;;N;;;0048;;0048
105 0069;LATIN SMALL LETTER I;Ll;0;L;;;;;N;;;0049;;0049
106 006A;LATIN SMALL LETTER J;Ll;0;L;;;;;N;;;004A;;004A
107 006B;LATIN SMALL LETTER K;Ll;0;L;;;;;N;;;004B;;004B
108 006C;LATIN SMALL LETTER L;Ll;0;L;;;;;N;;;004C;;004C
109 006D;LATIN SMALL LETTER M;Ll;0;L;;;;;N;;;004D;;004D
110 006E;LATIN SMALL LETTER N;Ll;0;L;;;;;N;;;004E;;004E
111 006F;LATIN SMALL LETTER O;Ll;0;L;;;;;N;;;004F;;004F
112 0070;LATIN SMALL LETTER P;Ll;0;L;;;;;N;;;0050;;0050
113 0071;LATIN SMALL LETTER Q;Ll;0;L;;;;;N;;;0051;;0051
114 0072;LATIN SMALL LETTER R;Ll;0;L;;;;;N;;;0052;;0052
115 0073;LATIN SMALL LETTER S;Ll;0;L;;;;;N;;;0053;;0053
116 0074;LATIN SMALL LETTER T;Ll;0;L;;;;;N;;;0054;;0054
117 0075;LATIN SMALL LETTER U;Ll;0;L;;;;;N;;;0055;;0055
118 0076;LATIN SMALL LETTER V;Ll;0;L;;;;;N;;;0056;;0056
119 0077;LATIN SMALL LETTER W;Ll;0;L;;;;;N;;;0057;;0057
120 0078;LATIN SMALL LETTER X;Ll;0;L;;;;;N;;;0058;;0058
121 0079;LATIN SMALL LETTER Y;Ll;0;L;;;;;N;;;0059;;0059
122 007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A
123 007B;LEFT CURLY BRACKET;Ps;0;ON;;;;;Y;OPENING CURLY BRACKET;;;;
124 007C;VERTICAL LINE;Sm;0;ON;;;;;N;VERTICAL BAR;;;;
125 007D;RIGHT CURLY BRACKET;Pe;0;ON;;;;;Y;CLOSING CURLY BRACKET;;;;
126 007E;TILDE;Sm;0;ON;;;;;N;;;;;
127 007F;<control>;Cc;0;BN;;;;;N;DELETE;;;;
128 0080;<control>;Cc;0;BN;;;;;N;;;;;
129 0081;<control>;Cc;0;BN;;;;;N;;;;;
130 0082;<control>;Cc;0;BN;;;;;N;BREAK PERMITTED HERE;;;;
131 0083;<control>;Cc;0;BN;;;;;N;NO BREAK HERE;;;;
132 0084;<control>;Cc;0;BN;;;;;N;;;;;
133 0085;<control>;Cc;0;B;;;;;N;NEXT LINE (NEL);;;;
134 0086;<control>;Cc;0;BN;;;;;N;START OF SELECTED AREA;;;;
135 0087;<control>;Cc;0;BN;;;;;N;END OF SELECTED AREA;;;;
136 0088;<control>;Cc;0;BN;;;;;N;CHARACTER TABULATION SET;;;;
137 0089;<control>;Cc;0;BN;;;;;N;CHARACTER TABULATION WITH JUSTIFICATION;;;;
138 008A;<control>;Cc;0;BN;;;;;N;LINE TABULATION SET;;;;
139 008B;<control>;Cc;0;BN;;;;;N;PARTIAL LINE FORWARD;;;;
140 008C;<control>;Cc;0;BN;;;;;N;PARTIAL LINE BACKWARD;;;;
141 008D;<control>;Cc;0;BN;;;;;N;REVERSE LINE FEED;;;;
142 008E;<control>;Cc;0;BN;;;;;N;SINGLE SHIFT TWO;;;;
143 008F;<control>;Cc;0;BN;;;;;N;SINGLE SHIFT THREE;;;;
144 0090;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL STRING;;;;
145 0091;<control>;Cc;0;BN;;;;;N;PRIVATE USE ONE;;;;
146 0092;<control>;Cc;0;BN;;;;;N;PRIVATE USE TWO;;;;
147 0093;<control>;Cc;0;BN;;;;;N;SET TRANSMIT STATE;;;;
148 0094;<control>;Cc;0;BN;;;;;N;CANCEL CHARACTER;;;;
149 0095;<control>;Cc;0;BN;;;;;N;MESSAGE WAITING;;;;
150 0096;<control>;Cc;0;BN;;;;;N;START OF GUARDED AREA;;;;
151 0097;<control>;Cc;0;BN;;;;;N;END OF GUARDED AREA;;;;
152 0098;<control>;Cc;0;BN;;;;;N;START OF STRING;;;;
153 0099;<control>;Cc;0;BN;;;;;N;;;;;
154 009A;<control>;Cc;0;BN;;;;;N;SINGLE CHARACTER INTRODUCER;;;;
155 009B;<control>;Cc;0;BN;;;;;N;CONTROL SEQUENCE INTRODUCER;;;;
156 009C;<control>;Cc;0;BN;;;;;N;STRING TERMINATOR;;;;
157 009D;<control>;Cc;0;BN;;;;;N;OPERATING SYSTEM COMMAND;;;;
158 009E;<control>;Cc;0;BN;;;;;N;PRIVACY MESSAGE;;;;
159 009F;<control>;Cc;0;BN;;;;;N;APPLICATION PROGRAM COMMAND;;;;
160 00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;
161 00A1;INVERTED EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
162 00A2;CENT SIGN;Sc;0;ET;;;;;N;;;;;
163 00A3;POUND SIGN;Sc;0;ET;;;;;N;;;;;
164 00A4;CURRENCY SIGN;Sc;0;ET;;;;;N;;;;;
165 00A5;YEN SIGN;Sc;0;ET;;;;;N;;;;;
166 00A6;BROKEN BAR;So;0;ON;;;;;N;BROKEN VERTICAL BAR;;;;
167 00A7;SECTION SIGN;So;0;ON;;;;;N;;;;;
168 00A8;DIAERESIS;Sk;0;ON;<compat> 0020 0308;;;;N;SPACING DIAERESIS;;;;
169 00A9;COPYRIGHT SIGN;So;0;ON;;;;;N;;;;;
170 00AA;FEMININE ORDINAL INDICATOR;Ll;0;L;<super> 0061;;;;N;;;;;
171 00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;*;;;
172 00AC;NOT SIGN;Sm;0;ON;;;;;N;;;;;
173 00AD;SOFT HYPHEN;Cf;0;BN;;;;;N;;;;;
174 00AE;REGISTERED SIGN;So;0;ON;;;;;N;REGISTERED TRADE MARK SIGN;;;;
175 00AF;MACRON;Sk;0;ON;<compat> 0020 0304;;;;N;SPACING MACRON;;;;
176 00B0;DEGREE SIGN;So;0;ET;;;;;N;;;;;
177 00B1;PLUS-MINUS SIGN;Sm;0;ET;;;;;N;PLUS-OR-MINUS SIGN;;;;
178 00B2;SUPERSCRIPT TWO;No;0;EN;<super> 0032;;2;2;N;SUPERSCRIPT DIGIT TWO;;;;
179 00B3;SUPERSCRIPT THREE;No;0;EN;<super> 0033;;3;3;N;SUPERSCRIPT DIGIT THREE;;;;
180 00B4;ACUTE ACCENT;Sk;0;ON;<compat> 0020 0301;;;;N;SPACING ACUTE;;;;
181 00B5;MICRO SIGN;Ll;0;L;<compat> 03BC;;;;N;;;039C;;039C
182 00B6;PILCROW SIGN;So;0;ON;;;;;N;PARAGRAPH SIGN;;;;
183 00B7;MIDDLE DOT;Po;0;ON;;;;;N;;;;;
184 00B8;CEDILLA;Sk;0;ON;<compat> 0020 0327;;;;N;SPACING CEDILLA;;;;
185 00B9;SUPERSCRIPT ONE;No;0;EN;<super> 0031;;1;1;N;SUPERSCRIPT DIGIT ONE;;;;
186 00BA;MASCULINE ORDINAL INDICATOR;Ll;0;L;<super> 006F;;;;N;;;;;
187 00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;*;;;
188 00BC;VULGAR FRACTION ONE QUARTER;No;0;ON;<fraction> 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;;
189 00BD;VULGAR FRACTION ONE HALF;No;0;ON;<fraction> 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;;
190 00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON;<fraction> 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;;
191 00BF;INVERTED QUESTION MARK;Po;0;ON;;;;;N;;;;;
192 00C0;LATIN CAPITAL LETTER A WITH GRAVE;Lu;0;L;0041 0300;;;;N;LATIN CAPITAL LETTER A GRAVE;;;00E0;
193 00C1;LATIN CAPITAL LETTER A WITH ACUTE;Lu;0;L;0041 0301;;;;N;LATIN CAPITAL LETTER A ACUTE;;;00E1;
194 00C2;LATIN CAPITAL LETTER A WITH CIRCUMFLEX;Lu;0;L;0041 0302;;;;N;LATIN CAPITAL LETTER A CIRCUMFLEX;;;00E2;
195 00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3;
196 00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4;
197 00C5;LATIN CAPITAL LETTER A WITH RING ABOVE;Lu;0;L;0041 030A;;;;N;LATIN CAPITAL LETTER A RING;;;00E5;
198 00C6;LATIN CAPITAL LETTER AE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER A E;ash *;;00E6;
199 00C7;LATIN CAPITAL LETTER C WITH CEDILLA;Lu;0;L;0043 0327;;;;N;LATIN CAPITAL LETTER C CEDILLA;;;00E7;
200 00C8;LATIN CAPITAL LETTER E WITH GRAVE;Lu;0;L;0045 0300;;;;N;LATIN CAPITAL LETTER E GRAVE;;;00E8;
201 00C9;LATIN CAPITAL LETTER E WITH ACUTE;Lu;0;L;0045 0301;;;;N;LATIN CAPITAL LETTER E ACUTE;;;00E9;
202 00CA;LATIN CAPITAL LETTER E WITH CIRCUMFLEX;Lu;0;L;0045 0302;;;;N;LATIN CAPITAL LETTER E CIRCUMFLEX;;;00EA;
203 00CB;LATIN CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;0045 0308;;;;N;LATIN CAPITAL LETTER E DIAERESIS;;;00EB;
204 00CC;LATIN CAPITAL LETTER I WITH GRAVE;Lu;0;L;0049 0300;;;;N;LATIN CAPITAL LETTER I GRAVE;;;00EC;
205 00CD;LATIN CAPITAL LETTER I WITH ACUTE;Lu;0;L;0049 0301;;;;N;LATIN CAPITAL LETTER I ACUTE;;;00ED;
206 00CE;LATIN CAPITAL LETTER I WITH CIRCUMFLEX;Lu;0;L;0049 0302;;;;N;LATIN CAPITAL LETTER I CIRCUMFLEX;;;00EE;
207 00CF;LATIN CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0049 0308;;;;N;LATIN CAPITAL LETTER I DIAERESIS;;;00EF;
208 00D0;LATIN CAPITAL LETTER ETH;Lu;0;L;;;;;N;;Icelandic;;00F0;
209 00D1;LATIN CAPITAL LETTER N WITH TILDE;Lu;0;L;004E 0303;;;;N;LATIN CAPITAL LETTER N TILDE;;;00F1;
210 00D2;LATIN CAPITAL LETTER O WITH GRAVE;Lu;0;L;004F 0300;;;;N;LATIN CAPITAL LETTER O GRAVE;;;00F2;
211 00D3;LATIN CAPITAL LETTER O WITH ACUTE;Lu;0;L;004F 0301;;;;N;LATIN CAPITAL LETTER O ACUTE;;;00F3;
212 00D4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX;Lu;0;L;004F 0302;;;;N;LATIN CAPITAL LETTER O CIRCUMFLEX;;;00F4;
213 00D5;LATIN CAPITAL LETTER O WITH TILDE;Lu;0;L;004F 0303;;;;N;LATIN CAPITAL LETTER O TILDE;;;00F5;
214 00D6;LATIN CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;004F 0308;;;;N;LATIN CAPITAL LETTER O DIAERESIS;;;00F6;
215 00D7;MULTIPLICATION SIGN;Sm;0;ON;;;;;N;;;;;
216 00D8;LATIN CAPITAL LETTER O WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O SLASH;;;00F8;
217 00D9;LATIN CAPITAL LETTER U WITH GRAVE;Lu;0;L;0055 0300;;;;N;LATIN CAPITAL LETTER U GRAVE;;;00F9;
218 00DA;LATIN CAPITAL LETTER U WITH ACUTE;Lu;0;L;0055 0301;;;;N;LATIN CAPITAL LETTER U ACUTE;;;00FA;
219 00DB;LATIN CAPITAL LETTER U WITH CIRCUMFLEX;Lu;0;L;0055 0302;;;;N;LATIN CAPITAL LETTER U CIRCUMFLEX;;;00FB;
220 00DC;LATIN CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0055 0308;;;;N;LATIN CAPITAL LETTER U DIAERESIS;;;00FC;
221 00DD;LATIN CAPITAL LETTER Y WITH ACUTE;Lu;0;L;0059 0301;;;;N;LATIN CAPITAL LETTER Y ACUTE;;;00FD;
222 00DE;LATIN CAPITAL LETTER THORN;Lu;0;L;;;;;N;;Icelandic;;00FE;
223 00DF;LATIN SMALL LETTER SHARP S;Ll;0;L;;;;;N;;German;;;
224 00E0;LATIN SMALL LETTER A WITH GRAVE;Ll;0;L;0061 0300;;;;N;LATIN SMALL LETTER A GRAVE;;00C0;;00C0
225 00E1;LATIN SMALL LETTER A WITH ACUTE;Ll;0;L;0061 0301;;;;N;LATIN SMALL LETTER A ACUTE;;00C1;;00C1
226 00E2;LATIN SMALL LETTER A WITH CIRCUMFLEX;Ll;0;L;0061 0302;;;;N;LATIN SMALL LETTER A CIRCUMFLEX;;00C2;;00C2
227 00E3;LATIN SMALL LETTER A WITH TILDE;Ll;0;L;0061 0303;;;;N;LATIN SMALL LETTER A TILDE;;00C3;;00C3
228 00E4;LATIN SMALL LETTER A WITH DIAERESIS;Ll;0;L;0061 0308;;;;N;LATIN SMALL LETTER A DIAERESIS;;00C4;;00C4
229 00E5;LATIN SMALL LETTER A WITH RING ABOVE;Ll;0;L;0061 030A;;;;N;LATIN SMALL LETTER A RING;;00C5;;00C5
230 00E6;LATIN SMALL LETTER AE;Ll;0;L;;;;;N;LATIN SMALL LETTER A E;ash *;00C6;;00C6
231 00E7;LATIN SMALL LETTER C WITH CEDILLA;Ll;0;L;0063 0327;;;;N;LATIN SMALL LETTER C CEDILLA;;00C7;;00C7
232 00E8;LATIN SMALL LETTER E WITH GRAVE;Ll;0;L;0065 0300;;;;N;LATIN SMALL LETTER E GRAVE;;00C8;;00C8
233 00E9;LATIN SMALL LETTER E WITH ACUTE;Ll;0;L;0065 0301;;;;N;LATIN SMALL LETTER E ACUTE;;00C9;;00C9
234 00EA;LATIN SMALL LETTER E WITH CIRCUMFLEX;Ll;0;L;0065 0302;;;;N;LATIN SMALL LETTER E CIRCUMFLEX;;00CA;;00CA
235 00EB;LATIN SMALL LETTER E WITH DIAERESIS;Ll;0;L;0065 0308;;;;N;LATIN SMALL LETTER E DIAERESIS;;00CB;;00CB
236 00EC;LATIN SMALL LETTER I WITH GRAVE;Ll;0;L;0069 0300;;;;N;LATIN SMALL LETTER I GRAVE;;00CC;;00CC
237 00ED;LATIN SMALL LETTER I WITH ACUTE;Ll;0;L;0069 0301;;;;N;LATIN SMALL LETTER I ACUTE;;00CD;;00CD
238 00EE;LATIN SMALL LETTER I WITH CIRCUMFLEX;Ll;0;L;0069 0302;;;;N;LATIN SMALL LETTER I CIRCUMFLEX;;00CE;;00CE
239 00EF;LATIN SMALL LETTER I WITH DIAERESIS;Ll;0;L;0069 0308;;;;N;LATIN SMALL LETTER I DIAERESIS;;00CF;;00CF
240 00F0;LATIN SMALL LETTER ETH;Ll;0;L;;;;;N;;Icelandic;00D0;;00D0
241 00F1;LATIN SMALL LETTER N WITH TILDE;Ll;0;L;006E 0303;;;;N;LATIN SMALL LETTER N TILDE;;00D1;;00D1
242 00F2;LATIN SMALL LETTER O WITH GRAVE;Ll;0;L;006F 0300;;;;N;LATIN SMALL LETTER O GRAVE;;00D2;;00D2
243 00F3;LATIN SMALL LETTER O WITH ACUTE;Ll;0;L;006F 0301;;;;N;LATIN SMALL LETTER O ACUTE;;00D3;;00D3
244 00F4;LATIN SMALL LETTER O WITH CIRCUMFLEX;Ll;0;L;006F 0302;;;;N;LATIN SMALL LETTER O CIRCUMFLEX;;00D4;;00D4
245 00F5;LATIN SMALL LETTER O WITH TILDE;Ll;0;L;006F 0303;;;;N;LATIN SMALL LETTER O TILDE;;00D5;;00D5
246 00F6;LATIN SMALL LETTER O WITH DIAERESIS;Ll;0;L;006F 0308;;;;N;LATIN SMALL LETTER O DIAERESIS;;00D6;;00D6
247 00F7;DIVISION SIGN;Sm;0;ON;;;;;N;;;;;
248 00F8;LATIN SMALL LETTER O WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER O SLASH;;00D8;;00D8
249 00F9;LATIN SMALL LETTER U WITH GRAVE;Ll;0;L;0075 0300;;;;N;LATIN SMALL LETTER U GRAVE;;00D9;;00D9
250 00FA;LATIN SMALL LETTER U WITH ACUTE;Ll;0;L;0075 0301;;;;N;LATIN SMALL LETTER U ACUTE;;00DA;;00DA
251 00FB;LATIN SMALL LETTER U WITH CIRCUMFLEX;Ll;0;L;0075 0302;;;;N;LATIN SMALL LETTER U CIRCUMFLEX;;00DB;;00DB
252 00FC;LATIN SMALL LETTER U WITH DIAERESIS;Ll;0;L;0075 0308;;;;N;LATIN SMALL LETTER U DIAERESIS;;00DC;;00DC
253 00FD;LATIN SMALL LETTER Y WITH ACUTE;Ll;0;L;0079 0301;;;;N;LATIN SMALL LETTER Y ACUTE;;00DD;;00DD
254 00FE;LATIN SMALL LETTER THORN;Ll;0;L;;;;;N;;Icelandic;00DE;;00DE
255 00FF;LATIN SMALL LETTER Y WITH DIAERESIS;Ll;0;L;0079 0308;;;;N;LATIN SMALL LETTER Y DIAERESIS;;0178;;0178
256 0100;LATIN CAPITAL LETTER A WITH MACRON;Lu;0;L;0041 0304;;;;N;LATIN CAPITAL LETTER A MACRON;;;0101;
257 0101;LATIN SMALL LETTER A WITH MACRON;Ll;0;L;0061 0304;;;;N;LATIN SMALL LETTER A MACRON;;0100;;0100
258 0102;LATIN CAPITAL LETTER A WITH BREVE;Lu;0;L;0041 0306;;;;N;LATIN CAPITAL LETTER A BREVE;;;0103;
259 0103;LATIN SMALL LETTER A WITH BREVE;Ll;0;L;0061 0306;;;;N;LATIN SMALL LETTER A BREVE;;0102;;0102
260 0104;LATIN CAPITAL LETTER A WITH OGONEK;Lu;0;L;0041 0328;;;;N;LATIN CAPITAL LETTER A OGONEK;;;0105;
261 0105;LATIN SMALL LETTER A WITH OGONEK;Ll;0;L;0061 0328;;;;N;LATIN SMALL LETTER A OGONEK;;0104;;0104
262 0106;LATIN CAPITAL LETTER C WITH ACUTE;Lu;0;L;0043 0301;;;;N;LATIN CAPITAL LETTER C ACUTE;;;0107;
263 0107;LATIN SMALL LETTER C WITH ACUTE;Ll;0;L;0063 0301;;;;N;LATIN SMALL LETTER C ACUTE;;0106;;0106
264 0108;LATIN CAPITAL LETTER C WITH CIRCUMFLEX;Lu;0;L;0043 0302;;;;N;LATIN CAPITAL LETTER C CIRCUMFLEX;;;0109;
265 0109;LATIN SMALL LETTER C WITH CIRCUMFLEX;Ll;0;L;0063 0302;;;;N;LATIN SMALL LETTER C CIRCUMFLEX;;0108;;0108
266 010A;LATIN CAPITAL LETTER C WITH DOT ABOVE;Lu;0;L;0043 0307;;;;N;LATIN CAPITAL LETTER C DOT;;;010B;
267 010B;LATIN SMALL LETTER C WITH DOT ABOVE;Ll;0;L;0063 0307;;;;N;LATIN SMALL LETTER C DOT;;010A;;010A
268 010C;LATIN CAPITAL LETTER C WITH CARON;Lu;0;L;0043 030C;;;;N;LATIN CAPITAL LETTER C HACEK;;;010D;
269 010D;LATIN SMALL LETTER C WITH CARON;Ll;0;L;0063 030C;;;;N;LATIN SMALL LETTER C HACEK;;010C;;010C
270 010E;LATIN CAPITAL LETTER D WITH CARON;Lu;0;L;0044 030C;;;;N;LATIN CAPITAL LETTER D HACEK;;;010F;
271 010F;LATIN SMALL LETTER D WITH CARON;Ll;0;L;0064 030C;;;;N;LATIN SMALL LETTER D HACEK;;010E;;010E
272 0110;LATIN CAPITAL LETTER D WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D BAR;;;0111;
273 0111;LATIN SMALL LETTER D WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER D BAR;;0110;;0110
274 0112;LATIN CAPITAL LETTER E WITH MACRON;Lu;0;L;0045 0304;;;;N;LATIN CAPITAL LETTER E MACRON;;;0113;
275 0113;LATIN SMALL LETTER E WITH MACRON;Ll;0;L;0065 0304;;;;N;LATIN SMALL LETTER E MACRON;;0112;;0112
276 0114;LATIN CAPITAL LETTER E WITH BREVE;Lu;0;L;0045 0306;;;;N;LATIN CAPITAL LETTER E BREVE;;;0115;
277 0115;LATIN SMALL LETTER E WITH BREVE;Ll;0;L;0065 0306;;;;N;LATIN SMALL LETTER E BREVE;;0114;;0114
278 0116;LATIN CAPITAL LETTER E WITH DOT ABOVE;Lu;0;L;0045 0307;;;;N;LATIN CAPITAL LETTER E DOT;;;0117;
279 0117;LATIN SMALL LETTER E WITH DOT ABOVE;Ll;0;L;0065 0307;;;;N;LATIN SMALL LETTER E DOT;;0116;;0116
280 0118;LATIN CAPITAL LETTER E WITH OGONEK;Lu;0;L;0045 0328;;;;N;LATIN CAPITAL LETTER E OGONEK;;;0119;
281 0119;LATIN SMALL LETTER E WITH OGONEK;Ll;0;L;0065 0328;;;;N;LATIN SMALL LETTER E OGONEK;;0118;;0118
282 011A;LATIN CAPITAL LETTER E WITH CARON;Lu;0;L;0045 030C;;;;N;LATIN CAPITAL LETTER E HACEK;;;011B;
283 011B;LATIN SMALL LETTER E WITH CARON;Ll;0;L;0065 030C;;;;N;LATIN SMALL LETTER E HACEK;;011A;;011A
284 011C;LATIN CAPITAL LETTER G WITH CIRCUMFLEX;Lu;0;L;0047 0302;;;;N;LATIN CAPITAL LETTER G CIRCUMFLEX;;;011D;
285 011D;LATIN SMALL LETTER G WITH CIRCUMFLEX;Ll;0;L;0067 0302;;;;N;LATIN SMALL LETTER G CIRCUMFLEX;;011C;;011C
286 011E;LATIN CAPITAL LETTER G WITH BREVE;Lu;0;L;0047 0306;;;;N;LATIN CAPITAL LETTER G BREVE;;;011F;
287 011F;LATIN SMALL LETTER G WITH BREVE;Ll;0;L;0067 0306;;;;N;LATIN SMALL LETTER G BREVE;;011E;;011E
288 0120;LATIN CAPITAL LETTER G WITH DOT ABOVE;Lu;0;L;0047 0307;;;;N;LATIN CAPITAL LETTER G DOT;;;0121;
289 0121;LATIN SMALL LETTER G WITH DOT ABOVE;Ll;0;L;0067 0307;;;;N;LATIN SMALL LETTER G DOT;;0120;;0120
290 0122;LATIN CAPITAL LETTER G WITH CEDILLA;Lu;0;L;0047 0327;;;;N;LATIN CAPITAL LETTER G CEDILLA;;;0123;
291 0123;LATIN SMALL LETTER G WITH CEDILLA;Ll;0;L;0067 0327;;;;N;LATIN SMALL LETTER G CEDILLA;;0122;;0122
292 0124;LATIN CAPITAL LETTER H WITH CIRCUMFLEX;Lu;0;L;0048 0302;;;;N;LATIN CAPITAL LETTER H CIRCUMFLEX;;;0125;
293 0125;LATIN SMALL LETTER H WITH CIRCUMFLEX;Ll;0;L;0068 0302;;;;N;LATIN SMALL LETTER H CIRCUMFLEX;;0124;;0124
294 0126;LATIN CAPITAL LETTER H WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER H BAR;;;0127;
295 0127;LATIN SMALL LETTER H WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER H BAR;;0126;;0126
296 0128;LATIN CAPITAL LETTER I WITH TILDE;Lu;0;L;0049 0303;;;;N;LATIN CAPITAL LETTER I TILDE;;;0129;
297 0129;LATIN SMALL LETTER I WITH TILDE;Ll;0;L;0069 0303;;;;N;LATIN SMALL LETTER I TILDE;;0128;;0128
298 012A;LATIN CAPITAL LETTER I WITH MACRON;Lu;0;L;0049 0304;;;;N;LATIN CAPITAL LETTER I MACRON;;;012B;
299 012B;LATIN SMALL LETTER I WITH MACRON;Ll;0;L;0069 0304;;;;N;LATIN SMALL LETTER I MACRON;;012A;;012A
300 012C;LATIN CAPITAL LETTER I WITH BREVE;Lu;0;L;0049 0306;;;;N;LATIN CAPITAL LETTER I BREVE;;;012D;
301 012D;LATIN SMALL LETTER I WITH BREVE;Ll;0;L;0069 0306;;;;N;LATIN SMALL LETTER I BREVE;;012C;;012C
302 012E;LATIN CAPITAL LETTER I WITH OGONEK;Lu;0;L;0049 0328;;;;N;LATIN CAPITAL LETTER I OGONEK;;;012F;
303 012F;LATIN SMALL LETTER I WITH OGONEK;Ll;0;L;0069 0328;;;;N;LATIN SMALL LETTER I OGONEK;;012E;;012E
304 0130;LATIN CAPITAL LETTER I WITH DOT ABOVE;Lu;0;L;0049 0307;;;;N;LATIN CAPITAL LETTER I DOT;;;0069;
305 0131;LATIN SMALL LETTER DOTLESS I;Ll;0;L;;;;;N;;;0049;;0049
306 0132;LATIN CAPITAL LIGATURE IJ;Lu;0;L;<compat> 0049 004A;;;;N;LATIN CAPITAL LETTER I J;;;0133;
307 0133;LATIN SMALL LIGATURE IJ;Ll;0;L;<compat> 0069 006A;;;;N;LATIN SMALL LETTER I J;;0132;;0132
308 0134;LATIN CAPITAL LETTER J WITH CIRCUMFLEX;Lu;0;L;004A 0302;;;;N;LATIN CAPITAL LETTER J CIRCUMFLEX;;;0135;
309 0135;LATIN SMALL LETTER J WITH CIRCUMFLEX;Ll;0;L;006A 0302;;;;N;LATIN SMALL LETTER J CIRCUMFLEX;;0134;;0134
310 0136;LATIN CAPITAL LETTER K WITH CEDILLA;Lu;0;L;004B 0327;;;;N;LATIN CAPITAL LETTER K CEDILLA;;;0137;
311 0137;LATIN SMALL LETTER K WITH CEDILLA;Ll;0;L;006B 0327;;;;N;LATIN SMALL LETTER K CEDILLA;;0136;;0136
312 0138;LATIN SMALL LETTER KRA;Ll;0;L;;;;;N;;Greenlandic;;;
313 0139;LATIN CAPITAL LETTER L WITH ACUTE;Lu;0;L;004C 0301;;;;N;LATIN CAPITAL LETTER L ACUTE;;;013A;
314 013A;LATIN SMALL LETTER L WITH ACUTE;Ll;0;L;006C 0301;;;;N;LATIN SMALL LETTER L ACUTE;;0139;;0139
315 013B;LATIN CAPITAL LETTER L WITH CEDILLA;Lu;0;L;004C 0327;;;;N;LATIN CAPITAL LETTER L CEDILLA;;;013C;
316 013C;LATIN SMALL LETTER L WITH CEDILLA;Ll;0;L;006C 0327;;;;N;LATIN SMALL LETTER L CEDILLA;;013B;;013B
317 013D;LATIN CAPITAL LETTER L WITH CARON;Lu;0;L;004C 030C;;;;N;LATIN CAPITAL LETTER L HACEK;;;013E;
318 013E;LATIN SMALL LETTER L WITH CARON;Ll;0;L;006C 030C;;;;N;LATIN SMALL LETTER L HACEK;;013D;;013D
319 013F;LATIN CAPITAL LETTER L WITH MIDDLE DOT;Lu;0;L;<compat> 004C 00B7;;;;N;;;;0140;
320 0140;LATIN SMALL LETTER L WITH MIDDLE DOT;Ll;0;L;<compat> 006C 00B7;;;;N;;;013F;;013F
321 0141;LATIN CAPITAL LETTER L WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER L SLASH;;;0142;
322 0142;LATIN SMALL LETTER L WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER L SLASH;;0141;;0141
323 0143;LATIN CAPITAL LETTER N WITH ACUTE;Lu;0;L;004E 0301;;;;N;LATIN CAPITAL LETTER N ACUTE;;;0144;
324 0144;LATIN SMALL LETTER N WITH ACUTE;Ll;0;L;006E 0301;;;;N;LATIN SMALL LETTER N ACUTE;;0143;;0143
325 0145;LATIN CAPITAL LETTER N WITH CEDILLA;Lu;0;L;004E 0327;;;;N;LATIN CAPITAL LETTER N CEDILLA;;;0146;
326 0146;LATIN SMALL LETTER N WITH CEDILLA;Ll;0;L;006E 0327;;;;N;LATIN SMALL LETTER N CEDILLA;;0145;;0145
327 0147;LATIN CAPITAL LETTER N WITH CARON;Lu;0;L;004E 030C;;;;N;LATIN CAPITAL LETTER N HACEK;;;0148;
328 0148;LATIN SMALL LETTER N WITH CARON;Ll;0;L;006E 030C;;;;N;LATIN SMALL LETTER N HACEK;;0147;;0147
329 0149;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE;Ll;0;L;<compat> 02BC 006E;;;;N;LATIN SMALL LETTER APOSTROPHE N;;;;
330 014A;LATIN CAPITAL LETTER ENG;Lu;0;L;;;;;N;;Sami;;014B;
331 014B;LATIN SMALL LETTER ENG;Ll;0;L;;;;;N;;Sami;014A;;014A
332 014C;LATIN CAPITAL LETTER O WITH MACRON;Lu;0;L;004F 0304;;;;N;LATIN CAPITAL LETTER O MACRON;;;014D;
333 014D;LATIN SMALL LETTER O WITH MACRON;Ll;0;L;006F 0304;;;;N;LATIN SMALL LETTER O MACRON;;014C;;014C
334 014E;LATIN CAPITAL LETTER O WITH BREVE;Lu;0;L;004F 0306;;;;N;LATIN CAPITAL LETTER O BREVE;;;014F;
335 014F;LATIN SMALL LETTER O WITH BREVE;Ll;0;L;006F 0306;;;;N;LATIN SMALL LETTER O BREVE;;014E;;014E
336 0150;LATIN CAPITAL LETTER O WITH DOUBLE ACUTE;Lu;0;L;004F 030B;;;;N;LATIN CAPITAL LETTER O DOUBLE ACUTE;;;0151;
337 0151;LATIN SMALL LETTER O WITH DOUBLE ACUTE;Ll;0;L;006F 030B;;;;N;LATIN SMALL LETTER O DOUBLE ACUTE;;0150;;0150
338 0152;LATIN CAPITAL LIGATURE OE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O E;;;0153;
339 0153;LATIN SMALL LIGATURE OE;Ll;0;L;;;;;N;LATIN SMALL LETTER O E;;0152;;0152
340 0154;LATIN CAPITAL LETTER R WITH ACUTE;Lu;0;L;0052 0301;;;;N;LATIN CAPITAL LETTER R ACUTE;;;0155;
341 0155;LATIN SMALL LETTER R WITH ACUTE;Ll;0;L;0072 0301;;;;N;LATIN SMALL LETTER R ACUTE;;0154;;0154
342 0156;LATIN CAPITAL LETTER R WITH CEDILLA;Lu;0;L;0052 0327;;;;N;LATIN CAPITAL LETTER R CEDILLA;;;0157;
343 0157;LATIN SMALL LETTER R WITH CEDILLA;Ll;0;L;0072 0327;;;;N;LATIN SMALL LETTER R CEDILLA;;0156;;0156
344 0158;LATIN CAPITAL LETTER R WITH CARON;Lu;0;L;0052 030C;;;;N;LATIN CAPITAL LETTER R HACEK;;;0159;
345 0159;LATIN SMALL LETTER R WITH CARON;Ll;0;L;0072 030C;;;;N;LATIN SMALL LETTER R HACEK;;0158;;0158
346 015A;LATIN CAPITAL LETTER S WITH ACUTE;Lu;0;L;0053 0301;;;;N;LATIN CAPITAL LETTER S ACUTE;;;015B;
347 015B;LATIN SMALL LETTER S WITH ACUTE;Ll;0;L;0073 0301;;;;N;LATIN SMALL LETTER S ACUTE;;015A;;015A
348 015C;LATIN CAPITAL LETTER S WITH CIRCUMFLEX;Lu;0;L;0053 0302;;;;N;LATIN CAPITAL LETTER S CIRCUMFLEX;;;015D;
349 015D;LATIN SMALL LETTER S WITH CIRCUMFLEX;Ll;0;L;0073 0302;;;;N;LATIN SMALL LETTER S CIRCUMFLEX;;015C;;015C
350 015E;LATIN CAPITAL LETTER S WITH CEDILLA;Lu;0;L;0053 0327;;;;N;LATIN CAPITAL LETTER S CEDILLA;*;;015F;
351 015F;LATIN SMALL LETTER S WITH CEDILLA;Ll;0;L;0073 0327;;;;N;LATIN SMALL LETTER S CEDILLA;*;015E;;015E
352 0160;LATIN CAPITAL LETTER S WITH CARON;Lu;0;L;0053 030C;;;;N;LATIN CAPITAL LETTER S HACEK;;;0161;
353 0161;LATIN SMALL LETTER S WITH CARON;Ll;0;L;0073 030C;;;;N;LATIN SMALL LETTER S HACEK;;0160;;0160
354 0162;LATIN CAPITAL LETTER T WITH CEDILLA;Lu;0;L;0054 0327;;;;N;LATIN CAPITAL LETTER T CEDILLA;*;;0163;
355 0163;LATIN SMALL LETTER T WITH CEDILLA;Ll;0;L;0074 0327;;;;N;LATIN SMALL LETTER T CEDILLA;*;0162;;0162
356 0164;LATIN CAPITAL LETTER T WITH CARON;Lu;0;L;0054 030C;;;;N;LATIN CAPITAL LETTER T HACEK;;;0165;
357 0165;LATIN SMALL LETTER T WITH CARON;Ll;0;L;0074 030C;;;;N;LATIN SMALL LETTER T HACEK;;0164;;0164
358 0166;LATIN CAPITAL LETTER T WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T BAR;;;0167;
359 0167;LATIN SMALL LETTER T WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER T BAR;;0166;;0166
360 0168;LATIN CAPITAL LETTER U WITH TILDE;Lu;0;L;0055 0303;;;;N;LATIN CAPITAL LETTER U TILDE;;;0169;
361 0169;LATIN SMALL LETTER U WITH TILDE;Ll;0;L;0075 0303;;;;N;LATIN SMALL LETTER U TILDE;;0168;;0168
362 016A;LATIN CAPITAL LETTER U WITH MACRON;Lu;0;L;0055 0304;;;;N;LATIN CAPITAL LETTER U MACRON;;;016B;
363 016B;LATIN SMALL LETTER U WITH MACRON;Ll;0;L;0075 0304;;;;N;LATIN SMALL LETTER U MACRON;;016A;;016A
364 016C;LATIN CAPITAL LETTER U WITH BREVE;Lu;0;L;0055 0306;;;;N;LATIN CAPITAL LETTER U BREVE;;;016D;
365 016D;LATIN SMALL LETTER U WITH BREVE;Ll;0;L;0075 0306;;;;N;LATIN SMALL LETTER U BREVE;;016C;;016C
366 016E;LATIN CAPITAL LETTER U WITH RING ABOVE;Lu;0;L;0055 030A;;;;N;LATIN CAPITAL LETTER U RING;;;016F;
367 016F;LATIN SMALL LETTER U WITH RING ABOVE;Ll;0;L;0075 030A;;;;N;LATIN SMALL LETTER U RING;;016E;;016E
368 0170;LATIN CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0055 030B;;;;N;LATIN CAPITAL LETTER U DOUBLE ACUTE;;;0171;
369 0171;LATIN SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0075 030B;;;;N;LATIN SMALL LETTER U DOUBLE ACUTE;;0170;;0170
370 0172;LATIN CAPITAL LETTER U WITH OGONEK;Lu;0;L;0055 0328;;;;N;LATIN CAPITAL LETTER U OGONEK;;;0173;
371 0173;LATIN SMALL LETTER U WITH OGONEK;Ll;0;L;0075 0328;;;;N;LATIN SMALL LETTER U OGONEK;;0172;;0172
372 0174;LATIN CAPITAL LETTER W WITH CIRCUMFLEX;Lu;0;L;0057 0302;;;;N;LATIN CAPITAL LETTER W CIRCUMFLEX;;;0175;
373 0175;LATIN SMALL LETTER W WITH CIRCUMFLEX;Ll;0;L;0077 0302;;;;N;LATIN SMALL LETTER W CIRCUMFLEX;;0174;;0174
374 0176;LATIN CAPITAL LETTER Y WITH CIRCUMFLEX;Lu;0;L;0059 0302;;;;N;LATIN CAPITAL LETTER Y CIRCUMFLEX;;;0177;
375 0177;LATIN SMALL LETTER Y WITH CIRCUMFLEX;Ll;0;L;0079 0302;;;;N;LATIN SMALL LETTER Y CIRCUMFLEX;;0176;;0176
376 0178;LATIN CAPITAL LETTER Y WITH DIAERESIS;Lu;0;L;0059 0308;;;;N;LATIN CAPITAL LETTER Y DIAERESIS;;;00FF;
377 0179;LATIN CAPITAL LETTER Z WITH ACUTE;Lu;0;L;005A 0301;;;;N;LATIN CAPITAL LETTER Z ACUTE;;;017A;
378 017A;LATIN SMALL LETTER Z WITH ACUTE;Ll;0;L;007A 0301;;;;N;LATIN SMALL LETTER Z ACUTE;;0179;;0179
379 017B;LATIN CAPITAL LETTER Z WITH DOT ABOVE;Lu;0;L;005A 0307;;;;N;LATIN CAPITAL LETTER Z DOT;;;017C;
380 017C;LATIN SMALL LETTER Z WITH DOT ABOVE;Ll;0;L;007A 0307;;;;N;LATIN SMALL LETTER Z DOT;;017B;;017B
381 017D;LATIN CAPITAL LETTER Z WITH CARON;Lu;0;L;005A 030C;;;;N;LATIN CAPITAL LETTER Z HACEK;;;017E;
382 017E;LATIN SMALL LETTER Z WITH CARON;Ll;0;L;007A 030C;;;;N;LATIN SMALL LETTER Z HACEK;;017D;;017D
383 017F;LATIN SMALL LETTER LONG S;Ll;0;L;<compat> 0073;;;;N;;;0053;;0053
384 0180;LATIN SMALL LETTER B WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER B BAR;;0243;;0243
385 0181;LATIN CAPITAL LETTER B WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B HOOK;;;0253;
386 0182;LATIN CAPITAL LETTER B WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B TOPBAR;;;0183;
387 0183;LATIN SMALL LETTER B WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER B TOPBAR;;0182;;0182
388 0184;LATIN CAPITAL LETTER TONE SIX;Lu;0;L;;;;;N;;;;0185;
389 0185;LATIN SMALL LETTER TONE SIX;Ll;0;L;;;;;N;;;0184;;0184
390 0186;LATIN CAPITAL LETTER OPEN O;Lu;0;L;;;;;N;;;;0254;
391 0187;LATIN CAPITAL LETTER C WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER C HOOK;;;0188;
392 0188;LATIN SMALL LETTER C WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER C HOOK;;0187;;0187
393 0189;LATIN CAPITAL LETTER AFRICAN D;Lu;0;L;;;;;N;;*;;0256;
394 018A;LATIN CAPITAL LETTER D WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D HOOK;;;0257;
395 018B;LATIN CAPITAL LETTER D WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D TOPBAR;;;018C;
396 018C;LATIN SMALL LETTER D WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER D TOPBAR;;018B;;018B
397 018D;LATIN SMALL LETTER TURNED DELTA;Ll;0;L;;;;;N;;;;;
398 018E;LATIN CAPITAL LETTER REVERSED E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER TURNED E;;;01DD;
399 018F;LATIN CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;0259;
400 0190;LATIN CAPITAL LETTER OPEN E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER EPSILON;;;025B;
401 0191;LATIN CAPITAL LETTER F WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER F HOOK;;;0192;
402 0192;LATIN SMALL LETTER F WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT F;;0191;;0191
403 0193;LATIN CAPITAL LETTER G WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G HOOK;;;0260;
404 0194;LATIN CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;0263;
405 0195;LATIN SMALL LETTER HV;Ll;0;L;;;;;N;LATIN SMALL LETTER H V;hwair;01F6;;01F6
406 0196;LATIN CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;0269;
407 0197;LATIN CAPITAL LETTER I WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED I;;;0268;
408 0198;LATIN CAPITAL LETTER K WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER K HOOK;;;0199;
409 0199;LATIN SMALL LETTER K WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER K HOOK;;0198;;0198
410 019A;LATIN SMALL LETTER L WITH BAR;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED L;;023D;;023D
411 019B;LATIN SMALL LETTER LAMBDA WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED LAMBDA;;;;
412 019C;LATIN CAPITAL LETTER TURNED M;Lu;0;L;;;;;N;;;;026F;
413 019D;LATIN CAPITAL LETTER N WITH LEFT HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER N HOOK;;;0272;
414 019E;LATIN SMALL LETTER N WITH LONG RIGHT LEG;Ll;0;L;;;;;N;;;0220;;0220
415 019F;LATIN CAPITAL LETTER O WITH MIDDLE TILDE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED O;*;;0275;
416 01A0;LATIN CAPITAL LETTER O WITH HORN;Lu;0;L;004F 031B;;;;N;LATIN CAPITAL LETTER O HORN;;;01A1;
417 01A1;LATIN SMALL LETTER O WITH HORN;Ll;0;L;006F 031B;;;;N;LATIN SMALL LETTER O HORN;;01A0;;01A0
418 01A2;LATIN CAPITAL LETTER OI;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O I;gha;;01A3;
419 01A3;LATIN SMALL LETTER OI;Ll;0;L;;;;;N;LATIN SMALL LETTER O I;gha;01A2;;01A2
420 01A4;LATIN CAPITAL LETTER P WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER P HOOK;;;01A5;
421 01A5;LATIN SMALL LETTER P WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER P HOOK;;01A4;;01A4
422 01A6;LATIN LETTER YR;Lu;0;L;;;;;N;LATIN LETTER Y R;*;;0280;
423 01A7;LATIN CAPITAL LETTER TONE TWO;Lu;0;L;;;;;N;;;;01A8;
424 01A8;LATIN SMALL LETTER TONE TWO;Ll;0;L;;;;;N;;;01A7;;01A7
425 01A9;LATIN CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;0283;
426 01AA;LATIN LETTER REVERSED ESH LOOP;Ll;0;L;;;;;N;;;;;
427 01AB;LATIN SMALL LETTER T WITH PALATAL HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T PALATAL HOOK;;;;
428 01AC;LATIN CAPITAL LETTER T WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T HOOK;;;01AD;
429 01AD;LATIN SMALL LETTER T WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T HOOK;;01AC;;01AC
430 01AE;LATIN CAPITAL LETTER T WITH RETROFLEX HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T RETROFLEX HOOK;;;0288;
431 01AF;LATIN CAPITAL LETTER U WITH HORN;Lu;0;L;0055 031B;;;;N;LATIN CAPITAL LETTER U HORN;;;01B0;
432 01B0;LATIN SMALL LETTER U WITH HORN;Ll;0;L;0075 031B;;;;N;LATIN SMALL LETTER U HORN;;01AF;;01AF
433 01B1;LATIN CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;028A;
434 01B2;LATIN CAPITAL LETTER V WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER SCRIPT V;;;028B;
435 01B3;LATIN CAPITAL LETTER Y WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Y HOOK;;;01B4;
436 01B4;LATIN SMALL LETTER Y WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Y HOOK;;01B3;;01B3
437 01B5;LATIN CAPITAL LETTER Z WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Z BAR;;;01B6;
438 01B6;LATIN SMALL LETTER Z WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER Z BAR;;01B5;;01B5
439 01B7;LATIN CAPITAL LETTER EZH;Lu;0;L;;;;;N;LATIN CAPITAL LETTER YOGH;;;0292;
440 01B8;LATIN CAPITAL LETTER EZH REVERSED;Lu;0;L;;;;;N;LATIN CAPITAL LETTER REVERSED YOGH;;;01B9;
441 01B9;LATIN SMALL LETTER EZH REVERSED;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED YOGH;;01B8;;01B8
442 01BA;LATIN SMALL LETTER EZH WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH WITH TAIL;;;;
443 01BB;LATIN LETTER TWO WITH STROKE;Lo;0;L;;;;;N;LATIN LETTER TWO BAR;;;;
444 01BC;LATIN CAPITAL LETTER TONE FIVE;Lu;0;L;;;;;N;;;;01BD;
445 01BD;LATIN SMALL LETTER TONE FIVE;Ll;0;L;;;;;N;;;01BC;;01BC
446 01BE;LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER INVERTED GLOTTAL STOP BAR;;;;
447 01BF;LATIN LETTER WYNN;Ll;0;L;;;;;N;;;01F7;;01F7
448 01C0;LATIN LETTER DENTAL CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE;;;;
449 01C1;LATIN LETTER LATERAL CLICK;Lo;0;L;;;;;N;LATIN LETTER DOUBLE PIPE;;;;
450 01C2;LATIN LETTER ALVEOLAR CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE DOUBLE BAR;;;;
451 01C3;LATIN LETTER RETROFLEX CLICK;Lo;0;L;;;;;N;LATIN LETTER EXCLAMATION MARK;;;;
452 01C4;LATIN CAPITAL LETTER DZ WITH CARON;Lu;0;L;<compat> 0044 017D;;;;N;LATIN CAPITAL LETTER D Z HACEK;;;01C6;01C5
453 01C5;LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON;Lt;0;L;<compat> 0044 017E;;;;N;LATIN LETTER CAPITAL D SMALL Z HACEK;;01C4;01C6;01C5
454 01C6;LATIN SMALL LETTER DZ WITH CARON;Ll;0;L;<compat> 0064 017E;;;;N;LATIN SMALL LETTER D Z HACEK;;01C4;;01C5
455 01C7;LATIN CAPITAL LETTER LJ;Lu;0;L;<compat> 004C 004A;;;;N;LATIN CAPITAL LETTER L J;;;01C9;01C8
456 01C8;LATIN CAPITAL LETTER L WITH SMALL LETTER J;Lt;0;L;<compat> 004C 006A;;;;N;LATIN LETTER CAPITAL L SMALL J;;01C7;01C9;01C8
457 01C9;LATIN SMALL LETTER LJ;Ll;0;L;<compat> 006C 006A;;;;N;LATIN SMALL LETTER L J;;01C7;;01C8
458 01CA;LATIN CAPITAL LETTER NJ;Lu;0;L;<compat> 004E 004A;;;;N;LATIN CAPITAL LETTER N J;;;01CC;01CB
459 01CB;LATIN CAPITAL LETTER N WITH SMALL LETTER J;Lt;0;L;<compat> 004E 006A;;;;N;LATIN LETTER CAPITAL N SMALL J;;01CA;01CC;01CB
460 01CC;LATIN SMALL LETTER NJ;Ll;0;L;<compat> 006E 006A;;;;N;LATIN SMALL LETTER N J;;01CA;;01CB
461 01CD;LATIN CAPITAL LETTER A WITH CARON;Lu;0;L;0041 030C;;;;N;LATIN CAPITAL LETTER A HACEK;;;01CE;
462 01CE;LATIN SMALL LETTER A WITH CARON;Ll;0;L;0061 030C;;;;N;LATIN SMALL LETTER A HACEK;;01CD;;01CD
463 01CF;LATIN CAPITAL LETTER I WITH CARON;Lu;0;L;0049 030C;;;;N;LATIN CAPITAL LETTER I HACEK;;;01D0;
464 01D0;LATIN SMALL LETTER I WITH CARON;Ll;0;L;0069 030C;;;;N;LATIN SMALL LETTER I HACEK;;01CF;;01CF
465 01D1;LATIN CAPITAL LETTER O WITH CARON;Lu;0;L;004F 030C;;;;N;LATIN CAPITAL LETTER O HACEK;;;01D2;
466 01D2;LATIN SMALL LETTER O WITH CARON;Ll;0;L;006F 030C;;;;N;LATIN SMALL LETTER O HACEK;;01D1;;01D1
467 01D3;LATIN CAPITAL LETTER U WITH CARON;Lu;0;L;0055 030C;;;;N;LATIN CAPITAL LETTER U HACEK;;;01D4;
468 01D4;LATIN SMALL LETTER U WITH CARON;Ll;0;L;0075 030C;;;;N;LATIN SMALL LETTER U HACEK;;01D3;;01D3
469 01D5;LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON;Lu;0;L;00DC 0304;;;;N;LATIN CAPITAL LETTER U DIAERESIS MACRON;;;01D6;
470 01D6;LATIN SMALL LETTER U WITH DIAERESIS AND MACRON;Ll;0;L;00FC 0304;;;;N;LATIN SMALL LETTER U DIAERESIS MACRON;;01D5;;01D5
471 01D7;LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE;Lu;0;L;00DC 0301;;;;N;LATIN CAPITAL LETTER U DIAERESIS ACUTE;;;01D8;
472 01D8;LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE;Ll;0;L;00FC 0301;;;;N;LATIN SMALL LETTER U DIAERESIS ACUTE;;01D7;;01D7
473 01D9;LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON;Lu;0;L;00DC 030C;;;;N;LATIN CAPITAL LETTER U DIAERESIS HACEK;;;01DA;
474 01DA;LATIN SMALL LETTER U WITH DIAERESIS AND CARON;Ll;0;L;00FC 030C;;;;N;LATIN SMALL LETTER U DIAERESIS HACEK;;01D9;;01D9
475 01DB;LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE;Lu;0;L;00DC 0300;;;;N;LATIN CAPITAL LETTER U DIAERESIS GRAVE;;;01DC;
476 01DC;LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE;Ll;0;L;00FC 0300;;;;N;LATIN SMALL LETTER U DIAERESIS GRAVE;;01DB;;01DB
477 01DD;LATIN SMALL LETTER TURNED E;Ll;0;L;;;;;N;;;018E;;018E
478 01DE;LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON;Lu;0;L;00C4 0304;;;;N;LATIN CAPITAL LETTER A DIAERESIS MACRON;;;01DF;
479 01DF;LATIN SMALL LETTER A WITH DIAERESIS AND MACRON;Ll;0;L;00E4 0304;;;;N;LATIN SMALL LETTER A DIAERESIS MACRON;;01DE;;01DE
480 01E0;LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON;Lu;0;L;0226 0304;;;;N;LATIN CAPITAL LETTER A DOT MACRON;;;01E1;
481 01E1;LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON;Ll;0;L;0227 0304;;;;N;LATIN SMALL LETTER A DOT MACRON;;01E0;;01E0
482 01E2;LATIN CAPITAL LETTER AE WITH MACRON;Lu;0;L;00C6 0304;;;;N;LATIN CAPITAL LETTER A E MACRON;ash *;;01E3;
483 01E3;LATIN SMALL LETTER AE WITH MACRON;Ll;0;L;00E6 0304;;;;N;LATIN SMALL LETTER A E MACRON;ash *;01E2;;01E2
484 01E4;LATIN CAPITAL LETTER G WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G BAR;;;01E5;
485 01E5;LATIN SMALL LETTER G WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER G BAR;;01E4;;01E4
486 01E6;LATIN CAPITAL LETTER G WITH CARON;Lu;0;L;0047 030C;;;;N;LATIN CAPITAL LETTER G HACEK;;;01E7;
487 01E7;LATIN SMALL LETTER G WITH CARON;Ll;0;L;0067 030C;;;;N;LATIN SMALL LETTER G HACEK;;01E6;;01E6
488 01E8;LATIN CAPITAL LETTER K WITH CARON;Lu;0;L;004B 030C;;;;N;LATIN CAPITAL LETTER K HACEK;;;01E9;
489 01E9;LATIN SMALL LETTER K WITH CARON;Ll;0;L;006B 030C;;;;N;LATIN SMALL LETTER K HACEK;;01E8;;01E8
490 01EA;LATIN CAPITAL LETTER O WITH OGONEK;Lu;0;L;004F 0328;;;;N;LATIN CAPITAL LETTER O OGONEK;;;01EB;
491 01EB;LATIN SMALL LETTER O WITH OGONEK;Ll;0;L;006F 0328;;;;N;LATIN SMALL LETTER O OGONEK;;01EA;;01EA
492 01EC;LATIN CAPITAL LETTER O WITH OGONEK AND MACRON;Lu;0;L;01EA 0304;;;;N;LATIN CAPITAL LETTER O OGONEK MACRON;;;01ED;
493 01ED;LATIN SMALL LETTER O WITH OGONEK AND MACRON;Ll;0;L;01EB 0304;;;;N;LATIN SMALL LETTER O OGONEK MACRON;;01EC;;01EC
494 01EE;LATIN CAPITAL LETTER EZH WITH CARON;Lu;0;L;01B7 030C;;;;N;LATIN CAPITAL LETTER YOGH HACEK;;;01EF;
495 01EF;LATIN SMALL LETTER EZH WITH CARON;Ll;0;L;0292 030C;;;;N;LATIN SMALL LETTER YOGH HACEK;;01EE;;01EE
496 01F0;LATIN SMALL LETTER J WITH CARON;Ll;0;L;006A 030C;;;;N;LATIN SMALL LETTER J HACEK;;;;
497 01F1;LATIN CAPITAL LETTER DZ;Lu;0;L;<compat> 0044 005A;;;;N;;;;01F3;01F2
498 01F2;LATIN CAPITAL LETTER D WITH SMALL LETTER Z;Lt;0;L;<compat> 0044 007A;;;;N;;;01F1;01F3;01F2
499 01F3;LATIN SMALL LETTER DZ;Ll;0;L;<compat> 0064 007A;;;;N;;;01F1;;01F2
500 01F4;LATIN CAPITAL LETTER G WITH ACUTE;Lu;0;L;0047 0301;;;;N;;;;01F5;
501 01F5;LATIN SMALL LETTER G WITH ACUTE;Ll;0;L;0067 0301;;;;N;;;01F4;;01F4
502 01F6;LATIN CAPITAL LETTER HWAIR;Lu;0;L;;;;;N;;;;0195;
503 01F7;LATIN CAPITAL LETTER WYNN;Lu;0;L;;;;;N;;;;01BF;
504 01F8;LATIN CAPITAL LETTER N WITH GRAVE;Lu;0;L;004E 0300;;;;N;;;;01F9;
505 01F9;LATIN SMALL LETTER N WITH GRAVE;Ll;0;L;006E 0300;;;;N;;;01F8;;01F8
506 01FA;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE;Lu;0;L;00C5 0301;;;;N;;;;01FB;
507 01FB;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE;Ll;0;L;00E5 0301;;;;N;;;01FA;;01FA
508 01FC;LATIN CAPITAL LETTER AE WITH ACUTE;Lu;0;L;00C6 0301;;;;N;;ash *;;01FD;
509 01FD;LATIN SMALL LETTER AE WITH ACUTE;Ll;0;L;00E6 0301;;;;N;;ash *;01FC;;01FC
510 01FE;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE;Lu;0;L;00D8 0301;;;;N;;;;01FF;
511 01FF;LATIN SMALL LETTER O WITH STROKE AND ACUTE;Ll;0;L;00F8 0301;;;;N;;;01FE;;01FE
512 0200;LATIN CAPITAL LETTER A WITH DOUBLE GRAVE;Lu;0;L;0041 030F;;;;N;;;;0201;
513 0201;LATIN SMALL LETTER A WITH DOUBLE GRAVE;Ll;0;L;0061 030F;;;;N;;;0200;;0200
514 0202;LATIN CAPITAL LETTER A WITH INVERTED BREVE;Lu;0;L;0041 0311;;;;N;;;;0203;
515 0203;LATIN SMALL LETTER A WITH INVERTED BREVE;Ll;0;L;0061 0311;;;;N;;;0202;;0202
516 0204;LATIN CAPITAL LETTER E WITH DOUBLE GRAVE;Lu;0;L;0045 030F;;;;N;;;;0205;
517 0205;LATIN SMALL LETTER E WITH DOUBLE GRAVE;Ll;0;L;0065 030F;;;;N;;;0204;;0204
518 0206;LATIN CAPITAL LETTER E WITH INVERTED BREVE;Lu;0;L;0045 0311;;;;N;;;;0207;
519 0207;LATIN SMALL LETTER E WITH INVERTED BREVE;Ll;0;L;0065 0311;;;;N;;;0206;;0206
520 0208;LATIN CAPITAL LETTER I WITH DOUBLE GRAVE;Lu;0;L;0049 030F;;;;N;;;;0209;
521 0209;LATIN SMALL LETTER I WITH DOUBLE GRAVE;Ll;0;L;0069 030F;;;;N;;;0208;;0208
522 020A;LATIN CAPITAL LETTER I WITH INVERTED BREVE;Lu;0;L;0049 0311;;;;N;;;;020B;
523 020B;LATIN SMALL LETTER I WITH INVERTED BREVE;Ll;0;L;0069 0311;;;;N;;;020A;;020A
524 020C;LATIN CAPITAL LETTER O WITH DOUBLE GRAVE;Lu;0;L;004F 030F;;;;N;;;;020D;
525 020D;LATIN SMALL LETTER O WITH DOUBLE GRAVE;Ll;0;L;006F 030F;;;;N;;;020C;;020C
526 020E;LATIN CAPITAL LETTER O WITH INVERTED BREVE;Lu;0;L;004F 0311;;;;N;;;;020F;
527 020F;LATIN SMALL LETTER O WITH INVERTED BREVE;Ll;0;L;006F 0311;;;;N;;;020E;;020E
528 0210;LATIN CAPITAL LETTER R WITH DOUBLE GRAVE;Lu;0;L;0052 030F;;;;N;;;;0211;
529 0211;LATIN SMALL LETTER R WITH DOUBLE GRAVE;Ll;0;L;0072 030F;;;;N;;;0210;;0210
530 0212;LATIN CAPITAL LETTER R WITH INVERTED BREVE;Lu;0;L;0052 0311;;;;N;;;;0213;
531 0213;LATIN SMALL LETTER R WITH INVERTED BREVE;Ll;0;L;0072 0311;;;;N;;;0212;;0212
532 0214;LATIN CAPITAL LETTER U WITH DOUBLE GRAVE;Lu;0;L;0055 030F;;;;N;;;;0215;
533 0215;LATIN SMALL LETTER U WITH DOUBLE GRAVE;Ll;0;L;0075 030F;;;;N;;;0214;;0214
534 0216;LATIN CAPITAL LETTER U WITH INVERTED BREVE;Lu;0;L;0055 0311;;;;N;;;;0217;
535 0217;LATIN SMALL LETTER U WITH INVERTED BREVE;Ll;0;L;0075 0311;;;;N;;;0216;;0216
536 0218;LATIN CAPITAL LETTER S WITH COMMA BELOW;Lu;0;L;0053 0326;;;;N;;*;;0219;
537 0219;LATIN SMALL LETTER S WITH COMMA BELOW;Ll;0;L;0073 0326;;;;N;;*;0218;;0218
538 021A;LATIN CAPITAL LETTER T WITH COMMA BELOW;Lu;0;L;0054 0326;;;;N;;*;;021B;
539 021B;LATIN SMALL LETTER T WITH COMMA BELOW;Ll;0;L;0074 0326;;;;N;;*;021A;;021A
540 021C;LATIN CAPITAL LETTER YOGH;Lu;0;L;;;;;N;;;;021D;
541 021D;LATIN SMALL LETTER YOGH;Ll;0;L;;;;;N;;;021C;;021C
542 021E;LATIN CAPITAL LETTER H WITH CARON;Lu;0;L;0048 030C;;;;N;;;;021F;
543 021F;LATIN SMALL LETTER H WITH CARON;Ll;0;L;0068 030C;;;;N;;;021E;;021E
544 0220;LATIN CAPITAL LETTER N WITH LONG RIGHT LEG;Lu;0;L;;;;;N;;;;019E;
545 0221;LATIN SMALL LETTER D WITH CURL;Ll;0;L;;;;;N;;;;;
546 0222;LATIN CAPITAL LETTER OU;Lu;0;L;;;;;N;;;;0223;
547 0223;LATIN SMALL LETTER OU;Ll;0;L;;;;;N;;;0222;;0222
548 0224;LATIN CAPITAL LETTER Z WITH HOOK;Lu;0;L;;;;;N;;;;0225;
549 0225;LATIN SMALL LETTER Z WITH HOOK;Ll;0;L;;;;;N;;;0224;;0224
550 0226;LATIN CAPITAL LETTER A WITH DOT ABOVE;Lu;0;L;0041 0307;;;;N;;;;0227;
551 0227;LATIN SMALL LETTER A WITH DOT ABOVE;Ll;0;L;0061 0307;;;;N;;;0226;;0226
552 0228;LATIN CAPITAL LETTER E WITH CEDILLA;Lu;0;L;0045 0327;;;;N;;;;0229;
553 0229;LATIN SMALL LETTER E WITH CEDILLA;Ll;0;L;0065 0327;;;;N;;;0228;;0228
554 022A;LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON;Lu;0;L;00D6 0304;;;;N;;;;022B;
555 022B;LATIN SMALL LETTER O WITH DIAERESIS AND MACRON;Ll;0;L;00F6 0304;;;;N;;;022A;;022A
556 022C;LATIN CAPITAL LETTER O WITH TILDE AND MACRON;Lu;0;L;00D5 0304;;;;N;;;;022D;
557 022D;LATIN SMALL LETTER O WITH TILDE AND MACRON;Ll;0;L;00F5 0304;;;;N;;;022C;;022C
558 022E;LATIN CAPITAL LETTER O WITH DOT ABOVE;Lu;0;L;004F 0307;;;;N;;;;022F;
559 022F;LATIN SMALL LETTER O WITH DOT ABOVE;Ll;0;L;006F 0307;;;;N;;;022E;;022E
560 0230;LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON;Lu;0;L;022E 0304;;;;N;;;;0231;
561 0231;LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON;Ll;0;L;022F 0304;;;;N;;;0230;;0230
562 0232;LATIN CAPITAL LETTER Y WITH MACRON;Lu;0;L;0059 0304;;;;N;;;;0233;
563 0233;LATIN SMALL LETTER Y WITH MACRON;Ll;0;L;0079 0304;;;;N;;;0232;;0232
564 0234;LATIN SMALL LETTER L WITH CURL;Ll;0;L;;;;;N;;;;;
565 0235;LATIN SMALL LETTER N WITH CURL;Ll;0;L;;;;;N;;;;;
566 0236;LATIN SMALL LETTER T WITH CURL;Ll;0;L;;;;;N;;;;;
567 0237;LATIN SMALL LETTER DOTLESS J;Ll;0;L;;;;;N;;;;;
568 0238;LATIN SMALL LETTER DB DIGRAPH;Ll;0;L;;;;;N;;;;;
569 0239;LATIN SMALL LETTER QP DIGRAPH;Ll;0;L;;;;;N;;;;;
570 023A;LATIN CAPITAL LETTER A WITH STROKE;Lu;0;L;;;;;N;;;;2C65;
571 023B;LATIN CAPITAL LETTER C WITH STROKE;Lu;0;L;;;;;N;;;;023C;
572 023C;LATIN SMALL LETTER C WITH STROKE;Ll;0;L;;;;;N;;;023B;;023B
573 023D;LATIN CAPITAL LETTER L WITH BAR;Lu;0;L;;;;;N;;;;019A;
574 023E;LATIN CAPITAL LETTER T WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;2C66;
575 023F;LATIN SMALL LETTER S WITH SWASH TAIL;Ll;0;L;;;;;N;;;;;
576 0240;LATIN SMALL LETTER Z WITH SWASH TAIL;Ll;0;L;;;;;N;;;;;
577 0241;LATIN CAPITAL LETTER GLOTTAL STOP;Lu;0;L;;;;;N;;;;0242;
578 0242;LATIN SMALL LETTER GLOTTAL STOP;Ll;0;L;;;;;N;;;0241;;0241
579 0243;LATIN CAPITAL LETTER B WITH STROKE;Lu;0;L;;;;;N;;;;0180;
580 0244;LATIN CAPITAL LETTER U BAR;Lu;0;L;;;;;N;;;;0289;
581 0245;LATIN CAPITAL LETTER TURNED V;Lu;0;L;;;;;N;;;;028C;
582 0246;LATIN CAPITAL LETTER E WITH STROKE;Lu;0;L;;;;;N;;;;0247;
583 0247;LATIN SMALL LETTER E WITH STROKE;Ll;0;L;;;;;N;;;0246;;0246
584 0248;LATIN CAPITAL LETTER J WITH STROKE;Lu;0;L;;;;;N;;;;0249;
585 0249;LATIN SMALL LETTER J WITH STROKE;Ll;0;L;;;;;N;;;0248;;0248
586 024A;LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL;Lu;0;L;;;;;N;;;;024B;
587 024B;LATIN SMALL LETTER Q WITH HOOK TAIL;Ll;0;L;;;;;N;;;024A;;024A
588 024C;LATIN CAPITAL LETTER R WITH STROKE;Lu;0;L;;;;;N;;;;024D;
589 024D;LATIN SMALL LETTER R WITH STROKE;Ll;0;L;;;;;N;;;024C;;024C
590 024E;LATIN CAPITAL LETTER Y WITH STROKE;Lu;0;L;;;;;N;;;;024F;
591 024F;LATIN SMALL LETTER Y WITH STROKE;Ll;0;L;;;;;N;;;024E;;024E
592 0250;LATIN SMALL LETTER TURNED A;Ll;0;L;;;;;N;;;2C6F;;2C6F
593 0251;LATIN SMALL LETTER ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT A;;2C6D;;2C6D
594 0252;LATIN SMALL LETTER TURNED ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED SCRIPT A;;;;
595 0253;LATIN SMALL LETTER B WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER B HOOK;;0181;;0181
596 0254;LATIN SMALL LETTER OPEN O;Ll;0;L;;;;;N;;;0186;;0186
597 0255;LATIN SMALL LETTER C WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER C CURL;;;;
598 0256;LATIN SMALL LETTER D WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER D RETROFLEX HOOK;;0189;;0189
599 0257;LATIN SMALL LETTER D WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER D HOOK;;018A;;018A
600 0258;LATIN SMALL LETTER REVERSED E;Ll;0;L;;;;;N;;;;;
601 0259;LATIN SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;018F;;018F
602 025A;LATIN SMALL LETTER SCHWA WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCHWA HOOK;;;;
603 025B;LATIN SMALL LETTER OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER EPSILON;;0190;;0190
604 025C;LATIN SMALL LETTER REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON;;;;
605 025D;LATIN SMALL LETTER REVERSED OPEN E WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON HOOK;;;;
606 025E;LATIN SMALL LETTER CLOSED REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED REVERSED EPSILON;;;;
607 025F;LATIN SMALL LETTER DOTLESS J WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR;;;;
608 0260;LATIN SMALL LETTER G WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER G HOOK;;0193;;0193
609 0261;LATIN SMALL LETTER SCRIPT G;Ll;0;L;;;;;N;;;;;
610 0262;LATIN LETTER SMALL CAPITAL G;Ll;0;L;;;;;N;;;;;
611 0263;LATIN SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0194;;0194
612 0264;LATIN SMALL LETTER RAMS HORN;Ll;0;L;;;;;N;LATIN SMALL LETTER BABY GAMMA;;;;
613 0265;LATIN SMALL LETTER TURNED H;Ll;0;L;;;;;N;;;;;
614 0266;LATIN SMALL LETTER H WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER H HOOK;;;;
615 0267;LATIN SMALL LETTER HENG WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER HENG HOOK;;;;
616 0268;LATIN SMALL LETTER I WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED I;;0197;;0197
617 0269;LATIN SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0196;;0196
618 026A;LATIN LETTER SMALL CAPITAL I;Ll;0;L;;;;;N;;;;;
619 026B;LATIN SMALL LETTER L WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;2C62;;2C62
620 026C;LATIN SMALL LETTER L WITH BELT;Ll;0;L;;;;;N;LATIN SMALL LETTER L BELT;;;;
621 026D;LATIN SMALL LETTER L WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER L RETROFLEX HOOK;;;;
622 026E;LATIN SMALL LETTER LEZH;Ll;0;L;;;;;N;LATIN SMALL LETTER L YOGH;;;;
623 026F;LATIN SMALL LETTER TURNED M;Ll;0;L;;;;;N;;;019C;;019C
624 0270;LATIN SMALL LETTER TURNED M WITH LONG LEG;Ll;0;L;;;;;N;;;;;
625 0271;LATIN SMALL LETTER M WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER M HOOK;;2C6E;;2C6E
626 0272;LATIN SMALL LETTER N WITH LEFT HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N HOOK;;019D;;019D
627 0273;LATIN SMALL LETTER N WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N RETROFLEX HOOK;;;;
628 0274;LATIN LETTER SMALL CAPITAL N;Ll;0;L;;;;;N;;;;;
629 0275;LATIN SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;019F;;019F
630 0276;LATIN LETTER SMALL CAPITAL OE;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL O E;;;;
631 0277;LATIN SMALL LETTER CLOSED OMEGA;Ll;0;L;;;;;N;;;;;
632 0278;LATIN SMALL LETTER PHI;Ll;0;L;;;;;N;;;;;
633 0279;LATIN SMALL LETTER TURNED R;Ll;0;L;;;;;N;;;;;
634 027A;LATIN SMALL LETTER TURNED R WITH LONG LEG;Ll;0;L;;;;;N;;;;;
635 027B;LATIN SMALL LETTER TURNED R WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED R HOOK;;;;
636 027C;LATIN SMALL LETTER R WITH LONG LEG;Ll;0;L;;;;;N;;;;;
637 027D;LATIN SMALL LETTER R WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER R HOOK;;2C64;;2C64
638 027E;LATIN SMALL LETTER R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER FISHHOOK R;;;;
639 027F;LATIN SMALL LETTER REVERSED R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED FISHHOOK R;;;;
640 0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;*;01A6;;01A6
641 0281;LATIN LETTER SMALL CAPITAL INVERTED R;Ll;0;L;;;;;N;;;;;
642 0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;;;
643 0283;LATIN SMALL LETTER ESH;Ll;0;L;;;;;N;;;01A9;;01A9
644 0284;LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR HOOK;;;;
645 0285;LATIN SMALL LETTER SQUAT REVERSED ESH;Ll;0;L;;;;;N;;;;;
646 0286;LATIN SMALL LETTER ESH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER ESH CURL;;;;
647 0287;LATIN SMALL LETTER TURNED T;Ll;0;L;;;;;N;;;;;
648 0288;LATIN SMALL LETTER T WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T RETROFLEX HOOK;;01AE;;01AE
649 0289;LATIN SMALL LETTER U BAR;Ll;0;L;;;;;N;;;0244;;0244
650 028A;LATIN SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;01B1;;01B1
651 028B;LATIN SMALL LETTER V WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT V;;01B2;;01B2
652 028C;LATIN SMALL LETTER TURNED V;Ll;0;L;;;;;N;;;0245;;0245
653 028D;LATIN SMALL LETTER TURNED W;Ll;0;L;;;;;N;;;;;
654 028E;LATIN SMALL LETTER TURNED Y;Ll;0;L;;;;;N;;;;;
655 028F;LATIN LETTER SMALL CAPITAL Y;Ll;0;L;;;;;N;;;;;
656 0290;LATIN SMALL LETTER Z WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Z RETROFLEX HOOK;;;;
657 0291;LATIN SMALL LETTER Z WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER Z CURL;;;;
658 0292;LATIN SMALL LETTER EZH;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH;;01B7;;01B7
659 0293;LATIN SMALL LETTER EZH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH CURL;;;;
660 0294;LATIN LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
661 0295;LATIN LETTER PHARYNGEAL VOICED FRICATIVE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP;;;;
662 0296;LATIN LETTER INVERTED GLOTTAL STOP;Ll;0;L;;;;;N;;;;;
663 0297;LATIN LETTER STRETCHED C;Ll;0;L;;;;;N;;;;;
664 0298;LATIN LETTER BILABIAL CLICK;Ll;0;L;;;;;N;LATIN LETTER BULLSEYE;;;;
665 0299;LATIN LETTER SMALL CAPITAL B;Ll;0;L;;;;;N;;;;;
666 029A;LATIN SMALL LETTER CLOSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED EPSILON;;;;
667 029B;LATIN LETTER SMALL CAPITAL G WITH HOOK;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL G HOOK;;;;
668 029C;LATIN LETTER SMALL CAPITAL H;Ll;0;L;;;;;N;;;;;
669 029D;LATIN SMALL LETTER J WITH CROSSED-TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER CROSSED-TAIL J;;;;
670 029E;LATIN SMALL LETTER TURNED K;Ll;0;L;;;;;N;;;;;
671 029F;LATIN LETTER SMALL CAPITAL L;Ll;0;L;;;;;N;;;;;
672 02A0;LATIN SMALL LETTER Q WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Q HOOK;;;;
673 02A1;LATIN LETTER GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER GLOTTAL STOP BAR;;;;
674 02A2;LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP BAR;;;;
675 02A3;LATIN SMALL LETTER DZ DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z;;;;
676 02A4;LATIN SMALL LETTER DEZH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D YOGH;;;;
677 02A5;LATIN SMALL LETTER DZ DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z CURL;;;;
678 02A6;LATIN SMALL LETTER TS DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T S;;;;
679 02A7;LATIN SMALL LETTER TESH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T ESH;;;;
680 02A8;LATIN SMALL LETTER TC DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER T C CURL;;;;
681 02A9;LATIN SMALL LETTER FENG DIGRAPH;Ll;0;L;;;;;N;;;;;
682 02AA;LATIN SMALL LETTER LS DIGRAPH;Ll;0;L;;;;;N;;;;;
683 02AB;LATIN SMALL LETTER LZ DIGRAPH;Ll;0;L;;;;;N;;;;;
684 02AC;LATIN LETTER BILABIAL PERCUSSIVE;Ll;0;L;;;;;N;;;;;
685 02AD;LATIN LETTER BIDENTAL PERCUSSIVE;Ll;0;L;;;;;N;;;;;
686 02AE;LATIN SMALL LETTER TURNED H WITH FISHHOOK;Ll;0;L;;;;;N;;;;;
687 02AF;LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL;Ll;0;L;;;;;N;;;;;
688 02B0;MODIFIER LETTER SMALL H;Lm;0;L;<super> 0068;;;;N;;;;;
689 02B1;MODIFIER LETTER SMALL H WITH HOOK;Lm;0;L;<super> 0266;;;;N;MODIFIER LETTER SMALL H HOOK;;;;
690 02B2;MODIFIER LETTER SMALL J;Lm;0;L;<super> 006A;;;;N;;;;;
691 02B3;MODIFIER LETTER SMALL R;Lm;0;L;<super> 0072;;;;N;;;;;
692 02B4;MODIFIER LETTER SMALL TURNED R;Lm;0;L;<super> 0279;;;;N;;;;;
693 02B5;MODIFIER LETTER SMALL TURNED R WITH HOOK;Lm;0;L;<super> 027B;;;;N;MODIFIER LETTER SMALL TURNED R HOOK;;;;
694 02B6;MODIFIER LETTER SMALL CAPITAL INVERTED R;Lm;0;L;<super> 0281;;;;N;;;;;
695 02B7;MODIFIER LETTER SMALL W;Lm;0;L;<super> 0077;;;;N;;;;;
696 02B8;MODIFIER LETTER SMALL Y;Lm;0;L;<super> 0079;;;;N;;;;;
697 02B9;MODIFIER LETTER PRIME;Lm;0;ON;;;;;N;;;;;
698 02BA;MODIFIER LETTER DOUBLE PRIME;Lm;0;ON;;;;;N;;;;;
699 02BB;MODIFIER LETTER TURNED COMMA;Lm;0;L;;;;;N;;;;;
700 02BC;MODIFIER LETTER APOSTROPHE;Lm;0;L;;;;;N;;;;;
701 02BD;MODIFIER LETTER REVERSED COMMA;Lm;0;L;;;;;N;;;;;
702 02BE;MODIFIER LETTER RIGHT HALF RING;Lm;0;L;;;;;N;;;;;
703 02BF;MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;;
704 02C0;MODIFIER LETTER GLOTTAL STOP;Lm;0;L;;;;;N;;;;;
705 02C1;MODIFIER LETTER REVERSED GLOTTAL STOP;Lm;0;L;;;;;N;;;;;
706 02C2;MODIFIER LETTER LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;;
707 02C3;MODIFIER LETTER RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;;
708 02C4;MODIFIER LETTER UP ARROWHEAD;Sk;0;ON;;;;;N;;;;;
709 02C5;MODIFIER LETTER DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;;
710 02C6;MODIFIER LETTER CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER CIRCUMFLEX;;;;
711 02C7;CARON;Lm;0;ON;;;;;N;MODIFIER LETTER HACEK;Mandarin Chinese third tone;;;
712 02C8;MODIFIER LETTER VERTICAL LINE;Lm;0;ON;;;;;N;;;;;
713 02C9;MODIFIER LETTER MACRON;Lm;0;ON;;;;;N;;Mandarin Chinese first tone;;;
714 02CA;MODIFIER LETTER ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER ACUTE;Mandarin Chinese second tone;;;
715 02CB;MODIFIER LETTER GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER GRAVE;Mandarin Chinese fourth tone;;;
716 02CC;MODIFIER LETTER LOW VERTICAL LINE;Lm;0;ON;;;;;N;;;;;
717 02CD;MODIFIER LETTER LOW MACRON;Lm;0;ON;;;;;N;;;;;
718 02CE;MODIFIER LETTER LOW GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW GRAVE;;;;
719 02CF;MODIFIER LETTER LOW ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW ACUTE;;;;
720 02D0;MODIFIER LETTER TRIANGULAR COLON;Lm;0;L;;;;;N;;;;;
721 02D1;MODIFIER LETTER HALF TRIANGULAR COLON;Lm;0;L;;;;;N;;;;;
722 02D2;MODIFIER LETTER CENTRED RIGHT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED RIGHT HALF RING;;;;
723 02D3;MODIFIER LETTER CENTRED LEFT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED LEFT HALF RING;;;;
724 02D4;MODIFIER LETTER UP TACK;Sk;0;ON;;;;;N;;;;;
725 02D5;MODIFIER LETTER DOWN TACK;Sk;0;ON;;;;;N;;;;;
726 02D6;MODIFIER LETTER PLUS SIGN;Sk;0;ON;;;;;N;;;;;
727 02D7;MODIFIER LETTER MINUS SIGN;Sk;0;ON;;;;;N;;;;;
728 02D8;BREVE;Sk;0;ON;<compat> 0020 0306;;;;N;SPACING BREVE;;;;
729 02D9;DOT ABOVE;Sk;0;ON;<compat> 0020 0307;;;;N;SPACING DOT ABOVE;Mandarin Chinese light tone;;;
730 02DA;RING ABOVE;Sk;0;ON;<compat> 0020 030A;;;;N;SPACING RING ABOVE;;;;
731 02DB;OGONEK;Sk;0;ON;<compat> 0020 0328;;;;N;SPACING OGONEK;;;;
732 02DC;SMALL TILDE;Sk;0;ON;<compat> 0020 0303;;;;N;SPACING TILDE;;;;
733 02DD;DOUBLE ACUTE ACCENT;Sk;0;ON;<compat> 0020 030B;;;;N;SPACING DOUBLE ACUTE;;;;
734 02DE;MODIFIER LETTER RHOTIC HOOK;Sk;0;ON;;;;;N;;;;;
735 02DF;MODIFIER LETTER CROSS ACCENT;Sk;0;ON;;;;;N;;;;;
736 02E0;MODIFIER LETTER SMALL GAMMA;Lm;0;L;<super> 0263;;;;N;;;;;
737 02E1;MODIFIER LETTER SMALL L;Lm;0;L;<super> 006C;;;;N;;;;;
738 02E2;MODIFIER LETTER SMALL S;Lm;0;L;<super> 0073;;;;N;;;;;
739 02E3;MODIFIER LETTER SMALL X;Lm;0;L;<super> 0078;;;;N;;;;;
740 02E4;MODIFIER LETTER SMALL REVERSED GLOTTAL STOP;Lm;0;L;<super> 0295;;;;N;;;;;
741 02E5;MODIFIER LETTER EXTRA-HIGH TONE BAR;Sk;0;ON;;;;;N;;;;;
742 02E6;MODIFIER LETTER HIGH TONE BAR;Sk;0;ON;;;;;N;;;;;
743 02E7;MODIFIER LETTER MID TONE BAR;Sk;0;ON;;;;;N;;;;;
744 02E8;MODIFIER LETTER LOW TONE BAR;Sk;0;ON;;;;;N;;;;;
745 02E9;MODIFIER LETTER EXTRA-LOW TONE BAR;Sk;0;ON;;;;;N;;;;;
746 02EA;MODIFIER LETTER YIN DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;;
747 02EB;MODIFIER LETTER YANG DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;;
748 02EC;MODIFIER LETTER VOICING;Lm;0;ON;;;;;N;;;;;
749 02ED;MODIFIER LETTER UNASPIRATED;Sk;0;ON;;;;;N;;;;;
750 02EE;MODIFIER LETTER DOUBLE APOSTROPHE;Lm;0;L;;;;;N;;;;;
751 02EF;MODIFIER LETTER LOW DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;;
752 02F0;MODIFIER LETTER LOW UP ARROWHEAD;Sk;0;ON;;;;;N;;;;;
753 02F1;MODIFIER LETTER LOW LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;;
754 02F2;MODIFIER LETTER LOW RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;;
755 02F3;MODIFIER LETTER LOW RING;Sk;0;ON;;;;;N;;;;;
756 02F4;MODIFIER LETTER MIDDLE GRAVE ACCENT;Sk;0;ON;;;;;N;;;;;
757 02F5;MODIFIER LETTER MIDDLE DOUBLE GRAVE ACCENT;Sk;0;ON;;;;;N;;;;;
758 02F6;MODIFIER LETTER MIDDLE DOUBLE ACUTE ACCENT;Sk;0;ON;;;;;N;;;;;
759 02F7;MODIFIER LETTER LOW TILDE;Sk;0;ON;;;;;N;;;;;
760 02F8;MODIFIER LETTER RAISED COLON;Sk;0;ON;;;;;N;;;;;
761 02F9;MODIFIER LETTER BEGIN HIGH TONE;Sk;0;ON;;;;;N;;;;;
762 02FA;MODIFIER LETTER END HIGH TONE;Sk;0;ON;;;;;N;;;;;
763 02FB;MODIFIER LETTER BEGIN LOW TONE;Sk;0;ON;;;;;N;;;;;
764 02FC;MODIFIER LETTER END LOW TONE;Sk;0;ON;;;;;N;;;;;
765 02FD;MODIFIER LETTER SHELF;Sk;0;ON;;;;;N;;;;;
766 02FE;MODIFIER LETTER OPEN SHELF;Sk;0;ON;;;;;N;;;;;
767 02FF;MODIFIER LETTER LOW LEFT ARROW;Sk;0;ON;;;;;N;;;;;
768 0300;COMBINING GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING GRAVE;Varia;;;
769 0301;COMBINING ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING ACUTE;Oxia, Tonos;;;
770 0302;COMBINING CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;NON-SPACING CIRCUMFLEX;;;;
771 0303;COMBINING TILDE;Mn;230;NSM;;;;;N;NON-SPACING TILDE;;;;
772 0304;COMBINING MACRON;Mn;230;NSM;;;;;N;NON-SPACING MACRON;;;;
773 0305;COMBINING OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING OVERSCORE;;;;
774 0306;COMBINING BREVE;Mn;230;NSM;;;;;N;NON-SPACING BREVE;Vrachy;;;
775 0307;COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOT ABOVE;;;;
776 0308;COMBINING DIAERESIS;Mn;230;NSM;;;;;N;NON-SPACING DIAERESIS;Dialytika;;;
777 0309;COMBINING HOOK ABOVE;Mn;230;NSM;;;;;N;NON-SPACING HOOK ABOVE;;;;
778 030A;COMBINING RING ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RING ABOVE;;;;
779 030B;COMBINING DOUBLE ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE ACUTE;;;;
780 030C;COMBINING CARON;Mn;230;NSM;;;;;N;NON-SPACING HACEK;;;;
781 030D;COMBINING VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL LINE ABOVE;;;;
782 030E;COMBINING DOUBLE VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE VERTICAL LINE ABOVE;;;;
783 030F;COMBINING DOUBLE GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE GRAVE;;;;
784 0310;COMBINING CANDRABINDU;Mn;230;NSM;;;;;N;NON-SPACING CANDRABINDU;;;;
785 0311;COMBINING INVERTED BREVE;Mn;230;NSM;;;;;N;NON-SPACING INVERTED BREVE;;;;
786 0312;COMBINING TURNED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING TURNED COMMA ABOVE;;;;
787 0313;COMBINING COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING COMMA ABOVE;Psili;;;
788 0314;COMBINING REVERSED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING REVERSED COMMA ABOVE;Dasia;;;
789 0315;COMBINING COMMA ABOVE RIGHT;Mn;232;NSM;;;;;N;NON-SPACING COMMA ABOVE RIGHT;;;;
790 0316;COMBINING GRAVE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING GRAVE BELOW;;;;
791 0317;COMBINING ACUTE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING ACUTE BELOW;;;;
792 0318;COMBINING LEFT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT TACK BELOW;;;;
793 0319;COMBINING RIGHT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT TACK BELOW;;;;
794 031A;COMBINING LEFT ANGLE ABOVE;Mn;232;NSM;;;;;N;NON-SPACING LEFT ANGLE ABOVE;;;;
795 031B;COMBINING HORN;Mn;216;NSM;;;;;N;NON-SPACING HORN;;;;
796 031C;COMBINING LEFT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT HALF RING BELOW;;;;
797 031D;COMBINING UP TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING UP TACK BELOW;;;;
798 031E;COMBINING DOWN TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOWN TACK BELOW;;;;
799 031F;COMBINING PLUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING PLUS SIGN BELOW;;;;
800 0320;COMBINING MINUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING MINUS SIGN BELOW;;;;
801 0321;COMBINING PALATALIZED HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING PALATALIZED HOOK BELOW;;;;
802 0322;COMBINING RETROFLEX HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING RETROFLEX HOOK BELOW;;;;
803 0323;COMBINING DOT BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOT BELOW;;;;
804 0324;COMBINING DIAERESIS BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE DOT BELOW;;;;
805 0325;COMBINING RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RING BELOW;;;;
806 0326;COMBINING COMMA BELOW;Mn;220;NSM;;;;;N;NON-SPACING COMMA BELOW;;;;
807 0327;COMBINING CEDILLA;Mn;202;NSM;;;;;N;NON-SPACING CEDILLA;;;;
808 0328;COMBINING OGONEK;Mn;202;NSM;;;;;N;NON-SPACING OGONEK;;;;
809 0329;COMBINING VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;NON-SPACING VERTICAL LINE BELOW;;;;
810 032A;COMBINING BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BRIDGE BELOW;;;;
811 032B;COMBINING INVERTED DOUBLE ARCH BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED DOUBLE ARCH BELOW;;;;
812 032C;COMBINING CARON BELOW;Mn;220;NSM;;;;;N;NON-SPACING HACEK BELOW;;;;
813 032D;COMBINING CIRCUMFLEX ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING CIRCUMFLEX BELOW;;;;
814 032E;COMBINING BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BREVE BELOW;;;;
815 032F;COMBINING INVERTED BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BREVE BELOW;;;;
816 0330;COMBINING TILDE BELOW;Mn;220;NSM;;;;;N;NON-SPACING TILDE BELOW;;;;
817 0331;COMBINING MACRON BELOW;Mn;220;NSM;;;;;N;NON-SPACING MACRON BELOW;;;;
818 0332;COMBINING LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING UNDERSCORE;;;;
819 0333;COMBINING DOUBLE LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE UNDERSCORE;;;;
820 0334;COMBINING TILDE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING TILDE OVERLAY;;;;
821 0335;COMBINING SHORT STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT BAR OVERLAY;;;;
822 0336;COMBINING LONG STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG BAR OVERLAY;;;;
823 0337;COMBINING SHORT SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT SLASH OVERLAY;;;;
824 0338;COMBINING LONG SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG SLASH OVERLAY;;;;
825 0339;COMBINING RIGHT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT HALF RING BELOW;;;;
826 033A;COMBINING INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BRIDGE BELOW;;;;
827 033B;COMBINING SQUARE BELOW;Mn;220;NSM;;;;;N;NON-SPACING SQUARE BELOW;;;;
828 033C;COMBINING SEAGULL BELOW;Mn;220;NSM;;;;;N;NON-SPACING SEAGULL BELOW;;;;
829 033D;COMBINING X ABOVE;Mn;230;NSM;;;;;N;NON-SPACING X ABOVE;;;;
830 033E;COMBINING VERTICAL TILDE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL TILDE;;;;
831 033F;COMBINING DOUBLE OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE OVERSCORE;;;;
832 0340;COMBINING GRAVE TONE MARK;Mn;230;NSM;0300;;;;N;NON-SPACING GRAVE TONE MARK;Vietnamese;;;
833 0341;COMBINING ACUTE TONE MARK;Mn;230;NSM;0301;;;;N;NON-SPACING ACUTE TONE MARK;Vietnamese;;;
834 0342;COMBINING GREEK PERISPOMENI;Mn;230;NSM;;;;;N;;;;;
835 0343;COMBINING GREEK KORONIS;Mn;230;NSM;0313;;;;N;;;;;
836 0344;COMBINING GREEK DIALYTIKA TONOS;Mn;230;NSM;0308 0301;;;;N;GREEK NON-SPACING DIAERESIS TONOS;;;;
837 0345;COMBINING GREEK YPOGEGRAMMENI;Mn;240;NSM;;;;;N;GREEK NON-SPACING IOTA BELOW;;0399;;0399
838 0346;COMBINING BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;;
839 0347;COMBINING EQUALS SIGN BELOW;Mn;220;NSM;;;;;N;;;;;
840 0348;COMBINING DOUBLE VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;;;;;
841 0349;COMBINING LEFT ANGLE BELOW;Mn;220;NSM;;;;;N;;;;;
842 034A;COMBINING NOT TILDE ABOVE;Mn;230;NSM;;;;;N;;;;;
843 034B;COMBINING HOMOTHETIC ABOVE;Mn;230;NSM;;;;;N;;;;;
844 034C;COMBINING ALMOST EQUAL TO ABOVE;Mn;230;NSM;;;;;N;;;;;
845 034D;COMBINING LEFT RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;;
846 034E;COMBINING UPWARDS ARROW BELOW;Mn;220;NSM;;;;;N;;;;;
847 034F;COMBINING GRAPHEME JOINER;Mn;0;NSM;;;;;N;;;;;
848 0350;COMBINING RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;
849 0351;COMBINING LEFT HALF RING ABOVE;Mn;230;NSM;;;;;N;;;;;
850 0352;COMBINING FERMATA;Mn;230;NSM;;;;;N;;;;;
851 0353;COMBINING X BELOW;Mn;220;NSM;;;;;N;;;;;
852 0354;COMBINING LEFT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
853 0355;COMBINING RIGHT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
854 0356;COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
855 0357;COMBINING RIGHT HALF RING ABOVE;Mn;230;NSM;;;;;N;;;;;
856 0358;COMBINING DOT ABOVE RIGHT;Mn;232;NSM;;;;;N;;;;;
857 0359;COMBINING ASTERISK BELOW;Mn;220;NSM;;;;;N;;;;;
858 035A;COMBINING DOUBLE RING BELOW;Mn;220;NSM;;;;;N;;;;;
859 035B;COMBINING ZIGZAG ABOVE;Mn;230;NSM;;;;;N;;;;;
860 035C;COMBINING DOUBLE BREVE BELOW;Mn;233;NSM;;;;;N;;;;;
861 035D;COMBINING DOUBLE BREVE;Mn;234;NSM;;;;;N;;;;;
862 035E;COMBINING DOUBLE MACRON;Mn;234;NSM;;;;;N;;;;;
863 035F;COMBINING DOUBLE MACRON BELOW;Mn;233;NSM;;;;;N;;;;;
864 0360;COMBINING DOUBLE TILDE;Mn;234;NSM;;;;;N;;;;;
865 0361;COMBINING DOUBLE INVERTED BREVE;Mn;234;NSM;;;;;N;;;;;
866 0362;COMBINING DOUBLE RIGHTWARDS ARROW BELOW;Mn;233;NSM;;;;;N;;;;;
867 0363;COMBINING LATIN SMALL LETTER A;Mn;230;NSM;;;;;N;;;;;
868 0364;COMBINING LATIN SMALL LETTER E;Mn;230;NSM;;;;;N;;;;;
869 0365;COMBINING LATIN SMALL LETTER I;Mn;230;NSM;;;;;N;;;;;
870 0366;COMBINING LATIN SMALL LETTER O;Mn;230;NSM;;;;;N;;;;;
871 0367;COMBINING LATIN SMALL LETTER U;Mn;230;NSM;;;;;N;;;;;
872 0368;COMBINING LATIN SMALL LETTER C;Mn;230;NSM;;;;;N;;;;;
873 0369;COMBINING LATIN SMALL LETTER D;Mn;230;NSM;;;;;N;;;;;
874 036A;COMBINING LATIN SMALL LETTER H;Mn;230;NSM;;;;;N;;;;;
875 036B;COMBINING LATIN SMALL LETTER M;Mn;230;NSM;;;;;N;;;;;
876 036C;COMBINING LATIN SMALL LETTER R;Mn;230;NSM;;;;;N;;;;;
877 036D;COMBINING LATIN SMALL LETTER T;Mn;230;NSM;;;;;N;;;;;
878 036E;COMBINING LATIN SMALL LETTER V;Mn;230;NSM;;;;;N;;;;;
879 036F;COMBINING LATIN SMALL LETTER X;Mn;230;NSM;;;;;N;;;;;
880 0370;GREEK CAPITAL LETTER HETA;Lu;0;L;;;;;N;;;;0371;
881 0371;GREEK SMALL LETTER HETA;Ll;0;L;;;;;N;;;0370;;0370
882 0372;GREEK CAPITAL LETTER ARCHAIC SAMPI;Lu;0;L;;;;;N;;;;0373;
883 0373;GREEK SMALL LETTER ARCHAIC SAMPI;Ll;0;L;;;;;N;;;0372;;0372
884 0374;GREEK NUMERAL SIGN;Lm;0;ON;02B9;;;;N;GREEK UPPER NUMERAL SIGN;Dexia keraia;;;
885 0375;GREEK LOWER NUMERAL SIGN;Sk;0;ON;;;;;N;;Aristeri keraia;;;
886 0376;GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA;Lu;0;L;;;;;N;;;;0377;
887 0377;GREEK SMALL LETTER PAMPHYLIAN DIGAMMA;Ll;0;L;;;;;N;;;0376;;0376
888 037A;GREEK YPOGEGRAMMENI;Lm;0;L;<compat> 0020 0345;;;;N;GREEK SPACING IOTA BELOW;;;;
889 037B;GREEK SMALL REVERSED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FD;;03FD
890 037C;GREEK SMALL DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FE;;03FE
891 037D;GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FF;;03FF
892 037E;GREEK QUESTION MARK;Po;0;ON;003B;;;;N;;Erotimatiko;;;
893 0384;GREEK TONOS;Sk;0;ON;<compat> 0020 0301;;;;N;GREEK SPACING TONOS;;;;
894 0385;GREEK DIALYTIKA TONOS;Sk;0;ON;00A8 0301;;;;N;GREEK SPACING DIAERESIS TONOS;;;;
895 0386;GREEK CAPITAL LETTER ALPHA WITH TONOS;Lu;0;L;0391 0301;;;;N;GREEK CAPITAL LETTER ALPHA TONOS;;;03AC;
896 0387;GREEK ANO TELEIA;Po;0;ON;00B7;;;;N;;;;;
897 0388;GREEK CAPITAL LETTER EPSILON WITH TONOS;Lu;0;L;0395 0301;;;;N;GREEK CAPITAL LETTER EPSILON TONOS;;;03AD;
898 0389;GREEK CAPITAL LETTER ETA WITH TONOS;Lu;0;L;0397 0301;;;;N;GREEK CAPITAL LETTER ETA TONOS;;;03AE;
899 038A;GREEK CAPITAL LETTER IOTA WITH TONOS;Lu;0;L;0399 0301;;;;N;GREEK CAPITAL LETTER IOTA TONOS;;;03AF;
900 038C;GREEK CAPITAL LETTER OMICRON WITH TONOS;Lu;0;L;039F 0301;;;;N;GREEK CAPITAL LETTER OMICRON TONOS;;;03CC;
901 038E;GREEK CAPITAL LETTER UPSILON WITH TONOS;Lu;0;L;03A5 0301;;;;N;GREEK CAPITAL LETTER UPSILON TONOS;;;03CD;
902 038F;GREEK CAPITAL LETTER OMEGA WITH TONOS;Lu;0;L;03A9 0301;;;;N;GREEK CAPITAL LETTER OMEGA TONOS;;;03CE;
903 0390;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS;Ll;0;L;03CA 0301;;;;N;GREEK SMALL LETTER IOTA DIAERESIS TONOS;;;;
904 0391;GREEK CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;03B1;
905 0392;GREEK CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;03B2;
906 0393;GREEK CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;03B3;
907 0394;GREEK CAPITAL LETTER DELTA;Lu;0;L;;;;;N;;;;03B4;
908 0395;GREEK CAPITAL LETTER EPSILON;Lu;0;L;;;;;N;;;;03B5;
909 0396;GREEK CAPITAL LETTER ZETA;Lu;0;L;;;;;N;;;;03B6;
910 0397;GREEK CAPITAL LETTER ETA;Lu;0;L;;;;;N;;;;03B7;
911 0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8;
912 0399;GREEK CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;03B9;
913 039A;GREEK CAPITAL LETTER KAPPA;Lu;0;L;;;;;N;;;;03BA;
914 039B;GREEK CAPITAL LETTER LAMDA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER LAMBDA;;;03BB;
915 039C;GREEK CAPITAL LETTER MU;Lu;0;L;;;;;N;;;;03BC;
916 039D;GREEK CAPITAL LETTER NU;Lu;0;L;;;;;N;;;;03BD;
917 039E;GREEK CAPITAL LETTER XI;Lu;0;L;;;;;N;;;;03BE;
918 039F;GREEK CAPITAL LETTER OMICRON;Lu;0;L;;;;;N;;;;03BF;
919 03A0;GREEK CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;03C0;
920 03A1;GREEK CAPITAL LETTER RHO;Lu;0;L;;;;;N;;;;03C1;
921 03A3;GREEK CAPITAL LETTER SIGMA;Lu;0;L;;;;;N;;;;03C3;
922 03A4;GREEK CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;03C4;
923 03A5;GREEK CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;03C5;
924 03A6;GREEK CAPITAL LETTER PHI;Lu;0;L;;;;;N;;;;03C6;
925 03A7;GREEK CAPITAL LETTER CHI;Lu;0;L;;;;;N;;;;03C7;
926 03A8;GREEK CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;03C8;
927 03A9;GREEK CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;03C9;
928 03AA;GREEK CAPITAL LETTER IOTA WITH DIALYTIKA;Lu;0;L;0399 0308;;;;N;GREEK CAPITAL LETTER IOTA DIAERESIS;;;03CA;
929 03AB;GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA;Lu;0;L;03A5 0308;;;;N;GREEK CAPITAL LETTER UPSILON DIAERESIS;;;03CB;
930 03AC;GREEK SMALL LETTER ALPHA WITH TONOS;Ll;0;L;03B1 0301;;;;N;GREEK SMALL LETTER ALPHA TONOS;;0386;;0386
931 03AD;GREEK SMALL LETTER EPSILON WITH TONOS;Ll;0;L;03B5 0301;;;;N;GREEK SMALL LETTER EPSILON TONOS;;0388;;0388
932 03AE;GREEK SMALL LETTER ETA WITH TONOS;Ll;0;L;03B7 0301;;;;N;GREEK SMALL LETTER ETA TONOS;;0389;;0389
933 03AF;GREEK SMALL LETTER IOTA WITH TONOS;Ll;0;L;03B9 0301;;;;N;GREEK SMALL LETTER IOTA TONOS;;038A;;038A
934 03B0;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS;Ll;0;L;03CB 0301;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS TONOS;;;;
935 03B1;GREEK SMALL LETTER ALPHA;Ll;0;L;;;;;N;;;0391;;0391
936 03B2;GREEK SMALL LETTER BETA;Ll;0;L;;;;;N;;;0392;;0392
937 03B3;GREEK SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0393;;0393
938 03B4;GREEK SMALL LETTER DELTA;Ll;0;L;;;;;N;;;0394;;0394
939 03B5;GREEK SMALL LETTER EPSILON;Ll;0;L;;;;;N;;;0395;;0395
940 03B6;GREEK SMALL LETTER ZETA;Ll;0;L;;;;;N;;;0396;;0396
941 03B7;GREEK SMALL LETTER ETA;Ll;0;L;;;;;N;;;0397;;0397
942 03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398
943 03B9;GREEK SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0399;;0399
944 03BA;GREEK SMALL LETTER KAPPA;Ll;0;L;;;;;N;;;039A;;039A
945 03BB;GREEK SMALL LETTER LAMDA;Ll;0;L;;;;;N;GREEK SMALL LETTER LAMBDA;;039B;;039B
946 03BC;GREEK SMALL LETTER MU;Ll;0;L;;;;;N;;;039C;;039C
947 03BD;GREEK SMALL LETTER NU;Ll;0;L;;;;;N;;;039D;;039D
948 03BE;GREEK SMALL LETTER XI;Ll;0;L;;;;;N;;;039E;;039E
949 03BF;GREEK SMALL LETTER OMICRON;Ll;0;L;;;;;N;;;039F;;039F
950 03C0;GREEK SMALL LETTER PI;Ll;0;L;;;;;N;;;03A0;;03A0
951 03C1;GREEK SMALL LETTER RHO;Ll;0;L;;;;;N;;;03A1;;03A1
952 03C2;GREEK SMALL LETTER FINAL SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3
953 03C3;GREEK SMALL LETTER SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3
954 03C4;GREEK SMALL LETTER TAU;Ll;0;L;;;;;N;;;03A4;;03A4
955 03C5;GREEK SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;03A5;;03A5
956 03C6;GREEK SMALL LETTER PHI;Ll;0;L;;;;;N;;;03A6;;03A6
957 03C7;GREEK SMALL LETTER CHI;Ll;0;L;;;;;N;;;03A7;;03A7
958 03C8;GREEK SMALL LETTER PSI;Ll;0;L;;;;;N;;;03A8;;03A8
959 03C9;GREEK SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;03A9;;03A9
960 03CA;GREEK SMALL LETTER IOTA WITH DIALYTIKA;Ll;0;L;03B9 0308;;;;N;GREEK SMALL LETTER IOTA DIAERESIS;;03AA;;03AA
961 03CB;GREEK SMALL LETTER UPSILON WITH DIALYTIKA;Ll;0;L;03C5 0308;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS;;03AB;;03AB
962 03CC;GREEK SMALL LETTER OMICRON WITH TONOS;Ll;0;L;03BF 0301;;;;N;GREEK SMALL LETTER OMICRON TONOS;;038C;;038C
963 03CD;GREEK SMALL LETTER UPSILON WITH TONOS;Ll;0;L;03C5 0301;;;;N;GREEK SMALL LETTER UPSILON TONOS;;038E;;038E
964 03CE;GREEK SMALL LETTER OMEGA WITH TONOS;Ll;0;L;03C9 0301;;;;N;GREEK SMALL LETTER OMEGA TONOS;;038F;;038F
965 03CF;GREEK CAPITAL KAI SYMBOL;Lu;0;L;;;;;N;;;;03D7;
966 03D0;GREEK BETA SYMBOL;Ll;0;L;<compat> 03B2;;;;N;GREEK SMALL LETTER CURLED BETA;;0392;;0392
967 03D1;GREEK THETA SYMBOL;Ll;0;L;<compat> 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398
968 03D2;GREEK UPSILON WITH HOOK SYMBOL;Lu;0;L;<compat> 03A5;;;;N;GREEK CAPITAL LETTER UPSILON HOOK;;;;
969 03D3;GREEK UPSILON WITH ACUTE AND HOOK SYMBOL;Lu;0;L;03D2 0301;;;;N;GREEK CAPITAL LETTER UPSILON HOOK TONOS;;;;
970 03D4;GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL;Lu;0;L;03D2 0308;;;;N;GREEK CAPITAL LETTER UPSILON HOOK DIAERESIS;;;;
971 03D5;GREEK PHI SYMBOL;Ll;0;L;<compat> 03C6;;;;N;GREEK SMALL LETTER SCRIPT PHI;;03A6;;03A6
972 03D6;GREEK PI SYMBOL;Ll;0;L;<compat> 03C0;;;;N;GREEK SMALL LETTER OMEGA PI;;03A0;;03A0
973 03D7;GREEK KAI SYMBOL;Ll;0;L;;;;;N;;;03CF;;03CF
974 03D8;GREEK LETTER ARCHAIC KOPPA;Lu;0;L;;;;;N;;*;;03D9;
975 03D9;GREEK SMALL LETTER ARCHAIC KOPPA;Ll;0;L;;;;;N;;*;03D8;;03D8
976 03DA;GREEK LETTER STIGMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER STIGMA;;;03DB;
977 03DB;GREEK SMALL LETTER STIGMA;Ll;0;L;;;;;N;;;03DA;;03DA
978 03DC;GREEK LETTER DIGAMMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DIGAMMA;;;03DD;
979 03DD;GREEK SMALL LETTER DIGAMMA;Ll;0;L;;;;;N;;;03DC;;03DC
980 03DE;GREEK LETTER KOPPA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KOPPA;;;03DF;
981 03DF;GREEK SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;03DE;;03DE
982 03E0;GREEK LETTER SAMPI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SAMPI;;;03E1;
983 03E1;GREEK SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;03E0;;03E0
984 03E2;COPTIC CAPITAL LETTER SHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHEI;;;03E3;
985 03E3;COPTIC SMALL LETTER SHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER SHEI;;03E2;;03E2
986 03E4;COPTIC CAPITAL LETTER FEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER FEI;;;03E5;
987 03E5;COPTIC SMALL LETTER FEI;Ll;0;L;;;;;N;GREEK SMALL LETTER FEI;;03E4;;03E4
988 03E6;COPTIC CAPITAL LETTER KHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KHEI;;;03E7;
989 03E7;COPTIC SMALL LETTER KHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER KHEI;;03E6;;03E6
990 03E8;COPTIC CAPITAL LETTER HORI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER HORI;;;03E9;
991 03E9;COPTIC SMALL LETTER HORI;Ll;0;L;;;;;N;GREEK SMALL LETTER HORI;;03E8;;03E8
992 03EA;COPTIC CAPITAL LETTER GANGIA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER GANGIA;;;03EB;
993 03EB;COPTIC SMALL LETTER GANGIA;Ll;0;L;;;;;N;GREEK SMALL LETTER GANGIA;;03EA;;03EA
994 03EC;COPTIC CAPITAL LETTER SHIMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHIMA;;;03ED;
995 03ED;COPTIC SMALL LETTER SHIMA;Ll;0;L;;;;;N;GREEK SMALL LETTER SHIMA;;03EC;;03EC
996 03EE;COPTIC CAPITAL LETTER DEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DEI;;;03EF;
997 03EF;COPTIC SMALL LETTER DEI;Ll;0;L;;;;;N;GREEK SMALL LETTER DEI;;03EE;;03EE
998 03F0;GREEK KAPPA SYMBOL;Ll;0;L;<compat> 03BA;;;;N;GREEK SMALL LETTER SCRIPT KAPPA;;039A;;039A
999 03F1;GREEK RHO SYMBOL;Ll;0;L;<compat> 03C1;;;;N;GREEK SMALL LETTER TAILED RHO;;03A1;;03A1
1000 03F2;GREEK LUNATE SIGMA SYMBOL;Ll;0;L;<compat> 03C2;;;;N;GREEK SMALL LETTER LUNATE SIGMA;;03F9;;03F9
1001 03F3;GREEK LETTER YOT;Ll;0;L;;;;;N;;;;;
1002 03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L;<compat> 0398;;;;N;;;;03B8;
1003 03F5;GREEK LUNATE EPSILON SYMBOL;Ll;0;L;<compat> 03B5;;;;N;;;0395;;0395
1004 03F6;GREEK REVERSED LUNATE EPSILON SYMBOL;Sm;0;ON;;;;;N;;;;;
1005 03F7;GREEK CAPITAL LETTER SHO;Lu;0;L;;;;;N;;;;03F8;
1006 03F8;GREEK SMALL LETTER SHO;Ll;0;L;;;;;N;;;03F7;;03F7
1007 03F9;GREEK CAPITAL LUNATE SIGMA SYMBOL;Lu;0;L;<compat> 03A3;;;;N;;;;03F2;
1008 03FA;GREEK CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;03FB;
1009 03FB;GREEK SMALL LETTER SAN;Ll;0;L;;;;;N;;;03FA;;03FA
1010 03FC;GREEK RHO WITH STROKE SYMBOL;Ll;0;L;;;;;N;;;;;
1011 03FD;GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037B;
1012 03FE;GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037C;
1013 03FF;GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037D;
1014 0400;CYRILLIC CAPITAL LETTER IE WITH GRAVE;Lu;0;L;0415 0300;;;;N;;;;0450;
1015 0401;CYRILLIC CAPITAL LETTER IO;Lu;0;L;0415 0308;;;;N;;;;0451;
1016 0402;CYRILLIC CAPITAL LETTER DJE;Lu;0;L;;;;;N;;Serbocroatian;;0452;
1017 0403;CYRILLIC CAPITAL LETTER GJE;Lu;0;L;0413 0301;;;;N;;;;0453;
1018 0404;CYRILLIC CAPITAL LETTER UKRAINIAN IE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER E;;;0454;
1019 0405;CYRILLIC CAPITAL LETTER DZE;Lu;0;L;;;;;N;;;;0455;
1020 0406;CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER I;;;0456;
1021 0407;CYRILLIC CAPITAL LETTER YI;Lu;0;L;0406 0308;;;;N;;Ukrainian;;0457;
1022 0408;CYRILLIC CAPITAL LETTER JE;Lu;0;L;;;;;N;;;;0458;
1023 0409;CYRILLIC CAPITAL LETTER LJE;Lu;0;L;;;;;N;;;;0459;
1024 040A;CYRILLIC CAPITAL LETTER NJE;Lu;0;L;;;;;N;;;;045A;
1025 040B;CYRILLIC CAPITAL LETTER TSHE;Lu;0;L;;;;;N;;Serbocroatian;;045B;
1026 040C;CYRILLIC CAPITAL LETTER KJE;Lu;0;L;041A 0301;;;;N;;;;045C;
1027 040D;CYRILLIC CAPITAL LETTER I WITH GRAVE;Lu;0;L;0418 0300;;;;N;;;;045D;
1028 040E;CYRILLIC CAPITAL LETTER SHORT U;Lu;0;L;0423 0306;;;;N;;Byelorussian;;045E;
1029 040F;CYRILLIC CAPITAL LETTER DZHE;Lu;0;L;;;;;N;;;;045F;
1030 0410;CYRILLIC CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0430;
1031 0411;CYRILLIC CAPITAL LETTER BE;Lu;0;L;;;;;N;;;;0431;
1032 0412;CYRILLIC CAPITAL LETTER VE;Lu;0;L;;;;;N;;;;0432;
1033 0413;CYRILLIC CAPITAL LETTER GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE;;;0433;
1034 0414;CYRILLIC CAPITAL LETTER DE;Lu;0;L;;;;;N;;;;0434;
1035 0415;CYRILLIC CAPITAL LETTER IE;Lu;0;L;;;;;N;;;;0435;
1036 0416;CYRILLIC CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;0436;
1037 0417;CYRILLIC CAPITAL LETTER ZE;Lu;0;L;;;;;N;;;;0437;
1038 0418;CYRILLIC CAPITAL LETTER I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER II;;;0438;
1039 0419;CYRILLIC CAPITAL LETTER SHORT I;Lu;0;L;0418 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT II;;;0439;
1040 041A;CYRILLIC CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;043A;
1041 041B;CYRILLIC CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;043B;
1042 041C;CYRILLIC CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;043C;
1043 041D;CYRILLIC CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;043D;
1044 041E;CYRILLIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;043E;
1045 041F;CYRILLIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;043F;
1046 0420;CYRILLIC CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;0440;
1047 0421;CYRILLIC CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;0441;
1048 0422;CYRILLIC CAPITAL LETTER TE;Lu;0;L;;;;;N;;;;0442;
1049 0423;CYRILLIC CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0443;
1050 0424;CYRILLIC CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;0444;
1051 0425;CYRILLIC CAPITAL LETTER HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA;;;0445;
1052 0426;CYRILLIC CAPITAL LETTER TSE;Lu;0;L;;;;;N;;;;0446;
1053 0427;CYRILLIC CAPITAL LETTER CHE;Lu;0;L;;;;;N;;;;0447;
1054 0428;CYRILLIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0448;
1055 0429;CYRILLIC CAPITAL LETTER SHCHA;Lu;0;L;;;;;N;;;;0449;
1056 042A;CYRILLIC CAPITAL LETTER HARD SIGN;Lu;0;L;;;;;N;;;;044A;
1057 042B;CYRILLIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER YERI;;;044B;
1058 042C;CYRILLIC CAPITAL LETTER SOFT SIGN;Lu;0;L;;;;;N;;;;044C;
1059 042D;CYRILLIC CAPITAL LETTER E;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED E;;;044D;
1060 042E;CYRILLIC CAPITAL LETTER YU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IU;;;044E;
1061 042F;CYRILLIC CAPITAL LETTER YA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IA;;;044F;
1062 0430;CYRILLIC SMALL LETTER A;Ll;0;L;;;;;N;;;0410;;0410
1063 0431;CYRILLIC SMALL LETTER BE;Ll;0;L;;;;;N;;;0411;;0411
1064 0432;CYRILLIC SMALL LETTER VE;Ll;0;L;;;;;N;;;0412;;0412
1065 0433;CYRILLIC SMALL LETTER GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE;;0413;;0413
1066 0434;CYRILLIC SMALL LETTER DE;Ll;0;L;;;;;N;;;0414;;0414
1067 0435;CYRILLIC SMALL LETTER IE;Ll;0;L;;;;;N;;;0415;;0415
1068 0436;CYRILLIC SMALL LETTER ZHE;Ll;0;L;;;;;N;;;0416;;0416
1069 0437;CYRILLIC SMALL LETTER ZE;Ll;0;L;;;;;N;;;0417;;0417
1070 0438;CYRILLIC SMALL LETTER I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER II;;0418;;0418
1071 0439;CYRILLIC SMALL LETTER SHORT I;Ll;0;L;0438 0306;;;;N;CYRILLIC SMALL LETTER SHORT II;;0419;;0419
1072 043A;CYRILLIC SMALL LETTER KA;Ll;0;L;;;;;N;;;041A;;041A
1073 043B;CYRILLIC SMALL LETTER EL;Ll;0;L;;;;;N;;;041B;;041B
1074 043C;CYRILLIC SMALL LETTER EM;Ll;0;L;;;;;N;;;041C;;041C
1075 043D;CYRILLIC SMALL LETTER EN;Ll;0;L;;;;;N;;;041D;;041D
1076 043E;CYRILLIC SMALL LETTER O;Ll;0;L;;;;;N;;;041E;;041E
1077 043F;CYRILLIC SMALL LETTER PE;Ll;0;L;;;;;N;;;041F;;041F
1078 0440;CYRILLIC SMALL LETTER ER;Ll;0;L;;;;;N;;;0420;;0420
1079 0441;CYRILLIC SMALL LETTER ES;Ll;0;L;;;;;N;;;0421;;0421
1080 0442;CYRILLIC SMALL LETTER TE;Ll;0;L;;;;;N;;;0422;;0422
1081 0443;CYRILLIC SMALL LETTER U;Ll;0;L;;;;;N;;;0423;;0423
1082 0444;CYRILLIC SMALL LETTER EF;Ll;0;L;;;;;N;;;0424;;0424
1083 0445;CYRILLIC SMALL LETTER HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA;;0425;;0425
1084 0446;CYRILLIC SMALL LETTER TSE;Ll;0;L;;;;;N;;;0426;;0426
1085 0447;CYRILLIC SMALL LETTER CHE;Ll;0;L;;;;;N;;;0427;;0427
1086 0448;CYRILLIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;0428;;0428
1087 0449;CYRILLIC SMALL LETTER SHCHA;Ll;0;L;;;;;N;;;0429;;0429
1088 044A;CYRILLIC SMALL LETTER HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A
1089 044B;CYRILLIC SMALL LETTER YERU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER YERI;;042B;;042B
1090 044C;CYRILLIC SMALL LETTER SOFT SIGN;Ll;0;L;;;;;N;;;042C;;042C
1091 044D;CYRILLIC SMALL LETTER E;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED E;;042D;;042D
1092 044E;CYRILLIC SMALL LETTER YU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IU;;042E;;042E
1093 044F;CYRILLIC SMALL LETTER YA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IA;;042F;;042F
1094 0450;CYRILLIC SMALL LETTER IE WITH GRAVE;Ll;0;L;0435 0300;;;;N;;;0400;;0400
1095 0451;CYRILLIC SMALL LETTER IO;Ll;0;L;0435 0308;;;;N;;;0401;;0401
1096 0452;CYRILLIC SMALL LETTER DJE;Ll;0;L;;;;;N;;Serbocroatian;0402;;0402
1097 0453;CYRILLIC SMALL LETTER GJE;Ll;0;L;0433 0301;;;;N;;;0403;;0403
1098 0454;CYRILLIC SMALL LETTER UKRAINIAN IE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER E;;0404;;0404
1099 0455;CYRILLIC SMALL LETTER DZE;Ll;0;L;;;;;N;;;0405;;0405
1100 0456;CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER I;;0406;;0406
1101 0457;CYRILLIC SMALL LETTER YI;Ll;0;L;0456 0308;;;;N;;Ukrainian;0407;;0407
1102 0458;CYRILLIC SMALL LETTER JE;Ll;0;L;;;;;N;;;0408;;0408
1103 0459;CYRILLIC SMALL LETTER LJE;Ll;0;L;;;;;N;;;0409;;0409
1104 045A;CYRILLIC SMALL LETTER NJE;Ll;0;L;;;;;N;;;040A;;040A
1105 045B;CYRILLIC SMALL LETTER TSHE;Ll;0;L;;;;;N;;Serbocroatian;040B;;040B
1106 045C;CYRILLIC SMALL LETTER KJE;Ll;0;L;043A 0301;;;;N;;;040C;;040C
1107 045D;CYRILLIC SMALL LETTER I WITH GRAVE;Ll;0;L;0438 0300;;;;N;;;040D;;040D
1108 045E;CYRILLIC SMALL LETTER SHORT U;Ll;0;L;0443 0306;;;;N;;Byelorussian;040E;;040E
1109 045F;CYRILLIC SMALL LETTER DZHE;Ll;0;L;;;;;N;;;040F;;040F
1110 0460;CYRILLIC CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;0461;
1111 0461;CYRILLIC SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;0460;;0460
1112 0462;CYRILLIC CAPITAL LETTER YAT;Lu;0;L;;;;;N;;;;0463;
1113 0463;CYRILLIC SMALL LETTER YAT;Ll;0;L;;;;;N;;;0462;;0462
1114 0464;CYRILLIC CAPITAL LETTER IOTIFIED E;Lu;0;L;;;;;N;;;;0465;
1115 0465;CYRILLIC SMALL LETTER IOTIFIED E;Ll;0;L;;;;;N;;;0464;;0464
1116 0466;CYRILLIC CAPITAL LETTER LITTLE YUS;Lu;0;L;;;;;N;;;;0467;
1117 0467;CYRILLIC SMALL LETTER LITTLE YUS;Ll;0;L;;;;;N;;;0466;;0466
1118 0468;CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS;Lu;0;L;;;;;N;;;;0469;
1119 0469;CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS;Ll;0;L;;;;;N;;;0468;;0468
1120 046A;CYRILLIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;046B;
1121 046B;CYRILLIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;046A;;046A
1122 046C;CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS;Lu;0;L;;;;;N;;;;046D;
1123 046D;CYRILLIC SMALL LETTER IOTIFIED BIG YUS;Ll;0;L;;;;;N;;;046C;;046C
1124 046E;CYRILLIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;046F;
1125 046F;CYRILLIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;046E;;046E
1126 0470;CYRILLIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;0471;
1127 0471;CYRILLIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;0470;;0470
1128 0472;CYRILLIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;0473;
1129 0473;CYRILLIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;0472;;0472
1130 0474;CYRILLIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;0475;
1131 0475;CYRILLIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;0474;;0474
1132 0476;CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Lu;0;L;0474 030F;;;;N;CYRILLIC CAPITAL LETTER IZHITSA DOUBLE GRAVE;;;0477;
1133 0477;CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Ll;0;L;0475 030F;;;;N;CYRILLIC SMALL LETTER IZHITSA DOUBLE GRAVE;;0476;;0476
1134 0478;CYRILLIC CAPITAL LETTER UK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER UK DIGRAPH;;;0479;
1135 0479;CYRILLIC SMALL LETTER UK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER UK DIGRAPH;;0478;;0478
1136 047A;CYRILLIC CAPITAL LETTER ROUND OMEGA;Lu;0;L;;;;;N;;;;047B;
1137 047B;CYRILLIC SMALL LETTER ROUND OMEGA;Ll;0;L;;;;;N;;;047A;;047A
1138 047C;CYRILLIC CAPITAL LETTER OMEGA WITH TITLO;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER OMEGA TITLO;;;047D;
1139 047D;CYRILLIC SMALL LETTER OMEGA WITH TITLO;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER OMEGA TITLO;;047C;;047C
1140 047E;CYRILLIC CAPITAL LETTER OT;Lu;0;L;;;;;N;;;;047F;
1141 047F;CYRILLIC SMALL LETTER OT;Ll;0;L;;;;;N;;;047E;;047E
1142 0480;CYRILLIC CAPITAL LETTER KOPPA;Lu;0;L;;;;;N;;;;0481;
1143 0481;CYRILLIC SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;0480;;0480
1144 0482;CYRILLIC THOUSANDS SIGN;So;0;L;;;;;N;;;;;
1145 0483;COMBINING CYRILLIC TITLO;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING TITLO;;;;
1146 0484;COMBINING CYRILLIC PALATALIZATION;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PALATALIZATION;;;;
1147 0485;COMBINING CYRILLIC DASIA PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING DASIA PNEUMATA;;;;
1148 0486;COMBINING CYRILLIC PSILI PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PSILI PNEUMATA;;;;
1149 0487;COMBINING CYRILLIC POKRYTIE;Mn;230;NSM;;;;;N;;;;;
1150 0488;COMBINING CYRILLIC HUNDRED THOUSANDS SIGN;Me;0;NSM;;;;;N;;;;;
1151 0489;COMBINING CYRILLIC MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
1152 048A;CYRILLIC CAPITAL LETTER SHORT I WITH TAIL;Lu;0;L;;;;;N;;;;048B;
1153 048B;CYRILLIC SMALL LETTER SHORT I WITH TAIL;Ll;0;L;;;;;N;;;048A;;048A
1154 048C;CYRILLIC CAPITAL LETTER SEMISOFT SIGN;Lu;0;L;;;;;N;;;;048D;
1155 048D;CYRILLIC SMALL LETTER SEMISOFT SIGN;Ll;0;L;;;;;N;;;048C;;048C
1156 048E;CYRILLIC CAPITAL LETTER ER WITH TICK;Lu;0;L;;;;;N;;;;048F;
1157 048F;CYRILLIC SMALL LETTER ER WITH TICK;Ll;0;L;;;;;N;;;048E;;048E
1158 0490;CYRILLIC CAPITAL LETTER GHE WITH UPTURN;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE WITH UPTURN;;;0491;
1159 0491;CYRILLIC SMALL LETTER GHE WITH UPTURN;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE WITH UPTURN;;0490;;0490
1160 0492;CYRILLIC CAPITAL LETTER GHE WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE BAR;;;0493;
1161 0493;CYRILLIC SMALL LETTER GHE WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE BAR;;0492;;0492
1162 0494;CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE HOOK;;;0495;
1163 0495;CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE HOOK;;0494;;0494
1164 0496;CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZHE WITH RIGHT DESCENDER;;;0497;
1165 0497;CYRILLIC SMALL LETTER ZHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZHE WITH RIGHT DESCENDER;;0496;;0496
1166 0498;CYRILLIC CAPITAL LETTER ZE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZE CEDILLA;;;0499;
1167 0499;CYRILLIC SMALL LETTER ZE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZE CEDILLA;;0498;;0498
1168 049A;CYRILLIC CAPITAL LETTER KA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA WITH RIGHT DESCENDER;;;049B;
1169 049B;CYRILLIC SMALL LETTER KA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA WITH RIGHT DESCENDER;;049A;;049A
1170 049C;CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA VERTICAL BAR;;;049D;
1171 049D;CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA VERTICAL BAR;;049C;;049C
1172 049E;CYRILLIC CAPITAL LETTER KA WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA BAR;;;049F;
1173 049F;CYRILLIC SMALL LETTER KA WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA BAR;;049E;;049E
1174 04A0;CYRILLIC CAPITAL LETTER BASHKIR KA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED GE KA;;;04A1;
1175 04A1;CYRILLIC SMALL LETTER BASHKIR KA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED GE KA;;04A0;;04A0
1176 04A2;CYRILLIC CAPITAL LETTER EN WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN WITH RIGHT DESCENDER;;;04A3;
1177 04A3;CYRILLIC SMALL LETTER EN WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN WITH RIGHT DESCENDER;;04A2;;04A2
1178 04A4;CYRILLIC CAPITAL LIGATURE EN GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN GE;;;04A5;
1179 04A5;CYRILLIC SMALL LIGATURE EN GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN GE;;04A4;;04A4
1180 04A6;CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER PE HOOK;Abkhasian;;04A7;
1181 04A7;CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER PE HOOK;Abkhasian;04A6;;04A6
1182 04A8;CYRILLIC CAPITAL LETTER ABKHASIAN HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER O HOOK;;;04A9;
1183 04A9;CYRILLIC SMALL LETTER ABKHASIAN HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER O HOOK;;04A8;;04A8
1184 04AA;CYRILLIC CAPITAL LETTER ES WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ES CEDILLA;;;04AB;
1185 04AB;CYRILLIC SMALL LETTER ES WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ES CEDILLA;;04AA;;04AA
1186 04AC;CYRILLIC CAPITAL LETTER TE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE WITH RIGHT DESCENDER;;;04AD;
1187 04AD;CYRILLIC SMALL LETTER TE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE WITH RIGHT DESCENDER;;04AC;;04AC
1188 04AE;CYRILLIC CAPITAL LETTER STRAIGHT U;Lu;0;L;;;;;N;;;;04AF;
1189 04AF;CYRILLIC SMALL LETTER STRAIGHT U;Ll;0;L;;;;;N;;;04AE;;04AE
1190 04B0;CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER STRAIGHT U BAR;;;04B1;
1191 04B1;CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER STRAIGHT U BAR;;04B0;;04B0
1192 04B2;CYRILLIC CAPITAL LETTER HA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA WITH RIGHT DESCENDER;;;04B3;
1193 04B3;CYRILLIC SMALL LETTER HA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA WITH RIGHT DESCENDER;;04B2;;04B2
1194 04B4;CYRILLIC CAPITAL LIGATURE TE TSE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE TSE;Abkhasian;;04B5;
1195 04B5;CYRILLIC SMALL LIGATURE TE TSE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE TSE;Abkhasian;04B4;;04B4
1196 04B6;CYRILLIC CAPITAL LETTER CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH RIGHT DESCENDER;;;04B7;
1197 04B7;CYRILLIC SMALL LETTER CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH RIGHT DESCENDER;;04B6;;04B6
1198 04B8;CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE VERTICAL BAR;;;04B9;
1199 04B9;CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE VERTICAL BAR;;04B8;;04B8
1200 04BA;CYRILLIC CAPITAL LETTER SHHA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER H;;;04BB;
1201 04BB;CYRILLIC SMALL LETTER SHHA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER H;;04BA;;04BA
1202 04BC;CYRILLIC CAPITAL LETTER ABKHASIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK;;;04BD;
1203 04BD;CYRILLIC SMALL LETTER ABKHASIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK;;04BC;;04BC
1204 04BE;CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK OGONEK;;;04BF;
1205 04BF;CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK OGONEK;;04BE;;04BE
1206 04C0;CYRILLIC LETTER PALOCHKA;Lu;0;L;;;;;N;CYRILLIC LETTER I;;;04CF;
1207 04C1;CYRILLIC CAPITAL LETTER ZHE WITH BREVE;Lu;0;L;0416 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT ZHE;;;04C2;
1208 04C2;CYRILLIC SMALL LETTER ZHE WITH BREVE;Ll;0;L;0436 0306;;;;N;CYRILLIC SMALL LETTER SHORT ZHE;;04C1;;04C1
1209 04C3;CYRILLIC CAPITAL LETTER KA WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA HOOK;;;04C4;
1210 04C4;CYRILLIC SMALL LETTER KA WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA HOOK;;04C3;;04C3
1211 04C5;CYRILLIC CAPITAL LETTER EL WITH TAIL;Lu;0;L;;;;;N;;;;04C6;
1212 04C6;CYRILLIC SMALL LETTER EL WITH TAIL;Ll;0;L;;;;;N;;;04C5;;04C5
1213 04C7;CYRILLIC CAPITAL LETTER EN WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN HOOK;;;04C8;
1214 04C8;CYRILLIC SMALL LETTER EN WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN HOOK;;04C7;;04C7
1215 04C9;CYRILLIC CAPITAL LETTER EN WITH TAIL;Lu;0;L;;;;;N;;;;04CA;
1216 04CA;CYRILLIC SMALL LETTER EN WITH TAIL;Ll;0;L;;;;;N;;;04C9;;04C9
1217 04CB;CYRILLIC CAPITAL LETTER KHAKASSIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH LEFT DESCENDER;;;04CC;
1218 04CC;CYRILLIC SMALL LETTER KHAKASSIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH LEFT DESCENDER;;04CB;;04CB
1219 04CD;CYRILLIC CAPITAL LETTER EM WITH TAIL;Lu;0;L;;;;;N;;;;04CE;
1220 04CE;CYRILLIC SMALL LETTER EM WITH TAIL;Ll;0;L;;;;;N;;;04CD;;04CD
1221 04CF;CYRILLIC SMALL LETTER PALOCHKA;Ll;0;L;;;;;N;;;04C0;;04C0
1222 04D0;CYRILLIC CAPITAL LETTER A WITH BREVE;Lu;0;L;0410 0306;;;;N;;;;04D1;
1223 04D1;CYRILLIC SMALL LETTER A WITH BREVE;Ll;0;L;0430 0306;;;;N;;;04D0;;04D0
1224 04D2;CYRILLIC CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0410 0308;;;;N;;;;04D3;
1225 04D3;CYRILLIC SMALL LETTER A WITH DIAERESIS;Ll;0;L;0430 0308;;;;N;;;04D2;;04D2
1226 04D4;CYRILLIC CAPITAL LIGATURE A IE;Lu;0;L;;;;;N;;;;04D5;
1227 04D5;CYRILLIC SMALL LIGATURE A IE;Ll;0;L;;;;;N;;;04D4;;04D4
1228 04D6;CYRILLIC CAPITAL LETTER IE WITH BREVE;Lu;0;L;0415 0306;;;;N;;;;04D7;
1229 04D7;CYRILLIC SMALL LETTER IE WITH BREVE;Ll;0;L;0435 0306;;;;N;;;04D6;;04D6
1230 04D8;CYRILLIC CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;04D9;
1231 04D9;CYRILLIC SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;04D8;;04D8
1232 04DA;CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS;Lu;0;L;04D8 0308;;;;N;;;;04DB;
1233 04DB;CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS;Ll;0;L;04D9 0308;;;;N;;;04DA;;04DA
1234 04DC;CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS;Lu;0;L;0416 0308;;;;N;;;;04DD;
1235 04DD;CYRILLIC SMALL LETTER ZHE WITH DIAERESIS;Ll;0;L;0436 0308;;;;N;;;04DC;;04DC
1236 04DE;CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS;Lu;0;L;0417 0308;;;;N;;;;04DF;
1237 04DF;CYRILLIC SMALL LETTER ZE WITH DIAERESIS;Ll;0;L;0437 0308;;;;N;;;04DE;;04DE
1238 04E0;CYRILLIC CAPITAL LETTER ABKHASIAN DZE;Lu;0;L;;;;;N;;;;04E1;
1239 04E1;CYRILLIC SMALL LETTER ABKHASIAN DZE;Ll;0;L;;;;;N;;;04E0;;04E0
1240 04E2;CYRILLIC CAPITAL LETTER I WITH MACRON;Lu;0;L;0418 0304;;;;N;;;;04E3;
1241 04E3;CYRILLIC SMALL LETTER I WITH MACRON;Ll;0;L;0438 0304;;;;N;;;04E2;;04E2
1242 04E4;CYRILLIC CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0418 0308;;;;N;;;;04E5;
1243 04E5;CYRILLIC SMALL LETTER I WITH DIAERESIS;Ll;0;L;0438 0308;;;;N;;;04E4;;04E4
1244 04E6;CYRILLIC CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;041E 0308;;;;N;;;;04E7;
1245 04E7;CYRILLIC SMALL LETTER O WITH DIAERESIS;Ll;0;L;043E 0308;;;;N;;;04E6;;04E6
1246 04E8;CYRILLIC CAPITAL LETTER BARRED O;Lu;0;L;;;;;N;;;;04E9;
1247 04E9;CYRILLIC SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;04E8;;04E8
1248 04EA;CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS;Lu;0;L;04E8 0308;;;;N;;;;04EB;
1249 04EB;CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS;Ll;0;L;04E9 0308;;;;N;;;04EA;;04EA
1250 04EC;CYRILLIC CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;042D 0308;;;;N;;;;04ED;
1251 04ED;CYRILLIC SMALL LETTER E WITH DIAERESIS;Ll;0;L;044D 0308;;;;N;;;04EC;;04EC
1252 04EE;CYRILLIC CAPITAL LETTER U WITH MACRON;Lu;0;L;0423 0304;;;;N;;;;04EF;
1253 04EF;CYRILLIC SMALL LETTER U WITH MACRON;Ll;0;L;0443 0304;;;;N;;;04EE;;04EE
1254 04F0;CYRILLIC CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0423 0308;;;;N;;;;04F1;
1255 04F1;CYRILLIC SMALL LETTER U WITH DIAERESIS;Ll;0;L;0443 0308;;;;N;;;04F0;;04F0
1256 04F2;CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0423 030B;;;;N;;;;04F3;
1257 04F3;CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0443 030B;;;;N;;;04F2;;04F2
1258 04F4;CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS;Lu;0;L;0427 0308;;;;N;;;;04F5;
1259 04F5;CYRILLIC SMALL LETTER CHE WITH DIAERESIS;Ll;0;L;0447 0308;;;;N;;;04F4;;04F4
1260 04F6;CYRILLIC CAPITAL LETTER GHE WITH DESCENDER;Lu;0;L;;;;;N;;;;04F7;
1261 04F7;CYRILLIC SMALL LETTER GHE WITH DESCENDER;Ll;0;L;;;;;N;;;04F6;;04F6
1262 04F8;CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS;Lu;0;L;042B 0308;;;;N;;;;04F9;
1263 04F9;CYRILLIC SMALL LETTER YERU WITH DIAERESIS;Ll;0;L;044B 0308;;;;N;;;04F8;;04F8
1264 04FA;CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK;Lu;0;L;;;;;N;;;;04FB;
1265 04FB;CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK;Ll;0;L;;;;;N;;;04FA;;04FA
1266 04FC;CYRILLIC CAPITAL LETTER HA WITH HOOK;Lu;0;L;;;;;N;;;;04FD;
1267 04FD;CYRILLIC SMALL LETTER HA WITH HOOK;Ll;0;L;;;;;N;;;04FC;;04FC
1268 04FE;CYRILLIC CAPITAL LETTER HA WITH STROKE;Lu;0;L;;;;;N;;;;04FF;
1269 04FF;CYRILLIC SMALL LETTER HA WITH STROKE;Ll;0;L;;;;;N;;;04FE;;04FE
1270 0500;CYRILLIC CAPITAL LETTER KOMI DE;Lu;0;L;;;;;N;;;;0501;
1271 0501;CYRILLIC SMALL LETTER KOMI DE;Ll;0;L;;;;;N;;;0500;;0500
1272 0502;CYRILLIC CAPITAL LETTER KOMI DJE;Lu;0;L;;;;;N;;;;0503;
1273 0503;CYRILLIC SMALL LETTER KOMI DJE;Ll;0;L;;;;;N;;;0502;;0502
1274 0504;CYRILLIC CAPITAL LETTER KOMI ZJE;Lu;0;L;;;;;N;;;;0505;
1275 0505;CYRILLIC SMALL LETTER KOMI ZJE;Ll;0;L;;;;;N;;;0504;;0504
1276 0506;CYRILLIC CAPITAL LETTER KOMI DZJE;Lu;0;L;;;;;N;;;;0507;
1277 0507;CYRILLIC SMALL LETTER KOMI DZJE;Ll;0;L;;;;;N;;;0506;;0506
1278 0508;CYRILLIC CAPITAL LETTER KOMI LJE;Lu;0;L;;;;;N;;;;0509;
1279 0509;CYRILLIC SMALL LETTER KOMI LJE;Ll;0;L;;;;;N;;;0508;;0508
1280 050A;CYRILLIC CAPITAL LETTER KOMI NJE;Lu;0;L;;;;;N;;;;050B;
1281 050B;CYRILLIC SMALL LETTER KOMI NJE;Ll;0;L;;;;;N;;;050A;;050A
1282 050C;CYRILLIC CAPITAL LETTER KOMI SJE;Lu;0;L;;;;;N;;;;050D;
1283 050D;CYRILLIC SMALL LETTER KOMI SJE;Ll;0;L;;;;;N;;;050C;;050C
1284 050E;CYRILLIC CAPITAL LETTER KOMI TJE;Lu;0;L;;;;;N;;;;050F;
1285 050F;CYRILLIC SMALL LETTER KOMI TJE;Ll;0;L;;;;;N;;;050E;;050E
1286 0510;CYRILLIC CAPITAL LETTER REVERSED ZE;Lu;0;L;;;;;N;;;;0511;
1287 0511;CYRILLIC SMALL LETTER REVERSED ZE;Ll;0;L;;;;;N;;;0510;;0510
1288 0512;CYRILLIC CAPITAL LETTER EL WITH HOOK;Lu;0;L;;;;;N;;;;0513;
1289 0513;CYRILLIC SMALL LETTER EL WITH HOOK;Ll;0;L;;;;;N;;;0512;;0512
1290 0514;CYRILLIC CAPITAL LETTER LHA;Lu;0;L;;;;;N;;;;0515;
1291 0515;CYRILLIC SMALL LETTER LHA;Ll;0;L;;;;;N;;;0514;;0514
1292 0516;CYRILLIC CAPITAL LETTER RHA;Lu;0;L;;;;;N;;;;0517;
1293 0517;CYRILLIC SMALL LETTER RHA;Ll;0;L;;;;;N;;;0516;;0516
1294 0518;CYRILLIC CAPITAL LETTER YAE;Lu;0;L;;;;;N;;;;0519;
1295 0519;CYRILLIC SMALL LETTER YAE;Ll;0;L;;;;;N;;;0518;;0518
1296 051A;CYRILLIC CAPITAL LETTER QA;Lu;0;L;;;;;N;;;;051B;
1297 051B;CYRILLIC SMALL LETTER QA;Ll;0;L;;;;;N;;;051A;;051A
1298 051C;CYRILLIC CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;051D;
1299 051D;CYRILLIC SMALL LETTER WE;Ll;0;L;;;;;N;;;051C;;051C
1300 051E;CYRILLIC CAPITAL LETTER ALEUT KA;Lu;0;L;;;;;N;;;;051F;
1301 051F;CYRILLIC SMALL LETTER ALEUT KA;Ll;0;L;;;;;N;;;051E;;051E
1302 0520;CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0521;
1303 0521;CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0520;;0520
1304 0522;CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0523;
1305 0523;CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0522;;0522
1306 0531;ARMENIAN CAPITAL LETTER AYB;Lu;0;L;;;;;N;;;;0561;
1307 0532;ARMENIAN CAPITAL LETTER BEN;Lu;0;L;;;;;N;;;;0562;
1308 0533;ARMENIAN CAPITAL LETTER GIM;Lu;0;L;;;;;N;;;;0563;
1309 0534;ARMENIAN CAPITAL LETTER DA;Lu;0;L;;;;;N;;;;0564;
1310 0535;ARMENIAN CAPITAL LETTER ECH;Lu;0;L;;;;;N;;;;0565;
1311 0536;ARMENIAN CAPITAL LETTER ZA;Lu;0;L;;;;;N;;;;0566;
1312 0537;ARMENIAN CAPITAL LETTER EH;Lu;0;L;;;;;N;;;;0567;
1313 0538;ARMENIAN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;0568;
1314 0539;ARMENIAN CAPITAL LETTER TO;Lu;0;L;;;;;N;;;;0569;
1315 053A;ARMENIAN CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;056A;
1316 053B;ARMENIAN CAPITAL LETTER INI;Lu;0;L;;;;;N;;;;056B;
1317 053C;ARMENIAN CAPITAL LETTER LIWN;Lu;0;L;;;;;N;;;;056C;
1318 053D;ARMENIAN CAPITAL LETTER XEH;Lu;0;L;;;;;N;;;;056D;
1319 053E;ARMENIAN CAPITAL LETTER CA;Lu;0;L;;;;;N;;;;056E;
1320 053F;ARMENIAN CAPITAL LETTER KEN;Lu;0;L;;;;;N;;;;056F;
1321 0540;ARMENIAN CAPITAL LETTER HO;Lu;0;L;;;;;N;;;;0570;
1322 0541;ARMENIAN CAPITAL LETTER JA;Lu;0;L;;;;;N;;;;0571;
1323 0542;ARMENIAN CAPITAL LETTER GHAD;Lu;0;L;;;;;N;ARMENIAN CAPITAL LETTER LAD;;;0572;
1324 0543;ARMENIAN CAPITAL LETTER CHEH;Lu;0;L;;;;;N;;;;0573;
1325 0544;ARMENIAN CAPITAL LETTER MEN;Lu;0;L;;;;;N;;;;0574;
1326 0545;ARMENIAN CAPITAL LETTER YI;Lu;0;L;;;;;N;;;;0575;
1327 0546;ARMENIAN CAPITAL LETTER NOW;Lu;0;L;;;;;N;;;;0576;
1328 0547;ARMENIAN CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0577;
1329 0548;ARMENIAN CAPITAL LETTER VO;Lu;0;L;;;;;N;;;;0578;
1330 0549;ARMENIAN CAPITAL LETTER CHA;Lu;0;L;;;;;N;;;;0579;
1331 054A;ARMENIAN CAPITAL LETTER PEH;Lu;0;L;;;;;N;;;;057A;
1332 054B;ARMENIAN CAPITAL LETTER JHEH;Lu;0;L;;;;;N;;;;057B;
1333 054C;ARMENIAN CAPITAL LETTER RA;Lu;0;L;;;;;N;;;;057C;
1334 054D;ARMENIAN CAPITAL LETTER SEH;Lu;0;L;;;;;N;;;;057D;
1335 054E;ARMENIAN CAPITAL LETTER VEW;Lu;0;L;;;;;N;;;;057E;
1336 054F;ARMENIAN CAPITAL LETTER TIWN;Lu;0;L;;;;;N;;;;057F;
1337 0550;ARMENIAN CAPITAL LETTER REH;Lu;0;L;;;;;N;;;;0580;
1338 0551;ARMENIAN CAPITAL LETTER CO;Lu;0;L;;;;;N;;;;0581;
1339 0552;ARMENIAN CAPITAL LETTER YIWN;Lu;0;L;;;;;N;;;;0582;
1340 0553;ARMENIAN CAPITAL LETTER PIWR;Lu;0;L;;;;;N;;;;0583;
1341 0554;ARMENIAN CAPITAL LETTER KEH;Lu;0;L;;;;;N;;;;0584;
1342 0555;ARMENIAN CAPITAL LETTER OH;Lu;0;L;;;;;N;;;;0585;
1343 0556;ARMENIAN CAPITAL LETTER FEH;Lu;0;L;;;;;N;;;;0586;
1344 0559;ARMENIAN MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;;
1345 055A;ARMENIAN APOSTROPHE;Po;0;L;;;;;N;ARMENIAN MODIFIER LETTER RIGHT HALF RING;;;;
1346 055B;ARMENIAN EMPHASIS MARK;Po;0;L;;;;;N;;;;;
1347 055C;ARMENIAN EXCLAMATION MARK;Po;0;L;;;;;N;;;;;
1348 055D;ARMENIAN COMMA;Po;0;L;;;;;N;;;;;
1349 055E;ARMENIAN QUESTION MARK;Po;0;L;;;;;N;;;;;
1350 055F;ARMENIAN ABBREVIATION MARK;Po;0;L;;;;;N;;;;;
1351 0561;ARMENIAN SMALL LETTER AYB;Ll;0;L;;;;;N;;;0531;;0531
1352 0562;ARMENIAN SMALL LETTER BEN;Ll;0;L;;;;;N;;;0532;;0532
1353 0563;ARMENIAN SMALL LETTER GIM;Ll;0;L;;;;;N;;;0533;;0533
1354 0564;ARMENIAN SMALL LETTER DA;Ll;0;L;;;;;N;;;0534;;0534
1355 0565;ARMENIAN SMALL LETTER ECH;Ll;0;L;;;;;N;;;0535;;0535
1356 0566;ARMENIAN SMALL LETTER ZA;Ll;0;L;;;;;N;;;0536;;0536
1357 0567;ARMENIAN SMALL LETTER EH;Ll;0;L;;;;;N;;;0537;;0537
1358 0568;ARMENIAN SMALL LETTER ET;Ll;0;L;;;;;N;;;0538;;0538
1359 0569;ARMENIAN SMALL LETTER TO;Ll;0;L;;;;;N;;;0539;;0539
1360 056A;ARMENIAN SMALL LETTER ZHE;Ll;0;L;;;;;N;;;053A;;053A
1361 056B;ARMENIAN SMALL LETTER INI;Ll;0;L;;;;;N;;;053B;;053B
1362 056C;ARMENIAN SMALL LETTER LIWN;Ll;0;L;;;;;N;;;053C;;053C
1363 056D;ARMENIAN SMALL LETTER XEH;Ll;0;L;;;;;N;;;053D;;053D
1364 056E;ARMENIAN SMALL LETTER CA;Ll;0;L;;;;;N;;;053E;;053E
1365 056F;ARMENIAN SMALL LETTER KEN;Ll;0;L;;;;;N;;;053F;;053F
1366 0570;ARMENIAN SMALL LETTER HO;Ll;0;L;;;;;N;;;0540;;0540
1367 0571;ARMENIAN SMALL LETTER JA;Ll;0;L;;;;;N;;;0541;;0541
1368 0572;ARMENIAN SMALL LETTER GHAD;Ll;0;L;;;;;N;ARMENIAN SMALL LETTER LAD;;0542;;0542
1369 0573;ARMENIAN SMALL LETTER CHEH;Ll;0;L;;;;;N;;;0543;;0543
1370 0574;ARMENIAN SMALL LETTER MEN;Ll;0;L;;;;;N;;;0544;;0544
1371 0575;ARMENIAN SMALL LETTER YI;Ll;0;L;;;;;N;;;0545;;0545
1372 0576;ARMENIAN SMALL LETTER NOW;Ll;0;L;;;;;N;;;0546;;0546
1373 0577;ARMENIAN SMALL LETTER SHA;Ll;0;L;;;;;N;;;0547;;0547
1374 0578;ARMENIAN SMALL LETTER VO;Ll;0;L;;;;;N;;;0548;;0548
1375 0579;ARMENIAN SMALL LETTER CHA;Ll;0;L;;;;;N;;;0549;;0549
1376 057A;ARMENIAN SMALL LETTER PEH;Ll;0;L;;;;;N;;;054A;;054A
1377 057B;ARMENIAN SMALL LETTER JHEH;Ll;0;L;;;;;N;;;054B;;054B
1378 057C;ARMENIAN SMALL LETTER RA;Ll;0;L;;;;;N;;;054C;;054C
1379 057D;ARMENIAN SMALL LETTER SEH;Ll;0;L;;;;;N;;;054D;;054D
1380 057E;ARMENIAN SMALL LETTER VEW;Ll;0;L;;;;;N;;;054E;;054E
1381 057F;ARMENIAN SMALL LETTER TIWN;Ll;0;L;;;;;N;;;054F;;054F
1382 0580;ARMENIAN SMALL LETTER REH;Ll;0;L;;;;;N;;;0550;;0550
1383 0581;ARMENIAN SMALL LETTER CO;Ll;0;L;;;;;N;;;0551;;0551
1384 0582;ARMENIAN SMALL LETTER YIWN;Ll;0;L;;;;;N;;;0552;;0552
1385 0583;ARMENIAN SMALL LETTER PIWR;Ll;0;L;;;;;N;;;0553;;0553
1386 0584;ARMENIAN SMALL LETTER KEH;Ll;0;L;;;;;N;;;0554;;0554
1387 0585;ARMENIAN SMALL LETTER OH;Ll;0;L;;;;;N;;;0555;;0555
1388 0586;ARMENIAN SMALL LETTER FEH;Ll;0;L;;;;;N;;;0556;;0556
1389 0587;ARMENIAN SMALL LIGATURE ECH YIWN;Ll;0;L;<compat> 0565 0582;;;;N;;;;;
1390 0589;ARMENIAN FULL STOP;Po;0;L;;;;;N;ARMENIAN PERIOD;;;;
1391 058A;ARMENIAN HYPHEN;Pd;0;ON;;;;;N;;;;;
1392 0591;HEBREW ACCENT ETNAHTA;Mn;220;NSM;;;;;N;;;;;
1393 0592;HEBREW ACCENT SEGOL;Mn;230;NSM;;;;;N;;;;;
1394 0593;HEBREW ACCENT SHALSHELET;Mn;230;NSM;;;;;N;;;;;
1395 0594;HEBREW ACCENT ZAQEF QATAN;Mn;230;NSM;;;;;N;;;;;
1396 0595;HEBREW ACCENT ZAQEF GADOL;Mn;230;NSM;;;;;N;;;;;
1397 0596;HEBREW ACCENT TIPEHA;Mn;220;NSM;;;;;N;;*;;;
1398 0597;HEBREW ACCENT REVIA;Mn;230;NSM;;;;;N;;;;;
1399 0598;HEBREW ACCENT ZARQA;Mn;230;NSM;;;;;N;;*;;;
1400 0599;HEBREW ACCENT PASHTA;Mn;230;NSM;;;;;N;;;;;
1401 059A;HEBREW ACCENT YETIV;Mn;222;NSM;;;;;N;;;;;
1402 059B;HEBREW ACCENT TEVIR;Mn;220;NSM;;;;;N;;;;;
1403 059C;HEBREW ACCENT GERESH;Mn;230;NSM;;;;;N;;;;;
1404 059D;HEBREW ACCENT GERESH MUQDAM;Mn;230;NSM;;;;;N;;;;;
1405 059E;HEBREW ACCENT GERSHAYIM;Mn;230;NSM;;;;;N;;;;;
1406 059F;HEBREW ACCENT QARNEY PARA;Mn;230;NSM;;;;;N;;;;;
1407 05A0;HEBREW ACCENT TELISHA GEDOLA;Mn;230;NSM;;;;;N;;;;;
1408 05A1;HEBREW ACCENT PAZER;Mn;230;NSM;;;;;N;;;;;
1409 05A2;HEBREW ACCENT ATNAH HAFUKH;Mn;220;NSM;;;;;N;;;;;
1410 05A3;HEBREW ACCENT MUNAH;Mn;220;NSM;;;;;N;;;;;
1411 05A4;HEBREW ACCENT MAHAPAKH;Mn;220;NSM;;;;;N;;;;;
1412 05A5;HEBREW ACCENT MERKHA;Mn;220;NSM;;;;;N;;*;;;
1413 05A6;HEBREW ACCENT MERKHA KEFULA;Mn;220;NSM;;;;;N;;;;;
1414 05A7;HEBREW ACCENT DARGA;Mn;220;NSM;;;;;N;;;;;
1415 05A8;HEBREW ACCENT QADMA;Mn;230;NSM;;;;;N;;*;;;
1416 05A9;HEBREW ACCENT TELISHA QETANA;Mn;230;NSM;;;;;N;;;;;
1417 05AA;HEBREW ACCENT YERAH BEN YOMO;Mn;220;NSM;;;;;N;;*;;;
1418 05AB;HEBREW ACCENT OLE;Mn;230;NSM;;;;;N;;;;;
1419 05AC;HEBREW ACCENT ILUY;Mn;230;NSM;;;;;N;;;;;
1420 05AD;HEBREW ACCENT DEHI;Mn;222;NSM;;;;;N;;;;;
1421 05AE;HEBREW ACCENT ZINOR;Mn;228;NSM;;;;;N;;;;;
1422 05AF;HEBREW MARK MASORA CIRCLE;Mn;230;NSM;;;;;N;;;;;
1423 05B0;HEBREW POINT SHEVA;Mn;10;NSM;;;;;N;;;;;
1424 05B1;HEBREW POINT HATAF SEGOL;Mn;11;NSM;;;;;N;;;;;
1425 05B2;HEBREW POINT HATAF PATAH;Mn;12;NSM;;;;;N;;;;;
1426 05B3;HEBREW POINT HATAF QAMATS;Mn;13;NSM;;;;;N;;;;;
1427 05B4;HEBREW POINT HIRIQ;Mn;14;NSM;;;;;N;;;;;
1428 05B5;HEBREW POINT TSERE;Mn;15;NSM;;;;;N;;;;;
1429 05B6;HEBREW POINT SEGOL;Mn;16;NSM;;;;;N;;;;;
1430 05B7;HEBREW POINT PATAH;Mn;17;NSM;;;;;N;;;;;
1431 05B8;HEBREW POINT QAMATS;Mn;18;NSM;;;;;N;;;;;
1432 05B9;HEBREW POINT HOLAM;Mn;19;NSM;;;;;N;;;;;
1433 05BA;HEBREW POINT HOLAM HASER FOR VAV;Mn;19;NSM;;;;;N;;;;;
1434 05BB;HEBREW POINT QUBUTS;Mn;20;NSM;;;;;N;;;;;
1435 05BC;HEBREW POINT DAGESH OR MAPIQ;Mn;21;NSM;;;;;N;HEBREW POINT DAGESH;or shuruq;;;
1436 05BD;HEBREW POINT METEG;Mn;22;NSM;;;;;N;;*;;;
1437 05BE;HEBREW PUNCTUATION MAQAF;Pd;0;R;;;;;N;;;;;
1438 05BF;HEBREW POINT RAFE;Mn;23;NSM;;;;;N;;;;;
1439 05C0;HEBREW PUNCTUATION PASEQ;Po;0;R;;;;;N;HEBREW POINT PASEQ;*;;;
1440 05C1;HEBREW POINT SHIN DOT;Mn;24;NSM;;;;;N;;;;;
1441 05C2;HEBREW POINT SIN DOT;Mn;25;NSM;;;;;N;;;;;
1442 05C3;HEBREW PUNCTUATION SOF PASUQ;Po;0;R;;;;;N;;*;;;
1443 05C4;HEBREW MARK UPPER DOT;Mn;230;NSM;;;;;N;;;;;
1444 05C5;HEBREW MARK LOWER DOT;Mn;220;NSM;;;;;N;;;;;
1445 05C6;HEBREW PUNCTUATION NUN HAFUKHA;Po;0;R;;;;;N;;;;;
1446 05C7;HEBREW POINT QAMATS QATAN;Mn;18;NSM;;;;;N;;;;;
1447 05D0;HEBREW LETTER ALEF;Lo;0;R;;;;;N;;;;;
1448 05D1;HEBREW LETTER BET;Lo;0;R;;;;;N;;;;;
1449 05D2;HEBREW LETTER GIMEL;Lo;0;R;;;;;N;;;;;
1450 05D3;HEBREW LETTER DALET;Lo;0;R;;;;;N;;;;;
1451 05D4;HEBREW LETTER HE;Lo;0;R;;;;;N;;;;;
1452 05D5;HEBREW LETTER VAV;Lo;0;R;;;;;N;;;;;
1453 05D6;HEBREW LETTER ZAYIN;Lo;0;R;;;;;N;;;;;
1454 05D7;HEBREW LETTER HET;Lo;0;R;;;;;N;;;;;
1455 05D8;HEBREW LETTER TET;Lo;0;R;;;;;N;;;;;
1456 05D9;HEBREW LETTER YOD;Lo;0;R;;;;;N;;;;;
1457 05DA;HEBREW LETTER FINAL KAF;Lo;0;R;;;;;N;;;;;
1458 05DB;HEBREW LETTER KAF;Lo;0;R;;;;;N;;;;;
1459 05DC;HEBREW LETTER LAMED;Lo;0;R;;;;;N;;;;;
1460 05DD;HEBREW LETTER FINAL MEM;Lo;0;R;;;;;N;;;;;
1461 05DE;HEBREW LETTER MEM;Lo;0;R;;;;;N;;;;;
1462 05DF;HEBREW LETTER FINAL NUN;Lo;0;R;;;;;N;;;;;
1463 05E0;HEBREW LETTER NUN;Lo;0;R;;;;;N;;;;;
1464 05E1;HEBREW LETTER SAMEKH;Lo;0;R;;;;;N;;;;;
1465 05E2;HEBREW LETTER AYIN;Lo;0;R;;;;;N;;;;;
1466 05E3;HEBREW LETTER FINAL PE;Lo;0;R;;;;;N;;;;;
1467 05E4;HEBREW LETTER PE;Lo;0;R;;;;;N;;;;;
1468 05E5;HEBREW LETTER FINAL TSADI;Lo;0;R;;;;;N;;;;;
1469 05E6;HEBREW LETTER TSADI;Lo;0;R;;;;;N;;;;;
1470 05E7;HEBREW LETTER QOF;Lo;0;R;;;;;N;;;;;
1471 05E8;HEBREW LETTER RESH;Lo;0;R;;;;;N;;;;;
1472 05E9;HEBREW LETTER SHIN;Lo;0;R;;;;;N;;;;;
1473 05EA;HEBREW LETTER TAV;Lo;0;R;;;;;N;;;;;
1474 05F0;HEBREW LIGATURE YIDDISH DOUBLE VAV;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE VAV;;;;
1475 05F1;HEBREW LIGATURE YIDDISH VAV YOD;Lo;0;R;;;;;N;HEBREW LETTER VAV YOD;;;;
1476 05F2;HEBREW LIGATURE YIDDISH DOUBLE YOD;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE YOD;;;;
1477 05F3;HEBREW PUNCTUATION GERESH;Po;0;R;;;;;N;;;;;
1478 05F4;HEBREW PUNCTUATION GERSHAYIM;Po;0;R;;;;;N;;;;;
1479 0600;ARABIC NUMBER SIGN;Cf;0;AN;;;;;N;;;;;
1480 0601;ARABIC SIGN SANAH;Cf;0;AN;;;;;N;;;;;
1481 0602;ARABIC FOOTNOTE MARKER;Cf;0;AN;;;;;N;;;;;
1482 0603;ARABIC SIGN SAFHA;Cf;0;AN;;;;;N;;;;;
1483 0606;ARABIC-INDIC CUBE ROOT;Sm;0;ON;;;;;N;;;;;
1484 0607;ARABIC-INDIC FOURTH ROOT;Sm;0;ON;;;;;N;;;;;
1485 0608;ARABIC RAY;Sm;0;AL;;;;;N;;;;;
1486 0609;ARABIC-INDIC PER MILLE SIGN;Po;0;ET;;;;;N;;;;;
1487 060A;ARABIC-INDIC PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;;
1488 060B;AFGHANI SIGN;Sc;0;AL;;;;;N;;;;;
1489 060C;ARABIC COMMA;Po;0;CS;;;;;N;;;;;
1490 060D;ARABIC DATE SEPARATOR;Po;0;AL;;;;;N;;;;;
1491 060E;ARABIC POETIC VERSE SIGN;So;0;ON;;;;;N;;;;;
1492 060F;ARABIC SIGN MISRA;So;0;ON;;;;;N;;;;;
1493 0610;ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM;Mn;230;NSM;;;;;N;;;;;
1494 0611;ARABIC SIGN ALAYHE ASSALLAM;Mn;230;NSM;;;;;N;;;;;
1495 0612;ARABIC SIGN RAHMATULLAH ALAYHE;Mn;230;NSM;;;;;N;;;;;
1496 0613;ARABIC SIGN RADI ALLAHOU ANHU;Mn;230;NSM;;;;;N;;;;;
1497 0614;ARABIC SIGN TAKHALLUS;Mn;230;NSM;;;;;N;;;;;
1498 0615;ARABIC SMALL HIGH TAH;Mn;230;NSM;;;;;N;;;;;
1499 0616;ARABIC SMALL HIGH LIGATURE ALEF WITH LAM WITH YEH;Mn;230;NSM;;;;;N;;;;;
1500 0617;ARABIC SMALL HIGH ZAIN;Mn;230;NSM;;;;;N;;;;;
1501 0618;ARABIC SMALL FATHA;Mn;30;NSM;;;;;N;;;;;
1502 0619;ARABIC SMALL DAMMA;Mn;31;NSM;;;;;N;;;;;
1503 061A;ARABIC SMALL KASRA;Mn;32;NSM;;;;;N;;;;;
1504 061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;;
1505 061E;ARABIC TRIPLE DOT PUNCTUATION MARK;Po;0;AL;;;;;N;;;;;
1506 061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;;
1507 0621;ARABIC LETTER HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH;;;;
1508 0622;ARABIC LETTER ALEF WITH MADDA ABOVE;Lo;0;AL;0627 0653;;;;N;ARABIC LETTER MADDAH ON ALEF;;;;
1509 0623;ARABIC LETTER ALEF WITH HAMZA ABOVE;Lo;0;AL;0627 0654;;;;N;ARABIC LETTER HAMZAH ON ALEF;;;;
1510 0624;ARABIC LETTER WAW WITH HAMZA ABOVE;Lo;0;AL;0648 0654;;;;N;ARABIC LETTER HAMZAH ON WAW;;;;
1511 0625;ARABIC LETTER ALEF WITH HAMZA BELOW;Lo;0;AL;0627 0655;;;;N;ARABIC LETTER HAMZAH UNDER ALEF;;;;
1512 0626;ARABIC LETTER YEH WITH HAMZA ABOVE;Lo;0;AL;064A 0654;;;;N;ARABIC LETTER HAMZAH ON YA;;;;
1513 0627;ARABIC LETTER ALEF;Lo;0;AL;;;;;N;;;;;
1514 0628;ARABIC LETTER BEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA;;;;
1515 0629;ARABIC LETTER TEH MARBUTA;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH;;;;
1516 062A;ARABIC LETTER TEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA;;;;
1517 062B;ARABIC LETTER THEH;Lo;0;AL;;;;;N;ARABIC LETTER THAA;;;;
1518 062C;ARABIC LETTER JEEM;Lo;0;AL;;;;;N;;;;;
1519 062D;ARABIC LETTER HAH;Lo;0;AL;;;;;N;ARABIC LETTER HAA;;;;
1520 062E;ARABIC LETTER KHAH;Lo;0;AL;;;;;N;ARABIC LETTER KHAA;;;;
1521 062F;ARABIC LETTER DAL;Lo;0;AL;;;;;N;;;;;
1522 0630;ARABIC LETTER THAL;Lo;0;AL;;;;;N;;;;;
1523 0631;ARABIC LETTER REH;Lo;0;AL;;;;;N;ARABIC LETTER RA;;;;
1524 0632;ARABIC LETTER ZAIN;Lo;0;AL;;;;;N;;;;;
1525 0633;ARABIC LETTER SEEN;Lo;0;AL;;;;;N;;;;;
1526 0634;ARABIC LETTER SHEEN;Lo;0;AL;;;;;N;;;;;
1527 0635;ARABIC LETTER SAD;Lo;0;AL;;;;;N;;;;;
1528 0636;ARABIC LETTER DAD;Lo;0;AL;;;;;N;;;;;
1529 0637;ARABIC LETTER TAH;Lo;0;AL;;;;;N;;;;;
1530 0638;ARABIC LETTER ZAH;Lo;0;AL;;;;;N;ARABIC LETTER DHAH;;;;
1531 0639;ARABIC LETTER AIN;Lo;0;AL;;;;;N;;;;;
1532 063A;ARABIC LETTER GHAIN;Lo;0;AL;;;;;N;;;;;
1533 063B;ARABIC LETTER KEHEH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1534 063C;ARABIC LETTER KEHEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
1535 063D;ARABIC LETTER FARSI YEH WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
1536 063E;ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1537 063F;ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1538 0640;ARABIC TATWEEL;Lm;0;AL;;;;;N;;;;;
1539 0641;ARABIC LETTER FEH;Lo;0;AL;;;;;N;ARABIC LETTER FA;;;;
1540 0642;ARABIC LETTER QAF;Lo;0;AL;;;;;N;;;;;
1541 0643;ARABIC LETTER KAF;Lo;0;AL;;;;;N;ARABIC LETTER CAF;;;;
1542 0644;ARABIC LETTER LAM;Lo;0;AL;;;;;N;;;;;
1543 0645;ARABIC LETTER MEEM;Lo;0;AL;;;;;N;;;;;
1544 0646;ARABIC LETTER NOON;Lo;0;AL;;;;;N;;;;;
1545 0647;ARABIC LETTER HEH;Lo;0;AL;;;;;N;ARABIC LETTER HA;;;;
1546 0648;ARABIC LETTER WAW;Lo;0;AL;;;;;N;;;;;
1547 0649;ARABIC LETTER ALEF MAKSURA;Lo;0;AL;;;;;N;ARABIC LETTER ALEF MAQSURAH;;;;
1548 064A;ARABIC LETTER YEH;Lo;0;AL;;;;;N;ARABIC LETTER YA;;;;
1549 064B;ARABIC FATHATAN;Mn;27;NSM;;;;;N;;;;;
1550 064C;ARABIC DAMMATAN;Mn;28;NSM;;;;;N;;;;;
1551 064D;ARABIC KASRATAN;Mn;29;NSM;;;;;N;;;;;
1552 064E;ARABIC FATHA;Mn;30;NSM;;;;;N;ARABIC FATHAH;;;;
1553 064F;ARABIC DAMMA;Mn;31;NSM;;;;;N;ARABIC DAMMAH;;;;
1554 0650;ARABIC KASRA;Mn;32;NSM;;;;;N;ARABIC KASRAH;;;;
1555 0651;ARABIC SHADDA;Mn;33;NSM;;;;;N;ARABIC SHADDAH;;;;
1556 0652;ARABIC SUKUN;Mn;34;NSM;;;;;N;;;;;
1557 0653;ARABIC MADDAH ABOVE;Mn;230;NSM;;;;;N;;;;;
1558 0654;ARABIC HAMZA ABOVE;Mn;230;NSM;;;;;N;;;;;
1559 0655;ARABIC HAMZA BELOW;Mn;220;NSM;;;;;N;;;;;
1560 0656;ARABIC SUBSCRIPT ALEF;Mn;220;NSM;;;;;N;;;;;
1561 0657;ARABIC INVERTED DAMMA;Mn;230;NSM;;;;;N;;;;;
1562 0658;ARABIC MARK NOON GHUNNA;Mn;230;NSM;;;;;N;;;;;
1563 0659;ARABIC ZWARAKAY;Mn;230;NSM;;;;;N;;;;;
1564 065A;ARABIC VOWEL SIGN SMALL V ABOVE;Mn;230;NSM;;;;;N;;;;;
1565 065B;ARABIC VOWEL SIGN INVERTED SMALL V ABOVE;Mn;230;NSM;;;;;N;;;;;
1566 065C;ARABIC VOWEL SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;;
1567 065D;ARABIC REVERSED DAMMA;Mn;230;NSM;;;;;N;;;;;
1568 065E;ARABIC FATHA WITH TWO DOTS;Mn;230;NSM;;;;;N;;;;;
1569 0660;ARABIC-INDIC DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;;
1570 0661;ARABIC-INDIC DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;;
1571 0662;ARABIC-INDIC DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;;
1572 0663;ARABIC-INDIC DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;;
1573 0664;ARABIC-INDIC DIGIT FOUR;Nd;0;AN;;4;4;4;N;;;;;
1574 0665;ARABIC-INDIC DIGIT FIVE;Nd;0;AN;;5;5;5;N;;;;;
1575 0666;ARABIC-INDIC DIGIT SIX;Nd;0;AN;;6;6;6;N;;;;;
1576 0667;ARABIC-INDIC DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;;
1577 0668;ARABIC-INDIC DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;;
1578 0669;ARABIC-INDIC DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;;
1579 066A;ARABIC PERCENT SIGN;Po;0;ET;;;;;N;;;;;
1580 066B;ARABIC DECIMAL SEPARATOR;Po;0;AN;;;;;N;;;;;
1581 066C;ARABIC THOUSANDS SEPARATOR;Po;0;AN;;;;;N;;;;;
1582 066D;ARABIC FIVE POINTED STAR;Po;0;AL;;;;;N;;;;;
1583 066E;ARABIC LETTER DOTLESS BEH;Lo;0;AL;;;;;N;;;;;
1584 066F;ARABIC LETTER DOTLESS QAF;Lo;0;AL;;;;;N;;;;;
1585 0670;ARABIC LETTER SUPERSCRIPT ALEF;Mn;35;NSM;;;;;N;ARABIC ALEF ABOVE;;;;
1586 0671;ARABIC LETTER ALEF WASLA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAT WASL ON ALEF;;;;
1587 0672;ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH ON ALEF;;;;
1588 0673;ARABIC LETTER ALEF WITH WAVY HAMZA BELOW;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH UNDER ALEF;;;;
1589 0674;ARABIC LETTER HIGH HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HIGH HAMZAH;;;;
1590 0675;ARABIC LETTER HIGH HAMZA ALEF;Lo;0;AL;<compat> 0627 0674;;;;N;ARABIC LETTER HIGH HAMZAH ALEF;;;;
1591 0676;ARABIC LETTER HIGH HAMZA WAW;Lo;0;AL;<compat> 0648 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW;;;;
1592 0677;ARABIC LETTER U WITH HAMZA ABOVE;Lo;0;AL;<compat> 06C7 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW WITH DAMMAH;;;;
1593 0678;ARABIC LETTER HIGH HAMZA YEH;Lo;0;AL;<compat> 064A 0674;;;;N;ARABIC LETTER HIGH HAMZAH YA;;;;
1594 0679;ARABIC LETTER TTEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH SMALL TAH;;;;
1595 067A;ARABIC LETTER TTEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH TWO DOTS VERTICAL ABOVE;;;;
1596 067B;ARABIC LETTER BEEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH TWO DOTS VERTICAL BELOW;;;;
1597 067C;ARABIC LETTER TEH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH RING;;;;
1598 067D;ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS ABOVE DOWNWARD;;;;
1599 067E;ARABIC LETTER PEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS BELOW;;;;
1600 067F;ARABIC LETTER TEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH FOUR DOTS ABOVE;;;;
1601 0680;ARABIC LETTER BEHEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH FOUR DOTS BELOW;;;;
1602 0681;ARABIC LETTER HAH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH ON HAA;;;;
1603 0682;ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH TWO DOTS VERTICAL ABOVE;;;;
1604 0683;ARABIC LETTER NYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS;;;;
1605 0684;ARABIC LETTER DYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS VERTICAL;;;;
1606 0685;ARABIC LETTER HAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH THREE DOTS ABOVE;;;;
1607 0686;ARABIC LETTER TCHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE THREE DOTS DOWNWARD;;;;
1608 0687;ARABIC LETTER TCHEHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE FOUR DOTS;;;;
1609 0688;ARABIC LETTER DDAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH SMALL TAH;;;;
1610 0689;ARABIC LETTER DAL WITH RING;Lo;0;AL;;;;;N;;;;;
1611 068A;ARABIC LETTER DAL WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
1612 068B;ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;;
1613 068C;ARABIC LETTER DAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS ABOVE;;;;
1614 068D;ARABIC LETTER DDAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS BELOW;;;;
1615 068E;ARABIC LETTER DUL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE;;;;
1616 068F;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARD;;;;
1617 0690;ARABIC LETTER DAL WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1618 0691;ARABIC LETTER RREH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL TAH;;;;
1619 0692;ARABIC LETTER REH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V;;;;
1620 0693;ARABIC LETTER REH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH RING;;;;
1621 0694;ARABIC LETTER REH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW;;;;
1622 0695;ARABIC LETTER REH WITH SMALL V BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V BELOW;;;;
1623 0696;ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW AND DOT ABOVE;;;;
1624 0697;ARABIC LETTER REH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH TWO DOTS ABOVE;;;;
1625 0698;ARABIC LETTER JEH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH THREE DOTS ABOVE;;;;
1626 0699;ARABIC LETTER REH WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH FOUR DOTS ABOVE;;;;
1627 069A;ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
1628 069B;ARABIC LETTER SEEN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
1629 069C;ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1630 069D;ARABIC LETTER SAD WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
1631 069E;ARABIC LETTER SAD WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1632 069F;ARABIC LETTER TAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1633 06A0;ARABIC LETTER AIN WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1634 06A1;ARABIC LETTER DOTLESS FEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS FA;;;;
1635 06A2;ARABIC LETTER FEH WITH DOT MOVED BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT MOVED BELOW;;;;
1636 06A3;ARABIC LETTER FEH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT BELOW;;;;
1637 06A4;ARABIC LETTER VEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS ABOVE;;;;
1638 06A5;ARABIC LETTER FEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS BELOW;;;;
1639 06A6;ARABIC LETTER PEHEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH FOUR DOTS ABOVE;;;;
1640 06A7;ARABIC LETTER QAF WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
1641 06A8;ARABIC LETTER QAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1642 06A9;ARABIC LETTER KEHEH;Lo;0;AL;;;;;N;ARABIC LETTER OPEN CAF;;;;
1643 06AA;ARABIC LETTER SWASH KAF;Lo;0;AL;;;;;N;ARABIC LETTER SWASH CAF;;;;
1644 06AB;ARABIC LETTER KAF WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH RING;;;;
1645 06AC;ARABIC LETTER KAF WITH DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH DOT ABOVE;;;;
1646 06AD;ARABIC LETTER NG;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS ABOVE;;;;
1647 06AE;ARABIC LETTER KAF WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS BELOW;;;;
1648 06AF;ARABIC LETTER GAF;Lo;0;AL;;;;;N;;*;;;
1649 06B0;ARABIC LETTER GAF WITH RING;Lo;0;AL;;;;;N;;;;;
1650 06B1;ARABIC LETTER NGOEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS ABOVE;;;;
1651 06B2;ARABIC LETTER GAF WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
1652 06B3;ARABIC LETTER GUEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS VERTICAL BELOW;;;;
1653 06B4;ARABIC LETTER GAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1654 06B5;ARABIC LETTER LAM WITH SMALL V;Lo;0;AL;;;;;N;;;;;
1655 06B6;ARABIC LETTER LAM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
1656 06B7;ARABIC LETTER LAM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1657 06B8;ARABIC LETTER LAM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;
1658 06B9;ARABIC LETTER NOON WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
1659 06BA;ARABIC LETTER NOON GHUNNA;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON;;;;
1660 06BB;ARABIC LETTER RNOON;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON WITH SMALL TAH;;;;
1661 06BC;ARABIC LETTER NOON WITH RING;Lo;0;AL;;;;;N;;;;;
1662 06BD;ARABIC LETTER NOON WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1663 06BE;ARABIC LETTER HEH DOACHASHMEE;Lo;0;AL;;;;;N;ARABIC LETTER KNOTTED HA;;;;
1664 06BF;ARABIC LETTER TCHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
1665 06C0;ARABIC LETTER HEH WITH YEH ABOVE;Lo;0;AL;06D5 0654;;;;N;ARABIC LETTER HAMZAH ON HA;;;;
1666 06C1;ARABIC LETTER HEH GOAL;Lo;0;AL;;;;;N;ARABIC LETTER HA GOAL;;;;
1667 06C2;ARABIC LETTER HEH GOAL WITH HAMZA ABOVE;Lo;0;AL;06C1 0654;;;;N;ARABIC LETTER HAMZAH ON HA GOAL;;;;
1668 06C3;ARABIC LETTER TEH MARBUTA GOAL;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH GOAL;;;;
1669 06C4;ARABIC LETTER WAW WITH RING;Lo;0;AL;;;;;N;;;;;
1670 06C5;ARABIC LETTER KIRGHIZ OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH BAR;;;;
1671 06C6;ARABIC LETTER OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH SMALL V;;;;
1672 06C7;ARABIC LETTER U;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH DAMMAH;;;;
1673 06C8;ARABIC LETTER YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH ALEF ABOVE;;;;
1674 06C9;ARABIC LETTER KIRGHIZ YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH INVERTED SMALL V;;;;
1675 06CA;ARABIC LETTER WAW WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1676 06CB;ARABIC LETTER VE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH THREE DOTS ABOVE;;;;
1677 06CC;ARABIC LETTER FARSI YEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS YA;;;;
1678 06CD;ARABIC LETTER YEH WITH TAIL;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TAIL;;;;
1679 06CE;ARABIC LETTER YEH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH SMALL V;;;;
1680 06CF;ARABIC LETTER WAW WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
1681 06D0;ARABIC LETTER E;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TWO DOTS VERTICAL BELOW;*;;;
1682 06D1;ARABIC LETTER YEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH THREE DOTS BELOW;;;;
1683 06D2;ARABIC LETTER YEH BARREE;Lo;0;AL;;;;;N;ARABIC LETTER YA BARREE;;;;
1684 06D3;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE;Lo;0;AL;06D2 0654;;;;N;ARABIC LETTER HAMZAH ON YA BARREE;;;;
1685 06D4;ARABIC FULL STOP;Po;0;AL;;;;;N;ARABIC PERIOD;;;;
1686 06D5;ARABIC LETTER AE;Lo;0;AL;;;;;N;;;;;
1687 06D6;ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;;
1688 06D7;ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;;
1689 06D8;ARABIC SMALL HIGH MEEM INITIAL FORM;Mn;230;NSM;;;;;N;;;;;
1690 06D9;ARABIC SMALL HIGH LAM ALEF;Mn;230;NSM;;;;;N;;;;;
1691 06DA;ARABIC SMALL HIGH JEEM;Mn;230;NSM;;;;;N;;;;;
1692 06DB;ARABIC SMALL HIGH THREE DOTS;Mn;230;NSM;;;;;N;;;;;
1693 06DC;ARABIC SMALL HIGH SEEN;Mn;230;NSM;;;;;N;;;;;
1694 06DD;ARABIC END OF AYAH;Cf;0;AN;;;;;N;;;;;
1695 06DE;ARABIC START OF RUB EL HIZB;Me;0;NSM;;;;;N;;;;;
1696 06DF;ARABIC SMALL HIGH ROUNDED ZERO;Mn;230;NSM;;;;;N;;;;;
1697 06E0;ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO;Mn;230;NSM;;;;;N;;;;;
1698 06E1;ARABIC SMALL HIGH DOTLESS HEAD OF KHAH;Mn;230;NSM;;;;;N;;;;;
1699 06E2;ARABIC SMALL HIGH MEEM ISOLATED FORM;Mn;230;NSM;;;;;N;;;;;
1700 06E3;ARABIC SMALL LOW SEEN;Mn;220;NSM;;;;;N;;;;;
1701 06E4;ARABIC SMALL HIGH MADDA;Mn;230;NSM;;;;;N;;;;;
1702 06E5;ARABIC SMALL WAW;Lm;0;AL;;;;;N;;;;;
1703 06E6;ARABIC SMALL YEH;Lm;0;AL;;;;;N;;;;;
1704 06E7;ARABIC SMALL HIGH YEH;Mn;230;NSM;;;;;N;;;;;
1705 06E8;ARABIC SMALL HIGH NOON;Mn;230;NSM;;;;;N;;;;;
1706 06E9;ARABIC PLACE OF SAJDAH;So;0;ON;;;;;N;;;;;
1707 06EA;ARABIC EMPTY CENTRE LOW STOP;Mn;220;NSM;;;;;N;;;;;
1708 06EB;ARABIC EMPTY CENTRE HIGH STOP;Mn;230;NSM;;;;;N;;;;;
1709 06EC;ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE;Mn;230;NSM;;;;;N;;;;;
1710 06ED;ARABIC SMALL LOW MEEM;Mn;220;NSM;;;;;N;;;;;
1711 06EE;ARABIC LETTER DAL WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
1712 06EF;ARABIC LETTER REH WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
1713 06F0;EXTENDED ARABIC-INDIC DIGIT ZERO;Nd;0;EN;;0;0;0;N;EASTERN ARABIC-INDIC DIGIT ZERO;;;;
1714 06F1;EXTENDED ARABIC-INDIC DIGIT ONE;Nd;0;EN;;1;1;1;N;EASTERN ARABIC-INDIC DIGIT ONE;;;;
1715 06F2;EXTENDED ARABIC-INDIC DIGIT TWO;Nd;0;EN;;2;2;2;N;EASTERN ARABIC-INDIC DIGIT TWO;;;;
1716 06F3;EXTENDED ARABIC-INDIC DIGIT THREE;Nd;0;EN;;3;3;3;N;EASTERN ARABIC-INDIC DIGIT THREE;;;;
1717 06F4;EXTENDED ARABIC-INDIC DIGIT FOUR;Nd;0;EN;;4;4;4;N;EASTERN ARABIC-INDIC DIGIT FOUR;;;;
1718 06F5;EXTENDED ARABIC-INDIC DIGIT FIVE;Nd;0;EN;;5;5;5;N;EASTERN ARABIC-INDIC DIGIT FIVE;;;;
1719 06F6;EXTENDED ARABIC-INDIC DIGIT SIX;Nd;0;EN;;6;6;6;N;EASTERN ARABIC-INDIC DIGIT SIX;;;;
1720 06F7;EXTENDED ARABIC-INDIC DIGIT SEVEN;Nd;0;EN;;7;7;7;N;EASTERN ARABIC-INDIC DIGIT SEVEN;;;;
1721 06F8;EXTENDED ARABIC-INDIC DIGIT EIGHT;Nd;0;EN;;8;8;8;N;EASTERN ARABIC-INDIC DIGIT EIGHT;;;;
1722 06F9;EXTENDED ARABIC-INDIC DIGIT NINE;Nd;0;EN;;9;9;9;N;EASTERN ARABIC-INDIC DIGIT NINE;;;;
1723 06FA;ARABIC LETTER SHEEN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
1724 06FB;ARABIC LETTER DAD WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
1725 06FC;ARABIC LETTER GHAIN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
1726 06FD;ARABIC SIGN SINDHI AMPERSAND;So;0;AL;;;;;N;;;;;
1727 06FE;ARABIC SIGN SINDHI POSTPOSITION MEN;So;0;AL;;;;;N;;;;;
1728 06FF;ARABIC LETTER HEH WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
1729 0700;SYRIAC END OF PARAGRAPH;Po;0;AL;;;;;N;;;;;
1730 0701;SYRIAC SUPRALINEAR FULL STOP;Po;0;AL;;;;;N;;;;;
1731 0702;SYRIAC SUBLINEAR FULL STOP;Po;0;AL;;;;;N;;;;;
1732 0703;SYRIAC SUPRALINEAR COLON;Po;0;AL;;;;;N;;;;;
1733 0704;SYRIAC SUBLINEAR COLON;Po;0;AL;;;;;N;;;;;
1734 0705;SYRIAC HORIZONTAL COLON;Po;0;AL;;;;;N;;;;;
1735 0706;SYRIAC COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;;
1736 0707;SYRIAC COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;;
1737 0708;SYRIAC SUPRALINEAR COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;;
1738 0709;SYRIAC SUBLINEAR COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;;
1739 070A;SYRIAC CONTRACTION;Po;0;AL;;;;;N;;;;;
1740 070B;SYRIAC HARKLEAN OBELUS;Po;0;AL;;;;;N;;;;;
1741 070C;SYRIAC HARKLEAN METOBELUS;Po;0;AL;;;;;N;;;;;
1742 070D;SYRIAC HARKLEAN ASTERISCUS;Po;0;AL;;;;;N;;;;;
1743 070F;SYRIAC ABBREVIATION MARK;Cf;0;BN;;;;;N;;;;;
1744 0710;SYRIAC LETTER ALAPH;Lo;0;AL;;;;;N;;;;;
1745 0711;SYRIAC LETTER SUPERSCRIPT ALAPH;Mn;36;NSM;;;;;N;;;;;
1746 0712;SYRIAC LETTER BETH;Lo;0;AL;;;;;N;;;;;
1747 0713;SYRIAC LETTER GAMAL;Lo;0;AL;;;;;N;;;;;
1748 0714;SYRIAC LETTER GAMAL GARSHUNI;Lo;0;AL;;;;;N;;;;;
1749 0715;SYRIAC LETTER DALATH;Lo;0;AL;;;;;N;;;;;
1750 0716;SYRIAC LETTER DOTLESS DALATH RISH;Lo;0;AL;;;;;N;;;;;
1751 0717;SYRIAC LETTER HE;Lo;0;AL;;;;;N;;;;;
1752 0718;SYRIAC LETTER WAW;Lo;0;AL;;;;;N;;;;;
1753 0719;SYRIAC LETTER ZAIN;Lo;0;AL;;;;;N;;;;;
1754 071A;SYRIAC LETTER HETH;Lo;0;AL;;;;;N;;;;;
1755 071B;SYRIAC LETTER TETH;Lo;0;AL;;;;;N;;;;;
1756 071C;SYRIAC LETTER TETH GARSHUNI;Lo;0;AL;;;;;N;;;;;
1757 071D;SYRIAC LETTER YUDH;Lo;0;AL;;;;;N;;;;;
1758 071E;SYRIAC LETTER YUDH HE;Lo;0;AL;;;;;N;;;;;
1759 071F;SYRIAC LETTER KAPH;Lo;0;AL;;;;;N;;;;;
1760 0720;SYRIAC LETTER LAMADH;Lo;0;AL;;;;;N;;;;;
1761 0721;SYRIAC LETTER MIM;Lo;0;AL;;;;;N;;;;;
1762 0722;SYRIAC LETTER NUN;Lo;0;AL;;;;;N;;;;;
1763 0723;SYRIAC LETTER SEMKATH;Lo;0;AL;;;;;N;;;;;
1764 0724;SYRIAC LETTER FINAL SEMKATH;Lo;0;AL;;;;;N;;;;;
1765 0725;SYRIAC LETTER E;Lo;0;AL;;;;;N;;;;;
1766 0726;SYRIAC LETTER PE;Lo;0;AL;;;;;N;;;;;
1767 0727;SYRIAC LETTER REVERSED PE;Lo;0;AL;;;;;N;;;;;
1768 0728;SYRIAC LETTER SADHE;Lo;0;AL;;;;;N;;;;;
1769 0729;SYRIAC LETTER QAPH;Lo;0;AL;;;;;N;;;;;
1770 072A;SYRIAC LETTER RISH;Lo;0;AL;;;;;N;;;;;
1771 072B;SYRIAC LETTER SHIN;Lo;0;AL;;;;;N;;;;;
1772 072C;SYRIAC LETTER TAW;Lo;0;AL;;;;;N;;;;;
1773 072D;SYRIAC LETTER PERSIAN BHETH;Lo;0;AL;;;;;N;;;;;
1774 072E;SYRIAC LETTER PERSIAN GHAMAL;Lo;0;AL;;;;;N;;;;;
1775 072F;SYRIAC LETTER PERSIAN DHALATH;Lo;0;AL;;;;;N;;;;;
1776 0730;SYRIAC PTHAHA ABOVE;Mn;230;NSM;;;;;N;;;;;
1777 0731;SYRIAC PTHAHA BELOW;Mn;220;NSM;;;;;N;;;;;
1778 0732;SYRIAC PTHAHA DOTTED;Mn;230;NSM;;;;;N;;;;;
1779 0733;SYRIAC ZQAPHA ABOVE;Mn;230;NSM;;;;;N;;;;;
1780 0734;SYRIAC ZQAPHA BELOW;Mn;220;NSM;;;;;N;;;;;
1781 0735;SYRIAC ZQAPHA DOTTED;Mn;230;NSM;;;;;N;;;;;
1782 0736;SYRIAC RBASA ABOVE;Mn;230;NSM;;;;;N;;;;;
1783 0737;SYRIAC RBASA BELOW;Mn;220;NSM;;;;;N;;;;;
1784 0738;SYRIAC DOTTED ZLAMA HORIZONTAL;Mn;220;NSM;;;;;N;;;;;
1785 0739;SYRIAC DOTTED ZLAMA ANGULAR;Mn;220;NSM;;;;;N;;;;;
1786 073A;SYRIAC HBASA ABOVE;Mn;230;NSM;;;;;N;;;;;
1787 073B;SYRIAC HBASA BELOW;Mn;220;NSM;;;;;N;;;;;
1788 073C;SYRIAC HBASA-ESASA DOTTED;Mn;220;NSM;;;;;N;;;;;
1789 073D;SYRIAC ESASA ABOVE;Mn;230;NSM;;;;;N;;;;;
1790 073E;SYRIAC ESASA BELOW;Mn;220;NSM;;;;;N;;;;;
1791 073F;SYRIAC RWAHA;Mn;230;NSM;;;;;N;;;;;
1792 0740;SYRIAC FEMININE DOT;Mn;230;NSM;;;;;N;;;;;
1793 0741;SYRIAC QUSHSHAYA;Mn;230;NSM;;;;;N;;;;;
1794 0742;SYRIAC RUKKAKHA;Mn;220;NSM;;;;;N;;;;;
1795 0743;SYRIAC TWO VERTICAL DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;
1796 0744;SYRIAC TWO VERTICAL DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
1797 0745;SYRIAC THREE DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;
1798 0746;SYRIAC THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;;
1799 0747;SYRIAC OBLIQUE LINE ABOVE;Mn;230;NSM;;;;;N;;;;;
1800 0748;SYRIAC OBLIQUE LINE BELOW;Mn;220;NSM;;;;;N;;;;;
1801 0749;SYRIAC MUSIC;Mn;230;NSM;;;;;N;;;;;
1802 074A;SYRIAC BARREKH;Mn;230;NSM;;;;;N;;;;;
1803 074D;SYRIAC LETTER SOGDIAN ZHAIN;Lo;0;AL;;;;;N;;;;;
1804 074E;SYRIAC LETTER SOGDIAN KHAPH;Lo;0;AL;;;;;N;;;;;
1805 074F;SYRIAC LETTER SOGDIAN FE;Lo;0;AL;;;;;N;;;;;
1806 0750;ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW;Lo;0;AL;;;;;N;;;;;
1807 0751;ARABIC LETTER BEH WITH DOT BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1808 0752;ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;
1809 0753;ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW AND TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1810 0754;ARABIC LETTER BEH WITH TWO DOTS BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;
1811 0755;ARABIC LETTER BEH WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;;
1812 0756;ARABIC LETTER BEH WITH SMALL V;Lo;0;AL;;;;;N;;;;;
1813 0757;ARABIC LETTER HAH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1814 0758;ARABIC LETTER HAH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;
1815 0759;ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;;
1816 075A;ARABIC LETTER DAL WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;;
1817 075B;ARABIC LETTER REH WITH STROKE;Lo;0;AL;;;;;N;;;;;
1818 075C;ARABIC LETTER SEEN WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1819 075D;ARABIC LETTER AIN WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1820 075E;ARABIC LETTER AIN WITH THREE DOTS POINTING DOWNWARDS ABOVE;Lo;0;AL;;;;;N;;;;;
1821 075F;ARABIC LETTER AIN WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;;
1822 0760;ARABIC LETTER FEH WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
1823 0761;ARABIC LETTER FEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;
1824 0762;ARABIC LETTER KEHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
1825 0763;ARABIC LETTER KEHEH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1826 0764;ARABIC LETTER KEHEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;
1827 0765;ARABIC LETTER MEEM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;
1828 0766;ARABIC LETTER MEEM WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;
1829 0767;ARABIC LETTER NOON WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;
1830 0768;ARABIC LETTER NOON WITH SMALL TAH;Lo;0;AL;;;;;N;;;;;
1831 0769;ARABIC LETTER NOON WITH SMALL V;Lo;0;AL;;;;;N;;;;;
1832 076A;ARABIC LETTER LAM WITH BAR;Lo;0;AL;;;;;N;;;;;
1833 076B;ARABIC LETTER REH WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;;
1834 076C;ARABIC LETTER REH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;;
1835 076D;ARABIC LETTER SEEN WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;;
1836 076E;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH BELOW;Lo;0;AL;;;;;N;;;;;
1837 076F;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;;
1838 0770;ARABIC LETTER SEEN WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;;
1839 0771;ARABIC LETTER REH WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;;
1840 0772;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH ABOVE;Lo;0;AL;;;;;N;;;;;
1841 0773;ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;
1842 0774;ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;
1843 0775;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;
1844 0776;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;
1845 0777;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW;Lo;0;AL;;;;;N;;;;;
1846 0778;ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;
1847 0779;ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;
1848 077A;ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;
1849 077B;ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;
1850 077C;ARABIC LETTER HAH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW;Lo;0;AL;;;;;N;;;;;
1851 077D;ARABIC LETTER SEEN WITH EXTENDED ARABIC-INDIC DIGIT FOUR ABOVE;Lo;0;AL;;;;;N;;;;;
1852 077E;ARABIC LETTER SEEN WITH INVERTED V;Lo;0;AL;;;;;N;;;;;
1853 077F;ARABIC LETTER KAF WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;
1854 0780;THAANA LETTER HAA;Lo;0;AL;;;;;N;;;;;
1855 0781;THAANA LETTER SHAVIYANI;Lo;0;AL;;;;;N;;;;;
1856 0782;THAANA LETTER NOONU;Lo;0;AL;;;;;N;;;;;
1857 0783;THAANA LETTER RAA;Lo;0;AL;;;;;N;;;;;
1858 0784;THAANA LETTER BAA;Lo;0;AL;;;;;N;;;;;
1859 0785;THAANA LETTER LHAVIYANI;Lo;0;AL;;;;;N;;;;;
1860 0786;THAANA LETTER KAAFU;Lo;0;AL;;;;;N;;;;;
1861 0787;THAANA LETTER ALIFU;Lo;0;AL;;;;;N;;;;;
1862 0788;THAANA LETTER VAAVU;Lo;0;AL;;;;;N;;;;;
1863 0789;THAANA LETTER MEEMU;Lo;0;AL;;;;;N;;;;;
1864 078A;THAANA LETTER FAAFU;Lo;0;AL;;;;;N;;;;;
1865 078B;THAANA LETTER DHAALU;Lo;0;AL;;;;;N;;;;;
1866 078C;THAANA LETTER THAA;Lo;0;AL;;;;;N;;;;;
1867 078D;THAANA LETTER LAAMU;Lo;0;AL;;;;;N;;;;;
1868 078E;THAANA LETTER GAAFU;Lo;0;AL;;;;;N;;;;;
1869 078F;THAANA LETTER GNAVIYANI;Lo;0;AL;;;;;N;;;;;
1870 0790;THAANA LETTER SEENU;Lo;0;AL;;;;;N;;;;;
1871 0791;THAANA LETTER DAVIYANI;Lo;0;AL;;;;;N;;;;;
1872 0792;THAANA LETTER ZAVIYANI;Lo;0;AL;;;;;N;;;;;
1873 0793;THAANA LETTER TAVIYANI;Lo;0;AL;;;;;N;;;;;
1874 0794;THAANA LETTER YAA;Lo;0;AL;;;;;N;;;;;
1875 0795;THAANA LETTER PAVIYANI;Lo;0;AL;;;;;N;;;;;
1876 0796;THAANA LETTER JAVIYANI;Lo;0;AL;;;;;N;;;;;
1877 0797;THAANA LETTER CHAVIYANI;Lo;0;AL;;;;;N;;;;;
1878 0798;THAANA LETTER TTAA;Lo;0;AL;;;;;N;;;;;
1879 0799;THAANA LETTER HHAA;Lo;0;AL;;;;;N;;;;;
1880 079A;THAANA LETTER KHAA;Lo;0;AL;;;;;N;;;;;
1881 079B;THAANA LETTER THAALU;Lo;0;AL;;;;;N;;;;;
1882 079C;THAANA LETTER ZAA;Lo;0;AL;;;;;N;;;;;
1883 079D;THAANA LETTER SHEENU;Lo;0;AL;;;;;N;;;;;
1884 079E;THAANA LETTER SAADHU;Lo;0;AL;;;;;N;;;;;
1885 079F;THAANA LETTER DAADHU;Lo;0;AL;;;;;N;;;;;
1886 07A0;THAANA LETTER TO;Lo;0;AL;;;;;N;;;;;
1887 07A1;THAANA LETTER ZO;Lo;0;AL;;;;;N;;;;;
1888 07A2;THAANA LETTER AINU;Lo;0;AL;;;;;N;;;;;
1889 07A3;THAANA LETTER GHAINU;Lo;0;AL;;;;;N;;;;;
1890 07A4;THAANA LETTER QAAFU;Lo;0;AL;;;;;N;;;;;
1891 07A5;THAANA LETTER WAAVU;Lo;0;AL;;;;;N;;;;;
1892 07A6;THAANA ABAFILI;Mn;0;NSM;;;;;N;;;;;
1893 07A7;THAANA AABAAFILI;Mn;0;NSM;;;;;N;;;;;
1894 07A8;THAANA IBIFILI;Mn;0;NSM;;;;;N;;;;;
1895 07A9;THAANA EEBEEFILI;Mn;0;NSM;;;;;N;;;;;
1896 07AA;THAANA UBUFILI;Mn;0;NSM;;;;;N;;;;;
1897 07AB;THAANA OOBOOFILI;Mn;0;NSM;;;;;N;;;;;
1898 07AC;THAANA EBEFILI;Mn;0;NSM;;;;;N;;;;;
1899 07AD;THAANA EYBEYFILI;Mn;0;NSM;;;;;N;;;;;
1900 07AE;THAANA OBOFILI;Mn;0;NSM;;;;;N;;;;;
1901 07AF;THAANA OABOAFILI;Mn;0;NSM;;;;;N;;;;;
1902 07B0;THAANA SUKUN;Mn;0;NSM;;;;;N;;;;;
1903 07B1;THAANA LETTER NAA;Lo;0;AL;;;;;N;;;;;
1904 07C0;NKO DIGIT ZERO;Nd;0;R;;0;0;0;N;;;;;
1905 07C1;NKO DIGIT ONE;Nd;0;R;;1;1;1;N;;;;;
1906 07C2;NKO DIGIT TWO;Nd;0;R;;2;2;2;N;;;;;
1907 07C3;NKO DIGIT THREE;Nd;0;R;;3;3;3;N;;;;;
1908 07C4;NKO DIGIT FOUR;Nd;0;R;;4;4;4;N;;;;;
1909 07C5;NKO DIGIT FIVE;Nd;0;R;;5;5;5;N;;;;;
1910 07C6;NKO DIGIT SIX;Nd;0;R;;6;6;6;N;;;;;
1911 07C7;NKO DIGIT SEVEN;Nd;0;R;;7;7;7;N;;;;;
1912 07C8;NKO DIGIT EIGHT;Nd;0;R;;8;8;8;N;;;;;
1913 07C9;NKO DIGIT NINE;Nd;0;R;;9;9;9;N;;;;;
1914 07CA;NKO LETTER A;Lo;0;R;;;;;N;;;;;
1915 07CB;NKO LETTER EE;Lo;0;R;;;;;N;;;;;
1916 07CC;NKO LETTER I;Lo;0;R;;;;;N;;;;;
1917 07CD;NKO LETTER E;Lo;0;R;;;;;N;;;;;
1918 07CE;NKO LETTER U;Lo;0;R;;;;;N;;;;;
1919 07CF;NKO LETTER OO;Lo;0;R;;;;;N;;;;;
1920 07D0;NKO LETTER O;Lo;0;R;;;;;N;;;;;
1921 07D1;NKO LETTER DAGBASINNA;Lo;0;R;;;;;N;;;;;
1922 07D2;NKO LETTER N;Lo;0;R;;;;;N;;;;;
1923 07D3;NKO LETTER BA;Lo;0;R;;;;;N;;;;;
1924 07D4;NKO LETTER PA;Lo;0;R;;;;;N;;;;;
1925 07D5;NKO LETTER TA;Lo;0;R;;;;;N;;;;;
1926 07D6;NKO LETTER JA;Lo;0;R;;;;;N;;;;;
1927 07D7;NKO LETTER CHA;Lo;0;R;;;;;N;;;;;
1928 07D8;NKO LETTER DA;Lo;0;R;;;;;N;;;;;
1929 07D9;NKO LETTER RA;Lo;0;R;;;;;N;;;;;
1930 07DA;NKO LETTER RRA;Lo;0;R;;;;;N;;;;;
1931 07DB;NKO LETTER SA;Lo;0;R;;;;;N;;;;;
1932 07DC;NKO LETTER GBA;Lo;0;R;;;;;N;;;;;
1933 07DD;NKO LETTER FA;Lo;0;R;;;;;N;;;;;
1934 07DE;NKO LETTER KA;Lo;0;R;;;;;N;;;;;
1935 07DF;NKO LETTER LA;Lo;0;R;;;;;N;;;;;
1936 07E0;NKO LETTER NA WOLOSO;Lo;0;R;;;;;N;;;;;
1937 07E1;NKO LETTER MA;Lo;0;R;;;;;N;;;;;
1938 07E2;NKO LETTER NYA;Lo;0;R;;;;;N;;;;;
1939 07E3;NKO LETTER NA;Lo;0;R;;;;;N;;;;;
1940 07E4;NKO LETTER HA;Lo;0;R;;;;;N;;;;;
1941 07E5;NKO LETTER WA;Lo;0;R;;;;;N;;;;;
1942 07E6;NKO LETTER YA;Lo;0;R;;;;;N;;;;;
1943 07E7;NKO LETTER NYA WOLOSO;Lo;0;R;;;;;N;;;;;
1944 07E8;NKO LETTER JONA JA;Lo;0;R;;;;;N;;;;;
1945 07E9;NKO LETTER JONA CHA;Lo;0;R;;;;;N;;;;;
1946 07EA;NKO LETTER JONA RA;Lo;0;R;;;;;N;;;;;
1947 07EB;NKO COMBINING SHORT HIGH TONE;Mn;230;NSM;;;;;N;;;;;
1948 07EC;NKO COMBINING SHORT LOW TONE;Mn;230;NSM;;;;;N;;;;;
1949 07ED;NKO COMBINING SHORT RISING TONE;Mn;230;NSM;;;;;N;;;;;
1950 07EE;NKO COMBINING LONG DESCENDING TONE;Mn;230;NSM;;;;;N;;;;;
1951 07EF;NKO COMBINING LONG HIGH TONE;Mn;230;NSM;;;;;N;;;;;
1952 07F0;NKO COMBINING LONG LOW TONE;Mn;230;NSM;;;;;N;;;;;
1953 07F1;NKO COMBINING LONG RISING TONE;Mn;230;NSM;;;;;N;;;;;
1954 07F2;NKO COMBINING NASALIZATION MARK;Mn;220;NSM;;;;;N;;;;;
1955 07F3;NKO COMBINING DOUBLE DOT ABOVE;Mn;230;NSM;;;;;N;;;;;
1956 07F4;NKO HIGH TONE APOSTROPHE;Lm;0;R;;;;;N;;;;;
1957 07F5;NKO LOW TONE APOSTROPHE;Lm;0;R;;;;;N;;;;;
1958 07F6;NKO SYMBOL OO DENNEN;So;0;ON;;;;;N;;;;;
1959 07F7;NKO SYMBOL GBAKURUNEN;Po;0;ON;;;;;N;;;;;
1960 07F8;NKO COMMA;Po;0;ON;;;;;N;;;;;
1961 07F9;NKO EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
1962 07FA;NKO LAJANYALAN;Lm;0;R;;;;;N;;;;;
1963 0901;DEVANAGARI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
1964 0902;DEVANAGARI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
1965 0903;DEVANAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
1966 0904;DEVANAGARI LETTER SHORT A;Lo;0;L;;;;;N;;;;;
1967 0905;DEVANAGARI LETTER A;Lo;0;L;;;;;N;;;;;
1968 0906;DEVANAGARI LETTER AA;Lo;0;L;;;;;N;;;;;
1969 0907;DEVANAGARI LETTER I;Lo;0;L;;;;;N;;;;;
1970 0908;DEVANAGARI LETTER II;Lo;0;L;;;;;N;;;;;
1971 0909;DEVANAGARI LETTER U;Lo;0;L;;;;;N;;;;;
1972 090A;DEVANAGARI LETTER UU;Lo;0;L;;;;;N;;;;;
1973 090B;DEVANAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
1974 090C;DEVANAGARI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
1975 090D;DEVANAGARI LETTER CANDRA E;Lo;0;L;;;;;N;;;;;
1976 090E;DEVANAGARI LETTER SHORT E;Lo;0;L;;;;;N;;;;;
1977 090F;DEVANAGARI LETTER E;Lo;0;L;;;;;N;;;;;
1978 0910;DEVANAGARI LETTER AI;Lo;0;L;;;;;N;;;;;
1979 0911;DEVANAGARI LETTER CANDRA O;Lo;0;L;;;;;N;;;;;
1980 0912;DEVANAGARI LETTER SHORT O;Lo;0;L;;;;;N;;;;;
1981 0913;DEVANAGARI LETTER O;Lo;0;L;;;;;N;;;;;
1982 0914;DEVANAGARI LETTER AU;Lo;0;L;;;;;N;;;;;
1983 0915;DEVANAGARI LETTER KA;Lo;0;L;;;;;N;;;;;
1984 0916;DEVANAGARI LETTER KHA;Lo;0;L;;;;;N;;;;;
1985 0917;DEVANAGARI LETTER GA;Lo;0;L;;;;;N;;;;;
1986 0918;DEVANAGARI LETTER GHA;Lo;0;L;;;;;N;;;;;
1987 0919;DEVANAGARI LETTER NGA;Lo;0;L;;;;;N;;;;;
1988 091A;DEVANAGARI LETTER CA;Lo;0;L;;;;;N;;;;;
1989 091B;DEVANAGARI LETTER CHA;Lo;0;L;;;;;N;;;;;
1990 091C;DEVANAGARI LETTER JA;Lo;0;L;;;;;N;;;;;
1991 091D;DEVANAGARI LETTER JHA;Lo;0;L;;;;;N;;;;;
1992 091E;DEVANAGARI LETTER NYA;Lo;0;L;;;;;N;;;;;
1993 091F;DEVANAGARI LETTER TTA;Lo;0;L;;;;;N;;;;;
1994 0920;DEVANAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;;
1995 0921;DEVANAGARI LETTER DDA;Lo;0;L;;;;;N;;;;;
1996 0922;DEVANAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;;
1997 0923;DEVANAGARI LETTER NNA;Lo;0;L;;;;;N;;;;;
1998 0924;DEVANAGARI LETTER TA;Lo;0;L;;;;;N;;;;;
1999 0925;DEVANAGARI LETTER THA;Lo;0;L;;;;;N;;;;;
2000 0926;DEVANAGARI LETTER DA;Lo;0;L;;;;;N;;;;;
2001 0927;DEVANAGARI LETTER DHA;Lo;0;L;;;;;N;;;;;
2002 0928;DEVANAGARI LETTER NA;Lo;0;L;;;;;N;;;;;
2003 0929;DEVANAGARI LETTER NNNA;Lo;0;L;0928 093C;;;;N;;;;;
2004 092A;DEVANAGARI LETTER PA;Lo;0;L;;;;;N;;;;;
2005 092B;DEVANAGARI LETTER PHA;Lo;0;L;;;;;N;;;;;
2006 092C;DEVANAGARI LETTER BA;Lo;0;L;;;;;N;;;;;
2007 092D;DEVANAGARI LETTER BHA;Lo;0;L;;;;;N;;;;;
2008 092E;DEVANAGARI LETTER MA;Lo;0;L;;;;;N;;;;;
2009 092F;DEVANAGARI LETTER YA;Lo;0;L;;;;;N;;;;;
2010 0930;DEVANAGARI LETTER RA;Lo;0;L;;;;;N;;;;;
2011 0931;DEVANAGARI LETTER RRA;Lo;0;L;0930 093C;;;;N;;;;;
2012 0932;DEVANAGARI LETTER LA;Lo;0;L;;;;;N;;;;;
2013 0933;DEVANAGARI LETTER LLA;Lo;0;L;;;;;N;;;;;
2014 0934;DEVANAGARI LETTER LLLA;Lo;0;L;0933 093C;;;;N;;;;;
2015 0935;DEVANAGARI LETTER VA;Lo;0;L;;;;;N;;;;;
2016 0936;DEVANAGARI LETTER SHA;Lo;0;L;;;;;N;;;;;
2017 0937;DEVANAGARI LETTER SSA;Lo;0;L;;;;;N;;;;;
2018 0938;DEVANAGARI LETTER SA;Lo;0;L;;;;;N;;;;;
2019 0939;DEVANAGARI LETTER HA;Lo;0;L;;;;;N;;;;;
2020 093C;DEVANAGARI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
2021 093D;DEVANAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
2022 093E;DEVANAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
2023 093F;DEVANAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
2024 0940;DEVANAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
2025 0941;DEVANAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
2026 0942;DEVANAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
2027 0943;DEVANAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
2028 0944;DEVANAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
2029 0945;DEVANAGARI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;;
2030 0946;DEVANAGARI VOWEL SIGN SHORT E;Mn;0;NSM;;;;;N;;;;;
2031 0947;DEVANAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
2032 0948;DEVANAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
2033 0949;DEVANAGARI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;;
2034 094A;DEVANAGARI VOWEL SIGN SHORT O;Mc;0;L;;;;;N;;;;;
2035 094B;DEVANAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
2036 094C;DEVANAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
2037 094D;DEVANAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
2038 0950;DEVANAGARI OM;Lo;0;L;;;;;N;;;;;
2039 0951;DEVANAGARI STRESS SIGN UDATTA;Mn;230;NSM;;;;;N;;;;;
2040 0952;DEVANAGARI STRESS SIGN ANUDATTA;Mn;220;NSM;;;;;N;;;;;
2041 0953;DEVANAGARI GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;;
2042 0954;DEVANAGARI ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;;
2043 0958;DEVANAGARI LETTER QA;Lo;0;L;0915 093C;;;;N;;;;;
2044 0959;DEVANAGARI LETTER KHHA;Lo;0;L;0916 093C;;;;N;;;;;
2045 095A;DEVANAGARI LETTER GHHA;Lo;0;L;0917 093C;;;;N;;;;;
2046 095B;DEVANAGARI LETTER ZA;Lo;0;L;091C 093C;;;;N;;;;;
2047 095C;DEVANAGARI LETTER DDDHA;Lo;0;L;0921 093C;;;;N;;;;;
2048 095D;DEVANAGARI LETTER RHA;Lo;0;L;0922 093C;;;;N;;;;;
2049 095E;DEVANAGARI LETTER FA;Lo;0;L;092B 093C;;;;N;;;;;
2050 095F;DEVANAGARI LETTER YYA;Lo;0;L;092F 093C;;;;N;;;;;
2051 0960;DEVANAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
2052 0961;DEVANAGARI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
2053 0962;DEVANAGARI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
2054 0963;DEVANAGARI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
2055 0964;DEVANAGARI DANDA;Po;0;L;;;;;N;;;;;
2056 0965;DEVANAGARI DOUBLE DANDA;Po;0;L;;;;;N;;;;;
2057 0966;DEVANAGARI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
2058 0967;DEVANAGARI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
2059 0968;DEVANAGARI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
2060 0969;DEVANAGARI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
2061 096A;DEVANAGARI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
2062 096B;DEVANAGARI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
2063 096C;DEVANAGARI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
2064 096D;DEVANAGARI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
2065 096E;DEVANAGARI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
2066 096F;DEVANAGARI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
2067 0970;DEVANAGARI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;
2068 0971;DEVANAGARI SIGN HIGH SPACING DOT;Lm;0;L;;;;;N;;;;;
2069 0972;DEVANAGARI LETTER CANDRA A;Lo;0;L;;;;;N;;;;;
2070 097B;DEVANAGARI LETTER GGA;Lo;0;L;;;;;N;;;;;
2071 097C;DEVANAGARI LETTER JJA;Lo;0;L;;;;;N;;;;;
2072 097D;DEVANAGARI LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
2073 097E;DEVANAGARI LETTER DDDA;Lo;0;L;;;;;N;;;;;
2074 097F;DEVANAGARI LETTER BBA;Lo;0;L;;;;;N;;;;;
2075 0981;BENGALI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
2076 0982;BENGALI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
2077 0983;BENGALI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
2078 0985;BENGALI LETTER A;Lo;0;L;;;;;N;;;;;
2079 0986;BENGALI LETTER AA;Lo;0;L;;;;;N;;;;;
2080 0987;BENGALI LETTER I;Lo;0;L;;;;;N;;;;;
2081 0988;BENGALI LETTER II;Lo;0;L;;;;;N;;;;;
2082 0989;BENGALI LETTER U;Lo;0;L;;;;;N;;;;;
2083 098A;BENGALI LETTER UU;Lo;0;L;;;;;N;;;;;
2084 098B;BENGALI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
2085 098C;BENGALI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
2086 098F;BENGALI LETTER E;Lo;0;L;;;;;N;;;;;
2087 0990;BENGALI LETTER AI;Lo;0;L;;;;;N;;;;;
2088 0993;BENGALI LETTER O;Lo;0;L;;;;;N;;;;;
2089 0994;BENGALI LETTER AU;Lo;0;L;;;;;N;;;;;
2090 0995;BENGALI LETTER KA;Lo;0;L;;;;;N;;;;;
2091 0996;BENGALI LETTER KHA;Lo;0;L;;;;;N;;;;;
2092 0997;BENGALI LETTER GA;Lo;0;L;;;;;N;;;;;
2093 0998;BENGALI LETTER GHA;Lo;0;L;;;;;N;;;;;
2094 0999;BENGALI LETTER NGA;Lo;0;L;;;;;N;;;;;
2095 099A;BENGALI LETTER CA;Lo;0;L;;;;;N;;;;;
2096 099B;BENGALI LETTER CHA;Lo;0;L;;;;;N;;;;;
2097 099C;BENGALI LETTER JA;Lo;0;L;;;;;N;;;;;
2098 099D;BENGALI LETTER JHA;Lo;0;L;;;;;N;;;;;
2099 099E;BENGALI LETTER NYA;Lo;0;L;;;;;N;;;;;
2100 099F;BENGALI LETTER TTA;Lo;0;L;;;;;N;;;;;
2101 09A0;BENGALI LETTER TTHA;Lo;0;L;;;;;N;;;;;
2102 09A1;BENGALI LETTER DDA;Lo;0;L;;;;;N;;;;;
2103 09A2;BENGALI LETTER DDHA;Lo;0;L;;;;;N;;;;;
2104 09A3;BENGALI LETTER NNA;Lo;0;L;;;;;N;;;;;
2105 09A4;BENGALI LETTER TA;Lo;0;L;;;;;N;;;;;
2106 09A5;BENGALI LETTER THA;Lo;0;L;;;;;N;;;;;
2107 09A6;BENGALI LETTER DA;Lo;0;L;;;;;N;;;;;
2108 09A7;BENGALI LETTER DHA;Lo;0;L;;;;;N;;;;;
2109 09A8;BENGALI LETTER NA;Lo;0;L;;;;;N;;;;;
2110 09AA;BENGALI LETTER PA;Lo;0;L;;;;;N;;;;;
2111 09AB;BENGALI LETTER PHA;Lo;0;L;;;;;N;;;;;
2112 09AC;BENGALI LETTER BA;Lo;0;L;;;;;N;;;;;
2113 09AD;BENGALI LETTER BHA;Lo;0;L;;;;;N;;;;;
2114 09AE;BENGALI LETTER MA;Lo;0;L;;;;;N;;;;;
2115 09AF;BENGALI LETTER YA;Lo;0;L;;;;;N;;;;;
2116 09B0;BENGALI LETTER RA;Lo;0;L;;;;;N;;;;;
2117 09B2;BENGALI LETTER LA;Lo;0;L;;;;;N;;;;;
2118 09B6;BENGALI LETTER SHA;Lo;0;L;;;;;N;;;;;
2119 09B7;BENGALI LETTER SSA;Lo;0;L;;;;;N;;;;;
2120 09B8;BENGALI LETTER SA;Lo;0;L;;;;;N;;;;;
2121 09B9;BENGALI LETTER HA;Lo;0;L;;;;;N;;;;;
2122 09BC;BENGALI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
2123 09BD;BENGALI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
2124 09BE;BENGALI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
2125 09BF;BENGALI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
2126 09C0;BENGALI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
2127 09C1;BENGALI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
2128 09C2;BENGALI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
2129 09C3;BENGALI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
2130 09C4;BENGALI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
2131 09C7;BENGALI VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
2132 09C8;BENGALI VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
2133 09CB;BENGALI VOWEL SIGN O;Mc;0;L;09C7 09BE;;;;N;;;;;
2134 09CC;BENGALI VOWEL SIGN AU;Mc;0;L;09C7 09D7;;;;N;;;;;
2135 09CD;BENGALI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
2136 09CE;BENGALI LETTER KHANDA TA;Lo;0;L;;;;;N;;;;;
2137 09D7;BENGALI AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
2138 09DC;BENGALI LETTER RRA;Lo;0;L;09A1 09BC;;;;N;;;;;
2139 09DD;BENGALI LETTER RHA;Lo;0;L;09A2 09BC;;;;N;;;;;
2140 09DF;BENGALI LETTER YYA;Lo;0;L;09AF 09BC;;;;N;;;;;
2141 09E0;BENGALI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
2142 09E1;BENGALI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
2143 09E2;BENGALI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
2144 09E3;BENGALI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
2145 09E6;BENGALI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
2146 09E7;BENGALI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
2147 09E8;BENGALI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
2148 09E9;BENGALI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
2149 09EA;BENGALI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
2150 09EB;BENGALI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
2151 09EC;BENGALI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
2152 09ED;BENGALI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
2153 09EE;BENGALI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
2154 09EF;BENGALI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
2155 09F0;BENGALI LETTER RA WITH MIDDLE DIAGONAL;Lo;0;L;;;;;N;;Assamese;;;
2156 09F1;BENGALI LETTER RA WITH LOWER DIAGONAL;Lo;0;L;;;;;N;BENGALI LETTER VA WITH LOWER DIAGONAL;Assamese;;;
2157 09F2;BENGALI RUPEE MARK;Sc;0;ET;;;;;N;;;;;
2158 09F3;BENGALI RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
2159 09F4;BENGALI CURRENCY NUMERATOR ONE;No;0;L;;;;1;N;;;;;
2160 09F5;BENGALI CURRENCY NUMERATOR TWO;No;0;L;;;;2;N;;;;;
2161 09F6;BENGALI CURRENCY NUMERATOR THREE;No;0;L;;;;3;N;;;;;
2162 09F7;BENGALI CURRENCY NUMERATOR FOUR;No;0;L;;;;4;N;;;;;
2163 09F8;BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR;No;0;L;;;;;N;;;;;
2164 09F9;BENGALI CURRENCY DENOMINATOR SIXTEEN;No;0;L;;;;16;N;;;;;
2165 09FA;BENGALI ISSHAR;So;0;L;;;;;N;;;;;
2166 0A01;GURMUKHI SIGN ADAK BINDI;Mn;0;NSM;;;;;N;;;;;
2167 0A02;GURMUKHI SIGN BINDI;Mn;0;NSM;;;;;N;;;;;
2168 0A03;GURMUKHI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
2169 0A05;GURMUKHI LETTER A;Lo;0;L;;;;;N;;;;;
2170 0A06;GURMUKHI LETTER AA;Lo;0;L;;;;;N;;;;;
2171 0A07;GURMUKHI LETTER I;Lo;0;L;;;;;N;;;;;
2172 0A08;GURMUKHI LETTER II;Lo;0;L;;;;;N;;;;;
2173 0A09;GURMUKHI LETTER U;Lo;0;L;;;;;N;;;;;
2174 0A0A;GURMUKHI LETTER UU;Lo;0;L;;;;;N;;;;;
2175 0A0F;GURMUKHI LETTER EE;Lo;0;L;;;;;N;;;;;
2176 0A10;GURMUKHI LETTER AI;Lo;0;L;;;;;N;;;;;
2177 0A13;GURMUKHI LETTER OO;Lo;0;L;;;;;N;;;;;
2178 0A14;GURMUKHI LETTER AU;Lo;0;L;;;;;N;;;;;
2179 0A15;GURMUKHI LETTER KA;Lo;0;L;;;;;N;;;;;
2180 0A16;GURMUKHI LETTER KHA;Lo;0;L;;;;;N;;;;;
2181 0A17;GURMUKHI LETTER GA;Lo;0;L;;;;;N;;;;;
2182 0A18;GURMUKHI LETTER GHA;Lo;0;L;;;;;N;;;;;
2183 0A19;GURMUKHI LETTER NGA;Lo;0;L;;;;;N;;;;;
2184 0A1A;GURMUKHI LETTER CA;Lo;0;L;;;;;N;;;;;
2185 0A1B;GURMUKHI LETTER CHA;Lo;0;L;;;;;N;;;;;
2186 0A1C;GURMUKHI LETTER JA;Lo;0;L;;;;;N;;;;;
2187 0A1D;GURMUKHI LETTER JHA;Lo;0;L;;;;;N;;;;;
2188 0A1E;GURMUKHI LETTER NYA;Lo;0;L;;;;;N;;;;;
2189 0A1F;GURMUKHI LETTER TTA;Lo;0;L;;;;;N;;;;;
2190 0A20;GURMUKHI LETTER TTHA;Lo;0;L;;;;;N;;;;;
2191 0A21;GURMUKHI LETTER DDA;Lo;0;L;;;;;N;;;;;
2192 0A22;GURMUKHI LETTER DDHA;Lo;0;L;;;;;N;;;;;
2193 0A23;GURMUKHI LETTER NNA;Lo;0;L;;;;;N;;;;;
2194 0A24;GURMUKHI LETTER TA;Lo;0;L;;;;;N;;;;;
2195 0A25;GURMUKHI LETTER THA;Lo;0;L;;;;;N;;;;;
2196 0A26;GURMUKHI LETTER DA;Lo;0;L;;;;;N;;;;;
2197 0A27;GURMUKHI LETTER DHA;Lo;0;L;;;;;N;;;;;
2198 0A28;GURMUKHI LETTER NA;Lo;0;L;;;;;N;;;;;
2199 0A2A;GURMUKHI LETTER PA;Lo;0;L;;;;;N;;;;;
2200 0A2B;GURMUKHI LETTER PHA;Lo;0;L;;;;;N;;;;;
2201 0A2C;GURMUKHI LETTER BA;Lo;0;L;;;;;N;;;;;
2202 0A2D;GURMUKHI LETTER BHA;Lo;0;L;;;;;N;;;;;
2203 0A2E;GURMUKHI LETTER MA;Lo;0;L;;;;;N;;;;;
2204 0A2F;GURMUKHI LETTER YA;Lo;0;L;;;;;N;;;;;
2205 0A30;GURMUKHI LETTER RA;Lo;0;L;;;;;N;;;;;
2206 0A32;GURMUKHI LETTER LA;Lo;0;L;;;;;N;;;;;
2207 0A33;GURMUKHI LETTER LLA;Lo;0;L;0A32 0A3C;;;;N;;;;;
2208 0A35;GURMUKHI LETTER VA;Lo;0;L;;;;;N;;;;;
2209 0A36;GURMUKHI LETTER SHA;Lo;0;L;0A38 0A3C;;;;N;;;;;
2210 0A38;GURMUKHI LETTER SA;Lo;0;L;;;;;N;;;;;
2211 0A39;GURMUKHI LETTER HA;Lo;0;L;;;;;N;;;;;
2212 0A3C;GURMUKHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
2213 0A3E;GURMUKHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
2214 0A3F;GURMUKHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
2215 0A40;GURMUKHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
2216 0A41;GURMUKHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
2217 0A42;GURMUKHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
2218 0A47;GURMUKHI VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;
2219 0A48;GURMUKHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
2220 0A4B;GURMUKHI VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;;
2221 0A4C;GURMUKHI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
2222 0A4D;GURMUKHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
2223 0A51;GURMUKHI SIGN UDAAT;Mn;0;NSM;;;;;N;;;;;
2224 0A59;GURMUKHI LETTER KHHA;Lo;0;L;0A16 0A3C;;;;N;;;;;
2225 0A5A;GURMUKHI LETTER GHHA;Lo;0;L;0A17 0A3C;;;;N;;;;;
2226 0A5B;GURMUKHI LETTER ZA;Lo;0;L;0A1C 0A3C;;;;N;;;;;
2227 0A5C;GURMUKHI LETTER RRA;Lo;0;L;;;;;N;;;;;
2228 0A5E;GURMUKHI LETTER FA;Lo;0;L;0A2B 0A3C;;;;N;;;;;
2229 0A66;GURMUKHI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
2230 0A67;GURMUKHI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
2231 0A68;GURMUKHI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
2232 0A69;GURMUKHI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
2233 0A6A;GURMUKHI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
2234 0A6B;GURMUKHI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
2235 0A6C;GURMUKHI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
2236 0A6D;GURMUKHI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
2237 0A6E;GURMUKHI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
2238 0A6F;GURMUKHI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
2239 0A70;GURMUKHI TIPPI;Mn;0;NSM;;;;;N;;;;;
2240 0A71;GURMUKHI ADDAK;Mn;0;NSM;;;;;N;;;;;
2241 0A72;GURMUKHI IRI;Lo;0;L;;;;;N;;;;;
2242 0A73;GURMUKHI URA;Lo;0;L;;;;;N;;;;;
2243 0A74;GURMUKHI EK ONKAR;Lo;0;L;;;;;N;;;;;
2244 0A75;GURMUKHI SIGN YAKASH;Mn;0;NSM;;;;;N;;;;;
2245 0A81;GUJARATI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
2246 0A82;GUJARATI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
2247 0A83;GUJARATI SIGN VISARGA;Mc;0;L;;;;;N;;;;;
2248 0A85;GUJARATI LETTER A;Lo;0;L;;;;;N;;;;;
2249 0A86;GUJARATI LETTER AA;Lo;0;L;;;;;N;;;;;
2250 0A87;GUJARATI LETTER I;Lo;0;L;;;;;N;;;;;
2251 0A88;GUJARATI LETTER II;Lo;0;L;;;;;N;;;;;
2252 0A89;GUJARATI LETTER U;Lo;0;L;;;;;N;;;;;
2253 0A8A;GUJARATI LETTER UU;Lo;0;L;;;;;N;;;;;
2254 0A8B;GUJARATI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
2255 0A8C;GUJARATI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
2256 0A8D;GUJARATI VOWEL CANDRA E;Lo;0;L;;;;;N;;;;;
2257 0A8F;GUJARATI LETTER E;Lo;0;L;;;;;N;;;;;
2258 0A90;GUJARATI LETTER AI;Lo;0;L;;;;;N;;;;;
2259 0A91;GUJARATI VOWEL CANDRA O;Lo;0;L;;;;;N;;;;;
2260 0A93;GUJARATI LETTER O;Lo;0;L;;;;;N;;;;;
2261 0A94;GUJARATI LETTER AU;Lo;0;L;;;;;N;;;;;
2262 0A95;GUJARATI LETTER KA;Lo;0;L;;;;;N;;;;;
2263 0A96;GUJARATI LETTER KHA;Lo;0;L;;;;;N;;;;;
2264 0A97;GUJARATI LETTER GA;Lo;0;L;;;;;N;;;;;
2265 0A98;GUJARATI LETTER GHA;Lo;0;L;;;;;N;;;;;
2266 0A99;GUJARATI LETTER NGA;Lo;0;L;;;;;N;;;;;
2267 0A9A;GUJARATI LETTER CA;Lo;0;L;;;;;N;;;;;
2268 0A9B;GUJARATI LETTER CHA;Lo;0;L;;;;;N;;;;;
2269 0A9C;GUJARATI LETTER JA;Lo;0;L;;;;;N;;;;;
2270 0A9D;GUJARATI LETTER JHA;Lo;0;L;;;;;N;;;;;
2271 0A9E;GUJARATI LETTER NYA;Lo;0;L;;;;;N;;;;;
2272 0A9F;GUJARATI LETTER TTA;Lo;0;L;;;;;N;;;;;
2273 0AA0;GUJARATI LETTER TTHA;Lo;0;L;;;;;N;;;;;
2274 0AA1;GUJARATI LETTER DDA;Lo;0;L;;;;;N;;;;;
2275 0AA2;GUJARATI LETTER DDHA;Lo;0;L;;;;;N;;;;;
2276 0AA3;GUJARATI LETTER NNA;Lo;0;L;;;;;N;;;;;
2277 0AA4;GUJARATI LETTER TA;Lo;0;L;;;;;N;;;;;
2278 0AA5;GUJARATI LETTER THA;Lo;0;L;;;;;N;;;;;
2279 0AA6;GUJARATI LETTER DA;Lo;0;L;;;;;N;;;;;
2280 0AA7;GUJARATI LETTER DHA;Lo;0;L;;;;;N;;;;;
2281 0AA8;GUJARATI LETTER NA;Lo;0;L;;;;;N;;;;;
2282 0AAA;GUJARATI LETTER PA;Lo;0;L;;;;;N;;;;;
2283 0AAB;GUJARATI LETTER PHA;Lo;0;L;;;;;N;;;;;
2284 0AAC;GUJARATI LETTER BA;Lo;0;L;;;;;N;;;;;
2285 0AAD;GUJARATI LETTER BHA;Lo;0;L;;;;;N;;;;;
2286 0AAE;GUJARATI LETTER MA;Lo;0;L;;;;;N;;;;;
2287 0AAF;GUJARATI LETTER YA;Lo;0;L;;;;;N;;;;;
2288 0AB0;GUJARATI LETTER RA;Lo;0;L;;;;;N;;;;;
2289 0AB2;GUJARATI LETTER LA;Lo;0;L;;;;;N;;;;;
2290 0AB3;GUJARATI LETTER LLA;Lo;0;L;;;;;N;;;;;
2291 0AB5;GUJARATI LETTER VA;Lo;0;L;;;;;N;;;;;
2292 0AB6;GUJARATI LETTER SHA;Lo;0;L;;;;;N;;;;;
2293 0AB7;GUJARATI LETTER SSA;Lo;0;L;;;;;N;;;;;
2294 0AB8;GUJARATI LETTER SA;Lo;0;L;;;;;N;;;;;
2295 0AB9;GUJARATI LETTER HA;Lo;0;L;;;;;N;;;;;
2296 0ABC;GUJARATI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
2297 0ABD;GUJARATI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
2298 0ABE;GUJARATI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
2299 0ABF;GUJARATI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
2300 0AC0;GUJARATI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
2301 0AC1;GUJARATI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
2302 0AC2;GUJARATI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
2303 0AC3;GUJARATI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
2304 0AC4;GUJARATI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
2305 0AC5;GUJARATI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;;
2306 0AC7;GUJARATI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
2307 0AC8;GUJARATI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
2308 0AC9;GUJARATI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;;
2309 0ACB;GUJARATI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
2310 0ACC;GUJARATI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
2311 0ACD;GUJARATI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
2312 0AD0;GUJARATI OM;Lo;0;L;;;;;N;;;;;
2313 0AE0;GUJARATI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
2314 0AE1;GUJARATI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
2315 0AE2;GUJARATI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
2316 0AE3;GUJARATI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
2317 0AE6;GUJARATI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
2318 0AE7;GUJARATI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
2319 0AE8;GUJARATI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
2320 0AE9;GUJARATI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
2321 0AEA;GUJARATI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
2322 0AEB;GUJARATI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
2323 0AEC;GUJARATI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
2324 0AED;GUJARATI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
2325 0AEE;GUJARATI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
2326 0AEF;GUJARATI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
2327 0AF1;GUJARATI RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
2328 0B01;ORIYA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;
2329 0B02;ORIYA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
2330 0B03;ORIYA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
2331 0B05;ORIYA LETTER A;Lo;0;L;;;;;N;;;;;
2332 0B06;ORIYA LETTER AA;Lo;0;L;;;;;N;;;;;
2333 0B07;ORIYA LETTER I;Lo;0;L;;;;;N;;;;;
2334 0B08;ORIYA LETTER II;Lo;0;L;;;;;N;;;;;
2335 0B09;ORIYA LETTER U;Lo;0;L;;;;;N;;;;;
2336 0B0A;ORIYA LETTER UU;Lo;0;L;;;;;N;;;;;
2337 0B0B;ORIYA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
2338 0B0C;ORIYA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
2339 0B0F;ORIYA LETTER E;Lo;0;L;;;;;N;;;;;
2340 0B10;ORIYA LETTER AI;Lo;0;L;;;;;N;;;;;
2341 0B13;ORIYA LETTER O;Lo;0;L;;;;;N;;;;;
2342 0B14;ORIYA LETTER AU;Lo;0;L;;;;;N;;;;;
2343 0B15;ORIYA LETTER KA;Lo;0;L;;;;;N;;;;;
2344 0B16;ORIYA LETTER KHA;Lo;0;L;;;;;N;;;;;
2345 0B17;ORIYA LETTER GA;Lo;0;L;;;;;N;;;;;
2346 0B18;ORIYA LETTER GHA;Lo;0;L;;;;;N;;;;;
2347 0B19;ORIYA LETTER NGA;Lo;0;L;;;;;N;;;;;
2348 0B1A;ORIYA LETTER CA;Lo;0;L;;;;;N;;;;;
2349 0B1B;ORIYA LETTER CHA;Lo;0;L;;;;;N;;;;;
2350 0B1C;ORIYA LETTER JA;Lo;0;L;;;;;N;;;;;
2351 0B1D;ORIYA LETTER JHA;Lo;0;L;;;;;N;;;;;
2352 0B1E;ORIYA LETTER NYA;Lo;0;L;;;;;N;;;;;
2353 0B1F;ORIYA LETTER TTA;Lo;0;L;;;;;N;;;;;
2354 0B20;ORIYA LETTER TTHA;Lo;0;L;;;;;N;;;;;
2355 0B21;ORIYA LETTER DDA;Lo;0;L;;;;;N;;;;;
2356 0B22;ORIYA LETTER DDHA;Lo;0;L;;;;;N;;;;;
2357 0B23;ORIYA LETTER NNA;Lo;0;L;;;;;N;;;;;
2358 0B24;ORIYA LETTER TA;Lo;0;L;;;;;N;;;;;
2359 0B25;ORIYA LETTER THA;Lo;0;L;;;;;N;;;;;
2360 0B26;ORIYA LETTER DA;Lo;0;L;;;;;N;;;;;
2361 0B27;ORIYA LETTER DHA;Lo;0;L;;;;;N;;;;;
2362 0B28;ORIYA LETTER NA;Lo;0;L;;;;;N;;;;;
2363 0B2A;ORIYA LETTER PA;Lo;0;L;;;;;N;;;;;
2364 0B2B;ORIYA LETTER PHA;Lo;0;L;;;;;N;;;;;
2365 0B2C;ORIYA LETTER BA;Lo;0;L;;;;;N;;;;;
2366 0B2D;ORIYA LETTER BHA;Lo;0;L;;;;;N;;;;;
2367 0B2E;ORIYA LETTER MA;Lo;0;L;;;;;N;;;;;
2368 0B2F;ORIYA LETTER YA;Lo;0;L;;;;;N;;;;;
2369 0B30;ORIYA LETTER RA;Lo;0;L;;;;;N;;;;;
2370 0B32;ORIYA LETTER LA;Lo;0;L;;;;;N;;;;;
2371 0B33;ORIYA LETTER LLA;Lo;0;L;;;;;N;;;;;
2372 0B35;ORIYA LETTER VA;Lo;0;L;;;;;N;;;;;
2373 0B36;ORIYA LETTER SHA;Lo;0;L;;;;;N;;;;;
2374 0B37;ORIYA LETTER SSA;Lo;0;L;;;;;N;;;;;
2375 0B38;ORIYA LETTER SA;Lo;0;L;;;;;N;;;;;
2376 0B39;ORIYA LETTER HA;Lo;0;L;;;;;N;;;;;
2377 0B3C;ORIYA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
2378 0B3D;ORIYA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
2379 0B3E;ORIYA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
2380 0B3F;ORIYA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
2381 0B40;ORIYA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
2382 0B41;ORIYA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
2383 0B42;ORIYA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
2384 0B43;ORIYA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
2385 0B44;ORIYA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
2386 0B47;ORIYA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
2387 0B48;ORIYA VOWEL SIGN AI;Mc;0;L;0B47 0B56;;;;N;;;;;
2388 0B4B;ORIYA VOWEL SIGN O;Mc;0;L;0B47 0B3E;;;;N;;;;;
2389 0B4C;ORIYA VOWEL SIGN AU;Mc;0;L;0B47 0B57;;;;N;;;;;
2390 0B4D;ORIYA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
2391 0B56;ORIYA AI LENGTH MARK;Mn;0;NSM;;;;;N;;;;;
2392 0B57;ORIYA AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
2393 0B5C;ORIYA LETTER RRA;Lo;0;L;0B21 0B3C;;;;N;;;;;
2394 0B5D;ORIYA LETTER RHA;Lo;0;L;0B22 0B3C;;;;N;;;;;
2395 0B5F;ORIYA LETTER YYA;Lo;0;L;;;;;N;;;;;
2396 0B60;ORIYA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
2397 0B61;ORIYA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
2398 0B62;ORIYA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
2399 0B63;ORIYA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
2400 0B66;ORIYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
2401 0B67;ORIYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
2402 0B68;ORIYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
2403 0B69;ORIYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
2404 0B6A;ORIYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
2405 0B6B;ORIYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
2406 0B6C;ORIYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
2407 0B6D;ORIYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
2408 0B6E;ORIYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
2409 0B6F;ORIYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
2410 0B70;ORIYA ISSHAR;So;0;L;;;;;N;;;;;
2411 0B71;ORIYA LETTER WA;Lo;0;L;;;;;N;;;;;
2412 0B82;TAMIL SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
2413 0B83;TAMIL SIGN VISARGA;Lo;0;L;;;;;N;;;;;
2414 0B85;TAMIL LETTER A;Lo;0;L;;;;;N;;;;;
2415 0B86;TAMIL LETTER AA;Lo;0;L;;;;;N;;;;;
2416 0B87;TAMIL LETTER I;Lo;0;L;;;;;N;;;;;
2417 0B88;TAMIL LETTER II;Lo;0;L;;;;;N;;;;;
2418 0B89;TAMIL LETTER U;Lo;0;L;;;;;N;;;;;
2419 0B8A;TAMIL LETTER UU;Lo;0;L;;;;;N;;;;;
2420 0B8E;TAMIL LETTER E;Lo;0;L;;;;;N;;;;;
2421 0B8F;TAMIL LETTER EE;Lo;0;L;;;;;N;;;;;
2422 0B90;TAMIL LETTER AI;Lo;0;L;;;;;N;;;;;
2423 0B92;TAMIL LETTER O;Lo;0;L;;;;;N;;;;;
2424 0B93;TAMIL LETTER OO;Lo;0;L;;;;;N;;;;;
2425 0B94;TAMIL LETTER AU;Lo;0;L;0B92 0BD7;;;;N;;;;;
2426 0B95;TAMIL LETTER KA;Lo;0;L;;;;;N;;;;;
2427 0B99;TAMIL LETTER NGA;Lo;0;L;;;;;N;;;;;
2428 0B9A;TAMIL LETTER CA;Lo;0;L;;;;;N;;;;;
2429 0B9C;TAMIL LETTER JA;Lo;0;L;;;;;N;;;;;
2430 0B9E;TAMIL LETTER NYA;Lo;0;L;;;;;N;;;;;
2431 0B9F;TAMIL LETTER TTA;Lo;0;L;;;;;N;;;;;
2432 0BA3;TAMIL LETTER NNA;Lo;0;L;;;;;N;;;;;
2433 0BA4;TAMIL LETTER TA;Lo;0;L;;;;;N;;;;;
2434 0BA8;TAMIL LETTER NA;Lo;0;L;;;;;N;;;;;
2435 0BA9;TAMIL LETTER NNNA;Lo;0;L;;;;;N;;;;;
2436 0BAA;TAMIL LETTER PA;Lo;0;L;;;;;N;;;;;
2437 0BAE;TAMIL LETTER MA;Lo;0;L;;;;;N;;;;;
2438 0BAF;TAMIL LETTER YA;Lo;0;L;;;;;N;;;;;
2439 0BB0;TAMIL LETTER RA;Lo;0;L;;;;;N;;;;;
2440 0BB1;TAMIL LETTER RRA;Lo;0;L;;;;;N;;;;;
2441 0BB2;TAMIL LETTER LA;Lo;0;L;;;;;N;;;;;
2442 0BB3;TAMIL LETTER LLA;Lo;0;L;;;;;N;;;;;
2443 0BB4;TAMIL LETTER LLLA;Lo;0;L;;;;;N;;;;;
2444 0BB5;TAMIL LETTER VA;Lo;0;L;;;;;N;;;;;
2445 0BB6;TAMIL LETTER SHA;Lo;0;L;;;;;N;;;;;
2446 0BB7;TAMIL LETTER SSA;Lo;0;L;;;;;N;;;;;
2447 0BB8;TAMIL LETTER SA;Lo;0;L;;;;;N;;;;;
2448 0BB9;TAMIL LETTER HA;Lo;0;L;;;;;N;;;;;
2449 0BBE;TAMIL VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
2450 0BBF;TAMIL VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
2451 0BC0;TAMIL VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
2452 0BC1;TAMIL VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
2453 0BC2;TAMIL VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
2454 0BC6;TAMIL VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
2455 0BC7;TAMIL VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
2456 0BC8;TAMIL VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
2457 0BCA;TAMIL VOWEL SIGN O;Mc;0;L;0BC6 0BBE;;;;N;;;;;
2458 0BCB;TAMIL VOWEL SIGN OO;Mc;0;L;0BC7 0BBE;;;;N;;;;;
2459 0BCC;TAMIL VOWEL SIGN AU;Mc;0;L;0BC6 0BD7;;;;N;;;;;
2460 0BCD;TAMIL SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
2461 0BD0;TAMIL OM;Lo;0;L;;;;;N;;;;;
2462 0BD7;TAMIL AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
2463 0BE6;TAMIL DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
2464 0BE7;TAMIL DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
2465 0BE8;TAMIL DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
2466 0BE9;TAMIL DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
2467 0BEA;TAMIL DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
2468 0BEB;TAMIL DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
2469 0BEC;TAMIL DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
2470 0BED;TAMIL DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
2471 0BEE;TAMIL DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
2472 0BEF;TAMIL DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
2473 0BF0;TAMIL NUMBER TEN;No;0;L;;;;10;N;;;;;
2474 0BF1;TAMIL NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;
2475 0BF2;TAMIL NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;
2476 0BF3;TAMIL DAY SIGN;So;0;ON;;;;;N;;Naal;;;
2477 0BF4;TAMIL MONTH SIGN;So;0;ON;;;;;N;;Maatham;;;
2478 0BF5;TAMIL YEAR SIGN;So;0;ON;;;;;N;;Varudam;;;
2479 0BF6;TAMIL DEBIT SIGN;So;0;ON;;;;;N;;Patru;;;
2480 0BF7;TAMIL CREDIT SIGN;So;0;ON;;;;;N;;Varavu;;;
2481 0BF8;TAMIL AS ABOVE SIGN;So;0;ON;;;;;N;;Merpadi;;;
2482 0BF9;TAMIL RUPEE SIGN;Sc;0;ET;;;;;N;;Rupai;;;
2483 0BFA;TAMIL NUMBER SIGN;So;0;ON;;;;;N;;Enn;;;
2484 0C01;TELUGU SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;;
2485 0C02;TELUGU SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
2486 0C03;TELUGU SIGN VISARGA;Mc;0;L;;;;;N;;;;;
2487 0C05;TELUGU LETTER A;Lo;0;L;;;;;N;;;;;
2488 0C06;TELUGU LETTER AA;Lo;0;L;;;;;N;;;;;
2489 0C07;TELUGU LETTER I;Lo;0;L;;;;;N;;;;;
2490 0C08;TELUGU LETTER II;Lo;0;L;;;;;N;;;;;
2491 0C09;TELUGU LETTER U;Lo;0;L;;;;;N;;;;;
2492 0C0A;TELUGU LETTER UU;Lo;0;L;;;;;N;;;;;
2493 0C0B;TELUGU LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
2494 0C0C;TELUGU LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
2495 0C0E;TELUGU LETTER E;Lo;0;L;;;;;N;;;;;
2496 0C0F;TELUGU LETTER EE;Lo;0;L;;;;;N;;;;;
2497 0C10;TELUGU LETTER AI;Lo;0;L;;;;;N;;;;;
2498 0C12;TELUGU LETTER O;Lo;0;L;;;;;N;;;;;
2499 0C13;TELUGU LETTER OO;Lo;0;L;;;;;N;;;;;
2500 0C14;TELUGU LETTER AU;Lo;0;L;;;;;N;;;;;
2501 0C15;TELUGU LETTER KA;Lo;0;L;;;;;N;;;;;
2502 0C16;TELUGU LETTER KHA;Lo;0;L;;;;;N;;;;;
2503 0C17;TELUGU LETTER GA;Lo;0;L;;;;;N;;;;;
2504 0C18;TELUGU LETTER GHA;Lo;0;L;;;;;N;;;;;
2505 0C19;TELUGU LETTER NGA;Lo;0;L;;;;;N;;;;;
2506 0C1A;TELUGU LETTER CA;Lo;0;L;;;;;N;;;;;
2507 0C1B;TELUGU LETTER CHA;Lo;0;L;;;;;N;;;;;
2508 0C1C;TELUGU LETTER JA;Lo;0;L;;;;;N;;;;;
2509 0C1D;TELUGU LETTER JHA;Lo;0;L;;;;;N;;;;;
2510 0C1E;TELUGU LETTER NYA;Lo;0;L;;;;;N;;;;;
2511 0C1F;TELUGU LETTER TTA;Lo;0;L;;;;;N;;;;;
2512 0C20;TELUGU LETTER TTHA;Lo;0;L;;;;;N;;;;;
2513 0C21;TELUGU LETTER DDA;Lo;0;L;;;;;N;;;;;
2514 0C22;TELUGU LETTER DDHA;Lo;0;L;;;;;N;;;;;
2515 0C23;TELUGU LETTER NNA;Lo;0;L;;;;;N;;;;;
2516 0C24;TELUGU LETTER TA;Lo;0;L;;;;;N;;;;;
2517 0C25;TELUGU LETTER THA;Lo;0;L;;;;;N;;;;;
2518 0C26;TELUGU LETTER DA;Lo;0;L;;;;;N;;;;;
2519 0C27;TELUGU LETTER DHA;Lo;0;L;;;;;N;;;;;
2520 0C28;TELUGU LETTER NA;Lo;0;L;;;;;N;;;;;
2521 0C2A;TELUGU LETTER PA;Lo;0;L;;;;;N;;;;;
2522 0C2B;TELUGU LETTER PHA;Lo;0;L;;;;;N;;;;;
2523 0C2C;TELUGU LETTER BA;Lo;0;L;;;;;N;;;;;
2524 0C2D;TELUGU LETTER BHA;Lo;0;L;;;;;N;;;;;
2525 0C2E;TELUGU LETTER MA;Lo;0;L;;;;;N;;;;;
2526 0C2F;TELUGU LETTER YA;Lo;0;L;;;;;N;;;;;
2527 0C30;TELUGU LETTER RA;Lo;0;L;;;;;N;;;;;
2528 0C31;TELUGU LETTER RRA;Lo;0;L;;;;;N;;;;;
2529 0C32;TELUGU LETTER LA;Lo;0;L;;;;;N;;;;;
2530 0C33;TELUGU LETTER LLA;Lo;0;L;;;;;N;;;;;
2531 0C35;TELUGU LETTER VA;Lo;0;L;;;;;N;;;;;
2532 0C36;TELUGU LETTER SHA;Lo;0;L;;;;;N;;;;;
2533 0C37;TELUGU LETTER SSA;Lo;0;L;;;;;N;;;;;
2534 0C38;TELUGU LETTER SA;Lo;0;L;;;;;N;;;;;
2535 0C39;TELUGU LETTER HA;Lo;0;L;;;;;N;;;;;
2536 0C3D;TELUGU SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
2537 0C3E;TELUGU VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
2538 0C3F;TELUGU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
2539 0C40;TELUGU VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
2540 0C41;TELUGU VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
2541 0C42;TELUGU VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
2542 0C43;TELUGU VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
2543 0C44;TELUGU VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
2544 0C46;TELUGU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
2545 0C47;TELUGU VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;
2546 0C48;TELUGU VOWEL SIGN AI;Mn;0;NSM;0C46 0C56;;;;N;;;;;
2547 0C4A;TELUGU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
2548 0C4B;TELUGU VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;;
2549 0C4C;TELUGU VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
2550 0C4D;TELUGU SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
2551 0C55;TELUGU LENGTH MARK;Mn;84;NSM;;;;;N;;;;;
2552 0C56;TELUGU AI LENGTH MARK;Mn;91;NSM;;;;;N;;;;;
2553 0C58;TELUGU LETTER TSA;Lo;0;L;;;;;N;;;;;
2554 0C59;TELUGU LETTER DZA;Lo;0;L;;;;;N;;;;;
2555 0C60;TELUGU LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
2556 0C61;TELUGU LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
2557 0C62;TELUGU VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
2558 0C63;TELUGU VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
2559 0C66;TELUGU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
2560 0C67;TELUGU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
2561 0C68;TELUGU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
2562 0C69;TELUGU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
2563 0C6A;TELUGU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
2564 0C6B;TELUGU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
2565 0C6C;TELUGU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
2566 0C6D;TELUGU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
2567 0C6E;TELUGU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
2568 0C6F;TELUGU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
2569 0C78;TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR;No;0;ON;;;;0;N;;;;;
2570 0C79;TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR;No;0;ON;;;;1;N;;;;;
2571 0C7A;TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR;No;0;ON;;;;2;N;;;;;
2572 0C7B;TELUGU FRACTION DIGIT THREE FOR ODD POWERS OF FOUR;No;0;ON;;;;3;N;;;;;
2573 0C7C;TELUGU FRACTION DIGIT ONE FOR EVEN POWERS OF FOUR;No;0;ON;;;;1;N;;;;;
2574 0C7D;TELUGU FRACTION DIGIT TWO FOR EVEN POWERS OF FOUR;No;0;ON;;;;2;N;;;;;
2575 0C7E;TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR;No;0;ON;;;;3;N;;;;;
2576 0C7F;TELUGU SIGN TUUMU;So;0;L;;;;;N;;;;;
2577 0C82;KANNADA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
2578 0C83;KANNADA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
2579 0C85;KANNADA LETTER A;Lo;0;L;;;;;N;;;;;
2580 0C86;KANNADA LETTER AA;Lo;0;L;;;;;N;;;;;
2581 0C87;KANNADA LETTER I;Lo;0;L;;;;;N;;;;;
2582 0C88;KANNADA LETTER II;Lo;0;L;;;;;N;;;;;
2583 0C89;KANNADA LETTER U;Lo;0;L;;;;;N;;;;;
2584 0C8A;KANNADA LETTER UU;Lo;0;L;;;;;N;;;;;
2585 0C8B;KANNADA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
2586 0C8C;KANNADA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
2587 0C8E;KANNADA LETTER E;Lo;0;L;;;;;N;;;;;
2588 0C8F;KANNADA LETTER EE;Lo;0;L;;;;;N;;;;;
2589 0C90;KANNADA LETTER AI;Lo;0;L;;;;;N;;;;;
2590 0C92;KANNADA LETTER O;Lo;0;L;;;;;N;;;;;
2591 0C93;KANNADA LETTER OO;Lo;0;L;;;;;N;;;;;
2592 0C94;KANNADA LETTER AU;Lo;0;L;;;;;N;;;;;
2593 0C95;KANNADA LETTER KA;Lo;0;L;;;;;N;;;;;
2594 0C96;KANNADA LETTER KHA;Lo;0;L;;;;;N;;;;;
2595 0C97;KANNADA LETTER GA;Lo;0;L;;;;;N;;;;;
2596 0C98;KANNADA LETTER GHA;Lo;0;L;;;;;N;;;;;
2597 0C99;KANNADA LETTER NGA;Lo;0;L;;;;;N;;;;;
2598 0C9A;KANNADA LETTER CA;Lo;0;L;;;;;N;;;;;
2599 0C9B;KANNADA LETTER CHA;Lo;0;L;;;;;N;;;;;
2600 0C9C;KANNADA LETTER JA;Lo;0;L;;;;;N;;;;;
2601 0C9D;KANNADA LETTER JHA;Lo;0;L;;;;;N;;;;;
2602 0C9E;KANNADA LETTER NYA;Lo;0;L;;;;;N;;;;;
2603 0C9F;KANNADA LETTER TTA;Lo;0;L;;;;;N;;;;;
2604 0CA0;KANNADA LETTER TTHA;Lo;0;L;;;;;N;;;;;
2605 0CA1;KANNADA LETTER DDA;Lo;0;L;;;;;N;;;;;
2606 0CA2;KANNADA LETTER DDHA;Lo;0;L;;;;;N;;;;;
2607 0CA3;KANNADA LETTER NNA;Lo;0;L;;;;;N;;;;;
2608 0CA4;KANNADA LETTER TA;Lo;0;L;;;;;N;;;;;
2609 0CA5;KANNADA LETTER THA;Lo;0;L;;;;;N;;;;;
2610 0CA6;KANNADA LETTER DA;Lo;0;L;;;;;N;;;;;
2611 0CA7;KANNADA LETTER DHA;Lo;0;L;;;;;N;;;;;
2612 0CA8;KANNADA LETTER NA;Lo;0;L;;;;;N;;;;;
2613 0CAA;KANNADA LETTER PA;Lo;0;L;;;;;N;;;;;
2614 0CAB;KANNADA LETTER PHA;Lo;0;L;;;;;N;;;;;
2615 0CAC;KANNADA LETTER BA;Lo;0;L;;;;;N;;;;;
2616 0CAD;KANNADA LETTER BHA;Lo;0;L;;;;;N;;;;;
2617 0CAE;KANNADA LETTER MA;Lo;0;L;;;;;N;;;;;
2618 0CAF;KANNADA LETTER YA;Lo;0;L;;;;;N;;;;;
2619 0CB0;KANNADA LETTER RA;Lo;0;L;;;;;N;;;;;
2620 0CB1;KANNADA LETTER RRA;Lo;0;L;;;;;N;;;;;
2621 0CB2;KANNADA LETTER LA;Lo;0;L;;;;;N;;;;;
2622 0CB3;KANNADA LETTER LLA;Lo;0;L;;;;;N;;;;;
2623 0CB5;KANNADA LETTER VA;Lo;0;L;;;;;N;;;;;
2624 0CB6;KANNADA LETTER SHA;Lo;0;L;;;;;N;;;;;
2625 0CB7;KANNADA LETTER SSA;Lo;0;L;;;;;N;;;;;
2626 0CB8;KANNADA LETTER SA;Lo;0;L;;;;;N;;;;;
2627 0CB9;KANNADA LETTER HA;Lo;0;L;;;;;N;;;;;
2628 0CBC;KANNADA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
2629 0CBD;KANNADA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
2630 0CBE;KANNADA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
2631 0CBF;KANNADA VOWEL SIGN I;Mn;0;L;;;;;N;;;;;
2632 0CC0;KANNADA VOWEL SIGN II;Mc;0;L;0CBF 0CD5;;;;N;;;;;
2633 0CC1;KANNADA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
2634 0CC2;KANNADA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
2635 0CC3;KANNADA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
2636 0CC4;KANNADA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
2637 0CC6;KANNADA VOWEL SIGN E;Mn;0;L;;;;;N;;;;;
2638 0CC7;KANNADA VOWEL SIGN EE;Mc;0;L;0CC6 0CD5;;;;N;;;;;
2639 0CC8;KANNADA VOWEL SIGN AI;Mc;0;L;0CC6 0CD6;;;;N;;;;;
2640 0CCA;KANNADA VOWEL SIGN O;Mc;0;L;0CC6 0CC2;;;;N;;;;;
2641 0CCB;KANNADA VOWEL SIGN OO;Mc;0;L;0CCA 0CD5;;;;N;;;;;
2642 0CCC;KANNADA VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
2643 0CCD;KANNADA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
2644 0CD5;KANNADA LENGTH MARK;Mc;0;L;;;;;N;;;;;
2645 0CD6;KANNADA AI LENGTH MARK;Mc;0;L;;;;;N;;;;;
2646 0CDE;KANNADA LETTER FA;Lo;0;L;;;;;N;;;;;
2647 0CE0;KANNADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
2648 0CE1;KANNADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
2649 0CE2;KANNADA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
2650 0CE3;KANNADA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
2651 0CE6;KANNADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
2652 0CE7;KANNADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
2653 0CE8;KANNADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
2654 0CE9;KANNADA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
2655 0CEA;KANNADA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
2656 0CEB;KANNADA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
2657 0CEC;KANNADA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
2658 0CED;KANNADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
2659 0CEE;KANNADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
2660 0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
2661 0CF1;KANNADA SIGN JIHVAMULIYA;So;0;ON;;;;;N;;;;;
2662 0CF2;KANNADA SIGN UPADHMANIYA;So;0;ON;;;;;N;;;;;
2663 0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
2664 0D03;MALAYALAM SIGN VISARGA;Mc;0;L;;;;;N;;;;;
2665 0D05;MALAYALAM LETTER A;Lo;0;L;;;;;N;;;;;
2666 0D06;MALAYALAM LETTER AA;Lo;0;L;;;;;N;;;;;
2667 0D07;MALAYALAM LETTER I;Lo;0;L;;;;;N;;;;;
2668 0D08;MALAYALAM LETTER II;Lo;0;L;;;;;N;;;;;
2669 0D09;MALAYALAM LETTER U;Lo;0;L;;;;;N;;;;;
2670 0D0A;MALAYALAM LETTER UU;Lo;0;L;;;;;N;;;;;
2671 0D0B;MALAYALAM LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
2672 0D0C;MALAYALAM LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
2673 0D0E;MALAYALAM LETTER E;Lo;0;L;;;;;N;;;;;
2674 0D0F;MALAYALAM LETTER EE;Lo;0;L;;;;;N;;;;;
2675 0D10;MALAYALAM LETTER AI;Lo;0;L;;;;;N;;;;;
2676 0D12;MALAYALAM LETTER O;Lo;0;L;;;;;N;;;;;
2677 0D13;MALAYALAM LETTER OO;Lo;0;L;;;;;N;;;;;
2678 0D14;MALAYALAM LETTER AU;Lo;0;L;;;;;N;;;;;
2679 0D15;MALAYALAM LETTER KA;Lo;0;L;;;;;N;;;;;
2680 0D16;MALAYALAM LETTER KHA;Lo;0;L;;;;;N;;;;;
2681 0D17;MALAYALAM LETTER GA;Lo;0;L;;;;;N;;;;;
2682 0D18;MALAYALAM LETTER GHA;Lo;0;L;;;;;N;;;;;
2683 0D19;MALAYALAM LETTER NGA;Lo;0;L;;;;;N;;;;;
2684 0D1A;MALAYALAM LETTER CA;Lo;0;L;;;;;N;;;;;
2685 0D1B;MALAYALAM LETTER CHA;Lo;0;L;;;;;N;;;;;
2686 0D1C;MALAYALAM LETTER JA;Lo;0;L;;;;;N;;;;;
2687 0D1D;MALAYALAM LETTER JHA;Lo;0;L;;;;;N;;;;;
2688 0D1E;MALAYALAM LETTER NYA;Lo;0;L;;;;;N;;;;;
2689 0D1F;MALAYALAM LETTER TTA;Lo;0;L;;;;;N;;;;;
2690 0D20;MALAYALAM LETTER TTHA;Lo;0;L;;;;;N;;;;;
2691 0D21;MALAYALAM LETTER DDA;Lo;0;L;;;;;N;;;;;
2692 0D22;MALAYALAM LETTER DDHA;Lo;0;L;;;;;N;;;;;
2693 0D23;MALAYALAM LETTER NNA;Lo;0;L;;;;;N;;;;;
2694 0D24;MALAYALAM LETTER TA;Lo;0;L;;;;;N;;;;;
2695 0D25;MALAYALAM LETTER THA;Lo;0;L;;;;;N;;;;;
2696 0D26;MALAYALAM LETTER DA;Lo;0;L;;;;;N;;;;;
2697 0D27;MALAYALAM LETTER DHA;Lo;0;L;;;;;N;;;;;
2698 0D28;MALAYALAM LETTER NA;Lo;0;L;;;;;N;;;;;
2699 0D2A;MALAYALAM LETTER PA;Lo;0;L;;;;;N;;;;;
2700 0D2B;MALAYALAM LETTER PHA;Lo;0;L;;;;;N;;;;;
2701 0D2C;MALAYALAM LETTER BA;Lo;0;L;;;;;N;;;;;
2702 0D2D;MALAYALAM LETTER BHA;Lo;0;L;;;;;N;;;;;
2703 0D2E;MALAYALAM LETTER MA;Lo;0;L;;;;;N;;;;;
2704 0D2F;MALAYALAM LETTER YA;Lo;0;L;;;;;N;;;;;
2705 0D30;MALAYALAM LETTER RA;Lo;0;L;;;;;N;;;;;
2706 0D31;MALAYALAM LETTER RRA;Lo;0;L;;;;;N;;;;;
2707 0D32;MALAYALAM LETTER LA;Lo;0;L;;;;;N;;;;;
2708 0D33;MALAYALAM LETTER LLA;Lo;0;L;;;;;N;;;;;
2709 0D34;MALAYALAM LETTER LLLA;Lo;0;L;;;;;N;;;;;
2710 0D35;MALAYALAM LETTER VA;Lo;0;L;;;;;N;;;;;
2711 0D36;MALAYALAM LETTER SHA;Lo;0;L;;;;;N;;;;;
2712 0D37;MALAYALAM LETTER SSA;Lo;0;L;;;;;N;;;;;
2713 0D38;MALAYALAM LETTER SA;Lo;0;L;;;;;N;;;;;
2714 0D39;MALAYALAM LETTER HA;Lo;0;L;;;;;N;;;;;
2715 0D3D;MALAYALAM SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;
2716 0D3E;MALAYALAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
2717 0D3F;MALAYALAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
2718 0D40;MALAYALAM VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
2719 0D41;MALAYALAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
2720 0D42;MALAYALAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
2721 0D43;MALAYALAM VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
2722 0D44;MALAYALAM VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;
2723 0D46;MALAYALAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
2724 0D47;MALAYALAM VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
2725 0D48;MALAYALAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
2726 0D4A;MALAYALAM VOWEL SIGN O;Mc;0;L;0D46 0D3E;;;;N;;;;;
2727 0D4B;MALAYALAM VOWEL SIGN OO;Mc;0;L;0D47 0D3E;;;;N;;;;;
2728 0D4C;MALAYALAM VOWEL SIGN AU;Mc;0;L;0D46 0D57;;;;N;;;;;
2729 0D4D;MALAYALAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
2730 0D57;MALAYALAM AU LENGTH MARK;Mc;0;L;;;;;N;;;;;
2731 0D60;MALAYALAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
2732 0D61;MALAYALAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
2733 0D62;MALAYALAM VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
2734 0D63;MALAYALAM VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
2735 0D66;MALAYALAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
2736 0D67;MALAYALAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
2737 0D68;MALAYALAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
2738 0D69;MALAYALAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
2739 0D6A;MALAYALAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
2740 0D6B;MALAYALAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
2741 0D6C;MALAYALAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
2742 0D6D;MALAYALAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
2743 0D6E;MALAYALAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
2744 0D6F;MALAYALAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
2745 0D70;MALAYALAM NUMBER TEN;No;0;L;;;;10;N;;;;;
2746 0D71;MALAYALAM NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;
2747 0D72;MALAYALAM NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;
2748 0D73;MALAYALAM FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;
2749 0D74;MALAYALAM FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;;
2750 0D75;MALAYALAM FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;
2751 0D79;MALAYALAM DATE MARK;So;0;L;;;;;N;;;;;
2752 0D7A;MALAYALAM LETTER CHILLU NN;Lo;0;L;;;;;N;;;;;
2753 0D7B;MALAYALAM LETTER CHILLU N;Lo;0;L;;;;;N;;;;;
2754 0D7C;MALAYALAM LETTER CHILLU RR;Lo;0;L;;;;;N;;;;;
2755 0D7D;MALAYALAM LETTER CHILLU L;Lo;0;L;;;;;N;;;;;
2756 0D7E;MALAYALAM LETTER CHILLU LL;Lo;0;L;;;;;N;;;;;
2757 0D7F;MALAYALAM LETTER CHILLU K;Lo;0;L;;;;;N;;;;;
2758 0D82;SINHALA SIGN ANUSVARAYA;Mc;0;L;;;;;N;;;;;
2759 0D83;SINHALA SIGN VISARGAYA;Mc;0;L;;;;;N;;;;;
2760 0D85;SINHALA LETTER AYANNA;Lo;0;L;;;;;N;;;;;
2761 0D86;SINHALA LETTER AAYANNA;Lo;0;L;;;;;N;;;;;
2762 0D87;SINHALA LETTER AEYANNA;Lo;0;L;;;;;N;;;;;
2763 0D88;SINHALA LETTER AEEYANNA;Lo;0;L;;;;;N;;;;;
2764 0D89;SINHALA LETTER IYANNA;Lo;0;L;;;;;N;;;;;
2765 0D8A;SINHALA LETTER IIYANNA;Lo;0;L;;;;;N;;;;;
2766 0D8B;SINHALA LETTER UYANNA;Lo;0;L;;;;;N;;;;;
2767 0D8C;SINHALA LETTER UUYANNA;Lo;0;L;;;;;N;;;;;
2768 0D8D;SINHALA LETTER IRUYANNA;Lo;0;L;;;;;N;;;;;
2769 0D8E;SINHALA LETTER IRUUYANNA;Lo;0;L;;;;;N;;;;;
2770 0D8F;SINHALA LETTER ILUYANNA;Lo;0;L;;;;;N;;;;;
2771 0D90;SINHALA LETTER ILUUYANNA;Lo;0;L;;;;;N;;;;;
2772 0D91;SINHALA LETTER EYANNA;Lo;0;L;;;;;N;;;;;
2773 0D92;SINHALA LETTER EEYANNA;Lo;0;L;;;;;N;;;;;
2774 0D93;SINHALA LETTER AIYANNA;Lo;0;L;;;;;N;;;;;
2775 0D94;SINHALA LETTER OYANNA;Lo;0;L;;;;;N;;;;;
2776 0D95;SINHALA LETTER OOYANNA;Lo;0;L;;;;;N;;;;;
2777 0D96;SINHALA LETTER AUYANNA;Lo;0;L;;;;;N;;;;;
2778 0D9A;SINHALA LETTER ALPAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;;
2779 0D9B;SINHALA LETTER MAHAAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;;
2780 0D9C;SINHALA LETTER ALPAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;;
2781 0D9D;SINHALA LETTER MAHAAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;;
2782 0D9E;SINHALA LETTER KANTAJA NAASIKYAYA;Lo;0;L;;;;;N;;;;;
2783 0D9F;SINHALA LETTER SANYAKA GAYANNA;Lo;0;L;;;;;N;;;;;
2784 0DA0;SINHALA LETTER ALPAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;;
2785 0DA1;SINHALA LETTER MAHAAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;;
2786 0DA2;SINHALA LETTER ALPAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;;
2787 0DA3;SINHALA LETTER MAHAAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;;
2788 0DA4;SINHALA LETTER TAALUJA NAASIKYAYA;Lo;0;L;;;;;N;;;;;
2789 0DA5;SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA;Lo;0;L;;;;;N;;;;;
2790 0DA6;SINHALA LETTER SANYAKA JAYANNA;Lo;0;L;;;;;N;;;;;
2791 0DA7;SINHALA LETTER ALPAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;;
2792 0DA8;SINHALA LETTER MAHAAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;;
2793 0DA9;SINHALA LETTER ALPAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;;
2794 0DAA;SINHALA LETTER MAHAAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;;
2795 0DAB;SINHALA LETTER MUURDHAJA NAYANNA;Lo;0;L;;;;;N;;;;;
2796 0DAC;SINHALA LETTER SANYAKA DDAYANNA;Lo;0;L;;;;;N;;;;;
2797 0DAD;SINHALA LETTER ALPAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;;
2798 0DAE;SINHALA LETTER MAHAAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;;
2799 0DAF;SINHALA LETTER ALPAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;;
2800 0DB0;SINHALA LETTER MAHAAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;;
2801 0DB1;SINHALA LETTER DANTAJA NAYANNA;Lo;0;L;;;;;N;;;;;
2802 0DB3;SINHALA LETTER SANYAKA DAYANNA;Lo;0;L;;;;;N;;;;;
2803 0DB4;SINHALA LETTER ALPAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;;
2804 0DB5;SINHALA LETTER MAHAAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;;
2805 0DB6;SINHALA LETTER ALPAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;;
2806 0DB7;SINHALA LETTER MAHAAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;;
2807 0DB8;SINHALA LETTER MAYANNA;Lo;0;L;;;;;N;;;;;
2808 0DB9;SINHALA LETTER AMBA BAYANNA;Lo;0;L;;;;;N;;;;;
2809 0DBA;SINHALA LETTER YAYANNA;Lo;0;L;;;;;N;;;;;
2810 0DBB;SINHALA LETTER RAYANNA;Lo;0;L;;;;;N;;;;;
2811 0DBD;SINHALA LETTER DANTAJA LAYANNA;Lo;0;L;;;;;N;;;;;
2812 0DC0;SINHALA LETTER VAYANNA;Lo;0;L;;;;;N;;;;;
2813 0DC1;SINHALA LETTER TAALUJA SAYANNA;Lo;0;L;;;;;N;;;;;
2814 0DC2;SINHALA LETTER MUURDHAJA SAYANNA;Lo;0;L;;;;;N;;;;;
2815 0DC3;SINHALA LETTER DANTAJA SAYANNA;Lo;0;L;;;;;N;;;;;
2816 0DC4;SINHALA LETTER HAYANNA;Lo;0;L;;;;;N;;;;;
2817 0DC5;SINHALA LETTER MUURDHAJA LAYANNA;Lo;0;L;;;;;N;;;;;
2818 0DC6;SINHALA LETTER FAYANNA;Lo;0;L;;;;;N;;;;;
2819 0DCA;SINHALA SIGN AL-LAKUNA;Mn;9;NSM;;;;;N;;;;;
2820 0DCF;SINHALA VOWEL SIGN AELA-PILLA;Mc;0;L;;;;;N;;;;;
2821 0DD0;SINHALA VOWEL SIGN KETTI AEDA-PILLA;Mc;0;L;;;;;N;;;;;
2822 0DD1;SINHALA VOWEL SIGN DIGA AEDA-PILLA;Mc;0;L;;;;;N;;;;;
2823 0DD2;SINHALA VOWEL SIGN KETTI IS-PILLA;Mn;0;NSM;;;;;N;;;;;
2824 0DD3;SINHALA VOWEL SIGN DIGA IS-PILLA;Mn;0;NSM;;;;;N;;;;;
2825 0DD4;SINHALA VOWEL SIGN KETTI PAA-PILLA;Mn;0;NSM;;;;;N;;;;;
2826 0DD6;SINHALA VOWEL SIGN DIGA PAA-PILLA;Mn;0;NSM;;;;;N;;;;;
2827 0DD8;SINHALA VOWEL SIGN GAETTA-PILLA;Mc;0;L;;;;;N;;;;;
2828 0DD9;SINHALA VOWEL SIGN KOMBUVA;Mc;0;L;;;;;N;;;;;
2829 0DDA;SINHALA VOWEL SIGN DIGA KOMBUVA;Mc;0;L;0DD9 0DCA;;;;N;;;;;
2830 0DDB;SINHALA VOWEL SIGN KOMBU DEKA;Mc;0;L;;;;;N;;;;;
2831 0DDC;SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA;Mc;0;L;0DD9 0DCF;;;;N;;;;;
2832 0DDD;SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA;Mc;0;L;0DDC 0DCA;;;;N;;;;;
2833 0DDE;SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA;Mc;0;L;0DD9 0DDF;;;;N;;;;;
2834 0DDF;SINHALA VOWEL SIGN GAYANUKITTA;Mc;0;L;;;;;N;;;;;
2835 0DF2;SINHALA VOWEL SIGN DIGA GAETTA-PILLA;Mc;0;L;;;;;N;;;;;
2836 0DF3;SINHALA VOWEL SIGN DIGA GAYANUKITTA;Mc;0;L;;;;;N;;;;;
2837 0DF4;SINHALA PUNCTUATION KUNDDALIYA;Po;0;L;;;;;N;;;;;
2838 0E01;THAI CHARACTER KO KAI;Lo;0;L;;;;;N;THAI LETTER KO KAI;;;;
2839 0E02;THAI CHARACTER KHO KHAI;Lo;0;L;;;;;N;THAI LETTER KHO KHAI;;;;
2840 0E03;THAI CHARACTER KHO KHUAT;Lo;0;L;;;;;N;THAI LETTER KHO KHUAT;;;;
2841 0E04;THAI CHARACTER KHO KHWAI;Lo;0;L;;;;;N;THAI LETTER KHO KHWAI;;;;
2842 0E05;THAI CHARACTER KHO KHON;Lo;0;L;;;;;N;THAI LETTER KHO KHON;;;;
2843 0E06;THAI CHARACTER KHO RAKHANG;Lo;0;L;;;;;N;THAI LETTER KHO RAKHANG;;;;
2844 0E07;THAI CHARACTER NGO NGU;Lo;0;L;;;;;N;THAI LETTER NGO NGU;;;;
2845 0E08;THAI CHARACTER CHO CHAN;Lo;0;L;;;;;N;THAI LETTER CHO CHAN;;;;
2846 0E09;THAI CHARACTER CHO CHING;Lo;0;L;;;;;N;THAI LETTER CHO CHING;;;;
2847 0E0A;THAI CHARACTER CHO CHANG;Lo;0;L;;;;;N;THAI LETTER CHO CHANG;;;;
2848 0E0B;THAI CHARACTER SO SO;Lo;0;L;;;;;N;THAI LETTER SO SO;;;;
2849 0E0C;THAI CHARACTER CHO CHOE;Lo;0;L;;;;;N;THAI LETTER CHO CHOE;;;;
2850 0E0D;THAI CHARACTER YO YING;Lo;0;L;;;;;N;THAI LETTER YO YING;;;;
2851 0E0E;THAI CHARACTER DO CHADA;Lo;0;L;;;;;N;THAI LETTER DO CHADA;;;;
2852 0E0F;THAI CHARACTER TO PATAK;Lo;0;L;;;;;N;THAI LETTER TO PATAK;;;;
2853 0E10;THAI CHARACTER THO THAN;Lo;0;L;;;;;N;THAI LETTER THO THAN;;;;
2854 0E11;THAI CHARACTER THO NANGMONTHO;Lo;0;L;;;;;N;THAI LETTER THO NANGMONTHO;;;;
2855 0E12;THAI CHARACTER THO PHUTHAO;Lo;0;L;;;;;N;THAI LETTER THO PHUTHAO;;;;
2856 0E13;THAI CHARACTER NO NEN;Lo;0;L;;;;;N;THAI LETTER NO NEN;;;;
2857 0E14;THAI CHARACTER DO DEK;Lo;0;L;;;;;N;THAI LETTER DO DEK;;;;
2858 0E15;THAI CHARACTER TO TAO;Lo;0;L;;;;;N;THAI LETTER TO TAO;;;;
2859 0E16;THAI CHARACTER THO THUNG;Lo;0;L;;;;;N;THAI LETTER THO THUNG;;;;
2860 0E17;THAI CHARACTER THO THAHAN;Lo;0;L;;;;;N;THAI LETTER THO THAHAN;;;;
2861 0E18;THAI CHARACTER THO THONG;Lo;0;L;;;;;N;THAI LETTER THO THONG;;;;
2862 0E19;THAI CHARACTER NO NU;Lo;0;L;;;;;N;THAI LETTER NO NU;;;;
2863 0E1A;THAI CHARACTER BO BAIMAI;Lo;0;L;;;;;N;THAI LETTER BO BAIMAI;;;;
2864 0E1B;THAI CHARACTER PO PLA;Lo;0;L;;;;;N;THAI LETTER PO PLA;;;;
2865 0E1C;THAI CHARACTER PHO PHUNG;Lo;0;L;;;;;N;THAI LETTER PHO PHUNG;;;;
2866 0E1D;THAI CHARACTER FO FA;Lo;0;L;;;;;N;THAI LETTER FO FA;;;;
2867 0E1E;THAI CHARACTER PHO PHAN;Lo;0;L;;;;;N;THAI LETTER PHO PHAN;;;;
2868 0E1F;THAI CHARACTER FO FAN;Lo;0;L;;;;;N;THAI LETTER FO FAN;;;;
2869 0E20;THAI CHARACTER PHO SAMPHAO;Lo;0;L;;;;;N;THAI LETTER PHO SAMPHAO;;;;
2870 0E21;THAI CHARACTER MO MA;Lo;0;L;;;;;N;THAI LETTER MO MA;;;;
2871 0E22;THAI CHARACTER YO YAK;Lo;0;L;;;;;N;THAI LETTER YO YAK;;;;
2872 0E23;THAI CHARACTER RO RUA;Lo;0;L;;;;;N;THAI LETTER RO RUA;;;;
2873 0E24;THAI CHARACTER RU;Lo;0;L;;;;;N;THAI LETTER RU;;;;
2874 0E25;THAI CHARACTER LO LING;Lo;0;L;;;;;N;THAI LETTER LO LING;;;;
2875 0E26;THAI CHARACTER LU;Lo;0;L;;;;;N;THAI LETTER LU;;;;
2876 0E27;THAI CHARACTER WO WAEN;Lo;0;L;;;;;N;THAI LETTER WO WAEN;;;;
2877 0E28;THAI CHARACTER SO SALA;Lo;0;L;;;;;N;THAI LETTER SO SALA;;;;
2878 0E29;THAI CHARACTER SO RUSI;Lo;0;L;;;;;N;THAI LETTER SO RUSI;;;;
2879 0E2A;THAI CHARACTER SO SUA;Lo;0;L;;;;;N;THAI LETTER SO SUA;;;;
2880 0E2B;THAI CHARACTER HO HIP;Lo;0;L;;;;;N;THAI LETTER HO HIP;;;;
2881 0E2C;THAI CHARACTER LO CHULA;Lo;0;L;;;;;N;THAI LETTER LO CHULA;;;;
2882 0E2D;THAI CHARACTER O ANG;Lo;0;L;;;;;N;THAI LETTER O ANG;;;;
2883 0E2E;THAI CHARACTER HO NOKHUK;Lo;0;L;;;;;N;THAI LETTER HO NOK HUK;;;;
2884 0E2F;THAI CHARACTER PAIYANNOI;Lo;0;L;;;;;N;THAI PAI YAN NOI;paiyan noi;;;
2885 0E30;THAI CHARACTER SARA A;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA A;;;;
2886 0E31;THAI CHARACTER MAI HAN-AKAT;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI HAN-AKAT;;;;
2887 0E32;THAI CHARACTER SARA AA;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AA;;;;
2888 0E33;THAI CHARACTER SARA AM;Lo;0;L;<compat> 0E4D 0E32;;;;N;THAI VOWEL SIGN SARA AM;;;;
2889 0E34;THAI CHARACTER SARA I;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA I;;;;
2890 0E35;THAI CHARACTER SARA II;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA II;;;;
2891 0E36;THAI CHARACTER SARA UE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UE;;;;
2892 0E37;THAI CHARACTER SARA UEE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UEE;sara uue;;;
2893 0E38;THAI CHARACTER SARA U;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA U;;;;
2894 0E39;THAI CHARACTER SARA UU;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA UU;;;;
2895 0E3A;THAI CHARACTER PHINTHU;Mn;9;NSM;;;;;N;THAI VOWEL SIGN PHINTHU;;;;
2896 0E3F;THAI CURRENCY SYMBOL BAHT;Sc;0;ET;;;;;N;THAI BAHT SIGN;;;;
2897 0E40;THAI CHARACTER SARA E;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA E;;;;
2898 0E41;THAI CHARACTER SARA AE;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AE;;;;
2899 0E42;THAI CHARACTER SARA O;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA O;;;;
2900 0E43;THAI CHARACTER SARA AI MAIMUAN;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MUAN;sara ai mai muan;;;
2901 0E44;THAI CHARACTER SARA AI MAIMALAI;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MALAI;sara ai mai malai;;;
2902 0E45;THAI CHARACTER LAKKHANGYAO;Lo;0;L;;;;;N;THAI LAK KHANG YAO;lakkhang yao;;;
2903 0E46;THAI CHARACTER MAIYAMOK;Lm;0;L;;;;;N;THAI MAI YAMOK;mai yamok;;;
2904 0E47;THAI CHARACTER MAITAIKHU;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI TAI KHU;mai taikhu;;;
2905 0E48;THAI CHARACTER MAI EK;Mn;107;NSM;;;;;N;THAI TONE MAI EK;;;;
2906 0E49;THAI CHARACTER MAI THO;Mn;107;NSM;;;;;N;THAI TONE MAI THO;;;;
2907 0E4A;THAI CHARACTER MAI TRI;Mn;107;NSM;;;;;N;THAI TONE MAI TRI;;;;
2908 0E4B;THAI CHARACTER MAI CHATTAWA;Mn;107;NSM;;;;;N;THAI TONE MAI CHATTAWA;;;;
2909 0E4C;THAI CHARACTER THANTHAKHAT;Mn;0;NSM;;;;;N;THAI THANTHAKHAT;;;;
2910 0E4D;THAI CHARACTER NIKHAHIT;Mn;0;NSM;;;;;N;THAI NIKKHAHIT;nikkhahit;;;
2911 0E4E;THAI CHARACTER YAMAKKAN;Mn;0;NSM;;;;;N;THAI YAMAKKAN;;;;
2912 0E4F;THAI CHARACTER FONGMAN;Po;0;L;;;;;N;THAI FONGMAN;;;;
2913 0E50;THAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
2914 0E51;THAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
2915 0E52;THAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
2916 0E53;THAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
2917 0E54;THAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
2918 0E55;THAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
2919 0E56;THAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
2920 0E57;THAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
2921 0E58;THAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
2922 0E59;THAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
2923 0E5A;THAI CHARACTER ANGKHANKHU;Po;0;L;;;;;N;THAI ANGKHANKHU;;;;
2924 0E5B;THAI CHARACTER KHOMUT;Po;0;L;;;;;N;THAI KHOMUT;;;;
2925 0E81;LAO LETTER KO;Lo;0;L;;;;;N;;;;;
2926 0E82;LAO LETTER KHO SUNG;Lo;0;L;;;;;N;;;;;
2927 0E84;LAO LETTER KHO TAM;Lo;0;L;;;;;N;;;;;
2928 0E87;LAO LETTER NGO;Lo;0;L;;;;;N;;;;;
2929 0E88;LAO LETTER CO;Lo;0;L;;;;;N;;;;;
2930 0E8A;LAO LETTER SO TAM;Lo;0;L;;;;;N;;;;;
2931 0E8D;LAO LETTER NYO;Lo;0;L;;;;;N;;;;;
2932 0E94;LAO LETTER DO;Lo;0;L;;;;;N;;;;;
2933 0E95;LAO LETTER TO;Lo;0;L;;;;;N;;;;;
2934 0E96;LAO LETTER THO SUNG;Lo;0;L;;;;;N;;;;;
2935 0E97;LAO LETTER THO TAM;Lo;0;L;;;;;N;;;;;
2936 0E99;LAO LETTER NO;Lo;0;L;;;;;N;;;;;
2937 0E9A;LAO LETTER BO;Lo;0;L;;;;;N;;;;;
2938 0E9B;LAO LETTER PO;Lo;0;L;;;;;N;;;;;
2939 0E9C;LAO LETTER PHO SUNG;Lo;0;L;;;;;N;;;;;
2940 0E9D;LAO LETTER FO TAM;Lo;0;L;;;;;N;;;;;
2941 0E9E;LAO LETTER PHO TAM;Lo;0;L;;;;;N;;;;;
2942 0E9F;LAO LETTER FO SUNG;Lo;0;L;;;;;N;;;;;
2943 0EA1;LAO LETTER MO;Lo;0;L;;;;;N;;;;;
2944 0EA2;LAO LETTER YO;Lo;0;L;;;;;N;;;;;
2945 0EA3;LAO LETTER LO LING;Lo;0;L;;;;;N;;;;;
2946 0EA5;LAO LETTER LO LOOT;Lo;0;L;;;;;N;;;;;
2947 0EA7;LAO LETTER WO;Lo;0;L;;;;;N;;;;;
2948 0EAA;LAO LETTER SO SUNG;Lo;0;L;;;;;N;;;;;
2949 0EAB;LAO LETTER HO SUNG;Lo;0;L;;;;;N;;;;;
2950 0EAD;LAO LETTER O;Lo;0;L;;;;;N;;;;;
2951 0EAE;LAO LETTER HO TAM;Lo;0;L;;;;;N;;;;;
2952 0EAF;LAO ELLIPSIS;Lo;0;L;;;;;N;;;;;
2953 0EB0;LAO VOWEL SIGN A;Lo;0;L;;;;;N;;;;;
2954 0EB1;LAO VOWEL SIGN MAI KAN;Mn;0;NSM;;;;;N;;;;;
2955 0EB2;LAO VOWEL SIGN AA;Lo;0;L;;;;;N;;;;;
2956 0EB3;LAO VOWEL SIGN AM;Lo;0;L;<compat> 0ECD 0EB2;;;;N;;;;;
2957 0EB4;LAO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
2958 0EB5;LAO VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
2959 0EB6;LAO VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;;
2960 0EB7;LAO VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;;
2961 0EB8;LAO VOWEL SIGN U;Mn;118;NSM;;;;;N;;;;;
2962 0EB9;LAO VOWEL SIGN UU;Mn;118;NSM;;;;;N;;;;;
2963 0EBB;LAO VOWEL SIGN MAI KON;Mn;0;NSM;;;;;N;;;;;
2964 0EBC;LAO SEMIVOWEL SIGN LO;Mn;0;NSM;;;;;N;;;;;
2965 0EBD;LAO SEMIVOWEL SIGN NYO;Lo;0;L;;;;;N;;;;;
2966 0EC0;LAO VOWEL SIGN E;Lo;0;L;;;;;N;;;;;
2967 0EC1;LAO VOWEL SIGN EI;Lo;0;L;;;;;N;;;;;
2968 0EC2;LAO VOWEL SIGN O;Lo;0;L;;;;;N;;;;;
2969 0EC3;LAO VOWEL SIGN AY;Lo;0;L;;;;;N;;;;;
2970 0EC4;LAO VOWEL SIGN AI;Lo;0;L;;;;;N;;;;;
2971 0EC6;LAO KO LA;Lm;0;L;;;;;N;;;;;
2972 0EC8;LAO TONE MAI EK;Mn;122;NSM;;;;;N;;;;;
2973 0EC9;LAO TONE MAI THO;Mn;122;NSM;;;;;N;;;;;
2974 0ECA;LAO TONE MAI TI;Mn;122;NSM;;;;;N;;;;;
2975 0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;;
2976 0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;;
2977 0ECD;LAO NIGGAHITA;Mn;0;NSM;;;;;N;;;;;
2978 0ED0;LAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
2979 0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
2980 0ED2;LAO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
2981 0ED3;LAO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
2982 0ED4;LAO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
2983 0ED5;LAO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
2984 0ED6;LAO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
2985 0ED7;LAO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
2986 0ED8;LAO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
2987 0ED9;LAO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
2988 0EDC;LAO HO NO;Lo;0;L;<compat> 0EAB 0E99;;;;N;;;;;
2989 0EDD;LAO HO MO;Lo;0;L;<compat> 0EAB 0EA1;;;;N;;;;;
2990 0F00;TIBETAN SYLLABLE OM;Lo;0;L;;;;;N;;;;;
2991 0F01;TIBETAN MARK GTER YIG MGO TRUNCATED A;So;0;L;;;;;N;;ter yik go a thung;;;
2992 0F02;TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA;So;0;L;;;;;N;;ter yik go wum nam chey ma;;;
2993 0F03;TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA;So;0;L;;;;;N;;ter yik go wum ter tsek ma;;;
2994 0F04;TIBETAN MARK INITIAL YIG MGO MDUN MA;Po;0;L;;;;;N;TIBETAN SINGLE ORNAMENT;yik go dun ma;;;
2995 0F05;TIBETAN MARK CLOSING YIG MGO SGAB MA;Po;0;L;;;;;N;;yik go kab ma;;;
2996 0F06;TIBETAN MARK CARET YIG MGO PHUR SHAD MA;Po;0;L;;;;;N;;yik go pur shey ma;;;
2997 0F07;TIBETAN MARK YIG MGO TSHEG SHAD MA;Po;0;L;;;;;N;;yik go tsek shey ma;;;
2998 0F08;TIBETAN MARK SBRUL SHAD;Po;0;L;;;;;N;TIBETAN RGYANSHAD;drul shey;;;
2999 0F09;TIBETAN MARK BSKUR YIG MGO;Po;0;L;;;;;N;;kur yik go;;;
3000 0F0A;TIBETAN MARK BKA- SHOG YIG MGO;Po;0;L;;;;;N;;ka sho yik go;;;
3001 0F0B;TIBETAN MARK INTERSYLLABIC TSHEG;Po;0;L;;;;;N;TIBETAN TSEG;tsek;;;
3002 0F0C;TIBETAN MARK DELIMITER TSHEG BSTAR;Po;0;L;<noBreak> 0F0B;;;;N;;tsek tar;;;
3003 0F0D;TIBETAN MARK SHAD;Po;0;L;;;;;N;TIBETAN SHAD;shey;;;
3004 0F0E;TIBETAN MARK NYIS SHAD;Po;0;L;;;;;N;TIBETAN DOUBLE SHAD;nyi shey;;;
3005 0F0F;TIBETAN MARK TSHEG SHAD;Po;0;L;;;;;N;;tsek shey;;;
3006 0F10;TIBETAN MARK NYIS TSHEG SHAD;Po;0;L;;;;;N;;nyi tsek shey;;;
3007 0F11;TIBETAN MARK RIN CHEN SPUNGS SHAD;Po;0;L;;;;;N;TIBETAN RINCHANPHUNGSHAD;rinchen pung shey;;;
3008 0F12;TIBETAN MARK RGYA GRAM SHAD;Po;0;L;;;;;N;;gya tram shey;;;
3009 0F13;TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN;So;0;L;;;;;N;;dzu ta me long chen;;;
3010 0F14;TIBETAN MARK GTER TSHEG;So;0;L;;;;;N;TIBETAN COMMA;ter tsek;;;
3011 0F15;TIBETAN LOGOTYPE SIGN CHAD RTAGS;So;0;L;;;;;N;;che ta;;;
3012 0F16;TIBETAN LOGOTYPE SIGN LHAG RTAGS;So;0;L;;;;;N;;hlak ta;;;
3013 0F17;TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS;So;0;L;;;;;N;;trachen char ta;;;
3014 0F18;TIBETAN ASTROLOGICAL SIGN -KHYUD PA;Mn;220;NSM;;;;;N;;kyu pa;;;
3015 0F19;TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS;Mn;220;NSM;;;;;N;;dong tsu;;;
3016 0F1A;TIBETAN SIGN RDEL DKAR GCIG;So;0;L;;;;;N;;deka chig;;;
3017 0F1B;TIBETAN SIGN RDEL DKAR GNYIS;So;0;L;;;;;N;;deka nyi;;;
3018 0F1C;TIBETAN SIGN RDEL DKAR GSUM;So;0;L;;;;;N;;deka sum;;;
3019 0F1D;TIBETAN SIGN RDEL NAG GCIG;So;0;L;;;;;N;;dena chig;;;
3020 0F1E;TIBETAN SIGN RDEL NAG GNYIS;So;0;L;;;;;N;;dena nyi;;;
3021 0F1F;TIBETAN SIGN RDEL DKAR RDEL NAG;So;0;L;;;;;N;;deka dena;;;
3022 0F20;TIBETAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
3023 0F21;TIBETAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
3024 0F22;TIBETAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
3025 0F23;TIBETAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
3026 0F24;TIBETAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
3027 0F25;TIBETAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
3028 0F26;TIBETAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
3029 0F27;TIBETAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
3030 0F28;TIBETAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
3031 0F29;TIBETAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
3032 0F2A;TIBETAN DIGIT HALF ONE;No;0;L;;;;1/2;N;;;;;
3033 0F2B;TIBETAN DIGIT HALF TWO;No;0;L;;;;3/2;N;;;;;
3034 0F2C;TIBETAN DIGIT HALF THREE;No;0;L;;;;5/2;N;;;;;
3035 0F2D;TIBETAN DIGIT HALF FOUR;No;0;L;;;;7/2;N;;;;;
3036 0F2E;TIBETAN DIGIT HALF FIVE;No;0;L;;;;9/2;N;;;;;
3037 0F2F;TIBETAN DIGIT HALF SIX;No;0;L;;;;11/2;N;;;;;
3038 0F30;TIBETAN DIGIT HALF SEVEN;No;0;L;;;;13/2;N;;;;;
3039 0F31;TIBETAN DIGIT HALF EIGHT;No;0;L;;;;15/2;N;;;;;
3040 0F32;TIBETAN DIGIT HALF NINE;No;0;L;;;;17/2;N;;;;;
3041 0F33;TIBETAN DIGIT HALF ZERO;No;0;L;;;;-1/2;N;;;;;
3042 0F34;TIBETAN MARK BSDUS RTAGS;So;0;L;;;;;N;;du ta;;;
3043 0F35;TIBETAN MARK NGAS BZUNG NYI ZLA;Mn;220;NSM;;;;;N;TIBETAN HONORIFIC UNDER RING;nge zung nyi da;;;
3044 0F36;TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN;So;0;L;;;;;N;;dzu ta shi mig chen;;;
3045 0F37;TIBETAN MARK NGAS BZUNG SGOR RTAGS;Mn;220;NSM;;;;;N;TIBETAN UNDER RING;nge zung gor ta;;;
3046 0F38;TIBETAN MARK CHE MGO;So;0;L;;;;;N;;che go;;;
3047 0F39;TIBETAN MARK TSA -PHRU;Mn;216;NSM;;;;;N;TIBETAN LENITION MARK;tsa tru;;;
3048 0F3A;TIBETAN MARK GUG RTAGS GYON;Ps;0;ON;;;;;Y;;gug ta yun;;;
3049 0F3B;TIBETAN MARK GUG RTAGS GYAS;Pe;0;ON;;;;;Y;;gug ta ye;;;
3050 0F3C;TIBETAN MARK ANG KHANG GYON;Ps;0;ON;;;;;Y;TIBETAN LEFT BRACE;ang kang yun;;;
3051 0F3D;TIBETAN MARK ANG KHANG GYAS;Pe;0;ON;;;;;Y;TIBETAN RIGHT BRACE;ang kang ye;;;
3052 0F3E;TIBETAN SIGN YAR TSHES;Mc;0;L;;;;;N;;yar tse;;;
3053 0F3F;TIBETAN SIGN MAR TSHES;Mc;0;L;;;;;N;;mar tse;;;
3054 0F40;TIBETAN LETTER KA;Lo;0;L;;;;;N;;;;;
3055 0F41;TIBETAN LETTER KHA;Lo;0;L;;;;;N;;;;;
3056 0F42;TIBETAN LETTER GA;Lo;0;L;;;;;N;;;;;
3057 0F43;TIBETAN LETTER GHA;Lo;0;L;0F42 0FB7;;;;N;;;;;
3058 0F44;TIBETAN LETTER NGA;Lo;0;L;;;;;N;;;;;
3059 0F45;TIBETAN LETTER CA;Lo;0;L;;;;;N;;;;;
3060 0F46;TIBETAN LETTER CHA;Lo;0;L;;;;;N;;;;;
3061 0F47;TIBETAN LETTER JA;Lo;0;L;;;;;N;;;;;
3062 0F49;TIBETAN LETTER NYA;Lo;0;L;;;;;N;;;;;
3063 0F4A;TIBETAN LETTER TTA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED TA;;;;
3064 0F4B;TIBETAN LETTER TTHA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED THA;;;;
3065 0F4C;TIBETAN LETTER DDA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED DA;;;;
3066 0F4D;TIBETAN LETTER DDHA;Lo;0;L;0F4C 0FB7;;;;N;;;;;
3067 0F4E;TIBETAN LETTER NNA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED NA;;;;
3068 0F4F;TIBETAN LETTER TA;Lo;0;L;;;;;N;;;;;
3069 0F50;TIBETAN LETTER THA;Lo;0;L;;;;;N;;;;;
3070 0F51;TIBETAN LETTER DA;Lo;0;L;;;;;N;;;;;
3071 0F52;TIBETAN LETTER DHA;Lo;0;L;0F51 0FB7;;;;N;;;;;
3072 0F53;TIBETAN LETTER NA;Lo;0;L;;;;;N;;;;;
3073 0F54;TIBETAN LETTER PA;Lo;0;L;;;;;N;;;;;
3074 0F55;TIBETAN LETTER PHA;Lo;0;L;;;;;N;;;;;
3075 0F56;TIBETAN LETTER BA;Lo;0;L;;;;;N;;;;;
3076 0F57;TIBETAN LETTER BHA;Lo;0;L;0F56 0FB7;;;;N;;;;;
3077 0F58;TIBETAN LETTER MA;Lo;0;L;;;;;N;;;;;
3078 0F59;TIBETAN LETTER TSA;Lo;0;L;;;;;N;;;;;
3079 0F5A;TIBETAN LETTER TSHA;Lo;0;L;;;;;N;;;;;
3080 0F5B;TIBETAN LETTER DZA;Lo;0;L;;;;;N;;;;;
3081 0F5C;TIBETAN LETTER DZHA;Lo;0;L;0F5B 0FB7;;;;N;;;;;
3082 0F5D;TIBETAN LETTER WA;Lo;0;L;;;;;N;;;;;
3083 0F5E;TIBETAN LETTER ZHA;Lo;0;L;;;;;N;;;;;
3084 0F5F;TIBETAN LETTER ZA;Lo;0;L;;;;;N;;;;;
3085 0F60;TIBETAN LETTER -A;Lo;0;L;;;;;N;TIBETAN LETTER AA;;;;
3086 0F61;TIBETAN LETTER YA;Lo;0;L;;;;;N;;;;;
3087 0F62;TIBETAN LETTER RA;Lo;0;L;;;;;N;;*;;;
3088 0F63;TIBETAN LETTER LA;Lo;0;L;;;;;N;;;;;
3089 0F64;TIBETAN LETTER SHA;Lo;0;L;;;;;N;;;;;
3090 0F65;TIBETAN LETTER SSA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED SHA;;;;
3091 0F66;TIBETAN LETTER SA;Lo;0;L;;;;;N;;;;;
3092 0F67;TIBETAN LETTER HA;Lo;0;L;;;;;N;;;;;
3093 0F68;TIBETAN LETTER A;Lo;0;L;;;;;N;;;;;
3094 0F69;TIBETAN LETTER KSSA;Lo;0;L;0F40 0FB5;;;;N;;;;;
3095 0F6A;TIBETAN LETTER FIXED-FORM RA;Lo;0;L;;;;;N;;*;;;
3096 0F6B;TIBETAN LETTER KKA;Lo;0;L;;;;;N;;;;;
3097 0F6C;TIBETAN LETTER RRA;Lo;0;L;;;;;N;;;;;
3098 0F71;TIBETAN VOWEL SIGN AA;Mn;129;NSM;;;;;N;;;;;
3099 0F72;TIBETAN VOWEL SIGN I;Mn;130;NSM;;;;;N;;;;;
3100 0F73;TIBETAN VOWEL SIGN II;Mn;0;NSM;0F71 0F72;;;;N;;;;;
3101 0F74;TIBETAN VOWEL SIGN U;Mn;132;NSM;;;;;N;;;;;
3102 0F75;TIBETAN VOWEL SIGN UU;Mn;0;NSM;0F71 0F74;;;;N;;;;;
3103 0F76;TIBETAN VOWEL SIGN VOCALIC R;Mn;0;NSM;0FB2 0F80;;;;N;;;;;
3104 0F77;TIBETAN VOWEL SIGN VOCALIC RR;Mn;0;NSM;<compat> 0FB2 0F81;;;;N;;;;;
3105 0F78;TIBETAN VOWEL SIGN VOCALIC L;Mn;0;NSM;0FB3 0F80;;;;N;;;;;
3106 0F79;TIBETAN VOWEL SIGN VOCALIC LL;Mn;0;NSM;<compat> 0FB3 0F81;;;;N;;;;;
3107 0F7A;TIBETAN VOWEL SIGN E;Mn;130;NSM;;;;;N;;;;;
3108 0F7B;TIBETAN VOWEL SIGN EE;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AI;;;;
3109 0F7C;TIBETAN VOWEL SIGN O;Mn;130;NSM;;;;;N;;;;;
3110 0F7D;TIBETAN VOWEL SIGN OO;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AU;;;;
3111 0F7E;TIBETAN SIGN RJES SU NGA RO;Mn;0;NSM;;;;;N;TIBETAN ANUSVARA;je su nga ro;;;
3112 0F7F;TIBETAN SIGN RNAM BCAD;Mc;0;L;;;;;N;TIBETAN VISARGA;nam chey;;;
3113 0F80;TIBETAN VOWEL SIGN REVERSED I;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN SHORT I;;;;
3114 0F81;TIBETAN VOWEL SIGN REVERSED II;Mn;0;NSM;0F71 0F80;;;;N;;;;;
3115 0F82;TIBETAN SIGN NYI ZLA NAA DA;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU WITH ORNAMENT;nyi da na da;;;
3116 0F83;TIBETAN SIGN SNA LDAN;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU;nan de;;;
3117 0F84;TIBETAN MARK HALANTA;Mn;9;NSM;;;;;N;TIBETAN VIRAMA;;;;
3118 0F85;TIBETAN MARK PALUTA;Po;0;L;;;;;N;TIBETAN CHUCHENYIGE;;;;
3119 0F86;TIBETAN SIGN LCI RTAGS;Mn;230;NSM;;;;;N;;ji ta;;;
3120 0F87;TIBETAN SIGN YANG RTAGS;Mn;230;NSM;;;;;N;;yang ta;;;
3121 0F88;TIBETAN SIGN LCE TSA CAN;Lo;0;L;;;;;N;;che tsa chen;;;
3122 0F89;TIBETAN SIGN MCHU CAN;Lo;0;L;;;;;N;;chu chen;;;
3123 0F8A;TIBETAN SIGN GRU CAN RGYINGS;Lo;0;L;;;;;N;;tru chen ging;;;
3124 0F8B;TIBETAN SIGN GRU MED RGYINGS;Lo;0;L;;;;;N;;tru me ging;;;
3125 0F90;TIBETAN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;;
3126 0F91;TIBETAN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;;
3127 0F92;TIBETAN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;;
3128 0F93;TIBETAN SUBJOINED LETTER GHA;Mn;0;NSM;0F92 0FB7;;;;N;;;;;
3129 0F94;TIBETAN SUBJOINED LETTER NGA;Mn;0;NSM;;;;;N;;;;;
3130 0F95;TIBETAN SUBJOINED LETTER CA;Mn;0;NSM;;;;;N;;;;;
3131 0F96;TIBETAN SUBJOINED LETTER CHA;Mn;0;NSM;;;;;N;;;;;
3132 0F97;TIBETAN SUBJOINED LETTER JA;Mn;0;NSM;;;;;N;;;;;
3133 0F99;TIBETAN SUBJOINED LETTER NYA;Mn;0;NSM;;;;;N;;;;;
3134 0F9A;TIBETAN SUBJOINED LETTER TTA;Mn;0;NSM;;;;;N;;;;;
3135 0F9B;TIBETAN SUBJOINED LETTER TTHA;Mn;0;NSM;;;;;N;;;;;
3136 0F9C;TIBETAN SUBJOINED LETTER DDA;Mn;0;NSM;;;;;N;;;;;
3137 0F9D;TIBETAN SUBJOINED LETTER DDHA;Mn;0;NSM;0F9C 0FB7;;;;N;;;;;
3138 0F9E;TIBETAN SUBJOINED LETTER NNA;Mn;0;NSM;;;;;N;;;;;
3139 0F9F;TIBETAN SUBJOINED LETTER TA;Mn;0;NSM;;;;;N;;;;;
3140 0FA0;TIBETAN SUBJOINED LETTER THA;Mn;0;NSM;;;;;N;;;;;
3141 0FA1;TIBETAN SUBJOINED LETTER DA;Mn;0;NSM;;;;;N;;;;;
3142 0FA2;TIBETAN SUBJOINED LETTER DHA;Mn;0;NSM;0FA1 0FB7;;;;N;;;;;
3143 0FA3;TIBETAN SUBJOINED LETTER NA;Mn;0;NSM;;;;;N;;;;;
3144 0FA4;TIBETAN SUBJOINED LETTER PA;Mn;0;NSM;;;;;N;;;;;
3145 0FA5;TIBETAN SUBJOINED LETTER PHA;Mn;0;NSM;;;;;N;;;;;
3146 0FA6;TIBETAN SUBJOINED LETTER BA;Mn;0;NSM;;;;;N;;;;;
3147 0FA7;TIBETAN SUBJOINED LETTER BHA;Mn;0;NSM;0FA6 0FB7;;;;N;;;;;
3148 0FA8;TIBETAN SUBJOINED LETTER MA;Mn;0;NSM;;;;;N;;;;;
3149 0FA9;TIBETAN SUBJOINED LETTER TSA;Mn;0;NSM;;;;;N;;;;;
3150 0FAA;TIBETAN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;;
3151 0FAB;TIBETAN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;;
3152 0FAC;TIBETAN SUBJOINED LETTER DZHA;Mn;0;NSM;0FAB 0FB7;;;;N;;;;;
3153 0FAD;TIBETAN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;*;;;
3154 0FAE;TIBETAN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;;
3155 0FAF;TIBETAN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;;
3156 0FB0;TIBETAN SUBJOINED LETTER -A;Mn;0;NSM;;;;;N;;;;;
3157 0FB1;TIBETAN SUBJOINED LETTER YA;Mn;0;NSM;;;;;N;;*;;;
3158 0FB2;TIBETAN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;*;;;
3159 0FB3;TIBETAN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;;
3160 0FB4;TIBETAN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;;
3161 0FB5;TIBETAN SUBJOINED LETTER SSA;Mn;0;NSM;;;;;N;;;;;
3162 0FB6;TIBETAN SUBJOINED LETTER SA;Mn;0;NSM;;;;;N;;;;;
3163 0FB7;TIBETAN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;;
3164 0FB8;TIBETAN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;;
3165 0FB9;TIBETAN SUBJOINED LETTER KSSA;Mn;0;NSM;0F90 0FB5;;;;N;;;;;
3166 0FBA;TIBETAN SUBJOINED LETTER FIXED-FORM WA;Mn;0;NSM;;;;;N;;*;;;
3167 0FBB;TIBETAN SUBJOINED LETTER FIXED-FORM YA;Mn;0;NSM;;;;;N;;*;;;
3168 0FBC;TIBETAN SUBJOINED LETTER FIXED-FORM RA;Mn;0;NSM;;;;;N;;*;;;
3169 0FBE;TIBETAN KU RU KHA;So;0;L;;;;;N;;kuruka;;;
3170 0FBF;TIBETAN KU RU KHA BZHI MIG CAN;So;0;L;;;;;N;;kuruka shi mik chen;;;
3171 0FC0;TIBETAN CANTILLATION SIGN HEAVY BEAT;So;0;L;;;;;N;;;;;
3172 0FC1;TIBETAN CANTILLATION SIGN LIGHT BEAT;So;0;L;;;;;N;;;;;
3173 0FC2;TIBETAN CANTILLATION SIGN CANG TE-U;So;0;L;;;;;N;;chang tyu;;;
3174 0FC3;TIBETAN CANTILLATION SIGN SBUB -CHAL;So;0;L;;;;;N;;bub chey;;;
3175 0FC4;TIBETAN SYMBOL DRIL BU;So;0;L;;;;;N;;drilbu;;;
3176 0FC5;TIBETAN SYMBOL RDO RJE;So;0;L;;;;;N;;dorje;;;
3177 0FC6;TIBETAN SYMBOL PADMA GDAN;Mn;220;NSM;;;;;N;;pema den;;;
3178 0FC7;TIBETAN SYMBOL RDO RJE RGYA GRAM;So;0;L;;;;;N;;dorje gya dram;;;
3179 0FC8;TIBETAN SYMBOL PHUR PA;So;0;L;;;;;N;;phurba;;;
3180 0FC9;TIBETAN SYMBOL NOR BU;So;0;L;;;;;N;;norbu;;;
3181 0FCA;TIBETAN SYMBOL NOR BU NYIS -KHYIL;So;0;L;;;;;N;;norbu nyi khyi;;;
3182 0FCB;TIBETAN SYMBOL NOR BU GSUM -KHYIL;So;0;L;;;;;N;;norbu sum khyi;;;
3183 0FCC;TIBETAN SYMBOL NOR BU BZHI -KHYIL;So;0;L;;;;;N;;norbu shi khyi;;;
3184 0FCE;TIBETAN SIGN RDEL NAG RDEL DKAR;So;0;L;;;;;N;;dena deka;;;
3185 0FCF;TIBETAN SIGN RDEL NAG GSUM;So;0;L;;;;;N;;dena sum;;;
3186 0FD0;TIBETAN MARK BSKA- SHOG GI MGO RGYAN;Po;0;L;;;;;N;;ka shog gi go gyen;;;
3187 0FD1;TIBETAN MARK MNYAM YIG GI MGO RGYAN;Po;0;L;;;;;N;;nyam yig gi go gyen;;;
3188 0FD2;TIBETAN MARK NYIS TSHEG;Po;0;L;;;;;N;;nyi tsek;;;
3189 0FD3;TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA;Po;0;L;;;;;N;;da nying yik go dun ma;;;
3190 0FD4;TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA;Po;0;L;;;;;N;;da nying yik go kab ma;;;
3191 1000;MYANMAR LETTER KA;Lo;0;L;;;;;N;;;;;
3192 1001;MYANMAR LETTER KHA;Lo;0;L;;;;;N;;;;;
3193 1002;MYANMAR LETTER GA;Lo;0;L;;;;;N;;;;;
3194 1003;MYANMAR LETTER GHA;Lo;0;L;;;;;N;;;;;
3195 1004;MYANMAR LETTER NGA;Lo;0;L;;;;;N;;;;;
3196 1005;MYANMAR LETTER CA;Lo;0;L;;;;;N;;;;;
3197 1006;MYANMAR LETTER CHA;Lo;0;L;;;;;N;;;;;
3198 1007;MYANMAR LETTER JA;Lo;0;L;;;;;N;;;;;
3199 1008;MYANMAR LETTER JHA;Lo;0;L;;;;;N;;;;;
3200 1009;MYANMAR LETTER NYA;Lo;0;L;;;;;N;;;;;
3201 100A;MYANMAR LETTER NNYA;Lo;0;L;;;;;N;;;;;
3202 100B;MYANMAR LETTER TTA;Lo;0;L;;;;;N;;;;;
3203 100C;MYANMAR LETTER TTHA;Lo;0;L;;;;;N;;;;;
3204 100D;MYANMAR LETTER DDA;Lo;0;L;;;;;N;;;;;
3205 100E;MYANMAR LETTER DDHA;Lo;0;L;;;;;N;;;;;
3206 100F;MYANMAR LETTER NNA;Lo;0;L;;;;;N;;;;;
3207 1010;MYANMAR LETTER TA;Lo;0;L;;;;;N;;;;;
3208 1011;MYANMAR LETTER THA;Lo;0;L;;;;;N;;;;;
3209 1012;MYANMAR LETTER DA;Lo;0;L;;;;;N;;;;;
3210 1013;MYANMAR LETTER DHA;Lo;0;L;;;;;N;;;;;
3211 1014;MYANMAR LETTER NA;Lo;0;L;;;;;N;;;;;
3212 1015;MYANMAR LETTER PA;Lo;0;L;;;;;N;;;;;
3213 1016;MYANMAR LETTER PHA;Lo;0;L;;;;;N;;;;;
3214 1017;MYANMAR LETTER BA;Lo;0;L;;;;;N;;;;;
3215 1018;MYANMAR LETTER BHA;Lo;0;L;;;;;N;;;;;
3216 1019;MYANMAR LETTER MA;Lo;0;L;;;;;N;;;;;
3217 101A;MYANMAR LETTER YA;Lo;0;L;;;;;N;;;;;
3218 101B;MYANMAR LETTER RA;Lo;0;L;;;;;N;;;;;
3219 101C;MYANMAR LETTER LA;Lo;0;L;;;;;N;;;;;
3220 101D;MYANMAR LETTER WA;Lo;0;L;;;;;N;;;;;
3221 101E;MYANMAR LETTER SA;Lo;0;L;;;;;N;;;;;
3222 101F;MYANMAR LETTER HA;Lo;0;L;;;;;N;;;;;
3223 1020;MYANMAR LETTER LLA;Lo;0;L;;;;;N;;;;;
3224 1021;MYANMAR LETTER A;Lo;0;L;;;;;N;;;;;
3225 1022;MYANMAR LETTER SHAN A;Lo;0;L;;;;;N;;;;;
3226 1023;MYANMAR LETTER I;Lo;0;L;;;;;N;;;;;
3227 1024;MYANMAR LETTER II;Lo;0;L;;;;;N;;;;;
3228 1025;MYANMAR LETTER U;Lo;0;L;;;;;N;;;;;
3229 1026;MYANMAR LETTER UU;Lo;0;L;1025 102E;;;;N;;;;;
3230 1027;MYANMAR LETTER E;Lo;0;L;;;;;N;;;;;
3231 1028;MYANMAR LETTER MON E;Lo;0;L;;;;;N;;;;;
3232 1029;MYANMAR LETTER O;Lo;0;L;;;;;N;;;;;
3233 102A;MYANMAR LETTER AU;Lo;0;L;;;;;N;;;;;
3234 102B;MYANMAR VOWEL SIGN TALL AA;Mc;0;L;;;;;N;;;;;
3235 102C;MYANMAR VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
3236 102D;MYANMAR VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
3237 102E;MYANMAR VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
3238 102F;MYANMAR VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
3239 1030;MYANMAR VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
3240 1031;MYANMAR VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
3241 1032;MYANMAR VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
3242 1033;MYANMAR VOWEL SIGN MON II;Mn;0;NSM;;;;;N;;;;;
3243 1034;MYANMAR VOWEL SIGN MON O;Mn;0;NSM;;;;;N;;;;;
3244 1035;MYANMAR VOWEL SIGN E ABOVE;Mn;0;NSM;;;;;N;;;;;
3245 1036;MYANMAR SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
3246 1037;MYANMAR SIGN DOT BELOW;Mn;7;NSM;;;;;N;;;;;
3247 1038;MYANMAR SIGN VISARGA;Mc;0;L;;;;;N;;;;;
3248 1039;MYANMAR SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
3249 103A;MYANMAR SIGN ASAT;Mn;9;NSM;;;;;N;;;;;
3250 103B;MYANMAR CONSONANT SIGN MEDIAL YA;Mc;0;L;;;;;N;;;;;
3251 103C;MYANMAR CONSONANT SIGN MEDIAL RA;Mc;0;L;;;;;N;;;;;
3252 103D;MYANMAR CONSONANT SIGN MEDIAL WA;Mn;0;NSM;;;;;N;;;;;
3253 103E;MYANMAR CONSONANT SIGN MEDIAL HA;Mn;0;NSM;;;;;N;;;;;
3254 103F;MYANMAR LETTER GREAT SA;Lo;0;L;;;;;N;;;;;
3255 1040;MYANMAR DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
3256 1041;MYANMAR DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
3257 1042;MYANMAR DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
3258 1043;MYANMAR DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
3259 1044;MYANMAR DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
3260 1045;MYANMAR DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
3261 1046;MYANMAR DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
3262 1047;MYANMAR DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
3263 1048;MYANMAR DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
3264 1049;MYANMAR DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
3265 104A;MYANMAR SIGN LITTLE SECTION;Po;0;L;;;;;N;;;;;
3266 104B;MYANMAR SIGN SECTION;Po;0;L;;;;;N;;;;;
3267 104C;MYANMAR SYMBOL LOCATIVE;Po;0;L;;;;;N;;;;;
3268 104D;MYANMAR SYMBOL COMPLETED;Po;0;L;;;;;N;;;;;
3269 104E;MYANMAR SYMBOL AFOREMENTIONED;Po;0;L;;;;;N;;;;;
3270 104F;MYANMAR SYMBOL GENITIVE;Po;0;L;;;;;N;;;;;
3271 1050;MYANMAR LETTER SHA;Lo;0;L;;;;;N;;;;;
3272 1051;MYANMAR LETTER SSA;Lo;0;L;;;;;N;;;;;
3273 1052;MYANMAR LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
3274 1053;MYANMAR LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
3275 1054;MYANMAR LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
3276 1055;MYANMAR LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
3277 1056;MYANMAR VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
3278 1057;MYANMAR VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
3279 1058;MYANMAR VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;
3280 1059;MYANMAR VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;
3281 105A;MYANMAR LETTER MON NGA;Lo;0;L;;;;;N;;;;;
3282 105B;MYANMAR LETTER MON JHA;Lo;0;L;;;;;N;;;;;
3283 105C;MYANMAR LETTER MON BBA;Lo;0;L;;;;;N;;;;;
3284 105D;MYANMAR LETTER MON BBE;Lo;0;L;;;;;N;;;;;
3285 105E;MYANMAR CONSONANT SIGN MON MEDIAL NA;Mn;0;NSM;;;;;N;;;;;
3286 105F;MYANMAR CONSONANT SIGN MON MEDIAL MA;Mn;0;NSM;;;;;N;;;;;
3287 1060;MYANMAR CONSONANT SIGN MON MEDIAL LA;Mn;0;NSM;;;;;N;;;;;
3288 1061;MYANMAR LETTER SGAW KAREN SHA;Lo;0;L;;;;;N;;;;;
3289 1062;MYANMAR VOWEL SIGN SGAW KAREN EU;Mc;0;L;;;;;N;;;;;
3290 1063;MYANMAR TONE MARK SGAW KAREN HATHI;Mc;0;L;;;;;N;;;;;
3291 1064;MYANMAR TONE MARK SGAW KAREN KE PHO;Mc;0;L;;;;;N;;;;;
3292 1065;MYANMAR LETTER WESTERN PWO KAREN THA;Lo;0;L;;;;;N;;;;;
3293 1066;MYANMAR LETTER WESTERN PWO KAREN PWA;Lo;0;L;;;;;N;;;;;
3294 1067;MYANMAR VOWEL SIGN WESTERN PWO KAREN EU;Mc;0;L;;;;;N;;;;;
3295 1068;MYANMAR VOWEL SIGN WESTERN PWO KAREN UE;Mc;0;L;;;;;N;;;;;
3296 1069;MYANMAR SIGN WESTERN PWO KAREN TONE-1;Mc;0;L;;;;;N;;;;;
3297 106A;MYANMAR SIGN WESTERN PWO KAREN TONE-2;Mc;0;L;;;;;N;;;;;
3298 106B;MYANMAR SIGN WESTERN PWO KAREN TONE-3;Mc;0;L;;;;;N;;;;;
3299 106C;MYANMAR SIGN WESTERN PWO KAREN TONE-4;Mc;0;L;;;;;N;;;;;
3300 106D;MYANMAR SIGN WESTERN PWO KAREN TONE-5;Mc;0;L;;;;;N;;;;;
3301 106E;MYANMAR LETTER EASTERN PWO KAREN NNA;Lo;0;L;;;;;N;;;;;
3302 106F;MYANMAR LETTER EASTERN PWO KAREN YWA;Lo;0;L;;;;;N;;;;;
3303 1070;MYANMAR LETTER EASTERN PWO KAREN GHWA;Lo;0;L;;;;;N;;;;;
3304 1071;MYANMAR VOWEL SIGN GEBA KAREN I;Mn;0;NSM;;;;;N;;;;;
3305 1072;MYANMAR VOWEL SIGN KAYAH OE;Mn;0;NSM;;;;;N;;;;;
3306 1073;MYANMAR VOWEL SIGN KAYAH U;Mn;0;NSM;;;;;N;;;;;
3307 1074;MYANMAR VOWEL SIGN KAYAH EE;Mn;0;NSM;;;;;N;;;;;
3308 1075;MYANMAR LETTER SHAN KA;Lo;0;L;;;;;N;;;;;
3309 1076;MYANMAR LETTER SHAN KHA;Lo;0;L;;;;;N;;;;;
3310 1077;MYANMAR LETTER SHAN GA;Lo;0;L;;;;;N;;;;;
3311 1078;MYANMAR LETTER SHAN CA;Lo;0;L;;;;;N;;;;;
3312 1079;MYANMAR LETTER SHAN ZA;Lo;0;L;;;;;N;;;;;
3313 107A;MYANMAR LETTER SHAN NYA;Lo;0;L;;;;;N;;;;;
3314 107B;MYANMAR LETTER SHAN DA;Lo;0;L;;;;;N;;;;;
3315 107C;MYANMAR LETTER SHAN NA;Lo;0;L;;;;;N;;;;;
3316 107D;MYANMAR LETTER SHAN PHA;Lo;0;L;;;;;N;;;;;
3317 107E;MYANMAR LETTER SHAN FA;Lo;0;L;;;;;N;;;;;
3318 107F;MYANMAR LETTER SHAN BA;Lo;0;L;;;;;N;;;;;
3319 1080;MYANMAR LETTER SHAN THA;Lo;0;L;;;;;N;;;;;
3320 1081;MYANMAR LETTER SHAN HA;Lo;0;L;;;;;N;;;;;
3321 1082;MYANMAR CONSONANT SIGN SHAN MEDIAL WA;Mn;0;NSM;;;;;N;;;;;
3322 1083;MYANMAR VOWEL SIGN SHAN AA;Mc;0;L;;;;;N;;;;;
3323 1084;MYANMAR VOWEL SIGN SHAN E;Mc;0;L;;;;;N;;;;;
3324 1085;MYANMAR VOWEL SIGN SHAN E ABOVE;Mn;0;NSM;;;;;N;;;;;
3325 1086;MYANMAR VOWEL SIGN SHAN FINAL Y;Mn;0;NSM;;;;;N;;;;;
3326 1087;MYANMAR SIGN SHAN TONE-2;Mc;0;L;;;;;N;;;;;
3327 1088;MYANMAR SIGN SHAN TONE-3;Mc;0;L;;;;;N;;;;;
3328 1089;MYANMAR SIGN SHAN TONE-5;Mc;0;L;;;;;N;;;;;
3329 108A;MYANMAR SIGN SHAN TONE-6;Mc;0;L;;;;;N;;;;;
3330 108B;MYANMAR SIGN SHAN COUNCIL TONE-2;Mc;0;L;;;;;N;;;;;
3331 108C;MYANMAR SIGN SHAN COUNCIL TONE-3;Mc;0;L;;;;;N;;;;;
3332 108D;MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE;Mn;220;NSM;;;;;N;;;;;
3333 108E;MYANMAR LETTER RUMAI PALAUNG FA;Lo;0;L;;;;;N;;;;;
3334 108F;MYANMAR SIGN RUMAI PALAUNG TONE-5;Mc;0;L;;;;;N;;;;;
3335 1090;MYANMAR SHAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
3336 1091;MYANMAR SHAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
3337 1092;MYANMAR SHAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
3338 1093;MYANMAR SHAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
3339 1094;MYANMAR SHAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
3340 1095;MYANMAR SHAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
3341 1096;MYANMAR SHAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
3342 1097;MYANMAR SHAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
3343 1098;MYANMAR SHAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
3344 1099;MYANMAR SHAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
3345 109E;MYANMAR SYMBOL SHAN ONE;So;0;L;;;;;N;;;;;
3346 109F;MYANMAR SYMBOL SHAN EXCLAMATION;So;0;L;;;;;N;;;;;
3347 10A0;GEORGIAN CAPITAL LETTER AN;Lu;0;L;;;;;N;;Khutsuri;;2D00;
3348 10A1;GEORGIAN CAPITAL LETTER BAN;Lu;0;L;;;;;N;;Khutsuri;;2D01;
3349 10A2;GEORGIAN CAPITAL LETTER GAN;Lu;0;L;;;;;N;;Khutsuri;;2D02;
3350 10A3;GEORGIAN CAPITAL LETTER DON;Lu;0;L;;;;;N;;Khutsuri;;2D03;
3351 10A4;GEORGIAN CAPITAL LETTER EN;Lu;0;L;;;;;N;;Khutsuri;;2D04;
3352 10A5;GEORGIAN CAPITAL LETTER VIN;Lu;0;L;;;;;N;;Khutsuri;;2D05;
3353 10A6;GEORGIAN CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;Khutsuri;;2D06;
3354 10A7;GEORGIAN CAPITAL LETTER TAN;Lu;0;L;;;;;N;;Khutsuri;;2D07;
3355 10A8;GEORGIAN CAPITAL LETTER IN;Lu;0;L;;;;;N;;Khutsuri;;2D08;
3356 10A9;GEORGIAN CAPITAL LETTER KAN;Lu;0;L;;;;;N;;Khutsuri;;2D09;
3357 10AA;GEORGIAN CAPITAL LETTER LAS;Lu;0;L;;;;;N;;Khutsuri;;2D0A;
3358 10AB;GEORGIAN CAPITAL LETTER MAN;Lu;0;L;;;;;N;;Khutsuri;;2D0B;
3359 10AC;GEORGIAN CAPITAL LETTER NAR;Lu;0;L;;;;;N;;Khutsuri;;2D0C;
3360 10AD;GEORGIAN CAPITAL LETTER ON;Lu;0;L;;;;;N;;Khutsuri;;2D0D;
3361 10AE;GEORGIAN CAPITAL LETTER PAR;Lu;0;L;;;;;N;;Khutsuri;;2D0E;
3362 10AF;GEORGIAN CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;Khutsuri;;2D0F;
3363 10B0;GEORGIAN CAPITAL LETTER RAE;Lu;0;L;;;;;N;;Khutsuri;;2D10;
3364 10B1;GEORGIAN CAPITAL LETTER SAN;Lu;0;L;;;;;N;;Khutsuri;;2D11;
3365 10B2;GEORGIAN CAPITAL LETTER TAR;Lu;0;L;;;;;N;;Khutsuri;;2D12;
3366 10B3;GEORGIAN CAPITAL LETTER UN;Lu;0;L;;;;;N;;Khutsuri;;2D13;
3367 10B4;GEORGIAN CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;Khutsuri;;2D14;
3368 10B5;GEORGIAN CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;Khutsuri;;2D15;
3369 10B6;GEORGIAN CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;Khutsuri;;2D16;
3370 10B7;GEORGIAN CAPITAL LETTER QAR;Lu;0;L;;;;;N;;Khutsuri;;2D17;
3371 10B8;GEORGIAN CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;Khutsuri;;2D18;
3372 10B9;GEORGIAN CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;Khutsuri;;2D19;
3373 10BA;GEORGIAN CAPITAL LETTER CAN;Lu;0;L;;;;;N;;Khutsuri;;2D1A;
3374 10BB;GEORGIAN CAPITAL LETTER JIL;Lu;0;L;;;;;N;;Khutsuri;;2D1B;
3375 10BC;GEORGIAN CAPITAL LETTER CIL;Lu;0;L;;;;;N;;Khutsuri;;2D1C;
3376 10BD;GEORGIAN CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;Khutsuri;;2D1D;
3377 10BE;GEORGIAN CAPITAL LETTER XAN;Lu;0;L;;;;;N;;Khutsuri;;2D1E;
3378 10BF;GEORGIAN CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;Khutsuri;;2D1F;
3379 10C0;GEORGIAN CAPITAL LETTER HAE;Lu;0;L;;;;;N;;Khutsuri;;2D20;
3380 10C1;GEORGIAN CAPITAL LETTER HE;Lu;0;L;;;;;N;;Khutsuri;;2D21;
3381 10C2;GEORGIAN CAPITAL LETTER HIE;Lu;0;L;;;;;N;;Khutsuri;;2D22;
3382 10C3;GEORGIAN CAPITAL LETTER WE;Lu;0;L;;;;;N;;Khutsuri;;2D23;
3383 10C4;GEORGIAN CAPITAL LETTER HAR;Lu;0;L;;;;;N;;Khutsuri;;2D24;
3384 10C5;GEORGIAN CAPITAL LETTER HOE;Lu;0;L;;;;;N;;Khutsuri;;2D25;
3385 10D0;GEORGIAN LETTER AN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER AN;;;;
3386 10D1;GEORGIAN LETTER BAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER BAN;;;;
3387 10D2;GEORGIAN LETTER GAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GAN;;;;
3388 10D3;GEORGIAN LETTER DON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER DON;;;;
3389 10D4;GEORGIAN LETTER EN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER EN;;;;
3390 10D5;GEORGIAN LETTER VIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER VIN;;;;
3391 10D6;GEORGIAN LETTER ZEN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZEN;;;;
3392 10D7;GEORGIAN LETTER TAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAN;;;;
3393 10D8;GEORGIAN LETTER IN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER IN;;;;
3394 10D9;GEORGIAN LETTER KAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KAN;;;;
3395 10DA;GEORGIAN LETTER LAS;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER LAS;;;;
3396 10DB;GEORGIAN LETTER MAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER MAN;;;;
3397 10DC;GEORGIAN LETTER NAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER NAR;;;;
3398 10DD;GEORGIAN LETTER ON;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ON;;;;
3399 10DE;GEORGIAN LETTER PAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PAR;;;;
3400 10DF;GEORGIAN LETTER ZHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER ZHAR;;;;
3401 10E0;GEORGIAN LETTER RAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER RAE;;;;
3402 10E1;GEORGIAN LETTER SAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SAN;;;;
3403 10E2;GEORGIAN LETTER TAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER TAR;;;;
3404 10E3;GEORGIAN LETTER UN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER UN;;;;
3405 10E4;GEORGIAN LETTER PHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER PHAR;;;;
3406 10E5;GEORGIAN LETTER KHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER KHAR;;;;
3407 10E6;GEORGIAN LETTER GHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER GHAN;;;;
3408 10E7;GEORGIAN LETTER QAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER QAR;;;;
3409 10E8;GEORGIAN LETTER SHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER SHIN;;;;
3410 10E9;GEORGIAN LETTER CHIN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHIN;;;;
3411 10EA;GEORGIAN LETTER CAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CAN;;;;
3412 10EB;GEORGIAN LETTER JIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JIL;;;;
3413 10EC;GEORGIAN LETTER CIL;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CIL;;;;
3414 10ED;GEORGIAN LETTER CHAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER CHAR;;;;
3415 10EE;GEORGIAN LETTER XAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER XAN;;;;
3416 10EF;GEORGIAN LETTER JHAN;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER JHAN;;;;
3417 10F0;GEORGIAN LETTER HAE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAE;;;;
3418 10F1;GEORGIAN LETTER HE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HE;;;;
3419 10F2;GEORGIAN LETTER HIE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HIE;;;;
3420 10F3;GEORGIAN LETTER WE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER WE;;;;
3421 10F4;GEORGIAN LETTER HAR;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HAR;;;;
3422 10F5;GEORGIAN LETTER HOE;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER HOE;;;;
3423 10F6;GEORGIAN LETTER FI;Lo;0;L;;;;;N;GEORGIAN SMALL LETTER FI;;;;
3424 10F7;GEORGIAN LETTER YN;Lo;0;L;;;;;N;;;;;
3425 10F8;GEORGIAN LETTER ELIFI;Lo;0;L;;;;;N;;;;;
3426 10F9;GEORGIAN LETTER TURNED GAN;Lo;0;L;;;;;N;;;;;
3427 10FA;GEORGIAN LETTER AIN;Lo;0;L;;;;;N;;;;;
3428 10FB;GEORGIAN PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;;
3429 10FC;MODIFIER LETTER GEORGIAN NAR;Lm;0;L;<super> 10DC;;;;N;;;;;
3430 1100;HANGUL CHOSEONG KIYEOK;Lo;0;L;;;;;N;;g *;;;
3431 1101;HANGUL CHOSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;gg *;;;
3432 1102;HANGUL CHOSEONG NIEUN;Lo;0;L;;;;;N;;n *;;;
3433 1103;HANGUL CHOSEONG TIKEUT;Lo;0;L;;;;;N;;d *;;;
3434 1104;HANGUL CHOSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;dd *;;;
3435 1105;HANGUL CHOSEONG RIEUL;Lo;0;L;;;;;N;;r *;;;
3436 1106;HANGUL CHOSEONG MIEUM;Lo;0;L;;;;;N;;m *;;;
3437 1107;HANGUL CHOSEONG PIEUP;Lo;0;L;;;;;N;;b *;;;
3438 1108;HANGUL CHOSEONG SSANGPIEUP;Lo;0;L;;;;;N;;bb *;;;
3439 1109;HANGUL CHOSEONG SIOS;Lo;0;L;;;;;N;;s *;;;
3440 110A;HANGUL CHOSEONG SSANGSIOS;Lo;0;L;;;;;N;;ss *;;;
3441 110B;HANGUL CHOSEONG IEUNG;Lo;0;L;;;;;N;;;;;
3442 110C;HANGUL CHOSEONG CIEUC;Lo;0;L;;;;;N;;j *;;;
3443 110D;HANGUL CHOSEONG SSANGCIEUC;Lo;0;L;;;;;N;;jj *;;;
3444 110E;HANGUL CHOSEONG CHIEUCH;Lo;0;L;;;;;N;;c *;;;
3445 110F;HANGUL CHOSEONG KHIEUKH;Lo;0;L;;;;;N;;k *;;;
3446 1110;HANGUL CHOSEONG THIEUTH;Lo;0;L;;;;;N;;t *;;;
3447 1111;HANGUL CHOSEONG PHIEUPH;Lo;0;L;;;;;N;;p *;;;
3448 1112;HANGUL CHOSEONG HIEUH;Lo;0;L;;;;;N;;h *;;;
3449 1113;HANGUL CHOSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;;
3450 1114;HANGUL CHOSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;;
3451 1115;HANGUL CHOSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;;
3452 1116;HANGUL CHOSEONG NIEUN-PIEUP;Lo;0;L;;;;;N;;;;;
3453 1117;HANGUL CHOSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;;
3454 1118;HANGUL CHOSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;;
3455 1119;HANGUL CHOSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;;
3456 111A;HANGUL CHOSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;;
3457 111B;HANGUL CHOSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;;
3458 111C;HANGUL CHOSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;;
3459 111D;HANGUL CHOSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;;
3460 111E;HANGUL CHOSEONG PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;;
3461 111F;HANGUL CHOSEONG PIEUP-NIEUN;Lo;0;L;;;;;N;;;;;
3462 1120;HANGUL CHOSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;;
3463 1121;HANGUL CHOSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;;
3464 1122;HANGUL CHOSEONG PIEUP-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
3465 1123;HANGUL CHOSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
3466 1124;HANGUL CHOSEONG PIEUP-SIOS-PIEUP;Lo;0;L;;;;;N;;;;;
3467 1125;HANGUL CHOSEONG PIEUP-SSANGSIOS;Lo;0;L;;;;;N;;;;;
3468 1126;HANGUL CHOSEONG PIEUP-SIOS-CIEUC;Lo;0;L;;;;;N;;;;;
3469 1127;HANGUL CHOSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;;
3470 1128;HANGUL CHOSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;;
3471 1129;HANGUL CHOSEONG PIEUP-THIEUTH;Lo;0;L;;;;;N;;;;;
3472 112A;HANGUL CHOSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;;
3473 112B;HANGUL CHOSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
3474 112C;HANGUL CHOSEONG KAPYEOUNSSANGPIEUP;Lo;0;L;;;;;N;;;;;
3475 112D;HANGUL CHOSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
3476 112E;HANGUL CHOSEONG SIOS-NIEUN;Lo;0;L;;;;;N;;;;;
3477 112F;HANGUL CHOSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
3478 1130;HANGUL CHOSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;;
3479 1131;HANGUL CHOSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;;
3480 1132;HANGUL CHOSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;;
3481 1133;HANGUL CHOSEONG SIOS-PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;;
3482 1134;HANGUL CHOSEONG SIOS-SSANGSIOS;Lo;0;L;;;;;N;;;;;
3483 1135;HANGUL CHOSEONG SIOS-IEUNG;Lo;0;L;;;;;N;;;;;
3484 1136;HANGUL CHOSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;;
3485 1137;HANGUL CHOSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;;
3486 1138;HANGUL CHOSEONG SIOS-KHIEUKH;Lo;0;L;;;;;N;;;;;
3487 1139;HANGUL CHOSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;;
3488 113A;HANGUL CHOSEONG SIOS-PHIEUPH;Lo;0;L;;;;;N;;;;;
3489 113B;HANGUL CHOSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;;
3490 113C;HANGUL CHOSEONG CHITUEUMSIOS;Lo;0;L;;;;;N;;;;;
3491 113D;HANGUL CHOSEONG CHITUEUMSSANGSIOS;Lo;0;L;;;;;N;;;;;
3492 113E;HANGUL CHOSEONG CEONGCHIEUMSIOS;Lo;0;L;;;;;N;;;;;
3493 113F;HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS;Lo;0;L;;;;;N;;;;;
3494 1140;HANGUL CHOSEONG PANSIOS;Lo;0;L;;;;;N;;;;;
3495 1141;HANGUL CHOSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;;
3496 1142;HANGUL CHOSEONG IEUNG-TIKEUT;Lo;0;L;;;;;N;;;;;
3497 1143;HANGUL CHOSEONG IEUNG-MIEUM;Lo;0;L;;;;;N;;;;;
3498 1144;HANGUL CHOSEONG IEUNG-PIEUP;Lo;0;L;;;;;N;;;;;
3499 1145;HANGUL CHOSEONG IEUNG-SIOS;Lo;0;L;;;;;N;;;;;
3500 1146;HANGUL CHOSEONG IEUNG-PANSIOS;Lo;0;L;;;;;N;;;;;
3501 1147;HANGUL CHOSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;;
3502 1148;HANGUL CHOSEONG IEUNG-CIEUC;Lo;0;L;;;;;N;;;;;
3503 1149;HANGUL CHOSEONG IEUNG-CHIEUCH;Lo;0;L;;;;;N;;;;;
3504 114A;HANGUL CHOSEONG IEUNG-THIEUTH;Lo;0;L;;;;;N;;;;;
3505 114B;HANGUL CHOSEONG IEUNG-PHIEUPH;Lo;0;L;;;;;N;;;;;
3506 114C;HANGUL CHOSEONG YESIEUNG;Lo;0;L;;;;;N;;;;;
3507 114D;HANGUL CHOSEONG CIEUC-IEUNG;Lo;0;L;;;;;N;;;;;
3508 114E;HANGUL CHOSEONG CHITUEUMCIEUC;Lo;0;L;;;;;N;;;;;
3509 114F;HANGUL CHOSEONG CHITUEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;;
3510 1150;HANGUL CHOSEONG CEONGCHIEUMCIEUC;Lo;0;L;;;;;N;;;;;
3511 1151;HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;;
3512 1152;HANGUL CHOSEONG CHIEUCH-KHIEUKH;Lo;0;L;;;;;N;;;;;
3513 1153;HANGUL CHOSEONG CHIEUCH-HIEUH;Lo;0;L;;;;;N;;;;;
3514 1154;HANGUL CHOSEONG CHITUEUMCHIEUCH;Lo;0;L;;;;;N;;;;;
3515 1155;HANGUL CHOSEONG CEONGCHIEUMCHIEUCH;Lo;0;L;;;;;N;;;;;
3516 1156;HANGUL CHOSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;;
3517 1157;HANGUL CHOSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;;
3518 1158;HANGUL CHOSEONG SSANGHIEUH;Lo;0;L;;;;;N;;;;;
3519 1159;HANGUL CHOSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;;
3520 115F;HANGUL CHOSEONG FILLER;Lo;0;L;;;;;N;;;;;
3521 1160;HANGUL JUNGSEONG FILLER;Lo;0;L;;;;;N;;;;;
3522 1161;HANGUL JUNGSEONG A;Lo;0;L;;;;;N;;;;;
3523 1162;HANGUL JUNGSEONG AE;Lo;0;L;;;;;N;;;;;
3524 1163;HANGUL JUNGSEONG YA;Lo;0;L;;;;;N;;;;;
3525 1164;HANGUL JUNGSEONG YAE;Lo;0;L;;;;;N;;;;;
3526 1165;HANGUL JUNGSEONG EO;Lo;0;L;;;;;N;;;;;
3527 1166;HANGUL JUNGSEONG E;Lo;0;L;;;;;N;;;;;
3528 1167;HANGUL JUNGSEONG YEO;Lo;0;L;;;;;N;;;;;
3529 1168;HANGUL JUNGSEONG YE;Lo;0;L;;;;;N;;;;;
3530 1169;HANGUL JUNGSEONG O;Lo;0;L;;;;;N;;;;;
3531 116A;HANGUL JUNGSEONG WA;Lo;0;L;;;;;N;;;;;
3532 116B;HANGUL JUNGSEONG WAE;Lo;0;L;;;;;N;;;;;
3533 116C;HANGUL JUNGSEONG OE;Lo;0;L;;;;;N;;;;;
3534 116D;HANGUL JUNGSEONG YO;Lo;0;L;;;;;N;;;;;
3535 116E;HANGUL JUNGSEONG U;Lo;0;L;;;;;N;;;;;
3536 116F;HANGUL JUNGSEONG WEO;Lo;0;L;;;;;N;;;;;
3537 1170;HANGUL JUNGSEONG WE;Lo;0;L;;;;;N;;;;;
3538 1171;HANGUL JUNGSEONG WI;Lo;0;L;;;;;N;;;;;
3539 1172;HANGUL JUNGSEONG YU;Lo;0;L;;;;;N;;;;;
3540 1173;HANGUL JUNGSEONG EU;Lo;0;L;;;;;N;;;;;
3541 1174;HANGUL JUNGSEONG YI;Lo;0;L;;;;;N;;;;;
3542 1175;HANGUL JUNGSEONG I;Lo;0;L;;;;;N;;;;;
3543 1176;HANGUL JUNGSEONG A-O;Lo;0;L;;;;;N;;;;;
3544 1177;HANGUL JUNGSEONG A-U;Lo;0;L;;;;;N;;;;;
3545 1178;HANGUL JUNGSEONG YA-O;Lo;0;L;;;;;N;;;;;
3546 1179;HANGUL JUNGSEONG YA-YO;Lo;0;L;;;;;N;;;;;
3547 117A;HANGUL JUNGSEONG EO-O;Lo;0;L;;;;;N;;;;;
3548 117B;HANGUL JUNGSEONG EO-U;Lo;0;L;;;;;N;;;;;
3549 117C;HANGUL JUNGSEONG EO-EU;Lo;0;L;;;;;N;;;;;
3550 117D;HANGUL JUNGSEONG YEO-O;Lo;0;L;;;;;N;;;;;
3551 117E;HANGUL JUNGSEONG YEO-U;Lo;0;L;;;;;N;;;;;
3552 117F;HANGUL JUNGSEONG O-EO;Lo;0;L;;;;;N;;;;;
3553 1180;HANGUL JUNGSEONG O-E;Lo;0;L;;;;;N;;;;;
3554 1181;HANGUL JUNGSEONG O-YE;Lo;0;L;;;;;N;;;;;
3555 1182;HANGUL JUNGSEONG O-O;Lo;0;L;;;;;N;;;;;
3556 1183;HANGUL JUNGSEONG O-U;Lo;0;L;;;;;N;;;;;
3557 1184;HANGUL JUNGSEONG YO-YA;Lo;0;L;;;;;N;;;;;
3558 1185;HANGUL JUNGSEONG YO-YAE;Lo;0;L;;;;;N;;;;;
3559 1186;HANGUL JUNGSEONG YO-YEO;Lo;0;L;;;;;N;;;;;
3560 1187;HANGUL JUNGSEONG YO-O;Lo;0;L;;;;;N;;;;;
3561 1188;HANGUL JUNGSEONG YO-I;Lo;0;L;;;;;N;;;;;
3562 1189;HANGUL JUNGSEONG U-A;Lo;0;L;;;;;N;;;;;
3563 118A;HANGUL JUNGSEONG U-AE;Lo;0;L;;;;;N;;;;;
3564 118B;HANGUL JUNGSEONG U-EO-EU;Lo;0;L;;;;;N;;;;;
3565 118C;HANGUL JUNGSEONG U-YE;Lo;0;L;;;;;N;;;;;
3566 118D;HANGUL JUNGSEONG U-U;Lo;0;L;;;;;N;;;;;
3567 118E;HANGUL JUNGSEONG YU-A;Lo;0;L;;;;;N;;;;;
3568 118F;HANGUL JUNGSEONG YU-EO;Lo;0;L;;;;;N;;;;;
3569 1190;HANGUL JUNGSEONG YU-E;Lo;0;L;;;;;N;;;;;
3570 1191;HANGUL JUNGSEONG YU-YEO;Lo;0;L;;;;;N;;;;;
3571 1192;HANGUL JUNGSEONG YU-YE;Lo;0;L;;;;;N;;;;;
3572 1193;HANGUL JUNGSEONG YU-U;Lo;0;L;;;;;N;;;;;
3573 1194;HANGUL JUNGSEONG YU-I;Lo;0;L;;;;;N;;;;;
3574 1195;HANGUL JUNGSEONG EU-U;Lo;0;L;;;;;N;;;;;
3575 1196;HANGUL JUNGSEONG EU-EU;Lo;0;L;;;;;N;;;;;
3576 1197;HANGUL JUNGSEONG YI-U;Lo;0;L;;;;;N;;;;;
3577 1198;HANGUL JUNGSEONG I-A;Lo;0;L;;;;;N;;;;;
3578 1199;HANGUL JUNGSEONG I-YA;Lo;0;L;;;;;N;;;;;
3579 119A;HANGUL JUNGSEONG I-O;Lo;0;L;;;;;N;;;;;
3580 119B;HANGUL JUNGSEONG I-U;Lo;0;L;;;;;N;;;;;
3581 119C;HANGUL JUNGSEONG I-EU;Lo;0;L;;;;;N;;;;;
3582 119D;HANGUL JUNGSEONG I-ARAEA;Lo;0;L;;;;;N;;;;;
3583 119E;HANGUL JUNGSEONG ARAEA;Lo;0;L;;;;;N;;;;;
3584 119F;HANGUL JUNGSEONG ARAEA-EO;Lo;0;L;;;;;N;;;;;
3585 11A0;HANGUL JUNGSEONG ARAEA-U;Lo;0;L;;;;;N;;;;;
3586 11A1;HANGUL JUNGSEONG ARAEA-I;Lo;0;L;;;;;N;;;;;
3587 11A2;HANGUL JUNGSEONG SSANGARAEA;Lo;0;L;;;;;N;;;;;
3588 11A8;HANGUL JONGSEONG KIYEOK;Lo;0;L;;;;;N;;g *;;;
3589 11A9;HANGUL JONGSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;gg *;;;
3590 11AA;HANGUL JONGSEONG KIYEOK-SIOS;Lo;0;L;;;;;N;;gs *;;;
3591 11AB;HANGUL JONGSEONG NIEUN;Lo;0;L;;;;;N;;n *;;;
3592 11AC;HANGUL JONGSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;nj *;;;
3593 11AD;HANGUL JONGSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;nh *;;;
3594 11AE;HANGUL JONGSEONG TIKEUT;Lo;0;L;;;;;N;;d *;;;
3595 11AF;HANGUL JONGSEONG RIEUL;Lo;0;L;;;;;N;;l *;;;
3596 11B0;HANGUL JONGSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;lg *;;;
3597 11B1;HANGUL JONGSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;lm *;;;
3598 11B2;HANGUL JONGSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;lb *;;;
3599 11B3;HANGUL JONGSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;ls *;;;
3600 11B4;HANGUL JONGSEONG RIEUL-THIEUTH;Lo;0;L;;;;;N;;lt *;;;
3601 11B5;HANGUL JONGSEONG RIEUL-PHIEUPH;Lo;0;L;;;;;N;;lp *;;;
3602 11B6;HANGUL JONGSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;lh *;;;
3603 11B7;HANGUL JONGSEONG MIEUM;Lo;0;L;;;;;N;;m *;;;
3604 11B8;HANGUL JONGSEONG PIEUP;Lo;0;L;;;;;N;;b *;;;
3605 11B9;HANGUL JONGSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;bs *;;;
3606 11BA;HANGUL JONGSEONG SIOS;Lo;0;L;;;;;N;;s *;;;
3607 11BB;HANGUL JONGSEONG SSANGSIOS;Lo;0;L;;;;;N;;ss *;;;
3608 11BC;HANGUL JONGSEONG IEUNG;Lo;0;L;;;;;N;;ng *;;;
3609 11BD;HANGUL JONGSEONG CIEUC;Lo;0;L;;;;;N;;j *;;;
3610 11BE;HANGUL JONGSEONG CHIEUCH;Lo;0;L;;;;;N;;c *;;;
3611 11BF;HANGUL JONGSEONG KHIEUKH;Lo;0;L;;;;;N;;k *;;;
3612 11C0;HANGUL JONGSEONG THIEUTH;Lo;0;L;;;;;N;;t *;;;
3613 11C1;HANGUL JONGSEONG PHIEUPH;Lo;0;L;;;;;N;;p *;;;
3614 11C2;HANGUL JONGSEONG HIEUH;Lo;0;L;;;;;N;;h *;;;
3615 11C3;HANGUL JONGSEONG KIYEOK-RIEUL;Lo;0;L;;;;;N;;;;;
3616 11C4;HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
3617 11C5;HANGUL JONGSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;;
3618 11C6;HANGUL JONGSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;;
3619 11C7;HANGUL JONGSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;;
3620 11C8;HANGUL JONGSEONG NIEUN-PANSIOS;Lo;0;L;;;;;N;;;;;
3621 11C9;HANGUL JONGSEONG NIEUN-THIEUTH;Lo;0;L;;;;;N;;;;;
3622 11CA;HANGUL JONGSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;;
3623 11CB;HANGUL JONGSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;;
3624 11CC;HANGUL JONGSEONG RIEUL-KIYEOK-SIOS;Lo;0;L;;;;;N;;;;;
3625 11CD;HANGUL JONGSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;;
3626 11CE;HANGUL JONGSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;;
3627 11CF;HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH;Lo;0;L;;;;;N;;;;;
3628 11D0;HANGUL JONGSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;;
3629 11D1;HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;;
3630 11D2;HANGUL JONGSEONG RIEUL-MIEUM-SIOS;Lo;0;L;;;;;N;;;;;
3631 11D3;HANGUL JONGSEONG RIEUL-PIEUP-SIOS;Lo;0;L;;;;;N;;;;;
3632 11D4;HANGUL JONGSEONG RIEUL-PIEUP-HIEUH;Lo;0;L;;;;;N;;;;;
3633 11D5;HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
3634 11D6;HANGUL JONGSEONG RIEUL-SSANGSIOS;Lo;0;L;;;;;N;;;;;
3635 11D7;HANGUL JONGSEONG RIEUL-PANSIOS;Lo;0;L;;;;;N;;;;;
3636 11D8;HANGUL JONGSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;;
3637 11D9;HANGUL JONGSEONG RIEUL-YEORINHIEUH;Lo;0;L;;;;;N;;;;;
3638 11DA;HANGUL JONGSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;;
3639 11DB;HANGUL JONGSEONG MIEUM-RIEUL;Lo;0;L;;;;;N;;;;;
3640 11DC;HANGUL JONGSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;;
3641 11DD;HANGUL JONGSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;;
3642 11DE;HANGUL JONGSEONG MIEUM-SSANGSIOS;Lo;0;L;;;;;N;;;;;
3643 11DF;HANGUL JONGSEONG MIEUM-PANSIOS;Lo;0;L;;;;;N;;;;;
3644 11E0;HANGUL JONGSEONG MIEUM-CHIEUCH;Lo;0;L;;;;;N;;;;;
3645 11E1;HANGUL JONGSEONG MIEUM-HIEUH;Lo;0;L;;;;;N;;;;;
3646 11E2;HANGUL JONGSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;;
3647 11E3;HANGUL JONGSEONG PIEUP-RIEUL;Lo;0;L;;;;;N;;;;;
3648 11E4;HANGUL JONGSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;;
3649 11E5;HANGUL JONGSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;;
3650 11E6;HANGUL JONGSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;
3651 11E7;HANGUL JONGSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;
3652 11E8;HANGUL JONGSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;
3653 11E9;HANGUL JONGSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;;
3654 11EA;HANGUL JONGSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;;
3655 11EB;HANGUL JONGSEONG PANSIOS;Lo;0;L;;;;;N;;;;;
3656 11EC;HANGUL JONGSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;;
3657 11ED;HANGUL JONGSEONG IEUNG-SSANGKIYEOK;Lo;0;L;;;;;N;;;;;
3658 11EE;HANGUL JONGSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;;
3659 11EF;HANGUL JONGSEONG IEUNG-KHIEUKH;Lo;0;L;;;;;N;;;;;
3660 11F0;HANGUL JONGSEONG YESIEUNG;Lo;0;L;;;;;N;;;;;
3661 11F1;HANGUL JONGSEONG YESIEUNG-SIOS;Lo;0;L;;;;;N;;;;;
3662 11F2;HANGUL JONGSEONG YESIEUNG-PANSIOS;Lo;0;L;;;;;N;;;;;
3663 11F3;HANGUL JONGSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;;
3664 11F4;HANGUL JONGSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;;
3665 11F5;HANGUL JONGSEONG HIEUH-NIEUN;Lo;0;L;;;;;N;;;;;
3666 11F6;HANGUL JONGSEONG HIEUH-RIEUL;Lo;0;L;;;;;N;;;;;
3667 11F7;HANGUL JONGSEONG HIEUH-MIEUM;Lo;0;L;;;;;N;;;;;
3668 11F8;HANGUL JONGSEONG HIEUH-PIEUP;Lo;0;L;;;;;N;;;;;
3669 11F9;HANGUL JONGSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;;
3670 1200;ETHIOPIC SYLLABLE HA;Lo;0;L;;;;;N;;;;;
3671 1201;ETHIOPIC SYLLABLE HU;Lo;0;L;;;;;N;;;;;
3672 1202;ETHIOPIC SYLLABLE HI;Lo;0;L;;;;;N;;;;;
3673 1203;ETHIOPIC SYLLABLE HAA;Lo;0;L;;;;;N;;;;;
3674 1204;ETHIOPIC SYLLABLE HEE;Lo;0;L;;;;;N;;;;;
3675 1205;ETHIOPIC SYLLABLE HE;Lo;0;L;;;;;N;;;;;
3676 1206;ETHIOPIC SYLLABLE HO;Lo;0;L;;;;;N;;;;;
3677 1207;ETHIOPIC SYLLABLE HOA;Lo;0;L;;;;;N;;;;;
3678 1208;ETHIOPIC SYLLABLE LA;Lo;0;L;;;;;N;;;;;
3679 1209;ETHIOPIC SYLLABLE LU;Lo;0;L;;;;;N;;;;;
3680 120A;ETHIOPIC SYLLABLE LI;Lo;0;L;;;;;N;;;;;
3681 120B;ETHIOPIC SYLLABLE LAA;Lo;0;L;;;;;N;;;;;
3682 120C;ETHIOPIC SYLLABLE LEE;Lo;0;L;;;;;N;;;;;
3683 120D;ETHIOPIC SYLLABLE LE;Lo;0;L;;;;;N;;;;;
3684 120E;ETHIOPIC SYLLABLE LO;Lo;0;L;;;;;N;;;;;
3685 120F;ETHIOPIC SYLLABLE LWA;Lo;0;L;;;;;N;;;;;
3686 1210;ETHIOPIC SYLLABLE HHA;Lo;0;L;;;;;N;;;;;
3687 1211;ETHIOPIC SYLLABLE HHU;Lo;0;L;;;;;N;;;;;
3688 1212;ETHIOPIC SYLLABLE HHI;Lo;0;L;;;;;N;;;;;
3689 1213;ETHIOPIC SYLLABLE HHAA;Lo;0;L;;;;;N;;;;;
3690 1214;ETHIOPIC SYLLABLE HHEE;Lo;0;L;;;;;N;;;;;
3691 1215;ETHIOPIC SYLLABLE HHE;Lo;0;L;;;;;N;;;;;
3692 1216;ETHIOPIC SYLLABLE HHO;Lo;0;L;;;;;N;;;;;
3693 1217;ETHIOPIC SYLLABLE HHWA;Lo;0;L;;;;;N;;;;;
3694 1218;ETHIOPIC SYLLABLE MA;Lo;0;L;;;;;N;;;;;
3695 1219;ETHIOPIC SYLLABLE MU;Lo;0;L;;;;;N;;;;;
3696 121A;ETHIOPIC SYLLABLE MI;Lo;0;L;;;;;N;;;;;
3697 121B;ETHIOPIC SYLLABLE MAA;Lo;0;L;;;;;N;;;;;
3698 121C;ETHIOPIC SYLLABLE MEE;Lo;0;L;;;;;N;;;;;
3699 121D;ETHIOPIC SYLLABLE ME;Lo;0;L;;;;;N;;;;;
3700 121E;ETHIOPIC SYLLABLE MO;Lo;0;L;;;;;N;;;;;
3701 121F;ETHIOPIC SYLLABLE MWA;Lo;0;L;;;;;N;;;;;
3702 1220;ETHIOPIC SYLLABLE SZA;Lo;0;L;;;;;N;;;;;
3703 1221;ETHIOPIC SYLLABLE SZU;Lo;0;L;;;;;N;;;;;
3704 1222;ETHIOPIC SYLLABLE SZI;Lo;0;L;;;;;N;;;;;
3705 1223;ETHIOPIC SYLLABLE SZAA;Lo;0;L;;;;;N;;;;;
3706 1224;ETHIOPIC SYLLABLE SZEE;Lo;0;L;;;;;N;;;;;
3707 1225;ETHIOPIC SYLLABLE SZE;Lo;0;L;;;;;N;;;;;
3708 1226;ETHIOPIC SYLLABLE SZO;Lo;0;L;;;;;N;;;;;
3709 1227;ETHIOPIC SYLLABLE SZWA;Lo;0;L;;;;;N;;;;;
3710 1228;ETHIOPIC SYLLABLE RA;Lo;0;L;;;;;N;;;;;
3711 1229;ETHIOPIC SYLLABLE RU;Lo;0;L;;;;;N;;;;;
3712 122A;ETHIOPIC SYLLABLE RI;Lo;0;L;;;;;N;;;;;
3713 122B;ETHIOPIC SYLLABLE RAA;Lo;0;L;;;;;N;;;;;
3714 122C;ETHIOPIC SYLLABLE REE;Lo;0;L;;;;;N;;;;;
3715 122D;ETHIOPIC SYLLABLE RE;Lo;0;L;;;;;N;;;;;
3716 122E;ETHIOPIC SYLLABLE RO;Lo;0;L;;;;;N;;;;;
3717 122F;ETHIOPIC SYLLABLE RWA;Lo;0;L;;;;;N;;;;;
3718 1230;ETHIOPIC SYLLABLE SA;Lo;0;L;;;;;N;;;;;
3719 1231;ETHIOPIC SYLLABLE SU;Lo;0;L;;;;;N;;;;;
3720 1232;ETHIOPIC SYLLABLE SI;Lo;0;L;;;;;N;;;;;
3721 1233;ETHIOPIC SYLLABLE SAA;Lo;0;L;;;;;N;;;;;
3722 1234;ETHIOPIC SYLLABLE SEE;Lo;0;L;;;;;N;;;;;
3723 1235;ETHIOPIC SYLLABLE SE;Lo;0;L;;;;;N;;;;;
3724 1236;ETHIOPIC SYLLABLE SO;Lo;0;L;;;;;N;;;;;
3725 1237;ETHIOPIC SYLLABLE SWA;Lo;0;L;;;;;N;;;;;
3726 1238;ETHIOPIC SYLLABLE SHA;Lo;0;L;;;;;N;;;;;
3727 1239;ETHIOPIC SYLLABLE SHU;Lo;0;L;;;;;N;;;;;
3728 123A;ETHIOPIC SYLLABLE SHI;Lo;0;L;;;;;N;;;;;
3729 123B;ETHIOPIC SYLLABLE SHAA;Lo;0;L;;;;;N;;;;;
3730 123C;ETHIOPIC SYLLABLE SHEE;Lo;0;L;;;;;N;;;;;
3731 123D;ETHIOPIC SYLLABLE SHE;Lo;0;L;;;;;N;;;;;
3732 123E;ETHIOPIC SYLLABLE SHO;Lo;0;L;;;;;N;;;;;
3733 123F;ETHIOPIC SYLLABLE SHWA;Lo;0;L;;;;;N;;;;;
3734 1240;ETHIOPIC SYLLABLE QA;Lo;0;L;;;;;N;;;;;
3735 1241;ETHIOPIC SYLLABLE QU;Lo;0;L;;;;;N;;;;;
3736 1242;ETHIOPIC SYLLABLE QI;Lo;0;L;;;;;N;;;;;
3737 1243;ETHIOPIC SYLLABLE QAA;Lo;0;L;;;;;N;;;;;
3738 1244;ETHIOPIC SYLLABLE QEE;Lo;0;L;;;;;N;;;;;
3739 1245;ETHIOPIC SYLLABLE QE;Lo;0;L;;;;;N;;;;;
3740 1246;ETHIOPIC SYLLABLE QO;Lo;0;L;;;;;N;;;;;
3741 1247;ETHIOPIC SYLLABLE QOA;Lo;0;L;;;;;N;;;;;
3742 1248;ETHIOPIC SYLLABLE QWA;Lo;0;L;;;;;N;;;;;
3743 124A;ETHIOPIC SYLLABLE QWI;Lo;0;L;;;;;N;;;;;
3744 124B;ETHIOPIC SYLLABLE QWAA;Lo;0;L;;;;;N;;;;;
3745 124C;ETHIOPIC SYLLABLE QWEE;Lo;0;L;;;;;N;;;;;
3746 124D;ETHIOPIC SYLLABLE QWE;Lo;0;L;;;;;N;;;;;
3747 1250;ETHIOPIC SYLLABLE QHA;Lo;0;L;;;;;N;;;;;
3748 1251;ETHIOPIC SYLLABLE QHU;Lo;0;L;;;;;N;;;;;
3749 1252;ETHIOPIC SYLLABLE QHI;Lo;0;L;;;;;N;;;;;
3750 1253;ETHIOPIC SYLLABLE QHAA;Lo;0;L;;;;;N;;;;;
3751 1254;ETHIOPIC SYLLABLE QHEE;Lo;0;L;;;;;N;;;;;
3752 1255;ETHIOPIC SYLLABLE QHE;Lo;0;L;;;;;N;;;;;
3753 1256;ETHIOPIC SYLLABLE QHO;Lo;0;L;;;;;N;;;;;
3754 1258;ETHIOPIC SYLLABLE QHWA;Lo;0;L;;;;;N;;;;;
3755 125A;ETHIOPIC SYLLABLE QHWI;Lo;0;L;;;;;N;;;;;
3756 125B;ETHIOPIC SYLLABLE QHWAA;Lo;0;L;;;;;N;;;;;
3757 125C;ETHIOPIC SYLLABLE QHWEE;Lo;0;L;;;;;N;;;;;
3758 125D;ETHIOPIC SYLLABLE QHWE;Lo;0;L;;;;;N;;;;;
3759 1260;ETHIOPIC SYLLABLE BA;Lo;0;L;;;;;N;;;;;
3760 1261;ETHIOPIC SYLLABLE BU;Lo;0;L;;;;;N;;;;;
3761 1262;ETHIOPIC SYLLABLE BI;Lo;0;L;;;;;N;;;;;
3762 1263;ETHIOPIC SYLLABLE BAA;Lo;0;L;;;;;N;;;;;
3763 1264;ETHIOPIC SYLLABLE BEE;Lo;0;L;;;;;N;;;;;
3764 1265;ETHIOPIC SYLLABLE BE;Lo;0;L;;;;;N;;;;;
3765 1266;ETHIOPIC SYLLABLE BO;Lo;0;L;;;;;N;;;;;
3766 1267;ETHIOPIC SYLLABLE BWA;Lo;0;L;;;;;N;;;;;
3767 1268;ETHIOPIC SYLLABLE VA;Lo;0;L;;;;;N;;;;;
3768 1269;ETHIOPIC SYLLABLE VU;Lo;0;L;;;;;N;;;;;
3769 126A;ETHIOPIC SYLLABLE VI;Lo;0;L;;;;;N;;;;;
3770 126B;ETHIOPIC SYLLABLE VAA;Lo;0;L;;;;;N;;;;;
3771 126C;ETHIOPIC SYLLABLE VEE;Lo;0;L;;;;;N;;;;;
3772 126D;ETHIOPIC SYLLABLE VE;Lo;0;L;;;;;N;;;;;
3773 126E;ETHIOPIC SYLLABLE VO;Lo;0;L;;;;;N;;;;;
3774 126F;ETHIOPIC SYLLABLE VWA;Lo;0;L;;;;;N;;;;;
3775 1270;ETHIOPIC SYLLABLE TA;Lo;0;L;;;;;N;;;;;
3776 1271;ETHIOPIC SYLLABLE TU;Lo;0;L;;;;;N;;;;;
3777 1272;ETHIOPIC SYLLABLE TI;Lo;0;L;;;;;N;;;;;
3778 1273;ETHIOPIC SYLLABLE TAA;Lo;0;L;;;;;N;;;;;
3779 1274;ETHIOPIC SYLLABLE TEE;Lo;0;L;;;;;N;;;;;
3780 1275;ETHIOPIC SYLLABLE TE;Lo;0;L;;;;;N;;;;;
3781 1276;ETHIOPIC SYLLABLE TO;Lo;0;L;;;;;N;;;;;
3782 1277;ETHIOPIC SYLLABLE TWA;Lo;0;L;;;;;N;;;;;
3783 1278;ETHIOPIC SYLLABLE CA;Lo;0;L;;;;;N;;;;;
3784 1279;ETHIOPIC SYLLABLE CU;Lo;0;L;;;;;N;;;;;
3785 127A;ETHIOPIC SYLLABLE CI;Lo;0;L;;;;;N;;;;;
3786 127B;ETHIOPIC SYLLABLE CAA;Lo;0;L;;;;;N;;;;;
3787 127C;ETHIOPIC SYLLABLE CEE;Lo;0;L;;;;;N;;;;;
3788 127D;ETHIOPIC SYLLABLE CE;Lo;0;L;;;;;N;;;;;
3789 127E;ETHIOPIC SYLLABLE CO;Lo;0;L;;;;;N;;;;;
3790 127F;ETHIOPIC SYLLABLE CWA;Lo;0;L;;;;;N;;;;;
3791 1280;ETHIOPIC SYLLABLE XA;Lo;0;L;;;;;N;;;;;
3792 1281;ETHIOPIC SYLLABLE XU;Lo;0;L;;;;;N;;;;;
3793 1282;ETHIOPIC SYLLABLE XI;Lo;0;L;;;;;N;;;;;
3794 1283;ETHIOPIC SYLLABLE XAA;Lo;0;L;;;;;N;;;;;
3795 1284;ETHIOPIC SYLLABLE XEE;Lo;0;L;;;;;N;;;;;
3796 1285;ETHIOPIC SYLLABLE XE;Lo;0;L;;;;;N;;;;;
3797 1286;ETHIOPIC SYLLABLE XO;Lo;0;L;;;;;N;;;;;
3798 1287;ETHIOPIC SYLLABLE XOA;Lo;0;L;;;;;N;;;;;
3799 1288;ETHIOPIC SYLLABLE XWA;Lo;0;L;;;;;N;;;;;
3800 128A;ETHIOPIC SYLLABLE XWI;Lo;0;L;;;;;N;;;;;
3801 128B;ETHIOPIC SYLLABLE XWAA;Lo;0;L;;;;;N;;;;;
3802 128C;ETHIOPIC SYLLABLE XWEE;Lo;0;L;;;;;N;;;;;
3803 128D;ETHIOPIC SYLLABLE XWE;Lo;0;L;;;;;N;;;;;
3804 1290;ETHIOPIC SYLLABLE NA;Lo;0;L;;;;;N;;;;;
3805 1291;ETHIOPIC SYLLABLE NU;Lo;0;L;;;;;N;;;;;
3806 1292;ETHIOPIC SYLLABLE NI;Lo;0;L;;;;;N;;;;;
3807 1293;ETHIOPIC SYLLABLE NAA;Lo;0;L;;;;;N;;;;;
3808 1294;ETHIOPIC SYLLABLE NEE;Lo;0;L;;;;;N;;;;;
3809 1295;ETHIOPIC SYLLABLE NE;Lo;0;L;;;;;N;;;;;
3810 1296;ETHIOPIC SYLLABLE NO;Lo;0;L;;;;;N;;;;;
3811 1297;ETHIOPIC SYLLABLE NWA;Lo;0;L;;;;;N;;;;;
3812 1298;ETHIOPIC SYLLABLE NYA;Lo;0;L;;;;;N;;;;;
3813 1299;ETHIOPIC SYLLABLE NYU;Lo;0;L;;;;;N;;;;;
3814 129A;ETHIOPIC SYLLABLE NYI;Lo;0;L;;;;;N;;;;;
3815 129B;ETHIOPIC SYLLABLE NYAA;Lo;0;L;;;;;N;;;;;
3816 129C;ETHIOPIC SYLLABLE NYEE;Lo;0;L;;;;;N;;;;;
3817 129D;ETHIOPIC SYLLABLE NYE;Lo;0;L;;;;;N;;;;;
3818 129E;ETHIOPIC SYLLABLE NYO;Lo;0;L;;;;;N;;;;;
3819 129F;ETHIOPIC SYLLABLE NYWA;Lo;0;L;;;;;N;;;;;
3820 12A0;ETHIOPIC SYLLABLE GLOTTAL A;Lo;0;L;;;;;N;;;;;
3821 12A1;ETHIOPIC SYLLABLE GLOTTAL U;Lo;0;L;;;;;N;;;;;
3822 12A2;ETHIOPIC SYLLABLE GLOTTAL I;Lo;0;L;;;;;N;;;;;
3823 12A3;ETHIOPIC SYLLABLE GLOTTAL AA;Lo;0;L;;;;;N;;;;;
3824 12A4;ETHIOPIC SYLLABLE GLOTTAL EE;Lo;0;L;;;;;N;;;;;
3825 12A5;ETHIOPIC SYLLABLE GLOTTAL E;Lo;0;L;;;;;N;;;;;
3826 12A6;ETHIOPIC SYLLABLE GLOTTAL O;Lo;0;L;;;;;N;;;;;
3827 12A7;ETHIOPIC SYLLABLE GLOTTAL WA;Lo;0;L;;;;;N;;;;;
3828 12A8;ETHIOPIC SYLLABLE KA;Lo;0;L;;;;;N;;;;;
3829 12A9;ETHIOPIC SYLLABLE KU;Lo;0;L;;;;;N;;;;;
3830 12AA;ETHIOPIC SYLLABLE KI;Lo;0;L;;;;;N;;;;;
3831 12AB;ETHIOPIC SYLLABLE KAA;Lo;0;L;;;;;N;;;;;
3832 12AC;ETHIOPIC SYLLABLE KEE;Lo;0;L;;;;;N;;;;;
3833 12AD;ETHIOPIC SYLLABLE KE;Lo;0;L;;;;;N;;;;;
3834 12AE;ETHIOPIC SYLLABLE KO;Lo;0;L;;;;;N;;;;;
3835 12AF;ETHIOPIC SYLLABLE KOA;Lo;0;L;;;;;N;;;;;
3836 12B0;ETHIOPIC SYLLABLE KWA;Lo;0;L;;;;;N;;;;;
3837 12B2;ETHIOPIC SYLLABLE KWI;Lo;0;L;;;;;N;;;;;
3838 12B3;ETHIOPIC SYLLABLE KWAA;Lo;0;L;;;;;N;;;;;
3839 12B4;ETHIOPIC SYLLABLE KWEE;Lo;0;L;;;;;N;;;;;
3840 12B5;ETHIOPIC SYLLABLE KWE;Lo;0;L;;;;;N;;;;;
3841 12B8;ETHIOPIC SYLLABLE KXA;Lo;0;L;;;;;N;;;;;
3842 12B9;ETHIOPIC SYLLABLE KXU;Lo;0;L;;;;;N;;;;;
3843 12BA;ETHIOPIC SYLLABLE KXI;Lo;0;L;;;;;N;;;;;
3844 12BB;ETHIOPIC SYLLABLE KXAA;Lo;0;L;;;;;N;;;;;
3845 12BC;ETHIOPIC SYLLABLE KXEE;Lo;0;L;;;;;N;;;;;
3846 12BD;ETHIOPIC SYLLABLE KXE;Lo;0;L;;;;;N;;;;;
3847 12BE;ETHIOPIC SYLLABLE KXO;Lo;0;L;;;;;N;;;;;
3848 12C0;ETHIOPIC SYLLABLE KXWA;Lo;0;L;;;;;N;;;;;
3849 12C2;ETHIOPIC SYLLABLE KXWI;Lo;0;L;;;;;N;;;;;
3850 12C3;ETHIOPIC SYLLABLE KXWAA;Lo;0;L;;;;;N;;;;;
3851 12C4;ETHIOPIC SYLLABLE KXWEE;Lo;0;L;;;;;N;;;;;
3852 12C5;ETHIOPIC SYLLABLE KXWE;Lo;0;L;;;;;N;;;;;
3853 12C8;ETHIOPIC SYLLABLE WA;Lo;0;L;;;;;N;;;;;
3854 12C9;ETHIOPIC SYLLABLE WU;Lo;0;L;;;;;N;;;;;
3855 12CA;ETHIOPIC SYLLABLE WI;Lo;0;L;;;;;N;;;;;
3856 12CB;ETHIOPIC SYLLABLE WAA;Lo;0;L;;;;;N;;;;;
3857 12CC;ETHIOPIC SYLLABLE WEE;Lo;0;L;;;;;N;;;;;
3858 12CD;ETHIOPIC SYLLABLE WE;Lo;0;L;;;;;N;;;;;
3859 12CE;ETHIOPIC SYLLABLE WO;Lo;0;L;;;;;N;;;;;
3860 12CF;ETHIOPIC SYLLABLE WOA;Lo;0;L;;;;;N;;;;;
3861 12D0;ETHIOPIC SYLLABLE PHARYNGEAL A;Lo;0;L;;;;;N;;;;;
3862 12D1;ETHIOPIC SYLLABLE PHARYNGEAL U;Lo;0;L;;;;;N;;;;;
3863 12D2;ETHIOPIC SYLLABLE PHARYNGEAL I;Lo;0;L;;;;;N;;;;;
3864 12D3;ETHIOPIC SYLLABLE PHARYNGEAL AA;Lo;0;L;;;;;N;;;;;
3865 12D4;ETHIOPIC SYLLABLE PHARYNGEAL EE;Lo;0;L;;;;;N;;;;;
3866 12D5;ETHIOPIC SYLLABLE PHARYNGEAL E;Lo;0;L;;;;;N;;;;;
3867 12D6;ETHIOPIC SYLLABLE PHARYNGEAL O;Lo;0;L;;;;;N;;;;;
3868 12D8;ETHIOPIC SYLLABLE ZA;Lo;0;L;;;;;N;;;;;
3869 12D9;ETHIOPIC SYLLABLE ZU;Lo;0;L;;;;;N;;;;;
3870 12DA;ETHIOPIC SYLLABLE ZI;Lo;0;L;;;;;N;;;;;
3871 12DB;ETHIOPIC SYLLABLE ZAA;Lo;0;L;;;;;N;;;;;
3872 12DC;ETHIOPIC SYLLABLE ZEE;Lo;0;L;;;;;N;;;;;
3873 12DD;ETHIOPIC SYLLABLE ZE;Lo;0;L;;;;;N;;;;;
3874 12DE;ETHIOPIC SYLLABLE ZO;Lo;0;L;;;;;N;;;;;
3875 12DF;ETHIOPIC SYLLABLE ZWA;Lo;0;L;;;;;N;;;;;
3876 12E0;ETHIOPIC SYLLABLE ZHA;Lo;0;L;;;;;N;;;;;
3877 12E1;ETHIOPIC SYLLABLE ZHU;Lo;0;L;;;;;N;;;;;
3878 12E2;ETHIOPIC SYLLABLE ZHI;Lo;0;L;;;;;N;;;;;
3879 12E3;ETHIOPIC SYLLABLE ZHAA;Lo;0;L;;;;;N;;;;;
3880 12E4;ETHIOPIC SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;;
3881 12E5;ETHIOPIC SYLLABLE ZHE;Lo;0;L;;;;;N;;;;;
3882 12E6;ETHIOPIC SYLLABLE ZHO;Lo;0;L;;;;;N;;;;;
3883 12E7;ETHIOPIC SYLLABLE ZHWA;Lo;0;L;;;;;N;;;;;
3884 12E8;ETHIOPIC SYLLABLE YA;Lo;0;L;;;;;N;;;;;
3885 12E9;ETHIOPIC SYLLABLE YU;Lo;0;L;;;;;N;;;;;
3886 12EA;ETHIOPIC SYLLABLE YI;Lo;0;L;;;;;N;;;;;
3887 12EB;ETHIOPIC SYLLABLE YAA;Lo;0;L;;;;;N;;;;;
3888 12EC;ETHIOPIC SYLLABLE YEE;Lo;0;L;;;;;N;;;;;
3889 12ED;ETHIOPIC SYLLABLE YE;Lo;0;L;;;;;N;;;;;
3890 12EE;ETHIOPIC SYLLABLE YO;Lo;0;L;;;;;N;;;;;
3891 12EF;ETHIOPIC SYLLABLE YOA;Lo;0;L;;;;;N;;;;;
3892 12F0;ETHIOPIC SYLLABLE DA;Lo;0;L;;;;;N;;;;;
3893 12F1;ETHIOPIC SYLLABLE DU;Lo;0;L;;;;;N;;;;;
3894 12F2;ETHIOPIC SYLLABLE DI;Lo;0;L;;;;;N;;;;;
3895 12F3;ETHIOPIC SYLLABLE DAA;Lo;0;L;;;;;N;;;;;
3896 12F4;ETHIOPIC SYLLABLE DEE;Lo;0;L;;;;;N;;;;;
3897 12F5;ETHIOPIC SYLLABLE DE;Lo;0;L;;;;;N;;;;;
3898 12F6;ETHIOPIC SYLLABLE DO;Lo;0;L;;;;;N;;;;;
3899 12F7;ETHIOPIC SYLLABLE DWA;Lo;0;L;;;;;N;;;;;
3900 12F8;ETHIOPIC SYLLABLE DDA;Lo;0;L;;;;;N;;;;;
3901 12F9;ETHIOPIC SYLLABLE DDU;Lo;0;L;;;;;N;;;;;
3902 12FA;ETHIOPIC SYLLABLE DDI;Lo;0;L;;;;;N;;;;;
3903 12FB;ETHIOPIC SYLLABLE DDAA;Lo;0;L;;;;;N;;;;;
3904 12FC;ETHIOPIC SYLLABLE DDEE;Lo;0;L;;;;;N;;;;;
3905 12FD;ETHIOPIC SYLLABLE DDE;Lo;0;L;;;;;N;;;;;
3906 12FE;ETHIOPIC SYLLABLE DDO;Lo;0;L;;;;;N;;;;;
3907 12FF;ETHIOPIC SYLLABLE DDWA;Lo;0;L;;;;;N;;;;;
3908 1300;ETHIOPIC SYLLABLE JA;Lo;0;L;;;;;N;;;;;
3909 1301;ETHIOPIC SYLLABLE JU;Lo;0;L;;;;;N;;;;;
3910 1302;ETHIOPIC SYLLABLE JI;Lo;0;L;;;;;N;;;;;
3911 1303;ETHIOPIC SYLLABLE JAA;Lo;0;L;;;;;N;;;;;
3912 1304;ETHIOPIC SYLLABLE JEE;Lo;0;L;;;;;N;;;;;
3913 1305;ETHIOPIC SYLLABLE JE;Lo;0;L;;;;;N;;;;;
3914 1306;ETHIOPIC SYLLABLE JO;Lo;0;L;;;;;N;;;;;
3915 1307;ETHIOPIC SYLLABLE JWA;Lo;0;L;;;;;N;;;;;
3916 1308;ETHIOPIC SYLLABLE GA;Lo;0;L;;;;;N;;;;;
3917 1309;ETHIOPIC SYLLABLE GU;Lo;0;L;;;;;N;;;;;
3918 130A;ETHIOPIC SYLLABLE GI;Lo;0;L;;;;;N;;;;;
3919 130B;ETHIOPIC SYLLABLE GAA;Lo;0;L;;;;;N;;;;;
3920 130C;ETHIOPIC SYLLABLE GEE;Lo;0;L;;;;;N;;;;;
3921 130D;ETHIOPIC SYLLABLE GE;Lo;0;L;;;;;N;;;;;
3922 130E;ETHIOPIC SYLLABLE GO;Lo;0;L;;;;;N;;;;;
3923 130F;ETHIOPIC SYLLABLE GOA;Lo;0;L;;;;;N;;;;;
3924 1310;ETHIOPIC SYLLABLE GWA;Lo;0;L;;;;;N;;;;;
3925 1312;ETHIOPIC SYLLABLE GWI;Lo;0;L;;;;;N;;;;;
3926 1313;ETHIOPIC SYLLABLE GWAA;Lo;0;L;;;;;N;;;;;
3927 1314;ETHIOPIC SYLLABLE GWEE;Lo;0;L;;;;;N;;;;;
3928 1315;ETHIOPIC SYLLABLE GWE;Lo;0;L;;;;;N;;;;;
3929 1318;ETHIOPIC SYLLABLE GGA;Lo;0;L;;;;;N;;;;;
3930 1319;ETHIOPIC SYLLABLE GGU;Lo;0;L;;;;;N;;;;;
3931 131A;ETHIOPIC SYLLABLE GGI;Lo;0;L;;;;;N;;;;;
3932 131B;ETHIOPIC SYLLABLE GGAA;Lo;0;L;;;;;N;;;;;
3933 131C;ETHIOPIC SYLLABLE GGEE;Lo;0;L;;;;;N;;;;;
3934 131D;ETHIOPIC SYLLABLE GGE;Lo;0;L;;;;;N;;;;;
3935 131E;ETHIOPIC SYLLABLE GGO;Lo;0;L;;;;;N;;;;;
3936 131F;ETHIOPIC SYLLABLE GGWAA;Lo;0;L;;;;;N;;;;;
3937 1320;ETHIOPIC SYLLABLE THA;Lo;0;L;;;;;N;;;;;
3938 1321;ETHIOPIC SYLLABLE THU;Lo;0;L;;;;;N;;;;;
3939 1322;ETHIOPIC SYLLABLE THI;Lo;0;L;;;;;N;;;;;
3940 1323;ETHIOPIC SYLLABLE THAA;Lo;0;L;;;;;N;;;;;
3941 1324;ETHIOPIC SYLLABLE THEE;Lo;0;L;;;;;N;;;;;
3942 1325;ETHIOPIC SYLLABLE THE;Lo;0;L;;;;;N;;;;;
3943 1326;ETHIOPIC SYLLABLE THO;Lo;0;L;;;;;N;;;;;
3944 1327;ETHIOPIC SYLLABLE THWA;Lo;0;L;;;;;N;;;;;
3945 1328;ETHIOPIC SYLLABLE CHA;Lo;0;L;;;;;N;;;;;
3946 1329;ETHIOPIC SYLLABLE CHU;Lo;0;L;;;;;N;;;;;
3947 132A;ETHIOPIC SYLLABLE CHI;Lo;0;L;;;;;N;;;;;
3948 132B;ETHIOPIC SYLLABLE CHAA;Lo;0;L;;;;;N;;;;;
3949 132C;ETHIOPIC SYLLABLE CHEE;Lo;0;L;;;;;N;;;;;
3950 132D;ETHIOPIC SYLLABLE CHE;Lo;0;L;;;;;N;;;;;
3951 132E;ETHIOPIC SYLLABLE CHO;Lo;0;L;;;;;N;;;;;
3952 132F;ETHIOPIC SYLLABLE CHWA;Lo;0;L;;;;;N;;;;;
3953 1330;ETHIOPIC SYLLABLE PHA;Lo;0;L;;;;;N;;;;;
3954 1331;ETHIOPIC SYLLABLE PHU;Lo;0;L;;;;;N;;;;;
3955 1332;ETHIOPIC SYLLABLE PHI;Lo;0;L;;;;;N;;;;;
3956 1333;ETHIOPIC SYLLABLE PHAA;Lo;0;L;;;;;N;;;;;
3957 1334;ETHIOPIC SYLLABLE PHEE;Lo;0;L;;;;;N;;;;;
3958 1335;ETHIOPIC SYLLABLE PHE;Lo;0;L;;;;;N;;;;;
3959 1336;ETHIOPIC SYLLABLE PHO;Lo;0;L;;;;;N;;;;;
3960 1337;ETHIOPIC SYLLABLE PHWA;Lo;0;L;;;;;N;;;;;
3961 1338;ETHIOPIC SYLLABLE TSA;Lo;0;L;;;;;N;;;;;
3962 1339;ETHIOPIC SYLLABLE TSU;Lo;0;L;;;;;N;;;;;
3963 133A;ETHIOPIC SYLLABLE TSI;Lo;0;L;;;;;N;;;;;
3964 133B;ETHIOPIC SYLLABLE TSAA;Lo;0;L;;;;;N;;;;;
3965 133C;ETHIOPIC SYLLABLE TSEE;Lo;0;L;;;;;N;;;;;
3966 133D;ETHIOPIC SYLLABLE TSE;Lo;0;L;;;;;N;;;;;
3967 133E;ETHIOPIC SYLLABLE TSO;Lo;0;L;;;;;N;;;;;
3968 133F;ETHIOPIC SYLLABLE TSWA;Lo;0;L;;;;;N;;;;;
3969 1340;ETHIOPIC SYLLABLE TZA;Lo;0;L;;;;;N;;;;;
3970 1341;ETHIOPIC SYLLABLE TZU;Lo;0;L;;;;;N;;;;;
3971 1342;ETHIOPIC SYLLABLE TZI;Lo;0;L;;;;;N;;;;;
3972 1343;ETHIOPIC SYLLABLE TZAA;Lo;0;L;;;;;N;;;;;
3973 1344;ETHIOPIC SYLLABLE TZEE;Lo;0;L;;;;;N;;;;;
3974 1345;ETHIOPIC SYLLABLE TZE;Lo;0;L;;;;;N;;;;;
3975 1346;ETHIOPIC SYLLABLE TZO;Lo;0;L;;;;;N;;;;;
3976 1347;ETHIOPIC SYLLABLE TZOA;Lo;0;L;;;;;N;;;;;
3977 1348;ETHIOPIC SYLLABLE FA;Lo;0;L;;;;;N;;;;;
3978 1349;ETHIOPIC SYLLABLE FU;Lo;0;L;;;;;N;;;;;
3979 134A;ETHIOPIC SYLLABLE FI;Lo;0;L;;;;;N;;;;;
3980 134B;ETHIOPIC SYLLABLE FAA;Lo;0;L;;;;;N;;;;;
3981 134C;ETHIOPIC SYLLABLE FEE;Lo;0;L;;;;;N;;;;;
3982 134D;ETHIOPIC SYLLABLE FE;Lo;0;L;;;;;N;;;;;
3983 134E;ETHIOPIC SYLLABLE FO;Lo;0;L;;;;;N;;;;;
3984 134F;ETHIOPIC SYLLABLE FWA;Lo;0;L;;;;;N;;;;;
3985 1350;ETHIOPIC SYLLABLE PA;Lo;0;L;;;;;N;;;;;
3986 1351;ETHIOPIC SYLLABLE PU;Lo;0;L;;;;;N;;;;;
3987 1352;ETHIOPIC SYLLABLE PI;Lo;0;L;;;;;N;;;;;
3988 1353;ETHIOPIC SYLLABLE PAA;Lo;0;L;;;;;N;;;;;
3989 1354;ETHIOPIC SYLLABLE PEE;Lo;0;L;;;;;N;;;;;
3990 1355;ETHIOPIC SYLLABLE PE;Lo;0;L;;;;;N;;;;;
3991 1356;ETHIOPIC SYLLABLE PO;Lo;0;L;;;;;N;;;;;
3992 1357;ETHIOPIC SYLLABLE PWA;Lo;0;L;;;;;N;;;;;
3993 1358;ETHIOPIC SYLLABLE RYA;Lo;0;L;;;;;N;;;;;
3994 1359;ETHIOPIC SYLLABLE MYA;Lo;0;L;;;;;N;;;;;
3995 135A;ETHIOPIC SYLLABLE FYA;Lo;0;L;;;;;N;;;;;
3996 135F;ETHIOPIC COMBINING GEMINATION MARK;Mn;230;NSM;;;;;N;;;;;
3997 1360;ETHIOPIC SECTION MARK;So;0;L;;;;;N;;;;;
3998 1361;ETHIOPIC WORDSPACE;Po;0;L;;;;;N;;;;;
3999 1362;ETHIOPIC FULL STOP;Po;0;L;;;;;N;;;;;
4000 1363;ETHIOPIC COMMA;Po;0;L;;;;;N;;;;;
4001 1364;ETHIOPIC SEMICOLON;Po;0;L;;;;;N;;;;;
4002 1365;ETHIOPIC COLON;Po;0;L;;;;;N;;;;;
4003 1366;ETHIOPIC PREFACE COLON;Po;0;L;;;;;N;;;;;
4004 1367;ETHIOPIC QUESTION MARK;Po;0;L;;;;;N;;;;;
4005 1368;ETHIOPIC PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;;
4006 1369;ETHIOPIC DIGIT ONE;No;0;L;;;1;1;N;;;;;
4007 136A;ETHIOPIC DIGIT TWO;No;0;L;;;2;2;N;;;;;
4008 136B;ETHIOPIC DIGIT THREE;No;0;L;;;3;3;N;;;;;
4009 136C;ETHIOPIC DIGIT FOUR;No;0;L;;;4;4;N;;;;;
4010 136D;ETHIOPIC DIGIT FIVE;No;0;L;;;5;5;N;;;;;
4011 136E;ETHIOPIC DIGIT SIX;No;0;L;;;6;6;N;;;;;
4012 136F;ETHIOPIC DIGIT SEVEN;No;0;L;;;7;7;N;;;;;
4013 1370;ETHIOPIC DIGIT EIGHT;No;0;L;;;8;8;N;;;;;
4014 1371;ETHIOPIC DIGIT NINE;No;0;L;;;9;9;N;;;;;
4015 1372;ETHIOPIC NUMBER TEN;No;0;L;;;;10;N;;;;;
4016 1373;ETHIOPIC NUMBER TWENTY;No;0;L;;;;20;N;;;;;
4017 1374;ETHIOPIC NUMBER THIRTY;No;0;L;;;;30;N;;;;;
4018 1375;ETHIOPIC NUMBER FORTY;No;0;L;;;;40;N;;;;;
4019 1376;ETHIOPIC NUMBER FIFTY;No;0;L;;;;50;N;;;;;
4020 1377;ETHIOPIC NUMBER SIXTY;No;0;L;;;;60;N;;;;;
4021 1378;ETHIOPIC NUMBER SEVENTY;No;0;L;;;;70;N;;;;;
4022 1379;ETHIOPIC NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
4023 137A;ETHIOPIC NUMBER NINETY;No;0;L;;;;90;N;;;;;
4024 137B;ETHIOPIC NUMBER HUNDRED;No;0;L;;;;100;N;;;;;
4025 137C;ETHIOPIC NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;;
4026 1380;ETHIOPIC SYLLABLE SEBATBEIT MWA;Lo;0;L;;;;;N;;;;;
4027 1381;ETHIOPIC SYLLABLE MWI;Lo;0;L;;;;;N;;;;;
4028 1382;ETHIOPIC SYLLABLE MWEE;Lo;0;L;;;;;N;;;;;
4029 1383;ETHIOPIC SYLLABLE MWE;Lo;0;L;;;;;N;;;;;
4030 1384;ETHIOPIC SYLLABLE SEBATBEIT BWA;Lo;0;L;;;;;N;;;;;
4031 1385;ETHIOPIC SYLLABLE BWI;Lo;0;L;;;;;N;;;;;
4032 1386;ETHIOPIC SYLLABLE BWEE;Lo;0;L;;;;;N;;;;;
4033 1387;ETHIOPIC SYLLABLE BWE;Lo;0;L;;;;;N;;;;;
4034 1388;ETHIOPIC SYLLABLE SEBATBEIT FWA;Lo;0;L;;;;;N;;;;;
4035 1389;ETHIOPIC SYLLABLE FWI;Lo;0;L;;;;;N;;;;;
4036 138A;ETHIOPIC SYLLABLE FWEE;Lo;0;L;;;;;N;;;;;
4037 138B;ETHIOPIC SYLLABLE FWE;Lo;0;L;;;;;N;;;;;
4038 138C;ETHIOPIC SYLLABLE SEBATBEIT PWA;Lo;0;L;;;;;N;;;;;
4039 138D;ETHIOPIC SYLLABLE PWI;Lo;0;L;;;;;N;;;;;
4040 138E;ETHIOPIC SYLLABLE PWEE;Lo;0;L;;;;;N;;;;;
4041 138F;ETHIOPIC SYLLABLE PWE;Lo;0;L;;;;;N;;;;;
4042 1390;ETHIOPIC TONAL MARK YIZET;So;0;ON;;;;;N;;;;;
4043 1391;ETHIOPIC TONAL MARK DERET;So;0;ON;;;;;N;;;;;
4044 1392;ETHIOPIC TONAL MARK RIKRIK;So;0;ON;;;;;N;;;;;
4045 1393;ETHIOPIC TONAL MARK SHORT RIKRIK;So;0;ON;;;;;N;;;;;
4046 1394;ETHIOPIC TONAL MARK DIFAT;So;0;ON;;;;;N;;;;;
4047 1395;ETHIOPIC TONAL MARK KENAT;So;0;ON;;;;;N;;;;;
4048 1396;ETHIOPIC TONAL MARK CHIRET;So;0;ON;;;;;N;;;;;
4049 1397;ETHIOPIC TONAL MARK HIDET;So;0;ON;;;;;N;;;;;
4050 1398;ETHIOPIC TONAL MARK DERET-HIDET;So;0;ON;;;;;N;;;;;
4051 1399;ETHIOPIC TONAL MARK KURT;So;0;ON;;;;;N;;;;;
4052 13A0;CHEROKEE LETTER A;Lo;0;L;;;;;N;;;;;
4053 13A1;CHEROKEE LETTER E;Lo;0;L;;;;;N;;;;;
4054 13A2;CHEROKEE LETTER I;Lo;0;L;;;;;N;;;;;
4055 13A3;CHEROKEE LETTER O;Lo;0;L;;;;;N;;;;;
4056 13A4;CHEROKEE LETTER U;Lo;0;L;;;;;N;;;;;
4057 13A5;CHEROKEE LETTER V;Lo;0;L;;;;;N;;;;;
4058 13A6;CHEROKEE LETTER GA;Lo;0;L;;;;;N;;;;;
4059 13A7;CHEROKEE LETTER KA;Lo;0;L;;;;;N;;;;;
4060 13A8;CHEROKEE LETTER GE;Lo;0;L;;;;;N;;;;;
4061 13A9;CHEROKEE LETTER GI;Lo;0;L;;;;;N;;;;;
4062 13AA;CHEROKEE LETTER GO;Lo;0;L;;;;;N;;;;;
4063 13AB;CHEROKEE LETTER GU;Lo;0;L;;;;;N;;;;;
4064 13AC;CHEROKEE LETTER GV;Lo;0;L;;;;;N;;;;;
4065 13AD;CHEROKEE LETTER HA;Lo;0;L;;;;;N;;;;;
4066 13AE;CHEROKEE LETTER HE;Lo;0;L;;;;;N;;;;;
4067 13AF;CHEROKEE LETTER HI;Lo;0;L;;;;;N;;;;;
4068 13B0;CHEROKEE LETTER HO;Lo;0;L;;;;;N;;;;;
4069 13B1;CHEROKEE LETTER HU;Lo;0;L;;;;;N;;;;;
4070 13B2;CHEROKEE LETTER HV;Lo;0;L;;;;;N;;;;;
4071 13B3;CHEROKEE LETTER LA;Lo;0;L;;;;;N;;;;;
4072 13B4;CHEROKEE LETTER LE;Lo;0;L;;;;;N;;;;;
4073 13B5;CHEROKEE LETTER LI;Lo;0;L;;;;;N;;;;;
4074 13B6;CHEROKEE LETTER LO;Lo;0;L;;;;;N;;;;;
4075 13B7;CHEROKEE LETTER LU;Lo;0;L;;;;;N;;;;;
4076 13B8;CHEROKEE LETTER LV;Lo;0;L;;;;;N;;;;;
4077 13B9;CHEROKEE LETTER MA;Lo;0;L;;;;;N;;;;;
4078 13BA;CHEROKEE LETTER ME;Lo;0;L;;;;;N;;;;;
4079 13BB;CHEROKEE LETTER MI;Lo;0;L;;;;;N;;;;;
4080 13BC;CHEROKEE LETTER MO;Lo;0;L;;;;;N;;;;;
4081 13BD;CHEROKEE LETTER MU;Lo;0;L;;;;;N;;;;;
4082 13BE;CHEROKEE LETTER NA;Lo;0;L;;;;;N;;;;;
4083 13BF;CHEROKEE LETTER HNA;Lo;0;L;;;;;N;;;;;
4084 13C0;CHEROKEE LETTER NAH;Lo;0;L;;;;;N;;;;;
4085 13C1;CHEROKEE LETTER NE;Lo;0;L;;;;;N;;;;;
4086 13C2;CHEROKEE LETTER NI;Lo;0;L;;;;;N;;;;;
4087 13C3;CHEROKEE LETTER NO;Lo;0;L;;;;;N;;;;;
4088 13C4;CHEROKEE LETTER NU;Lo;0;L;;;;;N;;;;;
4089 13C5;CHEROKEE LETTER NV;Lo;0;L;;;;;N;;;;;
4090 13C6;CHEROKEE LETTER QUA;Lo;0;L;;;;;N;;;;;
4091 13C7;CHEROKEE LETTER QUE;Lo;0;L;;;;;N;;;;;
4092 13C8;CHEROKEE LETTER QUI;Lo;0;L;;;;;N;;;;;
4093 13C9;CHEROKEE LETTER QUO;Lo;0;L;;;;;N;;;;;
4094 13CA;CHEROKEE LETTER QUU;Lo;0;L;;;;;N;;;;;
4095 13CB;CHEROKEE LETTER QUV;Lo;0;L;;;;;N;;;;;
4096 13CC;CHEROKEE LETTER SA;Lo;0;L;;;;;N;;;;;
4097 13CD;CHEROKEE LETTER S;Lo;0;L;;;;;N;;;;;
4098 13CE;CHEROKEE LETTER SE;Lo;0;L;;;;;N;;;;;
4099 13CF;CHEROKEE LETTER SI;Lo;0;L;;;;;N;;;;;
4100 13D0;CHEROKEE LETTER SO;Lo;0;L;;;;;N;;;;;
4101 13D1;CHEROKEE LETTER SU;Lo;0;L;;;;;N;;;;;
4102 13D2;CHEROKEE LETTER SV;Lo;0;L;;;;;N;;;;;
4103 13D3;CHEROKEE LETTER DA;Lo;0;L;;;;;N;;;;;
4104 13D4;CHEROKEE LETTER TA;Lo;0;L;;;;;N;;;;;
4105 13D5;CHEROKEE LETTER DE;Lo;0;L;;;;;N;;;;;
4106 13D6;CHEROKEE LETTER TE;Lo;0;L;;;;;N;;;;;
4107 13D7;CHEROKEE LETTER DI;Lo;0;L;;;;;N;;;;;
4108 13D8;CHEROKEE LETTER TI;Lo;0;L;;;;;N;;;;;
4109 13D9;CHEROKEE LETTER DO;Lo;0;L;;;;;N;;;;;
4110 13DA;CHEROKEE LETTER DU;Lo;0;L;;;;;N;;;;;
4111 13DB;CHEROKEE LETTER DV;Lo;0;L;;;;;N;;;;;
4112 13DC;CHEROKEE LETTER DLA;Lo;0;L;;;;;N;;;;;
4113 13DD;CHEROKEE LETTER TLA;Lo;0;L;;;;;N;;;;;
4114 13DE;CHEROKEE LETTER TLE;Lo;0;L;;;;;N;;;;;
4115 13DF;CHEROKEE LETTER TLI;Lo;0;L;;;;;N;;;;;
4116 13E0;CHEROKEE LETTER TLO;Lo;0;L;;;;;N;;;;;
4117 13E1;CHEROKEE LETTER TLU;Lo;0;L;;;;;N;;;;;
4118 13E2;CHEROKEE LETTER TLV;Lo;0;L;;;;;N;;;;;
4119 13E3;CHEROKEE LETTER TSA;Lo;0;L;;;;;N;;;;;
4120 13E4;CHEROKEE LETTER TSE;Lo;0;L;;;;;N;;;;;
4121 13E5;CHEROKEE LETTER TSI;Lo;0;L;;;;;N;;;;;
4122 13E6;CHEROKEE LETTER TSO;Lo;0;L;;;;;N;;;;;
4123 13E7;CHEROKEE LETTER TSU;Lo;0;L;;;;;N;;;;;
4124 13E8;CHEROKEE LETTER TSV;Lo;0;L;;;;;N;;;;;
4125 13E9;CHEROKEE LETTER WA;Lo;0;L;;;;;N;;;;;
4126 13EA;CHEROKEE LETTER WE;Lo;0;L;;;;;N;;;;;
4127 13EB;CHEROKEE LETTER WI;Lo;0;L;;;;;N;;;;;
4128 13EC;CHEROKEE LETTER WO;Lo;0;L;;;;;N;;;;;
4129 13ED;CHEROKEE LETTER WU;Lo;0;L;;;;;N;;;;;
4130 13EE;CHEROKEE LETTER WV;Lo;0;L;;;;;N;;;;;
4131 13EF;CHEROKEE LETTER YA;Lo;0;L;;;;;N;;;;;
4132 13F0;CHEROKEE LETTER YE;Lo;0;L;;;;;N;;;;;
4133 13F1;CHEROKEE LETTER YI;Lo;0;L;;;;;N;;;;;
4134 13F2;CHEROKEE LETTER YO;Lo;0;L;;;;;N;;;;;
4135 13F3;CHEROKEE LETTER YU;Lo;0;L;;;;;N;;;;;
4136 13F4;CHEROKEE LETTER YV;Lo;0;L;;;;;N;;;;;
4137 1401;CANADIAN SYLLABICS E;Lo;0;L;;;;;N;;;;;
4138 1402;CANADIAN SYLLABICS AAI;Lo;0;L;;;;;N;;;;;
4139 1403;CANADIAN SYLLABICS I;Lo;0;L;;;;;N;;;;;
4140 1404;CANADIAN SYLLABICS II;Lo;0;L;;;;;N;;;;;
4141 1405;CANADIAN SYLLABICS O;Lo;0;L;;;;;N;;;;;
4142 1406;CANADIAN SYLLABICS OO;Lo;0;L;;;;;N;;;;;
4143 1407;CANADIAN SYLLABICS Y-CREE OO;Lo;0;L;;;;;N;;;;;
4144 1408;CANADIAN SYLLABICS CARRIER EE;Lo;0;L;;;;;N;;;;;
4145 1409;CANADIAN SYLLABICS CARRIER I;Lo;0;L;;;;;N;;;;;
4146 140A;CANADIAN SYLLABICS A;Lo;0;L;;;;;N;;;;;
4147 140B;CANADIAN SYLLABICS AA;Lo;0;L;;;;;N;;;;;
4148 140C;CANADIAN SYLLABICS WE;Lo;0;L;;;;;N;;;;;
4149 140D;CANADIAN SYLLABICS WEST-CREE WE;Lo;0;L;;;;;N;;;;;
4150 140E;CANADIAN SYLLABICS WI;Lo;0;L;;;;;N;;;;;
4151 140F;CANADIAN SYLLABICS WEST-CREE WI;Lo;0;L;;;;;N;;;;;
4152 1410;CANADIAN SYLLABICS WII;Lo;0;L;;;;;N;;;;;
4153 1411;CANADIAN SYLLABICS WEST-CREE WII;Lo;0;L;;;;;N;;;;;
4154 1412;CANADIAN SYLLABICS WO;Lo;0;L;;;;;N;;;;;
4155 1413;CANADIAN SYLLABICS WEST-CREE WO;Lo;0;L;;;;;N;;;;;
4156 1414;CANADIAN SYLLABICS WOO;Lo;0;L;;;;;N;;;;;
4157 1415;CANADIAN SYLLABICS WEST-CREE WOO;Lo;0;L;;;;;N;;;;;
4158 1416;CANADIAN SYLLABICS NASKAPI WOO;Lo;0;L;;;;;N;;;;;
4159 1417;CANADIAN SYLLABICS WA;Lo;0;L;;;;;N;;;;;
4160 1418;CANADIAN SYLLABICS WEST-CREE WA;Lo;0;L;;;;;N;;;;;
4161 1419;CANADIAN SYLLABICS WAA;Lo;0;L;;;;;N;;;;;
4162 141A;CANADIAN SYLLABICS WEST-CREE WAA;Lo;0;L;;;;;N;;;;;
4163 141B;CANADIAN SYLLABICS NASKAPI WAA;Lo;0;L;;;;;N;;;;;
4164 141C;CANADIAN SYLLABICS AI;Lo;0;L;;;;;N;;;;;
4165 141D;CANADIAN SYLLABICS Y-CREE W;Lo;0;L;;;;;N;;;;;
4166 141E;CANADIAN SYLLABICS GLOTTAL STOP;Lo;0;L;;;;;N;;;;;
4167 141F;CANADIAN SYLLABICS FINAL ACUTE;Lo;0;L;;;;;N;;;;;
4168 1420;CANADIAN SYLLABICS FINAL GRAVE;Lo;0;L;;;;;N;;;;;
4169 1421;CANADIAN SYLLABICS FINAL BOTTOM HALF RING;Lo;0;L;;;;;N;;;;;
4170 1422;CANADIAN SYLLABICS FINAL TOP HALF RING;Lo;0;L;;;;;N;;;;;
4171 1423;CANADIAN SYLLABICS FINAL RIGHT HALF RING;Lo;0;L;;;;;N;;;;;
4172 1424;CANADIAN SYLLABICS FINAL RING;Lo;0;L;;;;;N;;;;;
4173 1425;CANADIAN SYLLABICS FINAL DOUBLE ACUTE;Lo;0;L;;;;;N;;;;;
4174 1426;CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES;Lo;0;L;;;;;N;;;;;
4175 1427;CANADIAN SYLLABICS FINAL MIDDLE DOT;Lo;0;L;;;;;N;;;;;
4176 1428;CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE;Lo;0;L;;;;;N;;;;;
4177 1429;CANADIAN SYLLABICS FINAL PLUS;Lo;0;L;;;;;N;;;;;
4178 142A;CANADIAN SYLLABICS FINAL DOWN TACK;Lo;0;L;;;;;N;;;;;
4179 142B;CANADIAN SYLLABICS EN;Lo;0;L;;;;;N;;;;;
4180 142C;CANADIAN SYLLABICS IN;Lo;0;L;;;;;N;;;;;
4181 142D;CANADIAN SYLLABICS ON;Lo;0;L;;;;;N;;;;;
4182 142E;CANADIAN SYLLABICS AN;Lo;0;L;;;;;N;;;;;
4183 142F;CANADIAN SYLLABICS PE;Lo;0;L;;;;;N;;;;;
4184 1430;CANADIAN SYLLABICS PAAI;Lo;0;L;;;;;N;;;;;
4185 1431;CANADIAN SYLLABICS PI;Lo;0;L;;;;;N;;;;;
4186 1432;CANADIAN SYLLABICS PII;Lo;0;L;;;;;N;;;;;
4187 1433;CANADIAN SYLLABICS PO;Lo;0;L;;;;;N;;;;;
4188 1434;CANADIAN SYLLABICS POO;Lo;0;L;;;;;N;;;;;
4189 1435;CANADIAN SYLLABICS Y-CREE POO;Lo;0;L;;;;;N;;;;;
4190 1436;CANADIAN SYLLABICS CARRIER HEE;Lo;0;L;;;;;N;;;;;
4191 1437;CANADIAN SYLLABICS CARRIER HI;Lo;0;L;;;;;N;;;;;
4192 1438;CANADIAN SYLLABICS PA;Lo;0;L;;;;;N;;;;;
4193 1439;CANADIAN SYLLABICS PAA;Lo;0;L;;;;;N;;;;;
4194 143A;CANADIAN SYLLABICS PWE;Lo;0;L;;;;;N;;;;;
4195 143B;CANADIAN SYLLABICS WEST-CREE PWE;Lo;0;L;;;;;N;;;;;
4196 143C;CANADIAN SYLLABICS PWI;Lo;0;L;;;;;N;;;;;
4197 143D;CANADIAN SYLLABICS WEST-CREE PWI;Lo;0;L;;;;;N;;;;;
4198 143E;CANADIAN SYLLABICS PWII;Lo;0;L;;;;;N;;;;;
4199 143F;CANADIAN SYLLABICS WEST-CREE PWII;Lo;0;L;;;;;N;;;;;
4200 1440;CANADIAN SYLLABICS PWO;Lo;0;L;;;;;N;;;;;
4201 1441;CANADIAN SYLLABICS WEST-CREE PWO;Lo;0;L;;;;;N;;;;;
4202 1442;CANADIAN SYLLABICS PWOO;Lo;0;L;;;;;N;;;;;
4203 1443;CANADIAN SYLLABICS WEST-CREE PWOO;Lo;0;L;;;;;N;;;;;
4204 1444;CANADIAN SYLLABICS PWA;Lo;0;L;;;;;N;;;;;
4205 1445;CANADIAN SYLLABICS WEST-CREE PWA;Lo;0;L;;;;;N;;;;;
4206 1446;CANADIAN SYLLABICS PWAA;Lo;0;L;;;;;N;;;;;
4207 1447;CANADIAN SYLLABICS WEST-CREE PWAA;Lo;0;L;;;;;N;;;;;
4208 1448;CANADIAN SYLLABICS Y-CREE PWAA;Lo;0;L;;;;;N;;;;;
4209 1449;CANADIAN SYLLABICS P;Lo;0;L;;;;;N;;;;;
4210 144A;CANADIAN SYLLABICS WEST-CREE P;Lo;0;L;;;;;N;;;;;
4211 144B;CANADIAN SYLLABICS CARRIER H;Lo;0;L;;;;;N;;;;;
4212 144C;CANADIAN SYLLABICS TE;Lo;0;L;;;;;N;;;;;
4213 144D;CANADIAN SYLLABICS TAAI;Lo;0;L;;;;;N;;;;;
4214 144E;CANADIAN SYLLABICS TI;Lo;0;L;;;;;N;;;;;
4215 144F;CANADIAN SYLLABICS TII;Lo;0;L;;;;;N;;;;;
4216 1450;CANADIAN SYLLABICS TO;Lo;0;L;;;;;N;;;;;
4217 1451;CANADIAN SYLLABICS TOO;Lo;0;L;;;;;N;;;;;
4218 1452;CANADIAN SYLLABICS Y-CREE TOO;Lo;0;L;;;;;N;;;;;
4219 1453;CANADIAN SYLLABICS CARRIER DEE;Lo;0;L;;;;;N;;;;;
4220 1454;CANADIAN SYLLABICS CARRIER DI;Lo;0;L;;;;;N;;;;;
4221 1455;CANADIAN SYLLABICS TA;Lo;0;L;;;;;N;;;;;
4222 1456;CANADIAN SYLLABICS TAA;Lo;0;L;;;;;N;;;;;
4223 1457;CANADIAN SYLLABICS TWE;Lo;0;L;;;;;N;;;;;
4224 1458;CANADIAN SYLLABICS WEST-CREE TWE;Lo;0;L;;;;;N;;;;;
4225 1459;CANADIAN SYLLABICS TWI;Lo;0;L;;;;;N;;;;;
4226 145A;CANADIAN SYLLABICS WEST-CREE TWI;Lo;0;L;;;;;N;;;;;
4227 145B;CANADIAN SYLLABICS TWII;Lo;0;L;;;;;N;;;;;
4228 145C;CANADIAN SYLLABICS WEST-CREE TWII;Lo;0;L;;;;;N;;;;;
4229 145D;CANADIAN SYLLABICS TWO;Lo;0;L;;;;;N;;;;;
4230 145E;CANADIAN SYLLABICS WEST-CREE TWO;Lo;0;L;;;;;N;;;;;
4231 145F;CANADIAN SYLLABICS TWOO;Lo;0;L;;;;;N;;;;;
4232 1460;CANADIAN SYLLABICS WEST-CREE TWOO;Lo;0;L;;;;;N;;;;;
4233 1461;CANADIAN SYLLABICS TWA;Lo;0;L;;;;;N;;;;;
4234 1462;CANADIAN SYLLABICS WEST-CREE TWA;Lo;0;L;;;;;N;;;;;
4235 1463;CANADIAN SYLLABICS TWAA;Lo;0;L;;;;;N;;;;;
4236 1464;CANADIAN SYLLABICS WEST-CREE TWAA;Lo;0;L;;;;;N;;;;;
4237 1465;CANADIAN SYLLABICS NASKAPI TWAA;Lo;0;L;;;;;N;;;;;
4238 1466;CANADIAN SYLLABICS T;Lo;0;L;;;;;N;;;;;
4239 1467;CANADIAN SYLLABICS TTE;Lo;0;L;;;;;N;;;;;
4240 1468;CANADIAN SYLLABICS TTI;Lo;0;L;;;;;N;;;;;
4241 1469;CANADIAN SYLLABICS TTO;Lo;0;L;;;;;N;;;;;
4242 146A;CANADIAN SYLLABICS TTA;Lo;0;L;;;;;N;;;;;
4243 146B;CANADIAN SYLLABICS KE;Lo;0;L;;;;;N;;;;;
4244 146C;CANADIAN SYLLABICS KAAI;Lo;0;L;;;;;N;;;;;
4245 146D;CANADIAN SYLLABICS KI;Lo;0;L;;;;;N;;;;;
4246 146E;CANADIAN SYLLABICS KII;Lo;0;L;;;;;N;;;;;
4247 146F;CANADIAN SYLLABICS KO;Lo;0;L;;;;;N;;;;;
4248 1470;CANADIAN SYLLABICS KOO;Lo;0;L;;;;;N;;;;;
4249 1471;CANADIAN SYLLABICS Y-CREE KOO;Lo;0;L;;;;;N;;;;;
4250 1472;CANADIAN SYLLABICS KA;Lo;0;L;;;;;N;;;;;
4251 1473;CANADIAN SYLLABICS KAA;Lo;0;L;;;;;N;;;;;
4252 1474;CANADIAN SYLLABICS KWE;Lo;0;L;;;;;N;;;;;
4253 1475;CANADIAN SYLLABICS WEST-CREE KWE;Lo;0;L;;;;;N;;;;;
4254 1476;CANADIAN SYLLABICS KWI;Lo;0;L;;;;;N;;;;;
4255 1477;CANADIAN SYLLABICS WEST-CREE KWI;Lo;0;L;;;;;N;;;;;
4256 1478;CANADIAN SYLLABICS KWII;Lo;0;L;;;;;N;;;;;
4257 1479;CANADIAN SYLLABICS WEST-CREE KWII;Lo;0;L;;;;;N;;;;;
4258 147A;CANADIAN SYLLABICS KWO;Lo;0;L;;;;;N;;;;;
4259 147B;CANADIAN SYLLABICS WEST-CREE KWO;Lo;0;L;;;;;N;;;;;
4260 147C;CANADIAN SYLLABICS KWOO;Lo;0;L;;;;;N;;;;;
4261 147D;CANADIAN SYLLABICS WEST-CREE KWOO;Lo;0;L;;;;;N;;;;;
4262 147E;CANADIAN SYLLABICS KWA;Lo;0;L;;;;;N;;;;;
4263 147F;CANADIAN SYLLABICS WEST-CREE KWA;Lo;0;L;;;;;N;;;;;
4264 1480;CANADIAN SYLLABICS KWAA;Lo;0;L;;;;;N;;;;;
4265 1481;CANADIAN SYLLABICS WEST-CREE KWAA;Lo;0;L;;;;;N;;;;;
4266 1482;CANADIAN SYLLABICS NASKAPI KWAA;Lo;0;L;;;;;N;;;;;
4267 1483;CANADIAN SYLLABICS K;Lo;0;L;;;;;N;;;;;
4268 1484;CANADIAN SYLLABICS KW;Lo;0;L;;;;;N;;;;;
4269 1485;CANADIAN SYLLABICS SOUTH-SLAVEY KEH;Lo;0;L;;;;;N;;;;;
4270 1486;CANADIAN SYLLABICS SOUTH-SLAVEY KIH;Lo;0;L;;;;;N;;;;;
4271 1487;CANADIAN SYLLABICS SOUTH-SLAVEY KOH;Lo;0;L;;;;;N;;;;;
4272 1488;CANADIAN SYLLABICS SOUTH-SLAVEY KAH;Lo;0;L;;;;;N;;;;;
4273 1489;CANADIAN SYLLABICS CE;Lo;0;L;;;;;N;;;;;
4274 148A;CANADIAN SYLLABICS CAAI;Lo;0;L;;;;;N;;;;;
4275 148B;CANADIAN SYLLABICS CI;Lo;0;L;;;;;N;;;;;
4276 148C;CANADIAN SYLLABICS CII;Lo;0;L;;;;;N;;;;;
4277 148D;CANADIAN SYLLABICS CO;Lo;0;L;;;;;N;;;;;
4278 148E;CANADIAN SYLLABICS COO;Lo;0;L;;;;;N;;;;;
4279 148F;CANADIAN SYLLABICS Y-CREE COO;Lo;0;L;;;;;N;;;;;
4280 1490;CANADIAN SYLLABICS CA;Lo;0;L;;;;;N;;;;;
4281 1491;CANADIAN SYLLABICS CAA;Lo;0;L;;;;;N;;;;;
4282 1492;CANADIAN SYLLABICS CWE;Lo;0;L;;;;;N;;;;;
4283 1493;CANADIAN SYLLABICS WEST-CREE CWE;Lo;0;L;;;;;N;;;;;
4284 1494;CANADIAN SYLLABICS CWI;Lo;0;L;;;;;N;;;;;
4285 1495;CANADIAN SYLLABICS WEST-CREE CWI;Lo;0;L;;;;;N;;;;;
4286 1496;CANADIAN SYLLABICS CWII;Lo;0;L;;;;;N;;;;;
4287 1497;CANADIAN SYLLABICS WEST-CREE CWII;Lo;0;L;;;;;N;;;;;
4288 1498;CANADIAN SYLLABICS CWO;Lo;0;L;;;;;N;;;;;
4289 1499;CANADIAN SYLLABICS WEST-CREE CWO;Lo;0;L;;;;;N;;;;;
4290 149A;CANADIAN SYLLABICS CWOO;Lo;0;L;;;;;N;;;;;
4291 149B;CANADIAN SYLLABICS WEST-CREE CWOO;Lo;0;L;;;;;N;;;;;
4292 149C;CANADIAN SYLLABICS CWA;Lo;0;L;;;;;N;;;;;
4293 149D;CANADIAN SYLLABICS WEST-CREE CWA;Lo;0;L;;;;;N;;;;;
4294 149E;CANADIAN SYLLABICS CWAA;Lo;0;L;;;;;N;;;;;
4295 149F;CANADIAN SYLLABICS WEST-CREE CWAA;Lo;0;L;;;;;N;;;;;
4296 14A0;CANADIAN SYLLABICS NASKAPI CWAA;Lo;0;L;;;;;N;;;;;
4297 14A1;CANADIAN SYLLABICS C;Lo;0;L;;;;;N;;;;;
4298 14A2;CANADIAN SYLLABICS SAYISI TH;Lo;0;L;;;;;N;;;;;
4299 14A3;CANADIAN SYLLABICS ME;Lo;0;L;;;;;N;;;;;
4300 14A4;CANADIAN SYLLABICS MAAI;Lo;0;L;;;;;N;;;;;
4301 14A5;CANADIAN SYLLABICS MI;Lo;0;L;;;;;N;;;;;
4302 14A6;CANADIAN SYLLABICS MII;Lo;0;L;;;;;N;;;;;
4303 14A7;CANADIAN SYLLABICS MO;Lo;0;L;;;;;N;;;;;
4304 14A8;CANADIAN SYLLABICS MOO;Lo;0;L;;;;;N;;;;;
4305 14A9;CANADIAN SYLLABICS Y-CREE MOO;Lo;0;L;;;;;N;;;;;
4306 14AA;CANADIAN SYLLABICS MA;Lo;0;L;;;;;N;;;;;
4307 14AB;CANADIAN SYLLABICS MAA;Lo;0;L;;;;;N;;;;;
4308 14AC;CANADIAN SYLLABICS MWE;Lo;0;L;;;;;N;;;;;
4309 14AD;CANADIAN SYLLABICS WEST-CREE MWE;Lo;0;L;;;;;N;;;;;
4310 14AE;CANADIAN SYLLABICS MWI;Lo;0;L;;;;;N;;;;;
4311 14AF;CANADIAN SYLLABICS WEST-CREE MWI;Lo;0;L;;;;;N;;;;;
4312 14B0;CANADIAN SYLLABICS MWII;Lo;0;L;;;;;N;;;;;
4313 14B1;CANADIAN SYLLABICS WEST-CREE MWII;Lo;0;L;;;;;N;;;;;
4314 14B2;CANADIAN SYLLABICS MWO;Lo;0;L;;;;;N;;;;;
4315 14B3;CANADIAN SYLLABICS WEST-CREE MWO;Lo;0;L;;;;;N;;;;;
4316 14B4;CANADIAN SYLLABICS MWOO;Lo;0;L;;;;;N;;;;;
4317 14B5;CANADIAN SYLLABICS WEST-CREE MWOO;Lo;0;L;;;;;N;;;;;
4318 14B6;CANADIAN SYLLABICS MWA;Lo;0;L;;;;;N;;;;;
4319 14B7;CANADIAN SYLLABICS WEST-CREE MWA;Lo;0;L;;;;;N;;;;;
4320 14B8;CANADIAN SYLLABICS MWAA;Lo;0;L;;;;;N;;;;;
4321 14B9;CANADIAN SYLLABICS WEST-CREE MWAA;Lo;0;L;;;;;N;;;;;
4322 14BA;CANADIAN SYLLABICS NASKAPI MWAA;Lo;0;L;;;;;N;;;;;
4323 14BB;CANADIAN SYLLABICS M;Lo;0;L;;;;;N;;;;;
4324 14BC;CANADIAN SYLLABICS WEST-CREE M;Lo;0;L;;;;;N;;;;;
4325 14BD;CANADIAN SYLLABICS MH;Lo;0;L;;;;;N;;;;;
4326 14BE;CANADIAN SYLLABICS ATHAPASCAN M;Lo;0;L;;;;;N;;;;;
4327 14BF;CANADIAN SYLLABICS SAYISI M;Lo;0;L;;;;;N;;;;;
4328 14C0;CANADIAN SYLLABICS NE;Lo;0;L;;;;;N;;;;;
4329 14C1;CANADIAN SYLLABICS NAAI;Lo;0;L;;;;;N;;;;;
4330 14C2;CANADIAN SYLLABICS NI;Lo;0;L;;;;;N;;;;;
4331 14C3;CANADIAN SYLLABICS NII;Lo;0;L;;;;;N;;;;;
4332 14C4;CANADIAN SYLLABICS NO;Lo;0;L;;;;;N;;;;;
4333 14C5;CANADIAN SYLLABICS NOO;Lo;0;L;;;;;N;;;;;
4334 14C6;CANADIAN SYLLABICS Y-CREE NOO;Lo;0;L;;;;;N;;;;;
4335 14C7;CANADIAN SYLLABICS NA;Lo;0;L;;;;;N;;;;;
4336 14C8;CANADIAN SYLLABICS NAA;Lo;0;L;;;;;N;;;;;
4337 14C9;CANADIAN SYLLABICS NWE;Lo;0;L;;;;;N;;;;;
4338 14CA;CANADIAN SYLLABICS WEST-CREE NWE;Lo;0;L;;;;;N;;;;;
4339 14CB;CANADIAN SYLLABICS NWA;Lo;0;L;;;;;N;;;;;
4340 14CC;CANADIAN SYLLABICS WEST-CREE NWA;Lo;0;L;;;;;N;;;;;
4341 14CD;CANADIAN SYLLABICS NWAA;Lo;0;L;;;;;N;;;;;
4342 14CE;CANADIAN SYLLABICS WEST-CREE NWAA;Lo;0;L;;;;;N;;;;;
4343 14CF;CANADIAN SYLLABICS NASKAPI NWAA;Lo;0;L;;;;;N;;;;;
4344 14D0;CANADIAN SYLLABICS N;Lo;0;L;;;;;N;;;;;
4345 14D1;CANADIAN SYLLABICS CARRIER NG;Lo;0;L;;;;;N;;;;;
4346 14D2;CANADIAN SYLLABICS NH;Lo;0;L;;;;;N;;;;;
4347 14D3;CANADIAN SYLLABICS LE;Lo;0;L;;;;;N;;;;;
4348 14D4;CANADIAN SYLLABICS LAAI;Lo;0;L;;;;;N;;;;;
4349 14D5;CANADIAN SYLLABICS LI;Lo;0;L;;;;;N;;;;;
4350 14D6;CANADIAN SYLLABICS LII;Lo;0;L;;;;;N;;;;;
4351 14D7;CANADIAN SYLLABICS LO;Lo;0;L;;;;;N;;;;;
4352 14D8;CANADIAN SYLLABICS LOO;Lo;0;L;;;;;N;;;;;
4353 14D9;CANADIAN SYLLABICS Y-CREE LOO;Lo;0;L;;;;;N;;;;;
4354 14DA;CANADIAN SYLLABICS LA;Lo;0;L;;;;;N;;;;;
4355 14DB;CANADIAN SYLLABICS LAA;Lo;0;L;;;;;N;;;;;
4356 14DC;CANADIAN SYLLABICS LWE;Lo;0;L;;;;;N;;;;;
4357 14DD;CANADIAN SYLLABICS WEST-CREE LWE;Lo;0;L;;;;;N;;;;;
4358 14DE;CANADIAN SYLLABICS LWI;Lo;0;L;;;;;N;;;;;
4359 14DF;CANADIAN SYLLABICS WEST-CREE LWI;Lo;0;L;;;;;N;;;;;
4360 14E0;CANADIAN SYLLABICS LWII;Lo;0;L;;;;;N;;;;;
4361 14E1;CANADIAN SYLLABICS WEST-CREE LWII;Lo;0;L;;;;;N;;;;;
4362 14E2;CANADIAN SYLLABICS LWO;Lo;0;L;;;;;N;;;;;
4363 14E3;CANADIAN SYLLABICS WEST-CREE LWO;Lo;0;L;;;;;N;;;;;
4364 14E4;CANADIAN SYLLABICS LWOO;Lo;0;L;;;;;N;;;;;
4365 14E5;CANADIAN SYLLABICS WEST-CREE LWOO;Lo;0;L;;;;;N;;;;;
4366 14E6;CANADIAN SYLLABICS LWA;Lo;0;L;;;;;N;;;;;
4367 14E7;CANADIAN SYLLABICS WEST-CREE LWA;Lo;0;L;;;;;N;;;;;
4368 14E8;CANADIAN SYLLABICS LWAA;Lo;0;L;;;;;N;;;;;
4369 14E9;CANADIAN SYLLABICS WEST-CREE LWAA;Lo;0;L;;;;;N;;;;;
4370 14EA;CANADIAN SYLLABICS L;Lo;0;L;;;;;N;;;;;
4371 14EB;CANADIAN SYLLABICS WEST-CREE L;Lo;0;L;;;;;N;;;;;
4372 14EC;CANADIAN SYLLABICS MEDIAL L;Lo;0;L;;;;;N;;;;;
4373 14ED;CANADIAN SYLLABICS SE;Lo;0;L;;;;;N;;;;;
4374 14EE;CANADIAN SYLLABICS SAAI;Lo;0;L;;;;;N;;;;;
4375 14EF;CANADIAN SYLLABICS SI;Lo;0;L;;;;;N;;;;;
4376 14F0;CANADIAN SYLLABICS SII;Lo;0;L;;;;;N;;;;;
4377 14F1;CANADIAN SYLLABICS SO;Lo;0;L;;;;;N;;;;;
4378 14F2;CANADIAN SYLLABICS SOO;Lo;0;L;;;;;N;;;;;
4379 14F3;CANADIAN SYLLABICS Y-CREE SOO;Lo;0;L;;;;;N;;;;;
4380 14F4;CANADIAN SYLLABICS SA;Lo;0;L;;;;;N;;;;;
4381 14F5;CANADIAN SYLLABICS SAA;Lo;0;L;;;;;N;;;;;
4382 14F6;CANADIAN SYLLABICS SWE;Lo;0;L;;;;;N;;;;;
4383 14F7;CANADIAN SYLLABICS WEST-CREE SWE;Lo;0;L;;;;;N;;;;;
4384 14F8;CANADIAN SYLLABICS SWI;Lo;0;L;;;;;N;;;;;
4385 14F9;CANADIAN SYLLABICS WEST-CREE SWI;Lo;0;L;;;;;N;;;;;
4386 14FA;CANADIAN SYLLABICS SWII;Lo;0;L;;;;;N;;;;;
4387 14FB;CANADIAN SYLLABICS WEST-CREE SWII;Lo;0;L;;;;;N;;;;;
4388 14FC;CANADIAN SYLLABICS SWO;Lo;0;L;;;;;N;;;;;
4389 14FD;CANADIAN SYLLABICS WEST-CREE SWO;Lo;0;L;;;;;N;;;;;
4390 14FE;CANADIAN SYLLABICS SWOO;Lo;0;L;;;;;N;;;;;
4391 14FF;CANADIAN SYLLABICS WEST-CREE SWOO;Lo;0;L;;;;;N;;;;;
4392 1500;CANADIAN SYLLABICS SWA;Lo;0;L;;;;;N;;;;;
4393 1501;CANADIAN SYLLABICS WEST-CREE SWA;Lo;0;L;;;;;N;;;;;
4394 1502;CANADIAN SYLLABICS SWAA;Lo;0;L;;;;;N;;;;;
4395 1503;CANADIAN SYLLABICS WEST-CREE SWAA;Lo;0;L;;;;;N;;;;;
4396 1504;CANADIAN SYLLABICS NASKAPI SWAA;Lo;0;L;;;;;N;;;;;
4397 1505;CANADIAN SYLLABICS S;Lo;0;L;;;;;N;;;;;
4398 1506;CANADIAN SYLLABICS ATHAPASCAN S;Lo;0;L;;;;;N;;;;;
4399 1507;CANADIAN SYLLABICS SW;Lo;0;L;;;;;N;;;;;
4400 1508;CANADIAN SYLLABICS BLACKFOOT S;Lo;0;L;;;;;N;;;;;
4401 1509;CANADIAN SYLLABICS MOOSE-CREE SK;Lo;0;L;;;;;N;;;;;
4402 150A;CANADIAN SYLLABICS NASKAPI SKW;Lo;0;L;;;;;N;;;;;
4403 150B;CANADIAN SYLLABICS NASKAPI S-W;Lo;0;L;;;;;N;;;;;
4404 150C;CANADIAN SYLLABICS NASKAPI SPWA;Lo;0;L;;;;;N;;;;;
4405 150D;CANADIAN SYLLABICS NASKAPI STWA;Lo;0;L;;;;;N;;;;;
4406 150E;CANADIAN SYLLABICS NASKAPI SKWA;Lo;0;L;;;;;N;;;;;
4407 150F;CANADIAN SYLLABICS NASKAPI SCWA;Lo;0;L;;;;;N;;;;;
4408 1510;CANADIAN SYLLABICS SHE;Lo;0;L;;;;;N;;;;;
4409 1511;CANADIAN SYLLABICS SHI;Lo;0;L;;;;;N;;;;;
4410 1512;CANADIAN SYLLABICS SHII;Lo;0;L;;;;;N;;;;;
4411 1513;CANADIAN SYLLABICS SHO;Lo;0;L;;;;;N;;;;;
4412 1514;CANADIAN SYLLABICS SHOO;Lo;0;L;;;;;N;;;;;
4413 1515;CANADIAN SYLLABICS SHA;Lo;0;L;;;;;N;;;;;
4414 1516;CANADIAN SYLLABICS SHAA;Lo;0;L;;;;;N;;;;;
4415 1517;CANADIAN SYLLABICS SHWE;Lo;0;L;;;;;N;;;;;
4416 1518;CANADIAN SYLLABICS WEST-CREE SHWE;Lo;0;L;;;;;N;;;;;
4417 1519;CANADIAN SYLLABICS SHWI;Lo;0;L;;;;;N;;;;;
4418 151A;CANADIAN SYLLABICS WEST-CREE SHWI;Lo;0;L;;;;;N;;;;;
4419 151B;CANADIAN SYLLABICS SHWII;Lo;0;L;;;;;N;;;;;
4420 151C;CANADIAN SYLLABICS WEST-CREE SHWII;Lo;0;L;;;;;N;;;;;
4421 151D;CANADIAN SYLLABICS SHWO;Lo;0;L;;;;;N;;;;;
4422 151E;CANADIAN SYLLABICS WEST-CREE SHWO;Lo;0;L;;;;;N;;;;;
4423 151F;CANADIAN SYLLABICS SHWOO;Lo;0;L;;;;;N;;;;;
4424 1520;CANADIAN SYLLABICS WEST-CREE SHWOO;Lo;0;L;;;;;N;;;;;
4425 1521;CANADIAN SYLLABICS SHWA;Lo;0;L;;;;;N;;;;;
4426 1522;CANADIAN SYLLABICS WEST-CREE SHWA;Lo;0;L;;;;;N;;;;;
4427 1523;CANADIAN SYLLABICS SHWAA;Lo;0;L;;;;;N;;;;;
4428 1524;CANADIAN SYLLABICS WEST-CREE SHWAA;Lo;0;L;;;;;N;;;;;
4429 1525;CANADIAN SYLLABICS SH;Lo;0;L;;;;;N;;;;;
4430 1526;CANADIAN SYLLABICS YE;Lo;0;L;;;;;N;;;;;
4431 1527;CANADIAN SYLLABICS YAAI;Lo;0;L;;;;;N;;;;;
4432 1528;CANADIAN SYLLABICS YI;Lo;0;L;;;;;N;;;;;
4433 1529;CANADIAN SYLLABICS YII;Lo;0;L;;;;;N;;;;;
4434 152A;CANADIAN SYLLABICS YO;Lo;0;L;;;;;N;;;;;
4435 152B;CANADIAN SYLLABICS YOO;Lo;0;L;;;;;N;;;;;
4436 152C;CANADIAN SYLLABICS Y-CREE YOO;Lo;0;L;;;;;N;;;;;
4437 152D;CANADIAN SYLLABICS YA;Lo;0;L;;;;;N;;;;;
4438 152E;CANADIAN SYLLABICS YAA;Lo;0;L;;;;;N;;;;;
4439 152F;CANADIAN SYLLABICS YWE;Lo;0;L;;;;;N;;;;;
4440 1530;CANADIAN SYLLABICS WEST-CREE YWE;Lo;0;L;;;;;N;;;;;
4441 1531;CANADIAN SYLLABICS YWI;Lo;0;L;;;;;N;;;;;
4442 1532;CANADIAN SYLLABICS WEST-CREE YWI;Lo;0;L;;;;;N;;;;;
4443 1533;CANADIAN SYLLABICS YWII;Lo;0;L;;;;;N;;;;;
4444 1534;CANADIAN SYLLABICS WEST-CREE YWII;Lo;0;L;;;;;N;;;;;
4445 1535;CANADIAN SYLLABICS YWO;Lo;0;L;;;;;N;;;;;
4446 1536;CANADIAN SYLLABICS WEST-CREE YWO;Lo;0;L;;;;;N;;;;;
4447 1537;CANADIAN SYLLABICS YWOO;Lo;0;L;;;;;N;;;;;
4448 1538;CANADIAN SYLLABICS WEST-CREE YWOO;Lo;0;L;;;;;N;;;;;
4449 1539;CANADIAN SYLLABICS YWA;Lo;0;L;;;;;N;;;;;
4450 153A;CANADIAN SYLLABICS WEST-CREE YWA;Lo;0;L;;;;;N;;;;;
4451 153B;CANADIAN SYLLABICS YWAA;Lo;0;L;;;;;N;;;;;
4452 153C;CANADIAN SYLLABICS WEST-CREE YWAA;Lo;0;L;;;;;N;;;;;
4453 153D;CANADIAN SYLLABICS NASKAPI YWAA;Lo;0;L;;;;;N;;;;;
4454 153E;CANADIAN SYLLABICS Y;Lo;0;L;;;;;N;;;;;
4455 153F;CANADIAN SYLLABICS BIBLE-CREE Y;Lo;0;L;;;;;N;;;;;
4456 1540;CANADIAN SYLLABICS WEST-CREE Y;Lo;0;L;;;;;N;;;;;
4457 1541;CANADIAN SYLLABICS SAYISI YI;Lo;0;L;;;;;N;;;;;
4458 1542;CANADIAN SYLLABICS RE;Lo;0;L;;;;;N;;;;;
4459 1543;CANADIAN SYLLABICS R-CREE RE;Lo;0;L;;;;;N;;;;;
4460 1544;CANADIAN SYLLABICS WEST-CREE LE;Lo;0;L;;;;;N;;;;;
4461 1545;CANADIAN SYLLABICS RAAI;Lo;0;L;;;;;N;;;;;
4462 1546;CANADIAN SYLLABICS RI;Lo;0;L;;;;;N;;;;;
4463 1547;CANADIAN SYLLABICS RII;Lo;0;L;;;;;N;;;;;
4464 1548;CANADIAN SYLLABICS RO;Lo;0;L;;;;;N;;;;;
4465 1549;CANADIAN SYLLABICS ROO;Lo;0;L;;;;;N;;;;;
4466 154A;CANADIAN SYLLABICS WEST-CREE LO;Lo;0;L;;;;;N;;;;;
4467 154B;CANADIAN SYLLABICS RA;Lo;0;L;;;;;N;;;;;
4468 154C;CANADIAN SYLLABICS RAA;Lo;0;L;;;;;N;;;;;
4469 154D;CANADIAN SYLLABICS WEST-CREE LA;Lo;0;L;;;;;N;;;;;
4470 154E;CANADIAN SYLLABICS RWAA;Lo;0;L;;;;;N;;;;;
4471 154F;CANADIAN SYLLABICS WEST-CREE RWAA;Lo;0;L;;;;;N;;;;;
4472 1550;CANADIAN SYLLABICS R;Lo;0;L;;;;;N;;;;;
4473 1551;CANADIAN SYLLABICS WEST-CREE R;Lo;0;L;;;;;N;;;;;
4474 1552;CANADIAN SYLLABICS MEDIAL R;Lo;0;L;;;;;N;;;;;
4475 1553;CANADIAN SYLLABICS FE;Lo;0;L;;;;;N;;;;;
4476 1554;CANADIAN SYLLABICS FAAI;Lo;0;L;;;;;N;;;;;
4477 1555;CANADIAN SYLLABICS FI;Lo;0;L;;;;;N;;;;;
4478 1556;CANADIAN SYLLABICS FII;Lo;0;L;;;;;N;;;;;
4479 1557;CANADIAN SYLLABICS FO;Lo;0;L;;;;;N;;;;;
4480 1558;CANADIAN SYLLABICS FOO;Lo;0;L;;;;;N;;;;;
4481 1559;CANADIAN SYLLABICS FA;Lo;0;L;;;;;N;;;;;
4482 155A;CANADIAN SYLLABICS FAA;Lo;0;L;;;;;N;;;;;
4483 155B;CANADIAN SYLLABICS FWAA;Lo;0;L;;;;;N;;;;;
4484 155C;CANADIAN SYLLABICS WEST-CREE FWAA;Lo;0;L;;;;;N;;;;;
4485 155D;CANADIAN SYLLABICS F;Lo;0;L;;;;;N;;;;;
4486 155E;CANADIAN SYLLABICS THE;Lo;0;L;;;;;N;;;;;
4487 155F;CANADIAN SYLLABICS N-CREE THE;Lo;0;L;;;;;N;;;;;
4488 1560;CANADIAN SYLLABICS THI;Lo;0;L;;;;;N;;;;;
4489 1561;CANADIAN SYLLABICS N-CREE THI;Lo;0;L;;;;;N;;;;;
4490 1562;CANADIAN SYLLABICS THII;Lo;0;L;;;;;N;;;;;
4491 1563;CANADIAN SYLLABICS N-CREE THII;Lo;0;L;;;;;N;;;;;
4492 1564;CANADIAN SYLLABICS THO;Lo;0;L;;;;;N;;;;;
4493 1565;CANADIAN SYLLABICS THOO;Lo;0;L;;;;;N;;;;;
4494 1566;CANADIAN SYLLABICS THA;Lo;0;L;;;;;N;;;;;
4495 1567;CANADIAN SYLLABICS THAA;Lo;0;L;;;;;N;;;;;
4496 1568;CANADIAN SYLLABICS THWAA;Lo;0;L;;;;;N;;;;;
4497 1569;CANADIAN SYLLABICS WEST-CREE THWAA;Lo;0;L;;;;;N;;;;;
4498 156A;CANADIAN SYLLABICS TH;Lo;0;L;;;;;N;;;;;
4499 156B;CANADIAN SYLLABICS TTHE;Lo;0;L;;;;;N;;;;;
4500 156C;CANADIAN SYLLABICS TTHI;Lo;0;L;;;;;N;;;;;
4501 156D;CANADIAN SYLLABICS TTHO;Lo;0;L;;;;;N;;;;;
4502 156E;CANADIAN SYLLABICS TTHA;Lo;0;L;;;;;N;;;;;
4503 156F;CANADIAN SYLLABICS TTH;Lo;0;L;;;;;N;;;;;
4504 1570;CANADIAN SYLLABICS TYE;Lo;0;L;;;;;N;;;;;
4505 1571;CANADIAN SYLLABICS TYI;Lo;0;L;;;;;N;;;;;
4506 1572;CANADIAN SYLLABICS TYO;Lo;0;L;;;;;N;;;;;
4507 1573;CANADIAN SYLLABICS TYA;Lo;0;L;;;;;N;;;;;
4508 1574;CANADIAN SYLLABICS NUNAVIK HE;Lo;0;L;;;;;N;;;;;
4509 1575;CANADIAN SYLLABICS NUNAVIK HI;Lo;0;L;;;;;N;;;;;
4510 1576;CANADIAN SYLLABICS NUNAVIK HII;Lo;0;L;;;;;N;;;;;
4511 1577;CANADIAN SYLLABICS NUNAVIK HO;Lo;0;L;;;;;N;;;;;
4512 1578;CANADIAN SYLLABICS NUNAVIK HOO;Lo;0;L;;;;;N;;;;;
4513 1579;CANADIAN SYLLABICS NUNAVIK HA;Lo;0;L;;;;;N;;;;;
4514 157A;CANADIAN SYLLABICS NUNAVIK HAA;Lo;0;L;;;;;N;;;;;
4515 157B;CANADIAN SYLLABICS NUNAVIK H;Lo;0;L;;;;;N;;;;;
4516 157C;CANADIAN SYLLABICS NUNAVUT H;Lo;0;L;;;;;N;;;;;
4517 157D;CANADIAN SYLLABICS HK;Lo;0;L;;;;;N;;;;;
4518 157E;CANADIAN SYLLABICS QAAI;Lo;0;L;;;;;N;;;;;
4519 157F;CANADIAN SYLLABICS QI;Lo;0;L;;;;;N;;;;;
4520 1580;CANADIAN SYLLABICS QII;Lo;0;L;;;;;N;;;;;
4521 1581;CANADIAN SYLLABICS QO;Lo;0;L;;;;;N;;;;;
4522 1582;CANADIAN SYLLABICS QOO;Lo;0;L;;;;;N;;;;;
4523 1583;CANADIAN SYLLABICS QA;Lo;0;L;;;;;N;;;;;
4524 1584;CANADIAN SYLLABICS QAA;Lo;0;L;;;;;N;;;;;
4525 1585;CANADIAN SYLLABICS Q;Lo;0;L;;;;;N;;;;;
4526 1586;CANADIAN SYLLABICS TLHE;Lo;0;L;;;;;N;;;;;
4527 1587;CANADIAN SYLLABICS TLHI;Lo;0;L;;;;;N;;;;;
4528 1588;CANADIAN SYLLABICS TLHO;Lo;0;L;;;;;N;;;;;
4529 1589;CANADIAN SYLLABICS TLHA;Lo;0;L;;;;;N;;;;;
4530 158A;CANADIAN SYLLABICS WEST-CREE RE;Lo;0;L;;;;;N;;;;;
4531 158B;CANADIAN SYLLABICS WEST-CREE RI;Lo;0;L;;;;;N;;;;;
4532 158C;CANADIAN SYLLABICS WEST-CREE RO;Lo;0;L;;;;;N;;;;;
4533 158D;CANADIAN SYLLABICS WEST-CREE RA;Lo;0;L;;;;;N;;;;;
4534 158E;CANADIAN SYLLABICS NGAAI;Lo;0;L;;;;;N;;;;;
4535 158F;CANADIAN SYLLABICS NGI;Lo;0;L;;;;;N;;;;;
4536 1590;CANADIAN SYLLABICS NGII;Lo;0;L;;;;;N;;;;;
4537 1591;CANADIAN SYLLABICS NGO;Lo;0;L;;;;;N;;;;;
4538 1592;CANADIAN SYLLABICS NGOO;Lo;0;L;;;;;N;;;;;
4539 1593;CANADIAN SYLLABICS NGA;Lo;0;L;;;;;N;;;;;
4540 1594;CANADIAN SYLLABICS NGAA;Lo;0;L;;;;;N;;;;;
4541 1595;CANADIAN SYLLABICS NG;Lo;0;L;;;;;N;;;;;
4542 1596;CANADIAN SYLLABICS NNG;Lo;0;L;;;;;N;;;;;
4543 1597;CANADIAN SYLLABICS SAYISI SHE;Lo;0;L;;;;;N;;;;;
4544 1598;CANADIAN SYLLABICS SAYISI SHI;Lo;0;L;;;;;N;;;;;
4545 1599;CANADIAN SYLLABICS SAYISI SHO;Lo;0;L;;;;;N;;;;;
4546 159A;CANADIAN SYLLABICS SAYISI SHA;Lo;0;L;;;;;N;;;;;
4547 159B;CANADIAN SYLLABICS WOODS-CREE THE;Lo;0;L;;;;;N;;;;;
4548 159C;CANADIAN SYLLABICS WOODS-CREE THI;Lo;0;L;;;;;N;;;;;
4549 159D;CANADIAN SYLLABICS WOODS-CREE THO;Lo;0;L;;;;;N;;;;;
4550 159E;CANADIAN SYLLABICS WOODS-CREE THA;Lo;0;L;;;;;N;;;;;
4551 159F;CANADIAN SYLLABICS WOODS-CREE TH;Lo;0;L;;;;;N;;;;;
4552 15A0;CANADIAN SYLLABICS LHI;Lo;0;L;;;;;N;;;;;
4553 15A1;CANADIAN SYLLABICS LHII;Lo;0;L;;;;;N;;;;;
4554 15A2;CANADIAN SYLLABICS LHO;Lo;0;L;;;;;N;;;;;
4555 15A3;CANADIAN SYLLABICS LHOO;Lo;0;L;;;;;N;;;;;
4556 15A4;CANADIAN SYLLABICS LHA;Lo;0;L;;;;;N;;;;;
4557 15A5;CANADIAN SYLLABICS LHAA;Lo;0;L;;;;;N;;;;;
4558 15A6;CANADIAN SYLLABICS LH;Lo;0;L;;;;;N;;;;;
4559 15A7;CANADIAN SYLLABICS TH-CREE THE;Lo;0;L;;;;;N;;;;;
4560 15A8;CANADIAN SYLLABICS TH-CREE THI;Lo;0;L;;;;;N;;;;;
4561 15A9;CANADIAN SYLLABICS TH-CREE THII;Lo;0;L;;;;;N;;;;;
4562 15AA;CANADIAN SYLLABICS TH-CREE THO;Lo;0;L;;;;;N;;;;;
4563 15AB;CANADIAN SYLLABICS TH-CREE THOO;Lo;0;L;;;;;N;;;;;
4564 15AC;CANADIAN SYLLABICS TH-CREE THA;Lo;0;L;;;;;N;;;;;
4565 15AD;CANADIAN SYLLABICS TH-CREE THAA;Lo;0;L;;;;;N;;;;;
4566 15AE;CANADIAN SYLLABICS TH-CREE TH;Lo;0;L;;;;;N;;;;;
4567 15AF;CANADIAN SYLLABICS AIVILIK B;Lo;0;L;;;;;N;;;;;
4568 15B0;CANADIAN SYLLABICS BLACKFOOT E;Lo;0;L;;;;;N;;;;;
4569 15B1;CANADIAN SYLLABICS BLACKFOOT I;Lo;0;L;;;;;N;;;;;
4570 15B2;CANADIAN SYLLABICS BLACKFOOT O;Lo;0;L;;;;;N;;;;;
4571 15B3;CANADIAN SYLLABICS BLACKFOOT A;Lo;0;L;;;;;N;;;;;
4572 15B4;CANADIAN SYLLABICS BLACKFOOT WE;Lo;0;L;;;;;N;;;;;
4573 15B5;CANADIAN SYLLABICS BLACKFOOT WI;Lo;0;L;;;;;N;;;;;
4574 15B6;CANADIAN SYLLABICS BLACKFOOT WO;Lo;0;L;;;;;N;;;;;
4575 15B7;CANADIAN SYLLABICS BLACKFOOT WA;Lo;0;L;;;;;N;;;;;
4576 15B8;CANADIAN SYLLABICS BLACKFOOT NE;Lo;0;L;;;;;N;;;;;
4577 15B9;CANADIAN SYLLABICS BLACKFOOT NI;Lo;0;L;;;;;N;;;;;
4578 15BA;CANADIAN SYLLABICS BLACKFOOT NO;Lo;0;L;;;;;N;;;;;
4579 15BB;CANADIAN SYLLABICS BLACKFOOT NA;Lo;0;L;;;;;N;;;;;
4580 15BC;CANADIAN SYLLABICS BLACKFOOT KE;Lo;0;L;;;;;N;;;;;
4581 15BD;CANADIAN SYLLABICS BLACKFOOT KI;Lo;0;L;;;;;N;;;;;
4582 15BE;CANADIAN SYLLABICS BLACKFOOT KO;Lo;0;L;;;;;N;;;;;
4583 15BF;CANADIAN SYLLABICS BLACKFOOT KA;Lo;0;L;;;;;N;;;;;
4584 15C0;CANADIAN SYLLABICS SAYISI HE;Lo;0;L;;;;;N;;;;;
4585 15C1;CANADIAN SYLLABICS SAYISI HI;Lo;0;L;;;;;N;;;;;
4586 15C2;CANADIAN SYLLABICS SAYISI HO;Lo;0;L;;;;;N;;;;;
4587 15C3;CANADIAN SYLLABICS SAYISI HA;Lo;0;L;;;;;N;;;;;
4588 15C4;CANADIAN SYLLABICS CARRIER GHU;Lo;0;L;;;;;N;;;;;
4589 15C5;CANADIAN SYLLABICS CARRIER GHO;Lo;0;L;;;;;N;;;;;
4590 15C6;CANADIAN SYLLABICS CARRIER GHE;Lo;0;L;;;;;N;;;;;
4591 15C7;CANADIAN SYLLABICS CARRIER GHEE;Lo;0;L;;;;;N;;;;;
4592 15C8;CANADIAN SYLLABICS CARRIER GHI;Lo;0;L;;;;;N;;;;;
4593 15C9;CANADIAN SYLLABICS CARRIER GHA;Lo;0;L;;;;;N;;;;;
4594 15CA;CANADIAN SYLLABICS CARRIER RU;Lo;0;L;;;;;N;;;;;
4595 15CB;CANADIAN SYLLABICS CARRIER RO;Lo;0;L;;;;;N;;;;;
4596 15CC;CANADIAN SYLLABICS CARRIER RE;Lo;0;L;;;;;N;;;;;
4597 15CD;CANADIAN SYLLABICS CARRIER REE;Lo;0;L;;;;;N;;;;;
4598 15CE;CANADIAN SYLLABICS CARRIER RI;Lo;0;L;;;;;N;;;;;
4599 15CF;CANADIAN SYLLABICS CARRIER RA;Lo;0;L;;;;;N;;;;;
4600 15D0;CANADIAN SYLLABICS CARRIER WU;Lo;0;L;;;;;N;;;;;
4601 15D1;CANADIAN SYLLABICS CARRIER WO;Lo;0;L;;;;;N;;;;;
4602 15D2;CANADIAN SYLLABICS CARRIER WE;Lo;0;L;;;;;N;;;;;
4603 15D3;CANADIAN SYLLABICS CARRIER WEE;Lo;0;L;;;;;N;;;;;
4604 15D4;CANADIAN SYLLABICS CARRIER WI;Lo;0;L;;;;;N;;;;;
4605 15D5;CANADIAN SYLLABICS CARRIER WA;Lo;0;L;;;;;N;;;;;
4606 15D6;CANADIAN SYLLABICS CARRIER HWU;Lo;0;L;;;;;N;;;;;
4607 15D7;CANADIAN SYLLABICS CARRIER HWO;Lo;0;L;;;;;N;;;;;
4608 15D8;CANADIAN SYLLABICS CARRIER HWE;Lo;0;L;;;;;N;;;;;
4609 15D9;CANADIAN SYLLABICS CARRIER HWEE;Lo;0;L;;;;;N;;;;;
4610 15DA;CANADIAN SYLLABICS CARRIER HWI;Lo;0;L;;;;;N;;;;;
4611 15DB;CANADIAN SYLLABICS CARRIER HWA;Lo;0;L;;;;;N;;;;;
4612 15DC;CANADIAN SYLLABICS CARRIER THU;Lo;0;L;;;;;N;;;;;
4613 15DD;CANADIAN SYLLABICS CARRIER THO;Lo;0;L;;;;;N;;;;;
4614 15DE;CANADIAN SYLLABICS CARRIER THE;Lo;0;L;;;;;N;;;;;
4615 15DF;CANADIAN SYLLABICS CARRIER THEE;Lo;0;L;;;;;N;;;;;
4616 15E0;CANADIAN SYLLABICS CARRIER THI;Lo;0;L;;;;;N;;;;;
4617 15E1;CANADIAN SYLLABICS CARRIER THA;Lo;0;L;;;;;N;;;;;
4618 15E2;CANADIAN SYLLABICS CARRIER TTU;Lo;0;L;;;;;N;;;;;
4619 15E3;CANADIAN SYLLABICS CARRIER TTO;Lo;0;L;;;;;N;;;;;
4620 15E4;CANADIAN SYLLABICS CARRIER TTE;Lo;0;L;;;;;N;;;;;
4621 15E5;CANADIAN SYLLABICS CARRIER TTEE;Lo;0;L;;;;;N;;;;;
4622 15E6;CANADIAN SYLLABICS CARRIER TTI;Lo;0;L;;;;;N;;;;;
4623 15E7;CANADIAN SYLLABICS CARRIER TTA;Lo;0;L;;;;;N;;;;;
4624 15E8;CANADIAN SYLLABICS CARRIER PU;Lo;0;L;;;;;N;;;;;
4625 15E9;CANADIAN SYLLABICS CARRIER PO;Lo;0;L;;;;;N;;;;;
4626 15EA;CANADIAN SYLLABICS CARRIER PE;Lo;0;L;;;;;N;;;;;
4627 15EB;CANADIAN SYLLABICS CARRIER PEE;Lo;0;L;;;;;N;;;;;
4628 15EC;CANADIAN SYLLABICS CARRIER PI;Lo;0;L;;;;;N;;;;;
4629 15ED;CANADIAN SYLLABICS CARRIER PA;Lo;0;L;;;;;N;;;;;
4630 15EE;CANADIAN SYLLABICS CARRIER P;Lo;0;L;;;;;N;;;;;
4631 15EF;CANADIAN SYLLABICS CARRIER GU;Lo;0;L;;;;;N;;;;;
4632 15F0;CANADIAN SYLLABICS CARRIER GO;Lo;0;L;;;;;N;;;;;
4633 15F1;CANADIAN SYLLABICS CARRIER GE;Lo;0;L;;;;;N;;;;;
4634 15F2;CANADIAN SYLLABICS CARRIER GEE;Lo;0;L;;;;;N;;;;;
4635 15F3;CANADIAN SYLLABICS CARRIER GI;Lo;0;L;;;;;N;;;;;
4636 15F4;CANADIAN SYLLABICS CARRIER GA;Lo;0;L;;;;;N;;;;;
4637 15F5;CANADIAN SYLLABICS CARRIER KHU;Lo;0;L;;;;;N;;;;;
4638 15F6;CANADIAN SYLLABICS CARRIER KHO;Lo;0;L;;;;;N;;;;;
4639 15F7;CANADIAN SYLLABICS CARRIER KHE;Lo;0;L;;;;;N;;;;;
4640 15F8;CANADIAN SYLLABICS CARRIER KHEE;Lo;0;L;;;;;N;;;;;
4641 15F9;CANADIAN SYLLABICS CARRIER KHI;Lo;0;L;;;;;N;;;;;
4642 15FA;CANADIAN SYLLABICS CARRIER KHA;Lo;0;L;;;;;N;;;;;
4643 15FB;CANADIAN SYLLABICS CARRIER KKU;Lo;0;L;;;;;N;;;;;
4644 15FC;CANADIAN SYLLABICS CARRIER KKO;Lo;0;L;;;;;N;;;;;
4645 15FD;CANADIAN SYLLABICS CARRIER KKE;Lo;0;L;;;;;N;;;;;
4646 15FE;CANADIAN SYLLABICS CARRIER KKEE;Lo;0;L;;;;;N;;;;;
4647 15FF;CANADIAN SYLLABICS CARRIER KKI;Lo;0;L;;;;;N;;;;;
4648 1600;CANADIAN SYLLABICS CARRIER KKA;Lo;0;L;;;;;N;;;;;
4649 1601;CANADIAN SYLLABICS CARRIER KK;Lo;0;L;;;;;N;;;;;
4650 1602;CANADIAN SYLLABICS CARRIER NU;Lo;0;L;;;;;N;;;;;
4651 1603;CANADIAN SYLLABICS CARRIER NO;Lo;0;L;;;;;N;;;;;
4652 1604;CANADIAN SYLLABICS CARRIER NE;Lo;0;L;;;;;N;;;;;
4653 1605;CANADIAN SYLLABICS CARRIER NEE;Lo;0;L;;;;;N;;;;;
4654 1606;CANADIAN SYLLABICS CARRIER NI;Lo;0;L;;;;;N;;;;;
4655 1607;CANADIAN SYLLABICS CARRIER NA;Lo;0;L;;;;;N;;;;;
4656 1608;CANADIAN SYLLABICS CARRIER MU;Lo;0;L;;;;;N;;;;;
4657 1609;CANADIAN SYLLABICS CARRIER MO;Lo;0;L;;;;;N;;;;;
4658 160A;CANADIAN SYLLABICS CARRIER ME;Lo;0;L;;;;;N;;;;;
4659 160B;CANADIAN SYLLABICS CARRIER MEE;Lo;0;L;;;;;N;;;;;
4660 160C;CANADIAN SYLLABICS CARRIER MI;Lo;0;L;;;;;N;;;;;
4661 160D;CANADIAN SYLLABICS CARRIER MA;Lo;0;L;;;;;N;;;;;
4662 160E;CANADIAN SYLLABICS CARRIER YU;Lo;0;L;;;;;N;;;;;
4663 160F;CANADIAN SYLLABICS CARRIER YO;Lo;0;L;;;;;N;;;;;
4664 1610;CANADIAN SYLLABICS CARRIER YE;Lo;0;L;;;;;N;;;;;
4665 1611;CANADIAN SYLLABICS CARRIER YEE;Lo;0;L;;;;;N;;;;;
4666 1612;CANADIAN SYLLABICS CARRIER YI;Lo;0;L;;;;;N;;;;;
4667 1613;CANADIAN SYLLABICS CARRIER YA;Lo;0;L;;;;;N;;;;;
4668 1614;CANADIAN SYLLABICS CARRIER JU;Lo;0;L;;;;;N;;;;;
4669 1615;CANADIAN SYLLABICS SAYISI JU;Lo;0;L;;;;;N;;;;;
4670 1616;CANADIAN SYLLABICS CARRIER JO;Lo;0;L;;;;;N;;;;;
4671 1617;CANADIAN SYLLABICS CARRIER JE;Lo;0;L;;;;;N;;;;;
4672 1618;CANADIAN SYLLABICS CARRIER JEE;Lo;0;L;;;;;N;;;;;
4673 1619;CANADIAN SYLLABICS CARRIER JI;Lo;0;L;;;;;N;;;;;
4674 161A;CANADIAN SYLLABICS SAYISI JI;Lo;0;L;;;;;N;;;;;
4675 161B;CANADIAN SYLLABICS CARRIER JA;Lo;0;L;;;;;N;;;;;
4676 161C;CANADIAN SYLLABICS CARRIER JJU;Lo;0;L;;;;;N;;;;;
4677 161D;CANADIAN SYLLABICS CARRIER JJO;Lo;0;L;;;;;N;;;;;
4678 161E;CANADIAN SYLLABICS CARRIER JJE;Lo;0;L;;;;;N;;;;;
4679 161F;CANADIAN SYLLABICS CARRIER JJEE;Lo;0;L;;;;;N;;;;;
4680 1620;CANADIAN SYLLABICS CARRIER JJI;Lo;0;L;;;;;N;;;;;
4681 1621;CANADIAN SYLLABICS CARRIER JJA;Lo;0;L;;;;;N;;;;;
4682 1622;CANADIAN SYLLABICS CARRIER LU;Lo;0;L;;;;;N;;;;;
4683 1623;CANADIAN SYLLABICS CARRIER LO;Lo;0;L;;;;;N;;;;;
4684 1624;CANADIAN SYLLABICS CARRIER LE;Lo;0;L;;;;;N;;;;;
4685 1625;CANADIAN SYLLABICS CARRIER LEE;Lo;0;L;;;;;N;;;;;
4686 1626;CANADIAN SYLLABICS CARRIER LI;Lo;0;L;;;;;N;;;;;
4687 1627;CANADIAN SYLLABICS CARRIER LA;Lo;0;L;;;;;N;;;;;
4688 1628;CANADIAN SYLLABICS CARRIER DLU;Lo;0;L;;;;;N;;;;;
4689 1629;CANADIAN SYLLABICS CARRIER DLO;Lo;0;L;;;;;N;;;;;
4690 162A;CANADIAN SYLLABICS CARRIER DLE;Lo;0;L;;;;;N;;;;;
4691 162B;CANADIAN SYLLABICS CARRIER DLEE;Lo;0;L;;;;;N;;;;;
4692 162C;CANADIAN SYLLABICS CARRIER DLI;Lo;0;L;;;;;N;;;;;
4693 162D;CANADIAN SYLLABICS CARRIER DLA;Lo;0;L;;;;;N;;;;;
4694 162E;CANADIAN SYLLABICS CARRIER LHU;Lo;0;L;;;;;N;;;;;
4695 162F;CANADIAN SYLLABICS CARRIER LHO;Lo;0;L;;;;;N;;;;;
4696 1630;CANADIAN SYLLABICS CARRIER LHE;Lo;0;L;;;;;N;;;;;
4697 1631;CANADIAN SYLLABICS CARRIER LHEE;Lo;0;L;;;;;N;;;;;
4698 1632;CANADIAN SYLLABICS CARRIER LHI;Lo;0;L;;;;;N;;;;;
4699 1633;CANADIAN SYLLABICS CARRIER LHA;Lo;0;L;;;;;N;;;;;
4700 1634;CANADIAN SYLLABICS CARRIER TLHU;Lo;0;L;;;;;N;;;;;
4701 1635;CANADIAN SYLLABICS CARRIER TLHO;Lo;0;L;;;;;N;;;;;
4702 1636;CANADIAN SYLLABICS CARRIER TLHE;Lo;0;L;;;;;N;;;;;
4703 1637;CANADIAN SYLLABICS CARRIER TLHEE;Lo;0;L;;;;;N;;;;;
4704 1638;CANADIAN SYLLABICS CARRIER TLHI;Lo;0;L;;;;;N;;;;;
4705 1639;CANADIAN SYLLABICS CARRIER TLHA;Lo;0;L;;;;;N;;;;;
4706 163A;CANADIAN SYLLABICS CARRIER TLU;Lo;0;L;;;;;N;;;;;
4707 163B;CANADIAN SYLLABICS CARRIER TLO;Lo;0;L;;;;;N;;;;;
4708 163C;CANADIAN SYLLABICS CARRIER TLE;Lo;0;L;;;;;N;;;;;
4709 163D;CANADIAN SYLLABICS CARRIER TLEE;Lo;0;L;;;;;N;;;;;
4710 163E;CANADIAN SYLLABICS CARRIER TLI;Lo;0;L;;;;;N;;;;;
4711 163F;CANADIAN SYLLABICS CARRIER TLA;Lo;0;L;;;;;N;;;;;
4712 1640;CANADIAN SYLLABICS CARRIER ZU;Lo;0;L;;;;;N;;;;;
4713 1641;CANADIAN SYLLABICS CARRIER ZO;Lo;0;L;;;;;N;;;;;
4714 1642;CANADIAN SYLLABICS CARRIER ZE;Lo;0;L;;;;;N;;;;;
4715 1643;CANADIAN SYLLABICS CARRIER ZEE;Lo;0;L;;;;;N;;;;;
4716 1644;CANADIAN SYLLABICS CARRIER ZI;Lo;0;L;;;;;N;;;;;
4717 1645;CANADIAN SYLLABICS CARRIER ZA;Lo;0;L;;;;;N;;;;;
4718 1646;CANADIAN SYLLABICS CARRIER Z;Lo;0;L;;;;;N;;;;;
4719 1647;CANADIAN SYLLABICS CARRIER INITIAL Z;Lo;0;L;;;;;N;;;;;
4720 1648;CANADIAN SYLLABICS CARRIER DZU;Lo;0;L;;;;;N;;;;;
4721 1649;CANADIAN SYLLABICS CARRIER DZO;Lo;0;L;;;;;N;;;;;
4722 164A;CANADIAN SYLLABICS CARRIER DZE;Lo;0;L;;;;;N;;;;;
4723 164B;CANADIAN SYLLABICS CARRIER DZEE;Lo;0;L;;;;;N;;;;;
4724 164C;CANADIAN SYLLABICS CARRIER DZI;Lo;0;L;;;;;N;;;;;
4725 164D;CANADIAN SYLLABICS CARRIER DZA;Lo;0;L;;;;;N;;;;;
4726 164E;CANADIAN SYLLABICS CARRIER SU;Lo;0;L;;;;;N;;;;;
4727 164F;CANADIAN SYLLABICS CARRIER SO;Lo;0;L;;;;;N;;;;;
4728 1650;CANADIAN SYLLABICS CARRIER SE;Lo;0;L;;;;;N;;;;;
4729 1651;CANADIAN SYLLABICS CARRIER SEE;Lo;0;L;;;;;N;;;;;
4730 1652;CANADIAN SYLLABICS CARRIER SI;Lo;0;L;;;;;N;;;;;
4731 1653;CANADIAN SYLLABICS CARRIER SA;Lo;0;L;;;;;N;;;;;
4732 1654;CANADIAN SYLLABICS CARRIER SHU;Lo;0;L;;;;;N;;;;;
4733 1655;CANADIAN SYLLABICS CARRIER SHO;Lo;0;L;;;;;N;;;;;
4734 1656;CANADIAN SYLLABICS CARRIER SHE;Lo;0;L;;;;;N;;;;;
4735 1657;CANADIAN SYLLABICS CARRIER SHEE;Lo;0;L;;;;;N;;;;;
4736 1658;CANADIAN SYLLABICS CARRIER SHI;Lo;0;L;;;;;N;;;;;
4737 1659;CANADIAN SYLLABICS CARRIER SHA;Lo;0;L;;;;;N;;;;;
4738 165A;CANADIAN SYLLABICS CARRIER SH;Lo;0;L;;;;;N;;;;;
4739 165B;CANADIAN SYLLABICS CARRIER TSU;Lo;0;L;;;;;N;;;;;
4740 165C;CANADIAN SYLLABICS CARRIER TSO;Lo;0;L;;;;;N;;;;;
4741 165D;CANADIAN SYLLABICS CARRIER TSE;Lo;0;L;;;;;N;;;;;
4742 165E;CANADIAN SYLLABICS CARRIER TSEE;Lo;0;L;;;;;N;;;;;
4743 165F;CANADIAN SYLLABICS CARRIER TSI;Lo;0;L;;;;;N;;;;;
4744 1660;CANADIAN SYLLABICS CARRIER TSA;Lo;0;L;;;;;N;;;;;
4745 1661;CANADIAN SYLLABICS CARRIER CHU;Lo;0;L;;;;;N;;;;;
4746 1662;CANADIAN SYLLABICS CARRIER CHO;Lo;0;L;;;;;N;;;;;
4747 1663;CANADIAN SYLLABICS CARRIER CHE;Lo;0;L;;;;;N;;;;;
4748 1664;CANADIAN SYLLABICS CARRIER CHEE;Lo;0;L;;;;;N;;;;;
4749 1665;CANADIAN SYLLABICS CARRIER CHI;Lo;0;L;;;;;N;;;;;
4750 1666;CANADIAN SYLLABICS CARRIER CHA;Lo;0;L;;;;;N;;;;;
4751 1667;CANADIAN SYLLABICS CARRIER TTSU;Lo;0;L;;;;;N;;;;;
4752 1668;CANADIAN SYLLABICS CARRIER TTSO;Lo;0;L;;;;;N;;;;;
4753 1669;CANADIAN SYLLABICS CARRIER TTSE;Lo;0;L;;;;;N;;;;;
4754 166A;CANADIAN SYLLABICS CARRIER TTSEE;Lo;0;L;;;;;N;;;;;
4755 166B;CANADIAN SYLLABICS CARRIER TTSI;Lo;0;L;;;;;N;;;;;
4756 166C;CANADIAN SYLLABICS CARRIER TTSA;Lo;0;L;;;;;N;;;;;
4757 166D;CANADIAN SYLLABICS CHI SIGN;Po;0;L;;;;;N;;;;;
4758 166E;CANADIAN SYLLABICS FULL STOP;Po;0;L;;;;;N;;;;;
4759 166F;CANADIAN SYLLABICS QAI;Lo;0;L;;;;;N;;;;;
4760 1670;CANADIAN SYLLABICS NGAI;Lo;0;L;;;;;N;;;;;
4761 1671;CANADIAN SYLLABICS NNGI;Lo;0;L;;;;;N;;;;;
4762 1672;CANADIAN SYLLABICS NNGII;Lo;0;L;;;;;N;;;;;
4763 1673;CANADIAN SYLLABICS NNGO;Lo;0;L;;;;;N;;;;;
4764 1674;CANADIAN SYLLABICS NNGOO;Lo;0;L;;;;;N;;;;;
4765 1675;CANADIAN SYLLABICS NNGA;Lo;0;L;;;;;N;;;;;
4766 1676;CANADIAN SYLLABICS NNGAA;Lo;0;L;;;;;N;;;;;
4767 1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;;
4768 1681;OGHAM LETTER BEITH;Lo;0;L;;;;;N;;;;;
4769 1682;OGHAM LETTER LUIS;Lo;0;L;;;;;N;;;;;
4770 1683;OGHAM LETTER FEARN;Lo;0;L;;;;;N;;;;;
4771 1684;OGHAM LETTER SAIL;Lo;0;L;;;;;N;;;;;
4772 1685;OGHAM LETTER NION;Lo;0;L;;;;;N;;;;;
4773 1686;OGHAM LETTER UATH;Lo;0;L;;;;;N;;;;;
4774 1687;OGHAM LETTER DAIR;Lo;0;L;;;;;N;;;;;
4775 1688;OGHAM LETTER TINNE;Lo;0;L;;;;;N;;;;;
4776 1689;OGHAM LETTER COLL;Lo;0;L;;;;;N;;;;;
4777 168A;OGHAM LETTER CEIRT;Lo;0;L;;;;;N;;;;;
4778 168B;OGHAM LETTER MUIN;Lo;0;L;;;;;N;;;;;
4779 168C;OGHAM LETTER GORT;Lo;0;L;;;;;N;;;;;
4780 168D;OGHAM LETTER NGEADAL;Lo;0;L;;;;;N;;;;;
4781 168E;OGHAM LETTER STRAIF;Lo;0;L;;;;;N;;;;;
4782 168F;OGHAM LETTER RUIS;Lo;0;L;;;;;N;;;;;
4783 1690;OGHAM LETTER AILM;Lo;0;L;;;;;N;;;;;
4784 1691;OGHAM LETTER ONN;Lo;0;L;;;;;N;;;;;
4785 1692;OGHAM LETTER UR;Lo;0;L;;;;;N;;;;;
4786 1693;OGHAM LETTER EADHADH;Lo;0;L;;;;;N;;;;;
4787 1694;OGHAM LETTER IODHADH;Lo;0;L;;;;;N;;;;;
4788 1695;OGHAM LETTER EABHADH;Lo;0;L;;;;;N;;;;;
4789 1696;OGHAM LETTER OR;Lo;0;L;;;;;N;;;;;
4790 1697;OGHAM LETTER UILLEANN;Lo;0;L;;;;;N;;;;;
4791 1698;OGHAM LETTER IFIN;Lo;0;L;;;;;N;;;;;
4792 1699;OGHAM LETTER EAMHANCHOLL;Lo;0;L;;;;;N;;;;;
4793 169A;OGHAM LETTER PEITH;Lo;0;L;;;;;N;;;;;
4794 169B;OGHAM FEATHER MARK;Ps;0;ON;;;;;Y;;;;;
4795 169C;OGHAM REVERSED FEATHER MARK;Pe;0;ON;;;;;Y;;;;;
4796 16A0;RUNIC LETTER FEHU FEOH FE F;Lo;0;L;;;;;N;;;;;
4797 16A1;RUNIC LETTER V;Lo;0;L;;;;;N;;;;;
4798 16A2;RUNIC LETTER URUZ UR U;Lo;0;L;;;;;N;;;;;
4799 16A3;RUNIC LETTER YR;Lo;0;L;;;;;N;;;;;
4800 16A4;RUNIC LETTER Y;Lo;0;L;;;;;N;;;;;
4801 16A5;RUNIC LETTER W;Lo;0;L;;;;;N;;;;;
4802 16A6;RUNIC LETTER THURISAZ THURS THORN;Lo;0;L;;;;;N;;;;;
4803 16A7;RUNIC LETTER ETH;Lo;0;L;;;;;N;;;;;
4804 16A8;RUNIC LETTER ANSUZ A;Lo;0;L;;;;;N;;;;;
4805 16A9;RUNIC LETTER OS O;Lo;0;L;;;;;N;;;;;
4806 16AA;RUNIC LETTER AC A;Lo;0;L;;;;;N;;;;;
4807 16AB;RUNIC LETTER AESC;Lo;0;L;;;;;N;;;;;
4808 16AC;RUNIC LETTER LONG-BRANCH-OSS O;Lo;0;L;;;;;N;;;;;
4809 16AD;RUNIC LETTER SHORT-TWIG-OSS O;Lo;0;L;;;;;N;;;;;
4810 16AE;RUNIC LETTER O;Lo;0;L;;;;;N;;;;;
4811 16AF;RUNIC LETTER OE;Lo;0;L;;;;;N;;;;;
4812 16B0;RUNIC LETTER ON;Lo;0;L;;;;;N;;;;;
4813 16B1;RUNIC LETTER RAIDO RAD REID R;Lo;0;L;;;;;N;;;;;
4814 16B2;RUNIC LETTER KAUNA;Lo;0;L;;;;;N;;;;;
4815 16B3;RUNIC LETTER CEN;Lo;0;L;;;;;N;;;;;
4816 16B4;RUNIC LETTER KAUN K;Lo;0;L;;;;;N;;;;;
4817 16B5;RUNIC LETTER G;Lo;0;L;;;;;N;;;;;
4818 16B6;RUNIC LETTER ENG;Lo;0;L;;;;;N;;;;;
4819 16B7;RUNIC LETTER GEBO GYFU G;Lo;0;L;;;;;N;;;;;
4820 16B8;RUNIC LETTER GAR;Lo;0;L;;;;;N;;;;;
4821 16B9;RUNIC LETTER WUNJO WYNN W;Lo;0;L;;;;;N;;;;;
4822 16BA;RUNIC LETTER HAGLAZ H;Lo;0;L;;;;;N;;;;;
4823 16BB;RUNIC LETTER HAEGL H;Lo;0;L;;;;;N;;;;;
4824 16BC;RUNIC LETTER LONG-BRANCH-HAGALL H;Lo;0;L;;;;;N;;;;;
4825 16BD;RUNIC LETTER SHORT-TWIG-HAGALL H;Lo;0;L;;;;;N;;;;;
4826 16BE;RUNIC LETTER NAUDIZ NYD NAUD N;Lo;0;L;;;;;N;;;;;
4827 16BF;RUNIC LETTER SHORT-TWIG-NAUD N;Lo;0;L;;;;;N;;;;;
4828 16C0;RUNIC LETTER DOTTED-N;Lo;0;L;;;;;N;;;;;
4829 16C1;RUNIC LETTER ISAZ IS ISS I;Lo;0;L;;;;;N;;;;;
4830 16C2;RUNIC LETTER E;Lo;0;L;;;;;N;;;;;
4831 16C3;RUNIC LETTER JERAN J;Lo;0;L;;;;;N;;;;;
4832 16C4;RUNIC LETTER GER;Lo;0;L;;;;;N;;;;;
4833 16C5;RUNIC LETTER LONG-BRANCH-AR AE;Lo;0;L;;;;;N;;;;;
4834 16C6;RUNIC LETTER SHORT-TWIG-AR A;Lo;0;L;;;;;N;;;;;
4835 16C7;RUNIC LETTER IWAZ EOH;Lo;0;L;;;;;N;;;;;
4836 16C8;RUNIC LETTER PERTHO PEORTH P;Lo;0;L;;;;;N;;;;;
4837 16C9;RUNIC LETTER ALGIZ EOLHX;Lo;0;L;;;;;N;;;;;
4838 16CA;RUNIC LETTER SOWILO S;Lo;0;L;;;;;N;;;;;
4839 16CB;RUNIC LETTER SIGEL LONG-BRANCH-SOL S;Lo;0;L;;;;;N;;;;;
4840 16CC;RUNIC LETTER SHORT-TWIG-SOL S;Lo;0;L;;;;;N;;;;;
4841 16CD;RUNIC LETTER C;Lo;0;L;;;;;N;;;;;
4842 16CE;RUNIC LETTER Z;Lo;0;L;;;;;N;;;;;
4843 16CF;RUNIC LETTER TIWAZ TIR TYR T;Lo;0;L;;;;;N;;;;;
4844 16D0;RUNIC LETTER SHORT-TWIG-TYR T;Lo;0;L;;;;;N;;;;;
4845 16D1;RUNIC LETTER D;Lo;0;L;;;;;N;;;;;
4846 16D2;RUNIC LETTER BERKANAN BEORC BJARKAN B;Lo;0;L;;;;;N;;;;;
4847 16D3;RUNIC LETTER SHORT-TWIG-BJARKAN B;Lo;0;L;;;;;N;;;;;
4848 16D4;RUNIC LETTER DOTTED-P;Lo;0;L;;;;;N;;;;;
4849 16D5;RUNIC LETTER OPEN-P;Lo;0;L;;;;;N;;;;;
4850 16D6;RUNIC LETTER EHWAZ EH E;Lo;0;L;;;;;N;;;;;
4851 16D7;RUNIC LETTER MANNAZ MAN M;Lo;0;L;;;;;N;;;;;
4852 16D8;RUNIC LETTER LONG-BRANCH-MADR M;Lo;0;L;;;;;N;;;;;
4853 16D9;RUNIC LETTER SHORT-TWIG-MADR M;Lo;0;L;;;;;N;;;;;
4854 16DA;RUNIC LETTER LAUKAZ LAGU LOGR L;Lo;0;L;;;;;N;;;;;
4855 16DB;RUNIC LETTER DOTTED-L;Lo;0;L;;;;;N;;;;;
4856 16DC;RUNIC LETTER INGWAZ;Lo;0;L;;;;;N;;;;;
4857 16DD;RUNIC LETTER ING;Lo;0;L;;;;;N;;;;;
4858 16DE;RUNIC LETTER DAGAZ DAEG D;Lo;0;L;;;;;N;;;;;
4859 16DF;RUNIC LETTER OTHALAN ETHEL O;Lo;0;L;;;;;N;;;;;
4860 16E0;RUNIC LETTER EAR;Lo;0;L;;;;;N;;;;;
4861 16E1;RUNIC LETTER IOR;Lo;0;L;;;;;N;;;;;
4862 16E2;RUNIC LETTER CWEORTH;Lo;0;L;;;;;N;;;;;
4863 16E3;RUNIC LETTER CALC;Lo;0;L;;;;;N;;;;;
4864 16E4;RUNIC LETTER CEALC;Lo;0;L;;;;;N;;;;;
4865 16E5;RUNIC LETTER STAN;Lo;0;L;;;;;N;;;;;
4866 16E6;RUNIC LETTER LONG-BRANCH-YR;Lo;0;L;;;;;N;;;;;
4867 16E7;RUNIC LETTER SHORT-TWIG-YR;Lo;0;L;;;;;N;;;;;
4868 16E8;RUNIC LETTER ICELANDIC-YR;Lo;0;L;;;;;N;;;;;
4869 16E9;RUNIC LETTER Q;Lo;0;L;;;;;N;;;;;
4870 16EA;RUNIC LETTER X;Lo;0;L;;;;;N;;;;;
4871 16EB;RUNIC SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;;
4872 16EC;RUNIC MULTIPLE PUNCTUATION;Po;0;L;;;;;N;;;;;
4873 16ED;RUNIC CROSS PUNCTUATION;Po;0;L;;;;;N;;;;;
4874 16EE;RUNIC ARLAUG SYMBOL;Nl;0;L;;;;17;N;;golden number 17;;;
4875 16EF;RUNIC TVIMADUR SYMBOL;Nl;0;L;;;;18;N;;golden number 18;;;
4876 16F0;RUNIC BELGTHOR SYMBOL;Nl;0;L;;;;19;N;;golden number 19;;;
4877 1700;TAGALOG LETTER A;Lo;0;L;;;;;N;;;;;
4878 1701;TAGALOG LETTER I;Lo;0;L;;;;;N;;;;;
4879 1702;TAGALOG LETTER U;Lo;0;L;;;;;N;;;;;
4880 1703;TAGALOG LETTER KA;Lo;0;L;;;;;N;;;;;
4881 1704;TAGALOG LETTER GA;Lo;0;L;;;;;N;;;;;
4882 1705;TAGALOG LETTER NGA;Lo;0;L;;;;;N;;;;;
4883 1706;TAGALOG LETTER TA;Lo;0;L;;;;;N;;;;;
4884 1707;TAGALOG LETTER DA;Lo;0;L;;;;;N;;;;;
4885 1708;TAGALOG LETTER NA;Lo;0;L;;;;;N;;;;;
4886 1709;TAGALOG LETTER PA;Lo;0;L;;;;;N;;;;;
4887 170A;TAGALOG LETTER BA;Lo;0;L;;;;;N;;;;;
4888 170B;TAGALOG LETTER MA;Lo;0;L;;;;;N;;;;;
4889 170C;TAGALOG LETTER YA;Lo;0;L;;;;;N;;;;;
4890 170E;TAGALOG LETTER LA;Lo;0;L;;;;;N;;;;;
4891 170F;TAGALOG LETTER WA;Lo;0;L;;;;;N;;;;;
4892 1710;TAGALOG LETTER SA;Lo;0;L;;;;;N;;;;;
4893 1711;TAGALOG LETTER HA;Lo;0;L;;;;;N;;;;;
4894 1712;TAGALOG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
4895 1713;TAGALOG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
4896 1714;TAGALOG SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
4897 1720;HANUNOO LETTER A;Lo;0;L;;;;;N;;;;;
4898 1721;HANUNOO LETTER I;Lo;0;L;;;;;N;;;;;
4899 1722;HANUNOO LETTER U;Lo;0;L;;;;;N;;;;;
4900 1723;HANUNOO LETTER KA;Lo;0;L;;;;;N;;;;;
4901 1724;HANUNOO LETTER GA;Lo;0;L;;;;;N;;;;;
4902 1725;HANUNOO LETTER NGA;Lo;0;L;;;;;N;;;;;
4903 1726;HANUNOO LETTER TA;Lo;0;L;;;;;N;;;;;
4904 1727;HANUNOO LETTER DA;Lo;0;L;;;;;N;;;;;
4905 1728;HANUNOO LETTER NA;Lo;0;L;;;;;N;;;;;
4906 1729;HANUNOO LETTER PA;Lo;0;L;;;;;N;;;;;
4907 172A;HANUNOO LETTER BA;Lo;0;L;;;;;N;;;;;
4908 172B;HANUNOO LETTER MA;Lo;0;L;;;;;N;;;;;
4909 172C;HANUNOO LETTER YA;Lo;0;L;;;;;N;;;;;
4910 172D;HANUNOO LETTER RA;Lo;0;L;;;;;N;;;;;
4911 172E;HANUNOO LETTER LA;Lo;0;L;;;;;N;;;;;
4912 172F;HANUNOO LETTER WA;Lo;0;L;;;;;N;;;;;
4913 1730;HANUNOO LETTER SA;Lo;0;L;;;;;N;;;;;
4914 1731;HANUNOO LETTER HA;Lo;0;L;;;;;N;;;;;
4915 1732;HANUNOO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
4916 1733;HANUNOO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
4917 1734;HANUNOO SIGN PAMUDPOD;Mn;9;NSM;;;;;N;;;;;
4918 1735;PHILIPPINE SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;;
4919 1736;PHILIPPINE DOUBLE PUNCTUATION;Po;0;L;;;;;N;;;;;
4920 1740;BUHID LETTER A;Lo;0;L;;;;;N;;;;;
4921 1741;BUHID LETTER I;Lo;0;L;;;;;N;;;;;
4922 1742;BUHID LETTER U;Lo;0;L;;;;;N;;;;;
4923 1743;BUHID LETTER KA;Lo;0;L;;;;;N;;;;;
4924 1744;BUHID LETTER GA;Lo;0;L;;;;;N;;;;;
4925 1745;BUHID LETTER NGA;Lo;0;L;;;;;N;;;;;
4926 1746;BUHID LETTER TA;Lo;0;L;;;;;N;;;;;
4927 1747;BUHID LETTER DA;Lo;0;L;;;;;N;;;;;
4928 1748;BUHID LETTER NA;Lo;0;L;;;;;N;;;;;
4929 1749;BUHID LETTER PA;Lo;0;L;;;;;N;;;;;
4930 174A;BUHID LETTER BA;Lo;0;L;;;;;N;;;;;
4931 174B;BUHID LETTER MA;Lo;0;L;;;;;N;;;;;
4932 174C;BUHID LETTER YA;Lo;0;L;;;;;N;;;;;
4933 174D;BUHID LETTER RA;Lo;0;L;;;;;N;;;;;
4934 174E;BUHID LETTER LA;Lo;0;L;;;;;N;;;;;
4935 174F;BUHID LETTER WA;Lo;0;L;;;;;N;;;;;
4936 1750;BUHID LETTER SA;Lo;0;L;;;;;N;;;;;
4937 1751;BUHID LETTER HA;Lo;0;L;;;;;N;;;;;
4938 1752;BUHID VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
4939 1753;BUHID VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
4940 1760;TAGBANWA LETTER A;Lo;0;L;;;;;N;;;;;
4941 1761;TAGBANWA LETTER I;Lo;0;L;;;;;N;;;;;
4942 1762;TAGBANWA LETTER U;Lo;0;L;;;;;N;;;;;
4943 1763;TAGBANWA LETTER KA;Lo;0;L;;;;;N;;;;;
4944 1764;TAGBANWA LETTER GA;Lo;0;L;;;;;N;;;;;
4945 1765;TAGBANWA LETTER NGA;Lo;0;L;;;;;N;;;;;
4946 1766;TAGBANWA LETTER TA;Lo;0;L;;;;;N;;;;;
4947 1767;TAGBANWA LETTER DA;Lo;0;L;;;;;N;;;;;
4948 1768;TAGBANWA LETTER NA;Lo;0;L;;;;;N;;;;;
4949 1769;TAGBANWA LETTER PA;Lo;0;L;;;;;N;;;;;
4950 176A;TAGBANWA LETTER BA;Lo;0;L;;;;;N;;;;;
4951 176B;TAGBANWA LETTER MA;Lo;0;L;;;;;N;;;;;
4952 176C;TAGBANWA LETTER YA;Lo;0;L;;;;;N;;;;;
4953 176E;TAGBANWA LETTER LA;Lo;0;L;;;;;N;;;;;
4954 176F;TAGBANWA LETTER WA;Lo;0;L;;;;;N;;;;;
4955 1770;TAGBANWA LETTER SA;Lo;0;L;;;;;N;;;;;
4956 1772;TAGBANWA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
4957 1773;TAGBANWA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
4958 1780;KHMER LETTER KA;Lo;0;L;;;;;N;;;;;
4959 1781;KHMER LETTER KHA;Lo;0;L;;;;;N;;;;;
4960 1782;KHMER LETTER KO;Lo;0;L;;;;;N;;;;;
4961 1783;KHMER LETTER KHO;Lo;0;L;;;;;N;;;;;
4962 1784;KHMER LETTER NGO;Lo;0;L;;;;;N;;;;;
4963 1785;KHMER LETTER CA;Lo;0;L;;;;;N;;;;;
4964 1786;KHMER LETTER CHA;Lo;0;L;;;;;N;;;;;
4965 1787;KHMER LETTER CO;Lo;0;L;;;;;N;;;;;
4966 1788;KHMER LETTER CHO;Lo;0;L;;;;;N;;;;;
4967 1789;KHMER LETTER NYO;Lo;0;L;;;;;N;;;;;
4968 178A;KHMER LETTER DA;Lo;0;L;;;;;N;;;;;
4969 178B;KHMER LETTER TTHA;Lo;0;L;;;;;N;;;;;
4970 178C;KHMER LETTER DO;Lo;0;L;;;;;N;;;;;
4971 178D;KHMER LETTER TTHO;Lo;0;L;;;;;N;;;;;
4972 178E;KHMER LETTER NNO;Lo;0;L;;;;;N;;;;;
4973 178F;KHMER LETTER TA;Lo;0;L;;;;;N;;;;;
4974 1790;KHMER LETTER THA;Lo;0;L;;;;;N;;;;;
4975 1791;KHMER LETTER TO;Lo;0;L;;;;;N;;;;;
4976 1792;KHMER LETTER THO;Lo;0;L;;;;;N;;;;;
4977 1793;KHMER LETTER NO;Lo;0;L;;;;;N;;;;;
4978 1794;KHMER LETTER BA;Lo;0;L;;;;;N;;;;;
4979 1795;KHMER LETTER PHA;Lo;0;L;;;;;N;;;;;
4980 1796;KHMER LETTER PO;Lo;0;L;;;;;N;;;;;
4981 1797;KHMER LETTER PHO;Lo;0;L;;;;;N;;;;;
4982 1798;KHMER LETTER MO;Lo;0;L;;;;;N;;;;;
4983 1799;KHMER LETTER YO;Lo;0;L;;;;;N;;;;;
4984 179A;KHMER LETTER RO;Lo;0;L;;;;;N;;;;;
4985 179B;KHMER LETTER LO;Lo;0;L;;;;;N;;;;;
4986 179C;KHMER LETTER VO;Lo;0;L;;;;;N;;;;;
4987 179D;KHMER LETTER SHA;Lo;0;L;;;;;N;;;;;
4988 179E;KHMER LETTER SSO;Lo;0;L;;;;;N;;;;;
4989 179F;KHMER LETTER SA;Lo;0;L;;;;;N;;;;;
4990 17A0;KHMER LETTER HA;Lo;0;L;;;;;N;;;;;
4991 17A1;KHMER LETTER LA;Lo;0;L;;;;;N;;;;;
4992 17A2;KHMER LETTER QA;Lo;0;L;;;;;N;;;;;
4993 17A3;KHMER INDEPENDENT VOWEL QAQ;Lo;0;L;;;;;N;;*;;;
4994 17A4;KHMER INDEPENDENT VOWEL QAA;Lo;0;L;;;;;N;;*;;;
4995 17A5;KHMER INDEPENDENT VOWEL QI;Lo;0;L;;;;;N;;;;;
4996 17A6;KHMER INDEPENDENT VOWEL QII;Lo;0;L;;;;;N;;;;;
4997 17A7;KHMER INDEPENDENT VOWEL QU;Lo;0;L;;;;;N;;;;;
4998 17A8;KHMER INDEPENDENT VOWEL QUK;Lo;0;L;;;;;N;;;;;
4999 17A9;KHMER INDEPENDENT VOWEL QUU;Lo;0;L;;;;;N;;;;;
5000 17AA;KHMER INDEPENDENT VOWEL QUUV;Lo;0;L;;;;;N;;;;;
5001 17AB;KHMER INDEPENDENT VOWEL RY;Lo;0;L;;;;;N;;;;;
5002 17AC;KHMER INDEPENDENT VOWEL RYY;Lo;0;L;;;;;N;;;;;
5003 17AD;KHMER INDEPENDENT VOWEL LY;Lo;0;L;;;;;N;;;;;
5004 17AE;KHMER INDEPENDENT VOWEL LYY;Lo;0;L;;;;;N;;;;;
5005 17AF;KHMER INDEPENDENT VOWEL QE;Lo;0;L;;;;;N;;;;;
5006 17B0;KHMER INDEPENDENT VOWEL QAI;Lo;0;L;;;;;N;;;;;
5007 17B1;KHMER INDEPENDENT VOWEL QOO TYPE ONE;Lo;0;L;;;;;N;;;;;
5008 17B2;KHMER INDEPENDENT VOWEL QOO TYPE TWO;Lo;0;L;;;;;N;;;;;
5009 17B3;KHMER INDEPENDENT VOWEL QAU;Lo;0;L;;;;;N;;;;;
5010 17B4;KHMER VOWEL INHERENT AQ;Cf;0;L;;;;;N;;*;;;
5011 17B5;KHMER VOWEL INHERENT AA;Cf;0;L;;;;;N;;*;;;
5012 17B6;KHMER VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
5013 17B7;KHMER VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
5014 17B8;KHMER VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
5015 17B9;KHMER VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;;
5016 17BA;KHMER VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;;
5017 17BB;KHMER VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
5018 17BC;KHMER VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;
5019 17BD;KHMER VOWEL SIGN UA;Mn;0;NSM;;;;;N;;;;;
5020 17BE;KHMER VOWEL SIGN OE;Mc;0;L;;;;;N;;;;;
5021 17BF;KHMER VOWEL SIGN YA;Mc;0;L;;;;;N;;;;;
5022 17C0;KHMER VOWEL SIGN IE;Mc;0;L;;;;;N;;;;;
5023 17C1;KHMER VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
5024 17C2;KHMER VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
5025 17C3;KHMER VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
5026 17C4;KHMER VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
5027 17C5;KHMER VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
5028 17C6;KHMER SIGN NIKAHIT;Mn;0;NSM;;;;;N;;;;;
5029 17C7;KHMER SIGN REAHMUK;Mc;0;L;;;;;N;;;;;
5030 17C8;KHMER SIGN YUUKALEAPINTU;Mc;0;L;;;;;N;;;;;
5031 17C9;KHMER SIGN MUUSIKATOAN;Mn;0;NSM;;;;;N;;;;;
5032 17CA;KHMER SIGN TRIISAP;Mn;0;NSM;;;;;N;;;;;
5033 17CB;KHMER SIGN BANTOC;Mn;0;NSM;;;;;N;;;;;
5034 17CC;KHMER SIGN ROBAT;Mn;0;NSM;;;;;N;;;;;
5035 17CD;KHMER SIGN TOANDAKHIAT;Mn;0;NSM;;;;;N;;;;;
5036 17CE;KHMER SIGN KAKABAT;Mn;0;NSM;;;;;N;;;;;
5037 17CF;KHMER SIGN AHSDA;Mn;0;NSM;;;;;N;;;;;
5038 17D0;KHMER SIGN SAMYOK SANNYA;Mn;0;NSM;;;;;N;;;;;
5039 17D1;KHMER SIGN VIRIAM;Mn;0;NSM;;;;;N;;;;;
5040 17D2;KHMER SIGN COENG;Mn;9;NSM;;;;;N;;;;;
5041 17D3;KHMER SIGN BATHAMASAT;Mn;0;NSM;;;;;N;;*;;;
5042 17D4;KHMER SIGN KHAN;Po;0;L;;;;;N;;;;;
5043 17D5;KHMER SIGN BARIYOOSAN;Po;0;L;;;;;N;;;;;
5044 17D6;KHMER SIGN CAMNUC PII KUUH;Po;0;L;;;;;N;;;;;
5045 17D7;KHMER SIGN LEK TOO;Lm;0;L;;;;;N;;;;;
5046 17D8;KHMER SIGN BEYYAL;Po;0;L;;;;;N;;*;;;
5047 17D9;KHMER SIGN PHNAEK MUAN;Po;0;L;;;;;N;;;;;
5048 17DA;KHMER SIGN KOOMUUT;Po;0;L;;;;;N;;;;;
5049 17DB;KHMER CURRENCY SYMBOL RIEL;Sc;0;ET;;;;;N;;;;;
5050 17DC;KHMER SIGN AVAKRAHASANYA;Lo;0;L;;;;;N;;;;;
5051 17DD;KHMER SIGN ATTHACAN;Mn;230;NSM;;;;;N;;;;;
5052 17E0;KHMER DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
5053 17E1;KHMER DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
5054 17E2;KHMER DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
5055 17E3;KHMER DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
5056 17E4;KHMER DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
5057 17E5;KHMER DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
5058 17E6;KHMER DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
5059 17E7;KHMER DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
5060 17E8;KHMER DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
5061 17E9;KHMER DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
5062 17F0;KHMER SYMBOL LEK ATTAK SON;No;0;ON;;;;0;N;;;;;
5063 17F1;KHMER SYMBOL LEK ATTAK MUOY;No;0;ON;;;;1;N;;;;;
5064 17F2;KHMER SYMBOL LEK ATTAK PII;No;0;ON;;;;2;N;;;;;
5065 17F3;KHMER SYMBOL LEK ATTAK BEI;No;0;ON;;;;3;N;;;;;
5066 17F4;KHMER SYMBOL LEK ATTAK BUON;No;0;ON;;;;4;N;;;;;
5067 17F5;KHMER SYMBOL LEK ATTAK PRAM;No;0;ON;;;;5;N;;;;;
5068 17F6;KHMER SYMBOL LEK ATTAK PRAM-MUOY;No;0;ON;;;;6;N;;;;;
5069 17F7;KHMER SYMBOL LEK ATTAK PRAM-PII;No;0;ON;;;;7;N;;;;;
5070 17F8;KHMER SYMBOL LEK ATTAK PRAM-BEI;No;0;ON;;;;8;N;;;;;
5071 17F9;KHMER SYMBOL LEK ATTAK PRAM-BUON;No;0;ON;;;;9;N;;;;;
5072 1800;MONGOLIAN BIRGA;Po;0;ON;;;;;N;;;;;
5073 1801;MONGOLIAN ELLIPSIS;Po;0;ON;;;;;N;;;;;
5074 1802;MONGOLIAN COMMA;Po;0;ON;;;;;N;;;;;
5075 1803;MONGOLIAN FULL STOP;Po;0;ON;;;;;N;;;;;
5076 1804;MONGOLIAN COLON;Po;0;ON;;;;;N;;;;;
5077 1805;MONGOLIAN FOUR DOTS;Po;0;ON;;;;;N;;;;;
5078 1806;MONGOLIAN TODO SOFT HYPHEN;Pd;0;ON;;;;;N;;;;;
5079 1807;MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER;Po;0;ON;;;;;N;;;;;
5080 1808;MONGOLIAN MANCHU COMMA;Po;0;ON;;;;;N;;;;;
5081 1809;MONGOLIAN MANCHU FULL STOP;Po;0;ON;;;;;N;;;;;
5082 180A;MONGOLIAN NIRUGU;Po;0;ON;;;;;N;;;;;
5083 180B;MONGOLIAN FREE VARIATION SELECTOR ONE;Mn;0;NSM;;;;;N;;;;;
5084 180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Mn;0;NSM;;;;;N;;;;;
5085 180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Mn;0;NSM;;;;;N;;;;;
5086 180E;MONGOLIAN VOWEL SEPARATOR;Zs;0;WS;;;;;N;;;;;
5087 1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
5088 1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
5089 1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
5090 1813;MONGOLIAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
5091 1814;MONGOLIAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
5092 1815;MONGOLIAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
5093 1816;MONGOLIAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
5094 1817;MONGOLIAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
5095 1818;MONGOLIAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
5096 1819;MONGOLIAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
5097 1820;MONGOLIAN LETTER A;Lo;0;L;;;;;N;;;;;
5098 1821;MONGOLIAN LETTER E;Lo;0;L;;;;;N;;;;;
5099 1822;MONGOLIAN LETTER I;Lo;0;L;;;;;N;;;;;
5100 1823;MONGOLIAN LETTER O;Lo;0;L;;;;;N;;;;;
5101 1824;MONGOLIAN LETTER U;Lo;0;L;;;;;N;;;;;
5102 1825;MONGOLIAN LETTER OE;Lo;0;L;;;;;N;;;;;
5103 1826;MONGOLIAN LETTER UE;Lo;0;L;;;;;N;;;;;
5104 1827;MONGOLIAN LETTER EE;Lo;0;L;;;;;N;;;;;
5105 1828;MONGOLIAN LETTER NA;Lo;0;L;;;;;N;;;;;
5106 1829;MONGOLIAN LETTER ANG;Lo;0;L;;;;;N;;;;;
5107 182A;MONGOLIAN LETTER BA;Lo;0;L;;;;;N;;;;;
5108 182B;MONGOLIAN LETTER PA;Lo;0;L;;;;;N;;;;;
5109 182C;MONGOLIAN LETTER QA;Lo;0;L;;;;;N;;;;;
5110 182D;MONGOLIAN LETTER GA;Lo;0;L;;;;;N;;;;;
5111 182E;MONGOLIAN LETTER MA;Lo;0;L;;;;;N;;;;;
5112 182F;MONGOLIAN LETTER LA;Lo;0;L;;;;;N;;;;;
5113 1830;MONGOLIAN LETTER SA;Lo;0;L;;;;;N;;;;;
5114 1831;MONGOLIAN LETTER SHA;Lo;0;L;;;;;N;;;;;
5115 1832;MONGOLIAN LETTER TA;Lo;0;L;;;;;N;;;;;
5116 1833;MONGOLIAN LETTER DA;Lo;0;L;;;;;N;;;;;
5117 1834;MONGOLIAN LETTER CHA;Lo;0;L;;;;;N;;;;;
5118 1835;MONGOLIAN LETTER JA;Lo;0;L;;;;;N;;;;;
5119 1836;MONGOLIAN LETTER YA;Lo;0;L;;;;;N;;;;;
5120 1837;MONGOLIAN LETTER RA;Lo;0;L;;;;;N;;;;;
5121 1838;MONGOLIAN LETTER WA;Lo;0;L;;;;;N;;;;;
5122 1839;MONGOLIAN LETTER FA;Lo;0;L;;;;;N;;;;;
5123 183A;MONGOLIAN LETTER KA;Lo;0;L;;;;;N;;;;;
5124 183B;MONGOLIAN LETTER KHA;Lo;0;L;;;;;N;;;;;
5125 183C;MONGOLIAN LETTER TSA;Lo;0;L;;;;;N;;;;;
5126 183D;MONGOLIAN LETTER ZA;Lo;0;L;;;;;N;;;;;
5127 183E;MONGOLIAN LETTER HAA;Lo;0;L;;;;;N;;;;;
5128 183F;MONGOLIAN LETTER ZRA;Lo;0;L;;;;;N;;;;;
5129 1840;MONGOLIAN LETTER LHA;Lo;0;L;;;;;N;;;;;
5130 1841;MONGOLIAN LETTER ZHI;Lo;0;L;;;;;N;;;;;
5131 1842;MONGOLIAN LETTER CHI;Lo;0;L;;;;;N;;;;;
5132 1843;MONGOLIAN LETTER TODO LONG VOWEL SIGN;Lm;0;L;;;;;N;;;;;
5133 1844;MONGOLIAN LETTER TODO E;Lo;0;L;;;;;N;;;;;
5134 1845;MONGOLIAN LETTER TODO I;Lo;0;L;;;;;N;;;;;
5135 1846;MONGOLIAN LETTER TODO O;Lo;0;L;;;;;N;;;;;
5136 1847;MONGOLIAN LETTER TODO U;Lo;0;L;;;;;N;;;;;
5137 1848;MONGOLIAN LETTER TODO OE;Lo;0;L;;;;;N;;;;;
5138 1849;MONGOLIAN LETTER TODO UE;Lo;0;L;;;;;N;;;;;
5139 184A;MONGOLIAN LETTER TODO ANG;Lo;0;L;;;;;N;;;;;
5140 184B;MONGOLIAN LETTER TODO BA;Lo;0;L;;;;;N;;;;;
5141 184C;MONGOLIAN LETTER TODO PA;Lo;0;L;;;;;N;;;;;
5142 184D;MONGOLIAN LETTER TODO QA;Lo;0;L;;;;;N;;;;;
5143 184E;MONGOLIAN LETTER TODO GA;Lo;0;L;;;;;N;;;;;
5144 184F;MONGOLIAN LETTER TODO MA;Lo;0;L;;;;;N;;;;;
5145 1850;MONGOLIAN LETTER TODO TA;Lo;0;L;;;;;N;;;;;
5146 1851;MONGOLIAN LETTER TODO DA;Lo;0;L;;;;;N;;;;;
5147 1852;MONGOLIAN LETTER TODO CHA;Lo;0;L;;;;;N;;;;;
5148 1853;MONGOLIAN LETTER TODO JA;Lo;0;L;;;;;N;;;;;
5149 1854;MONGOLIAN LETTER TODO TSA;Lo;0;L;;;;;N;;;;;
5150 1855;MONGOLIAN LETTER TODO YA;Lo;0;L;;;;;N;;;;;
5151 1856;MONGOLIAN LETTER TODO WA;Lo;0;L;;;;;N;;;;;
5152 1857;MONGOLIAN LETTER TODO KA;Lo;0;L;;;;;N;;;;;
5153 1858;MONGOLIAN LETTER TODO GAA;Lo;0;L;;;;;N;;;;;
5154 1859;MONGOLIAN LETTER TODO HAA;Lo;0;L;;;;;N;;;;;
5155 185A;MONGOLIAN LETTER TODO JIA;Lo;0;L;;;;;N;;;;;
5156 185B;MONGOLIAN LETTER TODO NIA;Lo;0;L;;;;;N;;;;;
5157 185C;MONGOLIAN LETTER TODO DZA;Lo;0;L;;;;;N;;;;;
5158 185D;MONGOLIAN LETTER SIBE E;Lo;0;L;;;;;N;;;;;
5159 185E;MONGOLIAN LETTER SIBE I;Lo;0;L;;;;;N;;;;;
5160 185F;MONGOLIAN LETTER SIBE IY;Lo;0;L;;;;;N;;;;;
5161 1860;MONGOLIAN LETTER SIBE UE;Lo;0;L;;;;;N;;;;;
5162 1861;MONGOLIAN LETTER SIBE U;Lo;0;L;;;;;N;;;;;
5163 1862;MONGOLIAN LETTER SIBE ANG;Lo;0;L;;;;;N;;;;;
5164 1863;MONGOLIAN LETTER SIBE KA;Lo;0;L;;;;;N;;;;;
5165 1864;MONGOLIAN LETTER SIBE GA;Lo;0;L;;;;;N;;;;;
5166 1865;MONGOLIAN LETTER SIBE HA;Lo;0;L;;;;;N;;;;;
5167 1866;MONGOLIAN LETTER SIBE PA;Lo;0;L;;;;;N;;;;;
5168 1867;MONGOLIAN LETTER SIBE SHA;Lo;0;L;;;;;N;;;;;
5169 1868;MONGOLIAN LETTER SIBE TA;Lo;0;L;;;;;N;;;;;
5170 1869;MONGOLIAN LETTER SIBE DA;Lo;0;L;;;;;N;;;;;
5171 186A;MONGOLIAN LETTER SIBE JA;Lo;0;L;;;;;N;;;;;
5172 186B;MONGOLIAN LETTER SIBE FA;Lo;0;L;;;;;N;;;;;
5173 186C;MONGOLIAN LETTER SIBE GAA;Lo;0;L;;;;;N;;;;;
5174 186D;MONGOLIAN LETTER SIBE HAA;Lo;0;L;;;;;N;;;;;
5175 186E;MONGOLIAN LETTER SIBE TSA;Lo;0;L;;;;;N;;;;;
5176 186F;MONGOLIAN LETTER SIBE ZA;Lo;0;L;;;;;N;;;;;
5177 1870;MONGOLIAN LETTER SIBE RAA;Lo;0;L;;;;;N;;;;;
5178 1871;MONGOLIAN LETTER SIBE CHA;Lo;0;L;;;;;N;;;;;
5179 1872;MONGOLIAN LETTER SIBE ZHA;Lo;0;L;;;;;N;;;;;
5180 1873;MONGOLIAN LETTER MANCHU I;Lo;0;L;;;;;N;;;;;
5181 1874;MONGOLIAN LETTER MANCHU KA;Lo;0;L;;;;;N;;;;;
5182 1875;MONGOLIAN LETTER MANCHU RA;Lo;0;L;;;;;N;;;;;
5183 1876;MONGOLIAN LETTER MANCHU FA;Lo;0;L;;;;;N;;;;;
5184 1877;MONGOLIAN LETTER MANCHU ZHA;Lo;0;L;;;;;N;;;;;
5185 1880;MONGOLIAN LETTER ALI GALI ANUSVARA ONE;Lo;0;L;;;;;N;;;;;
5186 1881;MONGOLIAN LETTER ALI GALI VISARGA ONE;Lo;0;L;;;;;N;;;;;
5187 1882;MONGOLIAN LETTER ALI GALI DAMARU;Lo;0;L;;;;;N;;;;;
5188 1883;MONGOLIAN LETTER ALI GALI UBADAMA;Lo;0;L;;;;;N;;;;;
5189 1884;MONGOLIAN LETTER ALI GALI INVERTED UBADAMA;Lo;0;L;;;;;N;;;;;
5190 1885;MONGOLIAN LETTER ALI GALI BALUDA;Lo;0;L;;;;;N;;;;;
5191 1886;MONGOLIAN LETTER ALI GALI THREE BALUDA;Lo;0;L;;;;;N;;;;;
5192 1887;MONGOLIAN LETTER ALI GALI A;Lo;0;L;;;;;N;;;;;
5193 1888;MONGOLIAN LETTER ALI GALI I;Lo;0;L;;;;;N;;;;;
5194 1889;MONGOLIAN LETTER ALI GALI KA;Lo;0;L;;;;;N;;;;;
5195 188A;MONGOLIAN LETTER ALI GALI NGA;Lo;0;L;;;;;N;;;;;
5196 188B;MONGOLIAN LETTER ALI GALI CA;Lo;0;L;;;;;N;;;;;
5197 188C;MONGOLIAN LETTER ALI GALI TTA;Lo;0;L;;;;;N;;;;;
5198 188D;MONGOLIAN LETTER ALI GALI TTHA;Lo;0;L;;;;;N;;;;;
5199 188E;MONGOLIAN LETTER ALI GALI DDA;Lo;0;L;;;;;N;;;;;
5200 188F;MONGOLIAN LETTER ALI GALI NNA;Lo;0;L;;;;;N;;;;;
5201 1890;MONGOLIAN LETTER ALI GALI TA;Lo;0;L;;;;;N;;;;;
5202 1891;MONGOLIAN LETTER ALI GALI DA;Lo;0;L;;;;;N;;;;;
5203 1892;MONGOLIAN LETTER ALI GALI PA;Lo;0;L;;;;;N;;;;;
5204 1893;MONGOLIAN LETTER ALI GALI PHA;Lo;0;L;;;;;N;;;;;
5205 1894;MONGOLIAN LETTER ALI GALI SSA;Lo;0;L;;;;;N;;;;;
5206 1895;MONGOLIAN LETTER ALI GALI ZHA;Lo;0;L;;;;;N;;;;;
5207 1896;MONGOLIAN LETTER ALI GALI ZA;Lo;0;L;;;;;N;;;;;
5208 1897;MONGOLIAN LETTER ALI GALI AH;Lo;0;L;;;;;N;;;;;
5209 1898;MONGOLIAN LETTER TODO ALI GALI TA;Lo;0;L;;;;;N;;;;;
5210 1899;MONGOLIAN LETTER TODO ALI GALI ZHA;Lo;0;L;;;;;N;;;;;
5211 189A;MONGOLIAN LETTER MANCHU ALI GALI GHA;Lo;0;L;;;;;N;;;;;
5212 189B;MONGOLIAN LETTER MANCHU ALI GALI NGA;Lo;0;L;;;;;N;;;;;
5213 189C;MONGOLIAN LETTER MANCHU ALI GALI CA;Lo;0;L;;;;;N;;;;;
5214 189D;MONGOLIAN LETTER MANCHU ALI GALI JHA;Lo;0;L;;;;;N;;;;;
5215 189E;MONGOLIAN LETTER MANCHU ALI GALI TTA;Lo;0;L;;;;;N;;;;;
5216 189F;MONGOLIAN LETTER MANCHU ALI GALI DDHA;Lo;0;L;;;;;N;;;;;
5217 18A0;MONGOLIAN LETTER MANCHU ALI GALI TA;Lo;0;L;;;;;N;;;;;
5218 18A1;MONGOLIAN LETTER MANCHU ALI GALI DHA;Lo;0;L;;;;;N;;;;;
5219 18A2;MONGOLIAN LETTER MANCHU ALI GALI SSA;Lo;0;L;;;;;N;;;;;
5220 18A3;MONGOLIAN LETTER MANCHU ALI GALI CYA;Lo;0;L;;;;;N;;;;;
5221 18A4;MONGOLIAN LETTER MANCHU ALI GALI ZHA;Lo;0;L;;;;;N;;;;;
5222 18A5;MONGOLIAN LETTER MANCHU ALI GALI ZA;Lo;0;L;;;;;N;;;;;
5223 18A6;MONGOLIAN LETTER ALI GALI HALF U;Lo;0;L;;;;;N;;;;;
5224 18A7;MONGOLIAN LETTER ALI GALI HALF YA;Lo;0;L;;;;;N;;;;;
5225 18A8;MONGOLIAN LETTER MANCHU ALI GALI BHA;Lo;0;L;;;;;N;;;;;
5226 18A9;MONGOLIAN LETTER ALI GALI DAGALGA;Mn;228;NSM;;;;;N;;;;;
5227 18AA;MONGOLIAN LETTER MANCHU ALI GALI LHA;Lo;0;L;;;;;N;;;;;
5228 1900;LIMBU VOWEL-CARRIER LETTER;Lo;0;L;;;;;N;;;;;
5229 1901;LIMBU LETTER KA;Lo;0;L;;;;;N;;;;;
5230 1902;LIMBU LETTER KHA;Lo;0;L;;;;;N;;;;;
5231 1903;LIMBU LETTER GA;Lo;0;L;;;;;N;;;;;
5232 1904;LIMBU LETTER GHA;Lo;0;L;;;;;N;;;;;
5233 1905;LIMBU LETTER NGA;Lo;0;L;;;;;N;;;;;
5234 1906;LIMBU LETTER CA;Lo;0;L;;;;;N;;;;;
5235 1907;LIMBU LETTER CHA;Lo;0;L;;;;;N;;;;;
5236 1908;LIMBU LETTER JA;Lo;0;L;;;;;N;;;;;
5237 1909;LIMBU LETTER JHA;Lo;0;L;;;;;N;;;;;
5238 190A;LIMBU LETTER YAN;Lo;0;L;;;;;N;;;;;
5239 190B;LIMBU LETTER TA;Lo;0;L;;;;;N;;;;;
5240 190C;LIMBU LETTER THA;Lo;0;L;;;;;N;;;;;
5241 190D;LIMBU LETTER DA;Lo;0;L;;;;;N;;;;;
5242 190E;LIMBU LETTER DHA;Lo;0;L;;;;;N;;;;;
5243 190F;LIMBU LETTER NA;Lo;0;L;;;;;N;;;;;
5244 1910;LIMBU LETTER PA;Lo;0;L;;;;;N;;;;;
5245 1911;LIMBU LETTER PHA;Lo;0;L;;;;;N;;;;;
5246 1912;LIMBU LETTER BA;Lo;0;L;;;;;N;;;;;
5247 1913;LIMBU LETTER BHA;Lo;0;L;;;;;N;;;;;
5248 1914;LIMBU LETTER MA;Lo;0;L;;;;;N;;;;;
5249 1915;LIMBU LETTER YA;Lo;0;L;;;;;N;;;;;
5250 1916;LIMBU LETTER RA;Lo;0;L;;;;;N;;;;;
5251 1917;LIMBU LETTER LA;Lo;0;L;;;;;N;;;;;
5252 1918;LIMBU LETTER WA;Lo;0;L;;;;;N;;;;;
5253 1919;LIMBU LETTER SHA;Lo;0;L;;;;;N;;;;;
5254 191A;LIMBU LETTER SSA;Lo;0;L;;;;;N;;;;;
5255 191B;LIMBU LETTER SA;Lo;0;L;;;;;N;;;;;
5256 191C;LIMBU LETTER HA;Lo;0;L;;;;;N;;;;;
5257 1920;LIMBU VOWEL SIGN A;Mn;0;NSM;;;;;N;;;;;
5258 1921;LIMBU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
5259 1922;LIMBU VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
5260 1923;LIMBU VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
5261 1924;LIMBU VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
5262 1925;LIMBU VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
5263 1926;LIMBU VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
5264 1927;LIMBU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
5265 1928;LIMBU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
5266 1929;LIMBU SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;;
5267 192A;LIMBU SUBJOINED LETTER RA;Mc;0;L;;;;;N;;;;;
5268 192B;LIMBU SUBJOINED LETTER WA;Mc;0;L;;;;;N;;;;;
5269 1930;LIMBU SMALL LETTER KA;Mc;0;L;;;;;N;;;;;
5270 1931;LIMBU SMALL LETTER NGA;Mc;0;L;;;;;N;;;;;
5271 1932;LIMBU SMALL LETTER ANUSVARA;Mn;0;NSM;;;;;N;;;;;
5272 1933;LIMBU SMALL LETTER TA;Mc;0;L;;;;;N;;;;;
5273 1934;LIMBU SMALL LETTER NA;Mc;0;L;;;;;N;;;;;
5274 1935;LIMBU SMALL LETTER PA;Mc;0;L;;;;;N;;;;;
5275 1936;LIMBU SMALL LETTER MA;Mc;0;L;;;;;N;;;;;
5276 1937;LIMBU SMALL LETTER RA;Mc;0;L;;;;;N;;;;;
5277 1938;LIMBU SMALL LETTER LA;Mc;0;L;;;;;N;;;;;
5278 1939;LIMBU SIGN MUKPHRENG;Mn;222;NSM;;;;;N;;;;;
5279 193A;LIMBU SIGN KEMPHRENG;Mn;230;NSM;;;;;N;;;;;
5280 193B;LIMBU SIGN SA-I;Mn;220;NSM;;;;;N;;;;;
5281 1940;LIMBU SIGN LOO;So;0;ON;;;;;N;;;;;
5282 1944;LIMBU EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;
5283 1945;LIMBU QUESTION MARK;Po;0;ON;;;;;N;;;;;
5284 1946;LIMBU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
5285 1947;LIMBU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
5286 1948;LIMBU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
5287 1949;LIMBU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
5288 194A;LIMBU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
5289 194B;LIMBU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
5290 194C;LIMBU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
5291 194D;LIMBU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
5292 194E;LIMBU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
5293 194F;LIMBU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
5294 1950;TAI LE LETTER KA;Lo;0;L;;;;;N;;;;;
5295 1951;TAI LE LETTER XA;Lo;0;L;;;;;N;;;;;
5296 1952;TAI LE LETTER NGA;Lo;0;L;;;;;N;;;;;
5297 1953;TAI LE LETTER TSA;Lo;0;L;;;;;N;;;;;
5298 1954;TAI LE LETTER SA;Lo;0;L;;;;;N;;;;;
5299 1955;TAI LE LETTER YA;Lo;0;L;;;;;N;;;;;
5300 1956;TAI LE LETTER TA;Lo;0;L;;;;;N;;;;;
5301 1957;TAI LE LETTER THA;Lo;0;L;;;;;N;;;;;
5302 1958;TAI LE LETTER LA;Lo;0;L;;;;;N;;;;;
5303 1959;TAI LE LETTER PA;Lo;0;L;;;;;N;;;;;
5304 195A;TAI LE LETTER PHA;Lo;0;L;;;;;N;;;;;
5305 195B;TAI LE LETTER MA;Lo;0;L;;;;;N;;;;;
5306 195C;TAI LE LETTER FA;Lo;0;L;;;;;N;;;;;
5307 195D;TAI LE LETTER VA;Lo;0;L;;;;;N;;;;;
5308 195E;TAI LE LETTER HA;Lo;0;L;;;;;N;;;;;
5309 195F;TAI LE LETTER QA;Lo;0;L;;;;;N;;;;;
5310 1960;TAI LE LETTER KHA;Lo;0;L;;;;;N;;;;;
5311 1961;TAI LE LETTER TSHA;Lo;0;L;;;;;N;;;;;
5312 1962;TAI LE LETTER NA;Lo;0;L;;;;;N;;;;;
5313 1963;TAI LE LETTER A;Lo;0;L;;;;;N;;;;;
5314 1964;TAI LE LETTER I;Lo;0;L;;;;;N;;;;;
5315 1965;TAI LE LETTER EE;Lo;0;L;;;;;N;;;;;
5316 1966;TAI LE LETTER EH;Lo;0;L;;;;;N;;;;;
5317 1967;TAI LE LETTER U;Lo;0;L;;;;;N;;;;;
5318 1968;TAI LE LETTER OO;Lo;0;L;;;;;N;;;;;
5319 1969;TAI LE LETTER O;Lo;0;L;;;;;N;;;;;
5320 196A;TAI LE LETTER UE;Lo;0;L;;;;;N;;;;;
5321 196B;TAI LE LETTER E;Lo;0;L;;;;;N;;;;;
5322 196C;TAI LE LETTER AUE;Lo;0;L;;;;;N;;;;;
5323 196D;TAI LE LETTER AI;Lo;0;L;;;;;N;;;;;
5324 1970;TAI LE LETTER TONE-2;Lo;0;L;;;;;N;;;;;
5325 1971;TAI LE LETTER TONE-3;Lo;0;L;;;;;N;;;;;
5326 1972;TAI LE LETTER TONE-4;Lo;0;L;;;;;N;;;;;
5327 1973;TAI LE LETTER TONE-5;Lo;0;L;;;;;N;;;;;
5328 1974;TAI LE LETTER TONE-6;Lo;0;L;;;;;N;;;;;
5329 1980;NEW TAI LUE LETTER HIGH QA;Lo;0;L;;;;;N;;;;;
5330 1981;NEW TAI LUE LETTER LOW QA;Lo;0;L;;;;;N;;;;;
5331 1982;NEW TAI LUE LETTER HIGH KA;Lo;0;L;;;;;N;;;;;
5332 1983;NEW TAI LUE LETTER HIGH XA;Lo;0;L;;;;;N;;;;;
5333 1984;NEW TAI LUE LETTER HIGH NGA;Lo;0;L;;;;;N;;;;;
5334 1985;NEW TAI LUE LETTER LOW KA;Lo;0;L;;;;;N;;;;;
5335 1986;NEW TAI LUE LETTER LOW XA;Lo;0;L;;;;;N;;;;;
5336 1987;NEW TAI LUE LETTER LOW NGA;Lo;0;L;;;;;N;;;;;
5337 1988;NEW TAI LUE LETTER HIGH TSA;Lo;0;L;;;;;N;;;;;
5338 1989;NEW TAI LUE LETTER HIGH SA;Lo;0;L;;;;;N;;;;;
5339 198A;NEW TAI LUE LETTER HIGH YA;Lo;0;L;;;;;N;;;;;
5340 198B;NEW TAI LUE LETTER LOW TSA;Lo;0;L;;;;;N;;;;;
5341 198C;NEW TAI LUE LETTER LOW SA;Lo;0;L;;;;;N;;;;;
5342 198D;NEW TAI LUE LETTER LOW YA;Lo;0;L;;;;;N;;;;;
5343 198E;NEW TAI LUE LETTER HIGH TA;Lo;0;L;;;;;N;;;;;
5344 198F;NEW TAI LUE LETTER HIGH THA;Lo;0;L;;;;;N;;;;;
5345 1990;NEW TAI LUE LETTER HIGH NA;Lo;0;L;;;;;N;;;;;
5346 1991;NEW TAI LUE LETTER LOW TA;Lo;0;L;;;;;N;;;;;
5347 1992;NEW TAI LUE LETTER LOW THA;Lo;0;L;;;;;N;;;;;
5348 1993;NEW TAI LUE LETTER LOW NA;Lo;0;L;;;;;N;;;;;
5349 1994;NEW TAI LUE LETTER HIGH PA;Lo;0;L;;;;;N;;;;;
5350 1995;NEW TAI LUE LETTER HIGH PHA;Lo;0;L;;;;;N;;;;;
5351 1996;NEW TAI LUE LETTER HIGH MA;Lo;0;L;;;;;N;;;;;
5352 1997;NEW TAI LUE LETTER LOW PA;Lo;0;L;;;;;N;;;;;
5353 1998;NEW TAI LUE LETTER LOW PHA;Lo;0;L;;;;;N;;;;;
5354 1999;NEW TAI LUE LETTER LOW MA;Lo;0;L;;;;;N;;;;;
5355 199A;NEW TAI LUE LETTER HIGH FA;Lo;0;L;;;;;N;;;;;
5356 199B;NEW TAI LUE LETTER HIGH VA;Lo;0;L;;;;;N;;;;;
5357 199C;NEW TAI LUE LETTER HIGH LA;Lo;0;L;;;;;N;;;;;
5358 199D;NEW TAI LUE LETTER LOW FA;Lo;0;L;;;;;N;;;;;
5359 199E;NEW TAI LUE LETTER LOW VA;Lo;0;L;;;;;N;;;;;
5360 199F;NEW TAI LUE LETTER LOW LA;Lo;0;L;;;;;N;;;;;
5361 19A0;NEW TAI LUE LETTER HIGH HA;Lo;0;L;;;;;N;;;;;
5362 19A1;NEW TAI LUE LETTER HIGH DA;Lo;0;L;;;;;N;;;;;
5363 19A2;NEW TAI LUE LETTER HIGH BA;Lo;0;L;;;;;N;;;;;
5364 19A3;NEW TAI LUE LETTER LOW HA;Lo;0;L;;;;;N;;;;;
5365 19A4;NEW TAI LUE LETTER LOW DA;Lo;0;L;;;;;N;;;;;
5366 19A5;NEW TAI LUE LETTER LOW BA;Lo;0;L;;;;;N;;;;;
5367 19A6;NEW TAI LUE LETTER HIGH KVA;Lo;0;L;;;;;N;;;;;
5368 19A7;NEW TAI LUE LETTER HIGH XVA;Lo;0;L;;;;;N;;;;;
5369 19A8;NEW TAI LUE LETTER LOW KVA;Lo;0;L;;;;;N;;;;;
5370 19A9;NEW TAI LUE LETTER LOW XVA;Lo;0;L;;;;;N;;;;;
5371 19B0;NEW TAI LUE VOWEL SIGN VOWEL SHORTENER;Mc;0;L;;;;;N;;;;;
5372 19B1;NEW TAI LUE VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
5373 19B2;NEW TAI LUE VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
5374 19B3;NEW TAI LUE VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
5375 19B4;NEW TAI LUE VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
5376 19B5;NEW TAI LUE VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
5377 19B6;NEW TAI LUE VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
5378 19B7;NEW TAI LUE VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
5379 19B8;NEW TAI LUE VOWEL SIGN OA;Mc;0;L;;;;;N;;;;;
5380 19B9;NEW TAI LUE VOWEL SIGN UE;Mc;0;L;;;;;N;;;;;
5381 19BA;NEW TAI LUE VOWEL SIGN AY;Mc;0;L;;;;;N;;;;;
5382 19BB;NEW TAI LUE VOWEL SIGN AAY;Mc;0;L;;;;;N;;;;;
5383 19BC;NEW TAI LUE VOWEL SIGN UY;Mc;0;L;;;;;N;;;;;
5384 19BD;NEW TAI LUE VOWEL SIGN OY;Mc;0;L;;;;;N;;;;;
5385 19BE;NEW TAI LUE VOWEL SIGN OAY;Mc;0;L;;;;;N;;;;;
5386 19BF;NEW TAI LUE VOWEL SIGN UEY;Mc;0;L;;;;;N;;;;;
5387 19C0;NEW TAI LUE VOWEL SIGN IY;Mc;0;L;;;;;N;;;;;
5388 19C1;NEW TAI LUE LETTER FINAL V;Lo;0;L;;;;;N;;;;;
5389 19C2;NEW TAI LUE LETTER FINAL NG;Lo;0;L;;;;;N;;;;;
5390 19C3;NEW TAI LUE LETTER FINAL N;Lo;0;L;;;;;N;;;;;
5391 19C4;NEW TAI LUE LETTER FINAL M;Lo;0;L;;;;;N;;;;;
5392 19C5;NEW TAI LUE LETTER FINAL K;Lo;0;L;;;;;N;;;;;
5393 19C6;NEW TAI LUE LETTER FINAL D;Lo;0;L;;;;;N;;;;;
5394 19C7;NEW TAI LUE LETTER FINAL B;Lo;0;L;;;;;N;;;;;
5395 19C8;NEW TAI LUE TONE MARK-1;Mc;0;L;;;;;N;;;;;
5396 19C9;NEW TAI LUE TONE MARK-2;Mc;0;L;;;;;N;;;;;
5397 19D0;NEW TAI LUE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
5398 19D1;NEW TAI LUE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
5399 19D2;NEW TAI LUE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
5400 19D3;NEW TAI LUE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
5401 19D4;NEW TAI LUE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
5402 19D5;NEW TAI LUE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
5403 19D6;NEW TAI LUE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
5404 19D7;NEW TAI LUE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
5405 19D8;NEW TAI LUE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
5406 19D9;NEW TAI LUE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
5407 19DE;NEW TAI LUE SIGN LAE;Po;0;ON;;;;;N;;;;;
5408 19DF;NEW TAI LUE SIGN LAEV;Po;0;ON;;;;;N;;;;;
5409 19E0;KHMER SYMBOL PATHAMASAT;So;0;ON;;;;;N;;;;;
5410 19E1;KHMER SYMBOL MUOY KOET;So;0;ON;;;;;N;;;;;
5411 19E2;KHMER SYMBOL PII KOET;So;0;ON;;;;;N;;;;;
5412 19E3;KHMER SYMBOL BEI KOET;So;0;ON;;;;;N;;;;;
5413 19E4;KHMER SYMBOL BUON KOET;So;0;ON;;;;;N;;;;;
5414 19E5;KHMER SYMBOL PRAM KOET;So;0;ON;;;;;N;;;;;
5415 19E6;KHMER SYMBOL PRAM-MUOY KOET;So;0;ON;;;;;N;;;;;
5416 19E7;KHMER SYMBOL PRAM-PII KOET;So;0;ON;;;;;N;;;;;
5417 19E8;KHMER SYMBOL PRAM-BEI KOET;So;0;ON;;;;;N;;;;;
5418 19E9;KHMER SYMBOL PRAM-BUON KOET;So;0;ON;;;;;N;;;;;
5419 19EA;KHMER SYMBOL DAP KOET;So;0;ON;;;;;N;;;;;
5420 19EB;KHMER SYMBOL DAP-MUOY KOET;So;0;ON;;;;;N;;;;;
5421 19EC;KHMER SYMBOL DAP-PII KOET;So;0;ON;;;;;N;;;;;
5422 19ED;KHMER SYMBOL DAP-BEI KOET;So;0;ON;;;;;N;;;;;
5423 19EE;KHMER SYMBOL DAP-BUON KOET;So;0;ON;;;;;N;;;;;
5424 19EF;KHMER SYMBOL DAP-PRAM KOET;So;0;ON;;;;;N;;;;;
5425 19F0;KHMER SYMBOL TUTEYASAT;So;0;ON;;;;;N;;;;;
5426 19F1;KHMER SYMBOL MUOY ROC;So;0;ON;;;;;N;;;;;
5427 19F2;KHMER SYMBOL PII ROC;So;0;ON;;;;;N;;;;;
5428 19F3;KHMER SYMBOL BEI ROC;So;0;ON;;;;;N;;;;;
5429 19F4;KHMER SYMBOL BUON ROC;So;0;ON;;;;;N;;;;;
5430 19F5;KHMER SYMBOL PRAM ROC;So;0;ON;;;;;N;;;;;
5431 19F6;KHMER SYMBOL PRAM-MUOY ROC;So;0;ON;;;;;N;;;;;
5432 19F7;KHMER SYMBOL PRAM-PII ROC;So;0;ON;;;;;N;;;;;
5433 19F8;KHMER SYMBOL PRAM-BEI ROC;So;0;ON;;;;;N;;;;;
5434 19F9;KHMER SYMBOL PRAM-BUON ROC;So;0;ON;;;;;N;;;;;
5435 19FA;KHMER SYMBOL DAP ROC;So;0;ON;;;;;N;;;;;
5436 19FB;KHMER SYMBOL DAP-MUOY ROC;So;0;ON;;;;;N;;;;;
5437 19FC;KHMER SYMBOL DAP-PII ROC;So;0;ON;;;;;N;;;;;
5438 19FD;KHMER SYMBOL DAP-BEI ROC;So;0;ON;;;;;N;;;;;
5439 19FE;KHMER SYMBOL DAP-BUON ROC;So;0;ON;;;;;N;;;;;
5440 19FF;KHMER SYMBOL DAP-PRAM ROC;So;0;ON;;;;;N;;;;;
5441 1A00;BUGINESE LETTER KA;Lo;0;L;;;;;N;;;;;
5442 1A01;BUGINESE LETTER GA;Lo;0;L;;;;;N;;;;;
5443 1A02;BUGINESE LETTER NGA;Lo;0;L;;;;;N;;;;;
5444 1A03;BUGINESE LETTER NGKA;Lo;0;L;;;;;N;;;;;
5445 1A04;BUGINESE LETTER PA;Lo;0;L;;;;;N;;;;;
5446 1A05;BUGINESE LETTER BA;Lo;0;L;;;;;N;;;;;
5447 1A06;BUGINESE LETTER MA;Lo;0;L;;;;;N;;;;;
5448 1A07;BUGINESE LETTER MPA;Lo;0;L;;;;;N;;;;;
5449 1A08;BUGINESE LETTER TA;Lo;0;L;;;;;N;;;;;
5450 1A09;BUGINESE LETTER DA;Lo;0;L;;;;;N;;;;;
5451 1A0A;BUGINESE LETTER NA;Lo;0;L;;;;;N;;;;;
5452 1A0B;BUGINESE LETTER NRA;Lo;0;L;;;;;N;;;;;
5453 1A0C;BUGINESE LETTER CA;Lo;0;L;;;;;N;;;;;
5454 1A0D;BUGINESE LETTER JA;Lo;0;L;;;;;N;;;;;
5455 1A0E;BUGINESE LETTER NYA;Lo;0;L;;;;;N;;;;;
5456 1A0F;BUGINESE LETTER NYCA;Lo;0;L;;;;;N;;;;;
5457 1A10;BUGINESE LETTER YA;Lo;0;L;;;;;N;;;;;
5458 1A11;BUGINESE LETTER RA;Lo;0;L;;;;;N;;;;;
5459 1A12;BUGINESE LETTER LA;Lo;0;L;;;;;N;;;;;
5460 1A13;BUGINESE LETTER VA;Lo;0;L;;;;;N;;;;;
5461 1A14;BUGINESE LETTER SA;Lo;0;L;;;;;N;;;;;
5462 1A15;BUGINESE LETTER A;Lo;0;L;;;;;N;;;;;
5463 1A16;BUGINESE LETTER HA;Lo;0;L;;;;;N;;;;;
5464 1A17;BUGINESE VOWEL SIGN I;Mn;230;NSM;;;;;N;;;;;
5465 1A18;BUGINESE VOWEL SIGN U;Mn;220;NSM;;;;;N;;;;;
5466 1A19;BUGINESE VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
5467 1A1A;BUGINESE VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
5468 1A1B;BUGINESE VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;
5469 1A1E;BUGINESE PALLAWA;Po;0;L;;;;;N;;;;;
5470 1A1F;BUGINESE END OF SECTION;Po;0;L;;;;;N;;;;;
5471 1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;ardhacandra;;;
5472 1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;candrabindu;;;
5473 1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;anusvara;;;
5474 1B03;BALINESE SIGN SURANG;Mn;0;NSM;;;;;N;;repha;;;
5475 1B04;BALINESE SIGN BISAH;Mc;0;L;;;;;N;;visarga;;;
5476 1B05;BALINESE LETTER AKARA;Lo;0;L;;;;;N;;a;;;
5477 1B06;BALINESE LETTER AKARA TEDUNG;Lo;0;L;1B05 1B35;;;;N;;aa;;;
5478 1B07;BALINESE LETTER IKARA;Lo;0;L;;;;;N;;i;;;
5479 1B08;BALINESE LETTER IKARA TEDUNG;Lo;0;L;1B07 1B35;;;;N;;ii;;;
5480 1B09;BALINESE LETTER UKARA;Lo;0;L;;;;;N;;u;;;
5481 1B0A;BALINESE LETTER UKARA TEDUNG;Lo;0;L;1B09 1B35;;;;N;;uu;;;
5482 1B0B;BALINESE LETTER RA REPA;Lo;0;L;;;;;N;;vocalic r;;;
5483 1B0C;BALINESE LETTER RA REPA TEDUNG;Lo;0;L;1B0B 1B35;;;;N;;vocalic rr;;;
5484 1B0D;BALINESE LETTER LA LENGA;Lo;0;L;;;;;N;;vocalic l;;;
5485 1B0E;BALINESE LETTER LA LENGA TEDUNG;Lo;0;L;1B0D 1B35;;;;N;;vocalic ll;;;
5486 1B0F;BALINESE LETTER EKARA;Lo;0;L;;;;;N;;e;;;
5487 1B10;BALINESE LETTER AIKARA;Lo;0;L;;;;;N;;ai;;;
5488 1B11;BALINESE LETTER OKARA;Lo;0;L;;;;;N;;o;;;
5489 1B12;BALINESE LETTER OKARA TEDUNG;Lo;0;L;1B11 1B35;;;;N;;au;;;
5490 1B13;BALINESE LETTER KA;Lo;0;L;;;;;N;;;;;
5491 1B14;BALINESE LETTER KA MAHAPRANA;Lo;0;L;;;;;N;;kha;;;
5492 1B15;BALINESE LETTER GA;Lo;0;L;;;;;N;;;;;
5493 1B16;BALINESE LETTER GA GORA;Lo;0;L;;;;;N;;gha;;;
5494 1B17;BALINESE LETTER NGA;Lo;0;L;;;;;N;;;;;
5495 1B18;BALINESE LETTER CA;Lo;0;L;;;;;N;;;;;
5496 1B19;BALINESE LETTER CA LACA;Lo;0;L;;;;;N;;cha;;;
5497 1B1A;BALINESE LETTER JA;Lo;0;L;;;;;N;;;;;
5498 1B1B;BALINESE LETTER JA JERA;Lo;0;L;;;;;N;;jha;;;
5499 1B1C;BALINESE LETTER NYA;Lo;0;L;;;;;N;;;;;
5500 1B1D;BALINESE LETTER TA LATIK;Lo;0;L;;;;;N;;tta;;;
5501 1B1E;BALINESE LETTER TA MURDA MAHAPRANA;Lo;0;L;;;;;N;;ttha;;;
5502 1B1F;BALINESE LETTER DA MURDA ALPAPRANA;Lo;0;L;;;;;N;;dda;;;
5503 1B20;BALINESE LETTER DA MURDA MAHAPRANA;Lo;0;L;;;;;N;;ddha;;;
5504 1B21;BALINESE LETTER NA RAMBAT;Lo;0;L;;;;;N;;nna;;;
5505 1B22;BALINESE LETTER TA;Lo;0;L;;;;;N;;;;;
5506 1B23;BALINESE LETTER TA TAWA;Lo;0;L;;;;;N;;tha;;;
5507 1B24;BALINESE LETTER DA;Lo;0;L;;;;;N;;;;;
5508 1B25;BALINESE LETTER DA MADU;Lo;0;L;;;;;N;;dha;;;
5509 1B26;BALINESE LETTER NA;Lo;0;L;;;;;N;;;;;
5510 1B27;BALINESE LETTER PA;Lo;0;L;;;;;N;;;;;
5511 1B28;BALINESE LETTER PA KAPAL;Lo;0;L;;;;;N;;pha;;;
5512 1B29;BALINESE LETTER BA;Lo;0;L;;;;;N;;;;;
5513 1B2A;BALINESE LETTER BA KEMBANG;Lo;0;L;;;;;N;;bha;;;
5514 1B2B;BALINESE LETTER MA;Lo;0;L;;;;;N;;;;;
5515 1B2C;BALINESE LETTER YA;Lo;0;L;;;;;N;;;;;
5516 1B2D;BALINESE LETTER RA;Lo;0;L;;;;;N;;;;;
5517 1B2E;BALINESE LETTER LA;Lo;0;L;;;;;N;;;;;
5518 1B2F;BALINESE LETTER WA;Lo;0;L;;;;;N;;;;;
5519 1B30;BALINESE LETTER SA SAGA;Lo;0;L;;;;;N;;sha;;;
5520 1B31;BALINESE LETTER SA SAPA;Lo;0;L;;;;;N;;ssa;;;
5521 1B32;BALINESE LETTER SA;Lo;0;L;;;;;N;;;;;
5522 1B33;BALINESE LETTER HA;Lo;0;L;;;;;N;;;;;
5523 1B34;BALINESE SIGN REREKAN;Mn;7;NSM;;;;;N;;nukta;;;
5524 1B35;BALINESE VOWEL SIGN TEDUNG;Mc;0;L;;;;;N;;aa;;;
5525 1B36;BALINESE VOWEL SIGN ULU;Mn;0;NSM;;;;;N;;i;;;
5526 1B37;BALINESE VOWEL SIGN ULU SARI;Mn;0;NSM;;;;;N;;ii;;;
5527 1B38;BALINESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;u;;;
5528 1B39;BALINESE VOWEL SIGN SUKU ILUT;Mn;0;NSM;;;;;N;;uu;;;
5529 1B3A;BALINESE VOWEL SIGN RA REPA;Mn;0;NSM;;;;;N;;vocalic r;;;
5530 1B3B;BALINESE VOWEL SIGN RA REPA TEDUNG;Mc;0;L;1B3A 1B35;;;;N;;vocalic rr;;;
5531 1B3C;BALINESE VOWEL SIGN LA LENGA;Mn;0;NSM;;;;;N;;vocalic l;;;
5532 1B3D;BALINESE VOWEL SIGN LA LENGA TEDUNG;Mc;0;L;1B3C 1B35;;;;N;;vocalic ll;;;
5533 1B3E;BALINESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;e;;;
5534 1B3F;BALINESE VOWEL SIGN TALING REPA;Mc;0;L;;;;;N;;ai;;;
5535 1B40;BALINESE VOWEL SIGN TALING TEDUNG;Mc;0;L;1B3E 1B35;;;;N;;o;;;
5536 1B41;BALINESE VOWEL SIGN TALING REPA TEDUNG;Mc;0;L;1B3F 1B35;;;;N;;au;;;
5537 1B42;BALINESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;ae;;;
5538 1B43;BALINESE VOWEL SIGN PEPET TEDUNG;Mc;0;L;1B42 1B35;;;;N;;oe;;;
5539 1B44;BALINESE ADEG ADEG;Mc;9;L;;;;;N;;virama;;;
5540 1B45;BALINESE LETTER KAF SASAK;Lo;0;L;;;;;N;;;;;
5541 1B46;BALINESE LETTER KHOT SASAK;Lo;0;L;;;;;N;;;;;
5542 1B47;BALINESE LETTER TZIR SASAK;Lo;0;L;;;;;N;;;;;
5543 1B48;BALINESE LETTER EF SASAK;Lo;0;L;;;;;N;;;;;
5544 1B49;BALINESE LETTER VE SASAK;Lo;0;L;;;;;N;;;;;
5545 1B4A;BALINESE LETTER ZAL SASAK;Lo;0;L;;;;;N;;;;;
5546 1B4B;BALINESE LETTER ASYURA SASAK;Lo;0;L;;;;;N;;;;;
5547 1B50;BALINESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
5548 1B51;BALINESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
5549 1B52;BALINESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
5550 1B53;BALINESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
5551 1B54;BALINESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
5552 1B55;BALINESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
5553 1B56;BALINESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
5554 1B57;BALINESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
5555 1B58;BALINESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
5556 1B59;BALINESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
5557 1B5A;BALINESE PANTI;Po;0;L;;;;;N;;section;;;
5558 1B5B;BALINESE PAMADA;Po;0;L;;;;;N;;honorific section;;;
5559 1B5C;BALINESE WINDU;Po;0;L;;;;;N;;punctuation ring;;;
5560 1B5D;BALINESE CARIK PAMUNGKAH;Po;0;L;;;;;N;;colon;;;
5561 1B5E;BALINESE CARIK SIKI;Po;0;L;;;;;N;;danda;;;
5562 1B5F;BALINESE CARIK PAREREN;Po;0;L;;;;;N;;double danda;;;
5563 1B60;BALINESE PAMENENG;Po;0;L;;;;;N;;line-breaking hyphen;;;
5564 1B61;BALINESE MUSICAL SYMBOL DONG;So;0;L;;;;;N;;;;;
5565 1B62;BALINESE MUSICAL SYMBOL DENG;So;0;L;;;;;N;;;;;
5566 1B63;BALINESE MUSICAL SYMBOL DUNG;So;0;L;;;;;N;;;;;
5567 1B64;BALINESE MUSICAL SYMBOL DANG;So;0;L;;;;;N;;;;;
5568 1B65;BALINESE MUSICAL SYMBOL DANG SURANG;So;0;L;;;;;N;;;;;
5569 1B66;BALINESE MUSICAL SYMBOL DING;So;0;L;;;;;N;;;;;
5570 1B67;BALINESE MUSICAL SYMBOL DAENG;So;0;L;;;;;N;;;;;
5571 1B68;BALINESE MUSICAL SYMBOL DEUNG;So;0;L;;;;;N;;;;;
5572 1B69;BALINESE MUSICAL SYMBOL DAING;So;0;L;;;;;N;;;;;
5573 1B6A;BALINESE MUSICAL SYMBOL DANG GEDE;So;0;L;;;;;N;;;;;
5574 1B6B;BALINESE MUSICAL SYMBOL COMBINING TEGEH;Mn;230;NSM;;;;;N;;;;;
5575 1B6C;BALINESE MUSICAL SYMBOL COMBINING ENDEP;Mn;220;NSM;;;;;N;;;;;
5576 1B6D;BALINESE MUSICAL SYMBOL COMBINING KEMPUL;Mn;230;NSM;;;;;N;;;;;
5577 1B6E;BALINESE MUSICAL SYMBOL COMBINING KEMPLI;Mn;230;NSM;;;;;N;;;;;
5578 1B6F;BALINESE MUSICAL SYMBOL COMBINING JEGOGAN;Mn;230;NSM;;;;;N;;;;;
5579 1B70;BALINESE MUSICAL SYMBOL COMBINING KEMPUL WITH JEGOGAN;Mn;230;NSM;;;;;N;;;;;
5580 1B71;BALINESE MUSICAL SYMBOL COMBINING KEMPLI WITH JEGOGAN;Mn;230;NSM;;;;;N;;;;;
5581 1B72;BALINESE MUSICAL SYMBOL COMBINING BENDE;Mn;230;NSM;;;;;N;;;;;
5582 1B73;BALINESE MUSICAL SYMBOL COMBINING GONG;Mn;230;NSM;;;;;N;;;;;
5583 1B74;BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG;So;0;L;;;;;N;;;;;
5584 1B75;BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DAG;So;0;L;;;;;N;;;;;
5585 1B76;BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TUK;So;0;L;;;;;N;;;;;
5586 1B77;BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TAK;So;0;L;;;;;N;;;;;
5587 1B78;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PANG;So;0;L;;;;;N;;;;;
5588 1B79;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PUNG;So;0;L;;;;;N;;;;;
5589 1B7A;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK;So;0;L;;;;;N;;;;;
5590 1B7B;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK;So;0;L;;;;;N;;;;;
5591 1B7C;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING;So;0;L;;;;;N;;;;;
5592 1B80;SUNDANESE SIGN PANYECEK;Mn;0;NSM;;;;;N;;;;;
5593 1B81;SUNDANESE SIGN PANGLAYAR;Mn;0;NSM;;;;;N;;;;;
5594 1B82;SUNDANESE SIGN PANGWISAD;Mc;0;L;;;;;N;;;;;
5595 1B83;SUNDANESE LETTER A;Lo;0;L;;;;;N;;;;;
5596 1B84;SUNDANESE LETTER I;Lo;0;L;;;;;N;;;;;
5597 1B85;SUNDANESE LETTER U;Lo;0;L;;;;;N;;;;;
5598 1B86;SUNDANESE LETTER AE;Lo;0;L;;;;;N;;;;;
5599 1B87;SUNDANESE LETTER O;Lo;0;L;;;;;N;;;;;
5600 1B88;SUNDANESE LETTER E;Lo;0;L;;;;;N;;;;;
5601 1B89;SUNDANESE LETTER EU;Lo;0;L;;;;;N;;;;;
5602 1B8A;SUNDANESE LETTER KA;Lo;0;L;;;;;N;;;;;
5603 1B8B;SUNDANESE LETTER QA;Lo;0;L;;;;;N;;;;;
5604 1B8C;SUNDANESE LETTER GA;Lo;0;L;;;;;N;;;;;
5605 1B8D;SUNDANESE LETTER NGA;Lo;0;L;;;;;N;;;;;
5606 1B8E;SUNDANESE LETTER CA;Lo;0;L;;;;;N;;;;;
5607 1B8F;SUNDANESE LETTER JA;Lo;0;L;;;;;N;;;;;
5608 1B90;SUNDANESE LETTER ZA;Lo;0;L;;;;;N;;;;;
5609 1B91;SUNDANESE LETTER NYA;Lo;0;L;;;;;N;;;;;
5610 1B92;SUNDANESE LETTER TA;Lo;0;L;;;;;N;;;;;
5611 1B93;SUNDANESE LETTER DA;Lo;0;L;;;;;N;;;;;
5612 1B94;SUNDANESE LETTER NA;Lo;0;L;;;;;N;;;;;
5613 1B95;SUNDANESE LETTER PA;Lo;0;L;;;;;N;;;;;
5614 1B96;SUNDANESE LETTER FA;Lo;0;L;;;;;N;;;;;
5615 1B97;SUNDANESE LETTER VA;Lo;0;L;;;;;N;;;;;
5616 1B98;SUNDANESE LETTER BA;Lo;0;L;;;;;N;;;;;
5617 1B99;SUNDANESE LETTER MA;Lo;0;L;;;;;N;;;;;
5618 1B9A;SUNDANESE LETTER YA;Lo;0;L;;;;;N;;;;;
5619 1B9B;SUNDANESE LETTER RA;Lo;0;L;;;;;N;;;;;
5620 1B9C;SUNDANESE LETTER LA;Lo;0;L;;;;;N;;;;;
5621 1B9D;SUNDANESE LETTER WA;Lo;0;L;;;;;N;;;;;
5622 1B9E;SUNDANESE LETTER SA;Lo;0;L;;;;;N;;;;;
5623 1B9F;SUNDANESE LETTER XA;Lo;0;L;;;;;N;;;;;
5624 1BA0;SUNDANESE LETTER HA;Lo;0;L;;;;;N;;;;;
5625 1BA1;SUNDANESE CONSONANT SIGN PAMINGKAL;Mc;0;L;;;;;N;;;;;
5626 1BA2;SUNDANESE CONSONANT SIGN PANYAKRA;Mn;0;NSM;;;;;N;;;;;
5627 1BA3;SUNDANESE CONSONANT SIGN PANYIKU;Mn;0;NSM;;;;;N;;;;;
5628 1BA4;SUNDANESE VOWEL SIGN PANGHULU;Mn;0;NSM;;;;;N;;;;;
5629 1BA5;SUNDANESE VOWEL SIGN PANYUKU;Mn;0;NSM;;;;;N;;;;;
5630 1BA6;SUNDANESE VOWEL SIGN PANAELAENG;Mc;0;L;;;;;N;;;;;
5631 1BA7;SUNDANESE VOWEL SIGN PANOLONG;Mc;0;L;;;;;N;;;;;
5632 1BA8;SUNDANESE VOWEL SIGN PAMEPET;Mn;0;NSM;;;;;N;;;;;
5633 1BA9;SUNDANESE VOWEL SIGN PANEULEUNG;Mn;0;NSM;;;;;N;;;;;
5634 1BAA;SUNDANESE SIGN PAMAAEH;Mc;9;L;;;;;N;;;;;
5635 1BAE;SUNDANESE LETTER KHA;Lo;0;L;;;;;N;;;;;
5636 1BAF;SUNDANESE LETTER SYA;Lo;0;L;;;;;N;;;;;
5637 1BB0;SUNDANESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
5638 1BB1;SUNDANESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
5639 1BB2;SUNDANESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
5640 1BB3;SUNDANESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
5641 1BB4;SUNDANESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
5642 1BB5;SUNDANESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
5643 1BB6;SUNDANESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
5644 1BB7;SUNDANESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
5645 1BB8;SUNDANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
5646 1BB9;SUNDANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
5647 1C00;LEPCHA LETTER KA;Lo;0;L;;;;;N;;;;;
5648 1C01;LEPCHA LETTER KLA;Lo;0;L;;;;;N;;;;;
5649 1C02;LEPCHA LETTER KHA;Lo;0;L;;;;;N;;;;;
5650 1C03;LEPCHA LETTER GA;Lo;0;L;;;;;N;;;;;
5651 1C04;LEPCHA LETTER GLA;Lo;0;L;;;;;N;;;;;
5652 1C05;LEPCHA LETTER NGA;Lo;0;L;;;;;N;;;;;
5653 1C06;LEPCHA LETTER CA;Lo;0;L;;;;;N;;;;;
5654 1C07;LEPCHA LETTER CHA;Lo;0;L;;;;;N;;;;;
5655 1C08;LEPCHA LETTER JA;Lo;0;L;;;;;N;;;;;
5656 1C09;LEPCHA LETTER NYA;Lo;0;L;;;;;N;;;;;
5657 1C0A;LEPCHA LETTER TA;Lo;0;L;;;;;N;;;;;
5658 1C0B;LEPCHA LETTER THA;Lo;0;L;;;;;N;;;;;
5659 1C0C;LEPCHA LETTER DA;Lo;0;L;;;;;N;;;;;
5660 1C0D;LEPCHA LETTER NA;Lo;0;L;;;;;N;;;;;
5661 1C0E;LEPCHA LETTER PA;Lo;0;L;;;;;N;;;;;
5662 1C0F;LEPCHA LETTER PLA;Lo;0;L;;;;;N;;;;;
5663 1C10;LEPCHA LETTER PHA;Lo;0;L;;;;;N;;;;;
5664 1C11;LEPCHA LETTER FA;Lo;0;L;;;;;N;;;;;
5665 1C12;LEPCHA LETTER FLA;Lo;0;L;;;;;N;;;;;
5666 1C13;LEPCHA LETTER BA;Lo;0;L;;;;;N;;;;;
5667 1C14;LEPCHA LETTER BLA;Lo;0;L;;;;;N;;;;;
5668 1C15;LEPCHA LETTER MA;Lo;0;L;;;;;N;;;;;
5669 1C16;LEPCHA LETTER MLA;Lo;0;L;;;;;N;;;;;
5670 1C17;LEPCHA LETTER TSA;Lo;0;L;;;;;N;;;;;
5671 1C18;LEPCHA LETTER TSHA;Lo;0;L;;;;;N;;;;;
5672 1C19;LEPCHA LETTER DZA;Lo;0;L;;;;;N;;;;;
5673 1C1A;LEPCHA LETTER YA;Lo;0;L;;;;;N;;;;;
5674 1C1B;LEPCHA LETTER RA;Lo;0;L;;;;;N;;;;;
5675 1C1C;LEPCHA LETTER LA;Lo;0;L;;;;;N;;;;;
5676 1C1D;LEPCHA LETTER HA;Lo;0;L;;;;;N;;;;;
5677 1C1E;LEPCHA LETTER HLA;Lo;0;L;;;;;N;;;;;
5678 1C1F;LEPCHA LETTER VA;Lo;0;L;;;;;N;;;;;
5679 1C20;LEPCHA LETTER SA;Lo;0;L;;;;;N;;;;;
5680 1C21;LEPCHA LETTER SHA;Lo;0;L;;;;;N;;;;;
5681 1C22;LEPCHA LETTER WA;Lo;0;L;;;;;N;;;;;
5682 1C23;LEPCHA LETTER A;Lo;0;L;;;;;N;;;;;
5683 1C24;LEPCHA SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;;
5684 1C25;LEPCHA SUBJOINED LETTER RA;Mc;0;L;;;;;N;;;;;
5685 1C26;LEPCHA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
5686 1C27;LEPCHA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
5687 1C28;LEPCHA VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
5688 1C29;LEPCHA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
5689 1C2A;LEPCHA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
5690 1C2B;LEPCHA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
5691 1C2C;LEPCHA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
5692 1C2D;LEPCHA CONSONANT SIGN K;Mn;0;NSM;;;;;N;;;;;
5693 1C2E;LEPCHA CONSONANT SIGN M;Mn;0;NSM;;;;;N;;;;;
5694 1C2F;LEPCHA CONSONANT SIGN L;Mn;0;NSM;;;;;N;;;;;
5695 1C30;LEPCHA CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;;
5696 1C31;LEPCHA CONSONANT SIGN P;Mn;0;NSM;;;;;N;;;;;
5697 1C32;LEPCHA CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;;
5698 1C33;LEPCHA CONSONANT SIGN T;Mn;0;NSM;;;;;N;;;;;
5699 1C34;LEPCHA CONSONANT SIGN NYIN-DO;Mc;0;L;;;;;N;;;;;
5700 1C35;LEPCHA CONSONANT SIGN KANG;Mc;0;L;;;;;N;;;;;
5701 1C36;LEPCHA SIGN RAN;Mn;0;NSM;;;;;N;;;;;
5702 1C37;LEPCHA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;
5703 1C3B;LEPCHA PUNCTUATION TA-ROL;Po;0;L;;;;;N;;;;;
5704 1C3C;LEPCHA PUNCTUATION NYET THYOOM TA-ROL;Po;0;L;;;;;N;;;;;
5705 1C3D;LEPCHA PUNCTUATION CER-WA;Po;0;L;;;;;N;;;;;
5706 1C3E;LEPCHA PUNCTUATION TSHOOK CER-WA;Po;0;L;;;;;N;;;;;
5707 1C3F;LEPCHA PUNCTUATION TSHOOK;Po;0;L;;;;;N;;;;;
5708 1C40;LEPCHA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
5709 1C41;LEPCHA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
5710 1C42;LEPCHA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
5711 1C43;LEPCHA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
5712 1C44;LEPCHA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
5713 1C45;LEPCHA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
5714 1C46;LEPCHA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
5715 1C47;LEPCHA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
5716 1C48;LEPCHA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
5717 1C49;LEPCHA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
5718 1C4D;LEPCHA LETTER TTA;Lo;0;L;;;;;N;;;;;
5719 1C4E;LEPCHA LETTER TTHA;Lo;0;L;;;;;N;;;;;
5720 1C4F;LEPCHA LETTER DDA;Lo;0;L;;;;;N;;;;;
5721 1C50;OL CHIKI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
5722 1C51;OL CHIKI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
5723 1C52;OL CHIKI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
5724 1C53;OL CHIKI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
5725 1C54;OL CHIKI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
5726 1C55;OL CHIKI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
5727 1C56;OL CHIKI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
5728 1C57;OL CHIKI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
5729 1C58;OL CHIKI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
5730 1C59;OL CHIKI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
5731 1C5A;OL CHIKI LETTER LA;Lo;0;L;;;;;N;;;;;
5732 1C5B;OL CHIKI LETTER AT;Lo;0;L;;;;;N;;;;;
5733 1C5C;OL CHIKI LETTER AG;Lo;0;L;;;;;N;;;;;
5734 1C5D;OL CHIKI LETTER ANG;Lo;0;L;;;;;N;;;;;
5735 1C5E;OL CHIKI LETTER AL;Lo;0;L;;;;;N;;;;;
5736 1C5F;OL CHIKI LETTER LAA;Lo;0;L;;;;;N;;;;;
5737 1C60;OL CHIKI LETTER AAK;Lo;0;L;;;;;N;;;;;
5738 1C61;OL CHIKI LETTER AAJ;Lo;0;L;;;;;N;;;;;
5739 1C62;OL CHIKI LETTER AAM;Lo;0;L;;;;;N;;;;;
5740 1C63;OL CHIKI LETTER AAW;Lo;0;L;;;;;N;;;;;
5741 1C64;OL CHIKI LETTER LI;Lo;0;L;;;;;N;;;;;
5742 1C65;OL CHIKI LETTER IS;Lo;0;L;;;;;N;;;;;
5743 1C66;OL CHIKI LETTER IH;Lo;0;L;;;;;N;;;;;
5744 1C67;OL CHIKI LETTER INY;Lo;0;L;;;;;N;;;;;
5745 1C68;OL CHIKI LETTER IR;Lo;0;L;;;;;N;;;;;
5746 1C69;OL CHIKI LETTER LU;Lo;0;L;;;;;N;;;;;
5747 1C6A;OL CHIKI LETTER UC;Lo;0;L;;;;;N;;;;;
5748 1C6B;OL CHIKI LETTER UD;Lo;0;L;;;;;N;;;;;
5749 1C6C;OL CHIKI LETTER UNN;Lo;0;L;;;;;N;;;;;
5750 1C6D;OL CHIKI LETTER UY;Lo;0;L;;;;;N;;;;;
5751 1C6E;OL CHIKI LETTER LE;Lo;0;L;;;;;N;;;;;
5752 1C6F;OL CHIKI LETTER EP;Lo;0;L;;;;;N;;;;;
5753 1C70;OL CHIKI LETTER EDD;Lo;0;L;;;;;N;;;;;
5754 1C71;OL CHIKI LETTER EN;Lo;0;L;;;;;N;;;;;
5755 1C72;OL CHIKI LETTER ERR;Lo;0;L;;;;;N;;;;;
5756 1C73;OL CHIKI LETTER LO;Lo;0;L;;;;;N;;;;;
5757 1C74;OL CHIKI LETTER OTT;Lo;0;L;;;;;N;;;;;
5758 1C75;OL CHIKI LETTER OB;Lo;0;L;;;;;N;;;;;
5759 1C76;OL CHIKI LETTER OV;Lo;0;L;;;;;N;;;;;
5760 1C77;OL CHIKI LETTER OH;Lo;0;L;;;;;N;;;;;
5761 1C78;OL CHIKI MU TTUDDAG;Lm;0;L;;;;;N;;;;;
5762 1C79;OL CHIKI GAAHLAA TTUDDAAG;Lm;0;L;;;;;N;;;;;
5763 1C7A;OL CHIKI MU-GAAHLAA TTUDDAAG;Lm;0;L;;;;;N;;;;;
5764 1C7B;OL CHIKI RELAA;Lm;0;L;;;;;N;;;;;
5765 1C7C;OL CHIKI PHAARKAA;Lm;0;L;;;;;N;;;;;
5766 1C7D;OL CHIKI AHAD;Lm;0;L;;;;;N;;;;;
5767 1C7E;OL CHIKI PUNCTUATION MUCAAD;Po;0;L;;;;;N;;;;;
5768 1C7F;OL CHIKI PUNCTUATION DOUBLE MUCAAD;Po;0;L;;;;;N;;;;;
5769 1D00;LATIN LETTER SMALL CAPITAL A;Ll;0;L;;;;;N;;;;;
5770 1D01;LATIN LETTER SMALL CAPITAL AE;Ll;0;L;;;;;N;;;;;
5771 1D02;LATIN SMALL LETTER TURNED AE;Ll;0;L;;;;;N;;;;;
5772 1D03;LATIN LETTER SMALL CAPITAL BARRED B;Ll;0;L;;;;;N;;;;;
5773 1D04;LATIN LETTER SMALL CAPITAL C;Ll;0;L;;;;;N;;;;;
5774 1D05;LATIN LETTER SMALL CAPITAL D;Ll;0;L;;;;;N;;;;;
5775 1D06;LATIN LETTER SMALL CAPITAL ETH;Ll;0;L;;;;;N;;;;;
5776 1D07;LATIN LETTER SMALL CAPITAL E;Ll;0;L;;;;;N;;;;;
5777 1D08;LATIN SMALL LETTER TURNED OPEN E;Ll;0;L;;;;;N;;;;;
5778 1D09;LATIN SMALL LETTER TURNED I;Ll;0;L;;;;;N;;;;;
5779 1D0A;LATIN LETTER SMALL CAPITAL J;Ll;0;L;;;;;N;;;;;
5780 1D0B;LATIN LETTER SMALL CAPITAL K;Ll;0;L;;;;;N;;;;;
5781 1D0C;LATIN LETTER SMALL CAPITAL L WITH STROKE;Ll;0;L;;;;;N;;;;;
5782 1D0D;LATIN LETTER SMALL CAPITAL M;Ll;0;L;;;;;N;;;;;
5783 1D0E;LATIN LETTER SMALL CAPITAL REVERSED N;Ll;0;L;;;;;N;;;;;
5784 1D0F;LATIN LETTER SMALL CAPITAL O;Ll;0;L;;;;;N;;;;;
5785 1D10;LATIN LETTER SMALL CAPITAL OPEN O;Ll;0;L;;;;;N;;;;;
5786 1D11;LATIN SMALL LETTER SIDEWAYS O;Ll;0;L;;;;;N;;;;;
5787 1D12;LATIN SMALL LETTER SIDEWAYS OPEN O;Ll;0;L;;;;;N;;;;;
5788 1D13;LATIN SMALL LETTER SIDEWAYS O WITH STROKE;Ll;0;L;;;;;N;;;;;
5789 1D14;LATIN SMALL LETTER TURNED OE;Ll;0;L;;;;;N;;;;;
5790 1D15;LATIN LETTER SMALL CAPITAL OU;Ll;0;L;;;;;N;;;;;
5791 1D16;LATIN SMALL LETTER TOP HALF O;Ll;0;L;;;;;N;;;;;
5792 1D17;LATIN SMALL LETTER BOTTOM HALF O;Ll;0;L;;;;;N;;;;;
5793 1D18;LATIN LETTER SMALL CAPITAL P;Ll;0;L;;;;;N;;;;;
5794 1D19;LATIN LETTER SMALL CAPITAL REVERSED R;Ll;0;L;;;;;N;;;;;
5795 1D1A;LATIN LETTER SMALL CAPITAL TURNED R;Ll;0;L;;;;;N;;;;;
5796 1D1B;LATIN LETTER SMALL CAPITAL T;Ll;0;L;;;;;N;;;;;
5797 1D1C;LATIN LETTER SMALL CAPITAL U;Ll;0;L;;;;;N;;;;;
5798 1D1D;LATIN SMALL LETTER SIDEWAYS U;Ll;0;L;;;;;N;;;;;
5799 1D1E;LATIN SMALL LETTER SIDEWAYS DIAERESIZED U;Ll;0;L;;;;;N;;;;;
5800 1D1F;LATIN SMALL LETTER SIDEWAYS TURNED M;Ll;0;L;;;;;N;;;;;
5801 1D20;LATIN LETTER SMALL CAPITAL V;Ll;0;L;;;;;N;;;;;
5802 1D21;LATIN LETTER SMALL CAPITAL W;Ll;0;L;;;;;N;;;;;
5803 1D22;LATIN LETTER SMALL CAPITAL Z;Ll;0;L;;;;;N;;;;;
5804 1D23;LATIN LETTER SMALL CAPITAL EZH;Ll;0;L;;;;;N;;;;;
5805 1D24;LATIN LETTER VOICED LARYNGEAL SPIRANT;Ll;0;L;;;;;N;;;;;
5806 1D25;LATIN LETTER AIN;Ll;0;L;;;;;N;;;;;
5807 1D26;GREEK LETTER SMALL CAPITAL GAMMA;Ll;0;L;;;;;N;;;;;
5808 1D27;GREEK LETTER SMALL CAPITAL LAMDA;Ll;0;L;;;;;N;;;;;
5809 1D28;GREEK LETTER SMALL CAPITAL PI;Ll;0;L;;;;;N;;;;;
5810 1D29;GREEK LETTER SMALL CAPITAL RHO;Ll;0;L;;;;;N;;;;;
5811 1D2A;GREEK LETTER SMALL CAPITAL PSI;Ll;0;L;;;;;N;;;;;
5812 1D2B;CYRILLIC LETTER SMALL CAPITAL EL;Ll;0;L;;;;;N;;;;;
5813 1D2C;MODIFIER LETTER CAPITAL A;Lm;0;L;<super> 0041;;;;N;;;;;
5814 1D2D;MODIFIER LETTER CAPITAL AE;Lm;0;L;<super> 00C6;;;;N;;;;;
5815 1D2E;MODIFIER LETTER CAPITAL B;Lm;0;L;<super> 0042;;;;N;;;;;
5816 1D2F;MODIFIER LETTER CAPITAL BARRED B;Lm;0;L;;;;;N;;;;;
5817 1D30;MODIFIER LETTER CAPITAL D;Lm;0;L;<super> 0044;;;;N;;;;;
5818 1D31;MODIFIER LETTER CAPITAL E;Lm;0;L;<super> 0045;;;;N;;;;;
5819 1D32;MODIFIER LETTER CAPITAL REVERSED E;Lm;0;L;<super> 018E;;;;N;;;;;
5820 1D33;MODIFIER LETTER CAPITAL G;Lm;0;L;<super> 0047;;;;N;;;;;
5821 1D34;MODIFIER LETTER CAPITAL H;Lm;0;L;<super> 0048;;;;N;;;;;
5822 1D35;MODIFIER LETTER CAPITAL I;Lm;0;L;<super> 0049;;;;N;;;;;
5823 1D36;MODIFIER LETTER CAPITAL J;Lm;0;L;<super> 004A;;;;N;;;;;
5824 1D37;MODIFIER LETTER CAPITAL K;Lm;0;L;<super> 004B;;;;N;;;;;
5825 1D38;MODIFIER LETTER CAPITAL L;Lm;0;L;<super> 004C;;;;N;;;;;
5826 1D39;MODIFIER LETTER CAPITAL M;Lm;0;L;<super> 004D;;;;N;;;;;
5827 1D3A;MODIFIER LETTER CAPITAL N;Lm;0;L;<super> 004E;;;;N;;;;;
5828 1D3B;MODIFIER LETTER CAPITAL REVERSED N;Lm;0;L;;;;;N;;;;;
5829 1D3C;MODIFIER LETTER CAPITAL O;Lm;0;L;<super> 004F;;;;N;;;;;
5830 1D3D;MODIFIER LETTER CAPITAL OU;Lm;0;L;<super> 0222;;;;N;;;;;
5831 1D3E;MODIFIER LETTER CAPITAL P;Lm;0;L;<super> 0050;;;;N;;;;;
5832 1D3F;MODIFIER LETTER CAPITAL R;Lm;0;L;<super> 0052;;;;N;;;;;
5833 1D40;MODIFIER LETTER CAPITAL T;Lm;0;L;<super> 0054;;;;N;;;;;
5834 1D41;MODIFIER LETTER CAPITAL U;Lm;0;L;<super> 0055;;;;N;;;;;
5835 1D42;MODIFIER LETTER CAPITAL W;Lm;0;L;<super> 0057;;;;N;;;;;
5836 1D43;MODIFIER LETTER SMALL A;Lm;0;L;<super> 0061;;;;N;;;;;
5837 1D44;MODIFIER LETTER SMALL TURNED A;Lm;0;L;<super> 0250;;;;N;;;;;
5838 1D45;MODIFIER LETTER SMALL ALPHA;Lm;0;L;<super> 0251;;;;N;;;;;
5839 1D46;MODIFIER LETTER SMALL TURNED AE;Lm;0;L;<super> 1D02;;;;N;;;;;
5840 1D47;MODIFIER LETTER SMALL B;Lm;0;L;<super> 0062;;;;N;;;;;
5841 1D48;MODIFIER LETTER SMALL D;Lm;0;L;<super> 0064;;;;N;;;;;
5842 1D49;MODIFIER LETTER SMALL E;Lm;0;L;<super> 0065;;;;N;;;;;
5843 1D4A;MODIFIER LETTER SMALL SCHWA;Lm;0;L;<super> 0259;;;;N;;;;;
5844 1D4B;MODIFIER LETTER SMALL OPEN E;Lm;0;L;<super> 025B;;;;N;;;;;
5845 1D4C;MODIFIER LETTER SMALL TURNED OPEN E;Lm;0;L;<super> 025C;;;;N;;;;;
5846 1D4D;MODIFIER LETTER SMALL G;Lm;0;L;<super> 0067;;;;N;;;;;
5847 1D4E;MODIFIER LETTER SMALL TURNED I;Lm;0;L;;;;;N;;;;;
5848 1D4F;MODIFIER LETTER SMALL K;Lm;0;L;<super> 006B;;;;N;;;;;
5849 1D50;MODIFIER LETTER SMALL M;Lm;0;L;<super> 006D;;;;N;;;;;
5850 1D51;MODIFIER LETTER SMALL ENG;Lm;0;L;<super> 014B;;;;N;;;;;
5851 1D52;MODIFIER LETTER SMALL O;Lm;0;L;<super> 006F;;;;N;;;;;
5852 1D53;MODIFIER LETTER SMALL OPEN O;Lm;0;L;<super> 0254;;;;N;;;;;
5853 1D54;MODIFIER LETTER SMALL TOP HALF O;Lm;0;L;<super> 1D16;;;;N;;;;;
5854 1D55;MODIFIER LETTER SMALL BOTTOM HALF O;Lm;0;L;<super> 1D17;;;;N;;;;;
5855 1D56;MODIFIER LETTER SMALL P;Lm;0;L;<super> 0070;;;;N;;;;;
5856 1D57;MODIFIER LETTER SMALL T;Lm;0;L;<super> 0074;;;;N;;;;;
5857 1D58;MODIFIER LETTER SMALL U;Lm;0;L;<super> 0075;;;;N;;;;;
5858 1D59;MODIFIER LETTER SMALL SIDEWAYS U;Lm;0;L;<super> 1D1D;;;;N;;;;;
5859 1D5A;MODIFIER LETTER SMALL TURNED M;Lm;0;L;<super> 026F;;;;N;;;;;
5860 1D5B;MODIFIER LETTER SMALL V;Lm;0;L;<super> 0076;;;;N;;;;;
5861 1D5C;MODIFIER LETTER SMALL AIN;Lm;0;L;<super> 1D25;;;;N;;;;;
5862 1D5D;MODIFIER LETTER SMALL BETA;Lm;0;L;<super> 03B2;;;;N;;;;;
5863 1D5E;MODIFIER LETTER SMALL GREEK GAMMA;Lm;0;L;<super> 03B3;;;;N;;;;;
5864 1D5F;MODIFIER LETTER SMALL DELTA;Lm;0;L;<super> 03B4;;;;N;;;;;
5865 1D60;MODIFIER LETTER SMALL GREEK PHI;Lm;0;L;<super> 03C6;;;;N;;;;;
5866 1D61;MODIFIER LETTER SMALL CHI;Lm;0;L;<super> 03C7;;;;N;;;;;
5867 1D62;LATIN SUBSCRIPT SMALL LETTER I;Ll;0;L;<sub> 0069;;;;N;;;;;
5868 1D63;LATIN SUBSCRIPT SMALL LETTER R;Ll;0;L;<sub> 0072;;;;N;;;;;
5869 1D64;LATIN SUBSCRIPT SMALL LETTER U;Ll;0;L;<sub> 0075;;;;N;;;;;
5870 1D65;LATIN SUBSCRIPT SMALL LETTER V;Ll;0;L;<sub> 0076;;;;N;;;;;
5871 1D66;GREEK SUBSCRIPT SMALL LETTER BETA;Ll;0;L;<sub> 03B2;;;;N;;;;;
5872 1D67;GREEK SUBSCRIPT SMALL LETTER GAMMA;Ll;0;L;<sub> 03B3;;;;N;;;;;
5873 1D68;GREEK SUBSCRIPT SMALL LETTER RHO;Ll;0;L;<sub> 03C1;;;;N;;;;;
5874 1D69;GREEK SUBSCRIPT SMALL LETTER PHI;Ll;0;L;<sub> 03C6;;;;N;;;;;
5875 1D6A;GREEK SUBSCRIPT SMALL LETTER CHI;Ll;0;L;<sub> 03C7;;;;N;;;;;
5876 1D6B;LATIN SMALL LETTER UE;Ll;0;L;;;;;N;;;;;
5877 1D6C;LATIN SMALL LETTER B WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
5878 1D6D;LATIN SMALL LETTER D WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
5879 1D6E;LATIN SMALL LETTER F WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
5880 1D6F;LATIN SMALL LETTER M WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
5881 1D70;LATIN SMALL LETTER N WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
5882 1D71;LATIN SMALL LETTER P WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
5883 1D72;LATIN SMALL LETTER R WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
5884 1D73;LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
5885 1D74;LATIN SMALL LETTER S WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
5886 1D75;LATIN SMALL LETTER T WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
5887 1D76;LATIN SMALL LETTER Z WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;
5888 1D77;LATIN SMALL LETTER TURNED G;Ll;0;L;;;;;N;;;;;
5889 1D78;MODIFIER LETTER CYRILLIC EN;Lm;0;L;<super> 043D;;;;N;;;;;
5890 1D79;LATIN SMALL LETTER INSULAR G;Ll;0;L;;;;;N;;;A77D;;A77D
5891 1D7A;LATIN SMALL LETTER TH WITH STRIKETHROUGH;Ll;0;L;;;;;N;;;;;
5892 1D7B;LATIN SMALL CAPITAL LETTER I WITH STROKE;Ll;0;L;;;;;N;;;;;
5893 1D7C;LATIN SMALL LETTER IOTA WITH STROKE;Ll;0;L;;;;;N;;;;;
5894 1D7D;LATIN SMALL LETTER P WITH STROKE;Ll;0;L;;;;;N;;;2C63;;2C63
5895 1D7E;LATIN SMALL CAPITAL LETTER U WITH STROKE;Ll;0;L;;;;;N;;;;;
5896 1D7F;LATIN SMALL LETTER UPSILON WITH STROKE;Ll;0;L;;;;;N;;;;;
5897 1D80;LATIN SMALL LETTER B WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5898 1D81;LATIN SMALL LETTER D WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5899 1D82;LATIN SMALL LETTER F WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5900 1D83;LATIN SMALL LETTER G WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5901 1D84;LATIN SMALL LETTER K WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5902 1D85;LATIN SMALL LETTER L WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5903 1D86;LATIN SMALL LETTER M WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5904 1D87;LATIN SMALL LETTER N WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5905 1D88;LATIN SMALL LETTER P WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5906 1D89;LATIN SMALL LETTER R WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5907 1D8A;LATIN SMALL LETTER S WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5908 1D8B;LATIN SMALL LETTER ESH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5909 1D8C;LATIN SMALL LETTER V WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5910 1D8D;LATIN SMALL LETTER X WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5911 1D8E;LATIN SMALL LETTER Z WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;
5912 1D8F;LATIN SMALL LETTER A WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
5913 1D90;LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
5914 1D91;LATIN SMALL LETTER D WITH HOOK AND TAIL;Ll;0;L;;;;;N;;;;;
5915 1D92;LATIN SMALL LETTER E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
5916 1D93;LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
5917 1D94;LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
5918 1D95;LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
5919 1D96;LATIN SMALL LETTER I WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
5920 1D97;LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
5921 1D98;LATIN SMALL LETTER ESH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
5922 1D99;LATIN SMALL LETTER U WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
5923 1D9A;LATIN SMALL LETTER EZH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;
5924 1D9B;MODIFIER LETTER SMALL TURNED ALPHA;Lm;0;L;<super> 0252;;;;N;;;;;
5925 1D9C;MODIFIER LETTER SMALL C;Lm;0;L;<super> 0063;;;;N;;;;;
5926 1D9D;MODIFIER LETTER SMALL C WITH CURL;Lm;0;L;<super> 0255;;;;N;;;;;
5927 1D9E;MODIFIER LETTER SMALL ETH;Lm;0;L;<super> 00F0;;;;N;;;;;
5928 1D9F;MODIFIER LETTER SMALL REVERSED OPEN E;Lm;0;L;<super> 025C;;;;N;;;;;
5929 1DA0;MODIFIER LETTER SMALL F;Lm;0;L;<super> 0066;;;;N;;;;;
5930 1DA1;MODIFIER LETTER SMALL DOTLESS J WITH STROKE;Lm;0;L;<super> 025F;;;;N;;;;;
5931 1DA2;MODIFIER LETTER SMALL SCRIPT G;Lm;0;L;<super> 0261;;;;N;;;;;
5932 1DA3;MODIFIER LETTER SMALL TURNED H;Lm;0;L;<super> 0265;;;;N;;;;;
5933 1DA4;MODIFIER LETTER SMALL I WITH STROKE;Lm;0;L;<super> 0268;;;;N;;;;;
5934 1DA5;MODIFIER LETTER SMALL IOTA;Lm;0;L;<super> 0269;;;;N;;;;;
5935 1DA6;MODIFIER LETTER SMALL CAPITAL I;Lm;0;L;<super> 026A;;;;N;;;;;
5936 1DA7;MODIFIER LETTER SMALL CAPITAL I WITH STROKE;Lm;0;L;<super> 1D7B;;;;N;;;;;
5937 1DA8;MODIFIER LETTER SMALL J WITH CROSSED-TAIL;Lm;0;L;<super> 029D;;;;N;;;;;
5938 1DA9;MODIFIER LETTER SMALL L WITH RETROFLEX HOOK;Lm;0;L;<super> 026D;;;;N;;;;;
5939 1DAA;MODIFIER LETTER SMALL L WITH PALATAL HOOK;Lm;0;L;<super> 1D85;;;;N;;;;;
5940 1DAB;MODIFIER LETTER SMALL CAPITAL L;Lm;0;L;<super> 029F;;;;N;;;;;
5941 1DAC;MODIFIER LETTER SMALL M WITH HOOK;Lm;0;L;<super> 0271;;;;N;;;;;
5942 1DAD;MODIFIER LETTER SMALL TURNED M WITH LONG LEG;Lm;0;L;<super> 0270;;;;N;;;;;
5943 1DAE;MODIFIER LETTER SMALL N WITH LEFT HOOK;Lm;0;L;<super> 0272;;;;N;;;;;
5944 1DAF;MODIFIER LETTER SMALL N WITH RETROFLEX HOOK;Lm;0;L;<super> 0273;;;;N;;;;;
5945 1DB0;MODIFIER LETTER SMALL CAPITAL N;Lm;0;L;<super> 0274;;;;N;;;;;
5946 1DB1;MODIFIER LETTER SMALL BARRED O;Lm;0;L;<super> 0275;;;;N;;;;;
5947 1DB2;MODIFIER LETTER SMALL PHI;Lm;0;L;<super> 0278;;;;N;;;;;
5948 1DB3;MODIFIER LETTER SMALL S WITH HOOK;Lm;0;L;<super> 0282;;;;N;;;;;
5949 1DB4;MODIFIER LETTER SMALL ESH;Lm;0;L;<super> 0283;;;;N;;;;;
5950 1DB5;MODIFIER LETTER SMALL T WITH PALATAL HOOK;Lm;0;L;<super> 01AB;;;;N;;;;;
5951 1DB6;MODIFIER LETTER SMALL U BAR;Lm;0;L;<super> 0289;;;;N;;;;;
5952 1DB7;MODIFIER LETTER SMALL UPSILON;Lm;0;L;<super> 028A;;;;N;;;;;
5953 1DB8;MODIFIER LETTER SMALL CAPITAL U;Lm;0;L;<super> 1D1C;;;;N;;;;;
5954 1DB9;MODIFIER LETTER SMALL V WITH HOOK;Lm;0;L;<super> 028B;;;;N;;;;;
5955 1DBA;MODIFIER LETTER SMALL TURNED V;Lm;0;L;<super> 028C;;;;N;;;;;
5956 1DBB;MODIFIER LETTER SMALL Z;Lm;0;L;<super> 007A;;;;N;;;;;
5957 1DBC;MODIFIER LETTER SMALL Z WITH RETROFLEX HOOK;Lm;0;L;<super> 0290;;;;N;;;;;
5958 1DBD;MODIFIER LETTER SMALL Z WITH CURL;Lm;0;L;<super> 0291;;;;N;;;;;
5959 1DBE;MODIFIER LETTER SMALL EZH;Lm;0;L;<super> 0292;;;;N;;;;;
5960 1DBF;MODIFIER LETTER SMALL THETA;Lm;0;L;<super> 03B8;;;;N;;;;;
5961 1DC0;COMBINING DOTTED GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;;
5962 1DC1;COMBINING DOTTED ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;;
5963 1DC2;COMBINING SNAKE BELOW;Mn;220;NSM;;;;;N;;;;;
5964 1DC3;COMBINING SUSPENSION MARK;Mn;230;NSM;;;;;N;;;;;
5965 1DC4;COMBINING MACRON-ACUTE;Mn;230;NSM;;;;;N;;;;;
5966 1DC5;COMBINING GRAVE-MACRON;Mn;230;NSM;;;;;N;;;;;
5967 1DC6;COMBINING MACRON-GRAVE;Mn;230;NSM;;;;;N;;;;;
5968 1DC7;COMBINING ACUTE-MACRON;Mn;230;NSM;;;;;N;;;;;
5969 1DC8;COMBINING GRAVE-ACUTE-GRAVE;Mn;230;NSM;;;;;N;;;;;
5970 1DC9;COMBINING ACUTE-GRAVE-ACUTE;Mn;230;NSM;;;;;N;;;;;
5971 1DCA;COMBINING LATIN SMALL LETTER R BELOW;Mn;220;NSM;;;;;N;;;;;
5972 1DCB;COMBINING BREVE-MACRON;Mn;230;NSM;;;;;N;;;;;
5973 1DCC;COMBINING MACRON-BREVE;Mn;230;NSM;;;;;N;;;;;
5974 1DCD;COMBINING DOUBLE CIRCUMFLEX ABOVE;Mn;234;NSM;;;;;N;;;;;
5975 1DCE;COMBINING OGONEK ABOVE;Mn;214;NSM;;;;;N;;;;;
5976 1DCF;COMBINING ZIGZAG BELOW;Mn;220;NSM;;;;;N;;;;;
5977 1DD0;COMBINING IS BELOW;Mn;202;NSM;;;;;N;;;;;
5978 1DD1;COMBINING UR ABOVE;Mn;230;NSM;;;;;N;;;;;
5979 1DD2;COMBINING US ABOVE;Mn;230;NSM;;;;;N;;;;;
5980 1DD3;COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE;Mn;230;NSM;;;;;N;;;;;
5981 1DD4;COMBINING LATIN SMALL LETTER AE;Mn;230;NSM;;;;;N;;;;;
5982 1DD5;COMBINING LATIN SMALL LETTER AO;Mn;230;NSM;;;;;N;;;;;
5983 1DD6;COMBINING LATIN SMALL LETTER AV;Mn;230;NSM;;;;;N;;;;;
5984 1DD7;COMBINING LATIN SMALL LETTER C CEDILLA;Mn;230;NSM;;;;;N;;;;;
5985 1DD8;COMBINING LATIN SMALL LETTER INSULAR D;Mn;230;NSM;;;;;N;;;;;
5986 1DD9;COMBINING LATIN SMALL LETTER ETH;Mn;230;NSM;;;;;N;;;;;
5987 1DDA;COMBINING LATIN SMALL LETTER G;Mn;230;NSM;;;;;N;;;;;
5988 1DDB;COMBINING LATIN LETTER SMALL CAPITAL G;Mn;230;NSM;;;;;N;;;;;
5989 1DDC;COMBINING LATIN SMALL LETTER K;Mn;230;NSM;;;;;N;;;;;
5990 1DDD;COMBINING LATIN SMALL LETTER L;Mn;230;NSM;;;;;N;;;;;
5991 1DDE;COMBINING LATIN LETTER SMALL CAPITAL L;Mn;230;NSM;;;;;N;;;;;
5992 1DDF;COMBINING LATIN LETTER SMALL CAPITAL M;Mn;230;NSM;;;;;N;;;;;
5993 1DE0;COMBINING LATIN SMALL LETTER N;Mn;230;NSM;;;;;N;;;;;
5994 1DE1;COMBINING LATIN LETTER SMALL CAPITAL N;Mn;230;NSM;;;;;N;;;;;
5995 1DE2;COMBINING LATIN LETTER SMALL CAPITAL R;Mn;230;NSM;;;;;N;;;;;
5996 1DE3;COMBINING LATIN SMALL LETTER R ROTUNDA;Mn;230;NSM;;;;;N;;;;;
5997 1DE4;COMBINING LATIN SMALL LETTER S;Mn;230;NSM;;;;;N;;;;;
5998 1DE5;COMBINING LATIN SMALL LETTER LONG S;Mn;230;NSM;;;;;N;;;;;
5999 1DE6;COMBINING LATIN SMALL LETTER Z;Mn;230;NSM;;;;;N;;;;;
6000 1DFE;COMBINING LEFT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;
6001 1DFF;COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;
6002 1E00;LATIN CAPITAL LETTER A WITH RING BELOW;Lu;0;L;0041 0325;;;;N;;;;1E01;
6003 1E01;LATIN SMALL LETTER A WITH RING BELOW;Ll;0;L;0061 0325;;;;N;;;1E00;;1E00
6004 1E02;LATIN CAPITAL LETTER B WITH DOT ABOVE;Lu;0;L;0042 0307;;;;N;;;;1E03;
6005 1E03;LATIN SMALL LETTER B WITH DOT ABOVE;Ll;0;L;0062 0307;;;;N;;;1E02;;1E02
6006 1E04;LATIN CAPITAL LETTER B WITH DOT BELOW;Lu;0;L;0042 0323;;;;N;;;;1E05;
6007 1E05;LATIN SMALL LETTER B WITH DOT BELOW;Ll;0;L;0062 0323;;;;N;;;1E04;;1E04
6008 1E06;LATIN CAPITAL LETTER B WITH LINE BELOW;Lu;0;L;0042 0331;;;;N;;;;1E07;
6009 1E07;LATIN SMALL LETTER B WITH LINE BELOW;Ll;0;L;0062 0331;;;;N;;;1E06;;1E06
6010 1E08;LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE;Lu;0;L;00C7 0301;;;;N;;;;1E09;
6011 1E09;LATIN SMALL LETTER C WITH CEDILLA AND ACUTE;Ll;0;L;00E7 0301;;;;N;;;1E08;;1E08
6012 1E0A;LATIN CAPITAL LETTER D WITH DOT ABOVE;Lu;0;L;0044 0307;;;;N;;;;1E0B;
6013 1E0B;LATIN SMALL LETTER D WITH DOT ABOVE;Ll;0;L;0064 0307;;;;N;;;1E0A;;1E0A
6014 1E0C;LATIN CAPITAL LETTER D WITH DOT BELOW;Lu;0;L;0044 0323;;;;N;;;;1E0D;
6015 1E0D;LATIN SMALL LETTER D WITH DOT BELOW;Ll;0;L;0064 0323;;;;N;;;1E0C;;1E0C
6016 1E0E;LATIN CAPITAL LETTER D WITH LINE BELOW;Lu;0;L;0044 0331;;;;N;;;;1E0F;
6017 1E0F;LATIN SMALL LETTER D WITH LINE BELOW;Ll;0;L;0064 0331;;;;N;;;1E0E;;1E0E
6018 1E10;LATIN CAPITAL LETTER D WITH CEDILLA;Lu;0;L;0044 0327;;;;N;;;;1E11;
6019 1E11;LATIN SMALL LETTER D WITH CEDILLA;Ll;0;L;0064 0327;;;;N;;;1E10;;1E10
6020 1E12;LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW;Lu;0;L;0044 032D;;;;N;;;;1E13;
6021 1E13;LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW;Ll;0;L;0064 032D;;;;N;;;1E12;;1E12
6022 1E14;LATIN CAPITAL LETTER E WITH MACRON AND GRAVE;Lu;0;L;0112 0300;;;;N;;;;1E15;
6023 1E15;LATIN SMALL LETTER E WITH MACRON AND GRAVE;Ll;0;L;0113 0300;;;;N;;;1E14;;1E14
6024 1E16;LATIN CAPITAL LETTER E WITH MACRON AND ACUTE;Lu;0;L;0112 0301;;;;N;;;;1E17;
6025 1E17;LATIN SMALL LETTER E WITH MACRON AND ACUTE;Ll;0;L;0113 0301;;;;N;;;1E16;;1E16
6026 1E18;LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW;Lu;0;L;0045 032D;;;;N;;;;1E19;
6027 1E19;LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW;Ll;0;L;0065 032D;;;;N;;;1E18;;1E18
6028 1E1A;LATIN CAPITAL LETTER E WITH TILDE BELOW;Lu;0;L;0045 0330;;;;N;;;;1E1B;
6029 1E1B;LATIN SMALL LETTER E WITH TILDE BELOW;Ll;0;L;0065 0330;;;;N;;;1E1A;;1E1A
6030 1E1C;LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE;Lu;0;L;0228 0306;;;;N;;;;1E1D;
6031 1E1D;LATIN SMALL LETTER E WITH CEDILLA AND BREVE;Ll;0;L;0229 0306;;;;N;;;1E1C;;1E1C
6032 1E1E;LATIN CAPITAL LETTER F WITH DOT ABOVE;Lu;0;L;0046 0307;;;;N;;;;1E1F;
6033 1E1F;LATIN SMALL LETTER F WITH DOT ABOVE;Ll;0;L;0066 0307;;;;N;;;1E1E;;1E1E
6034 1E20;LATIN CAPITAL LETTER G WITH MACRON;Lu;0;L;0047 0304;;;;N;;;;1E21;
6035 1E21;LATIN SMALL LETTER G WITH MACRON;Ll;0;L;0067 0304;;;;N;;;1E20;;1E20
6036 1E22;LATIN CAPITAL LETTER H WITH DOT ABOVE;Lu;0;L;0048 0307;;;;N;;;;1E23;
6037 1E23;LATIN SMALL LETTER H WITH DOT ABOVE;Ll;0;L;0068 0307;;;;N;;;1E22;;1E22
6038 1E24;LATIN CAPITAL LETTER H WITH DOT BELOW;Lu;0;L;0048 0323;;;;N;;;;1E25;
6039 1E25;LATIN SMALL LETTER H WITH DOT BELOW;Ll;0;L;0068 0323;;;;N;;;1E24;;1E24
6040 1E26;LATIN CAPITAL LETTER H WITH DIAERESIS;Lu;0;L;0048 0308;;;;N;;;;1E27;
6041 1E27;LATIN SMALL LETTER H WITH DIAERESIS;Ll;0;L;0068 0308;;;;N;;;1E26;;1E26
6042 1E28;LATIN CAPITAL LETTER H WITH CEDILLA;Lu;0;L;0048 0327;;;;N;;;;1E29;
6043 1E29;LATIN SMALL LETTER H WITH CEDILLA;Ll;0;L;0068 0327;;;;N;;;1E28;;1E28
6044 1E2A;LATIN CAPITAL LETTER H WITH BREVE BELOW;Lu;0;L;0048 032E;;;;N;;;;1E2B;
6045 1E2B;LATIN SMALL LETTER H WITH BREVE BELOW;Ll;0;L;0068 032E;;;;N;;;1E2A;;1E2A
6046 1E2C;LATIN CAPITAL LETTER I WITH TILDE BELOW;Lu;0;L;0049 0330;;;;N;;;;1E2D;
6047 1E2D;LATIN SMALL LETTER I WITH TILDE BELOW;Ll;0;L;0069 0330;;;;N;;;1E2C;;1E2C
6048 1E2E;LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE;Lu;0;L;00CF 0301;;;;N;;;;1E2F;
6049 1E2F;LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE;Ll;0;L;00EF 0301;;;;N;;;1E2E;;1E2E
6050 1E30;LATIN CAPITAL LETTER K WITH ACUTE;Lu;0;L;004B 0301;;;;N;;;;1E31;
6051 1E31;LATIN SMALL LETTER K WITH ACUTE;Ll;0;L;006B 0301;;;;N;;;1E30;;1E30
6052 1E32;LATIN CAPITAL LETTER K WITH DOT BELOW;Lu;0;L;004B 0323;;;;N;;;;1E33;
6053 1E33;LATIN SMALL LETTER K WITH DOT BELOW;Ll;0;L;006B 0323;;;;N;;;1E32;;1E32
6054 1E34;LATIN CAPITAL LETTER K WITH LINE BELOW;Lu;0;L;004B 0331;;;;N;;;;1E35;
6055 1E35;LATIN SMALL LETTER K WITH LINE BELOW;Ll;0;L;006B 0331;;;;N;;;1E34;;1E34
6056 1E36;LATIN CAPITAL LETTER L WITH DOT BELOW;Lu;0;L;004C 0323;;;;N;;;;1E37;
6057 1E37;LATIN SMALL LETTER L WITH DOT BELOW;Ll;0;L;006C 0323;;;;N;;;1E36;;1E36
6058 1E38;LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON;Lu;0;L;1E36 0304;;;;N;;;;1E39;
6059 1E39;LATIN SMALL LETTER L WITH DOT BELOW AND MACRON;Ll;0;L;1E37 0304;;;;N;;;1E38;;1E38
6060 1E3A;LATIN CAPITAL LETTER L WITH LINE BELOW;Lu;0;L;004C 0331;;;;N;;;;1E3B;
6061 1E3B;LATIN SMALL LETTER L WITH LINE BELOW;Ll;0;L;006C 0331;;;;N;;;1E3A;;1E3A
6062 1E3C;LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW;Lu;0;L;004C 032D;;;;N;;;;1E3D;
6063 1E3D;LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW;Ll;0;L;006C 032D;;;;N;;;1E3C;;1E3C
6064 1E3E;LATIN CAPITAL LETTER M WITH ACUTE;Lu;0;L;004D 0301;;;;N;;;;1E3F;
6065 1E3F;LATIN SMALL LETTER M WITH ACUTE;Ll;0;L;006D 0301;;;;N;;;1E3E;;1E3E
6066 1E40;LATIN CAPITAL LETTER M WITH DOT ABOVE;Lu;0;L;004D 0307;;;;N;;;;1E41;
6067 1E41;LATIN SMALL LETTER M WITH DOT ABOVE;Ll;0;L;006D 0307;;;;N;;;1E40;;1E40
6068 1E42;LATIN CAPITAL LETTER M WITH DOT BELOW;Lu;0;L;004D 0323;;;;N;;;;1E43;
6069 1E43;LATIN SMALL LETTER M WITH DOT BELOW;Ll;0;L;006D 0323;;;;N;;;1E42;;1E42
6070 1E44;LATIN CAPITAL LETTER N WITH DOT ABOVE;Lu;0;L;004E 0307;;;;N;;;;1E45;
6071 1E45;LATIN SMALL LETTER N WITH DOT ABOVE;Ll;0;L;006E 0307;;;;N;;;1E44;;1E44
6072 1E46;LATIN CAPITAL LETTER N WITH DOT BELOW;Lu;0;L;004E 0323;;;;N;;;;1E47;
6073 1E47;LATIN SMALL LETTER N WITH DOT BELOW;Ll;0;L;006E 0323;;;;N;;;1E46;;1E46
6074 1E48;LATIN CAPITAL LETTER N WITH LINE BELOW;Lu;0;L;004E 0331;;;;N;;;;1E49;
6075 1E49;LATIN SMALL LETTER N WITH LINE BELOW;Ll;0;L;006E 0331;;;;N;;;1E48;;1E48
6076 1E4A;LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW;Lu;0;L;004E 032D;;;;N;;;;1E4B;
6077 1E4B;LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW;Ll;0;L;006E 032D;;;;N;;;1E4A;;1E4A
6078 1E4C;LATIN CAPITAL LETTER O WITH TILDE AND ACUTE;Lu;0;L;00D5 0301;;;;N;;;;1E4D;
6079 1E4D;LATIN SMALL LETTER O WITH TILDE AND ACUTE;Ll;0;L;00F5 0301;;;;N;;;1E4C;;1E4C
6080 1E4E;LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS;Lu;0;L;00D5 0308;;;;N;;;;1E4F;
6081 1E4F;LATIN SMALL LETTER O WITH TILDE AND DIAERESIS;Ll;0;L;00F5 0308;;;;N;;;1E4E;;1E4E
6082 1E50;LATIN CAPITAL LETTER O WITH MACRON AND GRAVE;Lu;0;L;014C 0300;;;;N;;;;1E51;
6083 1E51;LATIN SMALL LETTER O WITH MACRON AND GRAVE;Ll;0;L;014D 0300;;;;N;;;1E50;;1E50
6084 1E52;LATIN CAPITAL LETTER O WITH MACRON AND ACUTE;Lu;0;L;014C 0301;;;;N;;;;1E53;
6085 1E53;LATIN SMALL LETTER O WITH MACRON AND ACUTE;Ll;0;L;014D 0301;;;;N;;;1E52;;1E52
6086 1E54;LATIN CAPITAL LETTER P WITH ACUTE;Lu;0;L;0050 0301;;;;N;;;;1E55;
6087 1E55;LATIN SMALL LETTER P WITH ACUTE;Ll;0;L;0070 0301;;;;N;;;1E54;;1E54
6088 1E56;LATIN CAPITAL LETTER P WITH DOT ABOVE;Lu;0;L;0050 0307;;;;N;;;;1E57;
6089 1E57;LATIN SMALL LETTER P WITH DOT ABOVE;Ll;0;L;0070 0307;;;;N;;;1E56;;1E56
6090 1E58;LATIN CAPITAL LETTER R WITH DOT ABOVE;Lu;0;L;0052 0307;;;;N;;;;1E59;
6091 1E59;LATIN SMALL LETTER R WITH DOT ABOVE;Ll;0;L;0072 0307;;;;N;;;1E58;;1E58
6092 1E5A;LATIN CAPITAL LETTER R WITH DOT BELOW;Lu;0;L;0052 0323;;;;N;;;;1E5B;
6093 1E5B;LATIN SMALL LETTER R WITH DOT BELOW;Ll;0;L;0072 0323;;;;N;;;1E5A;;1E5A
6094 1E5C;LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON;Lu;0;L;1E5A 0304;;;;N;;;;1E5D;
6095 1E5D;LATIN SMALL LETTER R WITH DOT BELOW AND MACRON;Ll;0;L;1E5B 0304;;;;N;;;1E5C;;1E5C
6096 1E5E;LATIN CAPITAL LETTER R WITH LINE BELOW;Lu;0;L;0052 0331;;;;N;;;;1E5F;
6097 1E5F;LATIN SMALL LETTER R WITH LINE BELOW;Ll;0;L;0072 0331;;;;N;;;1E5E;;1E5E
6098 1E60;LATIN CAPITAL LETTER S WITH DOT ABOVE;Lu;0;L;0053 0307;;;;N;;;;1E61;
6099 1E61;LATIN SMALL LETTER S WITH DOT ABOVE;Ll;0;L;0073 0307;;;;N;;;1E60;;1E60
6100 1E62;LATIN CAPITAL LETTER S WITH DOT BELOW;Lu;0;L;0053 0323;;;;N;;;;1E63;
6101 1E63;LATIN SMALL LETTER S WITH DOT BELOW;Ll;0;L;0073 0323;;;;N;;;1E62;;1E62
6102 1E64;LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE;Lu;0;L;015A 0307;;;;N;;;;1E65;
6103 1E65;LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE;Ll;0;L;015B 0307;;;;N;;;1E64;;1E64
6104 1E66;LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE;Lu;0;L;0160 0307;;;;N;;;;1E67;
6105 1E67;LATIN SMALL LETTER S WITH CARON AND DOT ABOVE;Ll;0;L;0161 0307;;;;N;;;1E66;;1E66
6106 1E68;LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE;Lu;0;L;1E62 0307;;;;N;;;;1E69;
6107 1E69;LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE;Ll;0;L;1E63 0307;;;;N;;;1E68;;1E68
6108 1E6A;LATIN CAPITAL LETTER T WITH DOT ABOVE;Lu;0;L;0054 0307;;;;N;;;;1E6B;
6109 1E6B;LATIN SMALL LETTER T WITH DOT ABOVE;Ll;0;L;0074 0307;;;;N;;;1E6A;;1E6A
6110 1E6C;LATIN CAPITAL LETTER T WITH DOT BELOW;Lu;0;L;0054 0323;;;;N;;;;1E6D;
6111 1E6D;LATIN SMALL LETTER T WITH DOT BELOW;Ll;0;L;0074 0323;;;;N;;;1E6C;;1E6C
6112 1E6E;LATIN CAPITAL LETTER T WITH LINE BELOW;Lu;0;L;0054 0331;;;;N;;;;1E6F;
6113 1E6F;LATIN SMALL LETTER T WITH LINE BELOW;Ll;0;L;0074 0331;;;;N;;;1E6E;;1E6E
6114 1E70;LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW;Lu;0;L;0054 032D;;;;N;;;;1E71;
6115 1E71;LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW;Ll;0;L;0074 032D;;;;N;;;1E70;;1E70
6116 1E72;LATIN CAPITAL LETTER U WITH DIAERESIS BELOW;Lu;0;L;0055 0324;;;;N;;;;1E73;
6117 1E73;LATIN SMALL LETTER U WITH DIAERESIS BELOW;Ll;0;L;0075 0324;;;;N;;;1E72;;1E72
6118 1E74;LATIN CAPITAL LETTER U WITH TILDE BELOW;Lu;0;L;0055 0330;;;;N;;;;1E75;
6119 1E75;LATIN SMALL LETTER U WITH TILDE BELOW;Ll;0;L;0075 0330;;;;N;;;1E74;;1E74
6120 1E76;LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW;Lu;0;L;0055 032D;;;;N;;;;1E77;
6121 1E77;LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW;Ll;0;L;0075 032D;;;;N;;;1E76;;1E76
6122 1E78;LATIN CAPITAL LETTER U WITH TILDE AND ACUTE;Lu;0;L;0168 0301;;;;N;;;;1E79;
6123 1E79;LATIN SMALL LETTER U WITH TILDE AND ACUTE;Ll;0;L;0169 0301;;;;N;;;1E78;;1E78
6124 1E7A;LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS;Lu;0;L;016A 0308;;;;N;;;;1E7B;
6125 1E7B;LATIN SMALL LETTER U WITH MACRON AND DIAERESIS;Ll;0;L;016B 0308;;;;N;;;1E7A;;1E7A
6126 1E7C;LATIN CAPITAL LETTER V WITH TILDE;Lu;0;L;0056 0303;;;;N;;;;1E7D;
6127 1E7D;LATIN SMALL LETTER V WITH TILDE;Ll;0;L;0076 0303;;;;N;;;1E7C;;1E7C
6128 1E7E;LATIN CAPITAL LETTER V WITH DOT BELOW;Lu;0;L;0056 0323;;;;N;;;;1E7F;
6129 1E7F;LATIN SMALL LETTER V WITH DOT BELOW;Ll;0;L;0076 0323;;;;N;;;1E7E;;1E7E
6130 1E80;LATIN CAPITAL LETTER W WITH GRAVE;Lu;0;L;0057 0300;;;;N;;;;1E81;
6131 1E81;LATIN SMALL LETTER W WITH GRAVE;Ll;0;L;0077 0300;;;;N;;;1E80;;1E80
6132 1E82;LATIN CAPITAL LETTER W WITH ACUTE;Lu;0;L;0057 0301;;;;N;;;;1E83;
6133 1E83;LATIN SMALL LETTER W WITH ACUTE;Ll;0;L;0077 0301;;;;N;;;1E82;;1E82
6134 1E84;LATIN CAPITAL LETTER W WITH DIAERESIS;Lu;0;L;0057 0308;;;;N;;;;1E85;
6135 1E85;LATIN SMALL LETTER W WITH DIAERESIS;Ll;0;L;0077 0308;;;;N;;;1E84;;1E84
6136 1E86;LATIN CAPITAL LETTER W WITH DOT ABOVE;Lu;0;L;0057 0307;;;;N;;;;1E87;
6137 1E87;LATIN SMALL LETTER W WITH DOT ABOVE;Ll;0;L;0077 0307;;;;N;;;1E86;;1E86
6138 1E88;LATIN CAPITAL LETTER W WITH DOT BELOW;Lu;0;L;0057 0323;;;;N;;;;1E89;
6139 1E89;LATIN SMALL LETTER W WITH DOT BELOW;Ll;0;L;0077 0323;;;;N;;;1E88;;1E88
6140 1E8A;LATIN CAPITAL LETTER X WITH DOT ABOVE;Lu;0;L;0058 0307;;;;N;;;;1E8B;
6141 1E8B;LATIN SMALL LETTER X WITH DOT ABOVE;Ll;0;L;0078 0307;;;;N;;;1E8A;;1E8A
6142 1E8C;LATIN CAPITAL LETTER X WITH DIAERESIS;Lu;0;L;0058 0308;;;;N;;;;1E8D;
6143 1E8D;LATIN SMALL LETTER X WITH DIAERESIS;Ll;0;L;0078 0308;;;;N;;;1E8C;;1E8C
6144 1E8E;LATIN CAPITAL LETTER Y WITH DOT ABOVE;Lu;0;L;0059 0307;;;;N;;;;1E8F;
6145 1E8F;LATIN SMALL LETTER Y WITH DOT ABOVE;Ll;0;L;0079 0307;;;;N;;;1E8E;;1E8E
6146 1E90;LATIN CAPITAL LETTER Z WITH CIRCUMFLEX;Lu;0;L;005A 0302;;;;N;;;;1E91;
6147 1E91;LATIN SMALL LETTER Z WITH CIRCUMFLEX;Ll;0;L;007A 0302;;;;N;;;1E90;;1E90
6148 1E92;LATIN CAPITAL LETTER Z WITH DOT BELOW;Lu;0;L;005A 0323;;;;N;;;;1E93;
6149 1E93;LATIN SMALL LETTER Z WITH DOT BELOW;Ll;0;L;007A 0323;;;;N;;;1E92;;1E92
6150 1E94;LATIN CAPITAL LETTER Z WITH LINE BELOW;Lu;0;L;005A 0331;;;;N;;;;1E95;
6151 1E95;LATIN SMALL LETTER Z WITH LINE BELOW;Ll;0;L;007A 0331;;;;N;;;1E94;;1E94
6152 1E96;LATIN SMALL LETTER H WITH LINE BELOW;Ll;0;L;0068 0331;;;;N;;;;;
6153 1E97;LATIN SMALL LETTER T WITH DIAERESIS;Ll;0;L;0074 0308;;;;N;;;;;
6154 1E98;LATIN SMALL LETTER W WITH RING ABOVE;Ll;0;L;0077 030A;;;;N;;;;;
6155 1E99;LATIN SMALL LETTER Y WITH RING ABOVE;Ll;0;L;0079 030A;;;;N;;;;;
6156 1E9A;LATIN SMALL LETTER A WITH RIGHT HALF RING;Ll;0;L;<compat> 0061 02BE;;;;N;;;;;
6157 1E9B;LATIN SMALL LETTER LONG S WITH DOT ABOVE;Ll;0;L;017F 0307;;;;N;;;1E60;;1E60
6158 1E9C;LATIN SMALL LETTER LONG S WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;;;
6159 1E9D;LATIN SMALL LETTER LONG S WITH HIGH STROKE;Ll;0;L;;;;;N;;;;;
6160 1E9E;LATIN CAPITAL LETTER SHARP S;Lu;0;L;;;;;N;;;;00DF;
6161 1E9F;LATIN SMALL LETTER DELTA;Ll;0;L;;;;;N;;;;;
6162 1EA0;LATIN CAPITAL LETTER A WITH DOT BELOW;Lu;0;L;0041 0323;;;;N;;;;1EA1;
6163 1EA1;LATIN SMALL LETTER A WITH DOT BELOW;Ll;0;L;0061 0323;;;;N;;;1EA0;;1EA0
6164 1EA2;LATIN CAPITAL LETTER A WITH HOOK ABOVE;Lu;0;L;0041 0309;;;;N;;;;1EA3;
6165 1EA3;LATIN SMALL LETTER A WITH HOOK ABOVE;Ll;0;L;0061 0309;;;;N;;;1EA2;;1EA2
6166 1EA4;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00C2 0301;;;;N;;;;1EA5;
6167 1EA5;LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00E2 0301;;;;N;;;1EA4;;1EA4
6168 1EA6;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00C2 0300;;;;N;;;;1EA7;
6169 1EA7;LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00E2 0300;;;;N;;;1EA6;;1EA6
6170 1EA8;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00C2 0309;;;;N;;;;1EA9;
6171 1EA9;LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00E2 0309;;;;N;;;1EA8;;1EA8
6172 1EAA;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE;Lu;0;L;00C2 0303;;;;N;;;;1EAB;
6173 1EAB;LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE;Ll;0;L;00E2 0303;;;;N;;;1EAA;;1EAA
6174 1EAC;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EA0 0302;;;;N;;;;1EAD;
6175 1EAD;LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EA1 0302;;;;N;;;1EAC;;1EAC
6176 1EAE;LATIN CAPITAL LETTER A WITH BREVE AND ACUTE;Lu;0;L;0102 0301;;;;N;;;;1EAF;
6177 1EAF;LATIN SMALL LETTER A WITH BREVE AND ACUTE;Ll;0;L;0103 0301;;;;N;;;1EAE;;1EAE
6178 1EB0;LATIN CAPITAL LETTER A WITH BREVE AND GRAVE;Lu;0;L;0102 0300;;;;N;;;;1EB1;
6179 1EB1;LATIN SMALL LETTER A WITH BREVE AND GRAVE;Ll;0;L;0103 0300;;;;N;;;1EB0;;1EB0
6180 1EB2;LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE;Lu;0;L;0102 0309;;;;N;;;;1EB3;
6181 1EB3;LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE;Ll;0;L;0103 0309;;;;N;;;1EB2;;1EB2
6182 1EB4;LATIN CAPITAL LETTER A WITH BREVE AND TILDE;Lu;0;L;0102 0303;;;;N;;;;1EB5;
6183 1EB5;LATIN SMALL LETTER A WITH BREVE AND TILDE;Ll;0;L;0103 0303;;;;N;;;1EB4;;1EB4
6184 1EB6;LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW;Lu;0;L;1EA0 0306;;;;N;;;;1EB7;
6185 1EB7;LATIN SMALL LETTER A WITH BREVE AND DOT BELOW;Ll;0;L;1EA1 0306;;;;N;;;1EB6;;1EB6
6186 1EB8;LATIN CAPITAL LETTER E WITH DOT BELOW;Lu;0;L;0045 0323;;;;N;;;;1EB9;
6187 1EB9;LATIN SMALL LETTER E WITH DOT BELOW;Ll;0;L;0065 0323;;;;N;;;1EB8;;1EB8
6188 1EBA;LATIN CAPITAL LETTER E WITH HOOK ABOVE;Lu;0;L;0045 0309;;;;N;;;;1EBB;
6189 1EBB;LATIN SMALL LETTER E WITH HOOK ABOVE;Ll;0;L;0065 0309;;;;N;;;1EBA;;1EBA
6190 1EBC;LATIN CAPITAL LETTER E WITH TILDE;Lu;0;L;0045 0303;;;;N;;;;1EBD;
6191 1EBD;LATIN SMALL LETTER E WITH TILDE;Ll;0;L;0065 0303;;;;N;;;1EBC;;1EBC
6192 1EBE;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00CA 0301;;;;N;;;;1EBF;
6193 1EBF;LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00EA 0301;;;;N;;;1EBE;;1EBE
6194 1EC0;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00CA 0300;;;;N;;;;1EC1;
6195 1EC1;LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00EA 0300;;;;N;;;1EC0;;1EC0
6196 1EC2;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00CA 0309;;;;N;;;;1EC3;
6197 1EC3;LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00EA 0309;;;;N;;;1EC2;;1EC2
6198 1EC4;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE;Lu;0;L;00CA 0303;;;;N;;;;1EC5;
6199 1EC5;LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE;Ll;0;L;00EA 0303;;;;N;;;1EC4;;1EC4
6200 1EC6;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EB8 0302;;;;N;;;;1EC7;
6201 1EC7;LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EB9 0302;;;;N;;;1EC6;;1EC6
6202 1EC8;LATIN CAPITAL LETTER I WITH HOOK ABOVE;Lu;0;L;0049 0309;;;;N;;;;1EC9;
6203 1EC9;LATIN SMALL LETTER I WITH HOOK ABOVE;Ll;0;L;0069 0309;;;;N;;;1EC8;;1EC8
6204 1ECA;LATIN CAPITAL LETTER I WITH DOT BELOW;Lu;0;L;0049 0323;;;;N;;;;1ECB;
6205 1ECB;LATIN SMALL LETTER I WITH DOT BELOW;Ll;0;L;0069 0323;;;;N;;;1ECA;;1ECA
6206 1ECC;LATIN CAPITAL LETTER O WITH DOT BELOW;Lu;0;L;004F 0323;;;;N;;;;1ECD;
6207 1ECD;LATIN SMALL LETTER O WITH DOT BELOW;Ll;0;L;006F 0323;;;;N;;;1ECC;;1ECC
6208 1ECE;LATIN CAPITAL LETTER O WITH HOOK ABOVE;Lu;0;L;004F 0309;;;;N;;;;1ECF;
6209 1ECF;LATIN SMALL LETTER O WITH HOOK ABOVE;Ll;0;L;006F 0309;;;;N;;;1ECE;;1ECE
6210 1ED0;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00D4 0301;;;;N;;;;1ED1;
6211 1ED1;LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00F4 0301;;;;N;;;1ED0;;1ED0
6212 1ED2;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00D4 0300;;;;N;;;;1ED3;
6213 1ED3;LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00F4 0300;;;;N;;;1ED2;;1ED2
6214 1ED4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00D4 0309;;;;N;;;;1ED5;
6215 1ED5;LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00F4 0309;;;;N;;;1ED4;;1ED4
6216 1ED6;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE;Lu;0;L;00D4 0303;;;;N;;;;1ED7;
6217 1ED7;LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE;Ll;0;L;00F4 0303;;;;N;;;1ED6;;1ED6
6218 1ED8;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1ECC 0302;;;;N;;;;1ED9;
6219 1ED9;LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1ECD 0302;;;;N;;;1ED8;;1ED8
6220 1EDA;LATIN CAPITAL LETTER O WITH HORN AND ACUTE;Lu;0;L;01A0 0301;;;;N;;;;1EDB;
6221 1EDB;LATIN SMALL LETTER O WITH HORN AND ACUTE;Ll;0;L;01A1 0301;;;;N;;;1EDA;;1EDA
6222 1EDC;LATIN CAPITAL LETTER O WITH HORN AND GRAVE;Lu;0;L;01A0 0300;;;;N;;;;1EDD;
6223 1EDD;LATIN SMALL LETTER O WITH HORN AND GRAVE;Ll;0;L;01A1 0300;;;;N;;;1EDC;;1EDC
6224 1EDE;LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE;Lu;0;L;01A0 0309;;;;N;;;;1EDF;
6225 1EDF;LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE;Ll;0;L;01A1 0309;;;;N;;;1EDE;;1EDE
6226 1EE0;LATIN CAPITAL LETTER O WITH HORN AND TILDE;Lu;0;L;01A0 0303;;;;N;;;;1EE1;
6227 1EE1;LATIN SMALL LETTER O WITH HORN AND TILDE;Ll;0;L;01A1 0303;;;;N;;;1EE0;;1EE0
6228 1EE2;LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW;Lu;0;L;01A0 0323;;;;N;;;;1EE3;
6229 1EE3;LATIN SMALL LETTER O WITH HORN AND DOT BELOW;Ll;0;L;01A1 0323;;;;N;;;1EE2;;1EE2
6230 1EE4;LATIN CAPITAL LETTER U WITH DOT BELOW;Lu;0;L;0055 0323;;;;N;;;;1EE5;
6231 1EE5;LATIN SMALL LETTER U WITH DOT BELOW;Ll;0;L;0075 0323;;;;N;;;1EE4;;1EE4
6232 1EE6;LATIN CAPITAL LETTER U WITH HOOK ABOVE;Lu;0;L;0055 0309;;;;N;;;;1EE7;
6233 1EE7;LATIN SMALL LETTER U WITH HOOK ABOVE;Ll;0;L;0075 0309;;;;N;;;1EE6;;1EE6
6234 1EE8;LATIN CAPITAL LETTER U WITH HORN AND ACUTE;Lu;0;L;01AF 0301;;;;N;;;;1EE9;
6235 1EE9;LATIN SMALL LETTER U WITH HORN AND ACUTE;Ll;0;L;01B0 0301;;;;N;;;1EE8;;1EE8
6236 1EEA;LATIN CAPITAL LETTER U WITH HORN AND GRAVE;Lu;0;L;01AF 0300;;;;N;;;;1EEB;
6237 1EEB;LATIN SMALL LETTER U WITH HORN AND GRAVE;Ll;0;L;01B0 0300;;;;N;;;1EEA;;1EEA
6238 1EEC;LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE;Lu;0;L;01AF 0309;;;;N;;;;1EED;
6239 1EED;LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE;Ll;0;L;01B0 0309;;;;N;;;1EEC;;1EEC
6240 1EEE;LATIN CAPITAL LETTER U WITH HORN AND TILDE;Lu;0;L;01AF 0303;;;;N;;;;1EEF;
6241 1EEF;LATIN SMALL LETTER U WITH HORN AND TILDE;Ll;0;L;01B0 0303;;;;N;;;1EEE;;1EEE
6242 1EF0;LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW;Lu;0;L;01AF 0323;;;;N;;;;1EF1;
6243 1EF1;LATIN SMALL LETTER U WITH HORN AND DOT BELOW;Ll;0;L;01B0 0323;;;;N;;;1EF0;;1EF0
6244 1EF2;LATIN CAPITAL LETTER Y WITH GRAVE;Lu;0;L;0059 0300;;;;N;;;;1EF3;
6245 1EF3;LATIN SMALL LETTER Y WITH GRAVE;Ll;0;L;0079 0300;;;;N;;;1EF2;;1EF2
6246 1EF4;LATIN CAPITAL LETTER Y WITH DOT BELOW;Lu;0;L;0059 0323;;;;N;;;;1EF5;
6247 1EF5;LATIN SMALL LETTER Y WITH DOT BELOW;Ll;0;L;0079 0323;;;;N;;;1EF4;;1EF4
6248 1EF6;LATIN CAPITAL LETTER Y WITH HOOK ABOVE;Lu;0;L;0059 0309;;;;N;;;;1EF7;
6249 1EF7;LATIN SMALL LETTER Y WITH HOOK ABOVE;Ll;0;L;0079 0309;;;;N;;;1EF6;;1EF6
6250 1EF8;LATIN CAPITAL LETTER Y WITH TILDE;Lu;0;L;0059 0303;;;;N;;;;1EF9;
6251 1EF9;LATIN SMALL LETTER Y WITH TILDE;Ll;0;L;0079 0303;;;;N;;;1EF8;;1EF8
6252 1EFA;LATIN CAPITAL LETTER MIDDLE-WELSH LL;Lu;0;L;;;;;N;;;;1EFB;
6253 1EFB;LATIN SMALL LETTER MIDDLE-WELSH LL;Ll;0;L;;;;;N;;;1EFA;;1EFA
6254 1EFC;LATIN CAPITAL LETTER MIDDLE-WELSH V;Lu;0;L;;;;;N;;;;1EFD;
6255 1EFD;LATIN SMALL LETTER MIDDLE-WELSH V;Ll;0;L;;;;;N;;;1EFC;;1EFC
6256 1EFE;LATIN CAPITAL LETTER Y WITH LOOP;Lu;0;L;;;;;N;;;;1EFF;
6257 1EFF;LATIN SMALL LETTER Y WITH LOOP;Ll;0;L;;;;;N;;;1EFE;;1EFE
6258 1F00;GREEK SMALL LETTER ALPHA WITH PSILI;Ll;0;L;03B1 0313;;;;N;;;1F08;;1F08
6259 1F01;GREEK SMALL LETTER ALPHA WITH DASIA;Ll;0;L;03B1 0314;;;;N;;;1F09;;1F09
6260 1F02;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA;Ll;0;L;1F00 0300;;;;N;;;1F0A;;1F0A
6261 1F03;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA;Ll;0;L;1F01 0300;;;;N;;;1F0B;;1F0B
6262 1F04;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA;Ll;0;L;1F00 0301;;;;N;;;1F0C;;1F0C
6263 1F05;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA;Ll;0;L;1F01 0301;;;;N;;;1F0D;;1F0D
6264 1F06;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI;Ll;0;L;1F00 0342;;;;N;;;1F0E;;1F0E
6265 1F07;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI;Ll;0;L;1F01 0342;;;;N;;;1F0F;;1F0F
6266 1F08;GREEK CAPITAL LETTER ALPHA WITH PSILI;Lu;0;L;0391 0313;;;;N;;;;1F00;
6267 1F09;GREEK CAPITAL LETTER ALPHA WITH DASIA;Lu;0;L;0391 0314;;;;N;;;;1F01;
6268 1F0A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA;Lu;0;L;1F08 0300;;;;N;;;;1F02;
6269 1F0B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA;Lu;0;L;1F09 0300;;;;N;;;;1F03;
6270 1F0C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA;Lu;0;L;1F08 0301;;;;N;;;;1F04;
6271 1F0D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA;Lu;0;L;1F09 0301;;;;N;;;;1F05;
6272 1F0E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI;Lu;0;L;1F08 0342;;;;N;;;;1F06;
6273 1F0F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI;Lu;0;L;1F09 0342;;;;N;;;;1F07;
6274 1F10;GREEK SMALL LETTER EPSILON WITH PSILI;Ll;0;L;03B5 0313;;;;N;;;1F18;;1F18
6275 1F11;GREEK SMALL LETTER EPSILON WITH DASIA;Ll;0;L;03B5 0314;;;;N;;;1F19;;1F19
6276 1F12;GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA;Ll;0;L;1F10 0300;;;;N;;;1F1A;;1F1A
6277 1F13;GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA;Ll;0;L;1F11 0300;;;;N;;;1F1B;;1F1B
6278 1F14;GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA;Ll;0;L;1F10 0301;;;;N;;;1F1C;;1F1C
6279 1F15;GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA;Ll;0;L;1F11 0301;;;;N;;;1F1D;;1F1D
6280 1F18;GREEK CAPITAL LETTER EPSILON WITH PSILI;Lu;0;L;0395 0313;;;;N;;;;1F10;
6281 1F19;GREEK CAPITAL LETTER EPSILON WITH DASIA;Lu;0;L;0395 0314;;;;N;;;;1F11;
6282 1F1A;GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA;Lu;0;L;1F18 0300;;;;N;;;;1F12;
6283 1F1B;GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA;Lu;0;L;1F19 0300;;;;N;;;;1F13;
6284 1F1C;GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA;Lu;0;L;1F18 0301;;;;N;;;;1F14;
6285 1F1D;GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA;Lu;0;L;1F19 0301;;;;N;;;;1F15;
6286 1F20;GREEK SMALL LETTER ETA WITH PSILI;Ll;0;L;03B7 0313;;;;N;;;1F28;;1F28
6287 1F21;GREEK SMALL LETTER ETA WITH DASIA;Ll;0;L;03B7 0314;;;;N;;;1F29;;1F29
6288 1F22;GREEK SMALL LETTER ETA WITH PSILI AND VARIA;Ll;0;L;1F20 0300;;;;N;;;1F2A;;1F2A
6289 1F23;GREEK SMALL LETTER ETA WITH DASIA AND VARIA;Ll;0;L;1F21 0300;;;;N;;;1F2B;;1F2B
6290 1F24;GREEK SMALL LETTER ETA WITH PSILI AND OXIA;Ll;0;L;1F20 0301;;;;N;;;1F2C;;1F2C
6291 1F25;GREEK SMALL LETTER ETA WITH DASIA AND OXIA;Ll;0;L;1F21 0301;;;;N;;;1F2D;;1F2D
6292 1F26;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI;Ll;0;L;1F20 0342;;;;N;;;1F2E;;1F2E
6293 1F27;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI;Ll;0;L;1F21 0342;;;;N;;;1F2F;;1F2F
6294 1F28;GREEK CAPITAL LETTER ETA WITH PSILI;Lu;0;L;0397 0313;;;;N;;;;1F20;
6295 1F29;GREEK CAPITAL LETTER ETA WITH DASIA;Lu;0;L;0397 0314;;;;N;;;;1F21;
6296 1F2A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA;Lu;0;L;1F28 0300;;;;N;;;;1F22;
6297 1F2B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA;Lu;0;L;1F29 0300;;;;N;;;;1F23;
6298 1F2C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA;Lu;0;L;1F28 0301;;;;N;;;;1F24;
6299 1F2D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA;Lu;0;L;1F29 0301;;;;N;;;;1F25;
6300 1F2E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI;Lu;0;L;1F28 0342;;;;N;;;;1F26;
6301 1F2F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI;Lu;0;L;1F29 0342;;;;N;;;;1F27;
6302 1F30;GREEK SMALL LETTER IOTA WITH PSILI;Ll;0;L;03B9 0313;;;;N;;;1F38;;1F38
6303 1F31;GREEK SMALL LETTER IOTA WITH DASIA;Ll;0;L;03B9 0314;;;;N;;;1F39;;1F39
6304 1F32;GREEK SMALL LETTER IOTA WITH PSILI AND VARIA;Ll;0;L;1F30 0300;;;;N;;;1F3A;;1F3A
6305 1F33;GREEK SMALL LETTER IOTA WITH DASIA AND VARIA;Ll;0;L;1F31 0300;;;;N;;;1F3B;;1F3B
6306 1F34;GREEK SMALL LETTER IOTA WITH PSILI AND OXIA;Ll;0;L;1F30 0301;;;;N;;;1F3C;;1F3C
6307 1F35;GREEK SMALL LETTER IOTA WITH DASIA AND OXIA;Ll;0;L;1F31 0301;;;;N;;;1F3D;;1F3D
6308 1F36;GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI;Ll;0;L;1F30 0342;;;;N;;;1F3E;;1F3E
6309 1F37;GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI;Ll;0;L;1F31 0342;;;;N;;;1F3F;;1F3F
6310 1F38;GREEK CAPITAL LETTER IOTA WITH PSILI;Lu;0;L;0399 0313;;;;N;;;;1F30;
6311 1F39;GREEK CAPITAL LETTER IOTA WITH DASIA;Lu;0;L;0399 0314;;;;N;;;;1F31;
6312 1F3A;GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA;Lu;0;L;1F38 0300;;;;N;;;;1F32;
6313 1F3B;GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA;Lu;0;L;1F39 0300;;;;N;;;;1F33;
6314 1F3C;GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA;Lu;0;L;1F38 0301;;;;N;;;;1F34;
6315 1F3D;GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA;Lu;0;L;1F39 0301;;;;N;;;;1F35;
6316 1F3E;GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI;Lu;0;L;1F38 0342;;;;N;;;;1F36;
6317 1F3F;GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI;Lu;0;L;1F39 0342;;;;N;;;;1F37;
6318 1F40;GREEK SMALL LETTER OMICRON WITH PSILI;Ll;0;L;03BF 0313;;;;N;;;1F48;;1F48
6319 1F41;GREEK SMALL LETTER OMICRON WITH DASIA;Ll;0;L;03BF 0314;;;;N;;;1F49;;1F49
6320 1F42;GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA;Ll;0;L;1F40 0300;;;;N;;;1F4A;;1F4A
6321 1F43;GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA;Ll;0;L;1F41 0300;;;;N;;;1F4B;;1F4B
6322 1F44;GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA;Ll;0;L;1F40 0301;;;;N;;;1F4C;;1F4C
6323 1F45;GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA;Ll;0;L;1F41 0301;;;;N;;;1F4D;;1F4D
6324 1F48;GREEK CAPITAL LETTER OMICRON WITH PSILI;Lu;0;L;039F 0313;;;;N;;;;1F40;
6325 1F49;GREEK CAPITAL LETTER OMICRON WITH DASIA;Lu;0;L;039F 0314;;;;N;;;;1F41;
6326 1F4A;GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA;Lu;0;L;1F48 0300;;;;N;;;;1F42;
6327 1F4B;GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA;Lu;0;L;1F49 0300;;;;N;;;;1F43;
6328 1F4C;GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA;Lu;0;L;1F48 0301;;;;N;;;;1F44;
6329 1F4D;GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA;Lu;0;L;1F49 0301;;;;N;;;;1F45;
6330 1F50;GREEK SMALL LETTER UPSILON WITH PSILI;Ll;0;L;03C5 0313;;;;N;;;;;
6331 1F51;GREEK SMALL LETTER UPSILON WITH DASIA;Ll;0;L;03C5 0314;;;;N;;;1F59;;1F59
6332 1F52;GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA;Ll;0;L;1F50 0300;;;;N;;;;;
6333 1F53;GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA;Ll;0;L;1F51 0300;;;;N;;;1F5B;;1F5B
6334 1F54;GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA;Ll;0;L;1F50 0301;;;;N;;;;;
6335 1F55;GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA;Ll;0;L;1F51 0301;;;;N;;;1F5D;;1F5D
6336 1F56;GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI;Ll;0;L;1F50 0342;;;;N;;;;;
6337 1F57;GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI;Ll;0;L;1F51 0342;;;;N;;;1F5F;;1F5F
6338 1F59;GREEK CAPITAL LETTER UPSILON WITH DASIA;Lu;0;L;03A5 0314;;;;N;;;;1F51;
6339 1F5B;GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA;Lu;0;L;1F59 0300;;;;N;;;;1F53;
6340 1F5D;GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA;Lu;0;L;1F59 0301;;;;N;;;;1F55;
6341 1F5F;GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI;Lu;0;L;1F59 0342;;;;N;;;;1F57;
6342 1F60;GREEK SMALL LETTER OMEGA WITH PSILI;Ll;0;L;03C9 0313;;;;N;;;1F68;;1F68
6343 1F61;GREEK SMALL LETTER OMEGA WITH DASIA;Ll;0;L;03C9 0314;;;;N;;;1F69;;1F69
6344 1F62;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA;Ll;0;L;1F60 0300;;;;N;;;1F6A;;1F6A
6345 1F63;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA;Ll;0;L;1F61 0300;;;;N;;;1F6B;;1F6B
6346 1F64;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA;Ll;0;L;1F60 0301;;;;N;;;1F6C;;1F6C
6347 1F65;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA;Ll;0;L;1F61 0301;;;;N;;;1F6D;;1F6D
6348 1F66;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI;Ll;0;L;1F60 0342;;;;N;;;1F6E;;1F6E
6349 1F67;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI;Ll;0;L;1F61 0342;;;;N;;;1F6F;;1F6F
6350 1F68;GREEK CAPITAL LETTER OMEGA WITH PSILI;Lu;0;L;03A9 0313;;;;N;;;;1F60;
6351 1F69;GREEK CAPITAL LETTER OMEGA WITH DASIA;Lu;0;L;03A9 0314;;;;N;;;;1F61;
6352 1F6A;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA;Lu;0;L;1F68 0300;;;;N;;;;1F62;
6353 1F6B;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA;Lu;0;L;1F69 0300;;;;N;;;;1F63;
6354 1F6C;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA;Lu;0;L;1F68 0301;;;;N;;;;1F64;
6355 1F6D;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA;Lu;0;L;1F69 0301;;;;N;;;;1F65;
6356 1F6E;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI;Lu;0;L;1F68 0342;;;;N;;;;1F66;
6357 1F6F;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI;Lu;0;L;1F69 0342;;;;N;;;;1F67;
6358 1F70;GREEK SMALL LETTER ALPHA WITH VARIA;Ll;0;L;03B1 0300;;;;N;;;1FBA;;1FBA
6359 1F71;GREEK SMALL LETTER ALPHA WITH OXIA;Ll;0;L;03AC;;;;N;;;1FBB;;1FBB
6360 1F72;GREEK SMALL LETTER EPSILON WITH VARIA;Ll;0;L;03B5 0300;;;;N;;;1FC8;;1FC8
6361 1F73;GREEK SMALL LETTER EPSILON WITH OXIA;Ll;0;L;03AD;;;;N;;;1FC9;;1FC9
6362 1F74;GREEK SMALL LETTER ETA WITH VARIA;Ll;0;L;03B7 0300;;;;N;;;1FCA;;1FCA
6363 1F75;GREEK SMALL LETTER ETA WITH OXIA;Ll;0;L;03AE;;;;N;;;1FCB;;1FCB
6364 1F76;GREEK SMALL LETTER IOTA WITH VARIA;Ll;0;L;03B9 0300;;;;N;;;1FDA;;1FDA
6365 1F77;GREEK SMALL LETTER IOTA WITH OXIA;Ll;0;L;03AF;;;;N;;;1FDB;;1FDB
6366 1F78;GREEK SMALL LETTER OMICRON WITH VARIA;Ll;0;L;03BF 0300;;;;N;;;1FF8;;1FF8
6367 1F79;GREEK SMALL LETTER OMICRON WITH OXIA;Ll;0;L;03CC;;;;N;;;1FF9;;1FF9
6368 1F7A;GREEK SMALL LETTER UPSILON WITH VARIA;Ll;0;L;03C5 0300;;;;N;;;1FEA;;1FEA
6369 1F7B;GREEK SMALL LETTER UPSILON WITH OXIA;Ll;0;L;03CD;;;;N;;;1FEB;;1FEB
6370 1F7C;GREEK SMALL LETTER OMEGA WITH VARIA;Ll;0;L;03C9 0300;;;;N;;;1FFA;;1FFA
6371 1F7D;GREEK SMALL LETTER OMEGA WITH OXIA;Ll;0;L;03CE;;;;N;;;1FFB;;1FFB
6372 1F80;GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F00 0345;;;;N;;;1F88;;1F88
6373 1F81;GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F01 0345;;;;N;;;1F89;;1F89
6374 1F82;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F02 0345;;;;N;;;1F8A;;1F8A
6375 1F83;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F03 0345;;;;N;;;1F8B;;1F8B
6376 1F84;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F04 0345;;;;N;;;1F8C;;1F8C
6377 1F85;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F05 0345;;;;N;;;1F8D;;1F8D
6378 1F86;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F06 0345;;;;N;;;1F8E;;1F8E
6379 1F87;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F07 0345;;;;N;;;1F8F;;1F8F
6380 1F88;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F08 0345;;;;N;;;;1F80;
6381 1F89;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F09 0345;;;;N;;;;1F81;
6382 1F8A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0A 0345;;;;N;;;;1F82;
6383 1F8B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0B 0345;;;;N;;;;1F83;
6384 1F8C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0C 0345;;;;N;;;;1F84;
6385 1F8D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0D 0345;;;;N;;;;1F85;
6386 1F8E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0E 0345;;;;N;;;;1F86;
6387 1F8F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0F 0345;;;;N;;;;1F87;
6388 1F90;GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F20 0345;;;;N;;;1F98;;1F98
6389 1F91;GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F21 0345;;;;N;;;1F99;;1F99
6390 1F92;GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F22 0345;;;;N;;;1F9A;;1F9A
6391 1F93;GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F23 0345;;;;N;;;1F9B;;1F9B
6392 1F94;GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F24 0345;;;;N;;;1F9C;;1F9C
6393 1F95;GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F25 0345;;;;N;;;1F9D;;1F9D
6394 1F96;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F26 0345;;;;N;;;1F9E;;1F9E
6395 1F97;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F27 0345;;;;N;;;1F9F;;1F9F
6396 1F98;GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F28 0345;;;;N;;;;1F90;
6397 1F99;GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F29 0345;;;;N;;;;1F91;
6398 1F9A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2A 0345;;;;N;;;;1F92;
6399 1F9B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2B 0345;;;;N;;;;1F93;
6400 1F9C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2C 0345;;;;N;;;;1F94;
6401 1F9D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2D 0345;;;;N;;;;1F95;
6402 1F9E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2E 0345;;;;N;;;;1F96;
6403 1F9F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2F 0345;;;;N;;;;1F97;
6404 1FA0;GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F60 0345;;;;N;;;1FA8;;1FA8
6405 1FA1;GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F61 0345;;;;N;;;1FA9;;1FA9
6406 1FA2;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F62 0345;;;;N;;;1FAA;;1FAA
6407 1FA3;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F63 0345;;;;N;;;1FAB;;1FAB
6408 1FA4;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F64 0345;;;;N;;;1FAC;;1FAC
6409 1FA5;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F65 0345;;;;N;;;1FAD;;1FAD
6410 1FA6;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F66 0345;;;;N;;;1FAE;;1FAE
6411 1FA7;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F67 0345;;;;N;;;1FAF;;1FAF
6412 1FA8;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F68 0345;;;;N;;;;1FA0;
6413 1FA9;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F69 0345;;;;N;;;;1FA1;
6414 1FAA;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6A 0345;;;;N;;;;1FA2;
6415 1FAB;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6B 0345;;;;N;;;;1FA3;
6416 1FAC;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6C 0345;;;;N;;;;1FA4;
6417 1FAD;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6D 0345;;;;N;;;;1FA5;
6418 1FAE;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6E 0345;;;;N;;;;1FA6;
6419 1FAF;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6F 0345;;;;N;;;;1FA7;
6420 1FB0;GREEK SMALL LETTER ALPHA WITH VRACHY;Ll;0;L;03B1 0306;;;;N;;;1FB8;;1FB8
6421 1FB1;GREEK SMALL LETTER ALPHA WITH MACRON;Ll;0;L;03B1 0304;;;;N;;;1FB9;;1FB9
6422 1FB2;GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F70 0345;;;;N;;;;;
6423 1FB3;GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI;Ll;0;L;03B1 0345;;;;N;;;1FBC;;1FBC
6424 1FB4;GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AC 0345;;;;N;;;;;
6425 1FB6;GREEK SMALL LETTER ALPHA WITH PERISPOMENI;Ll;0;L;03B1 0342;;;;N;;;;;
6426 1FB7;GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FB6 0345;;;;N;;;;;
6427 1FB8;GREEK CAPITAL LETTER ALPHA WITH VRACHY;Lu;0;L;0391 0306;;;;N;;;;1FB0;
6428 1FB9;GREEK CAPITAL LETTER ALPHA WITH MACRON;Lu;0;L;0391 0304;;;;N;;;;1FB1;
6429 1FBA;GREEK CAPITAL LETTER ALPHA WITH VARIA;Lu;0;L;0391 0300;;;;N;;;;1F70;
6430 1FBB;GREEK CAPITAL LETTER ALPHA WITH OXIA;Lu;0;L;0386;;;;N;;;;1F71;
6431 1FBC;GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI;Lt;0;L;0391 0345;;;;N;;;;1FB3;
6432 1FBD;GREEK KORONIS;Sk;0;ON;<compat> 0020 0313;;;;N;;;;;
6433 1FBE;GREEK PROSGEGRAMMENI;Ll;0;L;03B9;;;;N;;;0399;;0399
6434 1FBF;GREEK PSILI;Sk;0;ON;<compat> 0020 0313;;;;N;;;;;
6435 1FC0;GREEK PERISPOMENI;Sk;0;ON;<compat> 0020 0342;;;;N;;;;;
6436 1FC1;GREEK DIALYTIKA AND PERISPOMENI;Sk;0;ON;00A8 0342;;;;N;;;;;
6437 1FC2;GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F74 0345;;;;N;;;;;
6438 1FC3;GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI;Ll;0;L;03B7 0345;;;;N;;;1FCC;;1FCC
6439 1FC4;GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AE 0345;;;;N;;;;;
6440 1FC6;GREEK SMALL LETTER ETA WITH PERISPOMENI;Ll;0;L;03B7 0342;;;;N;;;;;
6441 1FC7;GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FC6 0345;;;;N;;;;;
6442 1FC8;GREEK CAPITAL LETTER EPSILON WITH VARIA;Lu;0;L;0395 0300;;;;N;;;;1F72;
6443 1FC9;GREEK CAPITAL LETTER EPSILON WITH OXIA;Lu;0;L;0388;;;;N;;;;1F73;
6444 1FCA;GREEK CAPITAL LETTER ETA WITH VARIA;Lu;0;L;0397 0300;;;;N;;;;1F74;
6445 1FCB;GREEK CAPITAL LETTER ETA WITH OXIA;Lu;0;L;0389;;;;N;;;;1F75;
6446 1FCC;GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI;Lt;0;L;0397 0345;;;;N;;;;1FC3;
6447 1FCD;GREEK PSILI AND VARIA;Sk;0;ON;1FBF 0300;;;;N;;;;;
6448 1FCE;GREEK PSILI AND OXIA;Sk;0;ON;1FBF 0301;;;;N;;;;;
6449 1FCF;GREEK PSILI AND PERISPOMENI;Sk;0;ON;1FBF 0342;;;;N;;;;;
6450 1FD0;GREEK SMALL LETTER IOTA WITH VRACHY;Ll;0;L;03B9 0306;;;;N;;;1FD8;;1FD8
6451 1FD1;GREEK SMALL LETTER IOTA WITH MACRON;Ll;0;L;03B9 0304;;;;N;;;1FD9;;1FD9
6452 1FD2;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA;Ll;0;L;03CA 0300;;;;N;;;;;
6453 1FD3;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA;Ll;0;L;0390;;;;N;;;;;
6454 1FD6;GREEK SMALL LETTER IOTA WITH PERISPOMENI;Ll;0;L;03B9 0342;;;;N;;;;;
6455 1FD7;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CA 0342;;;;N;;;;;
6456 1FD8;GREEK CAPITAL LETTER IOTA WITH VRACHY;Lu;0;L;0399 0306;;;;N;;;;1FD0;
6457 1FD9;GREEK CAPITAL LETTER IOTA WITH MACRON;Lu;0;L;0399 0304;;;;N;;;;1FD1;
6458 1FDA;GREEK CAPITAL LETTER IOTA WITH VARIA;Lu;0;L;0399 0300;;;;N;;;;1F76;
6459 1FDB;GREEK CAPITAL LETTER IOTA WITH OXIA;Lu;0;L;038A;;;;N;;;;1F77;
6460 1FDD;GREEK DASIA AND VARIA;Sk;0;ON;1FFE 0300;;;;N;;;;;
6461 1FDE;GREEK DASIA AND OXIA;Sk;0;ON;1FFE 0301;;;;N;;;;;
6462 1FDF;GREEK DASIA AND PERISPOMENI;Sk;0;ON;1FFE 0342;;;;N;;;;;
6463 1FE0;GREEK SMALL LETTER UPSILON WITH VRACHY;Ll;0;L;03C5 0306;;;;N;;;1FE8;;1FE8
6464 1FE1;GREEK SMALL LETTER UPSILON WITH MACRON;Ll;0;L;03C5 0304;;;;N;;;1FE9;;1FE9
6465 1FE2;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA;Ll;0;L;03CB 0300;;;;N;;;;;
6466 1FE3;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA;Ll;0;L;03B0;;;;N;;;;;
6467 1FE4;GREEK SMALL LETTER RHO WITH PSILI;Ll;0;L;03C1 0313;;;;N;;;;;
6468 1FE5;GREEK SMALL LETTER RHO WITH DASIA;Ll;0;L;03C1 0314;;;;N;;;1FEC;;1FEC
6469 1FE6;GREEK SMALL LETTER UPSILON WITH PERISPOMENI;Ll;0;L;03C5 0342;;;;N;;;;;
6470 1FE7;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CB 0342;;;;N;;;;;
6471 1FE8;GREEK CAPITAL LETTER UPSILON WITH VRACHY;Lu;0;L;03A5 0306;;;;N;;;;1FE0;
6472 1FE9;GREEK CAPITAL LETTER UPSILON WITH MACRON;Lu;0;L;03A5 0304;;;;N;;;;1FE1;
6473 1FEA;GREEK CAPITAL LETTER UPSILON WITH VARIA;Lu;0;L;03A5 0300;;;;N;;;;1F7A;
6474 1FEB;GREEK CAPITAL LETTER UPSILON WITH OXIA;Lu;0;L;038E;;;;N;;;;1F7B;
6475 1FEC;GREEK CAPITAL LETTER RHO WITH DASIA;Lu;0;L;03A1 0314;;;;N;;;;1FE5;
6476 1FED;GREEK DIALYTIKA AND VARIA;Sk;0;ON;00A8 0300;;;;N;;;;;
6477 1FEE;GREEK DIALYTIKA AND OXIA;Sk;0;ON;0385;;;;N;;;;;
6478 1FEF;GREEK VARIA;Sk;0;ON;0060;;;;N;;;;;
6479 1FF2;GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F7C 0345;;;;N;;;;;
6480 1FF3;GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI;Ll;0;L;03C9 0345;;;;N;;;1FFC;;1FFC
6481 1FF4;GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03CE 0345;;;;N;;;;;
6482 1FF6;GREEK SMALL LETTER OMEGA WITH PERISPOMENI;Ll;0;L;03C9 0342;;;;N;;;;;
6483 1FF7;GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FF6 0345;;;;N;;;;;
6484 1FF8;GREEK CAPITAL LETTER OMICRON WITH VARIA;Lu;0;L;039F 0300;;;;N;;;;1F78;
6485 1FF9;GREEK CAPITAL LETTER OMICRON WITH OXIA;Lu;0;L;038C;;;;N;;;;1F79;
6486 1FFA;GREEK CAPITAL LETTER OMEGA WITH VARIA;Lu;0;L;03A9 0300;;;;N;;;;1F7C;
6487 1FFB;GREEK CAPITAL LETTER OMEGA WITH OXIA;Lu;0;L;038F;;;;N;;;;1F7D;
6488 1FFC;GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI;Lt;0;L;03A9 0345;;;;N;;;;1FF3;
6489 1FFD;GREEK OXIA;Sk;0;ON;00B4;;;;N;;;;;
6490 1FFE;GREEK DASIA;Sk;0;ON;<compat> 0020 0314;;;;N;;;;;
6491 2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;;
6492 2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;;
6493 2002;EN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
6494 2003;EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
6495 2004;THREE-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
6496 2005;FOUR-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
6497 2006;SIX-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
6498 2007;FIGURE SPACE;Zs;0;WS;<noBreak> 0020;;;;N;;;;;
6499 2008;PUNCTUATION SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
6500 2009;THIN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
6501 200A;HAIR SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
6502 200B;ZERO WIDTH SPACE;Cf;0;BN;;;;;N;;;;;
6503 200C;ZERO WIDTH NON-JOINER;Cf;0;BN;;;;;N;;;;;
6504 200D;ZERO WIDTH JOINER;Cf;0;BN;;;;;N;;;;;
6505 200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;;
6506 200F;RIGHT-TO-LEFT MARK;Cf;0;R;;;;;N;;;;;
6507 2010;HYPHEN;Pd;0;ON;;;;;N;;;;;
6508 2011;NON-BREAKING HYPHEN;Pd;0;ON;<noBreak> 2010;;;;N;;;;;
6509 2012;FIGURE DASH;Pd;0;ON;;;;;N;;;;;
6510 2013;EN DASH;Pd;0;ON;;;;;N;;;;;
6511 2014;EM DASH;Pd;0;ON;;;;;N;;;;;
6512 2015;HORIZONTAL BAR;Pd;0;ON;;;;;N;QUOTATION DASH;;;;
6513 2016;DOUBLE VERTICAL LINE;Po;0;ON;;;;;N;DOUBLE VERTICAL BAR;;;;
6514 2017;DOUBLE LOW LINE;Po;0;ON;<compat> 0020 0333;;;;N;SPACING DOUBLE UNDERSCORE;;;;
6515 2018;LEFT SINGLE QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE TURNED COMMA QUOTATION MARK;;;;
6516 2019;RIGHT SINGLE QUOTATION MARK;Pf;0;ON;;;;;N;SINGLE COMMA QUOTATION MARK;;;;
6517 201A;SINGLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW SINGLE COMMA QUOTATION MARK;;;;
6518 201B;SINGLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE REVERSED COMMA QUOTATION MARK;;;;
6519 201C;LEFT DOUBLE QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE TURNED COMMA QUOTATION MARK;;;;
6520 201D;RIGHT DOUBLE QUOTATION MARK;Pf;0;ON;;;;;N;DOUBLE COMMA QUOTATION MARK;;;;
6521 201E;DOUBLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW DOUBLE COMMA QUOTATION MARK;;;;
6522 201F;DOUBLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE REVERSED COMMA QUOTATION MARK;;;;
6523 2020;DAGGER;Po;0;ON;;;;;N;;;;;
6524 2021;DOUBLE DAGGER;Po;0;ON;;;;;N;;;;;
6525 2022;BULLET;Po;0;ON;;;;;N;;;;;
6526 2023;TRIANGULAR BULLET;Po;0;ON;;;;;N;;;;;
6527 2024;ONE DOT LEADER;Po;0;ON;<compat> 002E;;;;N;;;;;
6528 2025;TWO DOT LEADER;Po;0;ON;<compat> 002E 002E;;;;N;;;;;
6529 2026;HORIZONTAL ELLIPSIS;Po;0;ON;<compat> 002E 002E 002E;;;;N;;;;;
6530 2027;HYPHENATION POINT;Po;0;ON;;;;;N;;;;;
6531 2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;;
6532 2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;;
6533 202A;LEFT-TO-RIGHT EMBEDDING;Cf;0;LRE;;;;;N;;;;;
6534 202B;RIGHT-TO-LEFT EMBEDDING;Cf;0;RLE;;;;;N;;;;;
6535 202C;POP DIRECTIONAL FORMATTING;Cf;0;PDF;;;;;N;;;;;
6536 202D;LEFT-TO-RIGHT OVERRIDE;Cf;0;LRO;;;;;N;;;;;
6537 202E;RIGHT-TO-LEFT OVERRIDE;Cf;0;RLO;;;;;N;;;;;
6538 202F;NARROW NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;;;;;
6539 2030;PER MILLE SIGN;Po;0;ET;;;;;N;;;;;
6540 2031;PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;;
6541 2032;PRIME;Po;0;ET;;;;;N;;;;;
6542 2033;DOUBLE PRIME;Po;0;ET;<compat> 2032 2032;;;;N;;;;;
6543 2034;TRIPLE PRIME;Po;0;ET;<compat> 2032 2032 2032;;;;N;;;;;
6544 2035;REVERSED PRIME;Po;0;ON;;;;;N;;;;;
6545 2036;REVERSED DOUBLE PRIME;Po;0;ON;<compat> 2035 2035;;;;N;;;;;
6546 2037;REVERSED TRIPLE PRIME;Po;0;ON;<compat> 2035 2035 2035;;;;N;;;;;
6547 2038;CARET;Po;0;ON;;;;;N;;;;;
6548 2039;SINGLE LEFT-POINTING ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING SINGLE GUILLEMET;;;;
6549 203A;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING SINGLE GUILLEMET;;;;
6550 203B;REFERENCE MARK;Po;0;ON;;;;;N;;;;;
6551 203C;DOUBLE EXCLAMATION MARK;Po;0;ON;<compat> 0021 0021;;;;N;;;;;
6552 203D;INTERROBANG;Po;0;ON;;;;;N;;;;;
6553 203E;OVERLINE;Po;0;ON;<compat> 0020 0305;;;;N;SPACING OVERSCORE;;;;
6554 203F;UNDERTIE;Pc;0;ON;;;;;N;;Enotikon;;;
6555 2040;CHARACTER TIE;Pc;0;ON;;;;;N;;;;;
6556 2041;CARET INSERTION POINT;Po;0;ON;;;;;N;;;;;
6557 2042;ASTERISM;Po;0;ON;;;;;N;;;;;
6558 2043;HYPHEN BULLET;Po;0;ON;;;;;N;;;;;
6559 2044;FRACTION SLASH;Sm;0;CS;;;;;N;;;;;
6560 2045;LEFT SQUARE BRACKET WITH QUILL;Ps;0;ON;;;;;Y;;;;;
6561 2046;RIGHT SQUARE BRACKET WITH QUILL;Pe;0;ON;;;;;Y;;;;;
6562 2047;DOUBLE QUESTION MARK;Po;0;ON;<compat> 003F 003F;;;;N;;;;;
6563 2048;QUESTION EXCLAMATION MARK;Po;0;ON;<compat> 003F 0021;;;;N;;;;;
6564 2049;EXCLAMATION QUESTION MARK;Po;0;ON;<compat> 0021 003F;;;;N;;;;;
6565 204A;TIRONIAN SIGN ET;Po;0;ON;;;;;N;;;;;
6566 204B;REVERSED PILCROW SIGN;Po;0;ON;;;;;N;;;;;
6567 204C;BLACK LEFTWARDS BULLET;Po;0;ON;;;;;N;;;;;
6568 204D;BLACK RIGHTWARDS BULLET;Po;0;ON;;;;;N;;;;;
6569 204E;LOW ASTERISK;Po;0;ON;;;;;N;;;;;
6570 204F;REVERSED SEMICOLON;Po;0;ON;;;;;N;;;;;
6571 2050;CLOSE UP;Po;0;ON;;;;;N;;;;;
6572 2051;TWO ASTERISKS ALIGNED VERTICALLY;Po;0;ON;;;;;N;;;;;
6573 2052;COMMERCIAL MINUS SIGN;Sm;0;ON;;;;;N;;;;;
6574 2053;SWUNG DASH;Po;0;ON;;;;;N;;;;;
6575 2054;INVERTED UNDERTIE;Pc;0;ON;;;;;N;;;;;
6576 2055;FLOWER PUNCTUATION MARK;Po;0;ON;;;;;N;;;;;
6577 2056;THREE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
6578 2057;QUADRUPLE PRIME;Po;0;ON;<compat> 2032 2032 2032 2032;;;;N;;;;;
6579 2058;FOUR DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
6580 2059;FIVE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
6581 205A;TWO DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
6582 205B;FOUR DOT MARK;Po;0;ON;;;;;N;;;;;
6583 205C;DOTTED CROSS;Po;0;ON;;;;;N;;;;;
6584 205D;TRICOLON;Po;0;ON;;;;;N;;;;;
6585 205E;VERTICAL FOUR DOTS;Po;0;ON;;;;;N;;;;;
6586 205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;
6587 2060;WORD JOINER;Cf;0;BN;;;;;N;;;;;
6588 2061;FUNCTION APPLICATION;Cf;0;BN;;;;;N;;;;;
6589 2062;INVISIBLE TIMES;Cf;0;BN;;;;;N;;;;;
6590 2063;INVISIBLE SEPARATOR;Cf;0;BN;;;;;N;;;;;
6591 2064;INVISIBLE PLUS;Cf;0;BN;;;;;N;;;;;
6592 206A;INHIBIT SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;;
6593 206B;ACTIVATE SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;;
6594 206C;INHIBIT ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;;
6595 206D;ACTIVATE ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;;
6596 206E;NATIONAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;;
6597 206F;NOMINAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;;
6598 2070;SUPERSCRIPT ZERO;No;0;EN;<super> 0030;;0;0;N;SUPERSCRIPT DIGIT ZERO;;;;
6599 2071;SUPERSCRIPT LATIN SMALL LETTER I;Ll;0;L;<super> 0069;;;;N;;;;;
6600 2074;SUPERSCRIPT FOUR;No;0;EN;<super> 0034;;4;4;N;SUPERSCRIPT DIGIT FOUR;;;;
6601 2075;SUPERSCRIPT FIVE;No;0;EN;<super> 0035;;5;5;N;SUPERSCRIPT DIGIT FIVE;;;;
6602 2076;SUPERSCRIPT SIX;No;0;EN;<super> 0036;;6;6;N;SUPERSCRIPT DIGIT SIX;;;;
6603 2077;SUPERSCRIPT SEVEN;No;0;EN;<super> 0037;;7;7;N;SUPERSCRIPT DIGIT SEVEN;;;;
6604 2078;SUPERSCRIPT EIGHT;No;0;EN;<super> 0038;;8;8;N;SUPERSCRIPT DIGIT EIGHT;;;;
6605 2079;SUPERSCRIPT NINE;No;0;EN;<super> 0039;;9;9;N;SUPERSCRIPT DIGIT NINE;;;;
6606 207A;SUPERSCRIPT PLUS SIGN;Sm;0;ES;<super> 002B;;;;N;;;;;
6607 207B;SUPERSCRIPT MINUS;Sm;0;ES;<super> 2212;;;;N;SUPERSCRIPT HYPHEN-MINUS;;;;
6608 207C;SUPERSCRIPT EQUALS SIGN;Sm;0;ON;<super> 003D;;;;N;;;;;
6609 207D;SUPERSCRIPT LEFT PARENTHESIS;Ps;0;ON;<super> 0028;;;;Y;SUPERSCRIPT OPENING PARENTHESIS;;;;
6610 207E;SUPERSCRIPT RIGHT PARENTHESIS;Pe;0;ON;<super> 0029;;;;Y;SUPERSCRIPT CLOSING PARENTHESIS;;;;
6611 207F;SUPERSCRIPT LATIN SMALL LETTER N;Ll;0;L;<super> 006E;;;;N;;;;;
6612 2080;SUBSCRIPT ZERO;No;0;EN;<sub> 0030;;0;0;N;SUBSCRIPT DIGIT ZERO;;;;
6613 2081;SUBSCRIPT ONE;No;0;EN;<sub> 0031;;1;1;N;SUBSCRIPT DIGIT ONE;;;;
6614 2082;SUBSCRIPT TWO;No;0;EN;<sub> 0032;;2;2;N;SUBSCRIPT DIGIT TWO;;;;
6615 2083;SUBSCRIPT THREE;No;0;EN;<sub> 0033;;3;3;N;SUBSCRIPT DIGIT THREE;;;;
6616 2084;SUBSCRIPT FOUR;No;0;EN;<sub> 0034;;4;4;N;SUBSCRIPT DIGIT FOUR;;;;
6617 2085;SUBSCRIPT FIVE;No;0;EN;<sub> 0035;;5;5;N;SUBSCRIPT DIGIT FIVE;;;;
6618 2086;SUBSCRIPT SIX;No;0;EN;<sub> 0036;;6;6;N;SUBSCRIPT DIGIT SIX;;;;
6619 2087;SUBSCRIPT SEVEN;No;0;EN;<sub> 0037;;7;7;N;SUBSCRIPT DIGIT SEVEN;;;;
6620 2088;SUBSCRIPT EIGHT;No;0;EN;<sub> 0038;;8;8;N;SUBSCRIPT DIGIT EIGHT;;;;
6621 2089;SUBSCRIPT NINE;No;0;EN;<sub> 0039;;9;9;N;SUBSCRIPT DIGIT NINE;;;;
6622 208A;SUBSCRIPT PLUS SIGN;Sm;0;ES;<sub> 002B;;;;N;;;;;
6623 208B;SUBSCRIPT MINUS;Sm;0;ES;<sub> 2212;;;;N;SUBSCRIPT HYPHEN-MINUS;;;;
6624 208C;SUBSCRIPT EQUALS SIGN;Sm;0;ON;<sub> 003D;;;;N;;;;;
6625 208D;SUBSCRIPT LEFT PARENTHESIS;Ps;0;ON;<sub> 0028;;;;Y;SUBSCRIPT OPENING PARENTHESIS;;;;
6626 208E;SUBSCRIPT RIGHT PARENTHESIS;Pe;0;ON;<sub> 0029;;;;Y;SUBSCRIPT CLOSING PARENTHESIS;;;;
6627 2090;LATIN SUBSCRIPT SMALL LETTER A;Lm;0;L;<sub> 0061;;;;N;;;;;
6628 2091;LATIN SUBSCRIPT SMALL LETTER E;Lm;0;L;<sub> 0065;;;;N;;;;;
6629 2092;LATIN SUBSCRIPT SMALL LETTER O;Lm;0;L;<sub> 006F;;;;N;;;;;
6630 2093;LATIN SUBSCRIPT SMALL LETTER X;Lm;0;L;<sub> 0078;;;;N;;;;;
6631 2094;LATIN SUBSCRIPT SMALL LETTER SCHWA;Lm;0;L;<sub> 0259;;;;N;;;;;
6632 20A0;EURO-CURRENCY SIGN;Sc;0;ET;;;;;N;;;;;
6633 20A1;COLON SIGN;Sc;0;ET;;;;;N;;;;;
6634 20A2;CRUZEIRO SIGN;Sc;0;ET;;;;;N;;;;;
6635 20A3;FRENCH FRANC SIGN;Sc;0;ET;;;;;N;;;;;
6636 20A4;LIRA SIGN;Sc;0;ET;;;;;N;;;;;
6637 20A5;MILL SIGN;Sc;0;ET;;;;;N;;;;;
6638 20A6;NAIRA SIGN;Sc;0;ET;;;;;N;;;;;
6639 20A7;PESETA SIGN;Sc;0;ET;;;;;N;;;;;
6640 20A8;RUPEE SIGN;Sc;0;ET;<compat> 0052 0073;;;;N;;;;;
6641 20A9;WON SIGN;Sc;0;ET;;;;;N;;;;;
6642 20AA;NEW SHEQEL SIGN;Sc;0;ET;;;;;N;;;;;
6643 20AB;DONG SIGN;Sc;0;ET;;;;;N;;;;;
6644 20AC;EURO SIGN;Sc;0;ET;;;;;N;;;;;
6645 20AD;KIP SIGN;Sc;0;ET;;;;;N;;;;;
6646 20AE;TUGRIK SIGN;Sc;0;ET;;;;;N;;;;;
6647 20AF;DRACHMA SIGN;Sc;0;ET;;;;;N;;;;;
6648 20B0;GERMAN PENNY SIGN;Sc;0;ET;;;;;N;;;;;
6649 20B1;PESO SIGN;Sc;0;ET;;;;;N;;;;;
6650 20B2;GUARANI SIGN;Sc;0;ET;;;;;N;;;;;
6651 20B3;AUSTRAL SIGN;Sc;0;ET;;;;;N;;;;;
6652 20B4;HRYVNIA SIGN;Sc;0;ET;;;;;N;;;;;
6653 20B5;CEDI SIGN;Sc;0;ET;;;;;N;;;;;
6654 20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;;
6655 20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;;
6656 20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;;
6657 20D3;COMBINING SHORT VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT VERTICAL BAR OVERLAY;;;;
6658 20D4;COMBINING ANTICLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING ANTICLOCKWISE ARROW ABOVE;;;;
6659 20D5;COMBINING CLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING CLOCKWISE ARROW ABOVE;;;;
6660 20D6;COMBINING LEFT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT ARROW ABOVE;;;;
6661 20D7;COMBINING RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT ARROW ABOVE;;;;
6662 20D8;COMBINING RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING RING OVERLAY;;;;
6663 20D9;COMBINING CLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING CLOCKWISE RING OVERLAY;;;;
6664 20DA;COMBINING ANTICLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING ANTICLOCKWISE RING OVERLAY;;;;
6665 20DB;COMBINING THREE DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING THREE DOTS ABOVE;;;;
6666 20DC;COMBINING FOUR DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING FOUR DOTS ABOVE;;;;
6667 20DD;COMBINING ENCLOSING CIRCLE;Me;0;NSM;;;;;N;ENCLOSING CIRCLE;;;;
6668 20DE;COMBINING ENCLOSING SQUARE;Me;0;NSM;;;;;N;ENCLOSING SQUARE;;;;
6669 20DF;COMBINING ENCLOSING DIAMOND;Me;0;NSM;;;;;N;ENCLOSING DIAMOND;;;;
6670 20E0;COMBINING ENCLOSING CIRCLE BACKSLASH;Me;0;NSM;;;;;N;ENCLOSING CIRCLE SLASH;;;;
6671 20E1;COMBINING LEFT RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT RIGHT ARROW ABOVE;;;;
6672 20E2;COMBINING ENCLOSING SCREEN;Me;0;NSM;;;;;N;;;;;
6673 20E3;COMBINING ENCLOSING KEYCAP;Me;0;NSM;;;;;N;;;;;
6674 20E4;COMBINING ENCLOSING UPWARD POINTING TRIANGLE;Me;0;NSM;;;;;N;;;;;
6675 20E5;COMBINING REVERSE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;;
6676 20E6;COMBINING DOUBLE VERTICAL STROKE OVERLAY;Mn;1;NSM;;;;;N;;;;;
6677 20E7;COMBINING ANNUITY SYMBOL;Mn;230;NSM;;;;;N;;;;;
6678 20E8;COMBINING TRIPLE UNDERDOT;Mn;220;NSM;;;;;N;;;;;
6679 20E9;COMBINING WIDE BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;;
6680 20EA;COMBINING LEFTWARDS ARROW OVERLAY;Mn;1;NSM;;;;;N;;;;;
6681 20EB;COMBINING LONG DOUBLE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;;
6682 20EC;COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS;Mn;220;NSM;;;;;N;;;;;
6683 20ED;COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS;Mn;220;NSM;;;;;N;;;;;
6684 20EE;COMBINING LEFT ARROW BELOW;Mn;220;NSM;;;;;N;;;;;
6685 20EF;COMBINING RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;;
6686 20F0;COMBINING ASTERISK ABOVE;Mn;230;NSM;;;;;N;;;;;
6687 2100;ACCOUNT OF;So;0;ON;<compat> 0061 002F 0063;;;;N;;;;;
6688 2101;ADDRESSED TO THE SUBJECT;So;0;ON;<compat> 0061 002F 0073;;;;N;;;;;
6689 2102;DOUBLE-STRUCK CAPITAL C;Lu;0;L;<font> 0043;;;;N;DOUBLE-STRUCK C;;;;
6690 2103;DEGREE CELSIUS;So;0;ON;<compat> 00B0 0043;;;;N;DEGREES CENTIGRADE;;;;
6691 2104;CENTRE LINE SYMBOL;So;0;ON;;;;;N;C L SYMBOL;;;;
6692 2105;CARE OF;So;0;ON;<compat> 0063 002F 006F;;;;N;;;;;
6693 2106;CADA UNA;So;0;ON;<compat> 0063 002F 0075;;;;N;;;;;
6694 2107;EULER CONSTANT;Lu;0;L;<compat> 0190;;;;N;EULERS;;;;
6695 2108;SCRUPLE;So;0;ON;;;;;N;;;;;
6696 2109;DEGREE FAHRENHEIT;So;0;ON;<compat> 00B0 0046;;;;N;DEGREES FAHRENHEIT;;;;
6697 210A;SCRIPT SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
6698 210B;SCRIPT CAPITAL H;Lu;0;L;<font> 0048;;;;N;SCRIPT H;;;;
6699 210C;BLACK-LETTER CAPITAL H;Lu;0;L;<font> 0048;;;;N;BLACK-LETTER H;;;;
6700 210D;DOUBLE-STRUCK CAPITAL H;Lu;0;L;<font> 0048;;;;N;DOUBLE-STRUCK H;;;;
6701 210E;PLANCK CONSTANT;Ll;0;L;<font> 0068;;;;N;;;;;
6702 210F;PLANCK CONSTANT OVER TWO PI;Ll;0;L;<font> 0127;;;;N;PLANCK CONSTANT OVER 2 PI;;;;
6703 2110;SCRIPT CAPITAL I;Lu;0;L;<font> 0049;;;;N;SCRIPT I;;;;
6704 2111;BLACK-LETTER CAPITAL I;Lu;0;L;<font> 0049;;;;N;BLACK-LETTER I;;;;
6705 2112;SCRIPT CAPITAL L;Lu;0;L;<font> 004C;;;;N;SCRIPT L;;;;
6706 2113;SCRIPT SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
6707 2114;L B BAR SYMBOL;So;0;ON;;;;;N;;;;;
6708 2115;DOUBLE-STRUCK CAPITAL N;Lu;0;L;<font> 004E;;;;N;DOUBLE-STRUCK N;;;;
6709 2116;NUMERO SIGN;So;0;ON;<compat> 004E 006F;;;;N;NUMERO;;;;
6710 2117;SOUND RECORDING COPYRIGHT;So;0;ON;;;;;N;;;;;
6711 2118;SCRIPT CAPITAL P;So;0;ON;;;;;N;SCRIPT P;;;;
6712 2119;DOUBLE-STRUCK CAPITAL P;Lu;0;L;<font> 0050;;;;N;DOUBLE-STRUCK P;;;;
6713 211A;DOUBLE-STRUCK CAPITAL Q;Lu;0;L;<font> 0051;;;;N;DOUBLE-STRUCK Q;;;;
6714 211B;SCRIPT CAPITAL R;Lu;0;L;<font> 0052;;;;N;SCRIPT R;;;;
6715 211C;BLACK-LETTER CAPITAL R;Lu;0;L;<font> 0052;;;;N;BLACK-LETTER R;;;;
6716 211D;DOUBLE-STRUCK CAPITAL R;Lu;0;L;<font> 0052;;;;N;DOUBLE-STRUCK R;;;;
6717 211E;PRESCRIPTION TAKE;So;0;ON;;;;;N;;;;;
6718 211F;RESPONSE;So;0;ON;;;;;N;;;;;
6719 2120;SERVICE MARK;So;0;ON;<super> 0053 004D;;;;N;;;;;
6720 2121;TELEPHONE SIGN;So;0;ON;<compat> 0054 0045 004C;;;;N;T E L SYMBOL;;;;
6721 2122;TRADE MARK SIGN;So;0;ON;<super> 0054 004D;;;;N;TRADEMARK;;;;
6722 2123;VERSICLE;So;0;ON;;;;;N;;;;;
6723 2124;DOUBLE-STRUCK CAPITAL Z;Lu;0;L;<font> 005A;;;;N;DOUBLE-STRUCK Z;;;;
6724 2125;OUNCE SIGN;So;0;ON;;;;;N;OUNCE;;;;
6725 2126;OHM SIGN;Lu;0;L;03A9;;;;N;OHM;;;03C9;
6726 2127;INVERTED OHM SIGN;So;0;ON;;;;;N;MHO;;;;
6727 2128;BLACK-LETTER CAPITAL Z;Lu;0;L;<font> 005A;;;;N;BLACK-LETTER Z;;;;
6728 2129;TURNED GREEK SMALL LETTER IOTA;So;0;ON;;;;;N;;;;;
6729 212A;KELVIN SIGN;Lu;0;L;004B;;;;N;DEGREES KELVIN;;;006B;
6730 212B;ANGSTROM SIGN;Lu;0;L;00C5;;;;N;ANGSTROM UNIT;;;00E5;
6731 212C;SCRIPT CAPITAL B;Lu;0;L;<font> 0042;;;;N;SCRIPT B;;;;
6732 212D;BLACK-LETTER CAPITAL C;Lu;0;L;<font> 0043;;;;N;BLACK-LETTER C;;;;
6733 212E;ESTIMATED SYMBOL;So;0;ET;;;;;N;;;;;
6734 212F;SCRIPT SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
6735 2130;SCRIPT CAPITAL E;Lu;0;L;<font> 0045;;;;N;SCRIPT E;;;;
6736 2131;SCRIPT CAPITAL F;Lu;0;L;<font> 0046;;;;N;SCRIPT F;;;;
6737 2132;TURNED CAPITAL F;Lu;0;L;;;;;N;TURNED F;;;214E;
6738 2133;SCRIPT CAPITAL M;Lu;0;L;<font> 004D;;;;N;SCRIPT M;;;;
6739 2134;SCRIPT SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
6740 2135;ALEF SYMBOL;Lo;0;L;<compat> 05D0;;;;N;FIRST TRANSFINITE CARDINAL;;;;
6741 2136;BET SYMBOL;Lo;0;L;<compat> 05D1;;;;N;SECOND TRANSFINITE CARDINAL;;;;
6742 2137;GIMEL SYMBOL;Lo;0;L;<compat> 05D2;;;;N;THIRD TRANSFINITE CARDINAL;;;;
6743 2138;DALET SYMBOL;Lo;0;L;<compat> 05D3;;;;N;FOURTH TRANSFINITE CARDINAL;;;;
6744 2139;INFORMATION SOURCE;Ll;0;L;<font> 0069;;;;N;;;;;
6745 213A;ROTATED CAPITAL Q;So;0;ON;;;;;N;;;;;
6746 213B;FACSIMILE SIGN;So;0;ON;<compat> 0046 0041 0058;;;;N;;;;;
6747 213C;DOUBLE-STRUCK SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
6748 213D;DOUBLE-STRUCK SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
6749 213E;DOUBLE-STRUCK CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
6750 213F;DOUBLE-STRUCK CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
6751 2140;DOUBLE-STRUCK N-ARY SUMMATION;Sm;0;ON;<font> 2211;;;;Y;;;;;
6752 2141;TURNED SANS-SERIF CAPITAL G;Sm;0;ON;;;;;N;;;;;
6753 2142;TURNED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;;
6754 2143;REVERSED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;;
6755 2144;TURNED SANS-SERIF CAPITAL Y;Sm;0;ON;;;;;N;;;;;
6756 2145;DOUBLE-STRUCK ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
6757 2146;DOUBLE-STRUCK ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
6758 2147;DOUBLE-STRUCK ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
6759 2148;DOUBLE-STRUCK ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
6760 2149;DOUBLE-STRUCK ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
6761 214A;PROPERTY LINE;So;0;ON;;;;;N;;;;;
6762 214B;TURNED AMPERSAND;Sm;0;ON;;;;;N;;;;;
6763 214C;PER SIGN;So;0;ON;;;;;N;;;;;
6764 214D;AKTIESELSKAB;So;0;ON;;;;;N;;;;;
6765 214E;TURNED SMALL F;Ll;0;L;;;;;N;;;2132;;2132
6766 214F;SYMBOL FOR SAMARITAN SOURCE;So;0;L;;;;;N;;;;;
6767 2153;VULGAR FRACTION ONE THIRD;No;0;ON;<fraction> 0031 2044 0033;;;1/3;N;FRACTION ONE THIRD;;;;
6768 2154;VULGAR FRACTION TWO THIRDS;No;0;ON;<fraction> 0032 2044 0033;;;2/3;N;FRACTION TWO THIRDS;;;;
6769 2155;VULGAR FRACTION ONE FIFTH;No;0;ON;<fraction> 0031 2044 0035;;;1/5;N;FRACTION ONE FIFTH;;;;
6770 2156;VULGAR FRACTION TWO FIFTHS;No;0;ON;<fraction> 0032 2044 0035;;;2/5;N;FRACTION TWO FIFTHS;;;;
6771 2157;VULGAR FRACTION THREE FIFTHS;No;0;ON;<fraction> 0033 2044 0035;;;3/5;N;FRACTION THREE FIFTHS;;;;
6772 2158;VULGAR FRACTION FOUR FIFTHS;No;0;ON;<fraction> 0034 2044 0035;;;4/5;N;FRACTION FOUR FIFTHS;;;;
6773 2159;VULGAR FRACTION ONE SIXTH;No;0;ON;<fraction> 0031 2044 0036;;;1/6;N;FRACTION ONE SIXTH;;;;
6774 215A;VULGAR FRACTION FIVE SIXTHS;No;0;ON;<fraction> 0035 2044 0036;;;5/6;N;FRACTION FIVE SIXTHS;;;;
6775 215B;VULGAR FRACTION ONE EIGHTH;No;0;ON;<fraction> 0031 2044 0038;;;1/8;N;FRACTION ONE EIGHTH;;;;
6776 215C;VULGAR FRACTION THREE EIGHTHS;No;0;ON;<fraction> 0033 2044 0038;;;3/8;N;FRACTION THREE EIGHTHS;;;;
6777 215D;VULGAR FRACTION FIVE EIGHTHS;No;0;ON;<fraction> 0035 2044 0038;;;5/8;N;FRACTION FIVE EIGHTHS;;;;
6778 215E;VULGAR FRACTION SEVEN EIGHTHS;No;0;ON;<fraction> 0037 2044 0038;;;7/8;N;FRACTION SEVEN EIGHTHS;;;;
6779 215F;FRACTION NUMERATOR ONE;No;0;ON;<fraction> 0031 2044;;;1;N;;;;;
6780 2160;ROMAN NUMERAL ONE;Nl;0;L;<compat> 0049;;;1;N;;;;2170;
6781 2161;ROMAN NUMERAL TWO;Nl;0;L;<compat> 0049 0049;;;2;N;;;;2171;
6782 2162;ROMAN NUMERAL THREE;Nl;0;L;<compat> 0049 0049 0049;;;3;N;;;;2172;
6783 2163;ROMAN NUMERAL FOUR;Nl;0;L;<compat> 0049 0056;;;4;N;;;;2173;
6784 2164;ROMAN NUMERAL FIVE;Nl;0;L;<compat> 0056;;;5;N;;;;2174;
6785 2165;ROMAN NUMERAL SIX;Nl;0;L;<compat> 0056 0049;;;6;N;;;;2175;
6786 2166;ROMAN NUMERAL SEVEN;Nl;0;L;<compat> 0056 0049 0049;;;7;N;;;;2176;
6787 2167;ROMAN NUMERAL EIGHT;Nl;0;L;<compat> 0056 0049 0049 0049;;;8;N;;;;2177;
6788 2168;ROMAN NUMERAL NINE;Nl;0;L;<compat> 0049 0058;;;9;N;;;;2178;
6789 2169;ROMAN NUMERAL TEN;Nl;0;L;<compat> 0058;;;10;N;;;;2179;
6790 216A;ROMAN NUMERAL ELEVEN;Nl;0;L;<compat> 0058 0049;;;11;N;;;;217A;
6791 216B;ROMAN NUMERAL TWELVE;Nl;0;L;<compat> 0058 0049 0049;;;12;N;;;;217B;
6792 216C;ROMAN NUMERAL FIFTY;Nl;0;L;<compat> 004C;;;50;N;;;;217C;
6793 216D;ROMAN NUMERAL ONE HUNDRED;Nl;0;L;<compat> 0043;;;100;N;;;;217D;
6794 216E;ROMAN NUMERAL FIVE HUNDRED;Nl;0;L;<compat> 0044;;;500;N;;;;217E;
6795 216F;ROMAN NUMERAL ONE THOUSAND;Nl;0;L;<compat> 004D;;;1000;N;;;;217F;
6796 2170;SMALL ROMAN NUMERAL ONE;Nl;0;L;<compat> 0069;;;1;N;;;2160;;2160
6797 2171;SMALL ROMAN NUMERAL TWO;Nl;0;L;<compat> 0069 0069;;;2;N;;;2161;;2161
6798 2172;SMALL ROMAN NUMERAL THREE;Nl;0;L;<compat> 0069 0069 0069;;;3;N;;;2162;;2162
6799 2173;SMALL ROMAN NUMERAL FOUR;Nl;0;L;<compat> 0069 0076;;;4;N;;;2163;;2163
6800 2174;SMALL ROMAN NUMERAL FIVE;Nl;0;L;<compat> 0076;;;5;N;;;2164;;2164
6801 2175;SMALL ROMAN NUMERAL SIX;Nl;0;L;<compat> 0076 0069;;;6;N;;;2165;;2165
6802 2176;SMALL ROMAN NUMERAL SEVEN;Nl;0;L;<compat> 0076 0069 0069;;;7;N;;;2166;;2166
6803 2177;SMALL ROMAN NUMERAL EIGHT;Nl;0;L;<compat> 0076 0069 0069 0069;;;8;N;;;2167;;2167
6804 2178;SMALL ROMAN NUMERAL NINE;Nl;0;L;<compat> 0069 0078;;;9;N;;;2168;;2168
6805 2179;SMALL ROMAN NUMERAL TEN;Nl;0;L;<compat> 0078;;;10;N;;;2169;;2169
6806 217A;SMALL ROMAN NUMERAL ELEVEN;Nl;0;L;<compat> 0078 0069;;;11;N;;;216A;;216A
6807 217B;SMALL ROMAN NUMERAL TWELVE;Nl;0;L;<compat> 0078 0069 0069;;;12;N;;;216B;;216B
6808 217C;SMALL ROMAN NUMERAL FIFTY;Nl;0;L;<compat> 006C;;;50;N;;;216C;;216C
6809 217D;SMALL ROMAN NUMERAL ONE HUNDRED;Nl;0;L;<compat> 0063;;;100;N;;;216D;;216D
6810 217E;SMALL ROMAN NUMERAL FIVE HUNDRED;Nl;0;L;<compat> 0064;;;500;N;;;216E;;216E
6811 217F;SMALL ROMAN NUMERAL ONE THOUSAND;Nl;0;L;<compat> 006D;;;1000;N;;;216F;;216F
6812 2180;ROMAN NUMERAL ONE THOUSAND C D;Nl;0;L;;;;1000;N;;;;;
6813 2181;ROMAN NUMERAL FIVE THOUSAND;Nl;0;L;;;;5000;N;;;;;
6814 2182;ROMAN NUMERAL TEN THOUSAND;Nl;0;L;;;;10000;N;;;;;
6815 2183;ROMAN NUMERAL REVERSED ONE HUNDRED;Lu;0;L;;;;;N;;;;2184;
6816 2184;LATIN SMALL LETTER REVERSED C;Ll;0;L;;;;;N;;;2183;;2183
6817 2185;ROMAN NUMERAL SIX LATE FORM;Nl;0;L;;;;6;N;;;;;
6818 2186;ROMAN NUMERAL FIFTY EARLY FORM;Nl;0;L;;;;50;N;;;;;
6819 2187;ROMAN NUMERAL FIFTY THOUSAND;Nl;0;L;;;;50000;N;;;;;
6820 2188;ROMAN NUMERAL ONE HUNDRED THOUSAND;Nl;0;L;;;;100000;N;;;;;
6821 2190;LEFTWARDS ARROW;Sm;0;ON;;;;;N;LEFT ARROW;;;;
6822 2191;UPWARDS ARROW;Sm;0;ON;;;;;N;UP ARROW;;;;
6823 2192;RIGHTWARDS ARROW;Sm;0;ON;;;;;N;RIGHT ARROW;;;;
6824 2193;DOWNWARDS ARROW;Sm;0;ON;;;;;N;DOWN ARROW;;;;
6825 2194;LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;;
6826 2195;UP DOWN ARROW;So;0;ON;;;;;N;;;;;
6827 2196;NORTH WEST ARROW;So;0;ON;;;;;N;UPPER LEFT ARROW;;;;
6828 2197;NORTH EAST ARROW;So;0;ON;;;;;N;UPPER RIGHT ARROW;;;;
6829 2198;SOUTH EAST ARROW;So;0;ON;;;;;N;LOWER RIGHT ARROW;;;;
6830 2199;SOUTH WEST ARROW;So;0;ON;;;;;N;LOWER LEFT ARROW;;;;
6831 219A;LEFTWARDS ARROW WITH STROKE;Sm;0;ON;2190 0338;;;;N;LEFT ARROW WITH STROKE;;;;
6832 219B;RIGHTWARDS ARROW WITH STROKE;Sm;0;ON;2192 0338;;;;N;RIGHT ARROW WITH STROKE;;;;
6833 219C;LEFTWARDS WAVE ARROW;So;0;ON;;;;;N;LEFT WAVE ARROW;;;;
6834 219D;RIGHTWARDS WAVE ARROW;So;0;ON;;;;;N;RIGHT WAVE ARROW;;;;
6835 219E;LEFTWARDS TWO HEADED ARROW;So;0;ON;;;;;N;LEFT TWO HEADED ARROW;;;;
6836 219F;UPWARDS TWO HEADED ARROW;So;0;ON;;;;;N;UP TWO HEADED ARROW;;;;
6837 21A0;RIGHTWARDS TWO HEADED ARROW;Sm;0;ON;;;;;N;RIGHT TWO HEADED ARROW;;;;
6838 21A1;DOWNWARDS TWO HEADED ARROW;So;0;ON;;;;;N;DOWN TWO HEADED ARROW;;;;
6839 21A2;LEFTWARDS ARROW WITH TAIL;So;0;ON;;;;;N;LEFT ARROW WITH TAIL;;;;
6840 21A3;RIGHTWARDS ARROW WITH TAIL;Sm;0;ON;;;;;N;RIGHT ARROW WITH TAIL;;;;
6841 21A4;LEFTWARDS ARROW FROM BAR;So;0;ON;;;;;N;LEFT ARROW FROM BAR;;;;
6842 21A5;UPWARDS ARROW FROM BAR;So;0;ON;;;;;N;UP ARROW FROM BAR;;;;
6843 21A6;RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;RIGHT ARROW FROM BAR;;;;
6844 21A7;DOWNWARDS ARROW FROM BAR;So;0;ON;;;;;N;DOWN ARROW FROM BAR;;;;
6845 21A8;UP DOWN ARROW WITH BASE;So;0;ON;;;;;N;;;;;
6846 21A9;LEFTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;LEFT ARROW WITH HOOK;;;;
6847 21AA;RIGHTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;RIGHT ARROW WITH HOOK;;;;
6848 21AB;LEFTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;LEFT ARROW WITH LOOP;;;;
6849 21AC;RIGHTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;RIGHT ARROW WITH LOOP;;;;
6850 21AD;LEFT RIGHT WAVE ARROW;So;0;ON;;;;;N;;;;;
6851 21AE;LEFT RIGHT ARROW WITH STROKE;Sm;0;ON;2194 0338;;;;N;;;;;
6852 21AF;DOWNWARDS ZIGZAG ARROW;So;0;ON;;;;;N;DOWN ZIGZAG ARROW;;;;
6853 21B0;UPWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP LEFT;;;;
6854 21B1;UPWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP RIGHT;;;;
6855 21B2;DOWNWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP LEFT;;;;
6856 21B3;DOWNWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP RIGHT;;;;
6857 21B4;RIGHTWARDS ARROW WITH CORNER DOWNWARDS;So;0;ON;;;;;N;RIGHT ARROW WITH CORNER DOWN;;;;
6858 21B5;DOWNWARDS ARROW WITH CORNER LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH CORNER LEFT;;;;
6859 21B6;ANTICLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;;
6860 21B7;CLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;;
6861 21B8;NORTH WEST ARROW TO LONG BAR;So;0;ON;;;;;N;UPPER LEFT ARROW TO LONG BAR;;;;
6862 21B9;LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR OVER RIGHT ARROW TO BAR;;;;
6863 21BA;ANTICLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;
6864 21BB;CLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;
6865 21BC;LEFTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB UP;;;;
6866 21BD;LEFTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB DOWN;;;;
6867 21BE;UPWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB RIGHT;;;;
6868 21BF;UPWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB LEFT;;;;
6869 21C0;RIGHTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB UP;;;;
6870 21C1;RIGHTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB DOWN;;;;
6871 21C2;DOWNWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB RIGHT;;;;
6872 21C3;DOWNWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB LEFT;;;;
6873 21C4;RIGHTWARDS ARROW OVER LEFTWARDS ARROW;So;0;ON;;;;;N;RIGHT ARROW OVER LEFT ARROW;;;;
6874 21C5;UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW;So;0;ON;;;;;N;UP ARROW LEFT OF DOWN ARROW;;;;
6875 21C6;LEFTWARDS ARROW OVER RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT ARROW OVER RIGHT ARROW;;;;
6876 21C7;LEFTWARDS PAIRED ARROWS;So;0;ON;;;;;N;LEFT PAIRED ARROWS;;;;
6877 21C8;UPWARDS PAIRED ARROWS;So;0;ON;;;;;N;UP PAIRED ARROWS;;;;
6878 21C9;RIGHTWARDS PAIRED ARROWS;So;0;ON;;;;;N;RIGHT PAIRED ARROWS;;;;
6879 21CA;DOWNWARDS PAIRED ARROWS;So;0;ON;;;;;N;DOWN PAIRED ARROWS;;;;
6880 21CB;LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON;So;0;ON;;;;;N;LEFT HARPOON OVER RIGHT HARPOON;;;;
6881 21CC;RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON;So;0;ON;;;;;N;RIGHT HARPOON OVER LEFT HARPOON;;;;
6882 21CD;LEFTWARDS DOUBLE ARROW WITH STROKE;So;0;ON;21D0 0338;;;;N;LEFT DOUBLE ARROW WITH STROKE;;;;
6883 21CE;LEFT RIGHT DOUBLE ARROW WITH STROKE;Sm;0;ON;21D4 0338;;;;N;;;;;
6884 21CF;RIGHTWARDS DOUBLE ARROW WITH STROKE;Sm;0;ON;21D2 0338;;;;N;RIGHT DOUBLE ARROW WITH STROKE;;;;
6885 21D0;LEFTWARDS DOUBLE ARROW;So;0;ON;;;;;N;LEFT DOUBLE ARROW;;;;
6886 21D1;UPWARDS DOUBLE ARROW;So;0;ON;;;;;N;UP DOUBLE ARROW;;;;
6887 21D2;RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;RIGHT DOUBLE ARROW;;;;
6888 21D3;DOWNWARDS DOUBLE ARROW;So;0;ON;;;;;N;DOWN DOUBLE ARROW;;;;
6889 21D4;LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;
6890 21D5;UP DOWN DOUBLE ARROW;So;0;ON;;;;;N;;;;;
6891 21D6;NORTH WEST DOUBLE ARROW;So;0;ON;;;;;N;UPPER LEFT DOUBLE ARROW;;;;
6892 21D7;NORTH EAST DOUBLE ARROW;So;0;ON;;;;;N;UPPER RIGHT DOUBLE ARROW;;;;
6893 21D8;SOUTH EAST DOUBLE ARROW;So;0;ON;;;;;N;LOWER RIGHT DOUBLE ARROW;;;;
6894 21D9;SOUTH WEST DOUBLE ARROW;So;0;ON;;;;;N;LOWER LEFT DOUBLE ARROW;;;;
6895 21DA;LEFTWARDS TRIPLE ARROW;So;0;ON;;;;;N;LEFT TRIPLE ARROW;;;;
6896 21DB;RIGHTWARDS TRIPLE ARROW;So;0;ON;;;;;N;RIGHT TRIPLE ARROW;;;;
6897 21DC;LEFTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;LEFT SQUIGGLE ARROW;;;;
6898 21DD;RIGHTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;RIGHT SQUIGGLE ARROW;;;;
6899 21DE;UPWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;UP ARROW WITH DOUBLE STROKE;;;;
6900 21DF;DOWNWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;DOWN ARROW WITH DOUBLE STROKE;;;;
6901 21E0;LEFTWARDS DASHED ARROW;So;0;ON;;;;;N;LEFT DASHED ARROW;;;;
6902 21E1;UPWARDS DASHED ARROW;So;0;ON;;;;;N;UP DASHED ARROW;;;;
6903 21E2;RIGHTWARDS DASHED ARROW;So;0;ON;;;;;N;RIGHT DASHED ARROW;;;;
6904 21E3;DOWNWARDS DASHED ARROW;So;0;ON;;;;;N;DOWN DASHED ARROW;;;;
6905 21E4;LEFTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR;;;;
6906 21E5;RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;RIGHT ARROW TO BAR;;;;
6907 21E6;LEFTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE LEFT ARROW;;;;
6908 21E7;UPWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE UP ARROW;;;;
6909 21E8;RIGHTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE RIGHT ARROW;;;;
6910 21E9;DOWNWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE DOWN ARROW;;;;
6911 21EA;UPWARDS WHITE ARROW FROM BAR;So;0;ON;;;;;N;WHITE UP ARROW FROM BAR;;;;
6912 21EB;UPWARDS WHITE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;;
6913 21EC;UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;;
6914 21ED;UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR;So;0;ON;;;;;N;;;;;
6915 21EE;UPWARDS WHITE DOUBLE ARROW;So;0;ON;;;;;N;;;;;
6916 21EF;UPWARDS WHITE DOUBLE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;;
6917 21F0;RIGHTWARDS WHITE ARROW FROM WALL;So;0;ON;;;;;N;;;;;
6918 21F1;NORTH WEST ARROW TO CORNER;So;0;ON;;;;;N;;;;;
6919 21F2;SOUTH EAST ARROW TO CORNER;So;0;ON;;;;;N;;;;;
6920 21F3;UP DOWN WHITE ARROW;So;0;ON;;;;;N;;;;;
6921 21F4;RIGHT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
6922 21F5;DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW;Sm;0;ON;;;;;N;;;;;
6923 21F6;THREE RIGHTWARDS ARROWS;Sm;0;ON;;;;;N;;;;;
6924 21F7;LEFTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
6925 21F8;RIGHTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
6926 21F9;LEFT RIGHT ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
6927 21FA;LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
6928 21FB;RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
6929 21FC;LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
6930 21FD;LEFTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;;
6931 21FE;RIGHTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;;
6932 21FF;LEFT RIGHT OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;;
6933 2200;FOR ALL;Sm;0;ON;;;;;N;;;;;
6934 2201;COMPLEMENT;Sm;0;ON;;;;;Y;;;;;
6935 2202;PARTIAL DIFFERENTIAL;Sm;0;ON;;;;;Y;;;;;
6936 2203;THERE EXISTS;Sm;0;ON;;;;;Y;;;;;
6937 2204;THERE DOES NOT EXIST;Sm;0;ON;2203 0338;;;;Y;;;;;
6938 2205;EMPTY SET;Sm;0;ON;;;;;N;;;;;
6939 2206;INCREMENT;Sm;0;ON;;;;;N;;;;;
6940 2207;NABLA;Sm;0;ON;;;;;N;;;;;
6941 2208;ELEMENT OF;Sm;0;ON;;;;;Y;;;;;
6942 2209;NOT AN ELEMENT OF;Sm;0;ON;2208 0338;;;;Y;;;;;
6943 220A;SMALL ELEMENT OF;Sm;0;ON;;;;;Y;;;;;
6944 220B;CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;;
6945 220C;DOES NOT CONTAIN AS MEMBER;Sm;0;ON;220B 0338;;;;Y;;;;;
6946 220D;SMALL CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;;
6947 220E;END OF PROOF;Sm;0;ON;;;;;N;;;;;
6948 220F;N-ARY PRODUCT;Sm;0;ON;;;;;N;;;;;
6949 2210;N-ARY COPRODUCT;Sm;0;ON;;;;;N;;;;;
6950 2211;N-ARY SUMMATION;Sm;0;ON;;;;;Y;;;;;
6951 2212;MINUS SIGN;Sm;0;ES;;;;;N;;;;;
6952 2213;MINUS-OR-PLUS SIGN;Sm;0;ET;;;;;N;;;;;
6953 2214;DOT PLUS;Sm;0;ON;;;;;N;;;;;
6954 2215;DIVISION SLASH;Sm;0;ON;;;;;Y;;;;;
6955 2216;SET MINUS;Sm;0;ON;;;;;Y;;;;;
6956 2217;ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;;
6957 2218;RING OPERATOR;Sm;0;ON;;;;;N;;;;;
6958 2219;BULLET OPERATOR;Sm;0;ON;;;;;N;;;;;
6959 221A;SQUARE ROOT;Sm;0;ON;;;;;Y;;;;;
6960 221B;CUBE ROOT;Sm;0;ON;;;;;Y;;;;;
6961 221C;FOURTH ROOT;Sm;0;ON;;;;;Y;;;;;
6962 221D;PROPORTIONAL TO;Sm;0;ON;;;;;Y;;;;;
6963 221E;INFINITY;Sm;0;ON;;;;;N;;;;;
6964 221F;RIGHT ANGLE;Sm;0;ON;;;;;Y;;;;;
6965 2220;ANGLE;Sm;0;ON;;;;;Y;;;;;
6966 2221;MEASURED ANGLE;Sm;0;ON;;;;;Y;;;;;
6967 2222;SPHERICAL ANGLE;Sm;0;ON;;;;;Y;;;;;
6968 2223;DIVIDES;Sm;0;ON;;;;;N;;;;;
6969 2224;DOES NOT DIVIDE;Sm;0;ON;2223 0338;;;;Y;;;;;
6970 2225;PARALLEL TO;Sm;0;ON;;;;;N;;;;;
6971 2226;NOT PARALLEL TO;Sm;0;ON;2225 0338;;;;Y;;;;;
6972 2227;LOGICAL AND;Sm;0;ON;;;;;N;;;;;
6973 2228;LOGICAL OR;Sm;0;ON;;;;;N;;;;;
6974 2229;INTERSECTION;Sm;0;ON;;;;;N;;;;;
6975 222A;UNION;Sm;0;ON;;;;;N;;;;;
6976 222B;INTEGRAL;Sm;0;ON;;;;;Y;;;;;
6977 222C;DOUBLE INTEGRAL;Sm;0;ON;<compat> 222B 222B;;;;Y;;;;;
6978 222D;TRIPLE INTEGRAL;Sm;0;ON;<compat> 222B 222B 222B;;;;Y;;;;;
6979 222E;CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;
6980 222F;SURFACE INTEGRAL;Sm;0;ON;<compat> 222E 222E;;;;Y;;;;;
6981 2230;VOLUME INTEGRAL;Sm;0;ON;<compat> 222E 222E 222E;;;;Y;;;;;
6982 2231;CLOCKWISE INTEGRAL;Sm;0;ON;;;;;Y;;;;;
6983 2232;CLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;
6984 2233;ANTICLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;
6985 2234;THEREFORE;Sm;0;ON;;;;;N;;;;;
6986 2235;BECAUSE;Sm;0;ON;;;;;N;;;;;
6987 2236;RATIO;Sm;0;ON;;;;;N;;;;;
6988 2237;PROPORTION;Sm;0;ON;;;;;N;;;;;
6989 2238;DOT MINUS;Sm;0;ON;;;;;N;;;;;
6990 2239;EXCESS;Sm;0;ON;;;;;Y;;;;;
6991 223A;GEOMETRIC PROPORTION;Sm;0;ON;;;;;N;;;;;
6992 223B;HOMOTHETIC;Sm;0;ON;;;;;Y;;;;;
6993 223C;TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
6994 223D;REVERSED TILDE;Sm;0;ON;;;;;Y;;lazy S;;;
6995 223E;INVERTED LAZY S;Sm;0;ON;;;;;Y;;;;;
6996 223F;SINE WAVE;Sm;0;ON;;;;;Y;;;;;
6997 2240;WREATH PRODUCT;Sm;0;ON;;;;;Y;;;;;
6998 2241;NOT TILDE;Sm;0;ON;223C 0338;;;;Y;;;;;
6999 2242;MINUS TILDE;Sm;0;ON;;;;;Y;;;;;
7000 2243;ASYMPTOTICALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7001 2244;NOT ASYMPTOTICALLY EQUAL TO;Sm;0;ON;2243 0338;;;;Y;;;;;
7002 2245;APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7003 2246;APPROXIMATELY BUT NOT ACTUALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7004 2247;NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO;Sm;0;ON;2245 0338;;;;Y;;;;;
7005 2248;ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7006 2249;NOT ALMOST EQUAL TO;Sm;0;ON;2248 0338;;;;Y;;;;;
7007 224A;ALMOST EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7008 224B;TRIPLE TILDE;Sm;0;ON;;;;;Y;;;;;
7009 224C;ALL EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7010 224D;EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;
7011 224E;GEOMETRICALLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;
7012 224F;DIFFERENCE BETWEEN;Sm;0;ON;;;;;N;;;;;
7013 2250;APPROACHES THE LIMIT;Sm;0;ON;;;;;N;;;;;
7014 2251;GEOMETRICALLY EQUAL TO;Sm;0;ON;;;;;N;;;;;
7015 2252;APPROXIMATELY EQUAL TO OR THE IMAGE OF;Sm;0;ON;;;;;Y;;;;;
7016 2253;IMAGE OF OR APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7017 2254;COLON EQUALS;Sm;0;ON;;;;;Y;COLON EQUAL;;;;
7018 2255;EQUALS COLON;Sm;0;ON;;;;;Y;EQUAL COLON;;;;
7019 2256;RING IN EQUAL TO;Sm;0;ON;;;;;N;;;;;
7020 2257;RING EQUAL TO;Sm;0;ON;;;;;N;;;;;
7021 2258;CORRESPONDS TO;Sm;0;ON;;;;;N;;;;;
7022 2259;ESTIMATES;Sm;0;ON;;;;;N;;;;;
7023 225A;EQUIANGULAR TO;Sm;0;ON;;;;;N;;;;;
7024 225B;STAR EQUALS;Sm;0;ON;;;;;N;;;;;
7025 225C;DELTA EQUAL TO;Sm;0;ON;;;;;N;;;;;
7026 225D;EQUAL TO BY DEFINITION;Sm;0;ON;;;;;N;;;;;
7027 225E;MEASURED BY;Sm;0;ON;;;;;N;;;;;
7028 225F;QUESTIONED EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7029 2260;NOT EQUAL TO;Sm;0;ON;003D 0338;;;;Y;;;;;
7030 2261;IDENTICAL TO;Sm;0;ON;;;;;N;;;;;
7031 2262;NOT IDENTICAL TO;Sm;0;ON;2261 0338;;;;Y;;;;;
7032 2263;STRICTLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;
7033 2264;LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUAL TO;;;;
7034 2265;GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUAL TO;;;;
7035 2266;LESS-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OVER EQUAL TO;;;;
7036 2267;GREATER-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OVER EQUAL TO;;;;
7037 2268;LESS-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUAL TO;;;;
7038 2269;GREATER-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUAL TO;;;;
7039 226A;MUCH LESS-THAN;Sm;0;ON;;;;;Y;MUCH LESS THAN;;;;
7040 226B;MUCH GREATER-THAN;Sm;0;ON;;;;;Y;MUCH GREATER THAN;;;;
7041 226C;BETWEEN;Sm;0;ON;;;;;N;;;;;
7042 226D;NOT EQUIVALENT TO;Sm;0;ON;224D 0338;;;;N;;;;;
7043 226E;NOT LESS-THAN;Sm;0;ON;003C 0338;;;;Y;NOT LESS THAN;;;;
7044 226F;NOT GREATER-THAN;Sm;0;ON;003E 0338;;;;Y;NOT GREATER THAN;;;;
7045 2270;NEITHER LESS-THAN NOR EQUAL TO;Sm;0;ON;2264 0338;;;;Y;NEITHER LESS THAN NOR EQUAL TO;;;;
7046 2271;NEITHER GREATER-THAN NOR EQUAL TO;Sm;0;ON;2265 0338;;;;Y;NEITHER GREATER THAN NOR EQUAL TO;;;;
7047 2272;LESS-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUIVALENT TO;;;;
7048 2273;GREATER-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUIVALENT TO;;;;
7049 2274;NEITHER LESS-THAN NOR EQUIVALENT TO;Sm;0;ON;2272 0338;;;;Y;NEITHER LESS THAN NOR EQUIVALENT TO;;;;
7050 2275;NEITHER GREATER-THAN NOR EQUIVALENT TO;Sm;0;ON;2273 0338;;;;Y;NEITHER GREATER THAN NOR EQUIVALENT TO;;;;
7051 2276;LESS-THAN OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN OR GREATER THAN;;;;
7052 2277;GREATER-THAN OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN OR LESS THAN;;;;
7053 2278;NEITHER LESS-THAN NOR GREATER-THAN;Sm;0;ON;2276 0338;;;;Y;NEITHER LESS THAN NOR GREATER THAN;;;;
7054 2279;NEITHER GREATER-THAN NOR LESS-THAN;Sm;0;ON;2277 0338;;;;Y;NEITHER GREATER THAN NOR LESS THAN;;;;
7055 227A;PRECEDES;Sm;0;ON;;;;;Y;;;;;
7056 227B;SUCCEEDS;Sm;0;ON;;;;;Y;;;;;
7057 227C;PRECEDES OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7058 227D;SUCCEEDS OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7059 227E;PRECEDES OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
7060 227F;SUCCEEDS OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
7061 2280;DOES NOT PRECEDE;Sm;0;ON;227A 0338;;;;Y;;;;;
7062 2281;DOES NOT SUCCEED;Sm;0;ON;227B 0338;;;;Y;;;;;
7063 2282;SUBSET OF;Sm;0;ON;;;;;Y;;;;;
7064 2283;SUPERSET OF;Sm;0;ON;;;;;Y;;;;;
7065 2284;NOT A SUBSET OF;Sm;0;ON;2282 0338;;;;Y;;;;;
7066 2285;NOT A SUPERSET OF;Sm;0;ON;2283 0338;;;;Y;;;;;
7067 2286;SUBSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7068 2287;SUPERSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7069 2288;NEITHER A SUBSET OF NOR EQUAL TO;Sm;0;ON;2286 0338;;;;Y;;;;;
7070 2289;NEITHER A SUPERSET OF NOR EQUAL TO;Sm;0;ON;2287 0338;;;;Y;;;;;
7071 228A;SUBSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUBSET OF OR NOT EQUAL TO;;;;
7072 228B;SUPERSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUPERSET OF OR NOT EQUAL TO;;;;
7073 228C;MULTISET;Sm;0;ON;;;;;Y;;;;;
7074 228D;MULTISET MULTIPLICATION;Sm;0;ON;;;;;N;;;;;
7075 228E;MULTISET UNION;Sm;0;ON;;;;;N;;;;;
7076 228F;SQUARE IMAGE OF;Sm;0;ON;;;;;Y;;;;;
7077 2290;SQUARE ORIGINAL OF;Sm;0;ON;;;;;Y;;;;;
7078 2291;SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7079 2292;SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7080 2293;SQUARE CAP;Sm;0;ON;;;;;N;;;;;
7081 2294;SQUARE CUP;Sm;0;ON;;;;;N;;;;;
7082 2295;CIRCLED PLUS;Sm;0;ON;;;;;N;;;;;
7083 2296;CIRCLED MINUS;Sm;0;ON;;;;;N;;;;;
7084 2297;CIRCLED TIMES;Sm;0;ON;;;;;N;;;;;
7085 2298;CIRCLED DIVISION SLASH;Sm;0;ON;;;;;Y;;;;;
7086 2299;CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
7087 229A;CIRCLED RING OPERATOR;Sm;0;ON;;;;;N;;;;;
7088 229B;CIRCLED ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;;
7089 229C;CIRCLED EQUALS;Sm;0;ON;;;;;N;;;;;
7090 229D;CIRCLED DASH;Sm;0;ON;;;;;N;;;;;
7091 229E;SQUARED PLUS;Sm;0;ON;;;;;N;;;;;
7092 229F;SQUARED MINUS;Sm;0;ON;;;;;N;;;;;
7093 22A0;SQUARED TIMES;Sm;0;ON;;;;;N;;;;;
7094 22A1;SQUARED DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
7095 22A2;RIGHT TACK;Sm;0;ON;;;;;Y;;;;;
7096 22A3;LEFT TACK;Sm;0;ON;;;;;Y;;;;;
7097 22A4;DOWN TACK;Sm;0;ON;;;;;N;;;;;
7098 22A5;UP TACK;Sm;0;ON;;;;;N;;;;;
7099 22A6;ASSERTION;Sm;0;ON;;;;;Y;;;;;
7100 22A7;MODELS;Sm;0;ON;;;;;Y;;;;;
7101 22A8;TRUE;Sm;0;ON;;;;;Y;;;;;
7102 22A9;FORCES;Sm;0;ON;;;;;Y;;;;;
7103 22AA;TRIPLE VERTICAL BAR RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
7104 22AB;DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
7105 22AC;DOES NOT PROVE;Sm;0;ON;22A2 0338;;;;Y;;;;;
7106 22AD;NOT TRUE;Sm;0;ON;22A8 0338;;;;Y;;;;;
7107 22AE;DOES NOT FORCE;Sm;0;ON;22A9 0338;;;;Y;;;;;
7108 22AF;NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;22AB 0338;;;;Y;;;;;
7109 22B0;PRECEDES UNDER RELATION;Sm;0;ON;;;;;Y;;;;;
7110 22B1;SUCCEEDS UNDER RELATION;Sm;0;ON;;;;;Y;;;;;
7111 22B2;NORMAL SUBGROUP OF;Sm;0;ON;;;;;Y;;;;;
7112 22B3;CONTAINS AS NORMAL SUBGROUP;Sm;0;ON;;;;;Y;;;;;
7113 22B4;NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7114 22B5;CONTAINS AS NORMAL SUBGROUP OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7115 22B6;ORIGINAL OF;Sm;0;ON;;;;;Y;;;;;
7116 22B7;IMAGE OF;Sm;0;ON;;;;;Y;;;;;
7117 22B8;MULTIMAP;Sm;0;ON;;;;;Y;;;;;
7118 22B9;HERMITIAN CONJUGATE MATRIX;Sm;0;ON;;;;;N;;;;;
7119 22BA;INTERCALATE;Sm;0;ON;;;;;N;;;;;
7120 22BB;XOR;Sm;0;ON;;;;;N;;;;;
7121 22BC;NAND;Sm;0;ON;;;;;N;;;;;
7122 22BD;NOR;Sm;0;ON;;;;;N;;;;;
7123 22BE;RIGHT ANGLE WITH ARC;Sm;0;ON;;;;;Y;;;;;
7124 22BF;RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;;
7125 22C0;N-ARY LOGICAL AND;Sm;0;ON;;;;;N;;;;;
7126 22C1;N-ARY LOGICAL OR;Sm;0;ON;;;;;N;;;;;
7127 22C2;N-ARY INTERSECTION;Sm;0;ON;;;;;N;;;;;
7128 22C3;N-ARY UNION;Sm;0;ON;;;;;N;;;;;
7129 22C4;DIAMOND OPERATOR;Sm;0;ON;;;;;N;;;;;
7130 22C5;DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
7131 22C6;STAR OPERATOR;Sm;0;ON;;;;;N;;;;;
7132 22C7;DIVISION TIMES;Sm;0;ON;;;;;N;;;;;
7133 22C8;BOWTIE;Sm;0;ON;;;;;N;;;;;
7134 22C9;LEFT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
7135 22CA;RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
7136 22CB;LEFT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
7137 22CC;RIGHT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;
7138 22CD;REVERSED TILDE EQUALS;Sm;0;ON;;;;;Y;;;;;
7139 22CE;CURLY LOGICAL OR;Sm;0;ON;;;;;N;;;;;
7140 22CF;CURLY LOGICAL AND;Sm;0;ON;;;;;N;;;;;
7141 22D0;DOUBLE SUBSET;Sm;0;ON;;;;;Y;;;;;
7142 22D1;DOUBLE SUPERSET;Sm;0;ON;;;;;Y;;;;;
7143 22D2;DOUBLE INTERSECTION;Sm;0;ON;;;;;N;;;;;
7144 22D3;DOUBLE UNION;Sm;0;ON;;;;;N;;;;;
7145 22D4;PITCHFORK;Sm;0;ON;;;;;N;;;;;
7146 22D5;EQUAL AND PARALLEL TO;Sm;0;ON;;;;;N;;;;;
7147 22D6;LESS-THAN WITH DOT;Sm;0;ON;;;;;Y;LESS THAN WITH DOT;;;;
7148 22D7;GREATER-THAN WITH DOT;Sm;0;ON;;;;;Y;GREATER THAN WITH DOT;;;;
7149 22D8;VERY MUCH LESS-THAN;Sm;0;ON;;;;;Y;VERY MUCH LESS THAN;;;;
7150 22D9;VERY MUCH GREATER-THAN;Sm;0;ON;;;;;Y;VERY MUCH GREATER THAN;;;;
7151 22DA;LESS-THAN EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN EQUAL TO OR GREATER THAN;;;;
7152 22DB;GREATER-THAN EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN EQUAL TO OR LESS THAN;;;;
7153 22DC;EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR LESS THAN;;;;
7154 22DD;EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR GREATER THAN;;;;
7155 22DE;EQUAL TO OR PRECEDES;Sm;0;ON;;;;;Y;;;;;
7156 22DF;EQUAL TO OR SUCCEEDS;Sm;0;ON;;;;;Y;;;;;
7157 22E0;DOES NOT PRECEDE OR EQUAL;Sm;0;ON;227C 0338;;;;Y;;;;;
7158 22E1;DOES NOT SUCCEED OR EQUAL;Sm;0;ON;227D 0338;;;;Y;;;;;
7159 22E2;NOT SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;2291 0338;;;;Y;;;;;
7160 22E3;NOT SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;2292 0338;;;;Y;;;;;
7161 22E4;SQUARE IMAGE OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7162 22E5;SQUARE ORIGINAL OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
7163 22E6;LESS-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUIVALENT TO;;;;
7164 22E7;GREATER-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUIVALENT TO;;;;
7165 22E8;PRECEDES BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
7166 22E9;SUCCEEDS BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;
7167 22EA;NOT NORMAL SUBGROUP OF;Sm;0;ON;22B2 0338;;;;Y;;;;;
7168 22EB;DOES NOT CONTAIN AS NORMAL SUBGROUP;Sm;0;ON;22B3 0338;;;;Y;;;;;
7169 22EC;NOT NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;22B4 0338;;;;Y;;;;;
7170 22ED;DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL;Sm;0;ON;22B5 0338;;;;Y;;;;;
7171 22EE;VERTICAL ELLIPSIS;Sm;0;ON;;;;;N;;;;;
7172 22EF;MIDLINE HORIZONTAL ELLIPSIS;Sm;0;ON;;;;;N;;;;;
7173 22F0;UP RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;;
7174 22F1;DOWN RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;;
7175 22F2;ELEMENT OF WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
7176 22F3;ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
7177 22F4;SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
7178 22F5;ELEMENT OF WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
7179 22F6;ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
7180 22F7;SMALL ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
7181 22F8;ELEMENT OF WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
7182 22F9;ELEMENT OF WITH TWO HORIZONTAL STROKES;Sm;0;ON;;;;;Y;;;;;
7183 22FA;CONTAINS WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
7184 22FB;CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
7185 22FC;SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
7186 22FD;CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
7187 22FE;SMALL CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
7188 22FF;Z NOTATION BAG MEMBERSHIP;Sm;0;ON;;;;;Y;;;;;
7189 2300;DIAMETER SIGN;So;0;ON;;;;;N;;;;;
7190 2301;ELECTRIC ARROW;So;0;ON;;;;;N;;;;;
7191 2302;HOUSE;So;0;ON;;;;;N;;;;;
7192 2303;UP ARROWHEAD;So;0;ON;;;;;N;;;;;
7193 2304;DOWN ARROWHEAD;So;0;ON;;;;;N;;;;;
7194 2305;PROJECTIVE;So;0;ON;;;;;N;;;;;
7195 2306;PERSPECTIVE;So;0;ON;;;;;N;;;;;
7196 2307;WAVY LINE;So;0;ON;;;;;N;;;;;
7197 2308;LEFT CEILING;Sm;0;ON;;;;;Y;;;;;
7198 2309;RIGHT CEILING;Sm;0;ON;;;;;Y;;;;;
7199 230A;LEFT FLOOR;Sm;0;ON;;;;;Y;;;;;
7200 230B;RIGHT FLOOR;Sm;0;ON;;;;;Y;;;;;
7201 230C;BOTTOM RIGHT CROP;So;0;ON;;;;;N;;;;;
7202 230D;BOTTOM LEFT CROP;So;0;ON;;;;;N;;;;;
7203 230E;TOP RIGHT CROP;So;0;ON;;;;;N;;;;;
7204 230F;TOP LEFT CROP;So;0;ON;;;;;N;;;;;
7205 2310;REVERSED NOT SIGN;So;0;ON;;;;;N;;;;;
7206 2311;SQUARE LOZENGE;So;0;ON;;;;;N;;;;;
7207 2312;ARC;So;0;ON;;;;;N;;;;;
7208 2313;SEGMENT;So;0;ON;;;;;N;;;;;
7209 2314;SECTOR;So;0;ON;;;;;N;;;;;
7210 2315;TELEPHONE RECORDER;So;0;ON;;;;;N;;;;;
7211 2316;POSITION INDICATOR;So;0;ON;;;;;N;;;;;
7212 2317;VIEWDATA SQUARE;So;0;ON;;;;;N;;;;;
7213 2318;PLACE OF INTEREST SIGN;So;0;ON;;;;;N;COMMAND KEY;;;;
7214 2319;TURNED NOT SIGN;So;0;ON;;;;;N;;;;;
7215 231A;WATCH;So;0;ON;;;;;N;;;;;
7216 231B;HOURGLASS;So;0;ON;;;;;N;;;;;
7217 231C;TOP LEFT CORNER;So;0;ON;;;;;N;;;;;
7218 231D;TOP RIGHT CORNER;So;0;ON;;;;;N;;;;;
7219 231E;BOTTOM LEFT CORNER;So;0;ON;;;;;N;;;;;
7220 231F;BOTTOM RIGHT CORNER;So;0;ON;;;;;N;;;;;
7221 2320;TOP HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;;
7222 2321;BOTTOM HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;;
7223 2322;FROWN;So;0;ON;;;;;N;;;;;
7224 2323;SMILE;So;0;ON;;;;;N;;;;;
7225 2324;UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS;So;0;ON;;;;;N;ENTER KEY;;;;
7226 2325;OPTION KEY;So;0;ON;;;;;N;;;;;
7227 2326;ERASE TO THE RIGHT;So;0;ON;;;;;N;DELETE TO THE RIGHT KEY;;;;
7228 2327;X IN A RECTANGLE BOX;So;0;ON;;;;;N;CLEAR KEY;;;;
7229 2328;KEYBOARD;So;0;ON;;;;;N;;;;;
7230 2329;LEFT-POINTING ANGLE BRACKET;Ps;0;ON;3008;;;;Y;BRA;;;;
7231 232A;RIGHT-POINTING ANGLE BRACKET;Pe;0;ON;3009;;;;Y;KET;;;;
7232 232B;ERASE TO THE LEFT;So;0;ON;;;;;N;DELETE TO THE LEFT KEY;;;;
7233 232C;BENZENE RING;So;0;ON;;;;;N;;;;;
7234 232D;CYLINDRICITY;So;0;ON;;;;;N;;;;;
7235 232E;ALL AROUND-PROFILE;So;0;ON;;;;;N;;;;;
7236 232F;SYMMETRY;So;0;ON;;;;;N;;;;;
7237 2330;TOTAL RUNOUT;So;0;ON;;;;;N;;;;;
7238 2331;DIMENSION ORIGIN;So;0;ON;;;;;N;;;;;
7239 2332;CONICAL TAPER;So;0;ON;;;;;N;;;;;
7240 2333;SLOPE;So;0;ON;;;;;N;;;;;
7241 2334;COUNTERBORE;So;0;ON;;;;;N;;;;;
7242 2335;COUNTERSINK;So;0;ON;;;;;N;;;;;
7243 2336;APL FUNCTIONAL SYMBOL I-BEAM;So;0;L;;;;;N;;;;;
7244 2337;APL FUNCTIONAL SYMBOL SQUISH QUAD;So;0;L;;;;;N;;;;;
7245 2338;APL FUNCTIONAL SYMBOL QUAD EQUAL;So;0;L;;;;;N;;;;;
7246 2339;APL FUNCTIONAL SYMBOL QUAD DIVIDE;So;0;L;;;;;N;;;;;
7247 233A;APL FUNCTIONAL SYMBOL QUAD DIAMOND;So;0;L;;;;;N;;;;;
7248 233B;APL FUNCTIONAL SYMBOL QUAD JOT;So;0;L;;;;;N;;;;;
7249 233C;APL FUNCTIONAL SYMBOL QUAD CIRCLE;So;0;L;;;;;N;;;;;
7250 233D;APL FUNCTIONAL SYMBOL CIRCLE STILE;So;0;L;;;;;N;;;;;
7251 233E;APL FUNCTIONAL SYMBOL CIRCLE JOT;So;0;L;;;;;N;;;;;
7252 233F;APL FUNCTIONAL SYMBOL SLASH BAR;So;0;L;;;;;N;;;;;
7253 2340;APL FUNCTIONAL SYMBOL BACKSLASH BAR;So;0;L;;;;;N;;;;;
7254 2341;APL FUNCTIONAL SYMBOL QUAD SLASH;So;0;L;;;;;N;;;;;
7255 2342;APL FUNCTIONAL SYMBOL QUAD BACKSLASH;So;0;L;;;;;N;;;;;
7256 2343;APL FUNCTIONAL SYMBOL QUAD LESS-THAN;So;0;L;;;;;N;;;;;
7257 2344;APL FUNCTIONAL SYMBOL QUAD GREATER-THAN;So;0;L;;;;;N;;;;;
7258 2345;APL FUNCTIONAL SYMBOL LEFTWARDS VANE;So;0;L;;;;;N;;;;;
7259 2346;APL FUNCTIONAL SYMBOL RIGHTWARDS VANE;So;0;L;;;;;N;;;;;
7260 2347;APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW;So;0;L;;;;;N;;;;;
7261 2348;APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW;So;0;L;;;;;N;;;;;
7262 2349;APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH;So;0;L;;;;;N;;;;;
7263 234A;APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR;So;0;L;;;;;N;;*;;;
7264 234B;APL FUNCTIONAL SYMBOL DELTA STILE;So;0;L;;;;;N;;;;;
7265 234C;APL FUNCTIONAL SYMBOL QUAD DOWN CARET;So;0;L;;;;;N;;;;;
7266 234D;APL FUNCTIONAL SYMBOL QUAD DELTA;So;0;L;;;;;N;;;;;
7267 234E;APL FUNCTIONAL SYMBOL DOWN TACK JOT;So;0;L;;;;;N;;*;;;
7268 234F;APL FUNCTIONAL SYMBOL UPWARDS VANE;So;0;L;;;;;N;;;;;
7269 2350;APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW;So;0;L;;;;;N;;;;;
7270 2351;APL FUNCTIONAL SYMBOL UP TACK OVERBAR;So;0;L;;;;;N;;*;;;
7271 2352;APL FUNCTIONAL SYMBOL DEL STILE;So;0;L;;;;;N;;;;;
7272 2353;APL FUNCTIONAL SYMBOL QUAD UP CARET;So;0;L;;;;;N;;;;;
7273 2354;APL FUNCTIONAL SYMBOL QUAD DEL;So;0;L;;;;;N;;;;;
7274 2355;APL FUNCTIONAL SYMBOL UP TACK JOT;So;0;L;;;;;N;;*;;;
7275 2356;APL FUNCTIONAL SYMBOL DOWNWARDS VANE;So;0;L;;;;;N;;;;;
7276 2357;APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW;So;0;L;;;;;N;;;;;
7277 2358;APL FUNCTIONAL SYMBOL QUOTE UNDERBAR;So;0;L;;;;;N;;;;;
7278 2359;APL FUNCTIONAL SYMBOL DELTA UNDERBAR;So;0;L;;;;;N;;;;;
7279 235A;APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR;So;0;L;;;;;N;;;;;
7280 235B;APL FUNCTIONAL SYMBOL JOT UNDERBAR;So;0;L;;;;;N;;;;;
7281 235C;APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR;So;0;L;;;;;N;;;;;
7282 235D;APL FUNCTIONAL SYMBOL UP SHOE JOT;So;0;L;;;;;N;;;;;
7283 235E;APL FUNCTIONAL SYMBOL QUOTE QUAD;So;0;L;;;;;N;;;;;
7284 235F;APL FUNCTIONAL SYMBOL CIRCLE STAR;So;0;L;;;;;N;;;;;
7285 2360;APL FUNCTIONAL SYMBOL QUAD COLON;So;0;L;;;;;N;;;;;
7286 2361;APL FUNCTIONAL SYMBOL UP TACK DIAERESIS;So;0;L;;;;;N;;*;;;
7287 2362;APL FUNCTIONAL SYMBOL DEL DIAERESIS;So;0;L;;;;;N;;;;;
7288 2363;APL FUNCTIONAL SYMBOL STAR DIAERESIS;So;0;L;;;;;N;;;;;
7289 2364;APL FUNCTIONAL SYMBOL JOT DIAERESIS;So;0;L;;;;;N;;;;;
7290 2365;APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS;So;0;L;;;;;N;;;;;
7291 2366;APL FUNCTIONAL SYMBOL DOWN SHOE STILE;So;0;L;;;;;N;;;;;
7292 2367;APL FUNCTIONAL SYMBOL LEFT SHOE STILE;So;0;L;;;;;N;;;;;
7293 2368;APL FUNCTIONAL SYMBOL TILDE DIAERESIS;So;0;L;;;;;N;;;;;
7294 2369;APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS;So;0;L;;;;;N;;;;;
7295 236A;APL FUNCTIONAL SYMBOL COMMA BAR;So;0;L;;;;;N;;;;;
7296 236B;APL FUNCTIONAL SYMBOL DEL TILDE;So;0;L;;;;;N;;;;;
7297 236C;APL FUNCTIONAL SYMBOL ZILDE;So;0;L;;;;;N;;;;;
7298 236D;APL FUNCTIONAL SYMBOL STILE TILDE;So;0;L;;;;;N;;;;;
7299 236E;APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR;So;0;L;;;;;N;;;;;
7300 236F;APL FUNCTIONAL SYMBOL QUAD NOT EQUAL;So;0;L;;;;;N;;;;;
7301 2370;APL FUNCTIONAL SYMBOL QUAD QUESTION;So;0;L;;;;;N;;;;;
7302 2371;APL FUNCTIONAL SYMBOL DOWN CARET TILDE;So;0;L;;;;;N;;;;;
7303 2372;APL FUNCTIONAL SYMBOL UP CARET TILDE;So;0;L;;;;;N;;;;;
7304 2373;APL FUNCTIONAL SYMBOL IOTA;So;0;L;;;;;N;;;;;
7305 2374;APL FUNCTIONAL SYMBOL RHO;So;0;L;;;;;N;;;;;
7306 2375;APL FUNCTIONAL SYMBOL OMEGA;So;0;L;;;;;N;;;;;
7307 2376;APL FUNCTIONAL SYMBOL ALPHA UNDERBAR;So;0;L;;;;;N;;;;;
7308 2377;APL FUNCTIONAL SYMBOL EPSILON UNDERBAR;So;0;L;;;;;N;;;;;
7309 2378;APL FUNCTIONAL SYMBOL IOTA UNDERBAR;So;0;L;;;;;N;;;;;
7310 2379;APL FUNCTIONAL SYMBOL OMEGA UNDERBAR;So;0;L;;;;;N;;;;;
7311 237A;APL FUNCTIONAL SYMBOL ALPHA;So;0;L;;;;;N;;;;;
7312 237B;NOT CHECK MARK;So;0;ON;;;;;N;;;;;
7313 237C;RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW;Sm;0;ON;;;;;N;;;;;
7314 237D;SHOULDERED OPEN BOX;So;0;ON;;;;;N;;;;;
7315 237E;BELL SYMBOL;So;0;ON;;;;;N;;;;;
7316 237F;VERTICAL LINE WITH MIDDLE DOT;So;0;ON;;;;;N;;;;;
7317 2380;INSERTION SYMBOL;So;0;ON;;;;;N;;;;;
7318 2381;CONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;;
7319 2382;DISCONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;;
7320 2383;EMPHASIS SYMBOL;So;0;ON;;;;;N;;;;;
7321 2384;COMPOSITION SYMBOL;So;0;ON;;;;;N;;;;;
7322 2385;WHITE SQUARE WITH CENTRE VERTICAL LINE;So;0;ON;;;;;N;;;;;
7323 2386;ENTER SYMBOL;So;0;ON;;;;;N;;;;;
7324 2387;ALTERNATIVE KEY SYMBOL;So;0;ON;;;;;N;;;;;
7325 2388;HELM SYMBOL;So;0;ON;;;;;N;;;;;
7326 2389;CIRCLED HORIZONTAL BAR WITH NOTCH;So;0;ON;;;;;N;;pause;;;
7327 238A;CIRCLED TRIANGLE DOWN;So;0;ON;;;;;N;;break;;;
7328 238B;BROKEN CIRCLE WITH NORTHWEST ARROW;So;0;ON;;;;;N;;escape;;;
7329 238C;UNDO SYMBOL;So;0;ON;;;;;N;;;;;
7330 238D;MONOSTABLE SYMBOL;So;0;ON;;;;;N;;;;;
7331 238E;HYSTERESIS SYMBOL;So;0;ON;;;;;N;;;;;
7332 238F;OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL;So;0;ON;;;;;N;;;;;
7333 2390;OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL;So;0;ON;;;;;N;;;;;
7334 2391;PASSIVE-PULL-DOWN-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;;
7335 2392;PASSIVE-PULL-UP-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;;
7336 2393;DIRECT CURRENT SYMBOL FORM TWO;So;0;ON;;;;;N;;;;;
7337 2394;SOFTWARE-FUNCTION SYMBOL;So;0;ON;;;;;N;;;;;
7338 2395;APL FUNCTIONAL SYMBOL QUAD;So;0;L;;;;;N;;;;;
7339 2396;DECIMAL SEPARATOR KEY SYMBOL;So;0;ON;;;;;N;;;;;
7340 2397;PREVIOUS PAGE;So;0;ON;;;;;N;;;;;
7341 2398;NEXT PAGE;So;0;ON;;;;;N;;;;;
7342 2399;PRINT SCREEN SYMBOL;So;0;ON;;;;;N;;;;;
7343 239A;CLEAR SCREEN SYMBOL;So;0;ON;;;;;N;;;;;
7344 239B;LEFT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;;
7345 239C;LEFT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;;
7346 239D;LEFT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;;
7347 239E;RIGHT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;;
7348 239F;RIGHT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;;
7349 23A0;RIGHT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;;
7350 23A1;LEFT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;;
7351 23A2;LEFT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;;
7352 23A3;LEFT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;;
7353 23A4;RIGHT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;;
7354 23A5;RIGHT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;;
7355 23A6;RIGHT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;;
7356 23A7;LEFT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;;
7357 23A8;LEFT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;;
7358 23A9;LEFT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;;
7359 23AA;CURLY BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;;
7360 23AB;RIGHT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;;
7361 23AC;RIGHT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;;
7362 23AD;RIGHT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;;
7363 23AE;INTEGRAL EXTENSION;Sm;0;ON;;;;;N;;;;;
7364 23AF;HORIZONTAL LINE EXTENSION;Sm;0;ON;;;;;N;;;;;
7365 23B0;UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;;
7366 23B1;UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;;
7367 23B2;SUMMATION TOP;Sm;0;ON;;;;;N;;;;;
7368 23B3;SUMMATION BOTTOM;Sm;0;ON;;;;;N;;;;;
7369 23B4;TOP SQUARE BRACKET;So;0;ON;;;;;N;;;;;
7370 23B5;BOTTOM SQUARE BRACKET;So;0;ON;;;;;N;;;;;
7371 23B6;BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET;So;0;ON;;;;;N;;;;;
7372 23B7;RADICAL SYMBOL BOTTOM;So;0;ON;;;;;N;;;;;
7373 23B8;LEFT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;;
7374 23B9;RIGHT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;;
7375 23BA;HORIZONTAL SCAN LINE-1;So;0;ON;;;;;N;;;;;
7376 23BB;HORIZONTAL SCAN LINE-3;So;0;ON;;;;;N;;;;;
7377 23BC;HORIZONTAL SCAN LINE-7;So;0;ON;;;;;N;;;;;
7378 23BD;HORIZONTAL SCAN LINE-9;So;0;ON;;;;;N;;;;;
7379 23BE;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT;So;0;ON;;;;;N;;;;;
7380 23BF;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT;So;0;ON;;;;;N;;;;;
7381 23C0;DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE;So;0;ON;;;;;N;;;;;
7382 23C1;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;;
7383 23C2;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;;
7384 23C3;DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE;So;0;ON;;;;;N;;;;;
7385 23C4;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;;
7386 23C5;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;;
7387 23C6;DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE;So;0;ON;;;;;N;;;;;
7388 23C7;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;;
7389 23C8;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;;
7390 23C9;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;;;;;
7391 23CA;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;;;;;
7392 23CB;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT;So;0;ON;;;;;N;;;;;
7393 23CC;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT;So;0;ON;;;;;N;;;;;
7394 23CD;SQUARE FOOT;So;0;ON;;;;;N;;;;;
7395 23CE;RETURN SYMBOL;So;0;ON;;;;;N;;;;;
7396 23CF;EJECT SYMBOL;So;0;ON;;;;;N;;;;;
7397 23D0;VERTICAL LINE EXTENSION;So;0;ON;;;;;N;;;;;
7398 23D1;METRICAL BREVE;So;0;ON;;;;;N;;;;;
7399 23D2;METRICAL LONG OVER SHORT;So;0;ON;;;;;N;;;;;
7400 23D3;METRICAL SHORT OVER LONG;So;0;ON;;;;;N;;;;;
7401 23D4;METRICAL LONG OVER TWO SHORTS;So;0;ON;;;;;N;;;;;
7402 23D5;METRICAL TWO SHORTS OVER LONG;So;0;ON;;;;;N;;;;;
7403 23D6;METRICAL TWO SHORTS JOINED;So;0;ON;;;;;N;;;;;
7404 23D7;METRICAL TRISEME;So;0;ON;;;;;N;;;;;
7405 23D8;METRICAL TETRASEME;So;0;ON;;;;;N;;;;;
7406 23D9;METRICAL PENTASEME;So;0;ON;;;;;N;;;;;
7407 23DA;EARTH GROUND;So;0;ON;;;;;N;;;;;
7408 23DB;FUSE;So;0;ON;;;;;N;;;;;
7409 23DC;TOP PARENTHESIS;Sm;0;ON;;;;;N;;mathematical use;;;
7410 23DD;BOTTOM PARENTHESIS;Sm;0;ON;;;;;N;;mathematical use;;;
7411 23DE;TOP CURLY BRACKET;Sm;0;ON;;;;;N;;mathematical use;;;
7412 23DF;BOTTOM CURLY BRACKET;Sm;0;ON;;;;;N;;mathematical use;;;
7413 23E0;TOP TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;mathematical use;;;
7414 23E1;BOTTOM TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;mathematical use;;;
7415 23E2;WHITE TRAPEZIUM;So;0;ON;;;;;N;;;;;
7416 23E3;BENZENE RING WITH CIRCLE;So;0;ON;;;;;N;;;;;
7417 23E4;STRAIGHTNESS;So;0;ON;;;;;N;;;;;
7418 23E5;FLATNESS;So;0;ON;;;;;N;;;;;
7419 23E6;AC CURRENT;So;0;ON;;;;;N;;;;;
7420 23E7;ELECTRICAL INTERSECTION;So;0;ON;;;;;N;;;;;
7421 2400;SYMBOL FOR NULL;So;0;ON;;;;;N;GRAPHIC FOR NULL;;;;
7422 2401;SYMBOL FOR START OF HEADING;So;0;ON;;;;;N;GRAPHIC FOR START OF HEADING;;;;
7423 2402;SYMBOL FOR START OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR START OF TEXT;;;;
7424 2403;SYMBOL FOR END OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR END OF TEXT;;;;
7425 2404;SYMBOL FOR END OF TRANSMISSION;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION;;;;
7426 2405;SYMBOL FOR ENQUIRY;So;0;ON;;;;;N;GRAPHIC FOR ENQUIRY;;;;
7427 2406;SYMBOL FOR ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR ACKNOWLEDGE;;;;
7428 2407;SYMBOL FOR BELL;So;0;ON;;;;;N;GRAPHIC FOR BELL;;;;
7429 2408;SYMBOL FOR BACKSPACE;So;0;ON;;;;;N;GRAPHIC FOR BACKSPACE;;;;
7430 2409;SYMBOL FOR HORIZONTAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR HORIZONTAL TABULATION;;;;
7431 240A;SYMBOL FOR LINE FEED;So;0;ON;;;;;N;GRAPHIC FOR LINE FEED;;;;
7432 240B;SYMBOL FOR VERTICAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR VERTICAL TABULATION;;;;
7433 240C;SYMBOL FOR FORM FEED;So;0;ON;;;;;N;GRAPHIC FOR FORM FEED;;;;
7434 240D;SYMBOL FOR CARRIAGE RETURN;So;0;ON;;;;;N;GRAPHIC FOR CARRIAGE RETURN;;;;
7435 240E;SYMBOL FOR SHIFT OUT;So;0;ON;;;;;N;GRAPHIC FOR SHIFT OUT;;;;
7436 240F;SYMBOL FOR SHIFT IN;So;0;ON;;;;;N;GRAPHIC FOR SHIFT IN;;;;
7437 2410;SYMBOL FOR DATA LINK ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR DATA LINK ESCAPE;;;;
7438 2411;SYMBOL FOR DEVICE CONTROL ONE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL ONE;;;;
7439 2412;SYMBOL FOR DEVICE CONTROL TWO;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL TWO;;;;
7440 2413;SYMBOL FOR DEVICE CONTROL THREE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL THREE;;;;
7441 2414;SYMBOL FOR DEVICE CONTROL FOUR;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL FOUR;;;;
7442 2415;SYMBOL FOR NEGATIVE ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR NEGATIVE ACKNOWLEDGE;;;;
7443 2416;SYMBOL FOR SYNCHRONOUS IDLE;So;0;ON;;;;;N;GRAPHIC FOR SYNCHRONOUS IDLE;;;;
7444 2417;SYMBOL FOR END OF TRANSMISSION BLOCK;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION BLOCK;;;;
7445 2418;SYMBOL FOR CANCEL;So;0;ON;;;;;N;GRAPHIC FOR CANCEL;;;;
7446 2419;SYMBOL FOR END OF MEDIUM;So;0;ON;;;;;N;GRAPHIC FOR END OF MEDIUM;;;;
7447 241A;SYMBOL FOR SUBSTITUTE;So;0;ON;;;;;N;GRAPHIC FOR SUBSTITUTE;;;;
7448 241B;SYMBOL FOR ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR ESCAPE;;;;
7449 241C;SYMBOL FOR FILE SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR FILE SEPARATOR;;;;
7450 241D;SYMBOL FOR GROUP SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR GROUP SEPARATOR;;;;
7451 241E;SYMBOL FOR RECORD SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR RECORD SEPARATOR;;;;
7452 241F;SYMBOL FOR UNIT SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR UNIT SEPARATOR;;;;
7453 2420;SYMBOL FOR SPACE;So;0;ON;;;;;N;GRAPHIC FOR SPACE;;;;
7454 2421;SYMBOL FOR DELETE;So;0;ON;;;;;N;GRAPHIC FOR DELETE;;;;
7455 2422;BLANK SYMBOL;So;0;ON;;;;;N;BLANK;;;;
7456 2423;OPEN BOX;So;0;ON;;;;;N;;;;;
7457 2424;SYMBOL FOR NEWLINE;So;0;ON;;;;;N;GRAPHIC FOR NEWLINE;;;;
7458 2425;SYMBOL FOR DELETE FORM TWO;So;0;ON;;;;;N;;;;;
7459 2426;SYMBOL FOR SUBSTITUTE FORM TWO;So;0;ON;;;;;N;;;;;
7460 2440;OCR HOOK;So;0;ON;;;;;N;;;;;
7461 2441;OCR CHAIR;So;0;ON;;;;;N;;;;;
7462 2442;OCR FORK;So;0;ON;;;;;N;;;;;
7463 2443;OCR INVERTED FORK;So;0;ON;;;;;N;;;;;
7464 2444;OCR BELT BUCKLE;So;0;ON;;;;;N;;;;;
7465 2445;OCR BOW TIE;So;0;ON;;;;;N;;;;;
7466 2446;OCR BRANCH BANK IDENTIFICATION;So;0;ON;;;;;N;;;;;
7467 2447;OCR AMOUNT OF CHECK;So;0;ON;;;;;N;;;;;
7468 2448;OCR DASH;So;0;ON;;;;;N;;;;;
7469 2449;OCR CUSTOMER ACCOUNT NUMBER;So;0;ON;;;;;N;;;;;
7470 244A;OCR DOUBLE BACKSLASH;So;0;ON;;;;;N;;;;;
7471 2460;CIRCLED DIGIT ONE;No;0;ON;<circle> 0031;;1;1;N;;;;;
7472 2461;CIRCLED DIGIT TWO;No;0;ON;<circle> 0032;;2;2;N;;;;;
7473 2462;CIRCLED DIGIT THREE;No;0;ON;<circle> 0033;;3;3;N;;;;;
7474 2463;CIRCLED DIGIT FOUR;No;0;ON;<circle> 0034;;4;4;N;;;;;
7475 2464;CIRCLED DIGIT FIVE;No;0;ON;<circle> 0035;;5;5;N;;;;;
7476 2465;CIRCLED DIGIT SIX;No;0;ON;<circle> 0036;;6;6;N;;;;;
7477 2466;CIRCLED DIGIT SEVEN;No;0;ON;<circle> 0037;;7;7;N;;;;;
7478 2467;CIRCLED DIGIT EIGHT;No;0;ON;<circle> 0038;;8;8;N;;;;;
7479 2468;CIRCLED DIGIT NINE;No;0;ON;<circle> 0039;;9;9;N;;;;;
7480 2469;CIRCLED NUMBER TEN;No;0;ON;<circle> 0031 0030;;;10;N;;;;;
7481 246A;CIRCLED NUMBER ELEVEN;No;0;ON;<circle> 0031 0031;;;11;N;;;;;
7482 246B;CIRCLED NUMBER TWELVE;No;0;ON;<circle> 0031 0032;;;12;N;;;;;
7483 246C;CIRCLED NUMBER THIRTEEN;No;0;ON;<circle> 0031 0033;;;13;N;;;;;
7484 246D;CIRCLED NUMBER FOURTEEN;No;0;ON;<circle> 0031 0034;;;14;N;;;;;
7485 246E;CIRCLED NUMBER FIFTEEN;No;0;ON;<circle> 0031 0035;;;15;N;;;;;
7486 246F;CIRCLED NUMBER SIXTEEN;No;0;ON;<circle> 0031 0036;;;16;N;;;;;
7487 2470;CIRCLED NUMBER SEVENTEEN;No;0;ON;<circle> 0031 0037;;;17;N;;;;;
7488 2471;CIRCLED NUMBER EIGHTEEN;No;0;ON;<circle> 0031 0038;;;18;N;;;;;
7489 2472;CIRCLED NUMBER NINETEEN;No;0;ON;<circle> 0031 0039;;;19;N;;;;;
7490 2473;CIRCLED NUMBER TWENTY;No;0;ON;<circle> 0032 0030;;;20;N;;;;;
7491 2474;PARENTHESIZED DIGIT ONE;No;0;ON;<compat> 0028 0031 0029;;1;1;N;;;;;
7492 2475;PARENTHESIZED DIGIT TWO;No;0;ON;<compat> 0028 0032 0029;;2;2;N;;;;;
7493 2476;PARENTHESIZED DIGIT THREE;No;0;ON;<compat> 0028 0033 0029;;3;3;N;;;;;
7494 2477;PARENTHESIZED DIGIT FOUR;No;0;ON;<compat> 0028 0034 0029;;4;4;N;;;;;
7495 2478;PARENTHESIZED DIGIT FIVE;No;0;ON;<compat> 0028 0035 0029;;5;5;N;;;;;
7496 2479;PARENTHESIZED DIGIT SIX;No;0;ON;<compat> 0028 0036 0029;;6;6;N;;;;;
7497 247A;PARENTHESIZED DIGIT SEVEN;No;0;ON;<compat> 0028 0037 0029;;7;7;N;;;;;
7498 247B;PARENTHESIZED DIGIT EIGHT;No;0;ON;<compat> 0028 0038 0029;;8;8;N;;;;;
7499 247C;PARENTHESIZED DIGIT NINE;No;0;ON;<compat> 0028 0039 0029;;9;9;N;;;;;
7500 247D;PARENTHESIZED NUMBER TEN;No;0;ON;<compat> 0028 0031 0030 0029;;;10;N;;;;;
7501 247E;PARENTHESIZED NUMBER ELEVEN;No;0;ON;<compat> 0028 0031 0031 0029;;;11;N;;;;;
7502 247F;PARENTHESIZED NUMBER TWELVE;No;0;ON;<compat> 0028 0031 0032 0029;;;12;N;;;;;
7503 2480;PARENTHESIZED NUMBER THIRTEEN;No;0;ON;<compat> 0028 0031 0033 0029;;;13;N;;;;;
7504 2481;PARENTHESIZED NUMBER FOURTEEN;No;0;ON;<compat> 0028 0031 0034 0029;;;14;N;;;;;
7505 2482;PARENTHESIZED NUMBER FIFTEEN;No;0;ON;<compat> 0028 0031 0035 0029;;;15;N;;;;;
7506 2483;PARENTHESIZED NUMBER SIXTEEN;No;0;ON;<compat> 0028 0031 0036 0029;;;16;N;;;;;
7507 2484;PARENTHESIZED NUMBER SEVENTEEN;No;0;ON;<compat> 0028 0031 0037 0029;;;17;N;;;;;
7508 2485;PARENTHESIZED NUMBER EIGHTEEN;No;0;ON;<compat> 0028 0031 0038 0029;;;18;N;;;;;
7509 2486;PARENTHESIZED NUMBER NINETEEN;No;0;ON;<compat> 0028 0031 0039 0029;;;19;N;;;;;
7510 2487;PARENTHESIZED NUMBER TWENTY;No;0;ON;<compat> 0028 0032 0030 0029;;;20;N;;;;;
7511 2488;DIGIT ONE FULL STOP;No;0;EN;<compat> 0031 002E;;1;1;N;DIGIT ONE PERIOD;;;;
7512 2489;DIGIT TWO FULL STOP;No;0;EN;<compat> 0032 002E;;2;2;N;DIGIT TWO PERIOD;;;;
7513 248A;DIGIT THREE FULL STOP;No;0;EN;<compat> 0033 002E;;3;3;N;DIGIT THREE PERIOD;;;;
7514 248B;DIGIT FOUR FULL STOP;No;0;EN;<compat> 0034 002E;;4;4;N;DIGIT FOUR PERIOD;;;;
7515 248C;DIGIT FIVE FULL STOP;No;0;EN;<compat> 0035 002E;;5;5;N;DIGIT FIVE PERIOD;;;;
7516 248D;DIGIT SIX FULL STOP;No;0;EN;<compat> 0036 002E;;6;6;N;DIGIT SIX PERIOD;;;;
7517 248E;DIGIT SEVEN FULL STOP;No;0;EN;<compat> 0037 002E;;7;7;N;DIGIT SEVEN PERIOD;;;;
7518 248F;DIGIT EIGHT FULL STOP;No;0;EN;<compat> 0038 002E;;8;8;N;DIGIT EIGHT PERIOD;;;;
7519 2490;DIGIT NINE FULL STOP;No;0;EN;<compat> 0039 002E;;9;9;N;DIGIT NINE PERIOD;;;;
7520 2491;NUMBER TEN FULL STOP;No;0;EN;<compat> 0031 0030 002E;;;10;N;NUMBER TEN PERIOD;;;;
7521 2492;NUMBER ELEVEN FULL STOP;No;0;EN;<compat> 0031 0031 002E;;;11;N;NUMBER ELEVEN PERIOD;;;;
7522 2493;NUMBER TWELVE FULL STOP;No;0;EN;<compat> 0031 0032 002E;;;12;N;NUMBER TWELVE PERIOD;;;;
7523 2494;NUMBER THIRTEEN FULL STOP;No;0;EN;<compat> 0031 0033 002E;;;13;N;NUMBER THIRTEEN PERIOD;;;;
7524 2495;NUMBER FOURTEEN FULL STOP;No;0;EN;<compat> 0031 0034 002E;;;14;N;NUMBER FOURTEEN PERIOD;;;;
7525 2496;NUMBER FIFTEEN FULL STOP;No;0;EN;<compat> 0031 0035 002E;;;15;N;NUMBER FIFTEEN PERIOD;;;;
7526 2497;NUMBER SIXTEEN FULL STOP;No;0;EN;<compat> 0031 0036 002E;;;16;N;NUMBER SIXTEEN PERIOD;;;;
7527 2498;NUMBER SEVENTEEN FULL STOP;No;0;EN;<compat> 0031 0037 002E;;;17;N;NUMBER SEVENTEEN PERIOD;;;;
7528 2499;NUMBER EIGHTEEN FULL STOP;No;0;EN;<compat> 0031 0038 002E;;;18;N;NUMBER EIGHTEEN PERIOD;;;;
7529 249A;NUMBER NINETEEN FULL STOP;No;0;EN;<compat> 0031 0039 002E;;;19;N;NUMBER NINETEEN PERIOD;;;;
7530 249B;NUMBER TWENTY FULL STOP;No;0;EN;<compat> 0032 0030 002E;;;20;N;NUMBER TWENTY PERIOD;;;;
7531 249C;PARENTHESIZED LATIN SMALL LETTER A;So;0;L;<compat> 0028 0061 0029;;;;N;;;;;
7532 249D;PARENTHESIZED LATIN SMALL LETTER B;So;0;L;<compat> 0028 0062 0029;;;;N;;;;;
7533 249E;PARENTHESIZED LATIN SMALL LETTER C;So;0;L;<compat> 0028 0063 0029;;;;N;;;;;
7534 249F;PARENTHESIZED LATIN SMALL LETTER D;So;0;L;<compat> 0028 0064 0029;;;;N;;;;;
7535 24A0;PARENTHESIZED LATIN SMALL LETTER E;So;0;L;<compat> 0028 0065 0029;;;;N;;;;;
7536 24A1;PARENTHESIZED LATIN SMALL LETTER F;So;0;L;<compat> 0028 0066 0029;;;;N;;;;;
7537 24A2;PARENTHESIZED LATIN SMALL LETTER G;So;0;L;<compat> 0028 0067 0029;;;;N;;;;;
7538 24A3;PARENTHESIZED LATIN SMALL LETTER H;So;0;L;<compat> 0028 0068 0029;;;;N;;;;;
7539 24A4;PARENTHESIZED LATIN SMALL LETTER I;So;0;L;<compat> 0028 0069 0029;;;;N;;;;;
7540 24A5;PARENTHESIZED LATIN SMALL LETTER J;So;0;L;<compat> 0028 006A 0029;;;;N;;;;;
7541 24A6;PARENTHESIZED LATIN SMALL LETTER K;So;0;L;<compat> 0028 006B 0029;;;;N;;;;;
7542 24A7;PARENTHESIZED LATIN SMALL LETTER L;So;0;L;<compat> 0028 006C 0029;;;;N;;;;;
7543 24A8;PARENTHESIZED LATIN SMALL LETTER M;So;0;L;<compat> 0028 006D 0029;;;;N;;;;;
7544 24A9;PARENTHESIZED LATIN SMALL LETTER N;So;0;L;<compat> 0028 006E 0029;;;;N;;;;;
7545 24AA;PARENTHESIZED LATIN SMALL LETTER O;So;0;L;<compat> 0028 006F 0029;;;;N;;;;;
7546 24AB;PARENTHESIZED LATIN SMALL LETTER P;So;0;L;<compat> 0028 0070 0029;;;;N;;;;;
7547 24AC;PARENTHESIZED LATIN SMALL LETTER Q;So;0;L;<compat> 0028 0071 0029;;;;N;;;;;
7548 24AD;PARENTHESIZED LATIN SMALL LETTER R;So;0;L;<compat> 0028 0072 0029;;;;N;;;;;
7549 24AE;PARENTHESIZED LATIN SMALL LETTER S;So;0;L;<compat> 0028 0073 0029;;;;N;;;;;
7550 24AF;PARENTHESIZED LATIN SMALL LETTER T;So;0;L;<compat> 0028 0074 0029;;;;N;;;;;
7551 24B0;PARENTHESIZED LATIN SMALL LETTER U;So;0;L;<compat> 0028 0075 0029;;;;N;;;;;
7552 24B1;PARENTHESIZED LATIN SMALL LETTER V;So;0;L;<compat> 0028 0076 0029;;;;N;;;;;
7553 24B2;PARENTHESIZED LATIN SMALL LETTER W;So;0;L;<compat> 0028 0077 0029;;;;N;;;;;
7554 24B3;PARENTHESIZED LATIN SMALL LETTER X;So;0;L;<compat> 0028 0078 0029;;;;N;;;;;
7555 24B4;PARENTHESIZED LATIN SMALL LETTER Y;So;0;L;<compat> 0028 0079 0029;;;;N;;;;;
7556 24B5;PARENTHESIZED LATIN SMALL LETTER Z;So;0;L;<compat> 0028 007A 0029;;;;N;;;;;
7557 24B6;CIRCLED LATIN CAPITAL LETTER A;So;0;L;<circle> 0041;;;;N;;;;24D0;
7558 24B7;CIRCLED LATIN CAPITAL LETTER B;So;0;L;<circle> 0042;;;;N;;;;24D1;
7559 24B8;CIRCLED LATIN CAPITAL LETTER C;So;0;L;<circle> 0043;;;;N;;;;24D2;
7560 24B9;CIRCLED LATIN CAPITAL LETTER D;So;0;L;<circle> 0044;;;;N;;;;24D3;
7561 24BA;CIRCLED LATIN CAPITAL LETTER E;So;0;L;<circle> 0045;;;;N;;;;24D4;
7562 24BB;CIRCLED LATIN CAPITAL LETTER F;So;0;L;<circle> 0046;;;;N;;;;24D5;
7563 24BC;CIRCLED LATIN CAPITAL LETTER G;So;0;L;<circle> 0047;;;;N;;;;24D6;
7564 24BD;CIRCLED LATIN CAPITAL LETTER H;So;0;L;<circle> 0048;;;;N;;;;24D7;
7565 24BE;CIRCLED LATIN CAPITAL LETTER I;So;0;L;<circle> 0049;;;;N;;;;24D8;
7566 24BF;CIRCLED LATIN CAPITAL LETTER J;So;0;L;<circle> 004A;;;;N;;;;24D9;
7567 24C0;CIRCLED LATIN CAPITAL LETTER K;So;0;L;<circle> 004B;;;;N;;;;24DA;
7568 24C1;CIRCLED LATIN CAPITAL LETTER L;So;0;L;<circle> 004C;;;;N;;;;24DB;
7569 24C2;CIRCLED LATIN CAPITAL LETTER M;So;0;L;<circle> 004D;;;;N;;;;24DC;
7570 24C3;CIRCLED LATIN CAPITAL LETTER N;So;0;L;<circle> 004E;;;;N;;;;24DD;
7571 24C4;CIRCLED LATIN CAPITAL LETTER O;So;0;L;<circle> 004F;;;;N;;;;24DE;
7572 24C5;CIRCLED LATIN CAPITAL LETTER P;So;0;L;<circle> 0050;;;;N;;;;24DF;
7573 24C6;CIRCLED LATIN CAPITAL LETTER Q;So;0;L;<circle> 0051;;;;N;;;;24E0;
7574 24C7;CIRCLED LATIN CAPITAL LETTER R;So;0;L;<circle> 0052;;;;N;;;;24E1;
7575 24C8;CIRCLED LATIN CAPITAL LETTER S;So;0;L;<circle> 0053;;;;N;;;;24E2;
7576 24C9;CIRCLED LATIN CAPITAL LETTER T;So;0;L;<circle> 0054;;;;N;;;;24E3;
7577 24CA;CIRCLED LATIN CAPITAL LETTER U;So;0;L;<circle> 0055;;;;N;;;;24E4;
7578 24CB;CIRCLED LATIN CAPITAL LETTER V;So;0;L;<circle> 0056;;;;N;;;;24E5;
7579 24CC;CIRCLED LATIN CAPITAL LETTER W;So;0;L;<circle> 0057;;;;N;;;;24E6;
7580 24CD;CIRCLED LATIN CAPITAL LETTER X;So;0;L;<circle> 0058;;;;N;;;;24E7;
7581 24CE;CIRCLED LATIN CAPITAL LETTER Y;So;0;L;<circle> 0059;;;;N;;;;24E8;
7582 24CF;CIRCLED LATIN CAPITAL LETTER Z;So;0;L;<circle> 005A;;;;N;;;;24E9;
7583 24D0;CIRCLED LATIN SMALL LETTER A;So;0;L;<circle> 0061;;;;N;;;24B6;;24B6
7584 24D1;CIRCLED LATIN SMALL LETTER B;So;0;L;<circle> 0062;;;;N;;;24B7;;24B7
7585 24D2;CIRCLED LATIN SMALL LETTER C;So;0;L;<circle> 0063;;;;N;;;24B8;;24B8
7586 24D3;CIRCLED LATIN SMALL LETTER D;So;0;L;<circle> 0064;;;;N;;;24B9;;24B9
7587 24D4;CIRCLED LATIN SMALL LETTER E;So;0;L;<circle> 0065;;;;N;;;24BA;;24BA
7588 24D5;CIRCLED LATIN SMALL LETTER F;So;0;L;<circle> 0066;;;;N;;;24BB;;24BB
7589 24D6;CIRCLED LATIN SMALL LETTER G;So;0;L;<circle> 0067;;;;N;;;24BC;;24BC
7590 24D7;CIRCLED LATIN SMALL LETTER H;So;0;L;<circle> 0068;;;;N;;;24BD;;24BD
7591 24D8;CIRCLED LATIN SMALL LETTER I;So;0;L;<circle> 0069;;;;N;;;24BE;;24BE
7592 24D9;CIRCLED LATIN SMALL LETTER J;So;0;L;<circle> 006A;;;;N;;;24BF;;24BF
7593 24DA;CIRCLED LATIN SMALL LETTER K;So;0;L;<circle> 006B;;;;N;;;24C0;;24C0
7594 24DB;CIRCLED LATIN SMALL LETTER L;So;0;L;<circle> 006C;;;;N;;;24C1;;24C1
7595 24DC;CIRCLED LATIN SMALL LETTER M;So;0;L;<circle> 006D;;;;N;;;24C2;;24C2
7596 24DD;CIRCLED LATIN SMALL LETTER N;So;0;L;<circle> 006E;;;;N;;;24C3;;24C3
7597 24DE;CIRCLED LATIN SMALL LETTER O;So;0;L;<circle> 006F;;;;N;;;24C4;;24C4
7598 24DF;CIRCLED LATIN SMALL LETTER P;So;0;L;<circle> 0070;;;;N;;;24C5;;24C5
7599 24E0;CIRCLED LATIN SMALL LETTER Q;So;0;L;<circle> 0071;;;;N;;;24C6;;24C6
7600 24E1;CIRCLED LATIN SMALL LETTER R;So;0;L;<circle> 0072;;;;N;;;24C7;;24C7
7601 24E2;CIRCLED LATIN SMALL LETTER S;So;0;L;<circle> 0073;;;;N;;;24C8;;24C8
7602 24E3;CIRCLED LATIN SMALL LETTER T;So;0;L;<circle> 0074;;;;N;;;24C9;;24C9
7603 24E4;CIRCLED LATIN SMALL LETTER U;So;0;L;<circle> 0075;;;;N;;;24CA;;24CA
7604 24E5;CIRCLED LATIN SMALL LETTER V;So;0;L;<circle> 0076;;;;N;;;24CB;;24CB
7605 24E6;CIRCLED LATIN SMALL LETTER W;So;0;L;<circle> 0077;;;;N;;;24CC;;24CC
7606 24E7;CIRCLED LATIN SMALL LETTER X;So;0;L;<circle> 0078;;;;N;;;24CD;;24CD
7607 24E8;CIRCLED LATIN SMALL LETTER Y;So;0;L;<circle> 0079;;;;N;;;24CE;;24CE
7608 24E9;CIRCLED LATIN SMALL LETTER Z;So;0;L;<circle> 007A;;;;N;;;24CF;;24CF
7609 24EA;CIRCLED DIGIT ZERO;No;0;ON;<circle> 0030;;0;0;N;;;;;
7610 24EB;NEGATIVE CIRCLED NUMBER ELEVEN;No;0;ON;;;;11;N;;;;;
7611 24EC;NEGATIVE CIRCLED NUMBER TWELVE;No;0;ON;;;;12;N;;;;;
7612 24ED;NEGATIVE CIRCLED NUMBER THIRTEEN;No;0;ON;;;;13;N;;;;;
7613 24EE;NEGATIVE CIRCLED NUMBER FOURTEEN;No;0;ON;;;;14;N;;;;;
7614 24EF;NEGATIVE CIRCLED NUMBER FIFTEEN;No;0;ON;;;;15;N;;;;;
7615 24F0;NEGATIVE CIRCLED NUMBER SIXTEEN;No;0;ON;;;;16;N;;;;;
7616 24F1;NEGATIVE CIRCLED NUMBER SEVENTEEN;No;0;ON;;;;17;N;;;;;
7617 24F2;NEGATIVE CIRCLED NUMBER EIGHTEEN;No;0;ON;;;;18;N;;;;;
7618 24F3;NEGATIVE CIRCLED NUMBER NINETEEN;No;0;ON;;;;19;N;;;;;
7619 24F4;NEGATIVE CIRCLED NUMBER TWENTY;No;0;ON;;;;20;N;;;;;
7620 24F5;DOUBLE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;;;;;
7621 24F6;DOUBLE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;;;;;
7622 24F7;DOUBLE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;;;;;
7623 24F8;DOUBLE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;;;;;
7624 24F9;DOUBLE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;;;;;
7625 24FA;DOUBLE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;;;;;
7626 24FB;DOUBLE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;;;;;
7627 24FC;DOUBLE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;;;;;
7628 24FD;DOUBLE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;;;;;
7629 24FE;DOUBLE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;;;;;
7630 24FF;NEGATIVE CIRCLED DIGIT ZERO;No;0;ON;;;0;0;N;;;;;
7631 2500;BOX DRAWINGS LIGHT HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT HORIZONTAL;;;;
7632 2501;BOX DRAWINGS HEAVY HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY HORIZONTAL;;;;
7633 2502;BOX DRAWINGS LIGHT VERTICAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL;;;;
7634 2503;BOX DRAWINGS HEAVY VERTICAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL;;;;
7635 2504;BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH HORIZONTAL;;;;
7636 2505;BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH HORIZONTAL;;;;
7637 2506;BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH VERTICAL;;;;
7638 2507;BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH VERTICAL;;;;
7639 2508;BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH HORIZONTAL;;;;
7640 2509;BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH HORIZONTAL;;;;
7641 250A;BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH VERTICAL;;;;
7642 250B;BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH VERTICAL;;;;
7643 250C;BOX DRAWINGS LIGHT DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND RIGHT;;;;
7644 250D;BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT HEAVY;;;;
7645 250E;BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT LIGHT;;;;
7646 250F;BOX DRAWINGS HEAVY DOWN AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND RIGHT;;;;
7647 2510;BOX DRAWINGS LIGHT DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND LEFT;;;;
7648 2511;BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT HEAVY;;;;
7649 2512;BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT LIGHT;;;;
7650 2513;BOX DRAWINGS HEAVY DOWN AND LEFT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND LEFT;;;;
7651 2514;BOX DRAWINGS LIGHT UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT UP AND RIGHT;;;;
7652 2515;BOX DRAWINGS UP LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT HEAVY;;;;
7653 2516;BOX DRAWINGS UP HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT LIGHT;;;;
7654 2517;BOX DRAWINGS HEAVY UP AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY UP AND RIGHT;;;;
7655 2518;BOX DRAWINGS LIGHT UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT UP AND LEFT;;;;
7656 2519;BOX DRAWINGS UP LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT HEAVY;;;;
7657 251A;BOX DRAWINGS UP HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT LIGHT;;;;
7658 251B;BOX DRAWINGS HEAVY UP AND LEFT;So;0;ON;;;;;N;FORMS HEAVY UP AND LEFT;;;;
7659 251C;BOX DRAWINGS LIGHT VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND RIGHT;;;;
7660 251D;BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND RIGHT HEAVY;;;;
7661 251E;BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT DOWN LIGHT;;;;
7662 251F;BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT UP LIGHT;;;;
7663 2520;BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND RIGHT LIGHT;;;;
7664 2521;BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT UP HEAVY;;;;
7665 2522;BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT DOWN HEAVY;;;;
7666 2523;BOX DRAWINGS HEAVY VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND RIGHT;;;;
7667 2524;BOX DRAWINGS LIGHT VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND LEFT;;;;
7668 2525;BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND LEFT HEAVY;;;;
7669 2526;BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT DOWN LIGHT;;;;
7670 2527;BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT UP LIGHT;;;;
7671 2528;BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND LEFT LIGHT;;;;
7672 2529;BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT UP HEAVY;;;;
7673 252A;BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT DOWN HEAVY;;;;
7674 252B;BOX DRAWINGS HEAVY VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND LEFT;;;;
7675 252C;BOX DRAWINGS LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOWN AND HORIZONTAL;;;;
7676 252D;BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT DOWN LIGHT;;;;
7677 252E;BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT DOWN LIGHT;;;;
7678 252F;BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND HORIZONTAL HEAVY;;;;
7679 2530;BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND HORIZONTAL LIGHT;;;;
7680 2531;BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT DOWN HEAVY;;;;
7681 2532;BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT DOWN HEAVY;;;;
7682 2533;BOX DRAWINGS HEAVY DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOWN AND HORIZONTAL;;;;
7683 2534;BOX DRAWINGS LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT UP AND HORIZONTAL;;;;
7684 2535;BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT UP LIGHT;;;;
7685 2536;BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT UP LIGHT;;;;
7686 2537;BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND HORIZONTAL HEAVY;;;;
7687 2538;BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND HORIZONTAL LIGHT;;;;
7688 2539;BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT UP HEAVY;;;;
7689 253A;BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT UP HEAVY;;;;
7690 253B;BOX DRAWINGS HEAVY UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY UP AND HORIZONTAL;;;;
7691 253C;BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND HORIZONTAL;;;;
7692 253D;BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT VERTICAL LIGHT;;;;
7693 253E;BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT VERTICAL LIGHT;;;;
7694 253F;BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND HORIZONTAL HEAVY;;;;
7695 2540;BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND DOWN HORIZONTAL LIGHT;;;;
7696 2541;BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND UP HORIZONTAL LIGHT;;;;
7697 2542;BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND HORIZONTAL LIGHT;;;;
7698 2543;BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT UP HEAVY AND RIGHT DOWN LIGHT;;;;
7699 2544;BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT UP HEAVY AND LEFT DOWN LIGHT;;;;
7700 2545;BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT DOWN HEAVY AND RIGHT UP LIGHT;;;;
7701 2546;BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT DOWN HEAVY AND LEFT UP LIGHT;;;;
7702 2547;BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND UP HORIZONTAL HEAVY;;;;
7703 2548;BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND DOWN HORIZONTAL HEAVY;;;;
7704 2549;BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT VERTICAL HEAVY;;;;
7705 254A;BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT VERTICAL HEAVY;;;;
7706 254B;BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND HORIZONTAL;;;;
7707 254C;BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH HORIZONTAL;;;;
7708 254D;BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH HORIZONTAL;;;;
7709 254E;BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH VERTICAL;;;;
7710 254F;BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH VERTICAL;;;;
7711 2550;BOX DRAWINGS DOUBLE HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE HORIZONTAL;;;;
7712 2551;BOX DRAWINGS DOUBLE VERTICAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL;;;;
7713 2552;BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND RIGHT DOUBLE;;;;
7714 2553;BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND RIGHT SINGLE;;;;
7715 2554;BOX DRAWINGS DOUBLE DOWN AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND RIGHT;;;;
7716 2555;BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND LEFT DOUBLE;;;;
7717 2556;BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND LEFT SINGLE;;;;
7718 2557;BOX DRAWINGS DOUBLE DOWN AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND LEFT;;;;
7719 2558;BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND RIGHT DOUBLE;;;;
7720 2559;BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND RIGHT SINGLE;;;;
7721 255A;BOX DRAWINGS DOUBLE UP AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE UP AND RIGHT;;;;
7722 255B;BOX DRAWINGS UP SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND LEFT DOUBLE;;;;
7723 255C;BOX DRAWINGS UP DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND LEFT SINGLE;;;;
7724 255D;BOX DRAWINGS DOUBLE UP AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE UP AND LEFT;;;;
7725 255E;BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND RIGHT DOUBLE;;;;
7726 255F;BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND RIGHT SINGLE;;;;
7727 2560;BOX DRAWINGS DOUBLE VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND RIGHT;;;;
7728 2561;BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND LEFT DOUBLE;;;;
7729 2562;BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND LEFT SINGLE;;;;
7730 2563;BOX DRAWINGS DOUBLE VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND LEFT;;;;
7731 2564;BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND HORIZONTAL DOUBLE;;;;
7732 2565;BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND HORIZONTAL SINGLE;;;;
7733 2566;BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND HORIZONTAL;;;;
7734 2567;BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND HORIZONTAL DOUBLE;;;;
7735 2568;BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND HORIZONTAL SINGLE;;;;
7736 2569;BOX DRAWINGS DOUBLE UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE UP AND HORIZONTAL;;;;
7737 256A;BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND HORIZONTAL DOUBLE;;;;
7738 256B;BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND HORIZONTAL SINGLE;;;;
7739 256C;BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND HORIZONTAL;;;;
7740 256D;BOX DRAWINGS LIGHT ARC DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND RIGHT;;;;
7741 256E;BOX DRAWINGS LIGHT ARC DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND LEFT;;;;
7742 256F;BOX DRAWINGS LIGHT ARC UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND LEFT;;;;
7743 2570;BOX DRAWINGS LIGHT ARC UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND RIGHT;;;;
7744 2571;BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;;;;
7745 2572;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;;;;
7746 2573;BOX DRAWINGS LIGHT DIAGONAL CROSS;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL CROSS;;;;
7747 2574;BOX DRAWINGS LIGHT LEFT;So;0;ON;;;;;N;FORMS LIGHT LEFT;;;;
7748 2575;BOX DRAWINGS LIGHT UP;So;0;ON;;;;;N;FORMS LIGHT UP;;;;
7749 2576;BOX DRAWINGS LIGHT RIGHT;So;0;ON;;;;;N;FORMS LIGHT RIGHT;;;;
7750 2577;BOX DRAWINGS LIGHT DOWN;So;0;ON;;;;;N;FORMS LIGHT DOWN;;;;
7751 2578;BOX DRAWINGS HEAVY LEFT;So;0;ON;;;;;N;FORMS HEAVY LEFT;;;;
7752 2579;BOX DRAWINGS HEAVY UP;So;0;ON;;;;;N;FORMS HEAVY UP;;;;
7753 257A;BOX DRAWINGS HEAVY RIGHT;So;0;ON;;;;;N;FORMS HEAVY RIGHT;;;;
7754 257B;BOX DRAWINGS HEAVY DOWN;So;0;ON;;;;;N;FORMS HEAVY DOWN;;;;
7755 257C;BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT;So;0;ON;;;;;N;FORMS LIGHT LEFT AND HEAVY RIGHT;;;;
7756 257D;BOX DRAWINGS LIGHT UP AND HEAVY DOWN;So;0;ON;;;;;N;FORMS LIGHT UP AND HEAVY DOWN;;;;
7757 257E;BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT;So;0;ON;;;;;N;FORMS HEAVY LEFT AND LIGHT RIGHT;;;;
7758 257F;BOX DRAWINGS HEAVY UP AND LIGHT DOWN;So;0;ON;;;;;N;FORMS HEAVY UP AND LIGHT DOWN;;;;
7759 2580;UPPER HALF BLOCK;So;0;ON;;;;;N;;;;;
7760 2581;LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
7761 2582;LOWER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;
7762 2583;LOWER THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
7763 2584;LOWER HALF BLOCK;So;0;ON;;;;;N;;;;;
7764 2585;LOWER FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
7765 2586;LOWER THREE QUARTERS BLOCK;So;0;ON;;;;;N;LOWER THREE QUARTER BLOCK;;;;
7766 2587;LOWER SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
7767 2588;FULL BLOCK;So;0;ON;;;;;N;;;;;
7768 2589;LEFT SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
7769 258A;LEFT THREE QUARTERS BLOCK;So;0;ON;;;;;N;LEFT THREE QUARTER BLOCK;;;;
7770 258B;LEFT FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
7771 258C;LEFT HALF BLOCK;So;0;ON;;;;;N;;;;;
7772 258D;LEFT THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;
7773 258E;LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;
7774 258F;LEFT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
7775 2590;RIGHT HALF BLOCK;So;0;ON;;;;;N;;;;;
7776 2591;LIGHT SHADE;So;0;ON;;;;;N;;;;;
7777 2592;MEDIUM SHADE;So;0;ON;;;;;N;;;;;
7778 2593;DARK SHADE;So;0;ON;;;;;N;;;;;
7779 2594;UPPER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
7780 2595;RIGHT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;
7781 2596;QUADRANT LOWER LEFT;So;0;ON;;;;;N;;;;;
7782 2597;QUADRANT LOWER RIGHT;So;0;ON;;;;;N;;;;;
7783 2598;QUADRANT UPPER LEFT;So;0;ON;;;;;N;;;;;
7784 2599;QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;
7785 259A;QUADRANT UPPER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;
7786 259B;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;;
7787 259C;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;
7788 259D;QUADRANT UPPER RIGHT;So;0;ON;;;;;N;;;;;
7789 259E;QUADRANT UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;;
7790 259F;QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;
7791 25A0;BLACK SQUARE;So;0;ON;;;;;N;;;;;
7792 25A1;WHITE SQUARE;So;0;ON;;;;;N;;;;;
7793 25A2;WHITE SQUARE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;;
7794 25A3;WHITE SQUARE CONTAINING BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;;
7795 25A4;SQUARE WITH HORIZONTAL FILL;So;0;ON;;;;;N;;;;;
7796 25A5;SQUARE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;;
7797 25A6;SQUARE WITH ORTHOGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;;
7798 25A7;SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL;So;0;ON;;;;;N;;;;;
7799 25A8;SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL;So;0;ON;;;;;N;;;;;
7800 25A9;SQUARE WITH DIAGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;;
7801 25AA;BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;;
7802 25AB;WHITE SMALL SQUARE;So;0;ON;;;;;N;;;;;
7803 25AC;BLACK RECTANGLE;So;0;ON;;;;;N;;;;;
7804 25AD;WHITE RECTANGLE;So;0;ON;;;;;N;;;;;
7805 25AE;BLACK VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;;
7806 25AF;WHITE VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;;
7807 25B0;BLACK PARALLELOGRAM;So;0;ON;;;;;N;;;;;
7808 25B1;WHITE PARALLELOGRAM;So;0;ON;;;;;N;;;;;
7809 25B2;BLACK UP-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING TRIANGLE;;;;
7810 25B3;WHITE UP-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE;;;;
7811 25B4;BLACK UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING SMALL TRIANGLE;;;;
7812 25B5;WHITE UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING SMALL TRIANGLE;;;;
7813 25B6;BLACK RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING TRIANGLE;;;;
7814 25B7;WHITE RIGHT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE RIGHT POINTING TRIANGLE;;;;
7815 25B8;BLACK RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING SMALL TRIANGLE;;;;
7816 25B9;WHITE RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE RIGHT POINTING SMALL TRIANGLE;;;;
7817 25BA;BLACK RIGHT-POINTING POINTER;So;0;ON;;;;;N;BLACK RIGHT POINTING POINTER;;;;
7818 25BB;WHITE RIGHT-POINTING POINTER;So;0;ON;;;;;N;WHITE RIGHT POINTING POINTER;;;;
7819 25BC;BLACK DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING TRIANGLE;;;;
7820 25BD;WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING TRIANGLE;;;;
7821 25BE;BLACK DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING SMALL TRIANGLE;;;;
7822 25BF;WHITE DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING SMALL TRIANGLE;;;;
7823 25C0;BLACK LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING TRIANGLE;;;;
7824 25C1;WHITE LEFT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE LEFT POINTING TRIANGLE;;;;
7825 25C2;BLACK LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING SMALL TRIANGLE;;;;
7826 25C3;WHITE LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE LEFT POINTING SMALL TRIANGLE;;;;
7827 25C4;BLACK LEFT-POINTING POINTER;So;0;ON;;;;;N;BLACK LEFT POINTING POINTER;;;;
7828 25C5;WHITE LEFT-POINTING POINTER;So;0;ON;;;;;N;WHITE LEFT POINTING POINTER;;;;
7829 25C6;BLACK DIAMOND;So;0;ON;;;;;N;;;;;
7830 25C7;WHITE DIAMOND;So;0;ON;;;;;N;;;;;
7831 25C8;WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;;
7832 25C9;FISHEYE;So;0;ON;;;;;N;;;;;
7833 25CA;LOZENGE;So;0;ON;;;;;N;;;;;
7834 25CB;WHITE CIRCLE;So;0;ON;;;;;N;;;;;
7835 25CC;DOTTED CIRCLE;So;0;ON;;;;;N;;;;;
7836 25CD;CIRCLE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;;
7837 25CE;BULLSEYE;So;0;ON;;;;;N;;;;;
7838 25CF;BLACK CIRCLE;So;0;ON;;;;;N;;;;;
7839 25D0;CIRCLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;
7840 25D1;CIRCLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;
7841 25D2;CIRCLE WITH LOWER HALF BLACK;So;0;ON;;;;;N;;;;;
7842 25D3;CIRCLE WITH UPPER HALF BLACK;So;0;ON;;;;;N;;;;;
7843 25D4;CIRCLE WITH UPPER RIGHT QUADRANT BLACK;So;0;ON;;;;;N;;;;;
7844 25D5;CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK;So;0;ON;;;;;N;;;;;
7845 25D6;LEFT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;
7846 25D7;RIGHT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;
7847 25D8;INVERSE BULLET;So;0;ON;;;;;N;;;;;
7848 25D9;INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;
7849 25DA;UPPER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;
7850 25DB;LOWER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;
7851 25DC;UPPER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
7852 25DD;UPPER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
7853 25DE;LOWER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
7854 25DF;LOWER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;
7855 25E0;UPPER HALF CIRCLE;So;0;ON;;;;;N;;;;;
7856 25E1;LOWER HALF CIRCLE;So;0;ON;;;;;N;;;;;
7857 25E2;BLACK LOWER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
7858 25E3;BLACK LOWER LEFT TRIANGLE;So;0;ON;;;;;N;;;;;
7859 25E4;BLACK UPPER LEFT TRIANGLE;So;0;ON;;;;;N;;;;;
7860 25E5;BLACK UPPER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;
7861 25E6;WHITE BULLET;So;0;ON;;;;;N;;;;;
7862 25E7;SQUARE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;
7863 25E8;SQUARE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;
7864 25E9;SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;
7865 25EA;SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;
7866 25EB;WHITE SQUARE WITH VERTICAL BISECTING LINE;So;0;ON;;;;;N;;;;;
7867 25EC;WHITE UP-POINTING TRIANGLE WITH DOT;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE WITH DOT;;;;
7868 25ED;UP-POINTING TRIANGLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH LEFT HALF BLACK;;;;
7869 25EE;UP-POINTING TRIANGLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH RIGHT HALF BLACK;;;;
7870 25EF;LARGE CIRCLE;So;0;ON;;;;;N;;;;;
7871 25F0;WHITE SQUARE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
7872 25F1;WHITE SQUARE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
7873 25F2;WHITE SQUARE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
7874 25F3;WHITE SQUARE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
7875 25F4;WHITE CIRCLE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
7876 25F5;WHITE CIRCLE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;;
7877 25F6;WHITE CIRCLE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
7878 25F7;WHITE CIRCLE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;
7879 25F8;UPPER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;;
7880 25F9;UPPER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;;
7881 25FA;LOWER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;;
7882 25FB;WHITE MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;;
7883 25FC;BLACK MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;;
7884 25FD;WHITE MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;;
7885 25FE;BLACK MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;;
7886 25FF;LOWER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;;
7887 2600;BLACK SUN WITH RAYS;So;0;ON;;;;;N;;;;;
7888 2601;CLOUD;So;0;ON;;;;;N;;;;;
7889 2602;UMBRELLA;So;0;ON;;;;;N;;;;;
7890 2603;SNOWMAN;So;0;ON;;;;;N;;;;;
7891 2604;COMET;So;0;ON;;;;;N;;;;;
7892 2605;BLACK STAR;So;0;ON;;;;;N;;;;;
7893 2606;WHITE STAR;So;0;ON;;;;;N;;;;;
7894 2607;LIGHTNING;So;0;ON;;;;;N;;;;;
7895 2608;THUNDERSTORM;So;0;ON;;;;;N;;;;;
7896 2609;SUN;So;0;ON;;;;;N;;;;;
7897 260A;ASCENDING NODE;So;0;ON;;;;;N;;;;;
7898 260B;DESCENDING NODE;So;0;ON;;;;;N;;;;;
7899 260C;CONJUNCTION;So;0;ON;;;;;N;;;;;
7900 260D;OPPOSITION;So;0;ON;;;;;N;;;;;
7901 260E;BLACK TELEPHONE;So;0;ON;;;;;N;;;;;
7902 260F;WHITE TELEPHONE;So;0;ON;;;;;N;;;;;
7903 2610;BALLOT BOX;So;0;ON;;;;;N;;;;;
7904 2611;BALLOT BOX WITH CHECK;So;0;ON;;;;;N;;;;;
7905 2612;BALLOT BOX WITH X;So;0;ON;;;;;N;;;;;
7906 2613;SALTIRE;So;0;ON;;;;;N;;;;;
7907 2614;UMBRELLA WITH RAIN DROPS;So;0;ON;;;;;N;;;;;
7908 2615;HOT BEVERAGE;So;0;ON;;;;;N;;;;;
7909 2616;WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;;
7910 2617;BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;;
7911 2618;SHAMROCK;So;0;ON;;;;;N;;;;;
7912 2619;REVERSED ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;;
7913 261A;BLACK LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;
7914 261B;BLACK RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
7915 261C;WHITE LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;
7916 261D;WHITE UP POINTING INDEX;So;0;ON;;;;;N;;;;;
7917 261E;WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;
7918 261F;WHITE DOWN POINTING INDEX;So;0;ON;;;;;N;;;;;
7919 2620;SKULL AND CROSSBONES;So;0;ON;;;;;N;;;;;
7920 2621;CAUTION SIGN;So;0;ON;;;;;N;;;;;
7921 2622;RADIOACTIVE SIGN;So;0;ON;;;;;N;;;;;
7922 2623;BIOHAZARD SIGN;So;0;ON;;;;;N;;;;;
7923 2624;CADUCEUS;So;0;ON;;;;;N;;;;;
7924 2625;ANKH;So;0;ON;;;;;N;;;;;
7925 2626;ORTHODOX CROSS;So;0;ON;;;;;N;;;;;
7926 2627;CHI RHO;So;0;ON;;;;;N;;;;;
7927 2628;CROSS OF LORRAINE;So;0;ON;;;;;N;;;;;
7928 2629;CROSS OF JERUSALEM;So;0;ON;;;;;N;;;;;
7929 262A;STAR AND CRESCENT;So;0;ON;;;;;N;;;;;
7930 262B;FARSI SYMBOL;So;0;ON;;;;;N;SYMBOL OF IRAN;;;;
7931 262C;ADI SHAKTI;So;0;ON;;;;;N;;;;;
7932 262D;HAMMER AND SICKLE;So;0;ON;;;;;N;;;;;
7933 262E;PEACE SYMBOL;So;0;ON;;;;;N;;;;;
7934 262F;YIN YANG;So;0;ON;;;;;N;;;;;
7935 2630;TRIGRAM FOR HEAVEN;So;0;ON;;;;;N;;;;;
7936 2631;TRIGRAM FOR LAKE;So;0;ON;;;;;N;;;;;
7937 2632;TRIGRAM FOR FIRE;So;0;ON;;;;;N;;;;;
7938 2633;TRIGRAM FOR THUNDER;So;0;ON;;;;;N;;;;;
7939 2634;TRIGRAM FOR WIND;So;0;ON;;;;;N;;;;;
7940 2635;TRIGRAM FOR WATER;So;0;ON;;;;;N;;;;;
7941 2636;TRIGRAM FOR MOUNTAIN;So;0;ON;;;;;N;;;;;
7942 2637;TRIGRAM FOR EARTH;So;0;ON;;;;;N;;;;;
7943 2638;WHEEL OF DHARMA;So;0;ON;;;;;N;;;;;
7944 2639;WHITE FROWNING FACE;So;0;ON;;;;;N;;;;;
7945 263A;WHITE SMILING FACE;So;0;ON;;;;;N;;;;;
7946 263B;BLACK SMILING FACE;So;0;ON;;;;;N;;;;;
7947 263C;WHITE SUN WITH RAYS;So;0;ON;;;;;N;;;;;
7948 263D;FIRST QUARTER MOON;So;0;ON;;;;;N;;;;;
7949 263E;LAST QUARTER MOON;So;0;ON;;;;;N;;;;;
7950 263F;MERCURY;So;0;ON;;;;;N;;;;;
7951 2640;FEMALE SIGN;So;0;ON;;;;;N;;;;;
7952 2641;EARTH;So;0;ON;;;;;N;;;;;
7953 2642;MALE SIGN;So;0;ON;;;;;N;;;;;
7954 2643;JUPITER;So;0;ON;;;;;N;;;;;
7955 2644;SATURN;So;0;ON;;;;;N;;;;;
7956 2645;URANUS;So;0;ON;;;;;N;;;;;
7957 2646;NEPTUNE;So;0;ON;;;;;N;;;;;
7958 2647;PLUTO;So;0;ON;;;;;N;;;;;
7959 2648;ARIES;So;0;ON;;;;;N;;;;;
7960 2649;TAURUS;So;0;ON;;;;;N;;;;;
7961 264A;GEMINI;So;0;ON;;;;;N;;;;;
7962 264B;CANCER;So;0;ON;;;;;N;;;;;
7963 264C;LEO;So;0;ON;;;;;N;;;;;
7964 264D;VIRGO;So;0;ON;;;;;N;;;;;
7965 264E;LIBRA;So;0;ON;;;;;N;;;;;
7966 264F;SCORPIUS;So;0;ON;;;;;N;;;;;
7967 2650;SAGITTARIUS;So;0;ON;;;;;N;;;;;
7968 2651;CAPRICORN;So;0;ON;;;;;N;;;;;
7969 2652;AQUARIUS;So;0;ON;;;;;N;;;;;
7970 2653;PISCES;So;0;ON;;;;;N;;;;;
7971 2654;WHITE CHESS KING;So;0;ON;;;;;N;;;;;
7972 2655;WHITE CHESS QUEEN;So;0;ON;;;;;N;;;;;
7973 2656;WHITE CHESS ROOK;So;0;ON;;;;;N;;;;;
7974 2657;WHITE CHESS BISHOP;So;0;ON;;;;;N;;;;;
7975 2658;WHITE CHESS KNIGHT;So;0;ON;;;;;N;;;;;
7976 2659;WHITE CHESS PAWN;So;0;ON;;;;;N;;;;;
7977 265A;BLACK CHESS KING;So;0;ON;;;;;N;;;;;
7978 265B;BLACK CHESS QUEEN;So;0;ON;;;;;N;;;;;
7979 265C;BLACK CHESS ROOK;So;0;ON;;;;;N;;;;;
7980 265D;BLACK CHESS BISHOP;So;0;ON;;;;;N;;;;;
7981 265E;BLACK CHESS KNIGHT;So;0;ON;;;;;N;;;;;
7982 265F;BLACK CHESS PAWN;So;0;ON;;;;;N;;;;;
7983 2660;BLACK SPADE SUIT;So;0;ON;;;;;N;;;;;
7984 2661;WHITE HEART SUIT;So;0;ON;;;;;N;;;;;
7985 2662;WHITE DIAMOND SUIT;So;0;ON;;;;;N;;;;;
7986 2663;BLACK CLUB SUIT;So;0;ON;;;;;N;;;;;
7987 2664;WHITE SPADE SUIT;So;0;ON;;;;;N;;;;;
7988 2665;BLACK HEART SUIT;So;0;ON;;;;;N;;;;;
7989 2666;BLACK DIAMOND SUIT;So;0;ON;;;;;N;;;;;
7990 2667;WHITE CLUB SUIT;So;0;ON;;;;;N;;;;;
7991 2668;HOT SPRINGS;So;0;ON;;;;;N;;;;;
7992 2669;QUARTER NOTE;So;0;ON;;;;;N;;;;;
7993 266A;EIGHTH NOTE;So;0;ON;;;;;N;;;;;
7994 266B;BEAMED EIGHTH NOTES;So;0;ON;;;;;N;BARRED EIGHTH NOTES;;;;
7995 266C;BEAMED SIXTEENTH NOTES;So;0;ON;;;;;N;BARRED SIXTEENTH NOTES;;;;
7996 266D;MUSIC FLAT SIGN;So;0;ON;;;;;N;FLAT;;;;
7997 266E;MUSIC NATURAL SIGN;So;0;ON;;;;;N;NATURAL;;;;
7998 266F;MUSIC SHARP SIGN;Sm;0;ON;;;;;N;SHARP;;;;
7999 2670;WEST SYRIAC CROSS;So;0;ON;;;;;N;;;;;
8000 2671;EAST SYRIAC CROSS;So;0;ON;;;;;N;;;;;
8001 2672;UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;;
8002 2673;RECYCLING SYMBOL FOR TYPE-1 PLASTICS;So;0;ON;;;;;N;;pete;;;
8003 2674;RECYCLING SYMBOL FOR TYPE-2 PLASTICS;So;0;ON;;;;;N;;hdpe;;;
8004 2675;RECYCLING SYMBOL FOR TYPE-3 PLASTICS;So;0;ON;;;;;N;;pvc;;;
8005 2676;RECYCLING SYMBOL FOR TYPE-4 PLASTICS;So;0;ON;;;;;N;;ldpe;;;
8006 2677;RECYCLING SYMBOL FOR TYPE-5 PLASTICS;So;0;ON;;;;;N;;pp;;;
8007 2678;RECYCLING SYMBOL FOR TYPE-6 PLASTICS;So;0;ON;;;;;N;;ps;;;
8008 2679;RECYCLING SYMBOL FOR TYPE-7 PLASTICS;So;0;ON;;;;;N;;other;;;
8009 267A;RECYCLING SYMBOL FOR GENERIC MATERIALS;So;0;ON;;;;;N;;;;;
8010 267B;BLACK UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;;
8011 267C;RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;;
8012 267D;PARTIALLY-RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;;
8013 267E;PERMANENT PAPER SIGN;So;0;ON;;;;;N;;;;;
8014 267F;WHEELCHAIR SYMBOL;So;0;ON;;;;;N;;;;;
8015 2680;DIE FACE-1;So;0;ON;;;;;N;;;;;
8016 2681;DIE FACE-2;So;0;ON;;;;;N;;;;;
8017 2682;DIE FACE-3;So;0;ON;;;;;N;;;;;
8018 2683;DIE FACE-4;So;0;ON;;;;;N;;;;;
8019 2684;DIE FACE-5;So;0;ON;;;;;N;;;;;
8020 2685;DIE FACE-6;So;0;ON;;;;;N;;;;;
8021 2686;WHITE CIRCLE WITH DOT RIGHT;So;0;ON;;;;;N;;;;;
8022 2687;WHITE CIRCLE WITH TWO DOTS;So;0;ON;;;;;N;;;;;
8023 2688;BLACK CIRCLE WITH WHITE DOT RIGHT;So;0;ON;;;;;N;;;;;
8024 2689;BLACK CIRCLE WITH TWO WHITE DOTS;So;0;ON;;;;;N;;;;;
8025 268A;MONOGRAM FOR YANG;So;0;ON;;;;;N;;;;;
8026 268B;MONOGRAM FOR YIN;So;0;ON;;;;;N;;;;;
8027 268C;DIGRAM FOR GREATER YANG;So;0;ON;;;;;N;;;;;
8028 268D;DIGRAM FOR LESSER YIN;So;0;ON;;;;;N;;;;;
8029 268E;DIGRAM FOR LESSER YANG;So;0;ON;;;;;N;;;;;
8030 268F;DIGRAM FOR GREATER YIN;So;0;ON;;;;;N;;;;;
8031 2690;WHITE FLAG;So;0;ON;;;;;N;;;;;
8032 2691;BLACK FLAG;So;0;ON;;;;;N;;;;;
8033 2692;HAMMER AND PICK;So;0;ON;;;;;N;;;;;
8034 2693;ANCHOR;So;0;ON;;;;;N;;;;;
8035 2694;CROSSED SWORDS;So;0;ON;;;;;N;;;;;
8036 2695;STAFF OF AESCULAPIUS;So;0;ON;;;;;N;;;;;
8037 2696;SCALES;So;0;ON;;;;;N;;;;;
8038 2697;ALEMBIC;So;0;ON;;;;;N;;;;;
8039 2698;FLOWER;So;0;ON;;;;;N;;;;;
8040 2699;GEAR;So;0;ON;;;;;N;;;;;
8041 269A;STAFF OF HERMES;So;0;ON;;;;;N;;;;;
8042 269B;ATOM SYMBOL;So;0;ON;;;;;N;;;;;
8043 269C;FLEUR-DE-LIS;So;0;ON;;;;;N;;;;;
8044 269D;OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;;
8045 26A0;WARNING SIGN;So;0;ON;;;;;N;;;;;
8046 26A1;HIGH VOLTAGE SIGN;So;0;ON;;;;;N;;;;;
8047 26A2;DOUBLED FEMALE SIGN;So;0;ON;;;;;N;;;;;
8048 26A3;DOUBLED MALE SIGN;So;0;ON;;;;;N;;;;;
8049 26A4;INTERLOCKED FEMALE AND MALE SIGN;So;0;ON;;;;;N;;;;;
8050 26A5;MALE AND FEMALE SIGN;So;0;ON;;;;;N;;;;;
8051 26A6;MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;;
8052 26A7;MALE WITH STROKE AND MALE AND FEMALE SIGN;So;0;ON;;;;;N;;;;;
8053 26A8;VERTICAL MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;;
8054 26A9;HORIZONTAL MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;;
8055 26AA;MEDIUM WHITE CIRCLE;So;0;ON;;;;;N;;;;;
8056 26AB;MEDIUM BLACK CIRCLE;So;0;ON;;;;;N;;;;;
8057 26AC;MEDIUM SMALL WHITE CIRCLE;So;0;L;;;;;N;;;;;
8058 26AD;MARRIAGE SYMBOL;So;0;ON;;;;;N;;;;;
8059 26AE;DIVORCE SYMBOL;So;0;ON;;;;;N;;;;;
8060 26AF;UNMARRIED PARTNERSHIP SYMBOL;So;0;ON;;;;;N;;;;;
8061 26B0;COFFIN;So;0;ON;;;;;N;;;;;
8062 26B1;FUNERAL URN;So;0;ON;;;;;N;;;;;
8063 26B2;NEUTER;So;0;ON;;;;;N;;;;;
8064 26B3;CERES;So;0;ON;;;;;N;;;;;
8065 26B4;PALLAS;So;0;ON;;;;;N;;;;;
8066 26B5;JUNO;So;0;ON;;;;;N;;;;;
8067 26B6;VESTA;So;0;ON;;;;;N;;;;;
8068 26B7;CHIRON;So;0;ON;;;;;N;;;;;
8069 26B8;BLACK MOON LILITH;So;0;ON;;;;;N;;;;;
8070 26B9;SEXTILE;So;0;ON;;;;;N;;;;;
8071 26BA;SEMISEXTILE;So;0;ON;;;;;N;;;;;
8072 26BB;QUINCUNX;So;0;ON;;;;;N;;;;;
8073 26BC;SESQUIQUADRATE;So;0;ON;;;;;N;;;;;
8074 26C0;WHITE DRAUGHTS MAN;So;0;ON;;;;;N;;;;;
8075 26C1;WHITE DRAUGHTS KING;So;0;ON;;;;;N;;;;;
8076 26C2;BLACK DRAUGHTS MAN;So;0;ON;;;;;N;;;;;
8077 26C3;BLACK DRAUGHTS KING;So;0;ON;;;;;N;;;;;
8078 2701;UPPER BLADE SCISSORS;So;0;ON;;;;;N;;;;;
8079 2702;BLACK SCISSORS;So;0;ON;;;;;N;;;;;
8080 2703;LOWER BLADE SCISSORS;So;0;ON;;;;;N;;;;;
8081 2704;WHITE SCISSORS;So;0;ON;;;;;N;;;;;
8082 2706;TELEPHONE LOCATION SIGN;So;0;ON;;;;;N;;;;;
8083 2707;TAPE DRIVE;So;0;ON;;;;;N;;;;;
8084 2708;AIRPLANE;So;0;ON;;;;;N;;;;;
8085 2709;ENVELOPE;So;0;ON;;;;;N;;;;;
8086 270C;VICTORY HAND;So;0;ON;;;;;N;;;;;
8087 270D;WRITING HAND;So;0;ON;;;;;N;;;;;
8088 270E;LOWER RIGHT PENCIL;So;0;ON;;;;;N;;;;;
8089 270F;PENCIL;So;0;ON;;;;;N;;;;;
8090 2710;UPPER RIGHT PENCIL;So;0;ON;;;;;N;;;;;
8091 2711;WHITE NIB;So;0;ON;;;;;N;;;;;
8092 2712;BLACK NIB;So;0;ON;;;;;N;;;;;
8093 2713;CHECK MARK;So;0;ON;;;;;N;;;;;
8094 2714;HEAVY CHECK MARK;So;0;ON;;;;;N;;;;;
8095 2715;MULTIPLICATION X;So;0;ON;;;;;N;;;;;
8096 2716;HEAVY MULTIPLICATION X;So;0;ON;;;;;N;;;;;
8097 2717;BALLOT X;So;0;ON;;;;;N;;;;;
8098 2718;HEAVY BALLOT X;So;0;ON;;;;;N;;;;;
8099 2719;OUTLINED GREEK CROSS;So;0;ON;;;;;N;;;;;
8100 271A;HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;;
8101 271B;OPEN CENTRE CROSS;So;0;ON;;;;;N;OPEN CENTER CROSS;;;;
8102 271C;HEAVY OPEN CENTRE CROSS;So;0;ON;;;;;N;HEAVY OPEN CENTER CROSS;;;;
8103 271D;LATIN CROSS;So;0;ON;;;;;N;;;;;
8104 271E;SHADOWED WHITE LATIN CROSS;So;0;ON;;;;;N;;;;;
8105 271F;OUTLINED LATIN CROSS;So;0;ON;;;;;N;;;;;
8106 2720;MALTESE CROSS;So;0;ON;;;;;N;;;;;
8107 2721;STAR OF DAVID;So;0;ON;;;;;N;;;;;
8108 2722;FOUR TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
8109 2723;FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
8110 2724;HEAVY FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
8111 2725;FOUR CLUB-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
8112 2726;BLACK FOUR POINTED STAR;So;0;ON;;;;;N;;;;;
8113 2727;WHITE FOUR POINTED STAR;So;0;ON;;;;;N;;;;;
8114 2729;STRESS OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;;
8115 272A;CIRCLED WHITE STAR;So;0;ON;;;;;N;;;;;
8116 272B;OPEN CENTRE BLACK STAR;So;0;ON;;;;;N;OPEN CENTER BLACK STAR;;;;
8117 272C;BLACK CENTRE WHITE STAR;So;0;ON;;;;;N;BLACK CENTER WHITE STAR;;;;
8118 272D;OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;;
8119 272E;HEAVY OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;;
8120 272F;PINWHEEL STAR;So;0;ON;;;;;N;;;;;
8121 2730;SHADOWED WHITE STAR;So;0;ON;;;;;N;;;;;
8122 2731;HEAVY ASTERISK;So;0;ON;;;;;N;;;;;
8123 2732;OPEN CENTRE ASTERISK;So;0;ON;;;;;N;OPEN CENTER ASTERISK;;;;
8124 2733;EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
8125 2734;EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
8126 2735;EIGHT POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;
8127 2736;SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
8128 2737;EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;;
8129 2738;HEAVY EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;;
8130 2739;TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;
8131 273A;SIXTEEN POINTED ASTERISK;So;0;ON;;;;;N;;;;;
8132 273B;TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
8133 273C;OPEN CENTRE TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;OPEN CENTER TEARDROP-SPOKED ASTERISK;;;;
8134 273D;HEAVY TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
8135 273E;SIX PETALLED BLACK AND WHITE FLORETTE;So;0;ON;;;;;N;;;;;
8136 273F;BLACK FLORETTE;So;0;ON;;;;;N;;;;;
8137 2740;WHITE FLORETTE;So;0;ON;;;;;N;;;;;
8138 2741;EIGHT PETALLED OUTLINED BLACK FLORETTE;So;0;ON;;;;;N;;;;;
8139 2742;CIRCLED OPEN CENTRE EIGHT POINTED STAR;So;0;ON;;;;;N;CIRCLED OPEN CENTER EIGHT POINTED STAR;;;;
8140 2743;HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK;So;0;ON;;;;;N;;;;;
8141 2744;SNOWFLAKE;So;0;ON;;;;;N;;;;;
8142 2745;TIGHT TRIFOLIATE SNOWFLAKE;So;0;ON;;;;;N;;;;;
8143 2746;HEAVY CHEVRON SNOWFLAKE;So;0;ON;;;;;N;;;;;
8144 2747;SPARKLE;So;0;ON;;;;;N;;;;;
8145 2748;HEAVY SPARKLE;So;0;ON;;;;;N;;;;;
8146 2749;BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;
8147 274A;EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;;
8148 274B;HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;;
8149 274D;SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;;
8150 274F;LOWER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
8151 2750;UPPER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
8152 2751;LOWER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
8153 2752;UPPER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;
8154 2756;BLACK DIAMOND MINUS WHITE X;So;0;ON;;;;;N;;;;;
8155 2758;LIGHT VERTICAL BAR;So;0;ON;;;;;N;;;;;
8156 2759;MEDIUM VERTICAL BAR;So;0;ON;;;;;N;;;;;
8157 275A;HEAVY VERTICAL BAR;So;0;ON;;;;;N;;;;;
8158 275B;HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
8159 275C;HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
8160 275D;HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
8161 275E;HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
8162 2761;CURVED STEM PARAGRAPH SIGN ORNAMENT;So;0;ON;;;;;N;;;;;
8163 2762;HEAVY EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
8164 2763;HEAVY HEART EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;
8165 2764;HEAVY BLACK HEART;So;0;ON;;;;;N;;;;;
8166 2765;ROTATED HEAVY BLACK HEART BULLET;So;0;ON;;;;;N;;;;;
8167 2766;FLORAL HEART;So;0;ON;;;;;N;;;;;
8168 2767;ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;;
8169 2768;MEDIUM LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;;
8170 2769;MEDIUM RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;;
8171 276A;MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;;
8172 276B;MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;;
8173 276C;MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;
8174 276D;MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;
8175 276E;HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT;Ps;0;ON;;;;;Y;;;;;
8176 276F;HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT;Pe;0;ON;;;;;Y;;;;;
8177 2770;HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;
8178 2771;HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;
8179 2772;LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;
8180 2773;LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;
8181 2774;MEDIUM LEFT CURLY BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;
8182 2775;MEDIUM RIGHT CURLY BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;
8183 2776;DINGBAT NEGATIVE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED DIGIT ONE;;;;
8184 2777;DINGBAT NEGATIVE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED DIGIT TWO;;;;
8185 2778;DINGBAT NEGATIVE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED DIGIT THREE;;;;
8186 2779;DINGBAT NEGATIVE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED DIGIT FOUR;;;;
8187 277A;DINGBAT NEGATIVE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED DIGIT FIVE;;;;
8188 277B;DINGBAT NEGATIVE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED DIGIT SIX;;;;
8189 277C;DINGBAT NEGATIVE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED DIGIT SEVEN;;;;
8190 277D;DINGBAT NEGATIVE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED DIGIT EIGHT;;;;
8191 277E;DINGBAT NEGATIVE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED DIGIT NINE;;;;
8192 277F;DINGBAT NEGATIVE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED NUMBER TEN;;;;
8193 2780;DINGBAT CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;CIRCLED SANS-SERIF DIGIT ONE;;;;
8194 2781;DINGBAT CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;CIRCLED SANS-SERIF DIGIT TWO;;;;
8195 2782;DINGBAT CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;CIRCLED SANS-SERIF DIGIT THREE;;;;
8196 2783;DINGBAT CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;CIRCLED SANS-SERIF DIGIT FOUR;;;;
8197 2784;DINGBAT CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;CIRCLED SANS-SERIF DIGIT FIVE;;;;
8198 2785;DINGBAT CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;CIRCLED SANS-SERIF DIGIT SIX;;;;
8199 2786;DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;CIRCLED SANS-SERIF DIGIT SEVEN;;;;
8200 2787;DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;CIRCLED SANS-SERIF DIGIT EIGHT;;;;
8201 2788;DINGBAT CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;CIRCLED SANS-SERIF DIGIT NINE;;;;
8202 2789;DINGBAT CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;CIRCLED SANS-SERIF NUMBER TEN;;;;
8203 278A;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED SANS-SERIF DIGIT ONE;;;;
8204 278B;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED SANS-SERIF DIGIT TWO;;;;
8205 278C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED SANS-SERIF DIGIT THREE;;;;
8206 278D;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED SANS-SERIF DIGIT FOUR;;;;
8207 278E;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED SANS-SERIF DIGIT FIVE;;;;
8208 278F;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED SANS-SERIF DIGIT SIX;;;;
8209 2790;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED SANS-SERIF DIGIT SEVEN;;;;
8210 2791;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED SANS-SERIF DIGIT EIGHT;;;;
8211 2792;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED SANS-SERIF DIGIT NINE;;;;
8212 2793;DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED SANS-SERIF NUMBER TEN;;;;
8213 2794;HEAVY WIDE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WIDE-HEADED RIGHT ARROW;;;;
8214 2798;HEAVY SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT ARROW;;;;
8215 2799;HEAVY RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY RIGHT ARROW;;;;
8216 279A;HEAVY NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT ARROW;;;;
8217 279B;DRAFTING POINT RIGHTWARDS ARROW;So;0;ON;;;;;N;DRAFTING POINT RIGHT ARROW;;;;
8218 279C;HEAVY ROUND-TIPPED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY ROUND-TIPPED RIGHT ARROW;;;;
8219 279D;TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;TRIANGLE-HEADED RIGHT ARROW;;;;
8220 279E;HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TRIANGLE-HEADED RIGHT ARROW;;;;
8221 279F;DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;DASHED TRIANGLE-HEADED RIGHT ARROW;;;;
8222 27A0;HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY DASHED TRIANGLE-HEADED RIGHT ARROW;;;;
8223 27A1;BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK RIGHT ARROW;;;;
8224 27A2;THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D TOP-LIGHTED RIGHT ARROWHEAD;;;;
8225 27A3;THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D BOTTOM-LIGHTED RIGHT ARROWHEAD;;;;
8226 27A4;BLACK RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;BLACK RIGHT ARROWHEAD;;;;
8227 27A5;HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED DOWN AND RIGHT ARROW;;;;
8228 27A6;HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED UP AND RIGHT ARROW;;;;
8229 27A7;SQUAT BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;SQUAT BLACK RIGHT ARROW;;;;
8230 27A8;HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY CONCAVE-POINTED BLACK RIGHT ARROW;;;;
8231 27A9;RIGHT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;RIGHT-SHADED WHITE RIGHT ARROW;;;;
8232 27AA;LEFT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT-SHADED WHITE RIGHT ARROW;;;;
8233 27AB;BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;BACK-TILTED SHADOWED WHITE RIGHT ARROW;;;;
8234 27AC;FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;FRONT-TILTED SHADOWED WHITE RIGHT ARROW;;;;
8235 27AD;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
8236 27AE;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
8237 27AF;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
8238 27B1;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;
8239 27B2;CIRCLED HEAVY WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;CIRCLED HEAVY WHITE RIGHT ARROW;;;;
8240 27B3;WHITE-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;WHITE-FEATHERED RIGHT ARROW;;;;
8241 27B4;BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED LOWER RIGHT ARROW;;;;
8242 27B5;BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK-FEATHERED RIGHT ARROW;;;;
8243 27B6;BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED UPPER RIGHT ARROW;;;;
8244 27B7;HEAVY BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED LOWER RIGHT ARROW;;;;
8245 27B8;HEAVY BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED RIGHT ARROW;;;;
8246 27B9;HEAVY BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED UPPER RIGHT ARROW;;;;
8247 27BA;TEARDROP-BARBED RIGHTWARDS ARROW;So;0;ON;;;;;N;TEARDROP-BARBED RIGHT ARROW;;;;
8248 27BB;HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TEARDROP-SHANKED RIGHT ARROW;;;;
8249 27BC;WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;WEDGE-TAILED RIGHT ARROW;;;;
8250 27BD;HEAVY WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WEDGE-TAILED RIGHT ARROW;;;;
8251 27BE;OPEN-OUTLINED RIGHTWARDS ARROW;So;0;ON;;;;;N;OPEN-OUTLINED RIGHT ARROW;;;;
8252 27C0;THREE DIMENSIONAL ANGLE;Sm;0;ON;;;;;Y;;;;;
8253 27C1;WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE;Sm;0;ON;;;;;N;;;;;
8254 27C2;PERPENDICULAR;Sm;0;ON;;;;;N;;;;;
8255 27C3;OPEN SUBSET;Sm;0;ON;;;;;Y;;;;;
8256 27C4;OPEN SUPERSET;Sm;0;ON;;;;;Y;;;;;
8257 27C5;LEFT S-SHAPED BAG DELIMITER;Ps;0;ON;;;;;Y;;;;;
8258 27C6;RIGHT S-SHAPED BAG DELIMITER;Pe;0;ON;;;;;Y;;;;;
8259 27C7;OR WITH DOT INSIDE;Sm;0;ON;;;;;N;;;;;
8260 27C8;REVERSE SOLIDUS PRECEDING SUBSET;Sm;0;ON;;;;;Y;;;;;
8261 27C9;SUPERSET PRECEDING SOLIDUS;Sm;0;ON;;;;;Y;;;;;
8262 27CA;VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
8263 27CC;LONG DIVISION;Sm;0;ON;;;;;Y;;;;;
8264 27D0;WHITE DIAMOND WITH CENTRED DOT;Sm;0;ON;;;;;N;;;;;
8265 27D1;AND WITH DOT;Sm;0;ON;;;;;N;;;;;
8266 27D2;ELEMENT OF OPENING UPWARDS;Sm;0;ON;;;;;N;;;;;
8267 27D3;LOWER RIGHT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;;
8268 27D4;UPPER LEFT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;;
8269 27D5;LEFT OUTER JOIN;Sm;0;ON;;;;;Y;;;;;
8270 27D6;RIGHT OUTER JOIN;Sm;0;ON;;;;;Y;;;;;
8271 27D7;FULL OUTER JOIN;Sm;0;ON;;;;;N;;;;;
8272 27D8;LARGE UP TACK;Sm;0;ON;;;;;N;;;;;
8273 27D9;LARGE DOWN TACK;Sm;0;ON;;;;;N;;;;;
8274 27DA;LEFT AND RIGHT DOUBLE TURNSTILE;Sm;0;ON;;;;;N;;;;;
8275 27DB;LEFT AND RIGHT TACK;Sm;0;ON;;;;;N;;;;;
8276 27DC;LEFT MULTIMAP;Sm;0;ON;;;;;Y;;;;;
8277 27DD;LONG RIGHT TACK;Sm;0;ON;;;;;Y;;;;;
8278 27DE;LONG LEFT TACK;Sm;0;ON;;;;;Y;;;;;
8279 27DF;UP TACK WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;
8280 27E0;LOZENGE DIVIDED BY HORIZONTAL RULE;Sm;0;ON;;;;;N;;;;;
8281 27E1;WHITE CONCAVE-SIDED DIAMOND;Sm;0;ON;;;;;N;;;;;
8282 27E2;WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;;
8283 27E3;WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;;
8284 27E4;WHITE SQUARE WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;;
8285 27E5;WHITE SQUARE WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;;
8286 27E6;MATHEMATICAL LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;;;;;
8287 27E7;MATHEMATICAL RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;;;;;
8288 27E8;MATHEMATICAL LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;;
8289 27E9;MATHEMATICAL RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;;
8290 27EA;MATHEMATICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;;
8291 27EB;MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;;
8292 27EC;MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;;
8293 27ED;MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;;
8294 27EE;MATHEMATICAL LEFT FLATTENED PARENTHESIS;Ps;0;ON;;;;;Y;;;;;
8295 27EF;MATHEMATICAL RIGHT FLATTENED PARENTHESIS;Pe;0;ON;;;;;Y;;;;;
8296 27F0;UPWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;;
8297 27F1;DOWNWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;;
8298 27F2;ANTICLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;
8299 27F3;CLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;
8300 27F4;RIGHT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;;
8301 27F5;LONG LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
8302 27F6;LONG RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
8303 27F7;LONG LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;;
8304 27F8;LONG LEFTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;
8305 27F9;LONG RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;
8306 27FA;LONG LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;
8307 27FB;LONG LEFTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
8308 27FC;LONG RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
8309 27FD;LONG LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
8310 27FE;LONG RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
8311 27FF;LONG RIGHTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;;
8312 2800;BRAILLE PATTERN BLANK;So;0;L;;;;;N;;;;;
8313 2801;BRAILLE PATTERN DOTS-1;So;0;L;;;;;N;;;;;
8314 2802;BRAILLE PATTERN DOTS-2;So;0;L;;;;;N;;;;;
8315 2803;BRAILLE PATTERN DOTS-12;So;0;L;;;;;N;;;;;
8316 2804;BRAILLE PATTERN DOTS-3;So;0;L;;;;;N;;;;;
8317 2805;BRAILLE PATTERN DOTS-13;So;0;L;;;;;N;;;;;
8318 2806;BRAILLE PATTERN DOTS-23;So;0;L;;;;;N;;;;;
8319 2807;BRAILLE PATTERN DOTS-123;So;0;L;;;;;N;;;;;
8320 2808;BRAILLE PATTERN DOTS-4;So;0;L;;;;;N;;;;;
8321 2809;BRAILLE PATTERN DOTS-14;So;0;L;;;;;N;;;;;
8322 280A;BRAILLE PATTERN DOTS-24;So;0;L;;;;;N;;;;;
8323 280B;BRAILLE PATTERN DOTS-124;So;0;L;;;;;N;;;;;
8324 280C;BRAILLE PATTERN DOTS-34;So;0;L;;;;;N;;;;;
8325 280D;BRAILLE PATTERN DOTS-134;So;0;L;;;;;N;;;;;
8326 280E;BRAILLE PATTERN DOTS-234;So;0;L;;;;;N;;;;;
8327 280F;BRAILLE PATTERN DOTS-1234;So;0;L;;;;;N;;;;;
8328 2810;BRAILLE PATTERN DOTS-5;So;0;L;;;;;N;;;;;
8329 2811;BRAILLE PATTERN DOTS-15;So;0;L;;;;;N;;;;;
8330 2812;BRAILLE PATTERN DOTS-25;So;0;L;;;;;N;;;;;
8331 2813;BRAILLE PATTERN DOTS-125;So;0;L;;;;;N;;;;;
8332 2814;BRAILLE PATTERN DOTS-35;So;0;L;;;;;N;;;;;
8333 2815;BRAILLE PATTERN DOTS-135;So;0;L;;;;;N;;;;;
8334 2816;BRAILLE PATTERN DOTS-235;So;0;L;;;;;N;;;;;
8335 2817;BRAILLE PATTERN DOTS-1235;So;0;L;;;;;N;;;;;
8336 2818;BRAILLE PATTERN DOTS-45;So;0;L;;;;;N;;;;;
8337 2819;BRAILLE PATTERN DOTS-145;So;0;L;;;;;N;;;;;
8338 281A;BRAILLE PATTERN DOTS-245;So;0;L;;;;;N;;;;;
8339 281B;BRAILLE PATTERN DOTS-1245;So;0;L;;;;;N;;;;;
8340 281C;BRAILLE PATTERN DOTS-345;So;0;L;;;;;N;;;;;
8341 281D;BRAILLE PATTERN DOTS-1345;So;0;L;;;;;N;;;;;
8342 281E;BRAILLE PATTERN DOTS-2345;So;0;L;;;;;N;;;;;
8343 281F;BRAILLE PATTERN DOTS-12345;So;0;L;;;;;N;;;;;
8344 2820;BRAILLE PATTERN DOTS-6;So;0;L;;;;;N;;;;;
8345 2821;BRAILLE PATTERN DOTS-16;So;0;L;;;;;N;;;;;
8346 2822;BRAILLE PATTERN DOTS-26;So;0;L;;;;;N;;;;;
8347 2823;BRAILLE PATTERN DOTS-126;So;0;L;;;;;N;;;;;
8348 2824;BRAILLE PATTERN DOTS-36;So;0;L;;;;;N;;;;;
8349 2825;BRAILLE PATTERN DOTS-136;So;0;L;;;;;N;;;;;
8350 2826;BRAILLE PATTERN DOTS-236;So;0;L;;;;;N;;;;;
8351 2827;BRAILLE PATTERN DOTS-1236;So;0;L;;;;;N;;;;;
8352 2828;BRAILLE PATTERN DOTS-46;So;0;L;;;;;N;;;;;
8353 2829;BRAILLE PATTERN DOTS-146;So;0;L;;;;;N;;;;;
8354 282A;BRAILLE PATTERN DOTS-246;So;0;L;;;;;N;;;;;
8355 282B;BRAILLE PATTERN DOTS-1246;So;0;L;;;;;N;;;;;
8356 282C;BRAILLE PATTERN DOTS-346;So;0;L;;;;;N;;;;;
8357 282D;BRAILLE PATTERN DOTS-1346;So;0;L;;;;;N;;;;;
8358 282E;BRAILLE PATTERN DOTS-2346;So;0;L;;;;;N;;;;;
8359 282F;BRAILLE PATTERN DOTS-12346;So;0;L;;;;;N;;;;;
8360 2830;BRAILLE PATTERN DOTS-56;So;0;L;;;;;N;;;;;
8361 2831;BRAILLE PATTERN DOTS-156;So;0;L;;;;;N;;;;;
8362 2832;BRAILLE PATTERN DOTS-256;So;0;L;;;;;N;;;;;
8363 2833;BRAILLE PATTERN DOTS-1256;So;0;L;;;;;N;;;;;
8364 2834;BRAILLE PATTERN DOTS-356;So;0;L;;;;;N;;;;;
8365 2835;BRAILLE PATTERN DOTS-1356;So;0;L;;;;;N;;;;;
8366 2836;BRAILLE PATTERN DOTS-2356;So;0;L;;;;;N;;;;;
8367 2837;BRAILLE PATTERN DOTS-12356;So;0;L;;;;;N;;;;;
8368 2838;BRAILLE PATTERN DOTS-456;So;0;L;;;;;N;;;;;
8369 2839;BRAILLE PATTERN DOTS-1456;So;0;L;;;;;N;;;;;
8370 283A;BRAILLE PATTERN DOTS-2456;So;0;L;;;;;N;;;;;
8371 283B;BRAILLE PATTERN DOTS-12456;So;0;L;;;;;N;;;;;
8372 283C;BRAILLE PATTERN DOTS-3456;So;0;L;;;;;N;;;;;
8373 283D;BRAILLE PATTERN DOTS-13456;So;0;L;;;;;N;;;;;
8374 283E;BRAILLE PATTERN DOTS-23456;So;0;L;;;;;N;;;;;
8375 283F;BRAILLE PATTERN DOTS-123456;So;0;L;;;;;N;;;;;
8376 2840;BRAILLE PATTERN DOTS-7;So;0;L;;;;;N;;;;;
8377 2841;BRAILLE PATTERN DOTS-17;So;0;L;;;;;N;;;;;
8378 2842;BRAILLE PATTERN DOTS-27;So;0;L;;;;;N;;;;;
8379 2843;BRAILLE PATTERN DOTS-127;So;0;L;;;;;N;;;;;
8380 2844;BRAILLE PATTERN DOTS-37;So;0;L;;;;;N;;;;;
8381 2845;BRAILLE PATTERN DOTS-137;So;0;L;;;;;N;;;;;
8382 2846;BRAILLE PATTERN DOTS-237;So;0;L;;;;;N;;;;;
8383 2847;BRAILLE PATTERN DOTS-1237;So;0;L;;;;;N;;;;;
8384 2848;BRAILLE PATTERN DOTS-47;So;0;L;;;;;N;;;;;
8385 2849;BRAILLE PATTERN DOTS-147;So;0;L;;;;;N;;;;;
8386 284A;BRAILLE PATTERN DOTS-247;So;0;L;;;;;N;;;;;
8387 284B;BRAILLE PATTERN DOTS-1247;So;0;L;;;;;N;;;;;
8388 284C;BRAILLE PATTERN DOTS-347;So;0;L;;;;;N;;;;;
8389 284D;BRAILLE PATTERN DOTS-1347;So;0;L;;;;;N;;;;;
8390 284E;BRAILLE PATTERN DOTS-2347;So;0;L;;;;;N;;;;;
8391 284F;BRAILLE PATTERN DOTS-12347;So;0;L;;;;;N;;;;;
8392 2850;BRAILLE PATTERN DOTS-57;So;0;L;;;;;N;;;;;
8393 2851;BRAILLE PATTERN DOTS-157;So;0;L;;;;;N;;;;;
8394 2852;BRAILLE PATTERN DOTS-257;So;0;L;;;;;N;;;;;
8395 2853;BRAILLE PATTERN DOTS-1257;So;0;L;;;;;N;;;;;
8396 2854;BRAILLE PATTERN DOTS-357;So;0;L;;;;;N;;;;;
8397 2855;BRAILLE PATTERN DOTS-1357;So;0;L;;;;;N;;;;;
8398 2856;BRAILLE PATTERN DOTS-2357;So;0;L;;;;;N;;;;;
8399 2857;BRAILLE PATTERN DOTS-12357;So;0;L;;;;;N;;;;;
8400 2858;BRAILLE PATTERN DOTS-457;So;0;L;;;;;N;;;;;
8401 2859;BRAILLE PATTERN DOTS-1457;So;0;L;;;;;N;;;;;
8402 285A;BRAILLE PATTERN DOTS-2457;So;0;L;;;;;N;;;;;
8403 285B;BRAILLE PATTERN DOTS-12457;So;0;L;;;;;N;;;;;
8404 285C;BRAILLE PATTERN DOTS-3457;So;0;L;;;;;N;;;;;
8405 285D;BRAILLE PATTERN DOTS-13457;So;0;L;;;;;N;;;;;
8406 285E;BRAILLE PATTERN DOTS-23457;So;0;L;;;;;N;;;;;
8407 285F;BRAILLE PATTERN DOTS-123457;So;0;L;;;;;N;;;;;
8408 2860;BRAILLE PATTERN DOTS-67;So;0;L;;;;;N;;;;;
8409 2861;BRAILLE PATTERN DOTS-167;So;0;L;;;;;N;;;;;
8410 2862;BRAILLE PATTERN DOTS-267;So;0;L;;;;;N;;;;;
8411 2863;BRAILLE PATTERN DOTS-1267;So;0;L;;;;;N;;;;;
8412 2864;BRAILLE PATTERN DOTS-367;So;0;L;;;;;N;;;;;
8413 2865;BRAILLE PATTERN DOTS-1367;So;0;L;;;;;N;;;;;
8414 2866;BRAILLE PATTERN DOTS-2367;So;0;L;;;;;N;;;;;
8415 2867;BRAILLE PATTERN DOTS-12367;So;0;L;;;;;N;;;;;
8416 2868;BRAILLE PATTERN DOTS-467;So;0;L;;;;;N;;;;;
8417 2869;BRAILLE PATTERN DOTS-1467;So;0;L;;;;;N;;;;;
8418 286A;BRAILLE PATTERN DOTS-2467;So;0;L;;;;;N;;;;;
8419 286B;BRAILLE PATTERN DOTS-12467;So;0;L;;;;;N;;;;;
8420 286C;BRAILLE PATTERN DOTS-3467;So;0;L;;;;;N;;;;;
8421 286D;BRAILLE PATTERN DOTS-13467;So;0;L;;;;;N;;;;;
8422 286E;BRAILLE PATTERN DOTS-23467;So;0;L;;;;;N;;;;;
8423 286F;BRAILLE PATTERN DOTS-123467;So;0;L;;;;;N;;;;;
8424 2870;BRAILLE PATTERN DOTS-567;So;0;L;;;;;N;;;;;
8425 2871;BRAILLE PATTERN DOTS-1567;So;0;L;;;;;N;;;;;
8426 2872;BRAILLE PATTERN DOTS-2567;So;0;L;;;;;N;;;;;
8427 2873;BRAILLE PATTERN DOTS-12567;So;0;L;;;;;N;;;;;
8428 2874;BRAILLE PATTERN DOTS-3567;So;0;L;;;;;N;;;;;
8429 2875;BRAILLE PATTERN DOTS-13567;So;0;L;;;;;N;;;;;
8430 2876;BRAILLE PATTERN DOTS-23567;So;0;L;;;;;N;;;;;
8431 2877;BRAILLE PATTERN DOTS-123567;So;0;L;;;;;N;;;;;
8432 2878;BRAILLE PATTERN DOTS-4567;So;0;L;;;;;N;;;;;
8433 2879;BRAILLE PATTERN DOTS-14567;So;0;L;;;;;N;;;;;
8434 287A;BRAILLE PATTERN DOTS-24567;So;0;L;;;;;N;;;;;
8435 287B;BRAILLE PATTERN DOTS-124567;So;0;L;;;;;N;;;;;
8436 287C;BRAILLE PATTERN DOTS-34567;So;0;L;;;;;N;;;;;
8437 287D;BRAILLE PATTERN DOTS-134567;So;0;L;;;;;N;;;;;
8438 287E;BRAILLE PATTERN DOTS-234567;So;0;L;;;;;N;;;;;
8439 287F;BRAILLE PATTERN DOTS-1234567;So;0;L;;;;;N;;;;;
8440 2880;BRAILLE PATTERN DOTS-8;So;0;L;;;;;N;;;;;
8441 2881;BRAILLE PATTERN DOTS-18;So;0;L;;;;;N;;;;;
8442 2882;BRAILLE PATTERN DOTS-28;So;0;L;;;;;N;;;;;
8443 2883;BRAILLE PATTERN DOTS-128;So;0;L;;;;;N;;;;;
8444 2884;BRAILLE PATTERN DOTS-38;So;0;L;;;;;N;;;;;
8445 2885;BRAILLE PATTERN DOTS-138;So;0;L;;;;;N;;;;;
8446 2886;BRAILLE PATTERN DOTS-238;So;0;L;;;;;N;;;;;
8447 2887;BRAILLE PATTERN DOTS-1238;So;0;L;;;;;N;;;;;
8448 2888;BRAILLE PATTERN DOTS-48;So;0;L;;;;;N;;;;;
8449 2889;BRAILLE PATTERN DOTS-148;So;0;L;;;;;N;;;;;
8450 288A;BRAILLE PATTERN DOTS-248;So;0;L;;;;;N;;;;;
8451 288B;BRAILLE PATTERN DOTS-1248;So;0;L;;;;;N;;;;;
8452 288C;BRAILLE PATTERN DOTS-348;So;0;L;;;;;N;;;;;
8453 288D;BRAILLE PATTERN DOTS-1348;So;0;L;;;;;N;;;;;
8454 288E;BRAILLE PATTERN DOTS-2348;So;0;L;;;;;N;;;;;
8455 288F;BRAILLE PATTERN DOTS-12348;So;0;L;;;;;N;;;;;
8456 2890;BRAILLE PATTERN DOTS-58;So;0;L;;;;;N;;;;;
8457 2891;BRAILLE PATTERN DOTS-158;So;0;L;;;;;N;;;;;
8458 2892;BRAILLE PATTERN DOTS-258;So;0;L;;;;;N;;;;;
8459 2893;BRAILLE PATTERN DOTS-1258;So;0;L;;;;;N;;;;;
8460 2894;BRAILLE PATTERN DOTS-358;So;0;L;;;;;N;;;;;
8461 2895;BRAILLE PATTERN DOTS-1358;So;0;L;;;;;N;;;;;
8462 2896;BRAILLE PATTERN DOTS-2358;So;0;L;;;;;N;;;;;
8463 2897;BRAILLE PATTERN DOTS-12358;So;0;L;;;;;N;;;;;
8464 2898;BRAILLE PATTERN DOTS-458;So;0;L;;;;;N;;;;;
8465 2899;BRAILLE PATTERN DOTS-1458;So;0;L;;;;;N;;;;;
8466 289A;BRAILLE PATTERN DOTS-2458;So;0;L;;;;;N;;;;;
8467 289B;BRAILLE PATTERN DOTS-12458;So;0;L;;;;;N;;;;;
8468 289C;BRAILLE PATTERN DOTS-3458;So;0;L;;;;;N;;;;;
8469 289D;BRAILLE PATTERN DOTS-13458;So;0;L;;;;;N;;;;;
8470 289E;BRAILLE PATTERN DOTS-23458;So;0;L;;;;;N;;;;;
8471 289F;BRAILLE PATTERN DOTS-123458;So;0;L;;;;;N;;;;;
8472 28A0;BRAILLE PATTERN DOTS-68;So;0;L;;;;;N;;;;;
8473 28A1;BRAILLE PATTERN DOTS-168;So;0;L;;;;;N;;;;;
8474 28A2;BRAILLE PATTERN DOTS-268;So;0;L;;;;;N;;;;;
8475 28A3;BRAILLE PATTERN DOTS-1268;So;0;L;;;;;N;;;;;
8476 28A4;BRAILLE PATTERN DOTS-368;So;0;L;;;;;N;;;;;
8477 28A5;BRAILLE PATTERN DOTS-1368;So;0;L;;;;;N;;;;;
8478 28A6;BRAILLE PATTERN DOTS-2368;So;0;L;;;;;N;;;;;
8479 28A7;BRAILLE PATTERN DOTS-12368;So;0;L;;;;;N;;;;;
8480 28A8;BRAILLE PATTERN DOTS-468;So;0;L;;;;;N;;;;;
8481 28A9;BRAILLE PATTERN DOTS-1468;So;0;L;;;;;N;;;;;
8482 28AA;BRAILLE PATTERN DOTS-2468;So;0;L;;;;;N;;;;;
8483 28AB;BRAILLE PATTERN DOTS-12468;So;0;L;;;;;N;;;;;
8484 28AC;BRAILLE PATTERN DOTS-3468;So;0;L;;;;;N;;;;;
8485 28AD;BRAILLE PATTERN DOTS-13468;So;0;L;;;;;N;;;;;
8486 28AE;BRAILLE PATTERN DOTS-23468;So;0;L;;;;;N;;;;;
8487 28AF;BRAILLE PATTERN DOTS-123468;So;0;L;;;;;N;;;;;
8488 28B0;BRAILLE PATTERN DOTS-568;So;0;L;;;;;N;;;;;
8489 28B1;BRAILLE PATTERN DOTS-1568;So;0;L;;;;;N;;;;;
8490 28B2;BRAILLE PATTERN DOTS-2568;So;0;L;;;;;N;;;;;
8491 28B3;BRAILLE PATTERN DOTS-12568;So;0;L;;;;;N;;;;;
8492 28B4;BRAILLE PATTERN DOTS-3568;So;0;L;;;;;N;;;;;
8493 28B5;BRAILLE PATTERN DOTS-13568;So;0;L;;;;;N;;;;;
8494 28B6;BRAILLE PATTERN DOTS-23568;So;0;L;;;;;N;;;;;
8495 28B7;BRAILLE PATTERN DOTS-123568;So;0;L;;;;;N;;;;;
8496 28B8;BRAILLE PATTERN DOTS-4568;So;0;L;;;;;N;;;;;
8497 28B9;BRAILLE PATTERN DOTS-14568;So;0;L;;;;;N;;;;;
8498 28BA;BRAILLE PATTERN DOTS-24568;So;0;L;;;;;N;;;;;
8499 28BB;BRAILLE PATTERN DOTS-124568;So;0;L;;;;;N;;;;;
8500 28BC;BRAILLE PATTERN DOTS-34568;So;0;L;;;;;N;;;;;
8501 28BD;BRAILLE PATTERN DOTS-134568;So;0;L;;;;;N;;;;;
8502 28BE;BRAILLE PATTERN DOTS-234568;So;0;L;;;;;N;;;;;
8503 28BF;BRAILLE PATTERN DOTS-1234568;So;0;L;;;;;N;;;;;
8504 28C0;BRAILLE PATTERN DOTS-78;So;0;L;;;;;N;;;;;
8505 28C1;BRAILLE PATTERN DOTS-178;So;0;L;;;;;N;;;;;
8506 28C2;BRAILLE PATTERN DOTS-278;So;0;L;;;;;N;;;;;
8507 28C3;BRAILLE PATTERN DOTS-1278;So;0;L;;;;;N;;;;;
8508 28C4;BRAILLE PATTERN DOTS-378;So;0;L;;;;;N;;;;;
8509 28C5;BRAILLE PATTERN DOTS-1378;So;0;L;;;;;N;;;;;
8510 28C6;BRAILLE PATTERN DOTS-2378;So;0;L;;;;;N;;;;;
8511 28C7;BRAILLE PATTERN DOTS-12378;So;0;L;;;;;N;;;;;
8512 28C8;BRAILLE PATTERN DOTS-478;So;0;L;;;;;N;;;;;
8513 28C9;BRAILLE PATTERN DOTS-1478;So;0;L;;;;;N;;;;;
8514 28CA;BRAILLE PATTERN DOTS-2478;So;0;L;;;;;N;;;;;
8515 28CB;BRAILLE PATTERN DOTS-12478;So;0;L;;;;;N;;;;;
8516 28CC;BRAILLE PATTERN DOTS-3478;So;0;L;;;;;N;;;;;
8517 28CD;BRAILLE PATTERN DOTS-13478;So;0;L;;;;;N;;;;;
8518 28CE;BRAILLE PATTERN DOTS-23478;So;0;L;;;;;N;;;;;
8519 28CF;BRAILLE PATTERN DOTS-123478;So;0;L;;;;;N;;;;;
8520 28D0;BRAILLE PATTERN DOTS-578;So;0;L;;;;;N;;;;;
8521 28D1;BRAILLE PATTERN DOTS-1578;So;0;L;;;;;N;;;;;
8522 28D2;BRAILLE PATTERN DOTS-2578;So;0;L;;;;;N;;;;;
8523 28D3;BRAILLE PATTERN DOTS-12578;So;0;L;;;;;N;;;;;
8524 28D4;BRAILLE PATTERN DOTS-3578;So;0;L;;;;;N;;;;;
8525 28D5;BRAILLE PATTERN DOTS-13578;So;0;L;;;;;N;;;;;
8526 28D6;BRAILLE PATTERN DOTS-23578;So;0;L;;;;;N;;;;;
8527 28D7;BRAILLE PATTERN DOTS-123578;So;0;L;;;;;N;;;;;
8528 28D8;BRAILLE PATTERN DOTS-4578;So;0;L;;;;;N;;;;;
8529 28D9;BRAILLE PATTERN DOTS-14578;So;0;L;;;;;N;;;;;
8530 28DA;BRAILLE PATTERN DOTS-24578;So;0;L;;;;;N;;;;;
8531 28DB;BRAILLE PATTERN DOTS-124578;So;0;L;;;;;N;;;;;
8532 28DC;BRAILLE PATTERN DOTS-34578;So;0;L;;;;;N;;;;;
8533 28DD;BRAILLE PATTERN DOTS-134578;So;0;L;;;;;N;;;;;
8534 28DE;BRAILLE PATTERN DOTS-234578;So;0;L;;;;;N;;;;;
8535 28DF;BRAILLE PATTERN DOTS-1234578;So;0;L;;;;;N;;;;;
8536 28E0;BRAILLE PATTERN DOTS-678;So;0;L;;;;;N;;;;;
8537 28E1;BRAILLE PATTERN DOTS-1678;So;0;L;;;;;N;;;;;
8538 28E2;BRAILLE PATTERN DOTS-2678;So;0;L;;;;;N;;;;;
8539 28E3;BRAILLE PATTERN DOTS-12678;So;0;L;;;;;N;;;;;
8540 28E4;BRAILLE PATTERN DOTS-3678;So;0;L;;;;;N;;;;;
8541 28E5;BRAILLE PATTERN DOTS-13678;So;0;L;;;;;N;;;;;
8542 28E6;BRAILLE PATTERN DOTS-23678;So;0;L;;;;;N;;;;;
8543 28E7;BRAILLE PATTERN DOTS-123678;So;0;L;;;;;N;;;;;
8544 28E8;BRAILLE PATTERN DOTS-4678;So;0;L;;;;;N;;;;;
8545 28E9;BRAILLE PATTERN DOTS-14678;So;0;L;;;;;N;;;;;
8546 28EA;BRAILLE PATTERN DOTS-24678;So;0;L;;;;;N;;;;;
8547 28EB;BRAILLE PATTERN DOTS-124678;So;0;L;;;;;N;;;;;
8548 28EC;BRAILLE PATTERN DOTS-34678;So;0;L;;;;;N;;;;;
8549 28ED;BRAILLE PATTERN DOTS-134678;So;0;L;;;;;N;;;;;
8550 28EE;BRAILLE PATTERN DOTS-234678;So;0;L;;;;;N;;;;;
8551 28EF;BRAILLE PATTERN DOTS-1234678;So;0;L;;;;;N;;;;;
8552 28F0;BRAILLE PATTERN DOTS-5678;So;0;L;;;;;N;;;;;
8553 28F1;BRAILLE PATTERN DOTS-15678;So;0;L;;;;;N;;;;;
8554 28F2;BRAILLE PATTERN DOTS-25678;So;0;L;;;;;N;;;;;
8555 28F3;BRAILLE PATTERN DOTS-125678;So;0;L;;;;;N;;;;;
8556 28F4;BRAILLE PATTERN DOTS-35678;So;0;L;;;;;N;;;;;
8557 28F5;BRAILLE PATTERN DOTS-135678;So;0;L;;;;;N;;;;;
8558 28F6;BRAILLE PATTERN DOTS-235678;So;0;L;;;;;N;;;;;
8559 28F7;BRAILLE PATTERN DOTS-1235678;So;0;L;;;;;N;;;;;
8560 28F8;BRAILLE PATTERN DOTS-45678;So;0;L;;;;;N;;;;;
8561 28F9;BRAILLE PATTERN DOTS-145678;So;0;L;;;;;N;;;;;
8562 28FA;BRAILLE PATTERN DOTS-245678;So;0;L;;;;;N;;;;;
8563 28FB;BRAILLE PATTERN DOTS-1245678;So;0;L;;;;;N;;;;;
8564 28FC;BRAILLE PATTERN DOTS-345678;So;0;L;;;;;N;;;;;
8565 28FD;BRAILLE PATTERN DOTS-1345678;So;0;L;;;;;N;;;;;
8566 28FE;BRAILLE PATTERN DOTS-2345678;So;0;L;;;;;N;;;;;
8567 28FF;BRAILLE PATTERN DOTS-12345678;So;0;L;;;;;N;;;;;
8568 2900;RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
8569 2901;RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
8570 2902;LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
8571 2903;RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
8572 2904;LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
8573 2905;RIGHTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
8574 2906;LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
8575 2907;RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
8576 2908;DOWNWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
8577 2909;UPWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
8578 290A;UPWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;;
8579 290B;DOWNWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;;
8580 290C;LEFTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
8581 290D;RIGHTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
8582 290E;LEFTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
8583 290F;RIGHTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
8584 2910;RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
8585 2911;RIGHTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;;
8586 2912;UPWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;;
8587 2913;DOWNWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;;
8588 2914;RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
8589 2915;RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
8590 2916;RIGHTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;;
8591 2917;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
8592 2918;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
8593 2919;LEFTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;;
8594 291A;RIGHTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;;
8595 291B;LEFTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;;
8596 291C;RIGHTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;;
8597 291D;LEFTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
8598 291E;RIGHTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
8599 291F;LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
8600 2920;RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
8601 2921;NORTH WEST AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
8602 2922;NORTH EAST AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;;
8603 2923;NORTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;
8604 2924;NORTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;
8605 2925;SOUTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;
8606 2926;SOUTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;
8607 2927;NORTH WEST ARROW AND NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
8608 2928;NORTH EAST ARROW AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
8609 2929;SOUTH EAST ARROW AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;;
8610 292A;SOUTH WEST ARROW AND NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;;
8611 292B;RISING DIAGONAL CROSSING FALLING DIAGONAL;Sm;0;ON;;;;;N;;;;;
8612 292C;FALLING DIAGONAL CROSSING RISING DIAGONAL;Sm;0;ON;;;;;N;;;;;
8613 292D;SOUTH EAST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
8614 292E;NORTH EAST ARROW CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
8615 292F;FALLING DIAGONAL CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
8616 2930;RISING DIAGONAL CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
8617 2931;NORTH EAST ARROW CROSSING NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;;
8618 2932;NORTH WEST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;
8619 2933;WAVE ARROW POINTING DIRECTLY RIGHT;Sm;0;ON;;;;;N;;;;;
8620 2934;ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS;Sm;0;ON;;;;;N;;;;;
8621 2935;ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS;Sm;0;ON;;;;;N;;;;;
8622 2936;ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS;Sm;0;ON;;;;;N;;;;;
8623 2937;ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS;Sm;0;ON;;;;;N;;;;;
8624 2938;RIGHT-SIDE ARC CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
8625 2939;LEFT-SIDE ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
8626 293A;TOP ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
8627 293B;BOTTOM ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
8628 293C;TOP ARC CLOCKWISE ARROW WITH MINUS;Sm;0;ON;;;;;N;;;;;
8629 293D;TOP ARC ANTICLOCKWISE ARROW WITH PLUS;Sm;0;ON;;;;;N;;;;;
8630 293E;LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
8631 293F;LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;
8632 2940;ANTICLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;
8633 2941;CLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;
8634 2942;RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
8635 2943;LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
8636 2944;SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
8637 2945;RIGHTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;;
8638 2946;LEFTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;;
8639 2947;RIGHTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;;
8640 2948;LEFT RIGHT ARROW THROUGH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
8641 2949;UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
8642 294A;LEFT BARB UP RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;;
8643 294B;LEFT BARB DOWN RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;;
8644 294C;UP BARB RIGHT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;;
8645 294D;UP BARB LEFT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;;
8646 294E;LEFT BARB UP RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;;
8647 294F;UP BARB RIGHT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;;
8648 2950;LEFT BARB DOWN RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;;
8649 2951;UP BARB LEFT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;;
8650 2952;LEFTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;;
8651 2953;RIGHTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;;
8652 2954;UPWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;;
8653 2955;DOWNWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;;
8654 2956;LEFTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;;
8655 2957;RIGHTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;;
8656 2958;UPWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;;
8657 2959;DOWNWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;;
8658 295A;LEFTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;;
8659 295B;RIGHTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;;
8660 295C;UPWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;;
8661 295D;DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;;
8662 295E;LEFTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;;
8663 295F;RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;;
8664 2960;UPWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;;
8665 2961;DOWNWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;;
8666 2962;LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;
8667 2963;UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;
8668 2964;RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;
8669 2965;DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;
8670 2966;LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;;
8671 2967;LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;
8672 2968;RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;;
8673 2969;RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;
8674 296A;LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;;
8675 296B;LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;;
8676 296C;RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;;
8677 296D;RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;;
8678 296E;UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;
8679 296F;DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;
8680 2970;RIGHT DOUBLE ARROW WITH ROUNDED HEAD;Sm;0;ON;;;;;N;;;;;
8681 2971;EQUALS SIGN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
8682 2972;TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
8683 2973;LEFTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;
8684 2974;RIGHTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;
8685 2975;RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;
8686 2976;LESS-THAN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
8687 2977;LEFTWARDS ARROW THROUGH LESS-THAN;Sm;0;ON;;;;;N;;;;;
8688 2978;GREATER-THAN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
8689 2979;SUBSET ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
8690 297A;LEFTWARDS ARROW THROUGH SUBSET;Sm;0;ON;;;;;N;;;;;
8691 297B;SUPERSET ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
8692 297C;LEFT FISH TAIL;Sm;0;ON;;;;;N;;;;;
8693 297D;RIGHT FISH TAIL;Sm;0;ON;;;;;N;;;;;
8694 297E;UP FISH TAIL;Sm;0;ON;;;;;N;;;;;
8695 297F;DOWN FISH TAIL;Sm;0;ON;;;;;N;;;;;
8696 2980;TRIPLE VERTICAL BAR DELIMITER;Sm;0;ON;;;;;N;;;;;
8697 2981;Z NOTATION SPOT;Sm;0;ON;;;;;N;;;;;
8698 2982;Z NOTATION TYPE COLON;Sm;0;ON;;;;;N;;;;;
8699 2983;LEFT WHITE CURLY BRACKET;Ps;0;ON;;;;;Y;;;;;
8700 2984;RIGHT WHITE CURLY BRACKET;Pe;0;ON;;;;;Y;;;;;
8701 2985;LEFT WHITE PARENTHESIS;Ps;0;ON;;;;;Y;;;;;
8702 2986;RIGHT WHITE PARENTHESIS;Pe;0;ON;;;;;Y;;;;;
8703 2987;Z NOTATION LEFT IMAGE BRACKET;Ps;0;ON;;;;;Y;;;;;
8704 2988;Z NOTATION RIGHT IMAGE BRACKET;Pe;0;ON;;;;;Y;;;;;
8705 2989;Z NOTATION LEFT BINDING BRACKET;Ps;0;ON;;;;;Y;;;;;
8706 298A;Z NOTATION RIGHT BINDING BRACKET;Pe;0;ON;;;;;Y;;;;;
8707 298B;LEFT SQUARE BRACKET WITH UNDERBAR;Ps;0;ON;;;;;Y;;;;;
8708 298C;RIGHT SQUARE BRACKET WITH UNDERBAR;Pe;0;ON;;;;;Y;;;;;
8709 298D;LEFT SQUARE BRACKET WITH TICK IN TOP CORNER;Ps;0;ON;;;;;Y;;;;;
8710 298E;RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Pe;0;ON;;;;;Y;;;;;
8711 298F;LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Ps;0;ON;;;;;Y;;;;;
8712 2990;RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER;Pe;0;ON;;;;;Y;;;;;
8713 2991;LEFT ANGLE BRACKET WITH DOT;Ps;0;ON;;;;;Y;;;;;
8714 2992;RIGHT ANGLE BRACKET WITH DOT;Pe;0;ON;;;;;Y;;;;;
8715 2993;LEFT ARC LESS-THAN BRACKET;Ps;0;ON;;;;;Y;;;;;
8716 2994;RIGHT ARC GREATER-THAN BRACKET;Pe;0;ON;;;;;Y;;;;;
8717 2995;DOUBLE LEFT ARC GREATER-THAN BRACKET;Ps;0;ON;;;;;Y;;;;;
8718 2996;DOUBLE RIGHT ARC LESS-THAN BRACKET;Pe;0;ON;;;;;Y;;;;;
8719 2997;LEFT BLACK TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;;
8720 2998;RIGHT BLACK TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;;
8721 2999;DOTTED FENCE;Sm;0;ON;;;;;N;;;;;
8722 299A;VERTICAL ZIGZAG LINE;Sm;0;ON;;;;;N;;;;;
8723 299B;MEASURED ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;;
8724 299C;RIGHT ANGLE VARIANT WITH SQUARE;Sm;0;ON;;;;;Y;;;;;
8725 299D;MEASURED RIGHT ANGLE WITH DOT;Sm;0;ON;;;;;Y;;;;;
8726 299E;ANGLE WITH S INSIDE;Sm;0;ON;;;;;Y;;;;;
8727 299F;ACUTE ANGLE;Sm;0;ON;;;;;Y;;;;;
8728 29A0;SPHERICAL ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;;
8729 29A1;SPHERICAL ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;;
8730 29A2;TURNED ANGLE;Sm;0;ON;;;;;Y;;;;;
8731 29A3;REVERSED ANGLE;Sm;0;ON;;;;;Y;;;;;
8732 29A4;ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
8733 29A5;REVERSED ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
8734 29A6;OBLIQUE ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;;
8735 29A7;OBLIQUE ANGLE OPENING DOWN;Sm;0;ON;;;;;Y;;;;;
8736 29A8;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT;Sm;0;ON;;;;;Y;;;;;
8737 29A9;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT;Sm;0;ON;;;;;Y;;;;;
8738 29AA;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT;Sm;0;ON;;;;;Y;;;;;
8739 29AB;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT;Sm;0;ON;;;;;Y;;;;;
8740 29AC;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP;Sm;0;ON;;;;;Y;;;;;
8741 29AD;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP;Sm;0;ON;;;;;Y;;;;;
8742 29AE;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN;Sm;0;ON;;;;;Y;;;;;
8743 29AF;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN;Sm;0;ON;;;;;Y;;;;;
8744 29B0;REVERSED EMPTY SET;Sm;0;ON;;;;;N;;;;;
8745 29B1;EMPTY SET WITH OVERBAR;Sm;0;ON;;;;;N;;;;;
8746 29B2;EMPTY SET WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;
8747 29B3;EMPTY SET WITH RIGHT ARROW ABOVE;Sm;0;ON;;;;;N;;;;;
8748 29B4;EMPTY SET WITH LEFT ARROW ABOVE;Sm;0;ON;;;;;N;;;;;
8749 29B5;CIRCLE WITH HORIZONTAL BAR;Sm;0;ON;;;;;N;;;;;
8750 29B6;CIRCLED VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
8751 29B7;CIRCLED PARALLEL;Sm;0;ON;;;;;N;;;;;
8752 29B8;CIRCLED REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;;
8753 29B9;CIRCLED PERPENDICULAR;Sm;0;ON;;;;;N;;;;;
8754 29BA;CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
8755 29BB;CIRCLE WITH SUPERIMPOSED X;Sm;0;ON;;;;;N;;;;;
8756 29BC;CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN;Sm;0;ON;;;;;N;;;;;
8757 29BD;UP ARROW THROUGH CIRCLE;Sm;0;ON;;;;;N;;;;;
8758 29BE;CIRCLED WHITE BULLET;Sm;0;ON;;;;;N;;;;;
8759 29BF;CIRCLED BULLET;Sm;0;ON;;;;;N;;;;;
8760 29C0;CIRCLED LESS-THAN;Sm;0;ON;;;;;Y;;;;;
8761 29C1;CIRCLED GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
8762 29C2;CIRCLE WITH SMALL CIRCLE TO THE RIGHT;Sm;0;ON;;;;;Y;;;;;
8763 29C3;CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT;Sm;0;ON;;;;;Y;;;;;
8764 29C4;SQUARED RISING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;;
8765 29C5;SQUARED FALLING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;;
8766 29C6;SQUARED ASTERISK;Sm;0;ON;;;;;N;;;;;
8767 29C7;SQUARED SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
8768 29C8;SQUARED SQUARE;Sm;0;ON;;;;;N;;;;;
8769 29C9;TWO JOINED SQUARES;Sm;0;ON;;;;;Y;;;;;
8770 29CA;TRIANGLE WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
8771 29CB;TRIANGLE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
8772 29CC;S IN TRIANGLE;Sm;0;ON;;;;;N;;;;;
8773 29CD;TRIANGLE WITH SERIFS AT BOTTOM;Sm;0;ON;;;;;N;;;;;
8774 29CE;RIGHT TRIANGLE ABOVE LEFT TRIANGLE;Sm;0;ON;;;;;Y;;;;;
8775 29CF;LEFT TRIANGLE BESIDE VERTICAL BAR;Sm;0;ON;;;;;Y;;;;;
8776 29D0;VERTICAL BAR BESIDE RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;;
8777 29D1;BOWTIE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
8778 29D2;BOWTIE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
8779 29D3;BLACK BOWTIE;Sm;0;ON;;;;;N;;;;;
8780 29D4;TIMES WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
8781 29D5;TIMES WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
8782 29D6;WHITE HOURGLASS;Sm;0;ON;;;;;N;;;;;
8783 29D7;BLACK HOURGLASS;Sm;0;ON;;;;;N;;;;;
8784 29D8;LEFT WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;;
8785 29D9;RIGHT WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;;
8786 29DA;LEFT DOUBLE WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;;
8787 29DB;RIGHT DOUBLE WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;;
8788 29DC;INCOMPLETE INFINITY;Sm;0;ON;;;;;Y;;;;;
8789 29DD;TIE OVER INFINITY;Sm;0;ON;;;;;N;;;;;
8790 29DE;INFINITY NEGATED WITH VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
8791 29DF;DOUBLE-ENDED MULTIMAP;Sm;0;ON;;;;;N;;;;;
8792 29E0;SQUARE WITH CONTOURED OUTLINE;Sm;0;ON;;;;;N;;;;;
8793 29E1;INCREASES AS;Sm;0;ON;;;;;Y;;;;;
8794 29E2;SHUFFLE PRODUCT;Sm;0;ON;;;;;N;;;;;
8795 29E3;EQUALS SIGN AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;;
8796 29E4;EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;;
8797 29E5;IDENTICAL TO AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;;
8798 29E6;GLEICH STARK;Sm;0;ON;;;;;N;;;;;
8799 29E7;THERMODYNAMIC;Sm;0;ON;;;;;N;;;;;
8800 29E8;DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
8801 29E9;DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;;
8802 29EA;BLACK DIAMOND WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;;
8803 29EB;BLACK LOZENGE;Sm;0;ON;;;;;N;;;;;
8804 29EC;WHITE CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;;
8805 29ED;BLACK CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;;
8806 29EE;ERROR-BARRED WHITE SQUARE;Sm;0;ON;;;;;N;;;;;
8807 29EF;ERROR-BARRED BLACK SQUARE;Sm;0;ON;;;;;N;;;;;
8808 29F0;ERROR-BARRED WHITE DIAMOND;Sm;0;ON;;;;;N;;;;;
8809 29F1;ERROR-BARRED BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;
8810 29F2;ERROR-BARRED WHITE CIRCLE;Sm;0;ON;;;;;N;;;;;
8811 29F3;ERROR-BARRED BLACK CIRCLE;Sm;0;ON;;;;;N;;;;;
8812 29F4;RULE-DELAYED;Sm;0;ON;;;;;Y;;;;;
8813 29F5;REVERSE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;;
8814 29F6;SOLIDUS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
8815 29F7;REVERSE SOLIDUS WITH HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;
8816 29F8;BIG SOLIDUS;Sm;0;ON;;;;;Y;;;;;
8817 29F9;BIG REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;;
8818 29FA;DOUBLE PLUS;Sm;0;ON;;;;;N;;;;;
8819 29FB;TRIPLE PLUS;Sm;0;ON;;;;;N;;;;;
8820 29FC;LEFT-POINTING CURVED ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;;
8821 29FD;RIGHT-POINTING CURVED ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;;
8822 29FE;TINY;Sm;0;ON;;;;;N;;;;;
8823 29FF;MINY;Sm;0;ON;;;;;N;;;;;
8824 2A00;N-ARY CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;;
8825 2A01;N-ARY CIRCLED PLUS OPERATOR;Sm;0;ON;;;;;N;;;;;
8826 2A02;N-ARY CIRCLED TIMES OPERATOR;Sm;0;ON;;;;;N;;;;;
8827 2A03;N-ARY UNION OPERATOR WITH DOT;Sm;0;ON;;;;;N;;;;;
8828 2A04;N-ARY UNION OPERATOR WITH PLUS;Sm;0;ON;;;;;N;;;;;
8829 2A05;N-ARY SQUARE INTERSECTION OPERATOR;Sm;0;ON;;;;;N;;;;;
8830 2A06;N-ARY SQUARE UNION OPERATOR;Sm;0;ON;;;;;N;;;;;
8831 2A07;TWO LOGICAL AND OPERATOR;Sm;0;ON;;;;;N;;;;;
8832 2A08;TWO LOGICAL OR OPERATOR;Sm;0;ON;;;;;N;;;;;
8833 2A09;N-ARY TIMES OPERATOR;Sm;0;ON;;;;;N;;;;;
8834 2A0A;MODULO TWO SUM;Sm;0;ON;;;;;Y;;;;;
8835 2A0B;SUMMATION WITH INTEGRAL;Sm;0;ON;;;;;Y;;;;;
8836 2A0C;QUADRUPLE INTEGRAL OPERATOR;Sm;0;ON;<compat> 222B 222B 222B 222B;;;;Y;;;;;
8837 2A0D;FINITE PART INTEGRAL;Sm;0;ON;;;;;Y;;;;;
8838 2A0E;INTEGRAL WITH DOUBLE STROKE;Sm;0;ON;;;;;Y;;;;;
8839 2A0F;INTEGRAL AVERAGE WITH SLASH;Sm;0;ON;;;;;Y;;;;;
8840 2A10;CIRCULATION FUNCTION;Sm;0;ON;;;;;Y;;;;;
8841 2A11;ANTICLOCKWISE INTEGRATION;Sm;0;ON;;;;;Y;;;;;
8842 2A12;LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;;
8843 2A13;LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;;
8844 2A14;LINE INTEGRATION NOT INCLUDING THE POLE;Sm;0;ON;;;;;Y;;;;;
8845 2A15;INTEGRAL AROUND A POINT OPERATOR;Sm;0;ON;;;;;Y;;;;;
8846 2A16;QUATERNION INTEGRAL OPERATOR;Sm;0;ON;;;;;Y;;;;;
8847 2A17;INTEGRAL WITH LEFTWARDS ARROW WITH HOOK;Sm;0;ON;;;;;Y;;;;;
8848 2A18;INTEGRAL WITH TIMES SIGN;Sm;0;ON;;;;;Y;;;;;
8849 2A19;INTEGRAL WITH INTERSECTION;Sm;0;ON;;;;;Y;;;;;
8850 2A1A;INTEGRAL WITH UNION;Sm;0;ON;;;;;Y;;;;;
8851 2A1B;INTEGRAL WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;
8852 2A1C;INTEGRAL WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
8853 2A1D;JOIN;Sm;0;ON;;;;;N;;;;;
8854 2A1E;LARGE LEFT TRIANGLE OPERATOR;Sm;0;ON;;;;;Y;;;;;
8855 2A1F;Z NOTATION SCHEMA COMPOSITION;Sm;0;ON;;;;;Y;;;;;
8856 2A20;Z NOTATION SCHEMA PIPING;Sm;0;ON;;;;;Y;;;;;
8857 2A21;Z NOTATION SCHEMA PROJECTION;Sm;0;ON;;;;;Y;;;;;
8858 2A22;PLUS SIGN WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;
8859 2A23;PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE;Sm;0;ON;;;;;N;;;;;
8860 2A24;PLUS SIGN WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;;
8861 2A25;PLUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;;
8862 2A26;PLUS SIGN WITH TILDE BELOW;Sm;0;ON;;;;;Y;;;;;
8863 2A27;PLUS SIGN WITH SUBSCRIPT TWO;Sm;0;ON;;;;;N;;;;;
8864 2A28;PLUS SIGN WITH BLACK TRIANGLE;Sm;0;ON;;;;;N;;;;;
8865 2A29;MINUS SIGN WITH COMMA ABOVE;Sm;0;ON;;;;;Y;;;;;
8866 2A2A;MINUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;;
8867 2A2B;MINUS SIGN WITH FALLING DOTS;Sm;0;ON;;;;;Y;;;;;
8868 2A2C;MINUS SIGN WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;;
8869 2A2D;PLUS SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;
8870 2A2E;PLUS SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;
8871 2A2F;VECTOR OR CROSS PRODUCT;Sm;0;ON;;;;;N;;;;;
8872 2A30;MULTIPLICATION SIGN WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
8873 2A31;MULTIPLICATION SIGN WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
8874 2A32;SEMIDIRECT PRODUCT WITH BOTTOM CLOSED;Sm;0;ON;;;;;N;;;;;
8875 2A33;SMASH PRODUCT;Sm;0;ON;;;;;N;;;;;
8876 2A34;MULTIPLICATION SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;
8877 2A35;MULTIPLICATION SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;
8878 2A36;CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;N;;;;;
8879 2A37;MULTIPLICATION SIGN IN DOUBLE CIRCLE;Sm;0;ON;;;;;N;;;;;
8880 2A38;CIRCLED DIVISION SIGN;Sm;0;ON;;;;;N;;;;;
8881 2A39;PLUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;;
8882 2A3A;MINUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;;
8883 2A3B;MULTIPLICATION SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;;
8884 2A3C;INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;;
8885 2A3D;RIGHTHAND INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;;
8886 2A3E;Z NOTATION RELATIONAL COMPOSITION;Sm;0;ON;;;;;Y;;;;;
8887 2A3F;AMALGAMATION OR COPRODUCT;Sm;0;ON;;;;;N;;;;;
8888 2A40;INTERSECTION WITH DOT;Sm;0;ON;;;;;N;;;;;
8889 2A41;UNION WITH MINUS SIGN;Sm;0;ON;;;;;N;;;;;
8890 2A42;UNION WITH OVERBAR;Sm;0;ON;;;;;N;;;;;
8891 2A43;INTERSECTION WITH OVERBAR;Sm;0;ON;;;;;N;;;;;
8892 2A44;INTERSECTION WITH LOGICAL AND;Sm;0;ON;;;;;N;;;;;
8893 2A45;UNION WITH LOGICAL OR;Sm;0;ON;;;;;N;;;;;
8894 2A46;UNION ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;;
8895 2A47;INTERSECTION ABOVE UNION;Sm;0;ON;;;;;N;;;;;
8896 2A48;UNION ABOVE BAR ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;;
8897 2A49;INTERSECTION ABOVE BAR ABOVE UNION;Sm;0;ON;;;;;N;;;;;
8898 2A4A;UNION BESIDE AND JOINED WITH UNION;Sm;0;ON;;;;;N;;;;;
8899 2A4B;INTERSECTION BESIDE AND JOINED WITH INTERSECTION;Sm;0;ON;;;;;N;;;;;
8900 2A4C;CLOSED UNION WITH SERIFS;Sm;0;ON;;;;;N;;;;;
8901 2A4D;CLOSED INTERSECTION WITH SERIFS;Sm;0;ON;;;;;N;;;;;
8902 2A4E;DOUBLE SQUARE INTERSECTION;Sm;0;ON;;;;;N;;;;;
8903 2A4F;DOUBLE SQUARE UNION;Sm;0;ON;;;;;N;;;;;
8904 2A50;CLOSED UNION WITH SERIFS AND SMASH PRODUCT;Sm;0;ON;;;;;N;;;;;
8905 2A51;LOGICAL AND WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
8906 2A52;LOGICAL OR WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
8907 2A53;DOUBLE LOGICAL AND;Sm;0;ON;;;;;N;;;;;
8908 2A54;DOUBLE LOGICAL OR;Sm;0;ON;;;;;N;;;;;
8909 2A55;TWO INTERSECTING LOGICAL AND;Sm;0;ON;;;;;N;;;;;
8910 2A56;TWO INTERSECTING LOGICAL OR;Sm;0;ON;;;;;N;;;;;
8911 2A57;SLOPING LARGE OR;Sm;0;ON;;;;;Y;;;;;
8912 2A58;SLOPING LARGE AND;Sm;0;ON;;;;;Y;;;;;
8913 2A59;LOGICAL OR OVERLAPPING LOGICAL AND;Sm;0;ON;;;;;N;;;;;
8914 2A5A;LOGICAL AND WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;;
8915 2A5B;LOGICAL OR WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;;
8916 2A5C;LOGICAL AND WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;;
8917 2A5D;LOGICAL OR WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;;
8918 2A5E;LOGICAL AND WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;;
8919 2A5F;LOGICAL AND WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
8920 2A60;LOGICAL AND WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;;
8921 2A61;SMALL VEE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
8922 2A62;LOGICAL OR WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;;
8923 2A63;LOGICAL OR WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;;
8924 2A64;Z NOTATION DOMAIN ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;;
8925 2A65;Z NOTATION RANGE ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;;
8926 2A66;EQUALS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;;
8927 2A67;IDENTICAL WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;
8928 2A68;TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
8929 2A69;TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
8930 2A6A;TILDE OPERATOR WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
8931 2A6B;TILDE OPERATOR WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;;
8932 2A6C;SIMILAR MINUS SIMILAR;Sm;0;ON;;;;;Y;;;;;
8933 2A6D;CONGRUENT WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
8934 2A6E;EQUALS WITH ASTERISK;Sm;0;ON;;;;;N;;;;;
8935 2A6F;ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;Y;;;;;
8936 2A70;APPROXIMATELY EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
8937 2A71;EQUALS SIGN ABOVE PLUS SIGN;Sm;0;ON;;;;;N;;;;;
8938 2A72;PLUS SIGN ABOVE EQUALS SIGN;Sm;0;ON;;;;;N;;;;;
8939 2A73;EQUALS SIGN ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
8940 2A74;DOUBLE COLON EQUAL;Sm;0;ON;<compat> 003A 003A 003D;;;;Y;;;;;
8941 2A75;TWO CONSECUTIVE EQUALS SIGNS;Sm;0;ON;<compat> 003D 003D;;;;N;;;;;
8942 2A76;THREE CONSECUTIVE EQUALS SIGNS;Sm;0;ON;<compat> 003D 003D 003D;;;;N;;;;;
8943 2A77;EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW;Sm;0;ON;;;;;N;;;;;
8944 2A78;EQUIVALENT WITH FOUR DOTS ABOVE;Sm;0;ON;;;;;N;;;;;
8945 2A79;LESS-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;;
8946 2A7A;GREATER-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;;
8947 2A7B;LESS-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;;
8948 2A7C;GREATER-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;;
8949 2A7D;LESS-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;;
8950 2A7E;GREATER-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;;
8951 2A7F;LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;
8952 2A80;GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;
8953 2A81;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
8954 2A82;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
8955 2A83;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT;Sm;0;ON;;;;;Y;;;;;
8956 2A84;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT;Sm;0;ON;;;;;Y;;;;;
8957 2A85;LESS-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;;
8958 2A86;GREATER-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;;
8959 2A87;LESS-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
8960 2A88;GREATER-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
8961 2A89;LESS-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;;
8962 2A8A;GREATER-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;;
8963 2A8B;LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
8964 2A8C;GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;;
8965 2A8D;LESS-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;;
8966 2A8E;GREATER-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;;
8967 2A8F;LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
8968 2A90;GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;;
8969 2A91;LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;;
8970 2A92;GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;;
8971 2A93;LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;
8972 2A94;GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;
8973 2A95;SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;
8974 2A96;SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
8975 2A97;SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;
8976 2A98;SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;
8977 2A99;DOUBLE-LINE EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;
8978 2A9A;DOUBLE-LINE EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
8979 2A9B;DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;
8980 2A9C;DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
8981 2A9D;SIMILAR OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;
8982 2A9E;SIMILAR OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
8983 2A9F;SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
8984 2AA0;SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
8985 2AA1;DOUBLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;;
8986 2AA2;DOUBLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
8987 2AA3;DOUBLE NESTED LESS-THAN WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;
8988 2AA4;GREATER-THAN OVERLAPPING LESS-THAN;Sm;0;ON;;;;;N;;;;;
8989 2AA5;GREATER-THAN BESIDE LESS-THAN;Sm;0;ON;;;;;N;;;;;
8990 2AA6;LESS-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;;
8991 2AA7;GREATER-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;;
8992 2AA8;LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;
8993 2AA9;GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;
8994 2AAA;SMALLER THAN;Sm;0;ON;;;;;Y;;;;;
8995 2AAB;LARGER THAN;Sm;0;ON;;;;;Y;;;;;
8996 2AAC;SMALLER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
8997 2AAD;LARGER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
8998 2AAE;EQUALS SIGN WITH BUMPY ABOVE;Sm;0;ON;;;;;N;;;;;
8999 2AAF;PRECEDES ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
9000 2AB0;SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
9001 2AB1;PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9002 2AB2;SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9003 2AB3;PRECEDES ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
9004 2AB4;SUCCEEDS ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
9005 2AB5;PRECEDES ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9006 2AB6;SUCCEEDS ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9007 2AB7;PRECEDES ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9008 2AB8;SUCCEEDS ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9009 2AB9;PRECEDES ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9010 2ABA;SUCCEEDS ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9011 2ABB;DOUBLE PRECEDES;Sm;0;ON;;;;;Y;;;;;
9012 2ABC;DOUBLE SUCCEEDS;Sm;0;ON;;;;;Y;;;;;
9013 2ABD;SUBSET WITH DOT;Sm;0;ON;;;;;Y;;;;;
9014 2ABE;SUPERSET WITH DOT;Sm;0;ON;;;;;Y;;;;;
9015 2ABF;SUBSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;;
9016 2AC0;SUPERSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;;
9017 2AC1;SUBSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;;
9018 2AC2;SUPERSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;;
9019 2AC3;SUBSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
9020 2AC4;SUPERSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;
9021 2AC5;SUBSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
9022 2AC6;SUPERSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;
9023 2AC7;SUBSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
9024 2AC8;SUPERSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
9025 2AC9;SUBSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9026 2ACA;SUPERSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9027 2ACB;SUBSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9028 2ACC;SUPERSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9029 2ACD;SQUARE LEFT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;;
9030 2ACE;SQUARE RIGHT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;;
9031 2ACF;CLOSED SUBSET;Sm;0;ON;;;;;Y;;;;;
9032 2AD0;CLOSED SUPERSET;Sm;0;ON;;;;;Y;;;;;
9033 2AD1;CLOSED SUBSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9034 2AD2;CLOSED SUPERSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9035 2AD3;SUBSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;;
9036 2AD4;SUPERSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;;
9037 2AD5;SUBSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;;
9038 2AD6;SUPERSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;;
9039 2AD7;SUPERSET BESIDE SUBSET;Sm;0;ON;;;;;N;;;;;
9040 2AD8;SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET;Sm;0;ON;;;;;N;;;;;
9041 2AD9;ELEMENT OF OPENING DOWNWARDS;Sm;0;ON;;;;;N;;;;;
9042 2ADA;PITCHFORK WITH TEE TOP;Sm;0;ON;;;;;N;;;;;
9043 2ADB;TRANSVERSAL INTERSECTION;Sm;0;ON;;;;;N;;;;;
9044 2ADC;FORKING;Sm;0;ON;2ADD 0338;;;;Y;;not independent;;;
9045 2ADD;NONFORKING;Sm;0;ON;;;;;N;;independent;;;
9046 2ADE;SHORT LEFT TACK;Sm;0;ON;;;;;Y;;;;;
9047 2ADF;SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;;
9048 2AE0;SHORT UP TACK;Sm;0;ON;;;;;N;;;;;
9049 2AE1;PERPENDICULAR WITH S;Sm;0;ON;;;;;N;;;;;
9050 2AE2;VERTICAL BAR TRIPLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
9051 2AE3;DOUBLE VERTICAL BAR LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
9052 2AE4;VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
9053 2AE5;DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;;
9054 2AE6;LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL;Sm;0;ON;;;;;Y;;;;;
9055 2AE7;SHORT DOWN TACK WITH OVERBAR;Sm;0;ON;;;;;N;;;;;
9056 2AE8;SHORT UP TACK WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;
9057 2AE9;SHORT UP TACK ABOVE SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;;
9058 2AEA;DOUBLE DOWN TACK;Sm;0;ON;;;;;N;;;;;
9059 2AEB;DOUBLE UP TACK;Sm;0;ON;;;;;N;;;;;
9060 2AEC;DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;;
9061 2AED;REVERSED DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;;
9062 2AEE;DOES NOT DIVIDE WITH REVERSED NEGATION SLASH;Sm;0;ON;;;;;Y;;;;;
9063 2AEF;VERTICAL LINE WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;
9064 2AF0;VERTICAL LINE WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;;
9065 2AF1;DOWN TACK WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;;
9066 2AF2;PARALLEL WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
9067 2AF3;PARALLEL WITH TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;
9068 2AF4;TRIPLE VERTICAL BAR BINARY RELATION;Sm;0;ON;;;;;N;;;;;
9069 2AF5;TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;
9070 2AF6;TRIPLE COLON OPERATOR;Sm;0;ON;;;;;N;;;;;
9071 2AF7;TRIPLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;;
9072 2AF8;TRIPLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;;
9073 2AF9;DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9074 2AFA;DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;
9075 2AFB;TRIPLE SOLIDUS BINARY RELATION;Sm;0;ON;;;;;Y;;;;;
9076 2AFC;LARGE TRIPLE VERTICAL BAR OPERATOR;Sm;0;ON;;;;;N;;;;;
9077 2AFD;DOUBLE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;;
9078 2AFE;WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
9079 2AFF;N-ARY WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;;
9080 2B00;NORTH EAST WHITE ARROW;So;0;ON;;;;;N;;;;;
9081 2B01;NORTH WEST WHITE ARROW;So;0;ON;;;;;N;;;;;
9082 2B02;SOUTH EAST WHITE ARROW;So;0;ON;;;;;N;;;;;
9083 2B03;SOUTH WEST WHITE ARROW;So;0;ON;;;;;N;;;;;
9084 2B04;LEFT RIGHT WHITE ARROW;So;0;ON;;;;;N;;;;;
9085 2B05;LEFTWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;
9086 2B06;UPWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;
9087 2B07;DOWNWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;
9088 2B08;NORTH EAST BLACK ARROW;So;0;ON;;;;;N;;;;;
9089 2B09;NORTH WEST BLACK ARROW;So;0;ON;;;;;N;;;;;
9090 2B0A;SOUTH EAST BLACK ARROW;So;0;ON;;;;;N;;;;;
9091 2B0B;SOUTH WEST BLACK ARROW;So;0;ON;;;;;N;;;;;
9092 2B0C;LEFT RIGHT BLACK ARROW;So;0;ON;;;;;N;;;;;
9093 2B0D;UP DOWN BLACK ARROW;So;0;ON;;;;;N;;;;;
9094 2B0E;RIGHTWARDS ARROW WITH TIP DOWNWARDS;So;0;ON;;;;;N;;;;;
9095 2B0F;RIGHTWARDS ARROW WITH TIP UPWARDS;So;0;ON;;;;;N;;;;;
9096 2B10;LEFTWARDS ARROW WITH TIP DOWNWARDS;So;0;ON;;;;;N;;;;;
9097 2B11;LEFTWARDS ARROW WITH TIP UPWARDS;So;0;ON;;;;;N;;;;;
9098 2B12;SQUARE WITH TOP HALF BLACK;So;0;ON;;;;;N;;;;;
9099 2B13;SQUARE WITH BOTTOM HALF BLACK;So;0;ON;;;;;N;;;;;
9100 2B14;SQUARE WITH UPPER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;
9101 2B15;SQUARE WITH LOWER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;
9102 2B16;DIAMOND WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;
9103 2B17;DIAMOND WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;
9104 2B18;DIAMOND WITH TOP HALF BLACK;So;0;ON;;;;;N;;;;;
9105 2B19;DIAMOND WITH BOTTOM HALF BLACK;So;0;ON;;;;;N;;;;;
9106 2B1A;DOTTED SQUARE;So;0;ON;;;;;N;;;;;
9107 2B1B;BLACK LARGE SQUARE;So;0;ON;;;;;N;;;;;
9108 2B1C;WHITE LARGE SQUARE;So;0;ON;;;;;N;;;;;
9109 2B1D;BLACK VERY SMALL SQUARE;So;0;ON;;;;;N;;;;;
9110 2B1E;WHITE VERY SMALL SQUARE;So;0;ON;;;;;N;;;;;
9111 2B1F;BLACK PENTAGON;So;0;ON;;;;;N;;;;;
9112 2B20;WHITE PENTAGON;So;0;ON;;;;;N;;;;;
9113 2B21;WHITE HEXAGON;So;0;ON;;;;;N;;;;;
9114 2B22;BLACK HEXAGON;So;0;ON;;;;;N;;;;;
9115 2B23;HORIZONTAL BLACK HEXAGON;So;0;ON;;;;;N;;;;;
9116 2B24;BLACK LARGE CIRCLE;So;0;ON;;;;;N;;;;;
9117 2B25;BLACK MEDIUM DIAMOND;So;0;ON;;;;;N;;;;;
9118 2B26;WHITE MEDIUM DIAMOND;So;0;ON;;;;;N;;;;;
9119 2B27;BLACK MEDIUM LOZENGE;So;0;ON;;;;;N;;;;;
9120 2B28;WHITE MEDIUM LOZENGE;So;0;ON;;;;;N;;;;;
9121 2B29;BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;;
9122 2B2A;BLACK SMALL LOZENGE;So;0;ON;;;;;N;;;;;
9123 2B2B;WHITE SMALL LOZENGE;So;0;ON;;;;;N;;;;;
9124 2B2C;BLACK HORIZONTAL ELLIPSE;So;0;ON;;;;;N;;;;;
9125 2B2D;WHITE HORIZONTAL ELLIPSE;So;0;ON;;;;;N;;;;;
9126 2B2E;BLACK VERTICAL ELLIPSE;So;0;ON;;;;;N;;;;;
9127 2B2F;WHITE VERTICAL ELLIPSE;So;0;ON;;;;;N;;;;;
9128 2B30;LEFT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;
9129 2B31;THREE LEFTWARDS ARROWS;Sm;0;ON;;;;;N;;;;;
9130 2B32;LEFT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;;
9131 2B33;LONG LEFTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;;
9132 2B34;LEFTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
9133 2B35;LEFTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
9134 2B36;LEFTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;
9135 2B37;LEFTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;
9136 2B38;LEFTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;;
9137 2B39;LEFTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
9138 2B3A;LEFTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
9139 2B3B;LEFTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;;
9140 2B3C;LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
9141 2B3D;LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;
9142 2B3E;LEFTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;;
9143 2B3F;WAVE ARROW POINTING DIRECTLY LEFT;Sm;0;ON;;;;;N;;;;;
9144 2B40;EQUALS SIGN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
9145 2B41;REVERSE TILDE OPERATOR ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
9146 2B42;LEFTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;
9147 2B43;RIGHTWARDS ARROW THROUGH GREATER-THAN;Sm;0;ON;;;;;N;;;;;
9148 2B44;RIGHTWARDS ARROW THROUGH SUPERSET;Sm;0;ON;;;;;N;;;;;
9149 2B45;LEFTWARDS QUADRUPLE ARROW;So;0;ON;;;;;N;;;;;
9150 2B46;RIGHTWARDS QUADRUPLE ARROW;So;0;ON;;;;;N;;;;;
9151 2B47;REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
9152 2B48;RIGHTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;
9153 2B49;TILDE OPERATOR ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;
9154 2B4A;LEFTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;
9155 2B4B;LEFTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;
9156 2B4C;RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;
9157 2B50;WHITE MEDIUM STAR;So;0;ON;;;;;N;;;;;
9158 2B51;BLACK SMALL STAR;So;0;ON;;;;;N;;;;;
9159 2B52;WHITE SMALL STAR;So;0;ON;;;;;N;;;;;
9160 2B53;BLACK RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;;
9161 2B54;WHITE RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;;
9162 2C00;GLAGOLITIC CAPITAL LETTER AZU;Lu;0;L;;;;;N;;;;2C30;
9163 2C01;GLAGOLITIC CAPITAL LETTER BUKY;Lu;0;L;;;;;N;;;;2C31;
9164 2C02;GLAGOLITIC CAPITAL LETTER VEDE;Lu;0;L;;;;;N;;;;2C32;
9165 2C03;GLAGOLITIC CAPITAL LETTER GLAGOLI;Lu;0;L;;;;;N;;;;2C33;
9166 2C04;GLAGOLITIC CAPITAL LETTER DOBRO;Lu;0;L;;;;;N;;;;2C34;
9167 2C05;GLAGOLITIC CAPITAL LETTER YESTU;Lu;0;L;;;;;N;;;;2C35;
9168 2C06;GLAGOLITIC CAPITAL LETTER ZHIVETE;Lu;0;L;;;;;N;;;;2C36;
9169 2C07;GLAGOLITIC CAPITAL LETTER DZELO;Lu;0;L;;;;;N;;;;2C37;
9170 2C08;GLAGOLITIC CAPITAL LETTER ZEMLJA;Lu;0;L;;;;;N;;;;2C38;
9171 2C09;GLAGOLITIC CAPITAL LETTER IZHE;Lu;0;L;;;;;N;;;;2C39;
9172 2C0A;GLAGOLITIC CAPITAL LETTER INITIAL IZHE;Lu;0;L;;;;;N;;;;2C3A;
9173 2C0B;GLAGOLITIC CAPITAL LETTER I;Lu;0;L;;;;;N;;;;2C3B;
9174 2C0C;GLAGOLITIC CAPITAL LETTER DJERVI;Lu;0;L;;;;;N;;;;2C3C;
9175 2C0D;GLAGOLITIC CAPITAL LETTER KAKO;Lu;0;L;;;;;N;;;;2C3D;
9176 2C0E;GLAGOLITIC CAPITAL LETTER LJUDIJE;Lu;0;L;;;;;N;;;;2C3E;
9177 2C0F;GLAGOLITIC CAPITAL LETTER MYSLITE;Lu;0;L;;;;;N;;;;2C3F;
9178 2C10;GLAGOLITIC CAPITAL LETTER NASHI;Lu;0;L;;;;;N;;;;2C40;
9179 2C11;GLAGOLITIC CAPITAL LETTER ONU;Lu;0;L;;;;;N;;;;2C41;
9180 2C12;GLAGOLITIC CAPITAL LETTER POKOJI;Lu;0;L;;;;;N;;;;2C42;
9181 2C13;GLAGOLITIC CAPITAL LETTER RITSI;Lu;0;L;;;;;N;;;;2C43;
9182 2C14;GLAGOLITIC CAPITAL LETTER SLOVO;Lu;0;L;;;;;N;;;;2C44;
9183 2C15;GLAGOLITIC CAPITAL LETTER TVRIDO;Lu;0;L;;;;;N;;;;2C45;
9184 2C16;GLAGOLITIC CAPITAL LETTER UKU;Lu;0;L;;;;;N;;;;2C46;
9185 2C17;GLAGOLITIC CAPITAL LETTER FRITU;Lu;0;L;;;;;N;;;;2C47;
9186 2C18;GLAGOLITIC CAPITAL LETTER HERU;Lu;0;L;;;;;N;;;;2C48;
9187 2C19;GLAGOLITIC CAPITAL LETTER OTU;Lu;0;L;;;;;N;;;;2C49;
9188 2C1A;GLAGOLITIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;2C4A;
9189 2C1B;GLAGOLITIC CAPITAL LETTER SHTA;Lu;0;L;;;;;N;;;;2C4B;
9190 2C1C;GLAGOLITIC CAPITAL LETTER TSI;Lu;0;L;;;;;N;;;;2C4C;
9191 2C1D;GLAGOLITIC CAPITAL LETTER CHRIVI;Lu;0;L;;;;;N;;;;2C4D;
9192 2C1E;GLAGOLITIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;2C4E;
9193 2C1F;GLAGOLITIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;;;;2C4F;
9194 2C20;GLAGOLITIC CAPITAL LETTER YERI;Lu;0;L;;;;;N;;;;2C50;
9195 2C21;GLAGOLITIC CAPITAL LETTER YATI;Lu;0;L;;;;;N;;;;2C51;
9196 2C22;GLAGOLITIC CAPITAL LETTER SPIDERY HA;Lu;0;L;;;;;N;;;;2C52;
9197 2C23;GLAGOLITIC CAPITAL LETTER YU;Lu;0;L;;;;;N;;;;2C53;
9198 2C24;GLAGOLITIC CAPITAL LETTER SMALL YUS;Lu;0;L;;;;;N;;;;2C54;
9199 2C25;GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL;Lu;0;L;;;;;N;;;;2C55;
9200 2C26;GLAGOLITIC CAPITAL LETTER YO;Lu;0;L;;;;;N;;;;2C56;
9201 2C27;GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS;Lu;0;L;;;;;N;;;;2C57;
9202 2C28;GLAGOLITIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;2C58;
9203 2C29;GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS;Lu;0;L;;;;;N;;;;2C59;
9204 2C2A;GLAGOLITIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;2C5A;
9205 2C2B;GLAGOLITIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;2C5B;
9206 2C2C;GLAGOLITIC CAPITAL LETTER SHTAPIC;Lu;0;L;;;;;N;;;;2C5C;
9207 2C2D;GLAGOLITIC CAPITAL LETTER TROKUTASTI A;Lu;0;L;;;;;N;;;;2C5D;
9208 2C2E;GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE;Lu;0;L;;;;;N;;;;2C5E;
9209 2C30;GLAGOLITIC SMALL LETTER AZU;Ll;0;L;;;;;N;;;2C00;;2C00
9210 2C31;GLAGOLITIC SMALL LETTER BUKY;Ll;0;L;;;;;N;;;2C01;;2C01
9211 2C32;GLAGOLITIC SMALL LETTER VEDE;Ll;0;L;;;;;N;;;2C02;;2C02
9212 2C33;GLAGOLITIC SMALL LETTER GLAGOLI;Ll;0;L;;;;;N;;;2C03;;2C03
9213 2C34;GLAGOLITIC SMALL LETTER DOBRO;Ll;0;L;;;;;N;;;2C04;;2C04
9214 2C35;GLAGOLITIC SMALL LETTER YESTU;Ll;0;L;;;;;N;;;2C05;;2C05
9215 2C36;GLAGOLITIC SMALL LETTER ZHIVETE;Ll;0;L;;;;;N;;;2C06;;2C06
9216 2C37;GLAGOLITIC SMALL LETTER DZELO;Ll;0;L;;;;;N;;;2C07;;2C07
9217 2C38;GLAGOLITIC SMALL LETTER ZEMLJA;Ll;0;L;;;;;N;;;2C08;;2C08
9218 2C39;GLAGOLITIC SMALL LETTER IZHE;Ll;0;L;;;;;N;;;2C09;;2C09
9219 2C3A;GLAGOLITIC SMALL LETTER INITIAL IZHE;Ll;0;L;;;;;N;;;2C0A;;2C0A
9220 2C3B;GLAGOLITIC SMALL LETTER I;Ll;0;L;;;;;N;;;2C0B;;2C0B
9221 2C3C;GLAGOLITIC SMALL LETTER DJERVI;Ll;0;L;;;;;N;;;2C0C;;2C0C
9222 2C3D;GLAGOLITIC SMALL LETTER KAKO;Ll;0;L;;;;;N;;;2C0D;;2C0D
9223 2C3E;GLAGOLITIC SMALL LETTER LJUDIJE;Ll;0;L;;;;;N;;;2C0E;;2C0E
9224 2C3F;GLAGOLITIC SMALL LETTER MYSLITE;Ll;0;L;;;;;N;;;2C0F;;2C0F
9225 2C40;GLAGOLITIC SMALL LETTER NASHI;Ll;0;L;;;;;N;;;2C10;;2C10
9226 2C41;GLAGOLITIC SMALL LETTER ONU;Ll;0;L;;;;;N;;;2C11;;2C11
9227 2C42;GLAGOLITIC SMALL LETTER POKOJI;Ll;0;L;;;;;N;;;2C12;;2C12
9228 2C43;GLAGOLITIC SMALL LETTER RITSI;Ll;0;L;;;;;N;;;2C13;;2C13
9229 2C44;GLAGOLITIC SMALL LETTER SLOVO;Ll;0;L;;;;;N;;;2C14;;2C14
9230 2C45;GLAGOLITIC SMALL LETTER TVRIDO;Ll;0;L;;;;;N;;;2C15;;2C15
9231 2C46;GLAGOLITIC SMALL LETTER UKU;Ll;0;L;;;;;N;;;2C16;;2C16
9232 2C47;GLAGOLITIC SMALL LETTER FRITU;Ll;0;L;;;;;N;;;2C17;;2C17
9233 2C48;GLAGOLITIC SMALL LETTER HERU;Ll;0;L;;;;;N;;;2C18;;2C18
9234 2C49;GLAGOLITIC SMALL LETTER OTU;Ll;0;L;;;;;N;;;2C19;;2C19
9235 2C4A;GLAGOLITIC SMALL LETTER PE;Ll;0;L;;;;;N;;;2C1A;;2C1A
9236 2C4B;GLAGOLITIC SMALL LETTER SHTA;Ll;0;L;;;;;N;;;2C1B;;2C1B
9237 2C4C;GLAGOLITIC SMALL LETTER TSI;Ll;0;L;;;;;N;;;2C1C;;2C1C
9238 2C4D;GLAGOLITIC SMALL LETTER CHRIVI;Ll;0;L;;;;;N;;;2C1D;;2C1D
9239 2C4E;GLAGOLITIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;2C1E;;2C1E
9240 2C4F;GLAGOLITIC SMALL LETTER YERU;Ll;0;L;;;;;N;;;2C1F;;2C1F
9241 2C50;GLAGOLITIC SMALL LETTER YERI;Ll;0;L;;;;;N;;;2C20;;2C20
9242 2C51;GLAGOLITIC SMALL LETTER YATI;Ll;0;L;;;;;N;;;2C21;;2C21
9243 2C52;GLAGOLITIC SMALL LETTER SPIDERY HA;Ll;0;L;;;;;N;;;2C22;;2C22
9244 2C53;GLAGOLITIC SMALL LETTER YU;Ll;0;L;;;;;N;;;2C23;;2C23
9245 2C54;GLAGOLITIC SMALL LETTER SMALL YUS;Ll;0;L;;;;;N;;;2C24;;2C24
9246 2C55;GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL;Ll;0;L;;;;;N;;;2C25;;2C25
9247 2C56;GLAGOLITIC SMALL LETTER YO;Ll;0;L;;;;;N;;;2C26;;2C26
9248 2C57;GLAGOLITIC SMALL LETTER IOTATED SMALL YUS;Ll;0;L;;;;;N;;;2C27;;2C27
9249 2C58;GLAGOLITIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;2C28;;2C28
9250 2C59;GLAGOLITIC SMALL LETTER IOTATED BIG YUS;Ll;0;L;;;;;N;;;2C29;;2C29
9251 2C5A;GLAGOLITIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;2C2A;;2C2A
9252 2C5B;GLAGOLITIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;2C2B;;2C2B
9253 2C5C;GLAGOLITIC SMALL LETTER SHTAPIC;Ll;0;L;;;;;N;;;2C2C;;2C2C
9254 2C5D;GLAGOLITIC SMALL LETTER TROKUTASTI A;Ll;0;L;;;;;N;;;2C2D;;2C2D
9255 2C5E;GLAGOLITIC SMALL LETTER LATINATE MYSLITE;Ll;0;L;;;;;N;;;2C2E;;2C2E
9256 2C60;LATIN CAPITAL LETTER L WITH DOUBLE BAR;Lu;0;L;;;;;N;;;;2C61;
9257 2C61;LATIN SMALL LETTER L WITH DOUBLE BAR;Ll;0;L;;;;;N;;;2C60;;2C60
9258 2C62;LATIN CAPITAL LETTER L WITH MIDDLE TILDE;Lu;0;L;;;;;N;;;;026B;
9259 2C63;LATIN CAPITAL LETTER P WITH STROKE;Lu;0;L;;;;;N;;;;1D7D;
9260 2C64;LATIN CAPITAL LETTER R WITH TAIL;Lu;0;L;;;;;N;;;;027D;
9261 2C65;LATIN SMALL LETTER A WITH STROKE;Ll;0;L;;;;;N;;;023A;;023A
9262 2C66;LATIN SMALL LETTER T WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;023E;;023E
9263 2C67;LATIN CAPITAL LETTER H WITH DESCENDER;Lu;0;L;;;;;N;;;;2C68;
9264 2C68;LATIN SMALL LETTER H WITH DESCENDER;Ll;0;L;;;;;N;;;2C67;;2C67
9265 2C69;LATIN CAPITAL LETTER K WITH DESCENDER;Lu;0;L;;;;;N;;;;2C6A;
9266 2C6A;LATIN SMALL LETTER K WITH DESCENDER;Ll;0;L;;;;;N;;;2C69;;2C69
9267 2C6B;LATIN CAPITAL LETTER Z WITH DESCENDER;Lu;0;L;;;;;N;;;;2C6C;
9268 2C6C;LATIN SMALL LETTER Z WITH DESCENDER;Ll;0;L;;;;;N;;;2C6B;;2C6B
9269 2C6D;LATIN CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;0251;
9270 2C6E;LATIN CAPITAL LETTER M WITH HOOK;Lu;0;L;;;;;N;;;;0271;
9271 2C6F;LATIN CAPITAL LETTER TURNED A;Lu;0;L;;;;;N;;;;0250;
9272 2C71;LATIN SMALL LETTER V WITH RIGHT HOOK;Ll;0;L;;;;;N;;;;;
9273 2C72;LATIN CAPITAL LETTER W WITH HOOK;Lu;0;L;;;;;N;;;;2C73;
9274 2C73;LATIN SMALL LETTER W WITH HOOK;Ll;0;L;;;;;N;;;2C72;;2C72
9275 2C74;LATIN SMALL LETTER V WITH CURL;Ll;0;L;;;;;N;;;;;
9276 2C75;LATIN CAPITAL LETTER HALF H;Lu;0;L;;;;;N;;;;2C76;
9277 2C76;LATIN SMALL LETTER HALF H;Ll;0;L;;;;;N;;;2C75;;2C75
9278 2C77;LATIN SMALL LETTER TAILLESS PHI;Ll;0;L;;;;;N;;;;;
9279 2C78;LATIN SMALL LETTER E WITH NOTCH;Ll;0;L;;;;;N;;;;;
9280 2C79;LATIN SMALL LETTER TURNED R WITH TAIL;Ll;0;L;;;;;N;;;;;
9281 2C7A;LATIN SMALL LETTER O WITH LOW RING INSIDE;Ll;0;L;;;;;N;;;;;
9282 2C7B;LATIN LETTER SMALL CAPITAL TURNED E;Ll;0;L;;;;;N;;;;;
9283 2C7C;LATIN SUBSCRIPT SMALL LETTER J;Ll;0;L;<sub> 006A;;;;N;;;;;
9284 2C7D;MODIFIER LETTER CAPITAL V;Lm;0;L;<super> 0056;;;;N;;;;;
9285 2C80;COPTIC CAPITAL LETTER ALFA;Lu;0;L;;;;;N;;;;2C81;
9286 2C81;COPTIC SMALL LETTER ALFA;Ll;0;L;;;;;N;;;2C80;;2C80
9287 2C82;COPTIC CAPITAL LETTER VIDA;Lu;0;L;;;;;N;;;;2C83;
9288 2C83;COPTIC SMALL LETTER VIDA;Ll;0;L;;;;;N;;;2C82;;2C82
9289 2C84;COPTIC CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;2C85;
9290 2C85;COPTIC SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;2C84;;2C84
9291 2C86;COPTIC CAPITAL LETTER DALDA;Lu;0;L;;;;;N;;;;2C87;
9292 2C87;COPTIC SMALL LETTER DALDA;Ll;0;L;;;;;N;;;2C86;;2C86
9293 2C88;COPTIC CAPITAL LETTER EIE;Lu;0;L;;;;;N;;;;2C89;
9294 2C89;COPTIC SMALL LETTER EIE;Ll;0;L;;;;;N;;;2C88;;2C88
9295 2C8A;COPTIC CAPITAL LETTER SOU;Lu;0;L;;;;;N;;;;2C8B;
9296 2C8B;COPTIC SMALL LETTER SOU;Ll;0;L;;;;;N;;;2C8A;;2C8A
9297 2C8C;COPTIC CAPITAL LETTER ZATA;Lu;0;L;;;;;N;;;;2C8D;
9298 2C8D;COPTIC SMALL LETTER ZATA;Ll;0;L;;;;;N;;;2C8C;;2C8C
9299 2C8E;COPTIC CAPITAL LETTER HATE;Lu;0;L;;;;;N;;;;2C8F;
9300 2C8F;COPTIC SMALL LETTER HATE;Ll;0;L;;;;;N;;;2C8E;;2C8E
9301 2C90;COPTIC CAPITAL LETTER THETHE;Lu;0;L;;;;;N;;;;2C91;
9302 2C91;COPTIC SMALL LETTER THETHE;Ll;0;L;;;;;N;;;2C90;;2C90
9303 2C92;COPTIC CAPITAL LETTER IAUDA;Lu;0;L;;;;;N;;;;2C93;
9304 2C93;COPTIC SMALL LETTER IAUDA;Ll;0;L;;;;;N;;;2C92;;2C92
9305 2C94;COPTIC CAPITAL LETTER KAPA;Lu;0;L;;;;;N;;;;2C95;
9306 2C95;COPTIC SMALL LETTER KAPA;Ll;0;L;;;;;N;;;2C94;;2C94
9307 2C96;COPTIC CAPITAL LETTER LAULA;Lu;0;L;;;;;N;;;;2C97;
9308 2C97;COPTIC SMALL LETTER LAULA;Ll;0;L;;;;;N;;;2C96;;2C96
9309 2C98;COPTIC CAPITAL LETTER MI;Lu;0;L;;;;;N;;;;2C99;
9310 2C99;COPTIC SMALL LETTER MI;Ll;0;L;;;;;N;;;2C98;;2C98
9311 2C9A;COPTIC CAPITAL LETTER NI;Lu;0;L;;;;;N;;;;2C9B;
9312 2C9B;COPTIC SMALL LETTER NI;Ll;0;L;;;;;N;;;2C9A;;2C9A
9313 2C9C;COPTIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;2C9D;
9314 2C9D;COPTIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;2C9C;;2C9C
9315 2C9E;COPTIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;2C9F;
9316 2C9F;COPTIC SMALL LETTER O;Ll;0;L;;;;;N;;;2C9E;;2C9E
9317 2CA0;COPTIC CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;2CA1;
9318 2CA1;COPTIC SMALL LETTER PI;Ll;0;L;;;;;N;;;2CA0;;2CA0
9319 2CA2;COPTIC CAPITAL LETTER RO;Lu;0;L;;;;;N;;;;2CA3;
9320 2CA3;COPTIC SMALL LETTER RO;Ll;0;L;;;;;N;;;2CA2;;2CA2
9321 2CA4;COPTIC CAPITAL LETTER SIMA;Lu;0;L;;;;;N;;;;2CA5;
9322 2CA5;COPTIC SMALL LETTER SIMA;Ll;0;L;;;;;N;;;2CA4;;2CA4
9323 2CA6;COPTIC CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;2CA7;
9324 2CA7;COPTIC SMALL LETTER TAU;Ll;0;L;;;;;N;;;2CA6;;2CA6
9325 2CA8;COPTIC CAPITAL LETTER UA;Lu;0;L;;;;;N;;;;2CA9;
9326 2CA9;COPTIC SMALL LETTER UA;Ll;0;L;;;;;N;;;2CA8;;2CA8
9327 2CAA;COPTIC CAPITAL LETTER FI;Lu;0;L;;;;;N;;;;2CAB;
9328 2CAB;COPTIC SMALL LETTER FI;Ll;0;L;;;;;N;;;2CAA;;2CAA
9329 2CAC;COPTIC CAPITAL LETTER KHI;Lu;0;L;;;;;N;;;;2CAD;
9330 2CAD;COPTIC SMALL LETTER KHI;Ll;0;L;;;;;N;;;2CAC;;2CAC
9331 2CAE;COPTIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;2CAF;
9332 2CAF;COPTIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;2CAE;;2CAE
9333 2CB0;COPTIC CAPITAL LETTER OOU;Lu;0;L;;;;;N;;;;2CB1;
9334 2CB1;COPTIC SMALL LETTER OOU;Ll;0;L;;;;;N;;;2CB0;;2CB0
9335 2CB2;COPTIC CAPITAL LETTER DIALECT-P ALEF;Lu;0;L;;;;;N;;;;2CB3;
9336 2CB3;COPTIC SMALL LETTER DIALECT-P ALEF;Ll;0;L;;;;;N;;;2CB2;;2CB2
9337 2CB4;COPTIC CAPITAL LETTER OLD COPTIC AIN;Lu;0;L;;;;;N;;;;2CB5;
9338 2CB5;COPTIC SMALL LETTER OLD COPTIC AIN;Ll;0;L;;;;;N;;;2CB4;;2CB4
9339 2CB6;COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE;Lu;0;L;;;;;N;;;;2CB7;
9340 2CB7;COPTIC SMALL LETTER CRYPTOGRAMMIC EIE;Ll;0;L;;;;;N;;;2CB6;;2CB6
9341 2CB8;COPTIC CAPITAL LETTER DIALECT-P KAPA;Lu;0;L;;;;;N;;;;2CB9;
9342 2CB9;COPTIC SMALL LETTER DIALECT-P KAPA;Ll;0;L;;;;;N;;;2CB8;;2CB8
9343 2CBA;COPTIC CAPITAL LETTER DIALECT-P NI;Lu;0;L;;;;;N;;;;2CBB;
9344 2CBB;COPTIC SMALL LETTER DIALECT-P NI;Ll;0;L;;;;;N;;;2CBA;;2CBA
9345 2CBC;COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI;Lu;0;L;;;;;N;;;;2CBD;
9346 2CBD;COPTIC SMALL LETTER CRYPTOGRAMMIC NI;Ll;0;L;;;;;N;;;2CBC;;2CBC
9347 2CBE;COPTIC CAPITAL LETTER OLD COPTIC OOU;Lu;0;L;;;;;N;;;;2CBF;
9348 2CBF;COPTIC SMALL LETTER OLD COPTIC OOU;Ll;0;L;;;;;N;;;2CBE;;2CBE
9349 2CC0;COPTIC CAPITAL LETTER SAMPI;Lu;0;L;;;;;N;;;;2CC1;
9350 2CC1;COPTIC SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;2CC0;;2CC0
9351 2CC2;COPTIC CAPITAL LETTER CROSSED SHEI;Lu;0;L;;;;;N;;;;2CC3;
9352 2CC3;COPTIC SMALL LETTER CROSSED SHEI;Ll;0;L;;;;;N;;;2CC2;;2CC2
9353 2CC4;COPTIC CAPITAL LETTER OLD COPTIC SHEI;Lu;0;L;;;;;N;;;;2CC5;
9354 2CC5;COPTIC SMALL LETTER OLD COPTIC SHEI;Ll;0;L;;;;;N;;;2CC4;;2CC4
9355 2CC6;COPTIC CAPITAL LETTER OLD COPTIC ESH;Lu;0;L;;;;;N;;;;2CC7;
9356 2CC7;COPTIC SMALL LETTER OLD COPTIC ESH;Ll;0;L;;;;;N;;;2CC6;;2CC6
9357 2CC8;COPTIC CAPITAL LETTER AKHMIMIC KHEI;Lu;0;L;;;;;N;;;;2CC9;
9358 2CC9;COPTIC SMALL LETTER AKHMIMIC KHEI;Ll;0;L;;;;;N;;;2CC8;;2CC8
9359 2CCA;COPTIC CAPITAL LETTER DIALECT-P HORI;Lu;0;L;;;;;N;;;;2CCB;
9360 2CCB;COPTIC SMALL LETTER DIALECT-P HORI;Ll;0;L;;;;;N;;;2CCA;;2CCA
9361 2CCC;COPTIC CAPITAL LETTER OLD COPTIC HORI;Lu;0;L;;;;;N;;;;2CCD;
9362 2CCD;COPTIC SMALL LETTER OLD COPTIC HORI;Ll;0;L;;;;;N;;;2CCC;;2CCC
9363 2CCE;COPTIC CAPITAL LETTER OLD COPTIC HA;Lu;0;L;;;;;N;;;;2CCF;
9364 2CCF;COPTIC SMALL LETTER OLD COPTIC HA;Ll;0;L;;;;;N;;;2CCE;;2CCE
9365 2CD0;COPTIC CAPITAL LETTER L-SHAPED HA;Lu;0;L;;;;;N;;;;2CD1;
9366 2CD1;COPTIC SMALL LETTER L-SHAPED HA;Ll;0;L;;;;;N;;;2CD0;;2CD0
9367 2CD2;COPTIC CAPITAL LETTER OLD COPTIC HEI;Lu;0;L;;;;;N;;;;2CD3;
9368 2CD3;COPTIC SMALL LETTER OLD COPTIC HEI;Ll;0;L;;;;;N;;;2CD2;;2CD2
9369 2CD4;COPTIC CAPITAL LETTER OLD COPTIC HAT;Lu;0;L;;;;;N;;;;2CD5;
9370 2CD5;COPTIC SMALL LETTER OLD COPTIC HAT;Ll;0;L;;;;;N;;;2CD4;;2CD4
9371 2CD6;COPTIC CAPITAL LETTER OLD COPTIC GANGIA;Lu;0;L;;;;;N;;;;2CD7;
9372 2CD7;COPTIC SMALL LETTER OLD COPTIC GANGIA;Ll;0;L;;;;;N;;;2CD6;;2CD6
9373 2CD8;COPTIC CAPITAL LETTER OLD COPTIC DJA;Lu;0;L;;;;;N;;;;2CD9;
9374 2CD9;COPTIC SMALL LETTER OLD COPTIC DJA;Ll;0;L;;;;;N;;;2CD8;;2CD8
9375 2CDA;COPTIC CAPITAL LETTER OLD COPTIC SHIMA;Lu;0;L;;;;;N;;;;2CDB;
9376 2CDB;COPTIC SMALL LETTER OLD COPTIC SHIMA;Ll;0;L;;;;;N;;;2CDA;;2CDA
9377 2CDC;COPTIC CAPITAL LETTER OLD NUBIAN SHIMA;Lu;0;L;;;;;N;;;;2CDD;
9378 2CDD;COPTIC SMALL LETTER OLD NUBIAN SHIMA;Ll;0;L;;;;;N;;;2CDC;;2CDC
9379 2CDE;COPTIC CAPITAL LETTER OLD NUBIAN NGI;Lu;0;L;;;;;N;;;;2CDF;
9380 2CDF;COPTIC SMALL LETTER OLD NUBIAN NGI;Ll;0;L;;;;;N;;;2CDE;;2CDE
9381 2CE0;COPTIC CAPITAL LETTER OLD NUBIAN NYI;Lu;0;L;;;;;N;;;;2CE1;
9382 2CE1;COPTIC SMALL LETTER OLD NUBIAN NYI;Ll;0;L;;;;;N;;;2CE0;;2CE0
9383 2CE2;COPTIC CAPITAL LETTER OLD NUBIAN WAU;Lu;0;L;;;;;N;;;;2CE3;
9384 2CE3;COPTIC SMALL LETTER OLD NUBIAN WAU;Ll;0;L;;;;;N;;;2CE2;;2CE2
9385 2CE4;COPTIC SYMBOL KAI;Ll;0;L;;;;;N;;;;;
9386 2CE5;COPTIC SYMBOL MI RO;So;0;ON;;;;;N;;;;;
9387 2CE6;COPTIC SYMBOL PI RO;So;0;ON;;;;;N;;;;;
9388 2CE7;COPTIC SYMBOL STAUROS;So;0;ON;;;;;N;;;;;
9389 2CE8;COPTIC SYMBOL TAU RO;So;0;ON;;;;;N;;;;;
9390 2CE9;COPTIC SYMBOL KHI RO;So;0;ON;;;;;N;;;;;
9391 2CEA;COPTIC SYMBOL SHIMA SIMA;So;0;ON;;;;;N;;;;;
9392 2CF9;COPTIC OLD NUBIAN FULL STOP;Po;0;ON;;;;;N;;;;;
9393 2CFA;COPTIC OLD NUBIAN DIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;;
9394 2CFB;COPTIC OLD NUBIAN INDIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;;
9395 2CFC;COPTIC OLD NUBIAN VERSE DIVIDER;Po;0;ON;;;;;N;;;;;
9396 2CFD;COPTIC FRACTION ONE HALF;No;0;ON;;;;1/2;N;;;;;
9397 2CFE;COPTIC FULL STOP;Po;0;ON;;;;;N;;;;;
9398 2CFF;COPTIC MORPHOLOGICAL DIVIDER;Po;0;ON;;;;;N;;;;;
9399 2D00;GEORGIAN SMALL LETTER AN;Ll;0;L;;;;;N;;Khutsuri;10A0;;10A0
9400 2D01;GEORGIAN SMALL LETTER BAN;Ll;0;L;;;;;N;;Khutsuri;10A1;;10A1
9401 2D02;GEORGIAN SMALL LETTER GAN;Ll;0;L;;;;;N;;Khutsuri;10A2;;10A2
9402 2D03;GEORGIAN SMALL LETTER DON;Ll;0;L;;;;;N;;Khutsuri;10A3;;10A3
9403 2D04;GEORGIAN SMALL LETTER EN;Ll;0;L;;;;;N;;Khutsuri;10A4;;10A4
9404 2D05;GEORGIAN SMALL LETTER VIN;Ll;0;L;;;;;N;;Khutsuri;10A5;;10A5
9405 2D06;GEORGIAN SMALL LETTER ZEN;Ll;0;L;;;;;N;;Khutsuri;10A6;;10A6
9406 2D07;GEORGIAN SMALL LETTER TAN;Ll;0;L;;;;;N;;Khutsuri;10A7;;10A7
9407 2D08;GEORGIAN SMALL LETTER IN;Ll;0;L;;;;;N;;Khutsuri;10A8;;10A8
9408 2D09;GEORGIAN SMALL LETTER KAN;Ll;0;L;;;;;N;;Khutsuri;10A9;;10A9
9409 2D0A;GEORGIAN SMALL LETTER LAS;Ll;0;L;;;;;N;;Khutsuri;10AA;;10AA
9410 2D0B;GEORGIAN SMALL LETTER MAN;Ll;0;L;;;;;N;;Khutsuri;10AB;;10AB
9411 2D0C;GEORGIAN SMALL LETTER NAR;Ll;0;L;;;;;N;;Khutsuri;10AC;;10AC
9412 2D0D;GEORGIAN SMALL LETTER ON;Ll;0;L;;;;;N;;Khutsuri;10AD;;10AD
9413 2D0E;GEORGIAN SMALL LETTER PAR;Ll;0;L;;;;;N;;Khutsuri;10AE;;10AE
9414 2D0F;GEORGIAN SMALL LETTER ZHAR;Ll;0;L;;;;;N;;Khutsuri;10AF;;10AF
9415 2D10;GEORGIAN SMALL LETTER RAE;Ll;0;L;;;;;N;;Khutsuri;10B0;;10B0
9416 2D11;GEORGIAN SMALL LETTER SAN;Ll;0;L;;;;;N;;Khutsuri;10B1;;10B1
9417 2D12;GEORGIAN SMALL LETTER TAR;Ll;0;L;;;;;N;;Khutsuri;10B2;;10B2
9418 2D13;GEORGIAN SMALL LETTER UN;Ll;0;L;;;;;N;;Khutsuri;10B3;;10B3
9419 2D14;GEORGIAN SMALL LETTER PHAR;Ll;0;L;;;;;N;;Khutsuri;10B4;;10B4
9420 2D15;GEORGIAN SMALL LETTER KHAR;Ll;0;L;;;;;N;;Khutsuri;10B5;;10B5
9421 2D16;GEORGIAN SMALL LETTER GHAN;Ll;0;L;;;;;N;;Khutsuri;10B6;;10B6
9422 2D17;GEORGIAN SMALL LETTER QAR;Ll;0;L;;;;;N;;Khutsuri;10B7;;10B7
9423 2D18;GEORGIAN SMALL LETTER SHIN;Ll;0;L;;;;;N;;Khutsuri;10B8;;10B8
9424 2D19;GEORGIAN SMALL LETTER CHIN;Ll;0;L;;;;;N;;Khutsuri;10B9;;10B9
9425 2D1A;GEORGIAN SMALL LETTER CAN;Ll;0;L;;;;;N;;Khutsuri;10BA;;10BA
9426 2D1B;GEORGIAN SMALL LETTER JIL;Ll;0;L;;;;;N;;Khutsuri;10BB;;10BB
9427 2D1C;GEORGIAN SMALL LETTER CIL;Ll;0;L;;;;;N;;Khutsuri;10BC;;10BC
9428 2D1D;GEORGIAN SMALL LETTER CHAR;Ll;0;L;;;;;N;;Khutsuri;10BD;;10BD
9429 2D1E;GEORGIAN SMALL LETTER XAN;Ll;0;L;;;;;N;;Khutsuri;10BE;;10BE
9430 2D1F;GEORGIAN SMALL LETTER JHAN;Ll;0;L;;;;;N;;Khutsuri;10BF;;10BF
9431 2D20;GEORGIAN SMALL LETTER HAE;Ll;0;L;;;;;N;;Khutsuri;10C0;;10C0
9432 2D21;GEORGIAN SMALL LETTER HE;Ll;0;L;;;;;N;;Khutsuri;10C1;;10C1
9433 2D22;GEORGIAN SMALL LETTER HIE;Ll;0;L;;;;;N;;Khutsuri;10C2;;10C2
9434 2D23;GEORGIAN SMALL LETTER WE;Ll;0;L;;;;;N;;Khutsuri;10C3;;10C3
9435 2D24;GEORGIAN SMALL LETTER HAR;Ll;0;L;;;;;N;;Khutsuri;10C4;;10C4
9436 2D25;GEORGIAN SMALL LETTER HOE;Ll;0;L;;;;;N;;Khutsuri;10C5;;10C5
9437 2D30;TIFINAGH LETTER YA;Lo;0;L;;;;;N;;;;;
9438 2D31;TIFINAGH LETTER YAB;Lo;0;L;;;;;N;;;;;
9439 2D32;TIFINAGH LETTER YABH;Lo;0;L;;;;;N;;;;;
9440 2D33;TIFINAGH LETTER YAG;Lo;0;L;;;;;N;;;;;
9441 2D34;TIFINAGH LETTER YAGHH;Lo;0;L;;;;;N;;;;;
9442 2D35;TIFINAGH LETTER BERBER ACADEMY YAJ;Lo;0;L;;;;;N;;;;;
9443 2D36;TIFINAGH LETTER YAJ;Lo;0;L;;;;;N;;;;;
9444 2D37;TIFINAGH LETTER YAD;Lo;0;L;;;;;N;;;;;
9445 2D38;TIFINAGH LETTER YADH;Lo;0;L;;;;;N;;;;;
9446 2D39;TIFINAGH LETTER YADD;Lo;0;L;;;;;N;;;;;
9447 2D3A;TIFINAGH LETTER YADDH;Lo;0;L;;;;;N;;;;;
9448 2D3B;TIFINAGH LETTER YEY;Lo;0;L;;;;;N;;;;;
9449 2D3C;TIFINAGH LETTER YAF;Lo;0;L;;;;;N;;;;;
9450 2D3D;TIFINAGH LETTER YAK;Lo;0;L;;;;;N;;;;;
9451 2D3E;TIFINAGH LETTER TUAREG YAK;Lo;0;L;;;;;N;;;;;
9452 2D3F;TIFINAGH LETTER YAKHH;Lo;0;L;;;;;N;;;;;
9453 2D40;TIFINAGH LETTER YAH;Lo;0;L;;;;;N;;Tuareg yab;;;
9454 2D41;TIFINAGH LETTER BERBER ACADEMY YAH;Lo;0;L;;;;;N;;;;;
9455 2D42;TIFINAGH LETTER TUAREG YAH;Lo;0;L;;;;;N;;;;;
9456 2D43;TIFINAGH LETTER YAHH;Lo;0;L;;;;;N;;;;;
9457 2D44;TIFINAGH LETTER YAA;Lo;0;L;;;;;N;;;;;
9458 2D45;TIFINAGH LETTER YAKH;Lo;0;L;;;;;N;;;;;
9459 2D46;TIFINAGH LETTER TUAREG YAKH;Lo;0;L;;;;;N;;;;;
9460 2D47;TIFINAGH LETTER YAQ;Lo;0;L;;;;;N;;;;;
9461 2D48;TIFINAGH LETTER TUAREG YAQ;Lo;0;L;;;;;N;;;;;
9462 2D49;TIFINAGH LETTER YI;Lo;0;L;;;;;N;;;;;
9463 2D4A;TIFINAGH LETTER YAZH;Lo;0;L;;;;;N;;;;;
9464 2D4B;TIFINAGH LETTER AHAGGAR YAZH;Lo;0;L;;;;;N;;;;;
9465 2D4C;TIFINAGH LETTER TUAREG YAZH;Lo;0;L;;;;;N;;;;;
9466 2D4D;TIFINAGH LETTER YAL;Lo;0;L;;;;;N;;;;;
9467 2D4E;TIFINAGH LETTER YAM;Lo;0;L;;;;;N;;;;;
9468 2D4F;TIFINAGH LETTER YAN;Lo;0;L;;;;;N;;;;;
9469 2D50;TIFINAGH LETTER TUAREG YAGN;Lo;0;L;;;;;N;;;;;
9470 2D51;TIFINAGH LETTER TUAREG YANG;Lo;0;L;;;;;N;;;;;
9471 2D52;TIFINAGH LETTER YAP;Lo;0;L;;;;;N;;;;;
9472 2D53;TIFINAGH LETTER YU;Lo;0;L;;;;;N;;Tuareg yaw;;;
9473 2D54;TIFINAGH LETTER YAR;Lo;0;L;;;;;N;;;;;
9474 2D55;TIFINAGH LETTER YARR;Lo;0;L;;;;;N;;;;;
9475 2D56;TIFINAGH LETTER YAGH;Lo;0;L;;;;;N;;;;;
9476 2D57;TIFINAGH LETTER TUAREG YAGH;Lo;0;L;;;;;N;;;;;
9477 2D58;TIFINAGH LETTER AYER YAGH;Lo;0;L;;;;;N;;Adrar yaj;;;
9478 2D59;TIFINAGH LETTER YAS;Lo;0;L;;;;;N;;;;;
9479 2D5A;TIFINAGH LETTER YASS;Lo;0;L;;;;;N;;;;;
9480 2D5B;TIFINAGH LETTER YASH;Lo;0;L;;;;;N;;;;;
9481 2D5C;TIFINAGH LETTER YAT;Lo;0;L;;;;;N;;;;;
9482 2D5D;TIFINAGH LETTER YATH;Lo;0;L;;;;;N;;;;;
9483 2D5E;TIFINAGH LETTER YACH;Lo;0;L;;;;;N;;;;;
9484 2D5F;TIFINAGH LETTER YATT;Lo;0;L;;;;;N;;;;;
9485 2D60;TIFINAGH LETTER YAV;Lo;0;L;;;;;N;;;;;
9486 2D61;TIFINAGH LETTER YAW;Lo;0;L;;;;;N;;;;;
9487 2D62;TIFINAGH LETTER YAY;Lo;0;L;;;;;N;;;;;
9488 2D63;TIFINAGH LETTER YAZ;Lo;0;L;;;;;N;;;;;
9489 2D64;TIFINAGH LETTER TAWELLEMET YAZ;Lo;0;L;;;;;N;;harpoon yaz;;;
9490 2D65;TIFINAGH LETTER YAZZ;Lo;0;L;;;;;N;;;;;
9491 2D6F;TIFINAGH MODIFIER LETTER LABIALIZATION MARK;Lm;0;L;<super> 2D61;;;;N;;tamatart;;;
9492 2D80;ETHIOPIC SYLLABLE LOA;Lo;0;L;;;;;N;;;;;
9493 2D81;ETHIOPIC SYLLABLE MOA;Lo;0;L;;;;;N;;;;;
9494 2D82;ETHIOPIC SYLLABLE ROA;Lo;0;L;;;;;N;;;;;
9495 2D83;ETHIOPIC SYLLABLE SOA;Lo;0;L;;;;;N;;;;;
9496 2D84;ETHIOPIC SYLLABLE SHOA;Lo;0;L;;;;;N;;;;;
9497 2D85;ETHIOPIC SYLLABLE BOA;Lo;0;L;;;;;N;;;;;
9498 2D86;ETHIOPIC SYLLABLE TOA;Lo;0;L;;;;;N;;;;;
9499 2D87;ETHIOPIC SYLLABLE COA;Lo;0;L;;;;;N;;;;;
9500 2D88;ETHIOPIC SYLLABLE NOA;Lo;0;L;;;;;N;;;;;
9501 2D89;ETHIOPIC SYLLABLE NYOA;Lo;0;L;;;;;N;;;;;
9502 2D8A;ETHIOPIC SYLLABLE GLOTTAL OA;Lo;0;L;;;;;N;;;;;
9503 2D8B;ETHIOPIC SYLLABLE ZOA;Lo;0;L;;;;;N;;;;;
9504 2D8C;ETHIOPIC SYLLABLE DOA;Lo;0;L;;;;;N;;;;;
9505 2D8D;ETHIOPIC SYLLABLE DDOA;Lo;0;L;;;;;N;;;;;
9506 2D8E;ETHIOPIC SYLLABLE JOA;Lo;0;L;;;;;N;;;;;
9507 2D8F;ETHIOPIC SYLLABLE THOA;Lo;0;L;;;;;N;;;;;
9508 2D90;ETHIOPIC SYLLABLE CHOA;Lo;0;L;;;;;N;;;;;
9509 2D91;ETHIOPIC SYLLABLE PHOA;Lo;0;L;;;;;N;;;;;
9510 2D92;ETHIOPIC SYLLABLE POA;Lo;0;L;;;;;N;;;;;
9511 2D93;ETHIOPIC SYLLABLE GGWA;Lo;0;L;;;;;N;;;;;
9512 2D94;ETHIOPIC SYLLABLE GGWI;Lo;0;L;;;;;N;;;;;
9513 2D95;ETHIOPIC SYLLABLE GGWEE;Lo;0;L;;;;;N;;;;;
9514 2D96;ETHIOPIC SYLLABLE GGWE;Lo;0;L;;;;;N;;;;;
9515 2DA0;ETHIOPIC SYLLABLE SSA;Lo;0;L;;;;;N;;;;;
9516 2DA1;ETHIOPIC SYLLABLE SSU;Lo;0;L;;;;;N;;;;;
9517 2DA2;ETHIOPIC SYLLABLE SSI;Lo;0;L;;;;;N;;;;;
9518 2DA3;ETHIOPIC SYLLABLE SSAA;Lo;0;L;;;;;N;;;;;
9519 2DA4;ETHIOPIC SYLLABLE SSEE;Lo;0;L;;;;;N;;;;;
9520 2DA5;ETHIOPIC SYLLABLE SSE;Lo;0;L;;;;;N;;;;;
9521 2DA6;ETHIOPIC SYLLABLE SSO;Lo;0;L;;;;;N;;;;;
9522 2DA8;ETHIOPIC SYLLABLE CCA;Lo;0;L;;;;;N;;;;;
9523 2DA9;ETHIOPIC SYLLABLE CCU;Lo;0;L;;;;;N;;;;;
9524 2DAA;ETHIOPIC SYLLABLE CCI;Lo;0;L;;;;;N;;;;;
9525 2DAB;ETHIOPIC SYLLABLE CCAA;Lo;0;L;;;;;N;;;;;
9526 2DAC;ETHIOPIC SYLLABLE CCEE;Lo;0;L;;;;;N;;;;;
9527 2DAD;ETHIOPIC SYLLABLE CCE;Lo;0;L;;;;;N;;;;;
9528 2DAE;ETHIOPIC SYLLABLE CCO;Lo;0;L;;;;;N;;;;;
9529 2DB0;ETHIOPIC SYLLABLE ZZA;Lo;0;L;;;;;N;;;;;
9530 2DB1;ETHIOPIC SYLLABLE ZZU;Lo;0;L;;;;;N;;;;;
9531 2DB2;ETHIOPIC SYLLABLE ZZI;Lo;0;L;;;;;N;;;;;
9532 2DB3;ETHIOPIC SYLLABLE ZZAA;Lo;0;L;;;;;N;;;;;
9533 2DB4;ETHIOPIC SYLLABLE ZZEE;Lo;0;L;;;;;N;;;;;
9534 2DB5;ETHIOPIC SYLLABLE ZZE;Lo;0;L;;;;;N;;;;;
9535 2DB6;ETHIOPIC SYLLABLE ZZO;Lo;0;L;;;;;N;;;;;
9536 2DB8;ETHIOPIC SYLLABLE CCHA;Lo;0;L;;;;;N;;;;;
9537 2DB9;ETHIOPIC SYLLABLE CCHU;Lo;0;L;;;;;N;;;;;
9538 2DBA;ETHIOPIC SYLLABLE CCHI;Lo;0;L;;;;;N;;;;;
9539 2DBB;ETHIOPIC SYLLABLE CCHAA;Lo;0;L;;;;;N;;;;;
9540 2DBC;ETHIOPIC SYLLABLE CCHEE;Lo;0;L;;;;;N;;;;;
9541 2DBD;ETHIOPIC SYLLABLE CCHE;Lo;0;L;;;;;N;;;;;
9542 2DBE;ETHIOPIC SYLLABLE CCHO;Lo;0;L;;;;;N;;;;;
9543 2DC0;ETHIOPIC SYLLABLE QYA;Lo;0;L;;;;;N;;;;;
9544 2DC1;ETHIOPIC SYLLABLE QYU;Lo;0;L;;;;;N;;;;;
9545 2DC2;ETHIOPIC SYLLABLE QYI;Lo;0;L;;;;;N;;;;;
9546 2DC3;ETHIOPIC SYLLABLE QYAA;Lo;0;L;;;;;N;;;;;
9547 2DC4;ETHIOPIC SYLLABLE QYEE;Lo;0;L;;;;;N;;;;;
9548 2DC5;ETHIOPIC SYLLABLE QYE;Lo;0;L;;;;;N;;;;;
9549 2DC6;ETHIOPIC SYLLABLE QYO;Lo;0;L;;;;;N;;;;;
9550 2DC8;ETHIOPIC SYLLABLE KYA;Lo;0;L;;;;;N;;;;;
9551 2DC9;ETHIOPIC SYLLABLE KYU;Lo;0;L;;;;;N;;;;;
9552 2DCA;ETHIOPIC SYLLABLE KYI;Lo;0;L;;;;;N;;;;;
9553 2DCB;ETHIOPIC SYLLABLE KYAA;Lo;0;L;;;;;N;;;;;
9554 2DCC;ETHIOPIC SYLLABLE KYEE;Lo;0;L;;;;;N;;;;;
9555 2DCD;ETHIOPIC SYLLABLE KYE;Lo;0;L;;;;;N;;;;;
9556 2DCE;ETHIOPIC SYLLABLE KYO;Lo;0;L;;;;;N;;;;;
9557 2DD0;ETHIOPIC SYLLABLE XYA;Lo;0;L;;;;;N;;;;;
9558 2DD1;ETHIOPIC SYLLABLE XYU;Lo;0;L;;;;;N;;;;;
9559 2DD2;ETHIOPIC SYLLABLE XYI;Lo;0;L;;;;;N;;;;;
9560 2DD3;ETHIOPIC SYLLABLE XYAA;Lo;0;L;;;;;N;;;;;
9561 2DD4;ETHIOPIC SYLLABLE XYEE;Lo;0;L;;;;;N;;;;;
9562 2DD5;ETHIOPIC SYLLABLE XYE;Lo;0;L;;;;;N;;;;;
9563 2DD6;ETHIOPIC SYLLABLE XYO;Lo;0;L;;;;;N;;;;;
9564 2DD8;ETHIOPIC SYLLABLE GYA;Lo;0;L;;;;;N;;;;;
9565 2DD9;ETHIOPIC SYLLABLE GYU;Lo;0;L;;;;;N;;;;;
9566 2DDA;ETHIOPIC SYLLABLE GYI;Lo;0;L;;;;;N;;;;;
9567 2DDB;ETHIOPIC SYLLABLE GYAA;Lo;0;L;;;;;N;;;;;
9568 2DDC;ETHIOPIC SYLLABLE GYEE;Lo;0;L;;;;;N;;;;;
9569 2DDD;ETHIOPIC SYLLABLE GYE;Lo;0;L;;;;;N;;;;;
9570 2DDE;ETHIOPIC SYLLABLE GYO;Lo;0;L;;;;;N;;;;;
9571 2DE0;COMBINING CYRILLIC LETTER BE;Mn;230;NSM;;;;;N;;;;;
9572 2DE1;COMBINING CYRILLIC LETTER VE;Mn;230;NSM;;;;;N;;;;;
9573 2DE2;COMBINING CYRILLIC LETTER GHE;Mn;230;NSM;;;;;N;;;;;
9574 2DE3;COMBINING CYRILLIC LETTER DE;Mn;230;NSM;;;;;N;;;;;
9575 2DE4;COMBINING CYRILLIC LETTER ZHE;Mn;230;NSM;;;;;N;;;;;
9576 2DE5;COMBINING CYRILLIC LETTER ZE;Mn;230;NSM;;;;;N;;;;;
9577 2DE6;COMBINING CYRILLIC LETTER KA;Mn;230;NSM;;;;;N;;;;;
9578 2DE7;COMBINING CYRILLIC LETTER EL;Mn;230;NSM;;;;;N;;;;;
9579 2DE8;COMBINING CYRILLIC LETTER EM;Mn;230;NSM;;;;;N;;;;;
9580 2DE9;COMBINING CYRILLIC LETTER EN;Mn;230;NSM;;;;;N;;;;;
9581 2DEA;COMBINING CYRILLIC LETTER O;Mn;230;NSM;;;;;N;;;;;
9582 2DEB;COMBINING CYRILLIC LETTER PE;Mn;230;NSM;;;;;N;;;;;
9583 2DEC;COMBINING CYRILLIC LETTER ER;Mn;230;NSM;;;;;N;;;;;
9584 2DED;COMBINING CYRILLIC LETTER ES;Mn;230;NSM;;;;;N;;;;;
9585 2DEE;COMBINING CYRILLIC LETTER TE;Mn;230;NSM;;;;;N;;;;;
9586 2DEF;COMBINING CYRILLIC LETTER HA;Mn;230;NSM;;;;;N;;;;;
9587 2DF0;COMBINING CYRILLIC LETTER TSE;Mn;230;NSM;;;;;N;;;;;
9588 2DF1;COMBINING CYRILLIC LETTER CHE;Mn;230;NSM;;;;;N;;;;;
9589 2DF2;COMBINING CYRILLIC LETTER SHA;Mn;230;NSM;;;;;N;;;;;
9590 2DF3;COMBINING CYRILLIC LETTER SHCHA;Mn;230;NSM;;;;;N;;;;;
9591 2DF4;COMBINING CYRILLIC LETTER FITA;Mn;230;NSM;;;;;N;;;;;
9592 2DF5;COMBINING CYRILLIC LETTER ES-TE;Mn;230;NSM;;;;;N;;;;;
9593 2DF6;COMBINING CYRILLIC LETTER A;Mn;230;NSM;;;;;N;;;;;
9594 2DF7;COMBINING CYRILLIC LETTER IE;Mn;230;NSM;;;;;N;;;;;
9595 2DF8;COMBINING CYRILLIC LETTER DJERV;Mn;230;NSM;;;;;N;;;;;
9596 2DF9;COMBINING CYRILLIC LETTER MONOGRAPH UK;Mn;230;NSM;;;;;N;;;;;
9597 2DFA;COMBINING CYRILLIC LETTER YAT;Mn;230;NSM;;;;;N;;;;;
9598 2DFB;COMBINING CYRILLIC LETTER YU;Mn;230;NSM;;;;;N;;;;;
9599 2DFC;COMBINING CYRILLIC LETTER IOTIFIED A;Mn;230;NSM;;;;;N;;;;;
9600 2DFD;COMBINING CYRILLIC LETTER LITTLE YUS;Mn;230;NSM;;;;;N;;;;;
9601 2DFE;COMBINING CYRILLIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;;
9602 2DFF;COMBINING CYRILLIC LETTER IOTIFIED BIG YUS;Mn;230;NSM;;;;;N;;;;;
9603 2E00;RIGHT ANGLE SUBSTITUTION MARKER;Po;0;ON;;;;;N;;;;;
9604 2E01;RIGHT ANGLE DOTTED SUBSTITUTION MARKER;Po;0;ON;;;;;N;;;;;
9605 2E02;LEFT SUBSTITUTION BRACKET;Pi;0;ON;;;;;Y;;;;;
9606 2E03;RIGHT SUBSTITUTION BRACKET;Pf;0;ON;;;;;Y;;;;;
9607 2E04;LEFT DOTTED SUBSTITUTION BRACKET;Pi;0;ON;;;;;Y;;;;;
9608 2E05;RIGHT DOTTED SUBSTITUTION BRACKET;Pf;0;ON;;;;;Y;;;;;
9609 2E06;RAISED INTERPOLATION MARKER;Po;0;ON;;;;;N;;;;;
9610 2E07;RAISED DOTTED INTERPOLATION MARKER;Po;0;ON;;;;;N;;;;;
9611 2E08;DOTTED TRANSPOSITION MARKER;Po;0;ON;;;;;N;;;;;
9612 2E09;LEFT TRANSPOSITION BRACKET;Pi;0;ON;;;;;Y;;;;;
9613 2E0A;RIGHT TRANSPOSITION BRACKET;Pf;0;ON;;;;;Y;;;;;
9614 2E0B;RAISED SQUARE;Po;0;ON;;;;;N;;;;;
9615 2E0C;LEFT RAISED OMISSION BRACKET;Pi;0;ON;;;;;Y;;;;;
9616 2E0D;RIGHT RAISED OMISSION BRACKET;Pf;0;ON;;;;;Y;;;;;
9617 2E0E;EDITORIAL CORONIS;Po;0;ON;;;;;N;;;;;
9618 2E0F;PARAGRAPHOS;Po;0;ON;;;;;N;;;;;
9619 2E10;FORKED PARAGRAPHOS;Po;0;ON;;;;;N;;;;;
9620 2E11;REVERSED FORKED PARAGRAPHOS;Po;0;ON;;;;;N;;;;;
9621 2E12;HYPODIASTOLE;Po;0;ON;;;;;N;;;;;
9622 2E13;DOTTED OBELOS;Po;0;ON;;;;;N;;;;;
9623 2E14;DOWNWARDS ANCORA;Po;0;ON;;;;;N;;;;;
9624 2E15;UPWARDS ANCORA;Po;0;ON;;;;;N;;;;;
9625 2E16;DOTTED RIGHT-POINTING ANGLE;Po;0;ON;;;;;N;;;;;
9626 2E17;DOUBLE OBLIQUE HYPHEN;Pd;0;ON;;;;;N;;;;;
9627 2E18;INVERTED INTERROBANG;Po;0;ON;;;;;N;;;;;
9628 2E19;PALM BRANCH;Po;0;ON;;;;;N;;;;;
9629 2E1A;HYPHEN WITH DIAERESIS;Pd;0;ON;;;;;N;;;;;
9630 2E1B;TILDE WITH RING ABOVE;Po;0;ON;;;;;N;;;;;
9631 2E1C;LEFT LOW PARAPHRASE BRACKET;Pi;0;ON;;;;;Y;;;;;
9632 2E1D;RIGHT LOW PARAPHRASE BRACKET;Pf;0;ON;;;;;Y;;;;;
9633 2E1E;TILDE WITH DOT ABOVE;Po;0;ON;;;;;N;;;;;
9634 2E1F;TILDE WITH DOT BELOW;Po;0;ON;;;;;N;;;;;
9635 2E20;LEFT VERTICAL BAR WITH QUILL;Pi;0;ON;;;;;Y;;;;;
9636 2E21;RIGHT VERTICAL BAR WITH QUILL;Pf;0;ON;;;;;Y;;;;;
9637 2E22;TOP LEFT HALF BRACKET;Ps;0;ON;;;;;Y;;;;;
9638 2E23;TOP RIGHT HALF BRACKET;Pe;0;ON;;;;;Y;;;;;
9639 2E24;BOTTOM LEFT HALF BRACKET;Ps;0;ON;;;;;Y;;;;;
9640 2E25;BOTTOM RIGHT HALF BRACKET;Pe;0;ON;;;;;Y;;;;;
9641 2E26;LEFT SIDEWAYS U BRACKET;Ps;0;ON;;;;;Y;;;;;
9642 2E27;RIGHT SIDEWAYS U BRACKET;Pe;0;ON;;;;;Y;;;;;
9643 2E28;LEFT DOUBLE PARENTHESIS;Ps;0;ON;;;;;Y;;;;;
9644 2E29;RIGHT DOUBLE PARENTHESIS;Pe;0;ON;;;;;Y;;;;;
9645 2E2A;TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
9646 2E2B;ONE DOT OVER TWO DOTS PUNCTUATION;Po;0;ON;;;;;N;;;;;
9647 2E2C;SQUARED FOUR DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;
9648 2E2D;FIVE DOT MARK;Po;0;ON;;;;;N;;;;;
9649 2E2E;REVERSED QUESTION MARK;Po;0;ON;;;;;N;;;;;
9650 2E2F;VERTICAL TILDE;Lm;0;ON;;;;;N;;;;;
9651 2E30;RING POINT;Po;0;ON;;;;;N;;;;;
9652 2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;;
9653 2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;;
9654 2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;;
9655 2E83;CJK RADICAL SECOND TWO;So;0;ON;;;;;N;;;;;
9656 2E84;CJK RADICAL SECOND THREE;So;0;ON;;;;;N;;;;;
9657 2E85;CJK RADICAL PERSON;So;0;ON;;;;;N;;;;;
9658 2E86;CJK RADICAL BOX;So;0;ON;;;;;N;;;;;
9659 2E87;CJK RADICAL TABLE;So;0;ON;;;;;N;;;;;
9660 2E88;CJK RADICAL KNIFE ONE;So;0;ON;;;;;N;;;;;
9661 2E89;CJK RADICAL KNIFE TWO;So;0;ON;;;;;N;;;;;
9662 2E8A;CJK RADICAL DIVINATION;So;0;ON;;;;;N;;;;;
9663 2E8B;CJK RADICAL SEAL;So;0;ON;;;;;N;;;;;
9664 2E8C;CJK RADICAL SMALL ONE;So;0;ON;;;;;N;;;;;
9665 2E8D;CJK RADICAL SMALL TWO;So;0;ON;;;;;N;;;;;
9666 2E8E;CJK RADICAL LAME ONE;So;0;ON;;;;;N;;;;;
9667 2E8F;CJK RADICAL LAME TWO;So;0;ON;;;;;N;;;;;
9668 2E90;CJK RADICAL LAME THREE;So;0;ON;;;;;N;;;;;
9669 2E91;CJK RADICAL LAME FOUR;So;0;ON;;;;;N;;;;;
9670 2E92;CJK RADICAL SNAKE;So;0;ON;;;;;N;;;;;
9671 2E93;CJK RADICAL THREAD;So;0;ON;;;;;N;;;;;
9672 2E94;CJK RADICAL SNOUT ONE;So;0;ON;;;;;N;;;;;
9673 2E95;CJK RADICAL SNOUT TWO;So;0;ON;;;;;N;;;;;
9674 2E96;CJK RADICAL HEART ONE;So;0;ON;;;;;N;;;;;
9675 2E97;CJK RADICAL HEART TWO;So;0;ON;;;;;N;;;;;
9676 2E98;CJK RADICAL HAND;So;0;ON;;;;;N;;;;;
9677 2E99;CJK RADICAL RAP;So;0;ON;;;;;N;;;;;
9678 2E9B;CJK RADICAL CHOKE;So;0;ON;;;;;N;;;;;
9679 2E9C;CJK RADICAL SUN;So;0;ON;;;;;N;;;;;
9680 2E9D;CJK RADICAL MOON;So;0;ON;;;;;N;;;;;
9681 2E9E;CJK RADICAL DEATH;So;0;ON;;;;;N;;;;;
9682 2E9F;CJK RADICAL MOTHER;So;0;ON;<compat> 6BCD;;;;N;;;;;
9683 2EA0;CJK RADICAL CIVILIAN;So;0;ON;;;;;N;;;;;
9684 2EA1;CJK RADICAL WATER ONE;So;0;ON;;;;;N;;;;;
9685 2EA2;CJK RADICAL WATER TWO;So;0;ON;;;;;N;;;;;
9686 2EA3;CJK RADICAL FIRE;So;0;ON;;;;;N;;;;;
9687 2EA4;CJK RADICAL PAW ONE;So;0;ON;;;;;N;;;;;
9688 2EA5;CJK RADICAL PAW TWO;So;0;ON;;;;;N;;;;;
9689 2EA6;CJK RADICAL SIMPLIFIED HALF TREE TRUNK;So;0;ON;;;;;N;;;;;
9690 2EA7;CJK RADICAL COW;So;0;ON;;;;;N;;;;;
9691 2EA8;CJK RADICAL DOG;So;0;ON;;;;;N;;;;;
9692 2EA9;CJK RADICAL JADE;So;0;ON;;;;;N;;;;;
9693 2EAA;CJK RADICAL BOLT OF CLOTH;So;0;ON;;;;;N;;;;;
9694 2EAB;CJK RADICAL EYE;So;0;ON;;;;;N;;;;;
9695 2EAC;CJK RADICAL SPIRIT ONE;So;0;ON;;;;;N;;;;;
9696 2EAD;CJK RADICAL SPIRIT TWO;So;0;ON;;;;;N;;;;;
9697 2EAE;CJK RADICAL BAMBOO;So;0;ON;;;;;N;;;;;
9698 2EAF;CJK RADICAL SILK;So;0;ON;;;;;N;;;;;
9699 2EB0;CJK RADICAL C-SIMPLIFIED SILK;So;0;ON;;;;;N;;;;;
9700 2EB1;CJK RADICAL NET ONE;So;0;ON;;;;;N;;;;;
9701 2EB2;CJK RADICAL NET TWO;So;0;ON;;;;;N;;;;;
9702 2EB3;CJK RADICAL NET THREE;So;0;ON;;;;;N;;;;;
9703 2EB4;CJK RADICAL NET FOUR;So;0;ON;;;;;N;;;;;
9704 2EB5;CJK RADICAL MESH;So;0;ON;;;;;N;;;;;
9705 2EB6;CJK RADICAL SHEEP;So;0;ON;;;;;N;;;;;
9706 2EB7;CJK RADICAL RAM;So;0;ON;;;;;N;;;;;
9707 2EB8;CJK RADICAL EWE;So;0;ON;;;;;N;;;;;
9708 2EB9;CJK RADICAL OLD;So;0;ON;;;;;N;;;;;
9709 2EBA;CJK RADICAL BRUSH ONE;So;0;ON;;;;;N;;;;;
9710 2EBB;CJK RADICAL BRUSH TWO;So;0;ON;;;;;N;;;;;
9711 2EBC;CJK RADICAL MEAT;So;0;ON;;;;;N;;;;;
9712 2EBD;CJK RADICAL MORTAR;So;0;ON;;;;;N;;;;;
9713 2EBE;CJK RADICAL GRASS ONE;So;0;ON;;;;;N;;;;;
9714 2EBF;CJK RADICAL GRASS TWO;So;0;ON;;;;;N;;;;;
9715 2EC0;CJK RADICAL GRASS THREE;So;0;ON;;;;;N;;;;;
9716 2EC1;CJK RADICAL TIGER;So;0;ON;;;;;N;;;;;
9717 2EC2;CJK RADICAL CLOTHES;So;0;ON;;;;;N;;;;;
9718 2EC3;CJK RADICAL WEST ONE;So;0;ON;;;;;N;;;;;
9719 2EC4;CJK RADICAL WEST TWO;So;0;ON;;;;;N;;;;;
9720 2EC5;CJK RADICAL C-SIMPLIFIED SEE;So;0;ON;;;;;N;;;;;
9721 2EC6;CJK RADICAL SIMPLIFIED HORN;So;0;ON;;;;;N;;;;;
9722 2EC7;CJK RADICAL HORN;So;0;ON;;;;;N;;;;;
9723 2EC8;CJK RADICAL C-SIMPLIFIED SPEECH;So;0;ON;;;;;N;;;;;
9724 2EC9;CJK RADICAL C-SIMPLIFIED SHELL;So;0;ON;;;;;N;;;;;
9725 2ECA;CJK RADICAL FOOT;So;0;ON;;;;;N;;;;;
9726 2ECB;CJK RADICAL C-SIMPLIFIED CART;So;0;ON;;;;;N;;;;;
9727 2ECC;CJK RADICAL SIMPLIFIED WALK;So;0;ON;;;;;N;;;;;
9728 2ECD;CJK RADICAL WALK ONE;So;0;ON;;;;;N;;;;;
9729 2ECE;CJK RADICAL WALK TWO;So;0;ON;;;;;N;;;;;
9730 2ECF;CJK RADICAL CITY;So;0;ON;;;;;N;;;;;
9731 2ED0;CJK RADICAL C-SIMPLIFIED GOLD;So;0;ON;;;;;N;;;;;
9732 2ED1;CJK RADICAL LONG ONE;So;0;ON;;;;;N;;;;;
9733 2ED2;CJK RADICAL LONG TWO;So;0;ON;;;;;N;;;;;
9734 2ED3;CJK RADICAL C-SIMPLIFIED LONG;So;0;ON;;;;;N;;;;;
9735 2ED4;CJK RADICAL C-SIMPLIFIED GATE;So;0;ON;;;;;N;;;;;
9736 2ED5;CJK RADICAL MOUND ONE;So;0;ON;;;;;N;;;;;
9737 2ED6;CJK RADICAL MOUND TWO;So;0;ON;;;;;N;;;;;
9738 2ED7;CJK RADICAL RAIN;So;0;ON;;;;;N;;;;;
9739 2ED8;CJK RADICAL BLUE;So;0;ON;;;;;N;;;;;
9740 2ED9;CJK RADICAL C-SIMPLIFIED TANNED LEATHER;So;0;ON;;;;;N;;;;;
9741 2EDA;CJK RADICAL C-SIMPLIFIED LEAF;So;0;ON;;;;;N;;;;;
9742 2EDB;CJK RADICAL C-SIMPLIFIED WIND;So;0;ON;;;;;N;;;;;
9743 2EDC;CJK RADICAL C-SIMPLIFIED FLY;So;0;ON;;;;;N;;;;;
9744 2EDD;CJK RADICAL EAT ONE;So;0;ON;;;;;N;;;;;
9745 2EDE;CJK RADICAL EAT TWO;So;0;ON;;;;;N;;;;;
9746 2EDF;CJK RADICAL EAT THREE;So;0;ON;;;;;N;;;;;
9747 2EE0;CJK RADICAL C-SIMPLIFIED EAT;So;0;ON;;;;;N;;;;;
9748 2EE1;CJK RADICAL HEAD;So;0;ON;;;;;N;;;;;
9749 2EE2;CJK RADICAL C-SIMPLIFIED HORSE;So;0;ON;;;;;N;;;;;
9750 2EE3;CJK RADICAL BONE;So;0;ON;;;;;N;;;;;
9751 2EE4;CJK RADICAL GHOST;So;0;ON;;;;;N;;;;;
9752 2EE5;CJK RADICAL C-SIMPLIFIED FISH;So;0;ON;;;;;N;;;;;
9753 2EE6;CJK RADICAL C-SIMPLIFIED BIRD;So;0;ON;;;;;N;;;;;
9754 2EE7;CJK RADICAL C-SIMPLIFIED SALT;So;0;ON;;;;;N;;;;;
9755 2EE8;CJK RADICAL SIMPLIFIED WHEAT;So;0;ON;;;;;N;;;;;
9756 2EE9;CJK RADICAL SIMPLIFIED YELLOW;So;0;ON;;;;;N;;;;;
9757 2EEA;CJK RADICAL C-SIMPLIFIED FROG;So;0;ON;;;;;N;;;;;
9758 2EEB;CJK RADICAL J-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;;
9759 2EEC;CJK RADICAL C-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;;
9760 2EED;CJK RADICAL J-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;;
9761 2EEE;CJK RADICAL C-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;;
9762 2EEF;CJK RADICAL J-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;;
9763 2EF0;CJK RADICAL C-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;;
9764 2EF1;CJK RADICAL TURTLE;So;0;ON;;;;;N;;;;;
9765 2EF2;CJK RADICAL J-SIMPLIFIED TURTLE;So;0;ON;;;;;N;;;;;
9766 2EF3;CJK RADICAL C-SIMPLIFIED TURTLE;So;0;ON;<compat> 9F9F;;;;N;;;;;
9767 2F00;KANGXI RADICAL ONE;So;0;ON;<compat> 4E00;;;;N;;;;;
9768 2F01;KANGXI RADICAL LINE;So;0;ON;<compat> 4E28;;;;N;;;;;
9769 2F02;KANGXI RADICAL DOT;So;0;ON;<compat> 4E36;;;;N;;;;;
9770 2F03;KANGXI RADICAL SLASH;So;0;ON;<compat> 4E3F;;;;N;;;;;
9771 2F04;KANGXI RADICAL SECOND;So;0;ON;<compat> 4E59;;;;N;;;;;
9772 2F05;KANGXI RADICAL HOOK;So;0;ON;<compat> 4E85;;;;N;;;;;
9773 2F06;KANGXI RADICAL TWO;So;0;ON;<compat> 4E8C;;;;N;;;;;
9774 2F07;KANGXI RADICAL LID;So;0;ON;<compat> 4EA0;;;;N;;;;;
9775 2F08;KANGXI RADICAL MAN;So;0;ON;<compat> 4EBA;;;;N;;;;;
9776 2F09;KANGXI RADICAL LEGS;So;0;ON;<compat> 513F;;;;N;;;;;
9777 2F0A;KANGXI RADICAL ENTER;So;0;ON;<compat> 5165;;;;N;;;;;
9778 2F0B;KANGXI RADICAL EIGHT;So;0;ON;<compat> 516B;;;;N;;;;;
9779 2F0C;KANGXI RADICAL DOWN BOX;So;0;ON;<compat> 5182;;;;N;;;;;
9780 2F0D;KANGXI RADICAL COVER;So;0;ON;<compat> 5196;;;;N;;;;;
9781 2F0E;KANGXI RADICAL ICE;So;0;ON;<compat> 51AB;;;;N;;;;;
9782 2F0F;KANGXI RADICAL TABLE;So;0;ON;<compat> 51E0;;;;N;;;;;
9783 2F10;KANGXI RADICAL OPEN BOX;So;0;ON;<compat> 51F5;;;;N;;;;;
9784 2F11;KANGXI RADICAL KNIFE;So;0;ON;<compat> 5200;;;;N;;;;;
9785 2F12;KANGXI RADICAL POWER;So;0;ON;<compat> 529B;;;;N;;;;;
9786 2F13;KANGXI RADICAL WRAP;So;0;ON;<compat> 52F9;;;;N;;;;;
9787 2F14;KANGXI RADICAL SPOON;So;0;ON;<compat> 5315;;;;N;;;;;
9788 2F15;KANGXI RADICAL RIGHT OPEN BOX;So;0;ON;<compat> 531A;;;;N;;;;;
9789 2F16;KANGXI RADICAL HIDING ENCLOSURE;So;0;ON;<compat> 5338;;;;N;;;;;
9790 2F17;KANGXI RADICAL TEN;So;0;ON;<compat> 5341;;;;N;;;;;
9791 2F18;KANGXI RADICAL DIVINATION;So;0;ON;<compat> 535C;;;;N;;;;;
9792 2F19;KANGXI RADICAL SEAL;So;0;ON;<compat> 5369;;;;N;;;;;
9793 2F1A;KANGXI RADICAL CLIFF;So;0;ON;<compat> 5382;;;;N;;;;;
9794 2F1B;KANGXI RADICAL PRIVATE;So;0;ON;<compat> 53B6;;;;N;;;;;
9795 2F1C;KANGXI RADICAL AGAIN;So;0;ON;<compat> 53C8;;;;N;;;;;
9796 2F1D;KANGXI RADICAL MOUTH;So;0;ON;<compat> 53E3;;;;N;;;;;
9797 2F1E;KANGXI RADICAL ENCLOSURE;So;0;ON;<compat> 56D7;;;;N;;;;;
9798 2F1F;KANGXI RADICAL EARTH;So;0;ON;<compat> 571F;;;;N;;;;;
9799 2F20;KANGXI RADICAL SCHOLAR;So;0;ON;<compat> 58EB;;;;N;;;;;
9800 2F21;KANGXI RADICAL GO;So;0;ON;<compat> 5902;;;;N;;;;;
9801 2F22;KANGXI RADICAL GO SLOWLY;So;0;ON;<compat> 590A;;;;N;;;;;
9802 2F23;KANGXI RADICAL EVENING;So;0;ON;<compat> 5915;;;;N;;;;;
9803 2F24;KANGXI RADICAL BIG;So;0;ON;<compat> 5927;;;;N;;;;;
9804 2F25;KANGXI RADICAL WOMAN;So;0;ON;<compat> 5973;;;;N;;;;;
9805 2F26;KANGXI RADICAL CHILD;So;0;ON;<compat> 5B50;;;;N;;;;;
9806 2F27;KANGXI RADICAL ROOF;So;0;ON;<compat> 5B80;;;;N;;;;;
9807 2F28;KANGXI RADICAL INCH;So;0;ON;<compat> 5BF8;;;;N;;;;;
9808 2F29;KANGXI RADICAL SMALL;So;0;ON;<compat> 5C0F;;;;N;;;;;
9809 2F2A;KANGXI RADICAL LAME;So;0;ON;<compat> 5C22;;;;N;;;;;
9810 2F2B;KANGXI RADICAL CORPSE;So;0;ON;<compat> 5C38;;;;N;;;;;
9811 2F2C;KANGXI RADICAL SPROUT;So;0;ON;<compat> 5C6E;;;;N;;;;;
9812 2F2D;KANGXI RADICAL MOUNTAIN;So;0;ON;<compat> 5C71;;;;N;;;;;
9813 2F2E;KANGXI RADICAL RIVER;So;0;ON;<compat> 5DDB;;;;N;;;;;
9814 2F2F;KANGXI RADICAL WORK;So;0;ON;<compat> 5DE5;;;;N;;;;;
9815 2F30;KANGXI RADICAL ONESELF;So;0;ON;<compat> 5DF1;;;;N;;;;;
9816 2F31;KANGXI RADICAL TURBAN;So;0;ON;<compat> 5DFE;;;;N;;;;;
9817 2F32;KANGXI RADICAL DRY;So;0;ON;<compat> 5E72;;;;N;;;;;
9818 2F33;KANGXI RADICAL SHORT THREAD;So;0;ON;<compat> 5E7A;;;;N;;;;;
9819 2F34;KANGXI RADICAL DOTTED CLIFF;So;0;ON;<compat> 5E7F;;;;N;;;;;
9820 2F35;KANGXI RADICAL LONG STRIDE;So;0;ON;<compat> 5EF4;;;;N;;;;;
9821 2F36;KANGXI RADICAL TWO HANDS;So;0;ON;<compat> 5EFE;;;;N;;;;;
9822 2F37;KANGXI RADICAL SHOOT;So;0;ON;<compat> 5F0B;;;;N;;;;;
9823 2F38;KANGXI RADICAL BOW;So;0;ON;<compat> 5F13;;;;N;;;;;
9824 2F39;KANGXI RADICAL SNOUT;So;0;ON;<compat> 5F50;;;;N;;;;;
9825 2F3A;KANGXI RADICAL BRISTLE;So;0;ON;<compat> 5F61;;;;N;;;;;
9826 2F3B;KANGXI RADICAL STEP;So;0;ON;<compat> 5F73;;;;N;;;;;
9827 2F3C;KANGXI RADICAL HEART;So;0;ON;<compat> 5FC3;;;;N;;;;;
9828 2F3D;KANGXI RADICAL HALBERD;So;0;ON;<compat> 6208;;;;N;;;;;
9829 2F3E;KANGXI RADICAL DOOR;So;0;ON;<compat> 6236;;;;N;;;;;
9830 2F3F;KANGXI RADICAL HAND;So;0;ON;<compat> 624B;;;;N;;;;;
9831 2F40;KANGXI RADICAL BRANCH;So;0;ON;<compat> 652F;;;;N;;;;;
9832 2F41;KANGXI RADICAL RAP;So;0;ON;<compat> 6534;;;;N;;;;;
9833 2F42;KANGXI RADICAL SCRIPT;So;0;ON;<compat> 6587;;;;N;;;;;
9834 2F43;KANGXI RADICAL DIPPER;So;0;ON;<compat> 6597;;;;N;;;;;
9835 2F44;KANGXI RADICAL AXE;So;0;ON;<compat> 65A4;;;;N;;;;;
9836 2F45;KANGXI RADICAL SQUARE;So;0;ON;<compat> 65B9;;;;N;;;;;
9837 2F46;KANGXI RADICAL NOT;So;0;ON;<compat> 65E0;;;;N;;;;;
9838 2F47;KANGXI RADICAL SUN;So;0;ON;<compat> 65E5;;;;N;;;;;
9839 2F48;KANGXI RADICAL SAY;So;0;ON;<compat> 66F0;;;;N;;;;;
9840 2F49;KANGXI RADICAL MOON;So;0;ON;<compat> 6708;;;;N;;;;;
9841 2F4A;KANGXI RADICAL TREE;So;0;ON;<compat> 6728;;;;N;;;;;
9842 2F4B;KANGXI RADICAL LACK;So;0;ON;<compat> 6B20;;;;N;;;;;
9843 2F4C;KANGXI RADICAL STOP;So;0;ON;<compat> 6B62;;;;N;;;;;
9844 2F4D;KANGXI RADICAL DEATH;So;0;ON;<compat> 6B79;;;;N;;;;;
9845 2F4E;KANGXI RADICAL WEAPON;So;0;ON;<compat> 6BB3;;;;N;;;;;
9846 2F4F;KANGXI RADICAL DO NOT;So;0;ON;<compat> 6BCB;;;;N;;;;;
9847 2F50;KANGXI RADICAL COMPARE;So;0;ON;<compat> 6BD4;;;;N;;;;;
9848 2F51;KANGXI RADICAL FUR;So;0;ON;<compat> 6BDB;;;;N;;;;;
9849 2F52;KANGXI RADICAL CLAN;So;0;ON;<compat> 6C0F;;;;N;;;;;
9850 2F53;KANGXI RADICAL STEAM;So;0;ON;<compat> 6C14;;;;N;;;;;
9851 2F54;KANGXI RADICAL WATER;So;0;ON;<compat> 6C34;;;;N;;;;;
9852 2F55;KANGXI RADICAL FIRE;So;0;ON;<compat> 706B;;;;N;;;;;
9853 2F56;KANGXI RADICAL CLAW;So;0;ON;<compat> 722A;;;;N;;;;;
9854 2F57;KANGXI RADICAL FATHER;So;0;ON;<compat> 7236;;;;N;;;;;
9855 2F58;KANGXI RADICAL DOUBLE X;So;0;ON;<compat> 723B;;;;N;;;;;
9856 2F59;KANGXI RADICAL HALF TREE TRUNK;So;0;ON;<compat> 723F;;;;N;;;;;
9857 2F5A;KANGXI RADICAL SLICE;So;0;ON;<compat> 7247;;;;N;;;;;
9858 2F5B;KANGXI RADICAL FANG;So;0;ON;<compat> 7259;;;;N;;;;;
9859 2F5C;KANGXI RADICAL COW;So;0;ON;<compat> 725B;;;;N;;;;;
9860 2F5D;KANGXI RADICAL DOG;So;0;ON;<compat> 72AC;;;;N;;;;;
9861 2F5E;KANGXI RADICAL PROFOUND;So;0;ON;<compat> 7384;;;;N;;;;;
9862 2F5F;KANGXI RADICAL JADE;So;0;ON;<compat> 7389;;;;N;;;;;
9863 2F60;KANGXI RADICAL MELON;So;0;ON;<compat> 74DC;;;;N;;;;;
9864 2F61;KANGXI RADICAL TILE;So;0;ON;<compat> 74E6;;;;N;;;;;
9865 2F62;KANGXI RADICAL SWEET;So;0;ON;<compat> 7518;;;;N;;;;;
9866 2F63;KANGXI RADICAL LIFE;So;0;ON;<compat> 751F;;;;N;;;;;
9867 2F64;KANGXI RADICAL USE;So;0;ON;<compat> 7528;;;;N;;;;;
9868 2F65;KANGXI RADICAL FIELD;So;0;ON;<compat> 7530;;;;N;;;;;
9869 2F66;KANGXI RADICAL BOLT OF CLOTH;So;0;ON;<compat> 758B;;;;N;;;;;
9870 2F67;KANGXI RADICAL SICKNESS;So;0;ON;<compat> 7592;;;;N;;;;;
9871 2F68;KANGXI RADICAL DOTTED TENT;So;0;ON;<compat> 7676;;;;N;;;;;
9872 2F69;KANGXI RADICAL WHITE;So;0;ON;<compat> 767D;;;;N;;;;;
9873 2F6A;KANGXI RADICAL SKIN;So;0;ON;<compat> 76AE;;;;N;;;;;
9874 2F6B;KANGXI RADICAL DISH;So;0;ON;<compat> 76BF;;;;N;;;;;
9875 2F6C;KANGXI RADICAL EYE;So;0;ON;<compat> 76EE;;;;N;;;;;
9876 2F6D;KANGXI RADICAL SPEAR;So;0;ON;<compat> 77DB;;;;N;;;;;
9877 2F6E;KANGXI RADICAL ARROW;So;0;ON;<compat> 77E2;;;;N;;;;;
9878 2F6F;KANGXI RADICAL STONE;So;0;ON;<compat> 77F3;;;;N;;;;;
9879 2F70;KANGXI RADICAL SPIRIT;So;0;ON;<compat> 793A;;;;N;;;;;
9880 2F71;KANGXI RADICAL TRACK;So;0;ON;<compat> 79B8;;;;N;;;;;
9881 2F72;KANGXI RADICAL GRAIN;So;0;ON;<compat> 79BE;;;;N;;;;;
9882 2F73;KANGXI RADICAL CAVE;So;0;ON;<compat> 7A74;;;;N;;;;;
9883 2F74;KANGXI RADICAL STAND;So;0;ON;<compat> 7ACB;;;;N;;;;;
9884 2F75;KANGXI RADICAL BAMBOO;So;0;ON;<compat> 7AF9;;;;N;;;;;
9885 2F76;KANGXI RADICAL RICE;So;0;ON;<compat> 7C73;;;;N;;;;;
9886 2F77;KANGXI RADICAL SILK;So;0;ON;<compat> 7CF8;;;;N;;;;;
9887 2F78;KANGXI RADICAL JAR;So;0;ON;<compat> 7F36;;;;N;;;;;
9888 2F79;KANGXI RADICAL NET;So;0;ON;<compat> 7F51;;;;N;;;;;
9889 2F7A;KANGXI RADICAL SHEEP;So;0;ON;<compat> 7F8A;;;;N;;;;;
9890 2F7B;KANGXI RADICAL FEATHER;So;0;ON;<compat> 7FBD;;;;N;;;;;
9891 2F7C;KANGXI RADICAL OLD;So;0;ON;<compat> 8001;;;;N;;;;;
9892 2F7D;KANGXI RADICAL AND;So;0;ON;<compat> 800C;;;;N;;;;;
9893 2F7E;KANGXI RADICAL PLOW;So;0;ON;<compat> 8012;;;;N;;;;;
9894 2F7F;KANGXI RADICAL EAR;So;0;ON;<compat> 8033;;;;N;;;;;
9895 2F80;KANGXI RADICAL BRUSH;So;0;ON;<compat> 807F;;;;N;;;;;
9896 2F81;KANGXI RADICAL MEAT;So;0;ON;<compat> 8089;;;;N;;;;;
9897 2F82;KANGXI RADICAL MINISTER;So;0;ON;<compat> 81E3;;;;N;;;;;
9898 2F83;KANGXI RADICAL SELF;So;0;ON;<compat> 81EA;;;;N;;;;;
9899 2F84;KANGXI RADICAL ARRIVE;So;0;ON;<compat> 81F3;;;;N;;;;;
9900 2F85;KANGXI RADICAL MORTAR;So;0;ON;<compat> 81FC;;;;N;;;;;
9901 2F86;KANGXI RADICAL TONGUE;So;0;ON;<compat> 820C;;;;N;;;;;
9902 2F87;KANGXI RADICAL OPPOSE;So;0;ON;<compat> 821B;;;;N;;;;;
9903 2F88;KANGXI RADICAL BOAT;So;0;ON;<compat> 821F;;;;N;;;;;
9904 2F89;KANGXI RADICAL STOPPING;So;0;ON;<compat> 826E;;;;N;;;;;
9905 2F8A;KANGXI RADICAL COLOR;So;0;ON;<compat> 8272;;;;N;;;;;
9906 2F8B;KANGXI RADICAL GRASS;So;0;ON;<compat> 8278;;;;N;;;;;
9907 2F8C;KANGXI RADICAL TIGER;So;0;ON;<compat> 864D;;;;N;;;;;
9908 2F8D;KANGXI RADICAL INSECT;So;0;ON;<compat> 866B;;;;N;;;;;
9909 2F8E;KANGXI RADICAL BLOOD;So;0;ON;<compat> 8840;;;;N;;;;;
9910 2F8F;KANGXI RADICAL WALK ENCLOSURE;So;0;ON;<compat> 884C;;;;N;;;;;
9911 2F90;KANGXI RADICAL CLOTHES;So;0;ON;<compat> 8863;;;;N;;;;;
9912 2F91;KANGXI RADICAL WEST;So;0;ON;<compat> 897E;;;;N;;;;;
9913 2F92;KANGXI RADICAL SEE;So;0;ON;<compat> 898B;;;;N;;;;;
9914 2F93;KANGXI RADICAL HORN;So;0;ON;<compat> 89D2;;;;N;;;;;
9915 2F94;KANGXI RADICAL SPEECH;So;0;ON;<compat> 8A00;;;;N;;;;;
9916 2F95;KANGXI RADICAL VALLEY;So;0;ON;<compat> 8C37;;;;N;;;;;
9917 2F96;KANGXI RADICAL BEAN;So;0;ON;<compat> 8C46;;;;N;;;;;
9918 2F97;KANGXI RADICAL PIG;So;0;ON;<compat> 8C55;;;;N;;;;;
9919 2F98;KANGXI RADICAL BADGER;So;0;ON;<compat> 8C78;;;;N;;;;;
9920 2F99;KANGXI RADICAL SHELL;So;0;ON;<compat> 8C9D;;;;N;;;;;
9921 2F9A;KANGXI RADICAL RED;So;0;ON;<compat> 8D64;;;;N;;;;;
9922 2F9B;KANGXI RADICAL RUN;So;0;ON;<compat> 8D70;;;;N;;;;;
9923 2F9C;KANGXI RADICAL FOOT;So;0;ON;<compat> 8DB3;;;;N;;;;;
9924 2F9D;KANGXI RADICAL BODY;So;0;ON;<compat> 8EAB;;;;N;;;;;
9925 2F9E;KANGXI RADICAL CART;So;0;ON;<compat> 8ECA;;;;N;;;;;
9926 2F9F;KANGXI RADICAL BITTER;So;0;ON;<compat> 8F9B;;;;N;;;;;
9927 2FA0;KANGXI RADICAL MORNING;So;0;ON;<compat> 8FB0;;;;N;;;;;
9928 2FA1;KANGXI RADICAL WALK;So;0;ON;<compat> 8FB5;;;;N;;;;;
9929 2FA2;KANGXI RADICAL CITY;So;0;ON;<compat> 9091;;;;N;;;;;
9930 2FA3;KANGXI RADICAL WINE;So;0;ON;<compat> 9149;;;;N;;;;;
9931 2FA4;KANGXI RADICAL DISTINGUISH;So;0;ON;<compat> 91C6;;;;N;;;;;
9932 2FA5;KANGXI RADICAL VILLAGE;So;0;ON;<compat> 91CC;;;;N;;;;;
9933 2FA6;KANGXI RADICAL GOLD;So;0;ON;<compat> 91D1;;;;N;;;;;
9934 2FA7;KANGXI RADICAL LONG;So;0;ON;<compat> 9577;;;;N;;;;;
9935 2FA8;KANGXI RADICAL GATE;So;0;ON;<compat> 9580;;;;N;;;;;
9936 2FA9;KANGXI RADICAL MOUND;So;0;ON;<compat> 961C;;;;N;;;;;
9937 2FAA;KANGXI RADICAL SLAVE;So;0;ON;<compat> 96B6;;;;N;;;;;
9938 2FAB;KANGXI RADICAL SHORT TAILED BIRD;So;0;ON;<compat> 96B9;;;;N;;;;;
9939 2FAC;KANGXI RADICAL RAIN;So;0;ON;<compat> 96E8;;;;N;;;;;
9940 2FAD;KANGXI RADICAL BLUE;So;0;ON;<compat> 9751;;;;N;;;;;
9941 2FAE;KANGXI RADICAL WRONG;So;0;ON;<compat> 975E;;;;N;;;;;
9942 2FAF;KANGXI RADICAL FACE;So;0;ON;<compat> 9762;;;;N;;;;;
9943 2FB0;KANGXI RADICAL LEATHER;So;0;ON;<compat> 9769;;;;N;;;;;
9944 2FB1;KANGXI RADICAL TANNED LEATHER;So;0;ON;<compat> 97CB;;;;N;;;;;
9945 2FB2;KANGXI RADICAL LEEK;So;0;ON;<compat> 97ED;;;;N;;;;;
9946 2FB3;KANGXI RADICAL SOUND;So;0;ON;<compat> 97F3;;;;N;;;;;
9947 2FB4;KANGXI RADICAL LEAF;So;0;ON;<compat> 9801;;;;N;;;;;
9948 2FB5;KANGXI RADICAL WIND;So;0;ON;<compat> 98A8;;;;N;;;;;
9949 2FB6;KANGXI RADICAL FLY;So;0;ON;<compat> 98DB;;;;N;;;;;
9950 2FB7;KANGXI RADICAL EAT;So;0;ON;<compat> 98DF;;;;N;;;;;
9951 2FB8;KANGXI RADICAL HEAD;So;0;ON;<compat> 9996;;;;N;;;;;
9952 2FB9;KANGXI RADICAL FRAGRANT;So;0;ON;<compat> 9999;;;;N;;;;;
9953 2FBA;KANGXI RADICAL HORSE;So;0;ON;<compat> 99AC;;;;N;;;;;
9954 2FBB;KANGXI RADICAL BONE;So;0;ON;<compat> 9AA8;;;;N;;;;;
9955 2FBC;KANGXI RADICAL TALL;So;0;ON;<compat> 9AD8;;;;N;;;;;
9956 2FBD;KANGXI RADICAL HAIR;So;0;ON;<compat> 9ADF;;;;N;;;;;
9957 2FBE;KANGXI RADICAL FIGHT;So;0;ON;<compat> 9B25;;;;N;;;;;
9958 2FBF;KANGXI RADICAL SACRIFICIAL WINE;So;0;ON;<compat> 9B2F;;;;N;;;;;
9959 2FC0;KANGXI RADICAL CAULDRON;So;0;ON;<compat> 9B32;;;;N;;;;;
9960 2FC1;KANGXI RADICAL GHOST;So;0;ON;<compat> 9B3C;;;;N;;;;;
9961 2FC2;KANGXI RADICAL FISH;So;0;ON;<compat> 9B5A;;;;N;;;;;
9962 2FC3;KANGXI RADICAL BIRD;So;0;ON;<compat> 9CE5;;;;N;;;;;
9963 2FC4;KANGXI RADICAL SALT;So;0;ON;<compat> 9E75;;;;N;;;;;
9964 2FC5;KANGXI RADICAL DEER;So;0;ON;<compat> 9E7F;;;;N;;;;;
9965 2FC6;KANGXI RADICAL WHEAT;So;0;ON;<compat> 9EA5;;;;N;;;;;
9966 2FC7;KANGXI RADICAL HEMP;So;0;ON;<compat> 9EBB;;;;N;;;;;
9967 2FC8;KANGXI RADICAL YELLOW;So;0;ON;<compat> 9EC3;;;;N;;;;;
9968 2FC9;KANGXI RADICAL MILLET;So;0;ON;<compat> 9ECD;;;;N;;;;;
9969 2FCA;KANGXI RADICAL BLACK;So;0;ON;<compat> 9ED1;;;;N;;;;;
9970 2FCB;KANGXI RADICAL EMBROIDERY;So;0;ON;<compat> 9EF9;;;;N;;;;;
9971 2FCC;KANGXI RADICAL FROG;So;0;ON;<compat> 9EFD;;;;N;;;;;
9972 2FCD;KANGXI RADICAL TRIPOD;So;0;ON;<compat> 9F0E;;;;N;;;;;
9973 2FCE;KANGXI RADICAL DRUM;So;0;ON;<compat> 9F13;;;;N;;;;;
9974 2FCF;KANGXI RADICAL RAT;So;0;ON;<compat> 9F20;;;;N;;;;;
9975 2FD0;KANGXI RADICAL NOSE;So;0;ON;<compat> 9F3B;;;;N;;;;;
9976 2FD1;KANGXI RADICAL EVEN;So;0;ON;<compat> 9F4A;;;;N;;;;;
9977 2FD2;KANGXI RADICAL TOOTH;So;0;ON;<compat> 9F52;;;;N;;;;;
9978 2FD3;KANGXI RADICAL DRAGON;So;0;ON;<compat> 9F8D;;;;N;;;;;
9979 2FD4;KANGXI RADICAL TURTLE;So;0;ON;<compat> 9F9C;;;;N;;;;;
9980 2FD5;KANGXI RADICAL FLUTE;So;0;ON;<compat> 9FA0;;;;N;;;;;
9981 2FF0;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT;So;0;ON;;;;;N;;;;;
9982 2FF1;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW;So;0;ON;;;;;N;;;;;
9983 2FF2;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT;So;0;ON;;;;;N;;;;;
9984 2FF3;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW;So;0;ON;;;;;N;;;;;
9985 2FF4;IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND;So;0;ON;;;;;N;;;;;
9986 2FF5;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE;So;0;ON;;;;;N;;;;;
9987 2FF6;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW;So;0;ON;;;;;N;;;;;
9988 2FF7;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT;So;0;ON;;;;;N;;;;;
9989 2FF8;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT;So;0;ON;;;;;N;;;;;
9990 2FF9;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT;So;0;ON;;;;;N;;;;;
9991 2FFA;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT;So;0;ON;;;;;N;;;;;
9992 2FFB;IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID;So;0;ON;;;;;N;;;;;
9993 3000;IDEOGRAPHIC SPACE;Zs;0;WS;<wide> 0020;;;;N;;;;;
9994 3001;IDEOGRAPHIC COMMA;Po;0;ON;;;;;N;;;;;
9995 3002;IDEOGRAPHIC FULL STOP;Po;0;ON;;;;;N;IDEOGRAPHIC PERIOD;;;;
9996 3003;DITTO MARK;Po;0;ON;;;;;N;;;;;
9997 3004;JAPANESE INDUSTRIAL STANDARD SYMBOL;So;0;ON;;;;;N;;;;;
9998 3005;IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;;
9999 3006;IDEOGRAPHIC CLOSING MARK;Lo;0;L;;;;;N;;;;;
10000 3007;IDEOGRAPHIC NUMBER ZERO;Nl;0;L;;;;0;N;;;;;
10001 3008;LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING ANGLE BRACKET;;;;
10002 3009;RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING ANGLE BRACKET;;;;
10003 300A;LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING DOUBLE ANGLE BRACKET;;;;
10004 300B;RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING DOUBLE ANGLE BRACKET;;;;
10005 300C;LEFT CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING CORNER BRACKET;;;;
10006 300D;RIGHT CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING CORNER BRACKET;;;;
10007 300E;LEFT WHITE CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE CORNER BRACKET;;;;
10008 300F;RIGHT WHITE CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE CORNER BRACKET;;;;
10009 3010;LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING BLACK LENTICULAR BRACKET;;;;
10010 3011;RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING BLACK LENTICULAR BRACKET;;;;
10011 3012;POSTAL MARK;So;0;ON;;;;;N;;;;;
10012 3013;GETA MARK;So;0;ON;;;;;N;;;;;
10013 3014;LEFT TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING TORTOISE SHELL BRACKET;;;;
10014 3015;RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING TORTOISE SHELL BRACKET;;;;
10015 3016;LEFT WHITE LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE LENTICULAR BRACKET;;;;
10016 3017;RIGHT WHITE LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE LENTICULAR BRACKET;;;;
10017 3018;LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE TORTOISE SHELL BRACKET;;;;
10018 3019;RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE TORTOISE SHELL BRACKET;;;;
10019 301A;LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE SQUARE BRACKET;;;;
10020 301B;RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE SQUARE BRACKET;;;;
10021 301C;WAVE DASH;Pd;0;ON;;;;;N;;;;;
10022 301D;REVERSED DOUBLE PRIME QUOTATION MARK;Ps;0;ON;;;;;N;;;;;
10023 301E;DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;;
10024 301F;LOW DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;;
10025 3020;POSTAL MARK FACE;So;0;ON;;;;;N;;;;;
10026 3021;HANGZHOU NUMERAL ONE;Nl;0;L;;;;1;N;;;;;
10027 3022;HANGZHOU NUMERAL TWO;Nl;0;L;;;;2;N;;;;;
10028 3023;HANGZHOU NUMERAL THREE;Nl;0;L;;;;3;N;;;;;
10029 3024;HANGZHOU NUMERAL FOUR;Nl;0;L;;;;4;N;;;;;
10030 3025;HANGZHOU NUMERAL FIVE;Nl;0;L;;;;5;N;;;;;
10031 3026;HANGZHOU NUMERAL SIX;Nl;0;L;;;;6;N;;;;;
10032 3027;HANGZHOU NUMERAL SEVEN;Nl;0;L;;;;7;N;;;;;
10033 3028;HANGZHOU NUMERAL EIGHT;Nl;0;L;;;;8;N;;;;;
10034 3029;HANGZHOU NUMERAL NINE;Nl;0;L;;;;9;N;;;;;
10035 302A;IDEOGRAPHIC LEVEL TONE MARK;Mn;218;NSM;;;;;N;;;;;
10036 302B;IDEOGRAPHIC RISING TONE MARK;Mn;228;NSM;;;;;N;;;;;
10037 302C;IDEOGRAPHIC DEPARTING TONE MARK;Mn;232;NSM;;;;;N;;;;;
10038 302D;IDEOGRAPHIC ENTERING TONE MARK;Mn;222;NSM;;;;;N;;;;;
10039 302E;HANGUL SINGLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;;
10040 302F;HANGUL DOUBLE DOT TONE MARK;Mn;224;NSM;;;;;N;;;;;
10041 3030;WAVY DASH;Pd;0;ON;;;;;N;;;;;
10042 3031;VERTICAL KANA REPEAT MARK;Lm;0;L;;;;;N;;;;;
10043 3032;VERTICAL KANA REPEAT WITH VOICED SOUND MARK;Lm;0;L;;;;;N;;;;;
10044 3033;VERTICAL KANA REPEAT MARK UPPER HALF;Lm;0;L;;;;;N;;;;;
10045 3034;VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF;Lm;0;L;;;;;N;;;;;
10046 3035;VERTICAL KANA REPEAT MARK LOWER HALF;Lm;0;L;;;;;N;;;;;
10047 3036;CIRCLED POSTAL MARK;So;0;ON;<compat> 3012;;;;N;;;;;
10048 3037;IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL;So;0;ON;;;;;N;;;;;
10049 3038;HANGZHOU NUMERAL TEN;Nl;0;L;<compat> 5341;;;10;N;;;;;
10050 3039;HANGZHOU NUMERAL TWENTY;Nl;0;L;<compat> 5344;;;20;N;;;;;
10051 303A;HANGZHOU NUMERAL THIRTY;Nl;0;L;<compat> 5345;;;30;N;;;;;
10052 303B;VERTICAL IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;;
10053 303C;MASU MARK;Lo;0;L;;;;;N;;;;;
10054 303D;PART ALTERNATION MARK;Po;0;ON;;;;;N;;;;;
10055 303E;IDEOGRAPHIC VARIATION INDICATOR;So;0;ON;;;;;N;;;;;
10056 303F;IDEOGRAPHIC HALF FILL SPACE;So;0;ON;;;;;N;;;;;
10057 3041;HIRAGANA LETTER SMALL A;Lo;0;L;;;;;N;;;;;
10058 3042;HIRAGANA LETTER A;Lo;0;L;;;;;N;;;;;
10059 3043;HIRAGANA LETTER SMALL I;Lo;0;L;;;;;N;;;;;
10060 3044;HIRAGANA LETTER I;Lo;0;L;;;;;N;;;;;
10061 3045;HIRAGANA LETTER SMALL U;Lo;0;L;;;;;N;;;;;
10062 3046;HIRAGANA LETTER U;Lo;0;L;;;;;N;;;;;
10063 3047;HIRAGANA LETTER SMALL E;Lo;0;L;;;;;N;;;;;
10064 3048;HIRAGANA LETTER E;Lo;0;L;;;;;N;;;;;
10065 3049;HIRAGANA LETTER SMALL O;Lo;0;L;;;;;N;;;;;
10066 304A;HIRAGANA LETTER O;Lo;0;L;;;;;N;;;;;
10067 304B;HIRAGANA LETTER KA;Lo;0;L;;;;;N;;;;;
10068 304C;HIRAGANA LETTER GA;Lo;0;L;304B 3099;;;;N;;;;;
10069 304D;HIRAGANA LETTER KI;Lo;0;L;;;;;N;;;;;
10070 304E;HIRAGANA LETTER GI;Lo;0;L;304D 3099;;;;N;;;;;
10071 304F;HIRAGANA LETTER KU;Lo;0;L;;;;;N;;;;;
10072 3050;HIRAGANA LETTER GU;Lo;0;L;304F 3099;;;;N;;;;;
10073 3051;HIRAGANA LETTER KE;Lo;0;L;;;;;N;;;;;
10074 3052;HIRAGANA LETTER GE;Lo;0;L;3051 3099;;;;N;;;;;
10075 3053;HIRAGANA LETTER KO;Lo;0;L;;;;;N;;;;;
10076 3054;HIRAGANA LETTER GO;Lo;0;L;3053 3099;;;;N;;;;;
10077 3055;HIRAGANA LETTER SA;Lo;0;L;;;;;N;;;;;
10078 3056;HIRAGANA LETTER ZA;Lo;0;L;3055 3099;;;;N;;;;;
10079 3057;HIRAGANA LETTER SI;Lo;0;L;;;;;N;;;;;
10080 3058;HIRAGANA LETTER ZI;Lo;0;L;3057 3099;;;;N;;;;;
10081 3059;HIRAGANA LETTER SU;Lo;0;L;;;;;N;;;;;
10082 305A;HIRAGANA LETTER ZU;Lo;0;L;3059 3099;;;;N;;;;;
10083 305B;HIRAGANA LETTER SE;Lo;0;L;;;;;N;;;;;
10084 305C;HIRAGANA LETTER ZE;Lo;0;L;305B 3099;;;;N;;;;;
10085 305D;HIRAGANA LETTER SO;Lo;0;L;;;;;N;;;;;
10086 305E;HIRAGANA LETTER ZO;Lo;0;L;305D 3099;;;;N;;;;;
10087 305F;HIRAGANA LETTER TA;Lo;0;L;;;;;N;;;;;
10088 3060;HIRAGANA LETTER DA;Lo;0;L;305F 3099;;;;N;;;;;
10089 3061;HIRAGANA LETTER TI;Lo;0;L;;;;;N;;;;;
10090 3062;HIRAGANA LETTER DI;Lo;0;L;3061 3099;;;;N;;;;;
10091 3063;HIRAGANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;;
10092 3064;HIRAGANA LETTER TU;Lo;0;L;;;;;N;;;;;
10093 3065;HIRAGANA LETTER DU;Lo;0;L;3064 3099;;;;N;;;;;
10094 3066;HIRAGANA LETTER TE;Lo;0;L;;;;;N;;;;;
10095 3067;HIRAGANA LETTER DE;Lo;0;L;3066 3099;;;;N;;;;;
10096 3068;HIRAGANA LETTER TO;Lo;0;L;;;;;N;;;;;
10097 3069;HIRAGANA LETTER DO;Lo;0;L;3068 3099;;;;N;;;;;
10098 306A;HIRAGANA LETTER NA;Lo;0;L;;;;;N;;;;;
10099 306B;HIRAGANA LETTER NI;Lo;0;L;;;;;N;;;;;
10100 306C;HIRAGANA LETTER NU;Lo;0;L;;;;;N;;;;;
10101 306D;HIRAGANA LETTER NE;Lo;0;L;;;;;N;;;;;
10102 306E;HIRAGANA LETTER NO;Lo;0;L;;;;;N;;;;;
10103 306F;HIRAGANA LETTER HA;Lo;0;L;;;;;N;;;;;
10104 3070;HIRAGANA LETTER BA;Lo;0;L;306F 3099;;;;N;;;;;
10105 3071;HIRAGANA LETTER PA;Lo;0;L;306F 309A;;;;N;;;;;
10106 3072;HIRAGANA LETTER HI;Lo;0;L;;;;;N;;;;;
10107 3073;HIRAGANA LETTER BI;Lo;0;L;3072 3099;;;;N;;;;;
10108 3074;HIRAGANA LETTER PI;Lo;0;L;3072 309A;;;;N;;;;;
10109 3075;HIRAGANA LETTER HU;Lo;0;L;;;;;N;;;;;
10110 3076;HIRAGANA LETTER BU;Lo;0;L;3075 3099;;;;N;;;;;
10111 3077;HIRAGANA LETTER PU;Lo;0;L;3075 309A;;;;N;;;;;
10112 3078;HIRAGANA LETTER HE;Lo;0;L;;;;;N;;;;;
10113 3079;HIRAGANA LETTER BE;Lo;0;L;3078 3099;;;;N;;;;;
10114 307A;HIRAGANA LETTER PE;Lo;0;L;3078 309A;;;;N;;;;;
10115 307B;HIRAGANA LETTER HO;Lo;0;L;;;;;N;;;;;
10116 307C;HIRAGANA LETTER BO;Lo;0;L;307B 3099;;;;N;;;;;
10117 307D;HIRAGANA LETTER PO;Lo;0;L;307B 309A;;;;N;;;;;
10118 307E;HIRAGANA LETTER MA;Lo;0;L;;;;;N;;;;;
10119 307F;HIRAGANA LETTER MI;Lo;0;L;;;;;N;;;;;
10120 3080;HIRAGANA LETTER MU;Lo;0;L;;;;;N;;;;;
10121 3081;HIRAGANA LETTER ME;Lo;0;L;;;;;N;;;;;
10122 3082;HIRAGANA LETTER MO;Lo;0;L;;;;;N;;;;;
10123 3083;HIRAGANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;;
10124 3084;HIRAGANA LETTER YA;Lo;0;L;;;;;N;;;;;
10125 3085;HIRAGANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;;
10126 3086;HIRAGANA LETTER YU;Lo;0;L;;;;;N;;;;;
10127 3087;HIRAGANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;;
10128 3088;HIRAGANA LETTER YO;Lo;0;L;;;;;N;;;;;
10129 3089;HIRAGANA LETTER RA;Lo;0;L;;;;;N;;;;;
10130 308A;HIRAGANA LETTER RI;Lo;0;L;;;;;N;;;;;
10131 308B;HIRAGANA LETTER RU;Lo;0;L;;;;;N;;;;;
10132 308C;HIRAGANA LETTER RE;Lo;0;L;;;;;N;;;;;
10133 308D;HIRAGANA LETTER RO;Lo;0;L;;;;;N;;;;;
10134 308E;HIRAGANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;;
10135 308F;HIRAGANA LETTER WA;Lo;0;L;;;;;N;;;;;
10136 3090;HIRAGANA LETTER WI;Lo;0;L;;;;;N;;;;;
10137 3091;HIRAGANA LETTER WE;Lo;0;L;;;;;N;;;;;
10138 3092;HIRAGANA LETTER WO;Lo;0;L;;;;;N;;;;;
10139 3093;HIRAGANA LETTER N;Lo;0;L;;;;;N;;;;;
10140 3094;HIRAGANA LETTER VU;Lo;0;L;3046 3099;;;;N;;;;;
10141 3095;HIRAGANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;;
10142 3096;HIRAGANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;;
10143 3099;COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA VOICED SOUND MARK;;;;
10144 309A;COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;;;;
10145 309B;KATAKANA-HIRAGANA VOICED SOUND MARK;Sk;0;ON;<compat> 0020 3099;;;;N;;;;;
10146 309C;KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Sk;0;ON;<compat> 0020 309A;;;;N;;;;;
10147 309D;HIRAGANA ITERATION MARK;Lm;0;L;;;;;N;;;;;
10148 309E;HIRAGANA VOICED ITERATION MARK;Lm;0;L;309D 3099;;;;N;;;;;
10149 309F;HIRAGANA DIGRAPH YORI;Lo;0;L;<vertical> 3088 308A;;;;N;;;;;
10150 30A0;KATAKANA-HIRAGANA DOUBLE HYPHEN;Pd;0;ON;;;;;N;;;;;
10151 30A1;KATAKANA LETTER SMALL A;Lo;0;L;;;;;N;;;;;
10152 30A2;KATAKANA LETTER A;Lo;0;L;;;;;N;;;;;
10153 30A3;KATAKANA LETTER SMALL I;Lo;0;L;;;;;N;;;;;
10154 30A4;KATAKANA LETTER I;Lo;0;L;;;;;N;;;;;
10155 30A5;KATAKANA LETTER SMALL U;Lo;0;L;;;;;N;;;;;
10156 30A6;KATAKANA LETTER U;Lo;0;L;;;;;N;;;;;
10157 30A7;KATAKANA LETTER SMALL E;Lo;0;L;;;;;N;;;;;
10158 30A8;KATAKANA LETTER E;Lo;0;L;;;;;N;;;;;
10159 30A9;KATAKANA LETTER SMALL O;Lo;0;L;;;;;N;;;;;
10160 30AA;KATAKANA LETTER O;Lo;0;L;;;;;N;;;;;
10161 30AB;KATAKANA LETTER KA;Lo;0;L;;;;;N;;;;;
10162 30AC;KATAKANA LETTER GA;Lo;0;L;30AB 3099;;;;N;;;;;
10163 30AD;KATAKANA LETTER KI;Lo;0;L;;;;;N;;;;;
10164 30AE;KATAKANA LETTER GI;Lo;0;L;30AD 3099;;;;N;;;;;
10165 30AF;KATAKANA LETTER KU;Lo;0;L;;;;;N;;;;;
10166 30B0;KATAKANA LETTER GU;Lo;0;L;30AF 3099;;;;N;;;;;
10167 30B1;KATAKANA LETTER KE;Lo;0;L;;;;;N;;;;;
10168 30B2;KATAKANA LETTER GE;Lo;0;L;30B1 3099;;;;N;;;;;
10169 30B3;KATAKANA LETTER KO;Lo;0;L;;;;;N;;;;;
10170 30B4;KATAKANA LETTER GO;Lo;0;L;30B3 3099;;;;N;;;;;
10171 30B5;KATAKANA LETTER SA;Lo;0;L;;;;;N;;;;;
10172 30B6;KATAKANA LETTER ZA;Lo;0;L;30B5 3099;;;;N;;;;;
10173 30B7;KATAKANA LETTER SI;Lo;0;L;;;;;N;;;;;
10174 30B8;KATAKANA LETTER ZI;Lo;0;L;30B7 3099;;;;N;;;;;
10175 30B9;KATAKANA LETTER SU;Lo;0;L;;;;;N;;;;;
10176 30BA;KATAKANA LETTER ZU;Lo;0;L;30B9 3099;;;;N;;;;;
10177 30BB;KATAKANA LETTER SE;Lo;0;L;;;;;N;;;;;
10178 30BC;KATAKANA LETTER ZE;Lo;0;L;30BB 3099;;;;N;;;;;
10179 30BD;KATAKANA LETTER SO;Lo;0;L;;;;;N;;;;;
10180 30BE;KATAKANA LETTER ZO;Lo;0;L;30BD 3099;;;;N;;;;;
10181 30BF;KATAKANA LETTER TA;Lo;0;L;;;;;N;;;;;
10182 30C0;KATAKANA LETTER DA;Lo;0;L;30BF 3099;;;;N;;;;;
10183 30C1;KATAKANA LETTER TI;Lo;0;L;;;;;N;;;;;
10184 30C2;KATAKANA LETTER DI;Lo;0;L;30C1 3099;;;;N;;;;;
10185 30C3;KATAKANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;;
10186 30C4;KATAKANA LETTER TU;Lo;0;L;;;;;N;;;;;
10187 30C5;KATAKANA LETTER DU;Lo;0;L;30C4 3099;;;;N;;;;;
10188 30C6;KATAKANA LETTER TE;Lo;0;L;;;;;N;;;;;
10189 30C7;KATAKANA LETTER DE;Lo;0;L;30C6 3099;;;;N;;;;;
10190 30C8;KATAKANA LETTER TO;Lo;0;L;;;;;N;;;;;
10191 30C9;KATAKANA LETTER DO;Lo;0;L;30C8 3099;;;;N;;;;;
10192 30CA;KATAKANA LETTER NA;Lo;0;L;;;;;N;;;;;
10193 30CB;KATAKANA LETTER NI;Lo;0;L;;;;;N;;;;;
10194 30CC;KATAKANA LETTER NU;Lo;0;L;;;;;N;;;;;
10195 30CD;KATAKANA LETTER NE;Lo;0;L;;;;;N;;;;;
10196 30CE;KATAKANA LETTER NO;Lo;0;L;;;;;N;;;;;
10197 30CF;KATAKANA LETTER HA;Lo;0;L;;;;;N;;;;;
10198 30D0;KATAKANA LETTER BA;Lo;0;L;30CF 3099;;;;N;;;;;
10199 30D1;KATAKANA LETTER PA;Lo;0;L;30CF 309A;;;;N;;;;;
10200 30D2;KATAKANA LETTER HI;Lo;0;L;;;;;N;;;;;
10201 30D3;KATAKANA LETTER BI;Lo;0;L;30D2 3099;;;;N;;;;;
10202 30D4;KATAKANA LETTER PI;Lo;0;L;30D2 309A;;;;N;;;;;
10203 30D5;KATAKANA LETTER HU;Lo;0;L;;;;;N;;;;;
10204 30D6;KATAKANA LETTER BU;Lo;0;L;30D5 3099;;;;N;;;;;
10205 30D7;KATAKANA LETTER PU;Lo;0;L;30D5 309A;;;;N;;;;;
10206 30D8;KATAKANA LETTER HE;Lo;0;L;;;;;N;;;;;
10207 30D9;KATAKANA LETTER BE;Lo;0;L;30D8 3099;;;;N;;;;;
10208 30DA;KATAKANA LETTER PE;Lo;0;L;30D8 309A;;;;N;;;;;
10209 30DB;KATAKANA LETTER HO;Lo;0;L;;;;;N;;;;;
10210 30DC;KATAKANA LETTER BO;Lo;0;L;30DB 3099;;;;N;;;;;
10211 30DD;KATAKANA LETTER PO;Lo;0;L;30DB 309A;;;;N;;;;;
10212 30DE;KATAKANA LETTER MA;Lo;0;L;;;;;N;;;;;
10213 30DF;KATAKANA LETTER MI;Lo;0;L;;;;;N;;;;;
10214 30E0;KATAKANA LETTER MU;Lo;0;L;;;;;N;;;;;
10215 30E1;KATAKANA LETTER ME;Lo;0;L;;;;;N;;;;;
10216 30E2;KATAKANA LETTER MO;Lo;0;L;;;;;N;;;;;
10217 30E3;KATAKANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;;
10218 30E4;KATAKANA LETTER YA;Lo;0;L;;;;;N;;;;;
10219 30E5;KATAKANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;;
10220 30E6;KATAKANA LETTER YU;Lo;0;L;;;;;N;;;;;
10221 30E7;KATAKANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;;
10222 30E8;KATAKANA LETTER YO;Lo;0;L;;;;;N;;;;;
10223 30E9;KATAKANA LETTER RA;Lo;0;L;;;;;N;;;;;
10224 30EA;KATAKANA LETTER RI;Lo;0;L;;;;;N;;;;;
10225 30EB;KATAKANA LETTER RU;Lo;0;L;;;;;N;;;;;
10226 30EC;KATAKANA LETTER RE;Lo;0;L;;;;;N;;;;;
10227 30ED;KATAKANA LETTER RO;Lo;0;L;;;;;N;;;;;
10228 30EE;KATAKANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;;
10229 30EF;KATAKANA LETTER WA;Lo;0;L;;;;;N;;;;;
10230 30F0;KATAKANA LETTER WI;Lo;0;L;;;;;N;;;;;
10231 30F1;KATAKANA LETTER WE;Lo;0;L;;;;;N;;;;;
10232 30F2;KATAKANA LETTER WO;Lo;0;L;;;;;N;;;;;
10233 30F3;KATAKANA LETTER N;Lo;0;L;;;;;N;;;;;
10234 30F4;KATAKANA LETTER VU;Lo;0;L;30A6 3099;;;;N;;;;;
10235 30F5;KATAKANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;;
10236 30F6;KATAKANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;;
10237 30F7;KATAKANA LETTER VA;Lo;0;L;30EF 3099;;;;N;;;;;
10238 30F8;KATAKANA LETTER VI;Lo;0;L;30F0 3099;;;;N;;;;;
10239 30F9;KATAKANA LETTER VE;Lo;0;L;30F1 3099;;;;N;;;;;
10240 30FA;KATAKANA LETTER VO;Lo;0;L;30F2 3099;;;;N;;;;;
10241 30FB;KATAKANA MIDDLE DOT;Po;0;ON;;;;;N;;;;;
10242 30FC;KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;;;;;N;;;;;
10243 30FD;KATAKANA ITERATION MARK;Lm;0;L;;;;;N;;;;;
10244 30FE;KATAKANA VOICED ITERATION MARK;Lm;0;L;30FD 3099;;;;N;;;;;
10245 30FF;KATAKANA DIGRAPH KOTO;Lo;0;L;<vertical> 30B3 30C8;;;;N;;;;;
10246 3105;BOPOMOFO LETTER B;Lo;0;L;;;;;N;;;;;
10247 3106;BOPOMOFO LETTER P;Lo;0;L;;;;;N;;;;;
10248 3107;BOPOMOFO LETTER M;Lo;0;L;;;;;N;;;;;
10249 3108;BOPOMOFO LETTER F;Lo;0;L;;;;;N;;;;;
10250 3109;BOPOMOFO LETTER D;Lo;0;L;;;;;N;;;;;
10251 310A;BOPOMOFO LETTER T;Lo;0;L;;;;;N;;;;;
10252 310B;BOPOMOFO LETTER N;Lo;0;L;;;;;N;;;;;
10253 310C;BOPOMOFO LETTER L;Lo;0;L;;;;;N;;;;;
10254 310D;BOPOMOFO LETTER G;Lo;0;L;;;;;N;;;;;
10255 310E;BOPOMOFO LETTER K;Lo;0;L;;;;;N;;;;;
10256 310F;BOPOMOFO LETTER H;Lo;0;L;;;;;N;;;;;
10257 3110;BOPOMOFO LETTER J;Lo;0;L;;;;;N;;;;;
10258 3111;BOPOMOFO LETTER Q;Lo;0;L;;;;;N;;;;;
10259 3112;BOPOMOFO LETTER X;Lo;0;L;;;;;N;;;;;
10260 3113;BOPOMOFO LETTER ZH;Lo;0;L;;;;;N;;;;;
10261 3114;BOPOMOFO LETTER CH;Lo;0;L;;;;;N;;;;;
10262 3115;BOPOMOFO LETTER SH;Lo;0;L;;;;;N;;;;;
10263 3116;BOPOMOFO LETTER R;Lo;0;L;;;;;N;;;;;
10264 3117;BOPOMOFO LETTER Z;Lo;0;L;;;;;N;;;;;
10265 3118;BOPOMOFO LETTER C;Lo;0;L;;;;;N;;;;;
10266 3119;BOPOMOFO LETTER S;Lo;0;L;;;;;N;;;;;
10267 311A;BOPOMOFO LETTER A;Lo;0;L;;;;;N;;;;;
10268 311B;BOPOMOFO LETTER O;Lo;0;L;;;;;N;;;;;
10269 311C;BOPOMOFO LETTER E;Lo;0;L;;;;;N;;;;;
10270 311D;BOPOMOFO LETTER EH;Lo;0;L;;;;;N;;;;;
10271 311E;BOPOMOFO LETTER AI;Lo;0;L;;;;;N;;;;;
10272 311F;BOPOMOFO LETTER EI;Lo;0;L;;;;;N;;;;;
10273 3120;BOPOMOFO LETTER AU;Lo;0;L;;;;;N;;;;;
10274 3121;BOPOMOFO LETTER OU;Lo;0;L;;;;;N;;;;;
10275 3122;BOPOMOFO LETTER AN;Lo;0;L;;;;;N;;;;;
10276 3123;BOPOMOFO LETTER EN;Lo;0;L;;;;;N;;;;;
10277 3124;BOPOMOFO LETTER ANG;Lo;0;L;;;;;N;;;;;
10278 3125;BOPOMOFO LETTER ENG;Lo;0;L;;;;;N;;;;;
10279 3126;BOPOMOFO LETTER ER;Lo;0;L;;;;;N;;;;;
10280 3127;BOPOMOFO LETTER I;Lo;0;L;;;;;N;;;;;
10281 3128;BOPOMOFO LETTER U;Lo;0;L;;;;;N;;;;;
10282 3129;BOPOMOFO LETTER IU;Lo;0;L;;;;;N;;;;;
10283 312A;BOPOMOFO LETTER V;Lo;0;L;;;;;N;;;;;
10284 312B;BOPOMOFO LETTER NG;Lo;0;L;;;;;N;;;;;
10285 312C;BOPOMOFO LETTER GN;Lo;0;L;;;;;N;;;;;
10286 312D;BOPOMOFO LETTER IH;Lo;0;L;;;;;N;;;;;
10287 3131;HANGUL LETTER KIYEOK;Lo;0;L;<compat> 1100;;;;N;HANGUL LETTER GIYEOG;;;;
10288 3132;HANGUL LETTER SSANGKIYEOK;Lo;0;L;<compat> 1101;;;;N;HANGUL LETTER SSANG GIYEOG;;;;
10289 3133;HANGUL LETTER KIYEOK-SIOS;Lo;0;L;<compat> 11AA;;;;N;HANGUL LETTER GIYEOG SIOS;;;;
10290 3134;HANGUL LETTER NIEUN;Lo;0;L;<compat> 1102;;;;N;;;;;
10291 3135;HANGUL LETTER NIEUN-CIEUC;Lo;0;L;<compat> 11AC;;;;N;HANGUL LETTER NIEUN JIEUJ;;;;
10292 3136;HANGUL LETTER NIEUN-HIEUH;Lo;0;L;<compat> 11AD;;;;N;HANGUL LETTER NIEUN HIEUH;;;;
10293 3137;HANGUL LETTER TIKEUT;Lo;0;L;<compat> 1103;;;;N;HANGUL LETTER DIGEUD;;;;
10294 3138;HANGUL LETTER SSANGTIKEUT;Lo;0;L;<compat> 1104;;;;N;HANGUL LETTER SSANG DIGEUD;;;;
10295 3139;HANGUL LETTER RIEUL;Lo;0;L;<compat> 1105;;;;N;HANGUL LETTER LIEUL;;;;
10296 313A;HANGUL LETTER RIEUL-KIYEOK;Lo;0;L;<compat> 11B0;;;;N;HANGUL LETTER LIEUL GIYEOG;;;;
10297 313B;HANGUL LETTER RIEUL-MIEUM;Lo;0;L;<compat> 11B1;;;;N;HANGUL LETTER LIEUL MIEUM;;;;
10298 313C;HANGUL LETTER RIEUL-PIEUP;Lo;0;L;<compat> 11B2;;;;N;HANGUL LETTER LIEUL BIEUB;;;;
10299 313D;HANGUL LETTER RIEUL-SIOS;Lo;0;L;<compat> 11B3;;;;N;HANGUL LETTER LIEUL SIOS;;;;
10300 313E;HANGUL LETTER RIEUL-THIEUTH;Lo;0;L;<compat> 11B4;;;;N;HANGUL LETTER LIEUL TIEUT;;;;
10301 313F;HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L;<compat> 11B5;;;;N;HANGUL LETTER LIEUL PIEUP;;;;
10302 3140;HANGUL LETTER RIEUL-HIEUH;Lo;0;L;<compat> 111A;;;;N;HANGUL LETTER LIEUL HIEUH;;;;
10303 3141;HANGUL LETTER MIEUM;Lo;0;L;<compat> 1106;;;;N;;;;;
10304 3142;HANGUL LETTER PIEUP;Lo;0;L;<compat> 1107;;;;N;HANGUL LETTER BIEUB;;;;
10305 3143;HANGUL LETTER SSANGPIEUP;Lo;0;L;<compat> 1108;;;;N;HANGUL LETTER SSANG BIEUB;;;;
10306 3144;HANGUL LETTER PIEUP-SIOS;Lo;0;L;<compat> 1121;;;;N;HANGUL LETTER BIEUB SIOS;;;;
10307 3145;HANGUL LETTER SIOS;Lo;0;L;<compat> 1109;;;;N;;;;;
10308 3146;HANGUL LETTER SSANGSIOS;Lo;0;L;<compat> 110A;;;;N;HANGUL LETTER SSANG SIOS;;;;
10309 3147;HANGUL LETTER IEUNG;Lo;0;L;<compat> 110B;;;;N;;;;;
10310 3148;HANGUL LETTER CIEUC;Lo;0;L;<compat> 110C;;;;N;HANGUL LETTER JIEUJ;;;;
10311 3149;HANGUL LETTER SSANGCIEUC;Lo;0;L;<compat> 110D;;;;N;HANGUL LETTER SSANG JIEUJ;;;;
10312 314A;HANGUL LETTER CHIEUCH;Lo;0;L;<compat> 110E;;;;N;HANGUL LETTER CIEUC;;;;
10313 314B;HANGUL LETTER KHIEUKH;Lo;0;L;<compat> 110F;;;;N;HANGUL LETTER KIYEOK;;;;
10314 314C;HANGUL LETTER THIEUTH;Lo;0;L;<compat> 1110;;;;N;HANGUL LETTER TIEUT;;;;
10315 314D;HANGUL LETTER PHIEUPH;Lo;0;L;<compat> 1111;;;;N;HANGUL LETTER PIEUP;;;;
10316 314E;HANGUL LETTER HIEUH;Lo;0;L;<compat> 1112;;;;N;;;;;
10317 314F;HANGUL LETTER A;Lo;0;L;<compat> 1161;;;;N;;;;;
10318 3150;HANGUL LETTER AE;Lo;0;L;<compat> 1162;;;;N;;;;;
10319 3151;HANGUL LETTER YA;Lo;0;L;<compat> 1163;;;;N;;;;;
10320 3152;HANGUL LETTER YAE;Lo;0;L;<compat> 1164;;;;N;;;;;
10321 3153;HANGUL LETTER EO;Lo;0;L;<compat> 1165;;;;N;;;;;
10322 3154;HANGUL LETTER E;Lo;0;L;<compat> 1166;;;;N;;;;;
10323 3155;HANGUL LETTER YEO;Lo;0;L;<compat> 1167;;;;N;;;;;
10324 3156;HANGUL LETTER YE;Lo;0;L;<compat> 1168;;;;N;;;;;
10325 3157;HANGUL LETTER O;Lo;0;L;<compat> 1169;;;;N;;;;;
10326 3158;HANGUL LETTER WA;Lo;0;L;<compat> 116A;;;;N;;;;;
10327 3159;HANGUL LETTER WAE;Lo;0;L;<compat> 116B;;;;N;;;;;
10328 315A;HANGUL LETTER OE;Lo;0;L;<compat> 116C;;;;N;;;;;
10329 315B;HANGUL LETTER YO;Lo;0;L;<compat> 116D;;;;N;;;;;
10330 315C;HANGUL LETTER U;Lo;0;L;<compat> 116E;;;;N;;;;;
10331 315D;HANGUL LETTER WEO;Lo;0;L;<compat> 116F;;;;N;;;;;
10332 315E;HANGUL LETTER WE;Lo;0;L;<compat> 1170;;;;N;;;;;
10333 315F;HANGUL LETTER WI;Lo;0;L;<compat> 1171;;;;N;;;;;
10334 3160;HANGUL LETTER YU;Lo;0;L;<compat> 1172;;;;N;;;;;
10335 3161;HANGUL LETTER EU;Lo;0;L;<compat> 1173;;;;N;;;;;
10336 3162;HANGUL LETTER YI;Lo;0;L;<compat> 1174;;;;N;;;;;
10337 3163;HANGUL LETTER I;Lo;0;L;<compat> 1175;;;;N;;;;;
10338 3164;HANGUL FILLER;Lo;0;L;<compat> 1160;;;;N;HANGUL CAE OM;;;;
10339 3165;HANGUL LETTER SSANGNIEUN;Lo;0;L;<compat> 1114;;;;N;HANGUL LETTER SSANG NIEUN;;;;
10340 3166;HANGUL LETTER NIEUN-TIKEUT;Lo;0;L;<compat> 1115;;;;N;HANGUL LETTER NIEUN DIGEUD;;;;
10341 3167;HANGUL LETTER NIEUN-SIOS;Lo;0;L;<compat> 11C7;;;;N;HANGUL LETTER NIEUN SIOS;;;;
10342 3168;HANGUL LETTER NIEUN-PANSIOS;Lo;0;L;<compat> 11C8;;;;N;HANGUL LETTER NIEUN BAN CHI EUM;;;;
10343 3169;HANGUL LETTER RIEUL-KIYEOK-SIOS;Lo;0;L;<compat> 11CC;;;;N;HANGUL LETTER LIEUL GIYEOG SIOS;;;;
10344 316A;HANGUL LETTER RIEUL-TIKEUT;Lo;0;L;<compat> 11CE;;;;N;HANGUL LETTER LIEUL DIGEUD;;;;
10345 316B;HANGUL LETTER RIEUL-PIEUP-SIOS;Lo;0;L;<compat> 11D3;;;;N;HANGUL LETTER LIEUL BIEUB SIOS;;;;
10346 316C;HANGUL LETTER RIEUL-PANSIOS;Lo;0;L;<compat> 11D7;;;;N;HANGUL LETTER LIEUL BAN CHI EUM;;;;
10347 316D;HANGUL LETTER RIEUL-YEORINHIEUH;Lo;0;L;<compat> 11D9;;;;N;HANGUL LETTER LIEUL YEOLIN HIEUH;;;;
10348 316E;HANGUL LETTER MIEUM-PIEUP;Lo;0;L;<compat> 111C;;;;N;HANGUL LETTER MIEUM BIEUB;;;;
10349 316F;HANGUL LETTER MIEUM-SIOS;Lo;0;L;<compat> 11DD;;;;N;HANGUL LETTER MIEUM SIOS;;;;
10350 3170;HANGUL LETTER MIEUM-PANSIOS;Lo;0;L;<compat> 11DF;;;;N;HANGUL LETTER BIEUB BAN CHI EUM;;;;
10351 3171;HANGUL LETTER KAPYEOUNMIEUM;Lo;0;L;<compat> 111D;;;;N;HANGUL LETTER MIEUM SUN GYEONG EUM;;;;
10352 3172;HANGUL LETTER PIEUP-KIYEOK;Lo;0;L;<compat> 111E;;;;N;HANGUL LETTER BIEUB GIYEOG;;;;
10353 3173;HANGUL LETTER PIEUP-TIKEUT;Lo;0;L;<compat> 1120;;;;N;HANGUL LETTER BIEUB DIGEUD;;;;
10354 3174;HANGUL LETTER PIEUP-SIOS-KIYEOK;Lo;0;L;<compat> 1122;;;;N;HANGUL LETTER BIEUB SIOS GIYEOG;;;;
10355 3175;HANGUL LETTER PIEUP-SIOS-TIKEUT;Lo;0;L;<compat> 1123;;;;N;HANGUL LETTER BIEUB SIOS DIGEUD;;;;
10356 3176;HANGUL LETTER PIEUP-CIEUC;Lo;0;L;<compat> 1127;;;;N;HANGUL LETTER BIEUB JIEUJ;;;;
10357 3177;HANGUL LETTER PIEUP-THIEUTH;Lo;0;L;<compat> 1129;;;;N;HANGUL LETTER BIEUB TIEUT;;;;
10358 3178;HANGUL LETTER KAPYEOUNPIEUP;Lo;0;L;<compat> 112B;;;;N;HANGUL LETTER BIEUB SUN GYEONG EUM;;;;
10359 3179;HANGUL LETTER KAPYEOUNSSANGPIEUP;Lo;0;L;<compat> 112C;;;;N;HANGUL LETTER SSANG BIEUB SUN GYEONG EUM;;;;
10360 317A;HANGUL LETTER SIOS-KIYEOK;Lo;0;L;<compat> 112D;;;;N;HANGUL LETTER SIOS GIYEOG;;;;
10361 317B;HANGUL LETTER SIOS-NIEUN;Lo;0;L;<compat> 112E;;;;N;HANGUL LETTER SIOS NIEUN;;;;
10362 317C;HANGUL LETTER SIOS-TIKEUT;Lo;0;L;<compat> 112F;;;;N;HANGUL LETTER SIOS DIGEUD;;;;
10363 317D;HANGUL LETTER SIOS-PIEUP;Lo;0;L;<compat> 1132;;;;N;HANGUL LETTER SIOS BIEUB;;;;
10364 317E;HANGUL LETTER SIOS-CIEUC;Lo;0;L;<compat> 1136;;;;N;HANGUL LETTER SIOS JIEUJ;;;;
10365 317F;HANGUL LETTER PANSIOS;Lo;0;L;<compat> 1140;;;;N;HANGUL LETTER BAN CHI EUM;;;;
10366 3180;HANGUL LETTER SSANGIEUNG;Lo;0;L;<compat> 1147;;;;N;HANGUL LETTER SSANG IEUNG;;;;
10367 3181;HANGUL LETTER YESIEUNG;Lo;0;L;<compat> 114C;;;;N;HANGUL LETTER NGIEUNG;;;;
10368 3182;HANGUL LETTER YESIEUNG-SIOS;Lo;0;L;<compat> 11F1;;;;N;HANGUL LETTER NGIEUNG SIOS;;;;
10369 3183;HANGUL LETTER YESIEUNG-PANSIOS;Lo;0;L;<compat> 11F2;;;;N;HANGUL LETTER NGIEUNG BAN CHI EUM;;;;
10370 3184;HANGUL LETTER KAPYEOUNPHIEUPH;Lo;0;L;<compat> 1157;;;;N;HANGUL LETTER PIEUP SUN GYEONG EUM;;;;
10371 3185;HANGUL LETTER SSANGHIEUH;Lo;0;L;<compat> 1158;;;;N;HANGUL LETTER SSANG HIEUH;;;;
10372 3186;HANGUL LETTER YEORINHIEUH;Lo;0;L;<compat> 1159;;;;N;HANGUL LETTER YEOLIN HIEUH;;;;
10373 3187;HANGUL LETTER YO-YA;Lo;0;L;<compat> 1184;;;;N;HANGUL LETTER YOYA;;;;
10374 3188;HANGUL LETTER YO-YAE;Lo;0;L;<compat> 1185;;;;N;HANGUL LETTER YOYAE;;;;
10375 3189;HANGUL LETTER YO-I;Lo;0;L;<compat> 1188;;;;N;HANGUL LETTER YOI;;;;
10376 318A;HANGUL LETTER YU-YEO;Lo;0;L;<compat> 1191;;;;N;HANGUL LETTER YUYEO;;;;
10377 318B;HANGUL LETTER YU-YE;Lo;0;L;<compat> 1192;;;;N;HANGUL LETTER YUYE;;;;
10378 318C;HANGUL LETTER YU-I;Lo;0;L;<compat> 1194;;;;N;HANGUL LETTER YUI;;;;
10379 318D;HANGUL LETTER ARAEA;Lo;0;L;<compat> 119E;;;;N;HANGUL LETTER ALAE A;;;;
10380 318E;HANGUL LETTER ARAEAE;Lo;0;L;<compat> 11A1;;;;N;HANGUL LETTER ALAE AE;;;;
10381 3190;IDEOGRAPHIC ANNOTATION LINKING MARK;So;0;L;;;;;N;KANBUN TATETEN;Kanbun Tateten;;;
10382 3191;IDEOGRAPHIC ANNOTATION REVERSE MARK;So;0;L;;;;;N;KAERITEN RE;Kaeriten;;;
10383 3192;IDEOGRAPHIC ANNOTATION ONE MARK;No;0;L;<super> 4E00;;;1;N;KAERITEN ITI;Kaeriten;;;
10384 3193;IDEOGRAPHIC ANNOTATION TWO MARK;No;0;L;<super> 4E8C;;;2;N;KAERITEN NI;Kaeriten;;;
10385 3194;IDEOGRAPHIC ANNOTATION THREE MARK;No;0;L;<super> 4E09;;;3;N;KAERITEN SAN;Kaeriten;;;
10386 3195;IDEOGRAPHIC ANNOTATION FOUR MARK;No;0;L;<super> 56DB;;;4;N;KAERITEN SI;Kaeriten;;;
10387 3196;IDEOGRAPHIC ANNOTATION TOP MARK;So;0;L;<super> 4E0A;;;;N;KAERITEN ZYOU;Kaeriten;;;
10388 3197;IDEOGRAPHIC ANNOTATION MIDDLE MARK;So;0;L;<super> 4E2D;;;;N;KAERITEN TYUU;Kaeriten;;;
10389 3198;IDEOGRAPHIC ANNOTATION BOTTOM MARK;So;0;L;<super> 4E0B;;;;N;KAERITEN GE;Kaeriten;;;
10390 3199;IDEOGRAPHIC ANNOTATION FIRST MARK;So;0;L;<super> 7532;;;;N;KAERITEN KOU;Kaeriten;;;
10391 319A;IDEOGRAPHIC ANNOTATION SECOND MARK;So;0;L;<super> 4E59;;;;N;KAERITEN OTU;Kaeriten;;;
10392 319B;IDEOGRAPHIC ANNOTATION THIRD MARK;So;0;L;<super> 4E19;;;;N;KAERITEN HEI;Kaeriten;;;
10393 319C;IDEOGRAPHIC ANNOTATION FOURTH MARK;So;0;L;<super> 4E01;;;;N;KAERITEN TEI;Kaeriten;;;
10394 319D;IDEOGRAPHIC ANNOTATION HEAVEN MARK;So;0;L;<super> 5929;;;;N;KAERITEN TEN;Kaeriten;;;
10395 319E;IDEOGRAPHIC ANNOTATION EARTH MARK;So;0;L;<super> 5730;;;;N;KAERITEN TI;Kaeriten;;;
10396 319F;IDEOGRAPHIC ANNOTATION MAN MARK;So;0;L;<super> 4EBA;;;;N;KAERITEN ZIN;Kaeriten;;;
10397 31A0;BOPOMOFO LETTER BU;Lo;0;L;;;;;N;;;;;
10398 31A1;BOPOMOFO LETTER ZI;Lo;0;L;;;;;N;;;;;
10399 31A2;BOPOMOFO LETTER JI;Lo;0;L;;;;;N;;;;;
10400 31A3;BOPOMOFO LETTER GU;Lo;0;L;;;;;N;;;;;
10401 31A4;BOPOMOFO LETTER EE;Lo;0;L;;;;;N;;;;;
10402 31A5;BOPOMOFO LETTER ENN;Lo;0;L;;;;;N;;;;;
10403 31A6;BOPOMOFO LETTER OO;Lo;0;L;;;;;N;;;;;
10404 31A7;BOPOMOFO LETTER ONN;Lo;0;L;;;;;N;;;;;
10405 31A8;BOPOMOFO LETTER IR;Lo;0;L;;;;;N;;;;;
10406 31A9;BOPOMOFO LETTER ANN;Lo;0;L;;;;;N;;;;;
10407 31AA;BOPOMOFO LETTER INN;Lo;0;L;;;;;N;;;;;
10408 31AB;BOPOMOFO LETTER UNN;Lo;0;L;;;;;N;;;;;
10409 31AC;BOPOMOFO LETTER IM;Lo;0;L;;;;;N;;;;;
10410 31AD;BOPOMOFO LETTER NGG;Lo;0;L;;;;;N;;;;;
10411 31AE;BOPOMOFO LETTER AINN;Lo;0;L;;;;;N;;;;;
10412 31AF;BOPOMOFO LETTER AUNN;Lo;0;L;;;;;N;;;;;
10413 31B0;BOPOMOFO LETTER AM;Lo;0;L;;;;;N;;;;;
10414 31B1;BOPOMOFO LETTER OM;Lo;0;L;;;;;N;;;;;
10415 31B2;BOPOMOFO LETTER ONG;Lo;0;L;;;;;N;;;;;
10416 31B3;BOPOMOFO LETTER INNN;Lo;0;L;;;;;N;;;;;
10417 31B4;BOPOMOFO FINAL LETTER P;Lo;0;L;;;;;N;;;;;
10418 31B5;BOPOMOFO FINAL LETTER T;Lo;0;L;;;;;N;;;;;
10419 31B6;BOPOMOFO FINAL LETTER K;Lo;0;L;;;;;N;;;;;
10420 31B7;BOPOMOFO FINAL LETTER H;Lo;0;L;;;;;N;;;;;
10421 31C0;CJK STROKE T;So;0;ON;;;;;N;;;;;
10422 31C1;CJK STROKE WG;So;0;ON;;;;;N;;;;;
10423 31C2;CJK STROKE XG;So;0;ON;;;;;N;;;;;
10424 31C3;CJK STROKE BXG;So;0;ON;;;;;N;;;;;
10425 31C4;CJK STROKE SW;So;0;ON;;;;;N;;;;;
10426 31C5;CJK STROKE HZZ;So;0;ON;;;;;N;;;;;
10427 31C6;CJK STROKE HZG;So;0;ON;;;;;N;;;;;
10428 31C7;CJK STROKE HP;So;0;ON;;;;;N;;;;;
10429 31C8;CJK STROKE HZWG;So;0;ON;;;;;N;;;;;
10430 31C9;CJK STROKE SZWG;So;0;ON;;;;;N;;;;;
10431 31CA;CJK STROKE HZT;So;0;ON;;;;;N;;;;;
10432 31CB;CJK STROKE HZZP;So;0;ON;;;;;N;;;;;
10433 31CC;CJK STROKE HPWG;So;0;ON;;;;;N;;;;;
10434 31CD;CJK STROKE HZW;So;0;ON;;;;;N;;;;;
10435 31CE;CJK STROKE HZZZ;So;0;ON;;;;;N;;;;;
10436 31CF;CJK STROKE N;So;0;ON;;;;;N;;;;;
10437 31D0;CJK STROKE H;So;0;ON;;;;;N;;;;;
10438 31D1;CJK STROKE S;So;0;ON;;;;;N;;;;;
10439 31D2;CJK STROKE P;So;0;ON;;;;;N;;;;;
10440 31D3;CJK STROKE SP;So;0;ON;;;;;N;;;;;
10441 31D4;CJK STROKE D;So;0;ON;;;;;N;;;;;
10442 31D5;CJK STROKE HZ;So;0;ON;;;;;N;;;;;
10443 31D6;CJK STROKE HG;So;0;ON;;;;;N;;;;;
10444 31D7;CJK STROKE SZ;So;0;ON;;;;;N;;;;;
10445 31D8;CJK STROKE SWZ;So;0;ON;;;;;N;;;;;
10446 31D9;CJK STROKE ST;So;0;ON;;;;;N;;;;;
10447 31DA;CJK STROKE SG;So;0;ON;;;;;N;;;;;
10448 31DB;CJK STROKE PD;So;0;ON;;;;;N;;;;;
10449 31DC;CJK STROKE PZ;So;0;ON;;;;;N;;;;;
10450 31DD;CJK STROKE TN;So;0;ON;;;;;N;;;;;
10451 31DE;CJK STROKE SZZ;So;0;ON;;;;;N;;;;;
10452 31DF;CJK STROKE SWG;So;0;ON;;;;;N;;;;;
10453 31E0;CJK STROKE HXWG;So;0;ON;;;;;N;;;;;
10454 31E1;CJK STROKE HZZZG;So;0;ON;;;;;N;;;;;
10455 31E2;CJK STROKE PG;So;0;ON;;;;;N;;;;;
10456 31E3;CJK STROKE Q;So;0;ON;;;;;N;;;;;
10457 31F0;KATAKANA LETTER SMALL KU;Lo;0;L;;;;;N;;;;;
10458 31F1;KATAKANA LETTER SMALL SI;Lo;0;L;;;;;N;;;;;
10459 31F2;KATAKANA LETTER SMALL SU;Lo;0;L;;;;;N;;;;;
10460 31F3;KATAKANA LETTER SMALL TO;Lo;0;L;;;;;N;;;;;
10461 31F4;KATAKANA LETTER SMALL NU;Lo;0;L;;;;;N;;;;;
10462 31F5;KATAKANA LETTER SMALL HA;Lo;0;L;;;;;N;;;;;
10463 31F6;KATAKANA LETTER SMALL HI;Lo;0;L;;;;;N;;;;;
10464 31F7;KATAKANA LETTER SMALL HU;Lo;0;L;;;;;N;;;;;
10465 31F8;KATAKANA LETTER SMALL HE;Lo;0;L;;;;;N;;;;;
10466 31F9;KATAKANA LETTER SMALL HO;Lo;0;L;;;;;N;;;;;
10467 31FA;KATAKANA LETTER SMALL MU;Lo;0;L;;;;;N;;;;;
10468 31FB;KATAKANA LETTER SMALL RA;Lo;0;L;;;;;N;;;;;
10469 31FC;KATAKANA LETTER SMALL RI;Lo;0;L;;;;;N;;;;;
10470 31FD;KATAKANA LETTER SMALL RU;Lo;0;L;;;;;N;;;;;
10471 31FE;KATAKANA LETTER SMALL RE;Lo;0;L;;;;;N;;;;;
10472 31FF;KATAKANA LETTER SMALL RO;Lo;0;L;;;;;N;;;;;
10473 3200;PARENTHESIZED HANGUL KIYEOK;So;0;L;<compat> 0028 1100 0029;;;;N;PARENTHESIZED HANGUL GIYEOG;;;;
10474 3201;PARENTHESIZED HANGUL NIEUN;So;0;L;<compat> 0028 1102 0029;;;;N;;;;;
10475 3202;PARENTHESIZED HANGUL TIKEUT;So;0;L;<compat> 0028 1103 0029;;;;N;PARENTHESIZED HANGUL DIGEUD;;;;
10476 3203;PARENTHESIZED HANGUL RIEUL;So;0;L;<compat> 0028 1105 0029;;;;N;PARENTHESIZED HANGUL LIEUL;;;;
10477 3204;PARENTHESIZED HANGUL MIEUM;So;0;L;<compat> 0028 1106 0029;;;;N;;;;;
10478 3205;PARENTHESIZED HANGUL PIEUP;So;0;L;<compat> 0028 1107 0029;;;;N;PARENTHESIZED HANGUL BIEUB;;;;
10479 3206;PARENTHESIZED HANGUL SIOS;So;0;L;<compat> 0028 1109 0029;;;;N;;;;;
10480 3207;PARENTHESIZED HANGUL IEUNG;So;0;L;<compat> 0028 110B 0029;;;;N;;;;;
10481 3208;PARENTHESIZED HANGUL CIEUC;So;0;L;<compat> 0028 110C 0029;;;;N;PARENTHESIZED HANGUL JIEUJ;;;;
10482 3209;PARENTHESIZED HANGUL CHIEUCH;So;0;L;<compat> 0028 110E 0029;;;;N;PARENTHESIZED HANGUL CIEUC;;;;
10483 320A;PARENTHESIZED HANGUL KHIEUKH;So;0;L;<compat> 0028 110F 0029;;;;N;PARENTHESIZED HANGUL KIYEOK;;;;
10484 320B;PARENTHESIZED HANGUL THIEUTH;So;0;L;<compat> 0028 1110 0029;;;;N;PARENTHESIZED HANGUL TIEUT;;;;
10485 320C;PARENTHESIZED HANGUL PHIEUPH;So;0;L;<compat> 0028 1111 0029;;;;N;PARENTHESIZED HANGUL PIEUP;;;;
10486 320D;PARENTHESIZED HANGUL HIEUH;So;0;L;<compat> 0028 1112 0029;;;;N;;;;;
10487 320E;PARENTHESIZED HANGUL KIYEOK A;So;0;L;<compat> 0028 1100 1161 0029;;;;N;PARENTHESIZED HANGUL GA;;;;
10488 320F;PARENTHESIZED HANGUL NIEUN A;So;0;L;<compat> 0028 1102 1161 0029;;;;N;PARENTHESIZED HANGUL NA;;;;
10489 3210;PARENTHESIZED HANGUL TIKEUT A;So;0;L;<compat> 0028 1103 1161 0029;;;;N;PARENTHESIZED HANGUL DA;;;;
10490 3211;PARENTHESIZED HANGUL RIEUL A;So;0;L;<compat> 0028 1105 1161 0029;;;;N;PARENTHESIZED HANGUL LA;;;;
10491 3212;PARENTHESIZED HANGUL MIEUM A;So;0;L;<compat> 0028 1106 1161 0029;;;;N;PARENTHESIZED HANGUL MA;;;;
10492 3213;PARENTHESIZED HANGUL PIEUP A;So;0;L;<compat> 0028 1107 1161 0029;;;;N;PARENTHESIZED HANGUL BA;;;;
10493 3214;PARENTHESIZED HANGUL SIOS A;So;0;L;<compat> 0028 1109 1161 0029;;;;N;PARENTHESIZED HANGUL SA;;;;
10494 3215;PARENTHESIZED HANGUL IEUNG A;So;0;L;<compat> 0028 110B 1161 0029;;;;N;PARENTHESIZED HANGUL A;;;;
10495 3216;PARENTHESIZED HANGUL CIEUC A;So;0;L;<compat> 0028 110C 1161 0029;;;;N;PARENTHESIZED HANGUL JA;;;;
10496 3217;PARENTHESIZED HANGUL CHIEUCH A;So;0;L;<compat> 0028 110E 1161 0029;;;;N;PARENTHESIZED HANGUL CA;;;;
10497 3218;PARENTHESIZED HANGUL KHIEUKH A;So;0;L;<compat> 0028 110F 1161 0029;;;;N;PARENTHESIZED HANGUL KA;;;;
10498 3219;PARENTHESIZED HANGUL THIEUTH A;So;0;L;<compat> 0028 1110 1161 0029;;;;N;PARENTHESIZED HANGUL TA;;;;
10499 321A;PARENTHESIZED HANGUL PHIEUPH A;So;0;L;<compat> 0028 1111 1161 0029;;;;N;PARENTHESIZED HANGUL PA;;;;
10500 321B;PARENTHESIZED HANGUL HIEUH A;So;0;L;<compat> 0028 1112 1161 0029;;;;N;PARENTHESIZED HANGUL HA;;;;
10501 321C;PARENTHESIZED HANGUL CIEUC U;So;0;L;<compat> 0028 110C 116E 0029;;;;N;PARENTHESIZED HANGUL JU;;;;
10502 321D;PARENTHESIZED KOREAN CHARACTER OJEON;So;0;ON;<compat> 0028 110B 1169 110C 1165 11AB 0029;;;;N;;;;;
10503 321E;PARENTHESIZED KOREAN CHARACTER O HU;So;0;ON;<compat> 0028 110B 1169 1112 116E 0029;;;;N;;;;;
10504 3220;PARENTHESIZED IDEOGRAPH ONE;No;0;L;<compat> 0028 4E00 0029;;;1;N;;;;;
10505 3221;PARENTHESIZED IDEOGRAPH TWO;No;0;L;<compat> 0028 4E8C 0029;;;2;N;;;;;
10506 3222;PARENTHESIZED IDEOGRAPH THREE;No;0;L;<compat> 0028 4E09 0029;;;3;N;;;;;
10507 3223;PARENTHESIZED IDEOGRAPH FOUR;No;0;L;<compat> 0028 56DB 0029;;;4;N;;;;;
10508 3224;PARENTHESIZED IDEOGRAPH FIVE;No;0;L;<compat> 0028 4E94 0029;;;5;N;;;;;
10509 3225;PARENTHESIZED IDEOGRAPH SIX;No;0;L;<compat> 0028 516D 0029;;;6;N;;;;;
10510 3226;PARENTHESIZED IDEOGRAPH SEVEN;No;0;L;<compat> 0028 4E03 0029;;;7;N;;;;;
10511 3227;PARENTHESIZED IDEOGRAPH EIGHT;No;0;L;<compat> 0028 516B 0029;;;8;N;;;;;
10512 3228;PARENTHESIZED IDEOGRAPH NINE;No;0;L;<compat> 0028 4E5D 0029;;;9;N;;;;;
10513 3229;PARENTHESIZED IDEOGRAPH TEN;No;0;L;<compat> 0028 5341 0029;;;10;N;;;;;
10514 322A;PARENTHESIZED IDEOGRAPH MOON;So;0;L;<compat> 0028 6708 0029;;;;N;;;;;
10515 322B;PARENTHESIZED IDEOGRAPH FIRE;So;0;L;<compat> 0028 706B 0029;;;;N;;;;;
10516 322C;PARENTHESIZED IDEOGRAPH WATER;So;0;L;<compat> 0028 6C34 0029;;;;N;;;;;
10517 322D;PARENTHESIZED IDEOGRAPH WOOD;So;0;L;<compat> 0028 6728 0029;;;;N;;;;;
10518 322E;PARENTHESIZED IDEOGRAPH METAL;So;0;L;<compat> 0028 91D1 0029;;;;N;;;;;
10519 322F;PARENTHESIZED IDEOGRAPH EARTH;So;0;L;<compat> 0028 571F 0029;;;;N;;;;;
10520 3230;PARENTHESIZED IDEOGRAPH SUN;So;0;L;<compat> 0028 65E5 0029;;;;N;;;;;
10521 3231;PARENTHESIZED IDEOGRAPH STOCK;So;0;L;<compat> 0028 682A 0029;;;;N;;;;;
10522 3232;PARENTHESIZED IDEOGRAPH HAVE;So;0;L;<compat> 0028 6709 0029;;;;N;;;;;
10523 3233;PARENTHESIZED IDEOGRAPH SOCIETY;So;0;L;<compat> 0028 793E 0029;;;;N;;;;;
10524 3234;PARENTHESIZED IDEOGRAPH NAME;So;0;L;<compat> 0028 540D 0029;;;;N;;;;;
10525 3235;PARENTHESIZED IDEOGRAPH SPECIAL;So;0;L;<compat> 0028 7279 0029;;;;N;;;;;
10526 3236;PARENTHESIZED IDEOGRAPH FINANCIAL;So;0;L;<compat> 0028 8CA1 0029;;;;N;;;;;
10527 3237;PARENTHESIZED IDEOGRAPH CONGRATULATION;So;0;L;<compat> 0028 795D 0029;;;;N;;;;;
10528 3238;PARENTHESIZED IDEOGRAPH LABOR;So;0;L;<compat> 0028 52B4 0029;;;;N;;;;;
10529 3239;PARENTHESIZED IDEOGRAPH REPRESENT;So;0;L;<compat> 0028 4EE3 0029;;;;N;;;;;
10530 323A;PARENTHESIZED IDEOGRAPH CALL;So;0;L;<compat> 0028 547C 0029;;;;N;;;;;
10531 323B;PARENTHESIZED IDEOGRAPH STUDY;So;0;L;<compat> 0028 5B66 0029;;;;N;;;;;
10532 323C;PARENTHESIZED IDEOGRAPH SUPERVISE;So;0;L;<compat> 0028 76E3 0029;;;;N;;;;;
10533 323D;PARENTHESIZED IDEOGRAPH ENTERPRISE;So;0;L;<compat> 0028 4F01 0029;;;;N;;;;;
10534 323E;PARENTHESIZED IDEOGRAPH RESOURCE;So;0;L;<compat> 0028 8CC7 0029;;;;N;;;;;
10535 323F;PARENTHESIZED IDEOGRAPH ALLIANCE;So;0;L;<compat> 0028 5354 0029;;;;N;;;;;
10536 3240;PARENTHESIZED IDEOGRAPH FESTIVAL;So;0;L;<compat> 0028 796D 0029;;;;N;;;;;
10537 3241;PARENTHESIZED IDEOGRAPH REST;So;0;L;<compat> 0028 4F11 0029;;;;N;;;;;
10538 3242;PARENTHESIZED IDEOGRAPH SELF;So;0;L;<compat> 0028 81EA 0029;;;;N;;;;;
10539 3243;PARENTHESIZED IDEOGRAPH REACH;So;0;L;<compat> 0028 81F3 0029;;;;N;;;;;
10540 3250;PARTNERSHIP SIGN;So;0;ON;<square> 0050 0054 0045;;;;N;;;;;
10541 3251;CIRCLED NUMBER TWENTY ONE;No;0;ON;<circle> 0032 0031;;;21;N;;;;;
10542 3252;CIRCLED NUMBER TWENTY TWO;No;0;ON;<circle> 0032 0032;;;22;N;;;;;
10543 3253;CIRCLED NUMBER TWENTY THREE;No;0;ON;<circle> 0032 0033;;;23;N;;;;;
10544 3254;CIRCLED NUMBER TWENTY FOUR;No;0;ON;<circle> 0032 0034;;;24;N;;;;;
10545 3255;CIRCLED NUMBER TWENTY FIVE;No;0;ON;<circle> 0032 0035;;;25;N;;;;;
10546 3256;CIRCLED NUMBER TWENTY SIX;No;0;ON;<circle> 0032 0036;;;26;N;;;;;
10547 3257;CIRCLED NUMBER TWENTY SEVEN;No;0;ON;<circle> 0032 0037;;;27;N;;;;;
10548 3258;CIRCLED NUMBER TWENTY EIGHT;No;0;ON;<circle> 0032 0038;;;28;N;;;;;
10549 3259;CIRCLED NUMBER TWENTY NINE;No;0;ON;<circle> 0032 0039;;;29;N;;;;;
10550 325A;CIRCLED NUMBER THIRTY;No;0;ON;<circle> 0033 0030;;;30;N;;;;;
10551 325B;CIRCLED NUMBER THIRTY ONE;No;0;ON;<circle> 0033 0031;;;31;N;;;;;
10552 325C;CIRCLED NUMBER THIRTY TWO;No;0;ON;<circle> 0033 0032;;;32;N;;;;;
10553 325D;CIRCLED NUMBER THIRTY THREE;No;0;ON;<circle> 0033 0033;;;33;N;;;;;
10554 325E;CIRCLED NUMBER THIRTY FOUR;No;0;ON;<circle> 0033 0034;;;34;N;;;;;
10555 325F;CIRCLED NUMBER THIRTY FIVE;No;0;ON;<circle> 0033 0035;;;35;N;;;;;
10556 3260;CIRCLED HANGUL KIYEOK;So;0;L;<circle> 1100;;;;N;CIRCLED HANGUL GIYEOG;;;;
10557 3261;CIRCLED HANGUL NIEUN;So;0;L;<circle> 1102;;;;N;;;;;
10558 3262;CIRCLED HANGUL TIKEUT;So;0;L;<circle> 1103;;;;N;CIRCLED HANGUL DIGEUD;;;;
10559 3263;CIRCLED HANGUL RIEUL;So;0;L;<circle> 1105;;;;N;CIRCLED HANGUL LIEUL;;;;
10560 3264;CIRCLED HANGUL MIEUM;So;0;L;<circle> 1106;;;;N;;;;;
10561 3265;CIRCLED HANGUL PIEUP;So;0;L;<circle> 1107;;;;N;CIRCLED HANGUL BIEUB;;;;
10562 3266;CIRCLED HANGUL SIOS;So;0;L;<circle> 1109;;;;N;;;;;
10563 3267;CIRCLED HANGUL IEUNG;So;0;L;<circle> 110B;;;;N;;;;;
10564 3268;CIRCLED HANGUL CIEUC;So;0;L;<circle> 110C;;;;N;CIRCLED HANGUL JIEUJ;;;;
10565 3269;CIRCLED HANGUL CHIEUCH;So;0;L;<circle> 110E;;;;N;CIRCLED HANGUL CIEUC;;;;
10566 326A;CIRCLED HANGUL KHIEUKH;So;0;L;<circle> 110F;;;;N;CIRCLED HANGUL KIYEOK;;;;
10567 326B;CIRCLED HANGUL THIEUTH;So;0;L;<circle> 1110;;;;N;CIRCLED HANGUL TIEUT;;;;
10568 326C;CIRCLED HANGUL PHIEUPH;So;0;L;<circle> 1111;;;;N;CIRCLED HANGUL PIEUP;;;;
10569 326D;CIRCLED HANGUL HIEUH;So;0;L;<circle> 1112;;;;N;;;;;
10570 326E;CIRCLED HANGUL KIYEOK A;So;0;L;<circle> 1100 1161;;;;N;CIRCLED HANGUL GA;;;;
10571 326F;CIRCLED HANGUL NIEUN A;So;0;L;<circle> 1102 1161;;;;N;CIRCLED HANGUL NA;;;;
10572 3270;CIRCLED HANGUL TIKEUT A;So;0;L;<circle> 1103 1161;;;;N;CIRCLED HANGUL DA;;;;
10573 3271;CIRCLED HANGUL RIEUL A;So;0;L;<circle> 1105 1161;;;;N;CIRCLED HANGUL LA;;;;
10574 3272;CIRCLED HANGUL MIEUM A;So;0;L;<circle> 1106 1161;;;;N;CIRCLED HANGUL MA;;;;
10575 3273;CIRCLED HANGUL PIEUP A;So;0;L;<circle> 1107 1161;;;;N;CIRCLED HANGUL BA;;;;
10576 3274;CIRCLED HANGUL SIOS A;So;0;L;<circle> 1109 1161;;;;N;CIRCLED HANGUL SA;;;;
10577 3275;CIRCLED HANGUL IEUNG A;So;0;L;<circle> 110B 1161;;;;N;CIRCLED HANGUL A;;;;
10578 3276;CIRCLED HANGUL CIEUC A;So;0;L;<circle> 110C 1161;;;;N;CIRCLED HANGUL JA;;;;
10579 3277;CIRCLED HANGUL CHIEUCH A;So;0;L;<circle> 110E 1161;;;;N;CIRCLED HANGUL CA;;;;
10580 3278;CIRCLED HANGUL KHIEUKH A;So;0;L;<circle> 110F 1161;;;;N;CIRCLED HANGUL KA;;;;
10581 3279;CIRCLED HANGUL THIEUTH A;So;0;L;<circle> 1110 1161;;;;N;CIRCLED HANGUL TA;;;;
10582 327A;CIRCLED HANGUL PHIEUPH A;So;0;L;<circle> 1111 1161;;;;N;CIRCLED HANGUL PA;;;;
10583 327B;CIRCLED HANGUL HIEUH A;So;0;L;<circle> 1112 1161;;;;N;CIRCLED HANGUL HA;;;;
10584 327C;CIRCLED KOREAN CHARACTER CHAMKO;So;0;ON;<circle> 110E 1161 11B7 1100 1169;;;;N;;;;;
10585 327D;CIRCLED KOREAN CHARACTER JUEUI;So;0;ON;<circle> 110C 116E 110B 1174;;;;N;;;;;
10586 327E;CIRCLED HANGUL IEUNG U;So;0;ON;<circle> 110B 116E;;;;N;;;;;
10587 327F;KOREAN STANDARD SYMBOL;So;0;L;;;;;N;;;;;
10588 3280;CIRCLED IDEOGRAPH ONE;No;0;L;<circle> 4E00;;;1;N;;;;;
10589 3281;CIRCLED IDEOGRAPH TWO;No;0;L;<circle> 4E8C;;;2;N;;;;;
10590 3282;CIRCLED IDEOGRAPH THREE;No;0;L;<circle> 4E09;;;3;N;;;;;
10591 3283;CIRCLED IDEOGRAPH FOUR;No;0;L;<circle> 56DB;;;4;N;;;;;
10592 3284;CIRCLED IDEOGRAPH FIVE;No;0;L;<circle> 4E94;;;5;N;;;;;
10593 3285;CIRCLED IDEOGRAPH SIX;No;0;L;<circle> 516D;;;6;N;;;;;
10594 3286;CIRCLED IDEOGRAPH SEVEN;No;0;L;<circle> 4E03;;;7;N;;;;;
10595 3287;CIRCLED IDEOGRAPH EIGHT;No;0;L;<circle> 516B;;;8;N;;;;;
10596 3288;CIRCLED IDEOGRAPH NINE;No;0;L;<circle> 4E5D;;;9;N;;;;;
10597 3289;CIRCLED IDEOGRAPH TEN;No;0;L;<circle> 5341;;;10;N;;;;;
10598 328A;CIRCLED IDEOGRAPH MOON;So;0;L;<circle> 6708;;;;N;;;;;
10599 328B;CIRCLED IDEOGRAPH FIRE;So;0;L;<circle> 706B;;;;N;;;;;
10600 328C;CIRCLED IDEOGRAPH WATER;So;0;L;<circle> 6C34;;;;N;;;;;
10601 328D;CIRCLED IDEOGRAPH WOOD;So;0;L;<circle> 6728;;;;N;;;;;
10602 328E;CIRCLED IDEOGRAPH METAL;So;0;L;<circle> 91D1;;;;N;;;;;
10603 328F;CIRCLED IDEOGRAPH EARTH;So;0;L;<circle> 571F;;;;N;;;;;
10604 3290;CIRCLED IDEOGRAPH SUN;So;0;L;<circle> 65E5;;;;N;;;;;
10605 3291;CIRCLED IDEOGRAPH STOCK;So;0;L;<circle> 682A;;;;N;;;;;
10606 3292;CIRCLED IDEOGRAPH HAVE;So;0;L;<circle> 6709;;;;N;;;;;
10607 3293;CIRCLED IDEOGRAPH SOCIETY;So;0;L;<circle> 793E;;;;N;;;;;
10608 3294;CIRCLED IDEOGRAPH NAME;So;0;L;<circle> 540D;;;;N;;;;;
10609 3295;CIRCLED IDEOGRAPH SPECIAL;So;0;L;<circle> 7279;;;;N;;;;;
10610 3296;CIRCLED IDEOGRAPH FINANCIAL;So;0;L;<circle> 8CA1;;;;N;;;;;
10611 3297;CIRCLED IDEOGRAPH CONGRATULATION;So;0;L;<circle> 795D;;;;N;;;;;
10612 3298;CIRCLED IDEOGRAPH LABOR;So;0;L;<circle> 52B4;;;;N;;;;;
10613 3299;CIRCLED IDEOGRAPH SECRET;So;0;L;<circle> 79D8;;;;N;;;;;
10614 329A;CIRCLED IDEOGRAPH MALE;So;0;L;<circle> 7537;;;;N;;;;;
10615 329B;CIRCLED IDEOGRAPH FEMALE;So;0;L;<circle> 5973;;;;N;;;;;
10616 329C;CIRCLED IDEOGRAPH SUITABLE;So;0;L;<circle> 9069;;;;N;;;;;
10617 329D;CIRCLED IDEOGRAPH EXCELLENT;So;0;L;<circle> 512A;;;;N;;;;;
10618 329E;CIRCLED IDEOGRAPH PRINT;So;0;L;<circle> 5370;;;;N;;;;;
10619 329F;CIRCLED IDEOGRAPH ATTENTION;So;0;L;<circle> 6CE8;;;;N;;;;;
10620 32A0;CIRCLED IDEOGRAPH ITEM;So;0;L;<circle> 9805;;;;N;;;;;
10621 32A1;CIRCLED IDEOGRAPH REST;So;0;L;<circle> 4F11;;;;N;;;;;
10622 32A2;CIRCLED IDEOGRAPH COPY;So;0;L;<circle> 5199;;;;N;;;;;
10623 32A3;CIRCLED IDEOGRAPH CORRECT;So;0;L;<circle> 6B63;;;;N;;;;;
10624 32A4;CIRCLED IDEOGRAPH HIGH;So;0;L;<circle> 4E0A;;;;N;;;;;
10625 32A5;CIRCLED IDEOGRAPH CENTRE;So;0;L;<circle> 4E2D;;;;N;CIRCLED IDEOGRAPH CENTER;;;;
10626 32A6;CIRCLED IDEOGRAPH LOW;So;0;L;<circle> 4E0B;;;;N;;;;;
10627 32A7;CIRCLED IDEOGRAPH LEFT;So;0;L;<circle> 5DE6;;;;N;;;;;
10628 32A8;CIRCLED IDEOGRAPH RIGHT;So;0;L;<circle> 53F3;;;;N;;;;;
10629 32A9;CIRCLED IDEOGRAPH MEDICINE;So;0;L;<circle> 533B;;;;N;;;;;
10630 32AA;CIRCLED IDEOGRAPH RELIGION;So;0;L;<circle> 5B97;;;;N;;;;;
10631 32AB;CIRCLED IDEOGRAPH STUDY;So;0;L;<circle> 5B66;;;;N;;;;;
10632 32AC;CIRCLED IDEOGRAPH SUPERVISE;So;0;L;<circle> 76E3;;;;N;;;;;
10633 32AD;CIRCLED IDEOGRAPH ENTERPRISE;So;0;L;<circle> 4F01;;;;N;;;;;
10634 32AE;CIRCLED IDEOGRAPH RESOURCE;So;0;L;<circle> 8CC7;;;;N;;;;;
10635 32AF;CIRCLED IDEOGRAPH ALLIANCE;So;0;L;<circle> 5354;;;;N;;;;;
10636 32B0;CIRCLED IDEOGRAPH NIGHT;So;0;L;<circle> 591C;;;;N;;;;;
10637 32B1;CIRCLED NUMBER THIRTY SIX;No;0;ON;<circle> 0033 0036;;;36;N;;;;;
10638 32B2;CIRCLED NUMBER THIRTY SEVEN;No;0;ON;<circle> 0033 0037;;;37;N;;;;;
10639 32B3;CIRCLED NUMBER THIRTY EIGHT;No;0;ON;<circle> 0033 0038;;;38;N;;;;;
10640 32B4;CIRCLED NUMBER THIRTY NINE;No;0;ON;<circle> 0033 0039;;;39;N;;;;;
10641 32B5;CIRCLED NUMBER FORTY;No;0;ON;<circle> 0034 0030;;;40;N;;;;;
10642 32B6;CIRCLED NUMBER FORTY ONE;No;0;ON;<circle> 0034 0031;;;41;N;;;;;
10643 32B7;CIRCLED NUMBER FORTY TWO;No;0;ON;<circle> 0034 0032;;;42;N;;;;;
10644 32B8;CIRCLED NUMBER FORTY THREE;No;0;ON;<circle> 0034 0033;;;43;N;;;;;
10645 32B9;CIRCLED NUMBER FORTY FOUR;No;0;ON;<circle> 0034 0034;;;44;N;;;;;
10646 32BA;CIRCLED NUMBER FORTY FIVE;No;0;ON;<circle> 0034 0035;;;45;N;;;;;
10647 32BB;CIRCLED NUMBER FORTY SIX;No;0;ON;<circle> 0034 0036;;;46;N;;;;;
10648 32BC;CIRCLED NUMBER FORTY SEVEN;No;0;ON;<circle> 0034 0037;;;47;N;;;;;
10649 32BD;CIRCLED NUMBER FORTY EIGHT;No;0;ON;<circle> 0034 0038;;;48;N;;;;;
10650 32BE;CIRCLED NUMBER FORTY NINE;No;0;ON;<circle> 0034 0039;;;49;N;;;;;
10651 32BF;CIRCLED NUMBER FIFTY;No;0;ON;<circle> 0035 0030;;;50;N;;;;;
10652 32C0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY;So;0;L;<compat> 0031 6708;;;;N;;;;;
10653 32C1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY;So;0;L;<compat> 0032 6708;;;;N;;;;;
10654 32C2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH;So;0;L;<compat> 0033 6708;;;;N;;;;;
10655 32C3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL;So;0;L;<compat> 0034 6708;;;;N;;;;;
10656 32C4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY;So;0;L;<compat> 0035 6708;;;;N;;;;;
10657 32C5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE;So;0;L;<compat> 0036 6708;;;;N;;;;;
10658 32C6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY;So;0;L;<compat> 0037 6708;;;;N;;;;;
10659 32C7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST;So;0;L;<compat> 0038 6708;;;;N;;;;;
10660 32C8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER;So;0;L;<compat> 0039 6708;;;;N;;;;;
10661 32C9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER;So;0;L;<compat> 0031 0030 6708;;;;N;;;;;
10662 32CA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER;So;0;L;<compat> 0031 0031 6708;;;;N;;;;;
10663 32CB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER;So;0;L;<compat> 0031 0032 6708;;;;N;;;;;
10664 32CC;SQUARE HG;So;0;ON;<square> 0048 0067;;;;N;;;;;
10665 32CD;SQUARE ERG;So;0;ON;<square> 0065 0072 0067;;;;N;;;;;
10666 32CE;SQUARE EV;So;0;ON;<square> 0065 0056;;;;N;;;;;
10667 32CF;LIMITED LIABILITY SIGN;So;0;ON;<square> 004C 0054 0044;;;;N;;;;;
10668 32D0;CIRCLED KATAKANA A;So;0;L;<circle> 30A2;;;;N;;;;;
10669 32D1;CIRCLED KATAKANA I;So;0;L;<circle> 30A4;;;;N;;;;;
10670 32D2;CIRCLED KATAKANA U;So;0;L;<circle> 30A6;;;;N;;;;;
10671 32D3;CIRCLED KATAKANA E;So;0;L;<circle> 30A8;;;;N;;;;;
10672 32D4;CIRCLED KATAKANA O;So;0;L;<circle> 30AA;;;;N;;;;;
10673 32D5;CIRCLED KATAKANA KA;So;0;L;<circle> 30AB;;;;N;;;;;
10674 32D6;CIRCLED KATAKANA KI;So;0;L;<circle> 30AD;;;;N;;;;;
10675 32D7;CIRCLED KATAKANA KU;So;0;L;<circle> 30AF;;;;N;;;;;
10676 32D8;CIRCLED KATAKANA KE;So;0;L;<circle> 30B1;;;;N;;;;;
10677 32D9;CIRCLED KATAKANA KO;So;0;L;<circle> 30B3;;;;N;;;;;
10678 32DA;CIRCLED KATAKANA SA;So;0;L;<circle> 30B5;;;;N;;;;;
10679 32DB;CIRCLED KATAKANA SI;So;0;L;<circle> 30B7;;;;N;;;;;
10680 32DC;CIRCLED KATAKANA SU;So;0;L;<circle> 30B9;;;;N;;;;;
10681 32DD;CIRCLED KATAKANA SE;So;0;L;<circle> 30BB;;;;N;;;;;
10682 32DE;CIRCLED KATAKANA SO;So;0;L;<circle> 30BD;;;;N;;;;;
10683 32DF;CIRCLED KATAKANA TA;So;0;L;<circle> 30BF;;;;N;;;;;
10684 32E0;CIRCLED KATAKANA TI;So;0;L;<circle> 30C1;;;;N;;;;;
10685 32E1;CIRCLED KATAKANA TU;So;0;L;<circle> 30C4;;;;N;;;;;
10686 32E2;CIRCLED KATAKANA TE;So;0;L;<circle> 30C6;;;;N;;;;;
10687 32E3;CIRCLED KATAKANA TO;So;0;L;<circle> 30C8;;;;N;;;;;
10688 32E4;CIRCLED KATAKANA NA;So;0;L;<circle> 30CA;;;;N;;;;;
10689 32E5;CIRCLED KATAKANA NI;So;0;L;<circle> 30CB;;;;N;;;;;
10690 32E6;CIRCLED KATAKANA NU;So;0;L;<circle> 30CC;;;;N;;;;;
10691 32E7;CIRCLED KATAKANA NE;So;0;L;<circle> 30CD;;;;N;;;;;
10692 32E8;CIRCLED KATAKANA NO;So;0;L;<circle> 30CE;;;;N;;;;;
10693 32E9;CIRCLED KATAKANA HA;So;0;L;<circle> 30CF;;;;N;;;;;
10694 32EA;CIRCLED KATAKANA HI;So;0;L;<circle> 30D2;;;;N;;;;;
10695 32EB;CIRCLED KATAKANA HU;So;0;L;<circle> 30D5;;;;N;;;;;
10696 32EC;CIRCLED KATAKANA HE;So;0;L;<circle> 30D8;;;;N;;;;;
10697 32ED;CIRCLED KATAKANA HO;So;0;L;<circle> 30DB;;;;N;;;;;
10698 32EE;CIRCLED KATAKANA MA;So;0;L;<circle> 30DE;;;;N;;;;;
10699 32EF;CIRCLED KATAKANA MI;So;0;L;<circle> 30DF;;;;N;;;;;
10700 32F0;CIRCLED KATAKANA MU;So;0;L;<circle> 30E0;;;;N;;;;;
10701 32F1;CIRCLED KATAKANA ME;So;0;L;<circle> 30E1;;;;N;;;;;
10702 32F2;CIRCLED KATAKANA MO;So;0;L;<circle> 30E2;;;;N;;;;;
10703 32F3;CIRCLED KATAKANA YA;So;0;L;<circle> 30E4;;;;N;;;;;
10704 32F4;CIRCLED KATAKANA YU;So;0;L;<circle> 30E6;;;;N;;;;;
10705 32F5;CIRCLED KATAKANA YO;So;0;L;<circle> 30E8;;;;N;;;;;
10706 32F6;CIRCLED KATAKANA RA;So;0;L;<circle> 30E9;;;;N;;;;;
10707 32F7;CIRCLED KATAKANA RI;So;0;L;<circle> 30EA;;;;N;;;;;
10708 32F8;CIRCLED KATAKANA RU;So;0;L;<circle> 30EB;;;;N;;;;;
10709 32F9;CIRCLED KATAKANA RE;So;0;L;<circle> 30EC;;;;N;;;;;
10710 32FA;CIRCLED KATAKANA RO;So;0;L;<circle> 30ED;;;;N;;;;;
10711 32FB;CIRCLED KATAKANA WA;So;0;L;<circle> 30EF;;;;N;;;;;
10712 32FC;CIRCLED KATAKANA WI;So;0;L;<circle> 30F0;;;;N;;;;;
10713 32FD;CIRCLED KATAKANA WE;So;0;L;<circle> 30F1;;;;N;;;;;
10714 32FE;CIRCLED KATAKANA WO;So;0;L;<circle> 30F2;;;;N;;;;;
10715 3300;SQUARE APAATO;So;0;L;<square> 30A2 30D1 30FC 30C8;;;;N;SQUARED APAATO;;;;
10716 3301;SQUARE ARUHUA;So;0;L;<square> 30A2 30EB 30D5 30A1;;;;N;SQUARED ARUHUA;;;;
10717 3302;SQUARE ANPEA;So;0;L;<square> 30A2 30F3 30DA 30A2;;;;N;SQUARED ANPEA;;;;
10718 3303;SQUARE AARU;So;0;L;<square> 30A2 30FC 30EB;;;;N;SQUARED AARU;;;;
10719 3304;SQUARE ININGU;So;0;L;<square> 30A4 30CB 30F3 30B0;;;;N;SQUARED ININGU;;;;
10720 3305;SQUARE INTI;So;0;L;<square> 30A4 30F3 30C1;;;;N;SQUARED INTI;;;;
10721 3306;SQUARE UON;So;0;L;<square> 30A6 30A9 30F3;;;;N;SQUARED UON;;;;
10722 3307;SQUARE ESUKUUDO;So;0;L;<square> 30A8 30B9 30AF 30FC 30C9;;;;N;SQUARED ESUKUUDO;;;;
10723 3308;SQUARE EEKAA;So;0;L;<square> 30A8 30FC 30AB 30FC;;;;N;SQUARED EEKAA;;;;
10724 3309;SQUARE ONSU;So;0;L;<square> 30AA 30F3 30B9;;;;N;SQUARED ONSU;;;;
10725 330A;SQUARE OOMU;So;0;L;<square> 30AA 30FC 30E0;;;;N;SQUARED OOMU;;;;
10726 330B;SQUARE KAIRI;So;0;L;<square> 30AB 30A4 30EA;;;;N;SQUARED KAIRI;;;;
10727 330C;SQUARE KARATTO;So;0;L;<square> 30AB 30E9 30C3 30C8;;;;N;SQUARED KARATTO;;;;
10728 330D;SQUARE KARORII;So;0;L;<square> 30AB 30ED 30EA 30FC;;;;N;SQUARED KARORII;;;;
10729 330E;SQUARE GARON;So;0;L;<square> 30AC 30ED 30F3;;;;N;SQUARED GARON;;;;
10730 330F;SQUARE GANMA;So;0;L;<square> 30AC 30F3 30DE;;;;N;SQUARED GANMA;;;;
10731 3310;SQUARE GIGA;So;0;L;<square> 30AE 30AC;;;;N;SQUARED GIGA;;;;
10732 3311;SQUARE GINII;So;0;L;<square> 30AE 30CB 30FC;;;;N;SQUARED GINII;;;;
10733 3312;SQUARE KYURII;So;0;L;<square> 30AD 30E5 30EA 30FC;;;;N;SQUARED KYURII;;;;
10734 3313;SQUARE GIRUDAA;So;0;L;<square> 30AE 30EB 30C0 30FC;;;;N;SQUARED GIRUDAA;;;;
10735 3314;SQUARE KIRO;So;0;L;<square> 30AD 30ED;;;;N;SQUARED KIRO;;;;
10736 3315;SQUARE KIROGURAMU;So;0;L;<square> 30AD 30ED 30B0 30E9 30E0;;;;N;SQUARED KIROGURAMU;;;;
10737 3316;SQUARE KIROMEETORU;So;0;L;<square> 30AD 30ED 30E1 30FC 30C8 30EB;;;;N;SQUARED KIROMEETORU;;;;
10738 3317;SQUARE KIROWATTO;So;0;L;<square> 30AD 30ED 30EF 30C3 30C8;;;;N;SQUARED KIROWATTO;;;;
10739 3318;SQUARE GURAMU;So;0;L;<square> 30B0 30E9 30E0;;;;N;SQUARED GURAMU;;;;
10740 3319;SQUARE GURAMUTON;So;0;L;<square> 30B0 30E9 30E0 30C8 30F3;;;;N;SQUARED GURAMUTON;;;;
10741 331A;SQUARE KURUZEIRO;So;0;L;<square> 30AF 30EB 30BC 30A4 30ED;;;;N;SQUARED KURUZEIRO;;;;
10742 331B;SQUARE KUROONE;So;0;L;<square> 30AF 30ED 30FC 30CD;;;;N;SQUARED KUROONE;;;;
10743 331C;SQUARE KEESU;So;0;L;<square> 30B1 30FC 30B9;;;;N;SQUARED KEESU;;;;
10744 331D;SQUARE KORUNA;So;0;L;<square> 30B3 30EB 30CA;;;;N;SQUARED KORUNA;;;;
10745 331E;SQUARE KOOPO;So;0;L;<square> 30B3 30FC 30DD;;;;N;SQUARED KOOPO;;;;
10746 331F;SQUARE SAIKURU;So;0;L;<square> 30B5 30A4 30AF 30EB;;;;N;SQUARED SAIKURU;;;;
10747 3320;SQUARE SANTIIMU;So;0;L;<square> 30B5 30F3 30C1 30FC 30E0;;;;N;SQUARED SANTIIMU;;;;
10748 3321;SQUARE SIRINGU;So;0;L;<square> 30B7 30EA 30F3 30B0;;;;N;SQUARED SIRINGU;;;;
10749 3322;SQUARE SENTI;So;0;L;<square> 30BB 30F3 30C1;;;;N;SQUARED SENTI;;;;
10750 3323;SQUARE SENTO;So;0;L;<square> 30BB 30F3 30C8;;;;N;SQUARED SENTO;;;;
10751 3324;SQUARE DAASU;So;0;L;<square> 30C0 30FC 30B9;;;;N;SQUARED DAASU;;;;
10752 3325;SQUARE DESI;So;0;L;<square> 30C7 30B7;;;;N;SQUARED DESI;;;;
10753 3326;SQUARE DORU;So;0;L;<square> 30C9 30EB;;;;N;SQUARED DORU;;;;
10754 3327;SQUARE TON;So;0;L;<square> 30C8 30F3;;;;N;SQUARED TON;;;;
10755 3328;SQUARE NANO;So;0;L;<square> 30CA 30CE;;;;N;SQUARED NANO;;;;
10756 3329;SQUARE NOTTO;So;0;L;<square> 30CE 30C3 30C8;;;;N;SQUARED NOTTO;;;;
10757 332A;SQUARE HAITU;So;0;L;<square> 30CF 30A4 30C4;;;;N;SQUARED HAITU;;;;
10758 332B;SQUARE PAASENTO;So;0;L;<square> 30D1 30FC 30BB 30F3 30C8;;;;N;SQUARED PAASENTO;;;;
10759 332C;SQUARE PAATU;So;0;L;<square> 30D1 30FC 30C4;;;;N;SQUARED PAATU;;;;
10760 332D;SQUARE BAARERU;So;0;L;<square> 30D0 30FC 30EC 30EB;;;;N;SQUARED BAARERU;;;;
10761 332E;SQUARE PIASUTORU;So;0;L;<square> 30D4 30A2 30B9 30C8 30EB;;;;N;SQUARED PIASUTORU;;;;
10762 332F;SQUARE PIKURU;So;0;L;<square> 30D4 30AF 30EB;;;;N;SQUARED PIKURU;;;;
10763 3330;SQUARE PIKO;So;0;L;<square> 30D4 30B3;;;;N;SQUARED PIKO;;;;
10764 3331;SQUARE BIRU;So;0;L;<square> 30D3 30EB;;;;N;SQUARED BIRU;;;;
10765 3332;SQUARE HUARADDO;So;0;L;<square> 30D5 30A1 30E9 30C3 30C9;;;;N;SQUARED HUARADDO;;;;
10766 3333;SQUARE HUIITO;So;0;L;<square> 30D5 30A3 30FC 30C8;;;;N;SQUARED HUIITO;;;;
10767 3334;SQUARE BUSSYERU;So;0;L;<square> 30D6 30C3 30B7 30A7 30EB;;;;N;SQUARED BUSSYERU;;;;
10768 3335;SQUARE HURAN;So;0;L;<square> 30D5 30E9 30F3;;;;N;SQUARED HURAN;;;;
10769 3336;SQUARE HEKUTAARU;So;0;L;<square> 30D8 30AF 30BF 30FC 30EB;;;;N;SQUARED HEKUTAARU;;;;
10770 3337;SQUARE PESO;So;0;L;<square> 30DA 30BD;;;;N;SQUARED PESO;;;;
10771 3338;SQUARE PENIHI;So;0;L;<square> 30DA 30CB 30D2;;;;N;SQUARED PENIHI;;;;
10772 3339;SQUARE HERUTU;So;0;L;<square> 30D8 30EB 30C4;;;;N;SQUARED HERUTU;;;;
10773 333A;SQUARE PENSU;So;0;L;<square> 30DA 30F3 30B9;;;;N;SQUARED PENSU;;;;
10774 333B;SQUARE PEEZI;So;0;L;<square> 30DA 30FC 30B8;;;;N;SQUARED PEEZI;;;;
10775 333C;SQUARE BEETA;So;0;L;<square> 30D9 30FC 30BF;;;;N;SQUARED BEETA;;;;
10776 333D;SQUARE POINTO;So;0;L;<square> 30DD 30A4 30F3 30C8;;;;N;SQUARED POINTO;;;;
10777 333E;SQUARE BORUTO;So;0;L;<square> 30DC 30EB 30C8;;;;N;SQUARED BORUTO;;;;
10778 333F;SQUARE HON;So;0;L;<square> 30DB 30F3;;;;N;SQUARED HON;;;;
10779 3340;SQUARE PONDO;So;0;L;<square> 30DD 30F3 30C9;;;;N;SQUARED PONDO;;;;
10780 3341;SQUARE HOORU;So;0;L;<square> 30DB 30FC 30EB;;;;N;SQUARED HOORU;;;;
10781 3342;SQUARE HOON;So;0;L;<square> 30DB 30FC 30F3;;;;N;SQUARED HOON;;;;
10782 3343;SQUARE MAIKURO;So;0;L;<square> 30DE 30A4 30AF 30ED;;;;N;SQUARED MAIKURO;;;;
10783 3344;SQUARE MAIRU;So;0;L;<square> 30DE 30A4 30EB;;;;N;SQUARED MAIRU;;;;
10784 3345;SQUARE MAHHA;So;0;L;<square> 30DE 30C3 30CF;;;;N;SQUARED MAHHA;;;;
10785 3346;SQUARE MARUKU;So;0;L;<square> 30DE 30EB 30AF;;;;N;SQUARED MARUKU;;;;
10786 3347;SQUARE MANSYON;So;0;L;<square> 30DE 30F3 30B7 30E7 30F3;;;;N;SQUARED MANSYON;;;;
10787 3348;SQUARE MIKURON;So;0;L;<square> 30DF 30AF 30ED 30F3;;;;N;SQUARED MIKURON;;;;
10788 3349;SQUARE MIRI;So;0;L;<square> 30DF 30EA;;;;N;SQUARED MIRI;;;;
10789 334A;SQUARE MIRIBAARU;So;0;L;<square> 30DF 30EA 30D0 30FC 30EB;;;;N;SQUARED MIRIBAARU;;;;
10790 334B;SQUARE MEGA;So;0;L;<square> 30E1 30AC;;;;N;SQUARED MEGA;;;;
10791 334C;SQUARE MEGATON;So;0;L;<square> 30E1 30AC 30C8 30F3;;;;N;SQUARED MEGATON;;;;
10792 334D;SQUARE MEETORU;So;0;L;<square> 30E1 30FC 30C8 30EB;;;;N;SQUARED MEETORU;;;;
10793 334E;SQUARE YAADO;So;0;L;<square> 30E4 30FC 30C9;;;;N;SQUARED YAADO;;;;
10794 334F;SQUARE YAARU;So;0;L;<square> 30E4 30FC 30EB;;;;N;SQUARED YAARU;;;;
10795 3350;SQUARE YUAN;So;0;L;<square> 30E6 30A2 30F3;;;;N;SQUARED YUAN;;;;
10796 3351;SQUARE RITTORU;So;0;L;<square> 30EA 30C3 30C8 30EB;;;;N;SQUARED RITTORU;;;;
10797 3352;SQUARE RIRA;So;0;L;<square> 30EA 30E9;;;;N;SQUARED RIRA;;;;
10798 3353;SQUARE RUPII;So;0;L;<square> 30EB 30D4 30FC;;;;N;SQUARED RUPII;;;;
10799 3354;SQUARE RUUBURU;So;0;L;<square> 30EB 30FC 30D6 30EB;;;;N;SQUARED RUUBURU;;;;
10800 3355;SQUARE REMU;So;0;L;<square> 30EC 30E0;;;;N;SQUARED REMU;;;;
10801 3356;SQUARE RENTOGEN;So;0;L;<square> 30EC 30F3 30C8 30B2 30F3;;;;N;SQUARED RENTOGEN;;;;
10802 3357;SQUARE WATTO;So;0;L;<square> 30EF 30C3 30C8;;;;N;SQUARED WATTO;;;;
10803 3358;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO;So;0;L;<compat> 0030 70B9;;;;N;;;;;
10804 3359;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE;So;0;L;<compat> 0031 70B9;;;;N;;;;;
10805 335A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO;So;0;L;<compat> 0032 70B9;;;;N;;;;;
10806 335B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE;So;0;L;<compat> 0033 70B9;;;;N;;;;;
10807 335C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR;So;0;L;<compat> 0034 70B9;;;;N;;;;;
10808 335D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE;So;0;L;<compat> 0035 70B9;;;;N;;;;;
10809 335E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX;So;0;L;<compat> 0036 70B9;;;;N;;;;;
10810 335F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN;So;0;L;<compat> 0037 70B9;;;;N;;;;;
10811 3360;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT;So;0;L;<compat> 0038 70B9;;;;N;;;;;
10812 3361;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE;So;0;L;<compat> 0039 70B9;;;;N;;;;;
10813 3362;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN;So;0;L;<compat> 0031 0030 70B9;;;;N;;;;;
10814 3363;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN;So;0;L;<compat> 0031 0031 70B9;;;;N;;;;;
10815 3364;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE;So;0;L;<compat> 0031 0032 70B9;;;;N;;;;;
10816 3365;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN;So;0;L;<compat> 0031 0033 70B9;;;;N;;;;;
10817 3366;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN;So;0;L;<compat> 0031 0034 70B9;;;;N;;;;;
10818 3367;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN;So;0;L;<compat> 0031 0035 70B9;;;;N;;;;;
10819 3368;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN;So;0;L;<compat> 0031 0036 70B9;;;;N;;;;;
10820 3369;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN;So;0;L;<compat> 0031 0037 70B9;;;;N;;;;;
10821 336A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN;So;0;L;<compat> 0031 0038 70B9;;;;N;;;;;
10822 336B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN;So;0;L;<compat> 0031 0039 70B9;;;;N;;;;;
10823 336C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY;So;0;L;<compat> 0032 0030 70B9;;;;N;;;;;
10824 336D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE;So;0;L;<compat> 0032 0031 70B9;;;;N;;;;;
10825 336E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO;So;0;L;<compat> 0032 0032 70B9;;;;N;;;;;
10826 336F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE;So;0;L;<compat> 0032 0033 70B9;;;;N;;;;;
10827 3370;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR;So;0;L;<compat> 0032 0034 70B9;;;;N;;;;;
10828 3371;SQUARE HPA;So;0;L;<square> 0068 0050 0061;;;;N;;;;;
10829 3372;SQUARE DA;So;0;L;<square> 0064 0061;;;;N;;;;;
10830 3373;SQUARE AU;So;0;L;<square> 0041 0055;;;;N;;;;;
10831 3374;SQUARE BAR;So;0;L;<square> 0062 0061 0072;;;;N;;;;;
10832 3375;SQUARE OV;So;0;L;<square> 006F 0056;;;;N;;;;;
10833 3376;SQUARE PC;So;0;L;<square> 0070 0063;;;;N;;;;;
10834 3377;SQUARE DM;So;0;ON;<square> 0064 006D;;;;N;;;;;
10835 3378;SQUARE DM SQUARED;So;0;ON;<square> 0064 006D 00B2;;;;N;;;;;
10836 3379;SQUARE DM CUBED;So;0;ON;<square> 0064 006D 00B3;;;;N;;;;;
10837 337A;SQUARE IU;So;0;ON;<square> 0049 0055;;;;N;;;;;
10838 337B;SQUARE ERA NAME HEISEI;So;0;L;<square> 5E73 6210;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME HEISEI;;;;
10839 337C;SQUARE ERA NAME SYOUWA;So;0;L;<square> 662D 548C;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME SYOUWA;;;;
10840 337D;SQUARE ERA NAME TAISYOU;So;0;L;<square> 5927 6B63;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME TAISYOU;;;;
10841 337E;SQUARE ERA NAME MEIZI;So;0;L;<square> 660E 6CBB;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME MEIZI;;;;
10842 337F;SQUARE CORPORATION;So;0;L;<square> 682A 5F0F 4F1A 793E;;;;N;SQUARED FOUR IDEOGRAPHS CORPORATION;;;;
10843 3380;SQUARE PA AMPS;So;0;L;<square> 0070 0041;;;;N;SQUARED PA AMPS;;;;
10844 3381;SQUARE NA;So;0;L;<square> 006E 0041;;;;N;SQUARED NA;;;;
10845 3382;SQUARE MU A;So;0;L;<square> 03BC 0041;;;;N;SQUARED MU A;;;;
10846 3383;SQUARE MA;So;0;L;<square> 006D 0041;;;;N;SQUARED MA;;;;
10847 3384;SQUARE KA;So;0;L;<square> 006B 0041;;;;N;SQUARED KA;;;;
10848 3385;SQUARE KB;So;0;L;<square> 004B 0042;;;;N;SQUARED KB;;;;
10849 3386;SQUARE MB;So;0;L;<square> 004D 0042;;;;N;SQUARED MB;;;;
10850 3387;SQUARE GB;So;0;L;<square> 0047 0042;;;;N;SQUARED GB;;;;
10851 3388;SQUARE CAL;So;0;L;<square> 0063 0061 006C;;;;N;SQUARED CAL;;;;
10852 3389;SQUARE KCAL;So;0;L;<square> 006B 0063 0061 006C;;;;N;SQUARED KCAL;;;;
10853 338A;SQUARE PF;So;0;L;<square> 0070 0046;;;;N;SQUARED PF;;;;
10854 338B;SQUARE NF;So;0;L;<square> 006E 0046;;;;N;SQUARED NF;;;;
10855 338C;SQUARE MU F;So;0;L;<square> 03BC 0046;;;;N;SQUARED MU F;;;;
10856 338D;SQUARE MU G;So;0;L;<square> 03BC 0067;;;;N;SQUARED MU G;;;;
10857 338E;SQUARE MG;So;0;L;<square> 006D 0067;;;;N;SQUARED MG;;;;
10858 338F;SQUARE KG;So;0;L;<square> 006B 0067;;;;N;SQUARED KG;;;;
10859 3390;SQUARE HZ;So;0;L;<square> 0048 007A;;;;N;SQUARED HZ;;;;
10860 3391;SQUARE KHZ;So;0;L;<square> 006B 0048 007A;;;;N;SQUARED KHZ;;;;
10861 3392;SQUARE MHZ;So;0;L;<square> 004D 0048 007A;;;;N;SQUARED MHZ;;;;
10862 3393;SQUARE GHZ;So;0;L;<square> 0047 0048 007A;;;;N;SQUARED GHZ;;;;
10863 3394;SQUARE THZ;So;0;L;<square> 0054 0048 007A;;;;N;SQUARED THZ;;;;
10864 3395;SQUARE MU L;So;0;L;<square> 03BC 2113;;;;N;SQUARED MU L;;;;
10865 3396;SQUARE ML;So;0;L;<square> 006D 2113;;;;N;SQUARED ML;;;;
10866 3397;SQUARE DL;So;0;L;<square> 0064 2113;;;;N;SQUARED DL;;;;
10867 3398;SQUARE KL;So;0;L;<square> 006B 2113;;;;N;SQUARED KL;;;;
10868 3399;SQUARE FM;So;0;L;<square> 0066 006D;;;;N;SQUARED FM;;;;
10869 339A;SQUARE NM;So;0;L;<square> 006E 006D;;;;N;SQUARED NM;;;;
10870 339B;SQUARE MU M;So;0;L;<square> 03BC 006D;;;;N;SQUARED MU M;;;;
10871 339C;SQUARE MM;So;0;L;<square> 006D 006D;;;;N;SQUARED MM;;;;
10872 339D;SQUARE CM;So;0;L;<square> 0063 006D;;;;N;SQUARED CM;;;;
10873 339E;SQUARE KM;So;0;L;<square> 006B 006D;;;;N;SQUARED KM;;;;
10874 339F;SQUARE MM SQUARED;So;0;L;<square> 006D 006D 00B2;;;;N;SQUARED MM SQUARED;;;;
10875 33A0;SQUARE CM SQUARED;So;0;L;<square> 0063 006D 00B2;;;;N;SQUARED CM SQUARED;;;;
10876 33A1;SQUARE M SQUARED;So;0;L;<square> 006D 00B2;;;;N;SQUARED M SQUARED;;;;
10877 33A2;SQUARE KM SQUARED;So;0;L;<square> 006B 006D 00B2;;;;N;SQUARED KM SQUARED;;;;
10878 33A3;SQUARE MM CUBED;So;0;L;<square> 006D 006D 00B3;;;;N;SQUARED MM CUBED;;;;
10879 33A4;SQUARE CM CUBED;So;0;L;<square> 0063 006D 00B3;;;;N;SQUARED CM CUBED;;;;
10880 33A5;SQUARE M CUBED;So;0;L;<square> 006D 00B3;;;;N;SQUARED M CUBED;;;;
10881 33A6;SQUARE KM CUBED;So;0;L;<square> 006B 006D 00B3;;;;N;SQUARED KM CUBED;;;;
10882 33A7;SQUARE M OVER S;So;0;L;<square> 006D 2215 0073;;;;N;SQUARED M OVER S;;;;
10883 33A8;SQUARE M OVER S SQUARED;So;0;L;<square> 006D 2215 0073 00B2;;;;N;SQUARED M OVER S SQUARED;;;;
10884 33A9;SQUARE PA;So;0;L;<square> 0050 0061;;;;N;SQUARED PA;;;;
10885 33AA;SQUARE KPA;So;0;L;<square> 006B 0050 0061;;;;N;SQUARED KPA;;;;
10886 33AB;SQUARE MPA;So;0;L;<square> 004D 0050 0061;;;;N;SQUARED MPA;;;;
10887 33AC;SQUARE GPA;So;0;L;<square> 0047 0050 0061;;;;N;SQUARED GPA;;;;
10888 33AD;SQUARE RAD;So;0;L;<square> 0072 0061 0064;;;;N;SQUARED RAD;;;;
10889 33AE;SQUARE RAD OVER S;So;0;L;<square> 0072 0061 0064 2215 0073;;;;N;SQUARED RAD OVER S;;;;
10890 33AF;SQUARE RAD OVER S SQUARED;So;0;L;<square> 0072 0061 0064 2215 0073 00B2;;;;N;SQUARED RAD OVER S SQUARED;;;;
10891 33B0;SQUARE PS;So;0;L;<square> 0070 0073;;;;N;SQUARED PS;;;;
10892 33B1;SQUARE NS;So;0;L;<square> 006E 0073;;;;N;SQUARED NS;;;;
10893 33B2;SQUARE MU S;So;0;L;<square> 03BC 0073;;;;N;SQUARED MU S;;;;
10894 33B3;SQUARE MS;So;0;L;<square> 006D 0073;;;;N;SQUARED MS;;;;
10895 33B4;SQUARE PV;So;0;L;<square> 0070 0056;;;;N;SQUARED PV;;;;
10896 33B5;SQUARE NV;So;0;L;<square> 006E 0056;;;;N;SQUARED NV;;;;
10897 33B6;SQUARE MU V;So;0;L;<square> 03BC 0056;;;;N;SQUARED MU V;;;;
10898 33B7;SQUARE MV;So;0;L;<square> 006D 0056;;;;N;SQUARED MV;;;;
10899 33B8;SQUARE KV;So;0;L;<square> 006B 0056;;;;N;SQUARED KV;;;;
10900 33B9;SQUARE MV MEGA;So;0;L;<square> 004D 0056;;;;N;SQUARED MV MEGA;;;;
10901 33BA;SQUARE PW;So;0;L;<square> 0070 0057;;;;N;SQUARED PW;;;;
10902 33BB;SQUARE NW;So;0;L;<square> 006E 0057;;;;N;SQUARED NW;;;;
10903 33BC;SQUARE MU W;So;0;L;<square> 03BC 0057;;;;N;SQUARED MU W;;;;
10904 33BD;SQUARE MW;So;0;L;<square> 006D 0057;;;;N;SQUARED MW;;;;
10905 33BE;SQUARE KW;So;0;L;<square> 006B 0057;;;;N;SQUARED KW;;;;
10906 33BF;SQUARE MW MEGA;So;0;L;<square> 004D 0057;;;;N;SQUARED MW MEGA;;;;
10907 33C0;SQUARE K OHM;So;0;L;<square> 006B 03A9;;;;N;SQUARED K OHM;;;;
10908 33C1;SQUARE M OHM;So;0;L;<square> 004D 03A9;;;;N;SQUARED M OHM;;;;
10909 33C2;SQUARE AM;So;0;L;<square> 0061 002E 006D 002E;;;;N;SQUARED AM;;;;
10910 33C3;SQUARE BQ;So;0;L;<square> 0042 0071;;;;N;SQUARED BQ;;;;
10911 33C4;SQUARE CC;So;0;L;<square> 0063 0063;;;;N;SQUARED CC;;;;
10912 33C5;SQUARE CD;So;0;L;<square> 0063 0064;;;;N;SQUARED CD;;;;
10913 33C6;SQUARE C OVER KG;So;0;L;<square> 0043 2215 006B 0067;;;;N;SQUARED C OVER KG;;;;
10914 33C7;SQUARE CO;So;0;L;<square> 0043 006F 002E;;;;N;SQUARED CO;;;;
10915 33C8;SQUARE DB;So;0;L;<square> 0064 0042;;;;N;SQUARED DB;;;;
10916 33C9;SQUARE GY;So;0;L;<square> 0047 0079;;;;N;SQUARED GY;;;;
10917 33CA;SQUARE HA;So;0;L;<square> 0068 0061;;;;N;SQUARED HA;;;;
10918 33CB;SQUARE HP;So;0;L;<square> 0048 0050;;;;N;SQUARED HP;;;;
10919 33CC;SQUARE IN;So;0;L;<square> 0069 006E;;;;N;SQUARED IN;;;;
10920 33CD;SQUARE KK;So;0;L;<square> 004B 004B;;;;N;SQUARED KK;;;;
10921 33CE;SQUARE KM CAPITAL;So;0;L;<square> 004B 004D;;;;N;SQUARED KM CAPITAL;;;;
10922 33CF;SQUARE KT;So;0;L;<square> 006B 0074;;;;N;SQUARED KT;;;;
10923 33D0;SQUARE LM;So;0;L;<square> 006C 006D;;;;N;SQUARED LM;;;;
10924 33D1;SQUARE LN;So;0;L;<square> 006C 006E;;;;N;SQUARED LN;;;;
10925 33D2;SQUARE LOG;So;0;L;<square> 006C 006F 0067;;;;N;SQUARED LOG;;;;
10926 33D3;SQUARE LX;So;0;L;<square> 006C 0078;;;;N;SQUARED LX;;;;
10927 33D4;SQUARE MB SMALL;So;0;L;<square> 006D 0062;;;;N;SQUARED MB SMALL;;;;
10928 33D5;SQUARE MIL;So;0;L;<square> 006D 0069 006C;;;;N;SQUARED MIL;;;;
10929 33D6;SQUARE MOL;So;0;L;<square> 006D 006F 006C;;;;N;SQUARED MOL;;;;
10930 33D7;SQUARE PH;So;0;L;<square> 0050 0048;;;;N;SQUARED PH;;;;
10931 33D8;SQUARE PM;So;0;L;<square> 0070 002E 006D 002E;;;;N;SQUARED PM;;;;
10932 33D9;SQUARE PPM;So;0;L;<square> 0050 0050 004D;;;;N;SQUARED PPM;;;;
10933 33DA;SQUARE PR;So;0;L;<square> 0050 0052;;;;N;SQUARED PR;;;;
10934 33DB;SQUARE SR;So;0;L;<square> 0073 0072;;;;N;SQUARED SR;;;;
10935 33DC;SQUARE SV;So;0;L;<square> 0053 0076;;;;N;SQUARED SV;;;;
10936 33DD;SQUARE WB;So;0;L;<square> 0057 0062;;;;N;SQUARED WB;;;;
10937 33DE;SQUARE V OVER M;So;0;ON;<square> 0056 2215 006D;;;;N;;;;;
10938 33DF;SQUARE A OVER M;So;0;ON;<square> 0041 2215 006D;;;;N;;;;;
10939 33E0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE;So;0;L;<compat> 0031 65E5;;;;N;;;;;
10940 33E1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO;So;0;L;<compat> 0032 65E5;;;;N;;;;;
10941 33E2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE;So;0;L;<compat> 0033 65E5;;;;N;;;;;
10942 33E3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR;So;0;L;<compat> 0034 65E5;;;;N;;;;;
10943 33E4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE;So;0;L;<compat> 0035 65E5;;;;N;;;;;
10944 33E5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX;So;0;L;<compat> 0036 65E5;;;;N;;;;;
10945 33E6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN;So;0;L;<compat> 0037 65E5;;;;N;;;;;
10946 33E7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT;So;0;L;<compat> 0038 65E5;;;;N;;;;;
10947 33E8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE;So;0;L;<compat> 0039 65E5;;;;N;;;;;
10948 33E9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN;So;0;L;<compat> 0031 0030 65E5;;;;N;;;;;
10949 33EA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN;So;0;L;<compat> 0031 0031 65E5;;;;N;;;;;
10950 33EB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE;So;0;L;<compat> 0031 0032 65E5;;;;N;;;;;
10951 33EC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN;So;0;L;<compat> 0031 0033 65E5;;;;N;;;;;
10952 33ED;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN;So;0;L;<compat> 0031 0034 65E5;;;;N;;;;;
10953 33EE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN;So;0;L;<compat> 0031 0035 65E5;;;;N;;;;;
10954 33EF;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN;So;0;L;<compat> 0031 0036 65E5;;;;N;;;;;
10955 33F0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN;So;0;L;<compat> 0031 0037 65E5;;;;N;;;;;
10956 33F1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN;So;0;L;<compat> 0031 0038 65E5;;;;N;;;;;
10957 33F2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN;So;0;L;<compat> 0031 0039 65E5;;;;N;;;;;
10958 33F3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY;So;0;L;<compat> 0032 0030 65E5;;;;N;;;;;
10959 33F4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE;So;0;L;<compat> 0032 0031 65E5;;;;N;;;;;
10960 33F5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO;So;0;L;<compat> 0032 0032 65E5;;;;N;;;;;
10961 33F6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE;So;0;L;<compat> 0032 0033 65E5;;;;N;;;;;
10962 33F7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR;So;0;L;<compat> 0032 0034 65E5;;;;N;;;;;
10963 33F8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE;So;0;L;<compat> 0032 0035 65E5;;;;N;;;;;
10964 33F9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX;So;0;L;<compat> 0032 0036 65E5;;;;N;;;;;
10965 33FA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN;So;0;L;<compat> 0032 0037 65E5;;;;N;;;;;
10966 33FB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT;So;0;L;<compat> 0032 0038 65E5;;;;N;;;;;
10967 33FC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE;So;0;L;<compat> 0032 0039 65E5;;;;N;;;;;
10968 33FD;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY;So;0;L;<compat> 0033 0030 65E5;;;;N;;;;;
10969 33FE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE;So;0;L;<compat> 0033 0031 65E5;;;;N;;;;;
10970 33FF;SQUARE GAL;So;0;ON;<square> 0067 0061 006C;;;;N;;;;;
10971 3400;<CJK Ideograph Extension A, First>;Lo;0;L;;;;;N;;;;;
10972 4DB5;<CJK Ideograph Extension A, Last>;Lo;0;L;;;;;N;;;;;
10973 4DC0;HEXAGRAM FOR THE CREATIVE HEAVEN;So;0;ON;;;;;N;;;;;
10974 4DC1;HEXAGRAM FOR THE RECEPTIVE EARTH;So;0;ON;;;;;N;;;;;
10975 4DC2;HEXAGRAM FOR DIFFICULTY AT THE BEGINNING;So;0;ON;;;;;N;;;;;
10976 4DC3;HEXAGRAM FOR YOUTHFUL FOLLY;So;0;ON;;;;;N;;;;;
10977 4DC4;HEXAGRAM FOR WAITING;So;0;ON;;;;;N;;;;;
10978 4DC5;HEXAGRAM FOR CONFLICT;So;0;ON;;;;;N;;;;;
10979 4DC6;HEXAGRAM FOR THE ARMY;So;0;ON;;;;;N;;;;;
10980 4DC7;HEXAGRAM FOR HOLDING TOGETHER;So;0;ON;;;;;N;;;;;
10981 4DC8;HEXAGRAM FOR SMALL TAMING;So;0;ON;;;;;N;;;;;
10982 4DC9;HEXAGRAM FOR TREADING;So;0;ON;;;;;N;;;;;
10983 4DCA;HEXAGRAM FOR PEACE;So;0;ON;;;;;N;;;;;
10984 4DCB;HEXAGRAM FOR STANDSTILL;So;0;ON;;;;;N;;;;;
10985 4DCC;HEXAGRAM FOR FELLOWSHIP;So;0;ON;;;;;N;;;;;
10986 4DCD;HEXAGRAM FOR GREAT POSSESSION;So;0;ON;;;;;N;;;;;
10987 4DCE;HEXAGRAM FOR MODESTY;So;0;ON;;;;;N;;;;;
10988 4DCF;HEXAGRAM FOR ENTHUSIASM;So;0;ON;;;;;N;;;;;
10989 4DD0;HEXAGRAM FOR FOLLOWING;So;0;ON;;;;;N;;;;;
10990 4DD1;HEXAGRAM FOR WORK ON THE DECAYED;So;0;ON;;;;;N;;;;;
10991 4DD2;HEXAGRAM FOR APPROACH;So;0;ON;;;;;N;;;;;
10992 4DD3;HEXAGRAM FOR CONTEMPLATION;So;0;ON;;;;;N;;;;;
10993 4DD4;HEXAGRAM FOR BITING THROUGH;So;0;ON;;;;;N;;;;;
10994 4DD5;HEXAGRAM FOR GRACE;So;0;ON;;;;;N;;;;;
10995 4DD6;HEXAGRAM FOR SPLITTING APART;So;0;ON;;;;;N;;;;;
10996 4DD7;HEXAGRAM FOR RETURN;So;0;ON;;;;;N;;;;;
10997 4DD8;HEXAGRAM FOR INNOCENCE;So;0;ON;;;;;N;;;;;
10998 4DD9;HEXAGRAM FOR GREAT TAMING;So;0;ON;;;;;N;;;;;
10999 4DDA;HEXAGRAM FOR MOUTH CORNERS;So;0;ON;;;;;N;;;;;
11000 4DDB;HEXAGRAM FOR GREAT PREPONDERANCE;So;0;ON;;;;;N;;;;;
11001 4DDC;HEXAGRAM FOR THE ABYSMAL WATER;So;0;ON;;;;;N;;;;;
11002 4DDD;HEXAGRAM FOR THE CLINGING FIRE;So;0;ON;;;;;N;;;;;
11003 4DDE;HEXAGRAM FOR INFLUENCE;So;0;ON;;;;;N;;;;;
11004 4DDF;HEXAGRAM FOR DURATION;So;0;ON;;;;;N;;;;;
11005 4DE0;HEXAGRAM FOR RETREAT;So;0;ON;;;;;N;;;;;
11006 4DE1;HEXAGRAM FOR GREAT POWER;So;0;ON;;;;;N;;;;;
11007 4DE2;HEXAGRAM FOR PROGRESS;So;0;ON;;;;;N;;;;;
11008 4DE3;HEXAGRAM FOR DARKENING OF THE LIGHT;So;0;ON;;;;;N;;;;;
11009 4DE4;HEXAGRAM FOR THE FAMILY;So;0;ON;;;;;N;;;;;
11010 4DE5;HEXAGRAM FOR OPPOSITION;So;0;ON;;;;;N;;;;;
11011 4DE6;HEXAGRAM FOR OBSTRUCTION;So;0;ON;;;;;N;;;;;
11012 4DE7;HEXAGRAM FOR DELIVERANCE;So;0;ON;;;;;N;;;;;
11013 4DE8;HEXAGRAM FOR DECREASE;So;0;ON;;;;;N;;;;;
11014 4DE9;HEXAGRAM FOR INCREASE;So;0;ON;;;;;N;;;;;
11015 4DEA;HEXAGRAM FOR BREAKTHROUGH;So;0;ON;;;;;N;;;;;
11016 4DEB;HEXAGRAM FOR COMING TO MEET;So;0;ON;;;;;N;;;;;
11017 4DEC;HEXAGRAM FOR GATHERING TOGETHER;So;0;ON;;;;;N;;;;;
11018 4DED;HEXAGRAM FOR PUSHING UPWARD;So;0;ON;;;;;N;;;;;
11019 4DEE;HEXAGRAM FOR OPPRESSION;So;0;ON;;;;;N;;;;;
11020 4DEF;HEXAGRAM FOR THE WELL;So;0;ON;;;;;N;;;;;
11021 4DF0;HEXAGRAM FOR REVOLUTION;So;0;ON;;;;;N;;;;;
11022 4DF1;HEXAGRAM FOR THE CAULDRON;So;0;ON;;;;;N;;;;;
11023 4DF2;HEXAGRAM FOR THE AROUSING THUNDER;So;0;ON;;;;;N;;;;;
11024 4DF3;HEXAGRAM FOR THE KEEPING STILL MOUNTAIN;So;0;ON;;;;;N;;;;;
11025 4DF4;HEXAGRAM FOR DEVELOPMENT;So;0;ON;;;;;N;;;;;
11026 4DF5;HEXAGRAM FOR THE MARRYING MAIDEN;So;0;ON;;;;;N;;;;;
11027 4DF6;HEXAGRAM FOR ABUNDANCE;So;0;ON;;;;;N;;;;;
11028 4DF7;HEXAGRAM FOR THE WANDERER;So;0;ON;;;;;N;;;;;
11029 4DF8;HEXAGRAM FOR THE GENTLE WIND;So;0;ON;;;;;N;;;;;
11030 4DF9;HEXAGRAM FOR THE JOYOUS LAKE;So;0;ON;;;;;N;;;;;
11031 4DFA;HEXAGRAM FOR DISPERSION;So;0;ON;;;;;N;;;;;
11032 4DFB;HEXAGRAM FOR LIMITATION;So;0;ON;;;;;N;;;;;
11033 4DFC;HEXAGRAM FOR INNER TRUTH;So;0;ON;;;;;N;;;;;
11034 4DFD;HEXAGRAM FOR SMALL PREPONDERANCE;So;0;ON;;;;;N;;;;;
11035 4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;;
11036 4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;;
11037 4E00;<CJK Ideograph, First>;Lo;0;L;;;;;N;;;;;
11038 9FC3;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;
11039 A000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;;
11040 A001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;;
11041 A002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;;
11042 A003;YI SYLLABLE IP;Lo;0;L;;;;;N;;;;;
11043 A004;YI SYLLABLE IET;Lo;0;L;;;;;N;;;;;
11044 A005;YI SYLLABLE IEX;Lo;0;L;;;;;N;;;;;
11045 A006;YI SYLLABLE IE;Lo;0;L;;;;;N;;;;;
11046 A007;YI SYLLABLE IEP;Lo;0;L;;;;;N;;;;;
11047 A008;YI SYLLABLE AT;Lo;0;L;;;;;N;;;;;
11048 A009;YI SYLLABLE AX;Lo;0;L;;;;;N;;;;;
11049 A00A;YI SYLLABLE A;Lo;0;L;;;;;N;;;;;
11050 A00B;YI SYLLABLE AP;Lo;0;L;;;;;N;;;;;
11051 A00C;YI SYLLABLE UOX;Lo;0;L;;;;;N;;;;;
11052 A00D;YI SYLLABLE UO;Lo;0;L;;;;;N;;;;;
11053 A00E;YI SYLLABLE UOP;Lo;0;L;;;;;N;;;;;
11054 A00F;YI SYLLABLE OT;Lo;0;L;;;;;N;;;;;
11055 A010;YI SYLLABLE OX;Lo;0;L;;;;;N;;;;;
11056 A011;YI SYLLABLE O;Lo;0;L;;;;;N;;;;;
11057 A012;YI SYLLABLE OP;Lo;0;L;;;;;N;;;;;
11058 A013;YI SYLLABLE EX;Lo;0;L;;;;;N;;;;;
11059 A014;YI SYLLABLE E;Lo;0;L;;;;;N;;;;;
11060 A015;YI SYLLABLE WU;Lm;0;L;;;;;N;;;;;
11061 A016;YI SYLLABLE BIT;Lo;0;L;;;;;N;;;;;
11062 A017;YI SYLLABLE BIX;Lo;0;L;;;;;N;;;;;
11063 A018;YI SYLLABLE BI;Lo;0;L;;;;;N;;;;;
11064 A019;YI SYLLABLE BIP;Lo;0;L;;;;;N;;;;;
11065 A01A;YI SYLLABLE BIET;Lo;0;L;;;;;N;;;;;
11066 A01B;YI SYLLABLE BIEX;Lo;0;L;;;;;N;;;;;
11067 A01C;YI SYLLABLE BIE;Lo;0;L;;;;;N;;;;;
11068 A01D;YI SYLLABLE BIEP;Lo;0;L;;;;;N;;;;;
11069 A01E;YI SYLLABLE BAT;Lo;0;L;;;;;N;;;;;
11070 A01F;YI SYLLABLE BAX;Lo;0;L;;;;;N;;;;;
11071 A020;YI SYLLABLE BA;Lo;0;L;;;;;N;;;;;
11072 A021;YI SYLLABLE BAP;Lo;0;L;;;;;N;;;;;
11073 A022;YI SYLLABLE BUOX;Lo;0;L;;;;;N;;;;;
11074 A023;YI SYLLABLE BUO;Lo;0;L;;;;;N;;;;;
11075 A024;YI SYLLABLE BUOP;Lo;0;L;;;;;N;;;;;
11076 A025;YI SYLLABLE BOT;Lo;0;L;;;;;N;;;;;
11077 A026;YI SYLLABLE BOX;Lo;0;L;;;;;N;;;;;
11078 A027;YI SYLLABLE BO;Lo;0;L;;;;;N;;;;;
11079 A028;YI SYLLABLE BOP;Lo;0;L;;;;;N;;;;;
11080 A029;YI SYLLABLE BEX;Lo;0;L;;;;;N;;;;;
11081 A02A;YI SYLLABLE BE;Lo;0;L;;;;;N;;;;;
11082 A02B;YI SYLLABLE BEP;Lo;0;L;;;;;N;;;;;
11083 A02C;YI SYLLABLE BUT;Lo;0;L;;;;;N;;;;;
11084 A02D;YI SYLLABLE BUX;Lo;0;L;;;;;N;;;;;
11085 A02E;YI SYLLABLE BU;Lo;0;L;;;;;N;;;;;
11086 A02F;YI SYLLABLE BUP;Lo;0;L;;;;;N;;;;;
11087 A030;YI SYLLABLE BURX;Lo;0;L;;;;;N;;;;;
11088 A031;YI SYLLABLE BUR;Lo;0;L;;;;;N;;;;;
11089 A032;YI SYLLABLE BYT;Lo;0;L;;;;;N;;;;;
11090 A033;YI SYLLABLE BYX;Lo;0;L;;;;;N;;;;;
11091 A034;YI SYLLABLE BY;Lo;0;L;;;;;N;;;;;
11092 A035;YI SYLLABLE BYP;Lo;0;L;;;;;N;;;;;
11093 A036;YI SYLLABLE BYRX;Lo;0;L;;;;;N;;;;;
11094 A037;YI SYLLABLE BYR;Lo;0;L;;;;;N;;;;;
11095 A038;YI SYLLABLE PIT;Lo;0;L;;;;;N;;;;;
11096 A039;YI SYLLABLE PIX;Lo;0;L;;;;;N;;;;;
11097 A03A;YI SYLLABLE PI;Lo;0;L;;;;;N;;;;;
11098 A03B;YI SYLLABLE PIP;Lo;0;L;;;;;N;;;;;
11099 A03C;YI SYLLABLE PIEX;Lo;0;L;;;;;N;;;;;
11100 A03D;YI SYLLABLE PIE;Lo;0;L;;;;;N;;;;;
11101 A03E;YI SYLLABLE PIEP;Lo;0;L;;;;;N;;;;;
11102 A03F;YI SYLLABLE PAT;Lo;0;L;;;;;N;;;;;
11103 A040;YI SYLLABLE PAX;Lo;0;L;;;;;N;;;;;
11104 A041;YI SYLLABLE PA;Lo;0;L;;;;;N;;;;;
11105 A042;YI SYLLABLE PAP;Lo;0;L;;;;;N;;;;;
11106 A043;YI SYLLABLE PUOX;Lo;0;L;;;;;N;;;;;
11107 A044;YI SYLLABLE PUO;Lo;0;L;;;;;N;;;;;
11108 A045;YI SYLLABLE PUOP;Lo;0;L;;;;;N;;;;;
11109 A046;YI SYLLABLE POT;Lo;0;L;;;;;N;;;;;
11110 A047;YI SYLLABLE POX;Lo;0;L;;;;;N;;;;;
11111 A048;YI SYLLABLE PO;Lo;0;L;;;;;N;;;;;
11112 A049;YI SYLLABLE POP;Lo;0;L;;;;;N;;;;;
11113 A04A;YI SYLLABLE PUT;Lo;0;L;;;;;N;;;;;
11114 A04B;YI SYLLABLE PUX;Lo;0;L;;;;;N;;;;;
11115 A04C;YI SYLLABLE PU;Lo;0;L;;;;;N;;;;;
11116 A04D;YI SYLLABLE PUP;Lo;0;L;;;;;N;;;;;
11117 A04E;YI SYLLABLE PURX;Lo;0;L;;;;;N;;;;;
11118 A04F;YI SYLLABLE PUR;Lo;0;L;;;;;N;;;;;
11119 A050;YI SYLLABLE PYT;Lo;0;L;;;;;N;;;;;
11120 A051;YI SYLLABLE PYX;Lo;0;L;;;;;N;;;;;
11121 A052;YI SYLLABLE PY;Lo;0;L;;;;;N;;;;;
11122 A053;YI SYLLABLE PYP;Lo;0;L;;;;;N;;;;;
11123 A054;YI SYLLABLE PYRX;Lo;0;L;;;;;N;;;;;
11124 A055;YI SYLLABLE PYR;Lo;0;L;;;;;N;;;;;
11125 A056;YI SYLLABLE BBIT;Lo;0;L;;;;;N;;;;;
11126 A057;YI SYLLABLE BBIX;Lo;0;L;;;;;N;;;;;
11127 A058;YI SYLLABLE BBI;Lo;0;L;;;;;N;;;;;
11128 A059;YI SYLLABLE BBIP;Lo;0;L;;;;;N;;;;;
11129 A05A;YI SYLLABLE BBIET;Lo;0;L;;;;;N;;;;;
11130 A05B;YI SYLLABLE BBIEX;Lo;0;L;;;;;N;;;;;
11131 A05C;YI SYLLABLE BBIE;Lo;0;L;;;;;N;;;;;
11132 A05D;YI SYLLABLE BBIEP;Lo;0;L;;;;;N;;;;;
11133 A05E;YI SYLLABLE BBAT;Lo;0;L;;;;;N;;;;;
11134 A05F;YI SYLLABLE BBAX;Lo;0;L;;;;;N;;;;;
11135 A060;YI SYLLABLE BBA;Lo;0;L;;;;;N;;;;;
11136 A061;YI SYLLABLE BBAP;Lo;0;L;;;;;N;;;;;
11137 A062;YI SYLLABLE BBUOX;Lo;0;L;;;;;N;;;;;
11138 A063;YI SYLLABLE BBUO;Lo;0;L;;;;;N;;;;;
11139 A064;YI SYLLABLE BBUOP;Lo;0;L;;;;;N;;;;;
11140 A065;YI SYLLABLE BBOT;Lo;0;L;;;;;N;;;;;
11141 A066;YI SYLLABLE BBOX;Lo;0;L;;;;;N;;;;;
11142 A067;YI SYLLABLE BBO;Lo;0;L;;;;;N;;;;;
11143 A068;YI SYLLABLE BBOP;Lo;0;L;;;;;N;;;;;
11144 A069;YI SYLLABLE BBEX;Lo;0;L;;;;;N;;;;;
11145 A06A;YI SYLLABLE BBE;Lo;0;L;;;;;N;;;;;
11146 A06B;YI SYLLABLE BBEP;Lo;0;L;;;;;N;;;;;
11147 A06C;YI SYLLABLE BBUT;Lo;0;L;;;;;N;;;;;
11148 A06D;YI SYLLABLE BBUX;Lo;0;L;;;;;N;;;;;
11149 A06E;YI SYLLABLE BBU;Lo;0;L;;;;;N;;;;;
11150 A06F;YI SYLLABLE BBUP;Lo;0;L;;;;;N;;;;;
11151 A070;YI SYLLABLE BBURX;Lo;0;L;;;;;N;;;;;
11152 A071;YI SYLLABLE BBUR;Lo;0;L;;;;;N;;;;;
11153 A072;YI SYLLABLE BBYT;Lo;0;L;;;;;N;;;;;
11154 A073;YI SYLLABLE BBYX;Lo;0;L;;;;;N;;;;;
11155 A074;YI SYLLABLE BBY;Lo;0;L;;;;;N;;;;;
11156 A075;YI SYLLABLE BBYP;Lo;0;L;;;;;N;;;;;
11157 A076;YI SYLLABLE NBIT;Lo;0;L;;;;;N;;;;;
11158 A077;YI SYLLABLE NBIX;Lo;0;L;;;;;N;;;;;
11159 A078;YI SYLLABLE NBI;Lo;0;L;;;;;N;;;;;
11160 A079;YI SYLLABLE NBIP;Lo;0;L;;;;;N;;;;;
11161 A07A;YI SYLLABLE NBIEX;Lo;0;L;;;;;N;;;;;
11162 A07B;YI SYLLABLE NBIE;Lo;0;L;;;;;N;;;;;
11163 A07C;YI SYLLABLE NBIEP;Lo;0;L;;;;;N;;;;;
11164 A07D;YI SYLLABLE NBAT;Lo;0;L;;;;;N;;;;;
11165 A07E;YI SYLLABLE NBAX;Lo;0;L;;;;;N;;;;;
11166 A07F;YI SYLLABLE NBA;Lo;0;L;;;;;N;;;;;
11167 A080;YI SYLLABLE NBAP;Lo;0;L;;;;;N;;;;;
11168 A081;YI SYLLABLE NBOT;Lo;0;L;;;;;N;;;;;
11169 A082;YI SYLLABLE NBOX;Lo;0;L;;;;;N;;;;;
11170 A083;YI SYLLABLE NBO;Lo;0;L;;;;;N;;;;;
11171 A084;YI SYLLABLE NBOP;Lo;0;L;;;;;N;;;;;
11172 A085;YI SYLLABLE NBUT;Lo;0;L;;;;;N;;;;;
11173 A086;YI SYLLABLE NBUX;Lo;0;L;;;;;N;;;;;
11174 A087;YI SYLLABLE NBU;Lo;0;L;;;;;N;;;;;
11175 A088;YI SYLLABLE NBUP;Lo;0;L;;;;;N;;;;;
11176 A089;YI SYLLABLE NBURX;Lo;0;L;;;;;N;;;;;
11177 A08A;YI SYLLABLE NBUR;Lo;0;L;;;;;N;;;;;
11178 A08B;YI SYLLABLE NBYT;Lo;0;L;;;;;N;;;;;
11179 A08C;YI SYLLABLE NBYX;Lo;0;L;;;;;N;;;;;
11180 A08D;YI SYLLABLE NBY;Lo;0;L;;;;;N;;;;;
11181 A08E;YI SYLLABLE NBYP;Lo;0;L;;;;;N;;;;;
11182 A08F;YI SYLLABLE NBYRX;Lo;0;L;;;;;N;;;;;
11183 A090;YI SYLLABLE NBYR;Lo;0;L;;;;;N;;;;;
11184 A091;YI SYLLABLE HMIT;Lo;0;L;;;;;N;;;;;
11185 A092;YI SYLLABLE HMIX;Lo;0;L;;;;;N;;;;;
11186 A093;YI SYLLABLE HMI;Lo;0;L;;;;;N;;;;;
11187 A094;YI SYLLABLE HMIP;Lo;0;L;;;;;N;;;;;
11188 A095;YI SYLLABLE HMIEX;Lo;0;L;;;;;N;;;;;
11189 A096;YI SYLLABLE HMIE;Lo;0;L;;;;;N;;;;;
11190 A097;YI SYLLABLE HMIEP;Lo;0;L;;;;;N;;;;;
11191 A098;YI SYLLABLE HMAT;Lo;0;L;;;;;N;;;;;
11192 A099;YI SYLLABLE HMAX;Lo;0;L;;;;;N;;;;;
11193 A09A;YI SYLLABLE HMA;Lo;0;L;;;;;N;;;;;
11194 A09B;YI SYLLABLE HMAP;Lo;0;L;;;;;N;;;;;
11195 A09C;YI SYLLABLE HMUOX;Lo;0;L;;;;;N;;;;;
11196 A09D;YI SYLLABLE HMUO;Lo;0;L;;;;;N;;;;;
11197 A09E;YI SYLLABLE HMUOP;Lo;0;L;;;;;N;;;;;
11198 A09F;YI SYLLABLE HMOT;Lo;0;L;;;;;N;;;;;
11199 A0A0;YI SYLLABLE HMOX;Lo;0;L;;;;;N;;;;;
11200 A0A1;YI SYLLABLE HMO;Lo;0;L;;;;;N;;;;;
11201 A0A2;YI SYLLABLE HMOP;Lo;0;L;;;;;N;;;;;
11202 A0A3;YI SYLLABLE HMUT;Lo;0;L;;;;;N;;;;;
11203 A0A4;YI SYLLABLE HMUX;Lo;0;L;;;;;N;;;;;
11204 A0A5;YI SYLLABLE HMU;Lo;0;L;;;;;N;;;;;
11205 A0A6;YI SYLLABLE HMUP;Lo;0;L;;;;;N;;;;;
11206 A0A7;YI SYLLABLE HMURX;Lo;0;L;;;;;N;;;;;
11207 A0A8;YI SYLLABLE HMUR;Lo;0;L;;;;;N;;;;;
11208 A0A9;YI SYLLABLE HMYX;Lo;0;L;;;;;N;;;;;
11209 A0AA;YI SYLLABLE HMY;Lo;0;L;;;;;N;;;;;
11210 A0AB;YI SYLLABLE HMYP;Lo;0;L;;;;;N;;;;;
11211 A0AC;YI SYLLABLE HMYRX;Lo;0;L;;;;;N;;;;;
11212 A0AD;YI SYLLABLE HMYR;Lo;0;L;;;;;N;;;;;
11213 A0AE;YI SYLLABLE MIT;Lo;0;L;;;;;N;;;;;
11214 A0AF;YI SYLLABLE MIX;Lo;0;L;;;;;N;;;;;
11215 A0B0;YI SYLLABLE MI;Lo;0;L;;;;;N;;;;;
11216 A0B1;YI SYLLABLE MIP;Lo;0;L;;;;;N;;;;;
11217 A0B2;YI SYLLABLE MIEX;Lo;0;L;;;;;N;;;;;
11218 A0B3;YI SYLLABLE MIE;Lo;0;L;;;;;N;;;;;
11219 A0B4;YI SYLLABLE MIEP;Lo;0;L;;;;;N;;;;;
11220 A0B5;YI SYLLABLE MAT;Lo;0;L;;;;;N;;;;;
11221 A0B6;YI SYLLABLE MAX;Lo;0;L;;;;;N;;;;;
11222 A0B7;YI SYLLABLE MA;Lo;0;L;;;;;N;;;;;
11223 A0B8;YI SYLLABLE MAP;Lo;0;L;;;;;N;;;;;
11224 A0B9;YI SYLLABLE MUOT;Lo;0;L;;;;;N;;;;;
11225 A0BA;YI SYLLABLE MUOX;Lo;0;L;;;;;N;;;;;
11226 A0BB;YI SYLLABLE MUO;Lo;0;L;;;;;N;;;;;
11227 A0BC;YI SYLLABLE MUOP;Lo;0;L;;;;;N;;;;;
11228 A0BD;YI SYLLABLE MOT;Lo;0;L;;;;;N;;;;;
11229 A0BE;YI SYLLABLE MOX;Lo;0;L;;;;;N;;;;;
11230 A0BF;YI SYLLABLE MO;Lo;0;L;;;;;N;;;;;
11231 A0C0;YI SYLLABLE MOP;Lo;0;L;;;;;N;;;;;
11232 A0C1;YI SYLLABLE MEX;Lo;0;L;;;;;N;;;;;
11233 A0C2;YI SYLLABLE ME;Lo;0;L;;;;;N;;;;;
11234 A0C3;YI SYLLABLE MUT;Lo;0;L;;;;;N;;;;;
11235 A0C4;YI SYLLABLE MUX;Lo;0;L;;;;;N;;;;;
11236 A0C5;YI SYLLABLE MU;Lo;0;L;;;;;N;;;;;
11237 A0C6;YI SYLLABLE MUP;Lo;0;L;;;;;N;;;;;
11238 A0C7;YI SYLLABLE MURX;Lo;0;L;;;;;N;;;;;
11239 A0C8;YI SYLLABLE MUR;Lo;0;L;;;;;N;;;;;
11240 A0C9;YI SYLLABLE MYT;Lo;0;L;;;;;N;;;;;
11241 A0CA;YI SYLLABLE MYX;Lo;0;L;;;;;N;;;;;
11242 A0CB;YI SYLLABLE MY;Lo;0;L;;;;;N;;;;;
11243 A0CC;YI SYLLABLE MYP;Lo;0;L;;;;;N;;;;;
11244 A0CD;YI SYLLABLE FIT;Lo;0;L;;;;;N;;;;;
11245 A0CE;YI SYLLABLE FIX;Lo;0;L;;;;;N;;;;;
11246 A0CF;YI SYLLABLE FI;Lo;0;L;;;;;N;;;;;
11247 A0D0;YI SYLLABLE FIP;Lo;0;L;;;;;N;;;;;
11248 A0D1;YI SYLLABLE FAT;Lo;0;L;;;;;N;;;;;
11249 A0D2;YI SYLLABLE FAX;Lo;0;L;;;;;N;;;;;
11250 A0D3;YI SYLLABLE FA;Lo;0;L;;;;;N;;;;;
11251 A0D4;YI SYLLABLE FAP;Lo;0;L;;;;;N;;;;;
11252 A0D5;YI SYLLABLE FOX;Lo;0;L;;;;;N;;;;;
11253 A0D6;YI SYLLABLE FO;Lo;0;L;;;;;N;;;;;
11254 A0D7;YI SYLLABLE FOP;Lo;0;L;;;;;N;;;;;
11255 A0D8;YI SYLLABLE FUT;Lo;0;L;;;;;N;;;;;
11256 A0D9;YI SYLLABLE FUX;Lo;0;L;;;;;N;;;;;
11257 A0DA;YI SYLLABLE FU;Lo;0;L;;;;;N;;;;;
11258 A0DB;YI SYLLABLE FUP;Lo;0;L;;;;;N;;;;;
11259 A0DC;YI SYLLABLE FURX;Lo;0;L;;;;;N;;;;;
11260 A0DD;YI SYLLABLE FUR;Lo;0;L;;;;;N;;;;;
11261 A0DE;YI SYLLABLE FYT;Lo;0;L;;;;;N;;;;;
11262 A0DF;YI SYLLABLE FYX;Lo;0;L;;;;;N;;;;;
11263 A0E0;YI SYLLABLE FY;Lo;0;L;;;;;N;;;;;
11264 A0E1;YI SYLLABLE FYP;Lo;0;L;;;;;N;;;;;
11265 A0E2;YI SYLLABLE VIT;Lo;0;L;;;;;N;;;;;
11266 A0E3;YI SYLLABLE VIX;Lo;0;L;;;;;N;;;;;
11267 A0E4;YI SYLLABLE VI;Lo;0;L;;;;;N;;;;;
11268 A0E5;YI SYLLABLE VIP;Lo;0;L;;;;;N;;;;;
11269 A0E6;YI SYLLABLE VIET;Lo;0;L;;;;;N;;;;;
11270 A0E7;YI SYLLABLE VIEX;Lo;0;L;;;;;N;;;;;
11271 A0E8;YI SYLLABLE VIE;Lo;0;L;;;;;N;;;;;
11272 A0E9;YI SYLLABLE VIEP;Lo;0;L;;;;;N;;;;;
11273 A0EA;YI SYLLABLE VAT;Lo;0;L;;;;;N;;;;;
11274 A0EB;YI SYLLABLE VAX;Lo;0;L;;;;;N;;;;;
11275 A0EC;YI SYLLABLE VA;Lo;0;L;;;;;N;;;;;
11276 A0ED;YI SYLLABLE VAP;Lo;0;L;;;;;N;;;;;
11277 A0EE;YI SYLLABLE VOT;Lo;0;L;;;;;N;;;;;
11278 A0EF;YI SYLLABLE VOX;Lo;0;L;;;;;N;;;;;
11279 A0F0;YI SYLLABLE VO;Lo;0;L;;;;;N;;;;;
11280 A0F1;YI SYLLABLE VOP;Lo;0;L;;;;;N;;;;;
11281 A0F2;YI SYLLABLE VEX;Lo;0;L;;;;;N;;;;;
11282 A0F3;YI SYLLABLE VEP;Lo;0;L;;;;;N;;;;;
11283 A0F4;YI SYLLABLE VUT;Lo;0;L;;;;;N;;;;;
11284 A0F5;YI SYLLABLE VUX;Lo;0;L;;;;;N;;;;;
11285 A0F6;YI SYLLABLE VU;Lo;0;L;;;;;N;;;;;
11286 A0F7;YI SYLLABLE VUP;Lo;0;L;;;;;N;;;;;
11287 A0F8;YI SYLLABLE VURX;Lo;0;L;;;;;N;;;;;
11288 A0F9;YI SYLLABLE VUR;Lo;0;L;;;;;N;;;;;
11289 A0FA;YI SYLLABLE VYT;Lo;0;L;;;;;N;;;;;
11290 A0FB;YI SYLLABLE VYX;Lo;0;L;;;;;N;;;;;
11291 A0FC;YI SYLLABLE VY;Lo;0;L;;;;;N;;;;;
11292 A0FD;YI SYLLABLE VYP;Lo;0;L;;;;;N;;;;;
11293 A0FE;YI SYLLABLE VYRX;Lo;0;L;;;;;N;;;;;
11294 A0FF;YI SYLLABLE VYR;Lo;0;L;;;;;N;;;;;
11295 A100;YI SYLLABLE DIT;Lo;0;L;;;;;N;;;;;
11296 A101;YI SYLLABLE DIX;Lo;0;L;;;;;N;;;;;
11297 A102;YI SYLLABLE DI;Lo;0;L;;;;;N;;;;;
11298 A103;YI SYLLABLE DIP;Lo;0;L;;;;;N;;;;;
11299 A104;YI SYLLABLE DIEX;Lo;0;L;;;;;N;;;;;
11300 A105;YI SYLLABLE DIE;Lo;0;L;;;;;N;;;;;
11301 A106;YI SYLLABLE DIEP;Lo;0;L;;;;;N;;;;;
11302 A107;YI SYLLABLE DAT;Lo;0;L;;;;;N;;;;;
11303 A108;YI SYLLABLE DAX;Lo;0;L;;;;;N;;;;;
11304 A109;YI SYLLABLE DA;Lo;0;L;;;;;N;;;;;
11305 A10A;YI SYLLABLE DAP;Lo;0;L;;;;;N;;;;;
11306 A10B;YI SYLLABLE DUOX;Lo;0;L;;;;;N;;;;;
11307 A10C;YI SYLLABLE DUO;Lo;0;L;;;;;N;;;;;
11308 A10D;YI SYLLABLE DOT;Lo;0;L;;;;;N;;;;;
11309 A10E;YI SYLLABLE DOX;Lo;0;L;;;;;N;;;;;
11310 A10F;YI SYLLABLE DO;Lo;0;L;;;;;N;;;;;
11311 A110;YI SYLLABLE DOP;Lo;0;L;;;;;N;;;;;
11312 A111;YI SYLLABLE DEX;Lo;0;L;;;;;N;;;;;
11313 A112;YI SYLLABLE DE;Lo;0;L;;;;;N;;;;;
11314 A113;YI SYLLABLE DEP;Lo;0;L;;;;;N;;;;;
11315 A114;YI SYLLABLE DUT;Lo;0;L;;;;;N;;;;;
11316 A115;YI SYLLABLE DUX;Lo;0;L;;;;;N;;;;;
11317 A116;YI SYLLABLE DU;Lo;0;L;;;;;N;;;;;
11318 A117;YI SYLLABLE DUP;Lo;0;L;;;;;N;;;;;
11319 A118;YI SYLLABLE DURX;Lo;0;L;;;;;N;;;;;
11320 A119;YI SYLLABLE DUR;Lo;0;L;;;;;N;;;;;
11321 A11A;YI SYLLABLE TIT;Lo;0;L;;;;;N;;;;;
11322 A11B;YI SYLLABLE TIX;Lo;0;L;;;;;N;;;;;
11323 A11C;YI SYLLABLE TI;Lo;0;L;;;;;N;;;;;
11324 A11D;YI SYLLABLE TIP;Lo;0;L;;;;;N;;;;;
11325 A11E;YI SYLLABLE TIEX;Lo;0;L;;;;;N;;;;;
11326 A11F;YI SYLLABLE TIE;Lo;0;L;;;;;N;;;;;
11327 A120;YI SYLLABLE TIEP;Lo;0;L;;;;;N;;;;;
11328 A121;YI SYLLABLE TAT;Lo;0;L;;;;;N;;;;;
11329 A122;YI SYLLABLE TAX;Lo;0;L;;;;;N;;;;;
11330 A123;YI SYLLABLE TA;Lo;0;L;;;;;N;;;;;
11331 A124;YI SYLLABLE TAP;Lo;0;L;;;;;N;;;;;
11332 A125;YI SYLLABLE TUOT;Lo;0;L;;;;;N;;;;;
11333 A126;YI SYLLABLE TUOX;Lo;0;L;;;;;N;;;;;
11334 A127;YI SYLLABLE TUO;Lo;0;L;;;;;N;;;;;
11335 A128;YI SYLLABLE TUOP;Lo;0;L;;;;;N;;;;;
11336 A129;YI SYLLABLE TOT;Lo;0;L;;;;;N;;;;;
11337 A12A;YI SYLLABLE TOX;Lo;0;L;;;;;N;;;;;
11338 A12B;YI SYLLABLE TO;Lo;0;L;;;;;N;;;;;
11339 A12C;YI SYLLABLE TOP;Lo;0;L;;;;;N;;;;;
11340 A12D;YI SYLLABLE TEX;Lo;0;L;;;;;N;;;;;
11341 A12E;YI SYLLABLE TE;Lo;0;L;;;;;N;;;;;
11342 A12F;YI SYLLABLE TEP;Lo;0;L;;;;;N;;;;;
11343 A130;YI SYLLABLE TUT;Lo;0;L;;;;;N;;;;;
11344 A131;YI SYLLABLE TUX;Lo;0;L;;;;;N;;;;;
11345 A132;YI SYLLABLE TU;Lo;0;L;;;;;N;;;;;
11346 A133;YI SYLLABLE TUP;Lo;0;L;;;;;N;;;;;
11347 A134;YI SYLLABLE TURX;Lo;0;L;;;;;N;;;;;
11348 A135;YI SYLLABLE TUR;Lo;0;L;;;;;N;;;;;
11349 A136;YI SYLLABLE DDIT;Lo;0;L;;;;;N;;;;;
11350 A137;YI SYLLABLE DDIX;Lo;0;L;;;;;N;;;;;
11351 A138;YI SYLLABLE DDI;Lo;0;L;;;;;N;;;;;
11352 A139;YI SYLLABLE DDIP;Lo;0;L;;;;;N;;;;;
11353 A13A;YI SYLLABLE DDIEX;Lo;0;L;;;;;N;;;;;
11354 A13B;YI SYLLABLE DDIE;Lo;0;L;;;;;N;;;;;
11355 A13C;YI SYLLABLE DDIEP;Lo;0;L;;;;;N;;;;;
11356 A13D;YI SYLLABLE DDAT;Lo;0;L;;;;;N;;;;;
11357 A13E;YI SYLLABLE DDAX;Lo;0;L;;;;;N;;;;;
11358 A13F;YI SYLLABLE DDA;Lo;0;L;;;;;N;;;;;
11359 A140;YI SYLLABLE DDAP;Lo;0;L;;;;;N;;;;;
11360 A141;YI SYLLABLE DDUOX;Lo;0;L;;;;;N;;;;;
11361 A142;YI SYLLABLE DDUO;Lo;0;L;;;;;N;;;;;
11362 A143;YI SYLLABLE DDUOP;Lo;0;L;;;;;N;;;;;
11363 A144;YI SYLLABLE DDOT;Lo;0;L;;;;;N;;;;;
11364 A145;YI SYLLABLE DDOX;Lo;0;L;;;;;N;;;;;
11365 A146;YI SYLLABLE DDO;Lo;0;L;;;;;N;;;;;
11366 A147;YI SYLLABLE DDOP;Lo;0;L;;;;;N;;;;;
11367 A148;YI SYLLABLE DDEX;Lo;0;L;;;;;N;;;;;
11368 A149;YI SYLLABLE DDE;Lo;0;L;;;;;N;;;;;
11369 A14A;YI SYLLABLE DDEP;Lo;0;L;;;;;N;;;;;
11370 A14B;YI SYLLABLE DDUT;Lo;0;L;;;;;N;;;;;
11371 A14C;YI SYLLABLE DDUX;Lo;0;L;;;;;N;;;;;
11372 A14D;YI SYLLABLE DDU;Lo;0;L;;;;;N;;;;;
11373 A14E;YI SYLLABLE DDUP;Lo;0;L;;;;;N;;;;;
11374 A14F;YI SYLLABLE DDURX;Lo;0;L;;;;;N;;;;;
11375 A150;YI SYLLABLE DDUR;Lo;0;L;;;;;N;;;;;
11376 A151;YI SYLLABLE NDIT;Lo;0;L;;;;;N;;;;;
11377 A152;YI SYLLABLE NDIX;Lo;0;L;;;;;N;;;;;
11378 A153;YI SYLLABLE NDI;Lo;0;L;;;;;N;;;;;
11379 A154;YI SYLLABLE NDIP;Lo;0;L;;;;;N;;;;;
11380 A155;YI SYLLABLE NDIEX;Lo;0;L;;;;;N;;;;;
11381 A156;YI SYLLABLE NDIE;Lo;0;L;;;;;N;;;;;
11382 A157;YI SYLLABLE NDAT;Lo;0;L;;;;;N;;;;;
11383 A158;YI SYLLABLE NDAX;Lo;0;L;;;;;N;;;;;
11384 A159;YI SYLLABLE NDA;Lo;0;L;;;;;N;;;;;
11385 A15A;YI SYLLABLE NDAP;Lo;0;L;;;;;N;;;;;
11386 A15B;YI SYLLABLE NDOT;Lo;0;L;;;;;N;;;;;
11387 A15C;YI SYLLABLE NDOX;Lo;0;L;;;;;N;;;;;
11388 A15D;YI SYLLABLE NDO;Lo;0;L;;;;;N;;;;;
11389 A15E;YI SYLLABLE NDOP;Lo;0;L;;;;;N;;;;;
11390 A15F;YI SYLLABLE NDEX;Lo;0;L;;;;;N;;;;;
11391 A160;YI SYLLABLE NDE;Lo;0;L;;;;;N;;;;;
11392 A161;YI SYLLABLE NDEP;Lo;0;L;;;;;N;;;;;
11393 A162;YI SYLLABLE NDUT;Lo;0;L;;;;;N;;;;;
11394 A163;YI SYLLABLE NDUX;Lo;0;L;;;;;N;;;;;
11395 A164;YI SYLLABLE NDU;Lo;0;L;;;;;N;;;;;
11396 A165;YI SYLLABLE NDUP;Lo;0;L;;;;;N;;;;;
11397 A166;YI SYLLABLE NDURX;Lo;0;L;;;;;N;;;;;
11398 A167;YI SYLLABLE NDUR;Lo;0;L;;;;;N;;;;;
11399 A168;YI SYLLABLE HNIT;Lo;0;L;;;;;N;;;;;
11400 A169;YI SYLLABLE HNIX;Lo;0;L;;;;;N;;;;;
11401 A16A;YI SYLLABLE HNI;Lo;0;L;;;;;N;;;;;
11402 A16B;YI SYLLABLE HNIP;Lo;0;L;;;;;N;;;;;
11403 A16C;YI SYLLABLE HNIET;Lo;0;L;;;;;N;;;;;
11404 A16D;YI SYLLABLE HNIEX;Lo;0;L;;;;;N;;;;;
11405 A16E;YI SYLLABLE HNIE;Lo;0;L;;;;;N;;;;;
11406 A16F;YI SYLLABLE HNIEP;Lo;0;L;;;;;N;;;;;
11407 A170;YI SYLLABLE HNAT;Lo;0;L;;;;;N;;;;;
11408 A171;YI SYLLABLE HNAX;Lo;0;L;;;;;N;;;;;
11409 A172;YI SYLLABLE HNA;Lo;0;L;;;;;N;;;;;
11410 A173;YI SYLLABLE HNAP;Lo;0;L;;;;;N;;;;;
11411 A174;YI SYLLABLE HNUOX;Lo;0;L;;;;;N;;;;;
11412 A175;YI SYLLABLE HNUO;Lo;0;L;;;;;N;;;;;
11413 A176;YI SYLLABLE HNOT;Lo;0;L;;;;;N;;;;;
11414 A177;YI SYLLABLE HNOX;Lo;0;L;;;;;N;;;;;
11415 A178;YI SYLLABLE HNOP;Lo;0;L;;;;;N;;;;;
11416 A179;YI SYLLABLE HNEX;Lo;0;L;;;;;N;;;;;
11417 A17A;YI SYLLABLE HNE;Lo;0;L;;;;;N;;;;;
11418 A17B;YI SYLLABLE HNEP;Lo;0;L;;;;;N;;;;;
11419 A17C;YI SYLLABLE HNUT;Lo;0;L;;;;;N;;;;;
11420 A17D;YI SYLLABLE NIT;Lo;0;L;;;;;N;;;;;
11421 A17E;YI SYLLABLE NIX;Lo;0;L;;;;;N;;;;;
11422 A17F;YI SYLLABLE NI;Lo;0;L;;;;;N;;;;;
11423 A180;YI SYLLABLE NIP;Lo;0;L;;;;;N;;;;;
11424 A181;YI SYLLABLE NIEX;Lo;0;L;;;;;N;;;;;
11425 A182;YI SYLLABLE NIE;Lo;0;L;;;;;N;;;;;
11426 A183;YI SYLLABLE NIEP;Lo;0;L;;;;;N;;;;;
11427 A184;YI SYLLABLE NAX;Lo;0;L;;;;;N;;;;;
11428 A185;YI SYLLABLE NA;Lo;0;L;;;;;N;;;;;
11429 A186;YI SYLLABLE NAP;Lo;0;L;;;;;N;;;;;
11430 A187;YI SYLLABLE NUOX;Lo;0;L;;;;;N;;;;;
11431 A188;YI SYLLABLE NUO;Lo;0;L;;;;;N;;;;;
11432 A189;YI SYLLABLE NUOP;Lo;0;L;;;;;N;;;;;
11433 A18A;YI SYLLABLE NOT;Lo;0;L;;;;;N;;;;;
11434 A18B;YI SYLLABLE NOX;Lo;0;L;;;;;N;;;;;
11435 A18C;YI SYLLABLE NO;Lo;0;L;;;;;N;;;;;
11436 A18D;YI SYLLABLE NOP;Lo;0;L;;;;;N;;;;;
11437 A18E;YI SYLLABLE NEX;Lo;0;L;;;;;N;;;;;
11438 A18F;YI SYLLABLE NE;Lo;0;L;;;;;N;;;;;
11439 A190;YI SYLLABLE NEP;Lo;0;L;;;;;N;;;;;
11440 A191;YI SYLLABLE NUT;Lo;0;L;;;;;N;;;;;
11441 A192;YI SYLLABLE NUX;Lo;0;L;;;;;N;;;;;
11442 A193;YI SYLLABLE NU;Lo;0;L;;;;;N;;;;;
11443 A194;YI SYLLABLE NUP;Lo;0;L;;;;;N;;;;;
11444 A195;YI SYLLABLE NURX;Lo;0;L;;;;;N;;;;;
11445 A196;YI SYLLABLE NUR;Lo;0;L;;;;;N;;;;;
11446 A197;YI SYLLABLE HLIT;Lo;0;L;;;;;N;;;;;
11447 A198;YI SYLLABLE HLIX;Lo;0;L;;;;;N;;;;;
11448 A199;YI SYLLABLE HLI;Lo;0;L;;;;;N;;;;;
11449 A19A;YI SYLLABLE HLIP;Lo;0;L;;;;;N;;;;;
11450 A19B;YI SYLLABLE HLIEX;Lo;0;L;;;;;N;;;;;
11451 A19C;YI SYLLABLE HLIE;Lo;0;L;;;;;N;;;;;
11452 A19D;YI SYLLABLE HLIEP;Lo;0;L;;;;;N;;;;;
11453 A19E;YI SYLLABLE HLAT;Lo;0;L;;;;;N;;;;;
11454 A19F;YI SYLLABLE HLAX;Lo;0;L;;;;;N;;;;;
11455 A1A0;YI SYLLABLE HLA;Lo;0;L;;;;;N;;;;;
11456 A1A1;YI SYLLABLE HLAP;Lo;0;L;;;;;N;;;;;
11457 A1A2;YI SYLLABLE HLUOX;Lo;0;L;;;;;N;;;;;
11458 A1A3;YI SYLLABLE HLUO;Lo;0;L;;;;;N;;;;;
11459 A1A4;YI SYLLABLE HLUOP;Lo;0;L;;;;;N;;;;;
11460 A1A5;YI SYLLABLE HLOX;Lo;0;L;;;;;N;;;;;
11461 A1A6;YI SYLLABLE HLO;Lo;0;L;;;;;N;;;;;
11462 A1A7;YI SYLLABLE HLOP;Lo;0;L;;;;;N;;;;;
11463 A1A8;YI SYLLABLE HLEX;Lo;0;L;;;;;N;;;;;
11464 A1A9;YI SYLLABLE HLE;Lo;0;L;;;;;N;;;;;
11465 A1AA;YI SYLLABLE HLEP;Lo;0;L;;;;;N;;;;;
11466 A1AB;YI SYLLABLE HLUT;Lo;0;L;;;;;N;;;;;
11467 A1AC;YI SYLLABLE HLUX;Lo;0;L;;;;;N;;;;;
11468 A1AD;YI SYLLABLE HLU;Lo;0;L;;;;;N;;;;;
11469 A1AE;YI SYLLABLE HLUP;Lo;0;L;;;;;N;;;;;
11470 A1AF;YI SYLLABLE HLURX;Lo;0;L;;;;;N;;;;;
11471 A1B0;YI SYLLABLE HLUR;Lo;0;L;;;;;N;;;;;
11472 A1B1;YI SYLLABLE HLYT;Lo;0;L;;;;;N;;;;;
11473 A1B2;YI SYLLABLE HLYX;Lo;0;L;;;;;N;;;;;
11474 A1B3;YI SYLLABLE HLY;Lo;0;L;;;;;N;;;;;
11475 A1B4;YI SYLLABLE HLYP;Lo;0;L;;;;;N;;;;;
11476 A1B5;YI SYLLABLE HLYRX;Lo;0;L;;;;;N;;;;;
11477 A1B6;YI SYLLABLE HLYR;Lo;0;L;;;;;N;;;;;
11478 A1B7;YI SYLLABLE LIT;Lo;0;L;;;;;N;;;;;
11479 A1B8;YI SYLLABLE LIX;Lo;0;L;;;;;N;;;;;
11480 A1B9;YI SYLLABLE LI;Lo;0;L;;;;;N;;;;;
11481 A1BA;YI SYLLABLE LIP;Lo;0;L;;;;;N;;;;;
11482 A1BB;YI SYLLABLE LIET;Lo;0;L;;;;;N;;;;;
11483 A1BC;YI SYLLABLE LIEX;Lo;0;L;;;;;N;;;;;
11484 A1BD;YI SYLLABLE LIE;Lo;0;L;;;;;N;;;;;
11485 A1BE;YI SYLLABLE LIEP;Lo;0;L;;;;;N;;;;;
11486 A1BF;YI SYLLABLE LAT;Lo;0;L;;;;;N;;;;;
11487 A1C0;YI SYLLABLE LAX;Lo;0;L;;;;;N;;;;;
11488 A1C1;YI SYLLABLE LA;Lo;0;L;;;;;N;;;;;
11489 A1C2;YI SYLLABLE LAP;Lo;0;L;;;;;N;;;;;
11490 A1C3;YI SYLLABLE LUOT;Lo;0;L;;;;;N;;;;;
11491 A1C4;YI SYLLABLE LUOX;Lo;0;L;;;;;N;;;;;
11492 A1C5;YI SYLLABLE LUO;Lo;0;L;;;;;N;;;;;
11493 A1C6;YI SYLLABLE LUOP;Lo;0;L;;;;;N;;;;;
11494 A1C7;YI SYLLABLE LOT;Lo;0;L;;;;;N;;;;;
11495 A1C8;YI SYLLABLE LOX;Lo;0;L;;;;;N;;;;;
11496 A1C9;YI SYLLABLE LO;Lo;0;L;;;;;N;;;;;
11497 A1CA;YI SYLLABLE LOP;Lo;0;L;;;;;N;;;;;
11498 A1CB;YI SYLLABLE LEX;Lo;0;L;;;;;N;;;;;
11499 A1CC;YI SYLLABLE LE;Lo;0;L;;;;;N;;;;;
11500 A1CD;YI SYLLABLE LEP;Lo;0;L;;;;;N;;;;;
11501 A1CE;YI SYLLABLE LUT;Lo;0;L;;;;;N;;;;;
11502 A1CF;YI SYLLABLE LUX;Lo;0;L;;;;;N;;;;;
11503 A1D0;YI SYLLABLE LU;Lo;0;L;;;;;N;;;;;
11504 A1D1;YI SYLLABLE LUP;Lo;0;L;;;;;N;;;;;
11505 A1D2;YI SYLLABLE LURX;Lo;0;L;;;;;N;;;;;
11506 A1D3;YI SYLLABLE LUR;Lo;0;L;;;;;N;;;;;
11507 A1D4;YI SYLLABLE LYT;Lo;0;L;;;;;N;;;;;
11508 A1D5;YI SYLLABLE LYX;Lo;0;L;;;;;N;;;;;
11509 A1D6;YI SYLLABLE LY;Lo;0;L;;;;;N;;;;;
11510 A1D7;YI SYLLABLE LYP;Lo;0;L;;;;;N;;;;;
11511 A1D8;YI SYLLABLE LYRX;Lo;0;L;;;;;N;;;;;
11512 A1D9;YI SYLLABLE LYR;Lo;0;L;;;;;N;;;;;
11513 A1DA;YI SYLLABLE GIT;Lo;0;L;;;;;N;;;;;
11514 A1DB;YI SYLLABLE GIX;Lo;0;L;;;;;N;;;;;
11515 A1DC;YI SYLLABLE GI;Lo;0;L;;;;;N;;;;;
11516 A1DD;YI SYLLABLE GIP;Lo;0;L;;;;;N;;;;;
11517 A1DE;YI SYLLABLE GIET;Lo;0;L;;;;;N;;;;;
11518 A1DF;YI SYLLABLE GIEX;Lo;0;L;;;;;N;;;;;
11519 A1E0;YI SYLLABLE GIE;Lo;0;L;;;;;N;;;;;
11520 A1E1;YI SYLLABLE GIEP;Lo;0;L;;;;;N;;;;;
11521 A1E2;YI SYLLABLE GAT;Lo;0;L;;;;;N;;;;;
11522 A1E3;YI SYLLABLE GAX;Lo;0;L;;;;;N;;;;;
11523 A1E4;YI SYLLABLE GA;Lo;0;L;;;;;N;;;;;
11524 A1E5;YI SYLLABLE GAP;Lo;0;L;;;;;N;;;;;
11525 A1E6;YI SYLLABLE GUOT;Lo;0;L;;;;;N;;;;;
11526 A1E7;YI SYLLABLE GUOX;Lo;0;L;;;;;N;;;;;
11527 A1E8;YI SYLLABLE GUO;Lo;0;L;;;;;N;;;;;
11528 A1E9;YI SYLLABLE GUOP;Lo;0;L;;;;;N;;;;;
11529 A1EA;YI SYLLABLE GOT;Lo;0;L;;;;;N;;;;;
11530 A1EB;YI SYLLABLE GOX;Lo;0;L;;;;;N;;;;;
11531 A1EC;YI SYLLABLE GO;Lo;0;L;;;;;N;;;;;
11532 A1ED;YI SYLLABLE GOP;Lo;0;L;;;;;N;;;;;
11533 A1EE;YI SYLLABLE GET;Lo;0;L;;;;;N;;;;;
11534 A1EF;YI SYLLABLE GEX;Lo;0;L;;;;;N;;;;;
11535 A1F0;YI SYLLABLE GE;Lo;0;L;;;;;N;;;;;
11536 A1F1;YI SYLLABLE GEP;Lo;0;L;;;;;N;;;;;
11537 A1F2;YI SYLLABLE GUT;Lo;0;L;;;;;N;;;;;
11538 A1F3;YI SYLLABLE GUX;Lo;0;L;;;;;N;;;;;
11539 A1F4;YI SYLLABLE GU;Lo;0;L;;;;;N;;;;;
11540 A1F5;YI SYLLABLE GUP;Lo;0;L;;;;;N;;;;;
11541 A1F6;YI SYLLABLE GURX;Lo;0;L;;;;;N;;;;;
11542 A1F7;YI SYLLABLE GUR;Lo;0;L;;;;;N;;;;;
11543 A1F8;YI SYLLABLE KIT;Lo;0;L;;;;;N;;;;;
11544 A1F9;YI SYLLABLE KIX;Lo;0;L;;;;;N;;;;;
11545 A1FA;YI SYLLABLE KI;Lo;0;L;;;;;N;;;;;
11546 A1FB;YI SYLLABLE KIP;Lo;0;L;;;;;N;;;;;
11547 A1FC;YI SYLLABLE KIEX;Lo;0;L;;;;;N;;;;;
11548 A1FD;YI SYLLABLE KIE;Lo;0;L;;;;;N;;;;;
11549 A1FE;YI SYLLABLE KIEP;Lo;0;L;;;;;N;;;;;
11550 A1FF;YI SYLLABLE KAT;Lo;0;L;;;;;N;;;;;
11551 A200;YI SYLLABLE KAX;Lo;0;L;;;;;N;;;;;
11552 A201;YI SYLLABLE KA;Lo;0;L;;;;;N;;;;;
11553 A202;YI SYLLABLE KAP;Lo;0;L;;;;;N;;;;;
11554 A203;YI SYLLABLE KUOX;Lo;0;L;;;;;N;;;;;
11555 A204;YI SYLLABLE KUO;Lo;0;L;;;;;N;;;;;
11556 A205;YI SYLLABLE KUOP;Lo;0;L;;;;;N;;;;;
11557 A206;YI SYLLABLE KOT;Lo;0;L;;;;;N;;;;;
11558 A207;YI SYLLABLE KOX;Lo;0;L;;;;;N;;;;;
11559 A208;YI SYLLABLE KO;Lo;0;L;;;;;N;;;;;
11560 A209;YI SYLLABLE KOP;Lo;0;L;;;;;N;;;;;
11561 A20A;YI SYLLABLE KET;Lo;0;L;;;;;N;;;;;
11562 A20B;YI SYLLABLE KEX;Lo;0;L;;;;;N;;;;;
11563 A20C;YI SYLLABLE KE;Lo;0;L;;;;;N;;;;;
11564 A20D;YI SYLLABLE KEP;Lo;0;L;;;;;N;;;;;
11565 A20E;YI SYLLABLE KUT;Lo;0;L;;;;;N;;;;;
11566 A20F;YI SYLLABLE KUX;Lo;0;L;;;;;N;;;;;
11567 A210;YI SYLLABLE KU;Lo;0;L;;;;;N;;;;;
11568 A211;YI SYLLABLE KUP;Lo;0;L;;;;;N;;;;;
11569 A212;YI SYLLABLE KURX;Lo;0;L;;;;;N;;;;;
11570 A213;YI SYLLABLE KUR;Lo;0;L;;;;;N;;;;;
11571 A214;YI SYLLABLE GGIT;Lo;0;L;;;;;N;;;;;
11572 A215;YI SYLLABLE GGIX;Lo;0;L;;;;;N;;;;;
11573 A216;YI SYLLABLE GGI;Lo;0;L;;;;;N;;;;;
11574 A217;YI SYLLABLE GGIEX;Lo;0;L;;;;;N;;;;;
11575 A218;YI SYLLABLE GGIE;Lo;0;L;;;;;N;;;;;
11576 A219;YI SYLLABLE GGIEP;Lo;0;L;;;;;N;;;;;
11577 A21A;YI SYLLABLE GGAT;Lo;0;L;;;;;N;;;;;
11578 A21B;YI SYLLABLE GGAX;Lo;0;L;;;;;N;;;;;
11579 A21C;YI SYLLABLE GGA;Lo;0;L;;;;;N;;;;;
11580 A21D;YI SYLLABLE GGAP;Lo;0;L;;;;;N;;;;;
11581 A21E;YI SYLLABLE GGUOT;Lo;0;L;;;;;N;;;;;
11582 A21F;YI SYLLABLE GGUOX;Lo;0;L;;;;;N;;;;;
11583 A220;YI SYLLABLE GGUO;Lo;0;L;;;;;N;;;;;
11584 A221;YI SYLLABLE GGUOP;Lo;0;L;;;;;N;;;;;
11585 A222;YI SYLLABLE GGOT;Lo;0;L;;;;;N;;;;;
11586 A223;YI SYLLABLE GGOX;Lo;0;L;;;;;N;;;;;
11587 A224;YI SYLLABLE GGO;Lo;0;L;;;;;N;;;;;
11588 A225;YI SYLLABLE GGOP;Lo;0;L;;;;;N;;;;;
11589 A226;YI SYLLABLE GGET;Lo;0;L;;;;;N;;;;;
11590 A227;YI SYLLABLE GGEX;Lo;0;L;;;;;N;;;;;
11591 A228;YI SYLLABLE GGE;Lo;0;L;;;;;N;;;;;
11592 A229;YI SYLLABLE GGEP;Lo;0;L;;;;;N;;;;;
11593 A22A;YI SYLLABLE GGUT;Lo;0;L;;;;;N;;;;;
11594 A22B;YI SYLLABLE GGUX;Lo;0;L;;;;;N;;;;;
11595 A22C;YI SYLLABLE GGU;Lo;0;L;;;;;N;;;;;
11596 A22D;YI SYLLABLE GGUP;Lo;0;L;;;;;N;;;;;
11597 A22E;YI SYLLABLE GGURX;Lo;0;L;;;;;N;;;;;
11598 A22F;YI SYLLABLE GGUR;Lo;0;L;;;;;N;;;;;
11599 A230;YI SYLLABLE MGIEX;Lo;0;L;;;;;N;;;;;
11600 A231;YI SYLLABLE MGIE;Lo;0;L;;;;;N;;;;;
11601 A232;YI SYLLABLE MGAT;Lo;0;L;;;;;N;;;;;
11602 A233;YI SYLLABLE MGAX;Lo;0;L;;;;;N;;;;;
11603 A234;YI SYLLABLE MGA;Lo;0;L;;;;;N;;;;;
11604 A235;YI SYLLABLE MGAP;Lo;0;L;;;;;N;;;;;
11605 A236;YI SYLLABLE MGUOX;Lo;0;L;;;;;N;;;;;
11606 A237;YI SYLLABLE MGUO;Lo;0;L;;;;;N;;;;;
11607 A238;YI SYLLABLE MGUOP;Lo;0;L;;;;;N;;;;;
11608 A239;YI SYLLABLE MGOT;Lo;0;L;;;;;N;;;;;
11609 A23A;YI SYLLABLE MGOX;Lo;0;L;;;;;N;;;;;
11610 A23B;YI SYLLABLE MGO;Lo;0;L;;;;;N;;;;;
11611 A23C;YI SYLLABLE MGOP;Lo;0;L;;;;;N;;;;;
11612 A23D;YI SYLLABLE MGEX;Lo;0;L;;;;;N;;;;;
11613 A23E;YI SYLLABLE MGE;Lo;0;L;;;;;N;;;;;
11614 A23F;YI SYLLABLE MGEP;Lo;0;L;;;;;N;;;;;
11615 A240;YI SYLLABLE MGUT;Lo;0;L;;;;;N;;;;;
11616 A241;YI SYLLABLE MGUX;Lo;0;L;;;;;N;;;;;
11617 A242;YI SYLLABLE MGU;Lo;0;L;;;;;N;;;;;
11618 A243;YI SYLLABLE MGUP;Lo;0;L;;;;;N;;;;;
11619 A244;YI SYLLABLE MGURX;Lo;0;L;;;;;N;;;;;
11620 A245;YI SYLLABLE MGUR;Lo;0;L;;;;;N;;;;;
11621 A246;YI SYLLABLE HXIT;Lo;0;L;;;;;N;;;;;
11622 A247;YI SYLLABLE HXIX;Lo;0;L;;;;;N;;;;;
11623 A248;YI SYLLABLE HXI;Lo;0;L;;;;;N;;;;;
11624 A249;YI SYLLABLE HXIP;Lo;0;L;;;;;N;;;;;
11625 A24A;YI SYLLABLE HXIET;Lo;0;L;;;;;N;;;;;
11626 A24B;YI SYLLABLE HXIEX;Lo;0;L;;;;;N;;;;;
11627 A24C;YI SYLLABLE HXIE;Lo;0;L;;;;;N;;;;;
11628 A24D;YI SYLLABLE HXIEP;Lo;0;L;;;;;N;;;;;
11629 A24E;YI SYLLABLE HXAT;Lo;0;L;;;;;N;;;;;
11630 A24F;YI SYLLABLE HXAX;Lo;0;L;;;;;N;;;;;
11631 A250;YI SYLLABLE HXA;Lo;0;L;;;;;N;;;;;
11632 A251;YI SYLLABLE HXAP;Lo;0;L;;;;;N;;;;;
11633 A252;YI SYLLABLE HXUOT;Lo;0;L;;;;;N;;;;;
11634 A253;YI SYLLABLE HXUOX;Lo;0;L;;;;;N;;;;;
11635 A254;YI SYLLABLE HXUO;Lo;0;L;;;;;N;;;;;
11636 A255;YI SYLLABLE HXUOP;Lo;0;L;;;;;N;;;;;
11637 A256;YI SYLLABLE HXOT;Lo;0;L;;;;;N;;;;;
11638 A257;YI SYLLABLE HXOX;Lo;0;L;;;;;N;;;;;
11639 A258;YI SYLLABLE HXO;Lo;0;L;;;;;N;;;;;
11640 A259;YI SYLLABLE HXOP;Lo;0;L;;;;;N;;;;;
11641 A25A;YI SYLLABLE HXEX;Lo;0;L;;;;;N;;;;;
11642 A25B;YI SYLLABLE HXE;Lo;0;L;;;;;N;;;;;
11643 A25C;YI SYLLABLE HXEP;Lo;0;L;;;;;N;;;;;
11644 A25D;YI SYLLABLE NGIEX;Lo;0;L;;;;;N;;;;;
11645 A25E;YI SYLLABLE NGIE;Lo;0;L;;;;;N;;;;;
11646 A25F;YI SYLLABLE NGIEP;Lo;0;L;;;;;N;;;;;
11647 A260;YI SYLLABLE NGAT;Lo;0;L;;;;;N;;;;;
11648 A261;YI SYLLABLE NGAX;Lo;0;L;;;;;N;;;;;
11649 A262;YI SYLLABLE NGA;Lo;0;L;;;;;N;;;;;
11650 A263;YI SYLLABLE NGAP;Lo;0;L;;;;;N;;;;;
11651 A264;YI SYLLABLE NGUOT;Lo;0;L;;;;;N;;;;;
11652 A265;YI SYLLABLE NGUOX;Lo;0;L;;;;;N;;;;;
11653 A266;YI SYLLABLE NGUO;Lo;0;L;;;;;N;;;;;
11654 A267;YI SYLLABLE NGOT;Lo;0;L;;;;;N;;;;;
11655 A268;YI SYLLABLE NGOX;Lo;0;L;;;;;N;;;;;
11656 A269;YI SYLLABLE NGO;Lo;0;L;;;;;N;;;;;
11657 A26A;YI SYLLABLE NGOP;Lo;0;L;;;;;N;;;;;
11658 A26B;YI SYLLABLE NGEX;Lo;0;L;;;;;N;;;;;
11659 A26C;YI SYLLABLE NGE;Lo;0;L;;;;;N;;;;;
11660 A26D;YI SYLLABLE NGEP;Lo;0;L;;;;;N;;;;;
11661 A26E;YI SYLLABLE HIT;Lo;0;L;;;;;N;;;;;
11662 A26F;YI SYLLABLE HIEX;Lo;0;L;;;;;N;;;;;
11663 A270;YI SYLLABLE HIE;Lo;0;L;;;;;N;;;;;
11664 A271;YI SYLLABLE HAT;Lo;0;L;;;;;N;;;;;
11665 A272;YI SYLLABLE HAX;Lo;0;L;;;;;N;;;;;
11666 A273;YI SYLLABLE HA;Lo;0;L;;;;;N;;;;;
11667 A274;YI SYLLABLE HAP;Lo;0;L;;;;;N;;;;;
11668 A275;YI SYLLABLE HUOT;Lo;0;L;;;;;N;;;;;
11669 A276;YI SYLLABLE HUOX;Lo;0;L;;;;;N;;;;;
11670 A277;YI SYLLABLE HUO;Lo;0;L;;;;;N;;;;;
11671 A278;YI SYLLABLE HUOP;Lo;0;L;;;;;N;;;;;
11672 A279;YI SYLLABLE HOT;Lo;0;L;;;;;N;;;;;
11673 A27A;YI SYLLABLE HOX;Lo;0;L;;;;;N;;;;;
11674 A27B;YI SYLLABLE HO;Lo;0;L;;;;;N;;;;;
11675 A27C;YI SYLLABLE HOP;Lo;0;L;;;;;N;;;;;
11676 A27D;YI SYLLABLE HEX;Lo;0;L;;;;;N;;;;;
11677 A27E;YI SYLLABLE HE;Lo;0;L;;;;;N;;;;;
11678 A27F;YI SYLLABLE HEP;Lo;0;L;;;;;N;;;;;
11679 A280;YI SYLLABLE WAT;Lo;0;L;;;;;N;;;;;
11680 A281;YI SYLLABLE WAX;Lo;0;L;;;;;N;;;;;
11681 A282;YI SYLLABLE WA;Lo;0;L;;;;;N;;;;;
11682 A283;YI SYLLABLE WAP;Lo;0;L;;;;;N;;;;;
11683 A284;YI SYLLABLE WUOX;Lo;0;L;;;;;N;;;;;
11684 A285;YI SYLLABLE WUO;Lo;0;L;;;;;N;;;;;
11685 A286;YI SYLLABLE WUOP;Lo;0;L;;;;;N;;;;;
11686 A287;YI SYLLABLE WOX;Lo;0;L;;;;;N;;;;;
11687 A288;YI SYLLABLE WO;Lo;0;L;;;;;N;;;;;
11688 A289;YI SYLLABLE WOP;Lo;0;L;;;;;N;;;;;
11689 A28A;YI SYLLABLE WEX;Lo;0;L;;;;;N;;;;;
11690 A28B;YI SYLLABLE WE;Lo;0;L;;;;;N;;;;;
11691 A28C;YI SYLLABLE WEP;Lo;0;L;;;;;N;;;;;
11692 A28D;YI SYLLABLE ZIT;Lo;0;L;;;;;N;;;;;
11693 A28E;YI SYLLABLE ZIX;Lo;0;L;;;;;N;;;;;
11694 A28F;YI SYLLABLE ZI;Lo;0;L;;;;;N;;;;;
11695 A290;YI SYLLABLE ZIP;Lo;0;L;;;;;N;;;;;
11696 A291;YI SYLLABLE ZIEX;Lo;0;L;;;;;N;;;;;
11697 A292;YI SYLLABLE ZIE;Lo;0;L;;;;;N;;;;;
11698 A293;YI SYLLABLE ZIEP;Lo;0;L;;;;;N;;;;;
11699 A294;YI SYLLABLE ZAT;Lo;0;L;;;;;N;;;;;
11700 A295;YI SYLLABLE ZAX;Lo;0;L;;;;;N;;;;;
11701 A296;YI SYLLABLE ZA;Lo;0;L;;;;;N;;;;;
11702 A297;YI SYLLABLE ZAP;Lo;0;L;;;;;N;;;;;
11703 A298;YI SYLLABLE ZUOX;Lo;0;L;;;;;N;;;;;
11704 A299;YI SYLLABLE ZUO;Lo;0;L;;;;;N;;;;;
11705 A29A;YI SYLLABLE ZUOP;Lo;0;L;;;;;N;;;;;
11706 A29B;YI SYLLABLE ZOT;Lo;0;L;;;;;N;;;;;
11707 A29C;YI SYLLABLE ZOX;Lo;0;L;;;;;N;;;;;
11708 A29D;YI SYLLABLE ZO;Lo;0;L;;;;;N;;;;;
11709 A29E;YI SYLLABLE ZOP;Lo;0;L;;;;;N;;;;;
11710 A29F;YI SYLLABLE ZEX;Lo;0;L;;;;;N;;;;;
11711 A2A0;YI SYLLABLE ZE;Lo;0;L;;;;;N;;;;;
11712 A2A1;YI SYLLABLE ZEP;Lo;0;L;;;;;N;;;;;
11713 A2A2;YI SYLLABLE ZUT;Lo;0;L;;;;;N;;;;;
11714 A2A3;YI SYLLABLE ZUX;Lo;0;L;;;;;N;;;;;
11715 A2A4;YI SYLLABLE ZU;Lo;0;L;;;;;N;;;;;
11716 A2A5;YI SYLLABLE ZUP;Lo;0;L;;;;;N;;;;;
11717 A2A6;YI SYLLABLE ZURX;Lo;0;L;;;;;N;;;;;
11718 A2A7;YI SYLLABLE ZUR;Lo;0;L;;;;;N;;;;;
11719 A2A8;YI SYLLABLE ZYT;Lo;0;L;;;;;N;;;;;
11720 A2A9;YI SYLLABLE ZYX;Lo;0;L;;;;;N;;;;;
11721 A2AA;YI SYLLABLE ZY;Lo;0;L;;;;;N;;;;;
11722 A2AB;YI SYLLABLE ZYP;Lo;0;L;;;;;N;;;;;
11723 A2AC;YI SYLLABLE ZYRX;Lo;0;L;;;;;N;;;;;
11724 A2AD;YI SYLLABLE ZYR;Lo;0;L;;;;;N;;;;;
11725 A2AE;YI SYLLABLE CIT;Lo;0;L;;;;;N;;;;;
11726 A2AF;YI SYLLABLE CIX;Lo;0;L;;;;;N;;;;;
11727 A2B0;YI SYLLABLE CI;Lo;0;L;;;;;N;;;;;
11728 A2B1;YI SYLLABLE CIP;Lo;0;L;;;;;N;;;;;
11729 A2B2;YI SYLLABLE CIET;Lo;0;L;;;;;N;;;;;
11730 A2B3;YI SYLLABLE CIEX;Lo;0;L;;;;;N;;;;;
11731 A2B4;YI SYLLABLE CIE;Lo;0;L;;;;;N;;;;;
11732 A2B5;YI SYLLABLE CIEP;Lo;0;L;;;;;N;;;;;
11733 A2B6;YI SYLLABLE CAT;Lo;0;L;;;;;N;;;;;
11734 A2B7;YI SYLLABLE CAX;Lo;0;L;;;;;N;;;;;
11735 A2B8;YI SYLLABLE CA;Lo;0;L;;;;;N;;;;;
11736 A2B9;YI SYLLABLE CAP;Lo;0;L;;;;;N;;;;;
11737 A2BA;YI SYLLABLE CUOX;Lo;0;L;;;;;N;;;;;
11738 A2BB;YI SYLLABLE CUO;Lo;0;L;;;;;N;;;;;
11739 A2BC;YI SYLLABLE CUOP;Lo;0;L;;;;;N;;;;;
11740 A2BD;YI SYLLABLE COT;Lo;0;L;;;;;N;;;;;
11741 A2BE;YI SYLLABLE COX;Lo;0;L;;;;;N;;;;;
11742 A2BF;YI SYLLABLE CO;Lo;0;L;;;;;N;;;;;
11743 A2C0;YI SYLLABLE COP;Lo;0;L;;;;;N;;;;;
11744 A2C1;YI SYLLABLE CEX;Lo;0;L;;;;;N;;;;;
11745 A2C2;YI SYLLABLE CE;Lo;0;L;;;;;N;;;;;
11746 A2C3;YI SYLLABLE CEP;Lo;0;L;;;;;N;;;;;
11747 A2C4;YI SYLLABLE CUT;Lo;0;L;;;;;N;;;;;
11748 A2C5;YI SYLLABLE CUX;Lo;0;L;;;;;N;;;;;
11749 A2C6;YI SYLLABLE CU;Lo;0;L;;;;;N;;;;;
11750 A2C7;YI SYLLABLE CUP;Lo;0;L;;;;;N;;;;;
11751 A2C8;YI SYLLABLE CURX;Lo;0;L;;;;;N;;;;;
11752 A2C9;YI SYLLABLE CUR;Lo;0;L;;;;;N;;;;;
11753 A2CA;YI SYLLABLE CYT;Lo;0;L;;;;;N;;;;;
11754 A2CB;YI SYLLABLE CYX;Lo;0;L;;;;;N;;;;;
11755 A2CC;YI SYLLABLE CY;Lo;0;L;;;;;N;;;;;
11756 A2CD;YI SYLLABLE CYP;Lo;0;L;;;;;N;;;;;
11757 A2CE;YI SYLLABLE CYRX;Lo;0;L;;;;;N;;;;;
11758 A2CF;YI SYLLABLE CYR;Lo;0;L;;;;;N;;;;;
11759 A2D0;YI SYLLABLE ZZIT;Lo;0;L;;;;;N;;;;;
11760 A2D1;YI SYLLABLE ZZIX;Lo;0;L;;;;;N;;;;;
11761 A2D2;YI SYLLABLE ZZI;Lo;0;L;;;;;N;;;;;
11762 A2D3;YI SYLLABLE ZZIP;Lo;0;L;;;;;N;;;;;
11763 A2D4;YI SYLLABLE ZZIET;Lo;0;L;;;;;N;;;;;
11764 A2D5;YI SYLLABLE ZZIEX;Lo;0;L;;;;;N;;;;;
11765 A2D6;YI SYLLABLE ZZIE;Lo;0;L;;;;;N;;;;;
11766 A2D7;YI SYLLABLE ZZIEP;Lo;0;L;;;;;N;;;;;
11767 A2D8;YI SYLLABLE ZZAT;Lo;0;L;;;;;N;;;;;
11768 A2D9;YI SYLLABLE ZZAX;Lo;0;L;;;;;N;;;;;
11769 A2DA;YI SYLLABLE ZZA;Lo;0;L;;;;;N;;;;;
11770 A2DB;YI SYLLABLE ZZAP;Lo;0;L;;;;;N;;;;;
11771 A2DC;YI SYLLABLE ZZOX;Lo;0;L;;;;;N;;;;;
11772 A2DD;YI SYLLABLE ZZO;Lo;0;L;;;;;N;;;;;
11773 A2DE;YI SYLLABLE ZZOP;Lo;0;L;;;;;N;;;;;
11774 A2DF;YI SYLLABLE ZZEX;Lo;0;L;;;;;N;;;;;
11775 A2E0;YI SYLLABLE ZZE;Lo;0;L;;;;;N;;;;;
11776 A2E1;YI SYLLABLE ZZEP;Lo;0;L;;;;;N;;;;;
11777 A2E2;YI SYLLABLE ZZUX;Lo;0;L;;;;;N;;;;;
11778 A2E3;YI SYLLABLE ZZU;Lo;0;L;;;;;N;;;;;
11779 A2E4;YI SYLLABLE ZZUP;Lo;0;L;;;;;N;;;;;
11780 A2E5;YI SYLLABLE ZZURX;Lo;0;L;;;;;N;;;;;
11781 A2E6;YI SYLLABLE ZZUR;Lo;0;L;;;;;N;;;;;
11782 A2E7;YI SYLLABLE ZZYT;Lo;0;L;;;;;N;;;;;
11783 A2E8;YI SYLLABLE ZZYX;Lo;0;L;;;;;N;;;;;
11784 A2E9;YI SYLLABLE ZZY;Lo;0;L;;;;;N;;;;;
11785 A2EA;YI SYLLABLE ZZYP;Lo;0;L;;;;;N;;;;;
11786 A2EB;YI SYLLABLE ZZYRX;Lo;0;L;;;;;N;;;;;
11787 A2EC;YI SYLLABLE ZZYR;Lo;0;L;;;;;N;;;;;
11788 A2ED;YI SYLLABLE NZIT;Lo;0;L;;;;;N;;;;;
11789 A2EE;YI SYLLABLE NZIX;Lo;0;L;;;;;N;;;;;
11790 A2EF;YI SYLLABLE NZI;Lo;0;L;;;;;N;;;;;
11791 A2F0;YI SYLLABLE NZIP;Lo;0;L;;;;;N;;;;;
11792 A2F1;YI SYLLABLE NZIEX;Lo;0;L;;;;;N;;;;;
11793 A2F2;YI SYLLABLE NZIE;Lo;0;L;;;;;N;;;;;
11794 A2F3;YI SYLLABLE NZIEP;Lo;0;L;;;;;N;;;;;
11795 A2F4;YI SYLLABLE NZAT;Lo;0;L;;;;;N;;;;;
11796 A2F5;YI SYLLABLE NZAX;Lo;0;L;;;;;N;;;;;
11797 A2F6;YI SYLLABLE NZA;Lo;0;L;;;;;N;;;;;
11798 A2F7;YI SYLLABLE NZAP;Lo;0;L;;;;;N;;;;;
11799 A2F8;YI SYLLABLE NZUOX;Lo;0;L;;;;;N;;;;;
11800 A2F9;YI SYLLABLE NZUO;Lo;0;L;;;;;N;;;;;
11801 A2FA;YI SYLLABLE NZOX;Lo;0;L;;;;;N;;;;;
11802 A2FB;YI SYLLABLE NZOP;Lo;0;L;;;;;N;;;;;
11803 A2FC;YI SYLLABLE NZEX;Lo;0;L;;;;;N;;;;;
11804 A2FD;YI SYLLABLE NZE;Lo;0;L;;;;;N;;;;;
11805 A2FE;YI SYLLABLE NZUX;Lo;0;L;;;;;N;;;;;
11806 A2FF;YI SYLLABLE NZU;Lo;0;L;;;;;N;;;;;
11807 A300;YI SYLLABLE NZUP;Lo;0;L;;;;;N;;;;;
11808 A301;YI SYLLABLE NZURX;Lo;0;L;;;;;N;;;;;
11809 A302;YI SYLLABLE NZUR;Lo;0;L;;;;;N;;;;;
11810 A303;YI SYLLABLE NZYT;Lo;0;L;;;;;N;;;;;
11811 A304;YI SYLLABLE NZYX;Lo;0;L;;;;;N;;;;;
11812 A305;YI SYLLABLE NZY;Lo;0;L;;;;;N;;;;;
11813 A306;YI SYLLABLE NZYP;Lo;0;L;;;;;N;;;;;
11814 A307;YI SYLLABLE NZYRX;Lo;0;L;;;;;N;;;;;
11815 A308;YI SYLLABLE NZYR;Lo;0;L;;;;;N;;;;;
11816 A309;YI SYLLABLE SIT;Lo;0;L;;;;;N;;;;;
11817 A30A;YI SYLLABLE SIX;Lo;0;L;;;;;N;;;;;
11818 A30B;YI SYLLABLE SI;Lo;0;L;;;;;N;;;;;
11819 A30C;YI SYLLABLE SIP;Lo;0;L;;;;;N;;;;;
11820 A30D;YI SYLLABLE SIEX;Lo;0;L;;;;;N;;;;;
11821 A30E;YI SYLLABLE SIE;Lo;0;L;;;;;N;;;;;
11822 A30F;YI SYLLABLE SIEP;Lo;0;L;;;;;N;;;;;
11823 A310;YI SYLLABLE SAT;Lo;0;L;;;;;N;;;;;
11824 A311;YI SYLLABLE SAX;Lo;0;L;;;;;N;;;;;
11825 A312;YI SYLLABLE SA;Lo;0;L;;;;;N;;;;;
11826 A313;YI SYLLABLE SAP;Lo;0;L;;;;;N;;;;;
11827 A314;YI SYLLABLE SUOX;Lo;0;L;;;;;N;;;;;
11828 A315;YI SYLLABLE SUO;Lo;0;L;;;;;N;;;;;
11829 A316;YI SYLLABLE SUOP;Lo;0;L;;;;;N;;;;;
11830 A317;YI SYLLABLE SOT;Lo;0;L;;;;;N;;;;;
11831 A318;YI SYLLABLE SOX;Lo;0;L;;;;;N;;;;;
11832 A319;YI SYLLABLE SO;Lo;0;L;;;;;N;;;;;
11833 A31A;YI SYLLABLE SOP;Lo;0;L;;;;;N;;;;;
11834 A31B;YI SYLLABLE SEX;Lo;0;L;;;;;N;;;;;
11835 A31C;YI SYLLABLE SE;Lo;0;L;;;;;N;;;;;
11836 A31D;YI SYLLABLE SEP;Lo;0;L;;;;;N;;;;;
11837 A31E;YI SYLLABLE SUT;Lo;0;L;;;;;N;;;;;
11838 A31F;YI SYLLABLE SUX;Lo;0;L;;;;;N;;;;;
11839 A320;YI SYLLABLE SU;Lo;0;L;;;;;N;;;;;
11840 A321;YI SYLLABLE SUP;Lo;0;L;;;;;N;;;;;
11841 A322;YI SYLLABLE SURX;Lo;0;L;;;;;N;;;;;
11842 A323;YI SYLLABLE SUR;Lo;0;L;;;;;N;;;;;
11843 A324;YI SYLLABLE SYT;Lo;0;L;;;;;N;;;;;
11844 A325;YI SYLLABLE SYX;Lo;0;L;;;;;N;;;;;
11845 A326;YI SYLLABLE SY;Lo;0;L;;;;;N;;;;;
11846 A327;YI SYLLABLE SYP;Lo;0;L;;;;;N;;;;;
11847 A328;YI SYLLABLE SYRX;Lo;0;L;;;;;N;;;;;
11848 A329;YI SYLLABLE SYR;Lo;0;L;;;;;N;;;;;
11849 A32A;YI SYLLABLE SSIT;Lo;0;L;;;;;N;;;;;
11850 A32B;YI SYLLABLE SSIX;Lo;0;L;;;;;N;;;;;
11851 A32C;YI SYLLABLE SSI;Lo;0;L;;;;;N;;;;;
11852 A32D;YI SYLLABLE SSIP;Lo;0;L;;;;;N;;;;;
11853 A32E;YI SYLLABLE SSIEX;Lo;0;L;;;;;N;;;;;
11854 A32F;YI SYLLABLE SSIE;Lo;0;L;;;;;N;;;;;
11855 A330;YI SYLLABLE SSIEP;Lo;0;L;;;;;N;;;;;
11856 A331;YI SYLLABLE SSAT;Lo;0;L;;;;;N;;;;;
11857 A332;YI SYLLABLE SSAX;Lo;0;L;;;;;N;;;;;
11858 A333;YI SYLLABLE SSA;Lo;0;L;;;;;N;;;;;
11859 A334;YI SYLLABLE SSAP;Lo;0;L;;;;;N;;;;;
11860 A335;YI SYLLABLE SSOT;Lo;0;L;;;;;N;;;;;
11861 A336;YI SYLLABLE SSOX;Lo;0;L;;;;;N;;;;;
11862 A337;YI SYLLABLE SSO;Lo;0;L;;;;;N;;;;;
11863 A338;YI SYLLABLE SSOP;Lo;0;L;;;;;N;;;;;
11864 A339;YI SYLLABLE SSEX;Lo;0;L;;;;;N;;;;;
11865 A33A;YI SYLLABLE SSE;Lo;0;L;;;;;N;;;;;
11866 A33B;YI SYLLABLE SSEP;Lo;0;L;;;;;N;;;;;
11867 A33C;YI SYLLABLE SSUT;Lo;0;L;;;;;N;;;;;
11868 A33D;YI SYLLABLE SSUX;Lo;0;L;;;;;N;;;;;
11869 A33E;YI SYLLABLE SSU;Lo;0;L;;;;;N;;;;;
11870 A33F;YI SYLLABLE SSUP;Lo;0;L;;;;;N;;;;;
11871 A340;YI SYLLABLE SSYT;Lo;0;L;;;;;N;;;;;
11872 A341;YI SYLLABLE SSYX;Lo;0;L;;;;;N;;;;;
11873 A342;YI SYLLABLE SSY;Lo;0;L;;;;;N;;;;;
11874 A343;YI SYLLABLE SSYP;Lo;0;L;;;;;N;;;;;
11875 A344;YI SYLLABLE SSYRX;Lo;0;L;;;;;N;;;;;
11876 A345;YI SYLLABLE SSYR;Lo;0;L;;;;;N;;;;;
11877 A346;YI SYLLABLE ZHAT;Lo;0;L;;;;;N;;;;;
11878 A347;YI SYLLABLE ZHAX;Lo;0;L;;;;;N;;;;;
11879 A348;YI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;;
11880 A349;YI SYLLABLE ZHAP;Lo;0;L;;;;;N;;;;;
11881 A34A;YI SYLLABLE ZHUOX;Lo;0;L;;;;;N;;;;;
11882 A34B;YI SYLLABLE ZHUO;Lo;0;L;;;;;N;;;;;
11883 A34C;YI SYLLABLE ZHUOP;Lo;0;L;;;;;N;;;;;
11884 A34D;YI SYLLABLE ZHOT;Lo;0;L;;;;;N;;;;;
11885 A34E;YI SYLLABLE ZHOX;Lo;0;L;;;;;N;;;;;
11886 A34F;YI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;;
11887 A350;YI SYLLABLE ZHOP;Lo;0;L;;;;;N;;;;;
11888 A351;YI SYLLABLE ZHET;Lo;0;L;;;;;N;;;;;
11889 A352;YI SYLLABLE ZHEX;Lo;0;L;;;;;N;;;;;
11890 A353;YI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;;
11891 A354;YI SYLLABLE ZHEP;Lo;0;L;;;;;N;;;;;
11892 A355;YI SYLLABLE ZHUT;Lo;0;L;;;;;N;;;;;
11893 A356;YI SYLLABLE ZHUX;Lo;0;L;;;;;N;;;;;
11894 A357;YI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;;
11895 A358;YI SYLLABLE ZHUP;Lo;0;L;;;;;N;;;;;
11896 A359;YI SYLLABLE ZHURX;Lo;0;L;;;;;N;;;;;
11897 A35A;YI SYLLABLE ZHUR;Lo;0;L;;;;;N;;;;;
11898 A35B;YI SYLLABLE ZHYT;Lo;0;L;;;;;N;;;;;
11899 A35C;YI SYLLABLE ZHYX;Lo;0;L;;;;;N;;;;;
11900 A35D;YI SYLLABLE ZHY;Lo;0;L;;;;;N;;;;;
11901 A35E;YI SYLLABLE ZHYP;Lo;0;L;;;;;N;;;;;
11902 A35F;YI SYLLABLE ZHYRX;Lo;0;L;;;;;N;;;;;
11903 A360;YI SYLLABLE ZHYR;Lo;0;L;;;;;N;;;;;
11904 A361;YI SYLLABLE CHAT;Lo;0;L;;;;;N;;;;;
11905 A362;YI SYLLABLE CHAX;Lo;0;L;;;;;N;;;;;
11906 A363;YI SYLLABLE CHA;Lo;0;L;;;;;N;;;;;
11907 A364;YI SYLLABLE CHAP;Lo;0;L;;;;;N;;;;;
11908 A365;YI SYLLABLE CHUOT;Lo;0;L;;;;;N;;;;;
11909 A366;YI SYLLABLE CHUOX;Lo;0;L;;;;;N;;;;;
11910 A367;YI SYLLABLE CHUO;Lo;0;L;;;;;N;;;;;
11911 A368;YI SYLLABLE CHUOP;Lo;0;L;;;;;N;;;;;
11912 A369;YI SYLLABLE CHOT;Lo;0;L;;;;;N;;;;;
11913 A36A;YI SYLLABLE CHOX;Lo;0;L;;;;;N;;;;;
11914 A36B;YI SYLLABLE CHO;Lo;0;L;;;;;N;;;;;
11915 A36C;YI SYLLABLE CHOP;Lo;0;L;;;;;N;;;;;
11916 A36D;YI SYLLABLE CHET;Lo;0;L;;;;;N;;;;;
11917 A36E;YI SYLLABLE CHEX;Lo;0;L;;;;;N;;;;;
11918 A36F;YI SYLLABLE CHE;Lo;0;L;;;;;N;;;;;
11919 A370;YI SYLLABLE CHEP;Lo;0;L;;;;;N;;;;;
11920 A371;YI SYLLABLE CHUX;Lo;0;L;;;;;N;;;;;
11921 A372;YI SYLLABLE CHU;Lo;0;L;;;;;N;;;;;
11922 A373;YI SYLLABLE CHUP;Lo;0;L;;;;;N;;;;;
11923 A374;YI SYLLABLE CHURX;Lo;0;L;;;;;N;;;;;
11924 A375;YI SYLLABLE CHUR;Lo;0;L;;;;;N;;;;;
11925 A376;YI SYLLABLE CHYT;Lo;0;L;;;;;N;;;;;
11926 A377;YI SYLLABLE CHYX;Lo;0;L;;;;;N;;;;;
11927 A378;YI SYLLABLE CHY;Lo;0;L;;;;;N;;;;;
11928 A379;YI SYLLABLE CHYP;Lo;0;L;;;;;N;;;;;
11929 A37A;YI SYLLABLE CHYRX;Lo;0;L;;;;;N;;;;;
11930 A37B;YI SYLLABLE CHYR;Lo;0;L;;;;;N;;;;;
11931 A37C;YI SYLLABLE RRAX;Lo;0;L;;;;;N;;;;;
11932 A37D;YI SYLLABLE RRA;Lo;0;L;;;;;N;;;;;
11933 A37E;YI SYLLABLE RRUOX;Lo;0;L;;;;;N;;;;;
11934 A37F;YI SYLLABLE RRUO;Lo;0;L;;;;;N;;;;;
11935 A380;YI SYLLABLE RROT;Lo;0;L;;;;;N;;;;;
11936 A381;YI SYLLABLE RROX;Lo;0;L;;;;;N;;;;;
11937 A382;YI SYLLABLE RRO;Lo;0;L;;;;;N;;;;;
11938 A383;YI SYLLABLE RROP;Lo;0;L;;;;;N;;;;;
11939 A384;YI SYLLABLE RRET;Lo;0;L;;;;;N;;;;;
11940 A385;YI SYLLABLE RREX;Lo;0;L;;;;;N;;;;;
11941 A386;YI SYLLABLE RRE;Lo;0;L;;;;;N;;;;;
11942 A387;YI SYLLABLE RREP;Lo;0;L;;;;;N;;;;;
11943 A388;YI SYLLABLE RRUT;Lo;0;L;;;;;N;;;;;
11944 A389;YI SYLLABLE RRUX;Lo;0;L;;;;;N;;;;;
11945 A38A;YI SYLLABLE RRU;Lo;0;L;;;;;N;;;;;
11946 A38B;YI SYLLABLE RRUP;Lo;0;L;;;;;N;;;;;
11947 A38C;YI SYLLABLE RRURX;Lo;0;L;;;;;N;;;;;
11948 A38D;YI SYLLABLE RRUR;Lo;0;L;;;;;N;;;;;
11949 A38E;YI SYLLABLE RRYT;Lo;0;L;;;;;N;;;;;
11950 A38F;YI SYLLABLE RRYX;Lo;0;L;;;;;N;;;;;
11951 A390;YI SYLLABLE RRY;Lo;0;L;;;;;N;;;;;
11952 A391;YI SYLLABLE RRYP;Lo;0;L;;;;;N;;;;;
11953 A392;YI SYLLABLE RRYRX;Lo;0;L;;;;;N;;;;;
11954 A393;YI SYLLABLE RRYR;Lo;0;L;;;;;N;;;;;
11955 A394;YI SYLLABLE NRAT;Lo;0;L;;;;;N;;;;;
11956 A395;YI SYLLABLE NRAX;Lo;0;L;;;;;N;;;;;
11957 A396;YI SYLLABLE NRA;Lo;0;L;;;;;N;;;;;
11958 A397;YI SYLLABLE NRAP;Lo;0;L;;;;;N;;;;;
11959 A398;YI SYLLABLE NROX;Lo;0;L;;;;;N;;;;;
11960 A399;YI SYLLABLE NRO;Lo;0;L;;;;;N;;;;;
11961 A39A;YI SYLLABLE NROP;Lo;0;L;;;;;N;;;;;
11962 A39B;YI SYLLABLE NRET;Lo;0;L;;;;;N;;;;;
11963 A39C;YI SYLLABLE NREX;Lo;0;L;;;;;N;;;;;
11964 A39D;YI SYLLABLE NRE;Lo;0;L;;;;;N;;;;;
11965 A39E;YI SYLLABLE NREP;Lo;0;L;;;;;N;;;;;
11966 A39F;YI SYLLABLE NRUT;Lo;0;L;;;;;N;;;;;
11967 A3A0;YI SYLLABLE NRUX;Lo;0;L;;;;;N;;;;;
11968 A3A1;YI SYLLABLE NRU;Lo;0;L;;;;;N;;;;;
11969 A3A2;YI SYLLABLE NRUP;Lo;0;L;;;;;N;;;;;
11970 A3A3;YI SYLLABLE NRURX;Lo;0;L;;;;;N;;;;;
11971 A3A4;YI SYLLABLE NRUR;Lo;0;L;;;;;N;;;;;
11972 A3A5;YI SYLLABLE NRYT;Lo;0;L;;;;;N;;;;;
11973 A3A6;YI SYLLABLE NRYX;Lo;0;L;;;;;N;;;;;
11974 A3A7;YI SYLLABLE NRY;Lo;0;L;;;;;N;;;;;
11975 A3A8;YI SYLLABLE NRYP;Lo;0;L;;;;;N;;;;;
11976 A3A9;YI SYLLABLE NRYRX;Lo;0;L;;;;;N;;;;;
11977 A3AA;YI SYLLABLE NRYR;Lo;0;L;;;;;N;;;;;
11978 A3AB;YI SYLLABLE SHAT;Lo;0;L;;;;;N;;;;;
11979 A3AC;YI SYLLABLE SHAX;Lo;0;L;;;;;N;;;;;
11980 A3AD;YI SYLLABLE SHA;Lo;0;L;;;;;N;;;;;
11981 A3AE;YI SYLLABLE SHAP;Lo;0;L;;;;;N;;;;;
11982 A3AF;YI SYLLABLE SHUOX;Lo;0;L;;;;;N;;;;;
11983 A3B0;YI SYLLABLE SHUO;Lo;0;L;;;;;N;;;;;
11984 A3B1;YI SYLLABLE SHUOP;Lo;0;L;;;;;N;;;;;
11985 A3B2;YI SYLLABLE SHOT;Lo;0;L;;;;;N;;;;;
11986 A3B3;YI SYLLABLE SHOX;Lo;0;L;;;;;N;;;;;
11987 A3B4;YI SYLLABLE SHO;Lo;0;L;;;;;N;;;;;
11988 A3B5;YI SYLLABLE SHOP;Lo;0;L;;;;;N;;;;;
11989 A3B6;YI SYLLABLE SHET;Lo;0;L;;;;;N;;;;;
11990 A3B7;YI SYLLABLE SHEX;Lo;0;L;;;;;N;;;;;
11991 A3B8;YI SYLLABLE SHE;Lo;0;L;;;;;N;;;;;
11992 A3B9;YI SYLLABLE SHEP;Lo;0;L;;;;;N;;;;;
11993 A3BA;YI SYLLABLE SHUT;Lo;0;L;;;;;N;;;;;
11994 A3BB;YI SYLLABLE SHUX;Lo;0;L;;;;;N;;;;;
11995 A3BC;YI SYLLABLE SHU;Lo;0;L;;;;;N;;;;;
11996 A3BD;YI SYLLABLE SHUP;Lo;0;L;;;;;N;;;;;
11997 A3BE;YI SYLLABLE SHURX;Lo;0;L;;;;;N;;;;;
11998 A3BF;YI SYLLABLE SHUR;Lo;0;L;;;;;N;;;;;
11999 A3C0;YI SYLLABLE SHYT;Lo;0;L;;;;;N;;;;;
12000 A3C1;YI SYLLABLE SHYX;Lo;0;L;;;;;N;;;;;
12001 A3C2;YI SYLLABLE SHY;Lo;0;L;;;;;N;;;;;
12002 A3C3;YI SYLLABLE SHYP;Lo;0;L;;;;;N;;;;;
12003 A3C4;YI SYLLABLE SHYRX;Lo;0;L;;;;;N;;;;;
12004 A3C5;YI SYLLABLE SHYR;Lo;0;L;;;;;N;;;;;
12005 A3C6;YI SYLLABLE RAT;Lo;0;L;;;;;N;;;;;
12006 A3C7;YI SYLLABLE RAX;Lo;0;L;;;;;N;;;;;
12007 A3C8;YI SYLLABLE RA;Lo;0;L;;;;;N;;;;;
12008 A3C9;YI SYLLABLE RAP;Lo;0;L;;;;;N;;;;;
12009 A3CA;YI SYLLABLE RUOX;Lo;0;L;;;;;N;;;;;
12010 A3CB;YI SYLLABLE RUO;Lo;0;L;;;;;N;;;;;
12011 A3CC;YI SYLLABLE RUOP;Lo;0;L;;;;;N;;;;;
12012 A3CD;YI SYLLABLE ROT;Lo;0;L;;;;;N;;;;;
12013 A3CE;YI SYLLABLE ROX;Lo;0;L;;;;;N;;;;;
12014 A3CF;YI SYLLABLE RO;Lo;0;L;;;;;N;;;;;
12015 A3D0;YI SYLLABLE ROP;Lo;0;L;;;;;N;;;;;
12016 A3D1;YI SYLLABLE REX;Lo;0;L;;;;;N;;;;;
12017 A3D2;YI SYLLABLE RE;Lo;0;L;;;;;N;;;;;
12018 A3D3;YI SYLLABLE REP;Lo;0;L;;;;;N;;;;;
12019 A3D4;YI SYLLABLE RUT;Lo;0;L;;;;;N;;;;;
12020 A3D5;YI SYLLABLE RUX;Lo;0;L;;;;;N;;;;;
12021 A3D6;YI SYLLABLE RU;Lo;0;L;;;;;N;;;;;
12022 A3D7;YI SYLLABLE RUP;Lo;0;L;;;;;N;;;;;
12023 A3D8;YI SYLLABLE RURX;Lo;0;L;;;;;N;;;;;
12024 A3D9;YI SYLLABLE RUR;Lo;0;L;;;;;N;;;;;
12025 A3DA;YI SYLLABLE RYT;Lo;0;L;;;;;N;;;;;
12026 A3DB;YI SYLLABLE RYX;Lo;0;L;;;;;N;;;;;
12027 A3DC;YI SYLLABLE RY;Lo;0;L;;;;;N;;;;;
12028 A3DD;YI SYLLABLE RYP;Lo;0;L;;;;;N;;;;;
12029 A3DE;YI SYLLABLE RYRX;Lo;0;L;;;;;N;;;;;
12030 A3DF;YI SYLLABLE RYR;Lo;0;L;;;;;N;;;;;
12031 A3E0;YI SYLLABLE JIT;Lo;0;L;;;;;N;;;;;
12032 A3E1;YI SYLLABLE JIX;Lo;0;L;;;;;N;;;;;
12033 A3E2;YI SYLLABLE JI;Lo;0;L;;;;;N;;;;;
12034 A3E3;YI SYLLABLE JIP;Lo;0;L;;;;;N;;;;;
12035 A3E4;YI SYLLABLE JIET;Lo;0;L;;;;;N;;;;;
12036 A3E5;YI SYLLABLE JIEX;Lo;0;L;;;;;N;;;;;
12037 A3E6;YI SYLLABLE JIE;Lo;0;L;;;;;N;;;;;
12038 A3E7;YI SYLLABLE JIEP;Lo;0;L;;;;;N;;;;;
12039 A3E8;YI SYLLABLE JUOT;Lo;0;L;;;;;N;;;;;
12040 A3E9;YI SYLLABLE JUOX;Lo;0;L;;;;;N;;;;;
12041 A3EA;YI SYLLABLE JUO;Lo;0;L;;;;;N;;;;;
12042 A3EB;YI SYLLABLE JUOP;Lo;0;L;;;;;N;;;;;
12043 A3EC;YI SYLLABLE JOT;Lo;0;L;;;;;N;;;;;
12044 A3ED;YI SYLLABLE JOX;Lo;0;L;;;;;N;;;;;
12045 A3EE;YI SYLLABLE JO;Lo;0;L;;;;;N;;;;;
12046 A3EF;YI SYLLABLE JOP;Lo;0;L;;;;;N;;;;;
12047 A3F0;YI SYLLABLE JUT;Lo;0;L;;;;;N;;;;;
12048 A3F1;YI SYLLABLE JUX;Lo;0;L;;;;;N;;;;;
12049 A3F2;YI SYLLABLE JU;Lo;0;L;;;;;N;;;;;
12050 A3F3;YI SYLLABLE JUP;Lo;0;L;;;;;N;;;;;
12051 A3F4;YI SYLLABLE JURX;Lo;0;L;;;;;N;;;;;
12052 A3F5;YI SYLLABLE JUR;Lo;0;L;;;;;N;;;;;
12053 A3F6;YI SYLLABLE JYT;Lo;0;L;;;;;N;;;;;
12054 A3F7;YI SYLLABLE JYX;Lo;0;L;;;;;N;;;;;
12055 A3F8;YI SYLLABLE JY;Lo;0;L;;;;;N;;;;;
12056 A3F9;YI SYLLABLE JYP;Lo;0;L;;;;;N;;;;;
12057 A3FA;YI SYLLABLE JYRX;Lo;0;L;;;;;N;;;;;
12058 A3FB;YI SYLLABLE JYR;Lo;0;L;;;;;N;;;;;
12059 A3FC;YI SYLLABLE QIT;Lo;0;L;;;;;N;;;;;
12060 A3FD;YI SYLLABLE QIX;Lo;0;L;;;;;N;;;;;
12061 A3FE;YI SYLLABLE QI;Lo;0;L;;;;;N;;;;;
12062 A3FF;YI SYLLABLE QIP;Lo;0;L;;;;;N;;;;;
12063 A400;YI SYLLABLE QIET;Lo;0;L;;;;;N;;;;;
12064 A401;YI SYLLABLE QIEX;Lo;0;L;;;;;N;;;;;
12065 A402;YI SYLLABLE QIE;Lo;0;L;;;;;N;;;;;
12066 A403;YI SYLLABLE QIEP;Lo;0;L;;;;;N;;;;;
12067 A404;YI SYLLABLE QUOT;Lo;0;L;;;;;N;;;;;
12068 A405;YI SYLLABLE QUOX;Lo;0;L;;;;;N;;;;;
12069 A406;YI SYLLABLE QUO;Lo;0;L;;;;;N;;;;;
12070 A407;YI SYLLABLE QUOP;Lo;0;L;;;;;N;;;;;
12071 A408;YI SYLLABLE QOT;Lo;0;L;;;;;N;;;;;
12072 A409;YI SYLLABLE QOX;Lo;0;L;;;;;N;;;;;
12073 A40A;YI SYLLABLE QO;Lo;0;L;;;;;N;;;;;
12074 A40B;YI SYLLABLE QOP;Lo;0;L;;;;;N;;;;;
12075 A40C;YI SYLLABLE QUT;Lo;0;L;;;;;N;;;;;
12076 A40D;YI SYLLABLE QUX;Lo;0;L;;;;;N;;;;;
12077 A40E;YI SYLLABLE QU;Lo;0;L;;;;;N;;;;;
12078 A40F;YI SYLLABLE QUP;Lo;0;L;;;;;N;;;;;
12079 A410;YI SYLLABLE QURX;Lo;0;L;;;;;N;;;;;
12080 A411;YI SYLLABLE QUR;Lo;0;L;;;;;N;;;;;
12081 A412;YI SYLLABLE QYT;Lo;0;L;;;;;N;;;;;
12082 A413;YI SYLLABLE QYX;Lo;0;L;;;;;N;;;;;
12083 A414;YI SYLLABLE QY;Lo;0;L;;;;;N;;;;;
12084 A415;YI SYLLABLE QYP;Lo;0;L;;;;;N;;;;;
12085 A416;YI SYLLABLE QYRX;Lo;0;L;;;;;N;;;;;
12086 A417;YI SYLLABLE QYR;Lo;0;L;;;;;N;;;;;
12087 A418;YI SYLLABLE JJIT;Lo;0;L;;;;;N;;;;;
12088 A419;YI SYLLABLE JJIX;Lo;0;L;;;;;N;;;;;
12089 A41A;YI SYLLABLE JJI;Lo;0;L;;;;;N;;;;;
12090 A41B;YI SYLLABLE JJIP;Lo;0;L;;;;;N;;;;;
12091 A41C;YI SYLLABLE JJIET;Lo;0;L;;;;;N;;;;;
12092 A41D;YI SYLLABLE JJIEX;Lo;0;L;;;;;N;;;;;
12093 A41E;YI SYLLABLE JJIE;Lo;0;L;;;;;N;;;;;
12094 A41F;YI SYLLABLE JJIEP;Lo;0;L;;;;;N;;;;;
12095 A420;YI SYLLABLE JJUOX;Lo;0;L;;;;;N;;;;;
12096 A421;YI SYLLABLE JJUO;Lo;0;L;;;;;N;;;;;
12097 A422;YI SYLLABLE JJUOP;Lo;0;L;;;;;N;;;;;
12098 A423;YI SYLLABLE JJOT;Lo;0;L;;;;;N;;;;;
12099 A424;YI SYLLABLE JJOX;Lo;0;L;;;;;N;;;;;
12100 A425;YI SYLLABLE JJO;Lo;0;L;;;;;N;;;;;
12101 A426;YI SYLLABLE JJOP;Lo;0;L;;;;;N;;;;;
12102 A427;YI SYLLABLE JJUT;Lo;0;L;;;;;N;;;;;
12103 A428;YI SYLLABLE JJUX;Lo;0;L;;;;;N;;;;;
12104 A429;YI SYLLABLE JJU;Lo;0;L;;;;;N;;;;;
12105 A42A;YI SYLLABLE JJUP;Lo;0;L;;;;;N;;;;;
12106 A42B;YI SYLLABLE JJURX;Lo;0;L;;;;;N;;;;;
12107 A42C;YI SYLLABLE JJUR;Lo;0;L;;;;;N;;;;;
12108 A42D;YI SYLLABLE JJYT;Lo;0;L;;;;;N;;;;;
12109 A42E;YI SYLLABLE JJYX;Lo;0;L;;;;;N;;;;;
12110 A42F;YI SYLLABLE JJY;Lo;0;L;;;;;N;;;;;
12111 A430;YI SYLLABLE JJYP;Lo;0;L;;;;;N;;;;;
12112 A431;YI SYLLABLE NJIT;Lo;0;L;;;;;N;;;;;
12113 A432;YI SYLLABLE NJIX;Lo;0;L;;;;;N;;;;;
12114 A433;YI SYLLABLE NJI;Lo;0;L;;;;;N;;;;;
12115 A434;YI SYLLABLE NJIP;Lo;0;L;;;;;N;;;;;
12116 A435;YI SYLLABLE NJIET;Lo;0;L;;;;;N;;;;;
12117 A436;YI SYLLABLE NJIEX;Lo;0;L;;;;;N;;;;;
12118 A437;YI SYLLABLE NJIE;Lo;0;L;;;;;N;;;;;
12119 A438;YI SYLLABLE NJIEP;Lo;0;L;;;;;N;;;;;
12120 A439;YI SYLLABLE NJUOX;Lo;0;L;;;;;N;;;;;
12121 A43A;YI SYLLABLE NJUO;Lo;0;L;;;;;N;;;;;
12122 A43B;YI SYLLABLE NJOT;Lo;0;L;;;;;N;;;;;
12123 A43C;YI SYLLABLE NJOX;Lo;0;L;;;;;N;;;;;
12124 A43D;YI SYLLABLE NJO;Lo;0;L;;;;;N;;;;;
12125 A43E;YI SYLLABLE NJOP;Lo;0;L;;;;;N;;;;;
12126 A43F;YI SYLLABLE NJUX;Lo;0;L;;;;;N;;;;;
12127 A440;YI SYLLABLE NJU;Lo;0;L;;;;;N;;;;;
12128 A441;YI SYLLABLE NJUP;Lo;0;L;;;;;N;;;;;
12129 A442;YI SYLLABLE NJURX;Lo;0;L;;;;;N;;;;;
12130 A443;YI SYLLABLE NJUR;Lo;0;L;;;;;N;;;;;
12131 A444;YI SYLLABLE NJYT;Lo;0;L;;;;;N;;;;;
12132 A445;YI SYLLABLE NJYX;Lo;0;L;;;;;N;;;;;
12133 A446;YI SYLLABLE NJY;Lo;0;L;;;;;N;;;;;
12134 A447;YI SYLLABLE NJYP;Lo;0;L;;;;;N;;;;;
12135 A448;YI SYLLABLE NJYRX;Lo;0;L;;;;;N;;;;;
12136 A449;YI SYLLABLE NJYR;Lo;0;L;;;;;N;;;;;
12137 A44A;YI SYLLABLE NYIT;Lo;0;L;;;;;N;;;;;
12138 A44B;YI SYLLABLE NYIX;Lo;0;L;;;;;N;;;;;
12139 A44C;YI SYLLABLE NYI;Lo;0;L;;;;;N;;;;;
12140 A44D;YI SYLLABLE NYIP;Lo;0;L;;;;;N;;;;;
12141 A44E;YI SYLLABLE NYIET;Lo;0;L;;;;;N;;;;;
12142 A44F;YI SYLLABLE NYIEX;Lo;0;L;;;;;N;;;;;
12143 A450;YI SYLLABLE NYIE;Lo;0;L;;;;;N;;;;;
12144 A451;YI SYLLABLE NYIEP;Lo;0;L;;;;;N;;;;;
12145 A452;YI SYLLABLE NYUOX;Lo;0;L;;;;;N;;;;;
12146 A453;YI SYLLABLE NYUO;Lo;0;L;;;;;N;;;;;
12147 A454;YI SYLLABLE NYUOP;Lo;0;L;;;;;N;;;;;
12148 A455;YI SYLLABLE NYOT;Lo;0;L;;;;;N;;;;;
12149 A456;YI SYLLABLE NYOX;Lo;0;L;;;;;N;;;;;
12150 A457;YI SYLLABLE NYO;Lo;0;L;;;;;N;;;;;
12151 A458;YI SYLLABLE NYOP;Lo;0;L;;;;;N;;;;;
12152 A459;YI SYLLABLE NYUT;Lo;0;L;;;;;N;;;;;
12153 A45A;YI SYLLABLE NYUX;Lo;0;L;;;;;N;;;;;
12154 A45B;YI SYLLABLE NYU;Lo;0;L;;;;;N;;;;;
12155 A45C;YI SYLLABLE NYUP;Lo;0;L;;;;;N;;;;;
12156 A45D;YI SYLLABLE XIT;Lo;0;L;;;;;N;;;;;
12157 A45E;YI SYLLABLE XIX;Lo;0;L;;;;;N;;;;;
12158 A45F;YI SYLLABLE XI;Lo;0;L;;;;;N;;;;;
12159 A460;YI SYLLABLE XIP;Lo;0;L;;;;;N;;;;;
12160 A461;YI SYLLABLE XIET;Lo;0;L;;;;;N;;;;;
12161 A462;YI SYLLABLE XIEX;Lo;0;L;;;;;N;;;;;
12162 A463;YI SYLLABLE XIE;Lo;0;L;;;;;N;;;;;
12163 A464;YI SYLLABLE XIEP;Lo;0;L;;;;;N;;;;;
12164 A465;YI SYLLABLE XUOX;Lo;0;L;;;;;N;;;;;
12165 A466;YI SYLLABLE XUO;Lo;0;L;;;;;N;;;;;
12166 A467;YI SYLLABLE XOT;Lo;0;L;;;;;N;;;;;
12167 A468;YI SYLLABLE XOX;Lo;0;L;;;;;N;;;;;
12168 A469;YI SYLLABLE XO;Lo;0;L;;;;;N;;;;;
12169 A46A;YI SYLLABLE XOP;Lo;0;L;;;;;N;;;;;
12170 A46B;YI SYLLABLE XYT;Lo;0;L;;;;;N;;;;;
12171 A46C;YI SYLLABLE XYX;Lo;0;L;;;;;N;;;;;
12172 A46D;YI SYLLABLE XY;Lo;0;L;;;;;N;;;;;
12173 A46E;YI SYLLABLE XYP;Lo;0;L;;;;;N;;;;;
12174 A46F;YI SYLLABLE XYRX;Lo;0;L;;;;;N;;;;;
12175 A470;YI SYLLABLE XYR;Lo;0;L;;;;;N;;;;;
12176 A471;YI SYLLABLE YIT;Lo;0;L;;;;;N;;;;;
12177 A472;YI SYLLABLE YIX;Lo;0;L;;;;;N;;;;;
12178 A473;YI SYLLABLE YI;Lo;0;L;;;;;N;;;;;
12179 A474;YI SYLLABLE YIP;Lo;0;L;;;;;N;;;;;
12180 A475;YI SYLLABLE YIET;Lo;0;L;;;;;N;;;;;
12181 A476;YI SYLLABLE YIEX;Lo;0;L;;;;;N;;;;;
12182 A477;YI SYLLABLE YIE;Lo;0;L;;;;;N;;;;;
12183 A478;YI SYLLABLE YIEP;Lo;0;L;;;;;N;;;;;
12184 A479;YI SYLLABLE YUOT;Lo;0;L;;;;;N;;;;;
12185 A47A;YI SYLLABLE YUOX;Lo;0;L;;;;;N;;;;;
12186 A47B;YI SYLLABLE YUO;Lo;0;L;;;;;N;;;;;
12187 A47C;YI SYLLABLE YUOP;Lo;0;L;;;;;N;;;;;
12188 A47D;YI SYLLABLE YOT;Lo;0;L;;;;;N;;;;;
12189 A47E;YI SYLLABLE YOX;Lo;0;L;;;;;N;;;;;
12190 A47F;YI SYLLABLE YO;Lo;0;L;;;;;N;;;;;
12191 A480;YI SYLLABLE YOP;Lo;0;L;;;;;N;;;;;
12192 A481;YI SYLLABLE YUT;Lo;0;L;;;;;N;;;;;
12193 A482;YI SYLLABLE YUX;Lo;0;L;;;;;N;;;;;
12194 A483;YI SYLLABLE YU;Lo;0;L;;;;;N;;;;;
12195 A484;YI SYLLABLE YUP;Lo;0;L;;;;;N;;;;;
12196 A485;YI SYLLABLE YURX;Lo;0;L;;;;;N;;;;;
12197 A486;YI SYLLABLE YUR;Lo;0;L;;;;;N;;;;;
12198 A487;YI SYLLABLE YYT;Lo;0;L;;;;;N;;;;;
12199 A488;YI SYLLABLE YYX;Lo;0;L;;;;;N;;;;;
12200 A489;YI SYLLABLE YY;Lo;0;L;;;;;N;;;;;
12201 A48A;YI SYLLABLE YYP;Lo;0;L;;;;;N;;;;;
12202 A48B;YI SYLLABLE YYRX;Lo;0;L;;;;;N;;;;;
12203 A48C;YI SYLLABLE YYR;Lo;0;L;;;;;N;;;;;
12204 A490;YI RADICAL QOT;So;0;ON;;;;;N;;;;;
12205 A491;YI RADICAL LI;So;0;ON;;;;;N;;;;;
12206 A492;YI RADICAL KIT;So;0;ON;;;;;N;;;;;
12207 A493;YI RADICAL NYIP;So;0;ON;;;;;N;;;;;
12208 A494;YI RADICAL CYP;So;0;ON;;;;;N;;;;;
12209 A495;YI RADICAL SSI;So;0;ON;;;;;N;;;;;
12210 A496;YI RADICAL GGOP;So;0;ON;;;;;N;;;;;
12211 A497;YI RADICAL GEP;So;0;ON;;;;;N;;;;;
12212 A498;YI RADICAL MI;So;0;ON;;;;;N;;;;;
12213 A499;YI RADICAL HXIT;So;0;ON;;;;;N;;;;;
12214 A49A;YI RADICAL LYR;So;0;ON;;;;;N;;;;;
12215 A49B;YI RADICAL BBUT;So;0;ON;;;;;N;;;;;
12216 A49C;YI RADICAL MOP;So;0;ON;;;;;N;;;;;
12217 A49D;YI RADICAL YO;So;0;ON;;;;;N;;;;;
12218 A49E;YI RADICAL PUT;So;0;ON;;;;;N;;;;;
12219 A49F;YI RADICAL HXUO;So;0;ON;;;;;N;;;;;
12220 A4A0;YI RADICAL TAT;So;0;ON;;;;;N;;;;;
12221 A4A1;YI RADICAL GA;So;0;ON;;;;;N;;;;;
12222 A4A2;YI RADICAL ZUP;So;0;ON;;;;;N;;;;;
12223 A4A3;YI RADICAL CYT;So;0;ON;;;;;N;;;;;
12224 A4A4;YI RADICAL DDUR;So;0;ON;;;;;N;;;;;
12225 A4A5;YI RADICAL BUR;So;0;ON;;;;;N;;;;;
12226 A4A6;YI RADICAL GGUO;So;0;ON;;;;;N;;;;;
12227 A4A7;YI RADICAL NYOP;So;0;ON;;;;;N;;;;;
12228 A4A8;YI RADICAL TU;So;0;ON;;;;;N;;;;;
12229 A4A9;YI RADICAL OP;So;0;ON;;;;;N;;;;;
12230 A4AA;YI RADICAL JJUT;So;0;ON;;;;;N;;;;;
12231 A4AB;YI RADICAL ZOT;So;0;ON;;;;;N;;;;;
12232 A4AC;YI RADICAL PYT;So;0;ON;;;;;N;;;;;
12233 A4AD;YI RADICAL HMO;So;0;ON;;;;;N;;;;;
12234 A4AE;YI RADICAL YIT;So;0;ON;;;;;N;;;;;
12235 A4AF;YI RADICAL VUR;So;0;ON;;;;;N;;;;;
12236 A4B0;YI RADICAL SHY;So;0;ON;;;;;N;;;;;
12237 A4B1;YI RADICAL VEP;So;0;ON;;;;;N;;;;;
12238 A4B2;YI RADICAL ZA;So;0;ON;;;;;N;;;;;
12239 A4B3;YI RADICAL JO;So;0;ON;;;;;N;;;;;
12240 A4B4;YI RADICAL NZUP;So;0;ON;;;;;N;;;;;
12241 A4B5;YI RADICAL JJY;So;0;ON;;;;;N;;;;;
12242 A4B6;YI RADICAL GOT;So;0;ON;;;;;N;;;;;
12243 A4B7;YI RADICAL JJIE;So;0;ON;;;;;N;;;;;
12244 A4B8;YI RADICAL WO;So;0;ON;;;;;N;;;;;
12245 A4B9;YI RADICAL DU;So;0;ON;;;;;N;;;;;
12246 A4BA;YI RADICAL SHUR;So;0;ON;;;;;N;;;;;
12247 A4BB;YI RADICAL LIE;So;0;ON;;;;;N;;;;;
12248 A4BC;YI RADICAL CY;So;0;ON;;;;;N;;;;;
12249 A4BD;YI RADICAL CUOP;So;0;ON;;;;;N;;;;;
12250 A4BE;YI RADICAL CIP;So;0;ON;;;;;N;;;;;
12251 A4BF;YI RADICAL HXOP;So;0;ON;;;;;N;;;;;
12252 A4C0;YI RADICAL SHAT;So;0;ON;;;;;N;;;;;
12253 A4C1;YI RADICAL ZUR;So;0;ON;;;;;N;;;;;
12254 A4C2;YI RADICAL SHOP;So;0;ON;;;;;N;;;;;
12255 A4C3;YI RADICAL CHE;So;0;ON;;;;;N;;;;;
12256 A4C4;YI RADICAL ZZIET;So;0;ON;;;;;N;;;;;
12257 A4C5;YI RADICAL NBIE;So;0;ON;;;;;N;;;;;
12258 A4C6;YI RADICAL KE;So;0;ON;;;;;N;;;;;
12259 A500;VAI SYLLABLE EE;Lo;0;L;;;;;N;;;;;
12260 A501;VAI SYLLABLE EEN;Lo;0;L;;;;;N;;;;;
12261 A502;VAI SYLLABLE HEE;Lo;0;L;;;;;N;;;;;
12262 A503;VAI SYLLABLE WEE;Lo;0;L;;;;;N;;;;;
12263 A504;VAI SYLLABLE WEEN;Lo;0;L;;;;;N;;;;;
12264 A505;VAI SYLLABLE PEE;Lo;0;L;;;;;N;;;;;
12265 A506;VAI SYLLABLE BHEE;Lo;0;L;;;;;N;;;;;
12266 A507;VAI SYLLABLE BEE;Lo;0;L;;;;;N;;;;;
12267 A508;VAI SYLLABLE MBEE;Lo;0;L;;;;;N;;;;;
12268 A509;VAI SYLLABLE KPEE;Lo;0;L;;;;;N;;;;;
12269 A50A;VAI SYLLABLE MGBEE;Lo;0;L;;;;;N;;;;;
12270 A50B;VAI SYLLABLE GBEE;Lo;0;L;;;;;N;;;;;
12271 A50C;VAI SYLLABLE FEE;Lo;0;L;;;;;N;;;;;
12272 A50D;VAI SYLLABLE VEE;Lo;0;L;;;;;N;;;;;
12273 A50E;VAI SYLLABLE TEE;Lo;0;L;;;;;N;;;;;
12274 A50F;VAI SYLLABLE THEE;Lo;0;L;;;;;N;;;;;
12275 A510;VAI SYLLABLE DHEE;Lo;0;L;;;;;N;;;;;
12276 A511;VAI SYLLABLE DHHEE;Lo;0;L;;;;;N;;;;;
12277 A512;VAI SYLLABLE LEE;Lo;0;L;;;;;N;;;;;
12278 A513;VAI SYLLABLE REE;Lo;0;L;;;;;N;;;;;
12279 A514;VAI SYLLABLE DEE;Lo;0;L;;;;;N;;;;;
12280 A515;VAI SYLLABLE NDEE;Lo;0;L;;;;;N;;;;;
12281 A516;VAI SYLLABLE SEE;Lo;0;L;;;;;N;;;;;
12282 A517;VAI SYLLABLE SHEE;Lo;0;L;;;;;N;;;;;
12283 A518;VAI SYLLABLE ZEE;Lo;0;L;;;;;N;;;;;
12284 A519;VAI SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;;
12285 A51A;VAI SYLLABLE CEE;Lo;0;L;;;;;N;;;;;
12286 A51B;VAI SYLLABLE JEE;Lo;0;L;;;;;N;;;;;
12287 A51C;VAI SYLLABLE NJEE;Lo;0;L;;;;;N;;;;;
12288 A51D;VAI SYLLABLE YEE;Lo;0;L;;;;;N;;;;;
12289 A51E;VAI SYLLABLE KEE;Lo;0;L;;;;;N;;;;;
12290 A51F;VAI SYLLABLE NGGEE;Lo;0;L;;;;;N;;;;;
12291 A520;VAI SYLLABLE GEE;Lo;0;L;;;;;N;;;;;
12292 A521;VAI SYLLABLE MEE;Lo;0;L;;;;;N;;;;;
12293 A522;VAI SYLLABLE NEE;Lo;0;L;;;;;N;;;;;
12294 A523;VAI SYLLABLE NYEE;Lo;0;L;;;;;N;;;;;
12295 A524;VAI SYLLABLE I;Lo;0;L;;;;;N;;;;;
12296 A525;VAI SYLLABLE IN;Lo;0;L;;;;;N;;;;;
12297 A526;VAI SYLLABLE HI;Lo;0;L;;;;;N;;;;;
12298 A527;VAI SYLLABLE HIN;Lo;0;L;;;;;N;;;;;
12299 A528;VAI SYLLABLE WI;Lo;0;L;;;;;N;;;;;
12300 A529;VAI SYLLABLE WIN;Lo;0;L;;;;;N;;;;;
12301 A52A;VAI SYLLABLE PI;Lo;0;L;;;;;N;;;;;
12302 A52B;VAI SYLLABLE BHI;Lo;0;L;;;;;N;;;;;
12303 A52C;VAI SYLLABLE BI;Lo;0;L;;;;;N;;;;;
12304 A52D;VAI SYLLABLE MBI;Lo;0;L;;;;;N;;;;;
12305 A52E;VAI SYLLABLE KPI;Lo;0;L;;;;;N;;;;;
12306 A52F;VAI SYLLABLE MGBI;Lo;0;L;;;;;N;;;;;
12307 A530;VAI SYLLABLE GBI;Lo;0;L;;;;;N;;;;;
12308 A531;VAI SYLLABLE FI;Lo;0;L;;;;;N;;;;;
12309 A532;VAI SYLLABLE VI;Lo;0;L;;;;;N;;;;;
12310 A533;VAI SYLLABLE TI;Lo;0;L;;;;;N;;;;;
12311 A534;VAI SYLLABLE THI;Lo;0;L;;;;;N;;;;;
12312 A535;VAI SYLLABLE DHI;Lo;0;L;;;;;N;;;;;
12313 A536;VAI SYLLABLE DHHI;Lo;0;L;;;;;N;;;;;
12314 A537;VAI SYLLABLE LI;Lo;0;L;;;;;N;;;;;
12315 A538;VAI SYLLABLE RI;Lo;0;L;;;;;N;;;;;
12316 A539;VAI SYLLABLE DI;Lo;0;L;;;;;N;;;;;
12317 A53A;VAI SYLLABLE NDI;Lo;0;L;;;;;N;;;;;
12318 A53B;VAI SYLLABLE SI;Lo;0;L;;;;;N;;;;;
12319 A53C;VAI SYLLABLE SHI;Lo;0;L;;;;;N;;;;;
12320 A53D;VAI SYLLABLE ZI;Lo;0;L;;;;;N;;;;;
12321 A53E;VAI SYLLABLE ZHI;Lo;0;L;;;;;N;;;;;
12322 A53F;VAI SYLLABLE CI;Lo;0;L;;;;;N;;;;;
12323 A540;VAI SYLLABLE JI;Lo;0;L;;;;;N;;;;;
12324 A541;VAI SYLLABLE NJI;Lo;0;L;;;;;N;;;;;
12325 A542;VAI SYLLABLE YI;Lo;0;L;;;;;N;;;;;
12326 A543;VAI SYLLABLE KI;Lo;0;L;;;;;N;;;;;
12327 A544;VAI SYLLABLE NGGI;Lo;0;L;;;;;N;;;;;
12328 A545;VAI SYLLABLE GI;Lo;0;L;;;;;N;;;;;
12329 A546;VAI SYLLABLE MI;Lo;0;L;;;;;N;;;;;
12330 A547;VAI SYLLABLE NI;Lo;0;L;;;;;N;;;;;
12331 A548;VAI SYLLABLE NYI;Lo;0;L;;;;;N;;;;;
12332 A549;VAI SYLLABLE A;Lo;0;L;;;;;N;;;;;
12333 A54A;VAI SYLLABLE AN;Lo;0;L;;;;;N;;;;;
12334 A54B;VAI SYLLABLE NGAN;Lo;0;L;;;;;N;;;;;
12335 A54C;VAI SYLLABLE HA;Lo;0;L;;;;;N;;;;;
12336 A54D;VAI SYLLABLE HAN;Lo;0;L;;;;;N;;;;;
12337 A54E;VAI SYLLABLE WA;Lo;0;L;;;;;N;;;;;
12338 A54F;VAI SYLLABLE WAN;Lo;0;L;;;;;N;;;;;
12339 A550;VAI SYLLABLE PA;Lo;0;L;;;;;N;;;;;
12340 A551;VAI SYLLABLE BHA;Lo;0;L;;;;;N;;;;;
12341 A552;VAI SYLLABLE BA;Lo;0;L;;;;;N;;;;;
12342 A553;VAI SYLLABLE MBA;Lo;0;L;;;;;N;;;;;
12343 A554;VAI SYLLABLE KPA;Lo;0;L;;;;;N;;;;;
12344 A555;VAI SYLLABLE KPAN;Lo;0;L;;;;;N;;;;;
12345 A556;VAI SYLLABLE MGBA;Lo;0;L;;;;;N;;;;;
12346 A557;VAI SYLLABLE GBA;Lo;0;L;;;;;N;;;;;
12347 A558;VAI SYLLABLE FA;Lo;0;L;;;;;N;;;;;
12348 A559;VAI SYLLABLE VA;Lo;0;L;;;;;N;;;;;
12349 A55A;VAI SYLLABLE TA;Lo;0;L;;;;;N;;;;;
12350 A55B;VAI SYLLABLE THA;Lo;0;L;;;;;N;;;;;
12351 A55C;VAI SYLLABLE DHA;Lo;0;L;;;;;N;;;;;
12352 A55D;VAI SYLLABLE DHHA;Lo;0;L;;;;;N;;;;;
12353 A55E;VAI SYLLABLE LA;Lo;0;L;;;;;N;;;;;
12354 A55F;VAI SYLLABLE RA;Lo;0;L;;;;;N;;;;;
12355 A560;VAI SYLLABLE DA;Lo;0;L;;;;;N;;;;;
12356 A561;VAI SYLLABLE NDA;Lo;0;L;;;;;N;;;;;
12357 A562;VAI SYLLABLE SA;Lo;0;L;;;;;N;;;;;
12358 A563;VAI SYLLABLE SHA;Lo;0;L;;;;;N;;;;;
12359 A564;VAI SYLLABLE ZA;Lo;0;L;;;;;N;;;;;
12360 A565;VAI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;;
12361 A566;VAI SYLLABLE CA;Lo;0;L;;;;;N;;;;;
12362 A567;VAI SYLLABLE JA;Lo;0;L;;;;;N;;;;;
12363 A568;VAI SYLLABLE NJA;Lo;0;L;;;;;N;;;;;
12364 A569;VAI SYLLABLE YA;Lo;0;L;;;;;N;;;;;
12365 A56A;VAI SYLLABLE KA;Lo;0;L;;;;;N;;;;;
12366 A56B;VAI SYLLABLE KAN;Lo;0;L;;;;;N;;;;;
12367 A56C;VAI SYLLABLE NGGA;Lo;0;L;;;;;N;;;;;
12368 A56D;VAI SYLLABLE GA;Lo;0;L;;;;;N;;;;;
12369 A56E;VAI SYLLABLE MA;Lo;0;L;;;;;N;;;;;
12370 A56F;VAI SYLLABLE NA;Lo;0;L;;;;;N;;;;;
12371 A570;VAI SYLLABLE NYA;Lo;0;L;;;;;N;;;;;
12372 A571;VAI SYLLABLE OO;Lo;0;L;;;;;N;;;;;
12373 A572;VAI SYLLABLE OON;Lo;0;L;;;;;N;;;;;
12374 A573;VAI SYLLABLE HOO;Lo;0;L;;;;;N;;;;;
12375 A574;VAI SYLLABLE WOO;Lo;0;L;;;;;N;;;;;
12376 A575;VAI SYLLABLE WOON;Lo;0;L;;;;;N;;;;;
12377 A576;VAI SYLLABLE POO;Lo;0;L;;;;;N;;;;;
12378 A577;VAI SYLLABLE BHOO;Lo;0;L;;;;;N;;;;;
12379 A578;VAI SYLLABLE BOO;Lo;0;L;;;;;N;;;;;
12380 A579;VAI SYLLABLE MBOO;Lo;0;L;;;;;N;;;;;
12381 A57A;VAI SYLLABLE KPOO;Lo;0;L;;;;;N;;;;;
12382 A57B;VAI SYLLABLE MGBOO;Lo;0;L;;;;;N;;;;;
12383 A57C;VAI SYLLABLE GBOO;Lo;0;L;;;;;N;;;;;
12384 A57D;VAI SYLLABLE FOO;Lo;0;L;;;;;N;;;;;
12385 A57E;VAI SYLLABLE VOO;Lo;0;L;;;;;N;;;;;
12386 A57F;VAI SYLLABLE TOO;Lo;0;L;;;;;N;;;;;
12387 A580;VAI SYLLABLE THOO;Lo;0;L;;;;;N;;;;;
12388 A581;VAI SYLLABLE DHOO;Lo;0;L;;;;;N;;;;;
12389 A582;VAI SYLLABLE DHHOO;Lo;0;L;;;;;N;;;;;
12390 A583;VAI SYLLABLE LOO;Lo;0;L;;;;;N;;;;;
12391 A584;VAI SYLLABLE ROO;Lo;0;L;;;;;N;;;;;
12392 A585;VAI SYLLABLE DOO;Lo;0;L;;;;;N;;;;;
12393 A586;VAI SYLLABLE NDOO;Lo;0;L;;;;;N;;;;;
12394 A587;VAI SYLLABLE SOO;Lo;0;L;;;;;N;;;;;
12395 A588;VAI SYLLABLE SHOO;Lo;0;L;;;;;N;;;;;
12396 A589;VAI SYLLABLE ZOO;Lo;0;L;;;;;N;;;;;
12397 A58A;VAI SYLLABLE ZHOO;Lo;0;L;;;;;N;;;;;
12398 A58B;VAI SYLLABLE COO;Lo;0;L;;;;;N;;;;;
12399 A58C;VAI SYLLABLE JOO;Lo;0;L;;;;;N;;;;;
12400 A58D;VAI SYLLABLE NJOO;Lo;0;L;;;;;N;;;;;
12401 A58E;VAI SYLLABLE YOO;Lo;0;L;;;;;N;;;;;
12402 A58F;VAI SYLLABLE KOO;Lo;0;L;;;;;N;;;;;
12403 A590;VAI SYLLABLE NGGOO;Lo;0;L;;;;;N;;;;;
12404 A591;VAI SYLLABLE GOO;Lo;0;L;;;;;N;;;;;
12405 A592;VAI SYLLABLE MOO;Lo;0;L;;;;;N;;;;;
12406 A593;VAI SYLLABLE NOO;Lo;0;L;;;;;N;;;;;
12407 A594;VAI SYLLABLE NYOO;Lo;0;L;;;;;N;;;;;
12408 A595;VAI SYLLABLE U;Lo;0;L;;;;;N;;;;;
12409 A596;VAI SYLLABLE UN;Lo;0;L;;;;;N;;;;;
12410 A597;VAI SYLLABLE HU;Lo;0;L;;;;;N;;;;;
12411 A598;VAI SYLLABLE HUN;Lo;0;L;;;;;N;;;;;
12412 A599;VAI SYLLABLE WU;Lo;0;L;;;;;N;;;;;
12413 A59A;VAI SYLLABLE WUN;Lo;0;L;;;;;N;;;;;
12414 A59B;VAI SYLLABLE PU;Lo;0;L;;;;;N;;;;;
12415 A59C;VAI SYLLABLE BHU;Lo;0;L;;;;;N;;;;;
12416 A59D;VAI SYLLABLE BU;Lo;0;L;;;;;N;;;;;
12417 A59E;VAI SYLLABLE MBU;Lo;0;L;;;;;N;;;;;
12418 A59F;VAI SYLLABLE KPU;Lo;0;L;;;;;N;;;;;
12419 A5A0;VAI SYLLABLE MGBU;Lo;0;L;;;;;N;;;;;
12420 A5A1;VAI SYLLABLE GBU;Lo;0;L;;;;;N;;;;;
12421 A5A2;VAI SYLLABLE FU;Lo;0;L;;;;;N;;;;;
12422 A5A3;VAI SYLLABLE VU;Lo;0;L;;;;;N;;;;;
12423 A5A4;VAI SYLLABLE TU;Lo;0;L;;;;;N;;;;;
12424 A5A5;VAI SYLLABLE THU;Lo;0;L;;;;;N;;;;;
12425 A5A6;VAI SYLLABLE DHU;Lo;0;L;;;;;N;;;;;
12426 A5A7;VAI SYLLABLE DHHU;Lo;0;L;;;;;N;;;;;
12427 A5A8;VAI SYLLABLE LU;Lo;0;L;;;;;N;;;;;
12428 A5A9;VAI SYLLABLE RU;Lo;0;L;;;;;N;;;;;
12429 A5AA;VAI SYLLABLE DU;Lo;0;L;;;;;N;;;;;
12430 A5AB;VAI SYLLABLE NDU;Lo;0;L;;;;;N;;;;;
12431 A5AC;VAI SYLLABLE SU;Lo;0;L;;;;;N;;;;;
12432 A5AD;VAI SYLLABLE SHU;Lo;0;L;;;;;N;;;;;
12433 A5AE;VAI SYLLABLE ZU;Lo;0;L;;;;;N;;;;;
12434 A5AF;VAI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;;
12435 A5B0;VAI SYLLABLE CU;Lo;0;L;;;;;N;;;;;
12436 A5B1;VAI SYLLABLE JU;Lo;0;L;;;;;N;;;;;
12437 A5B2;VAI SYLLABLE NJU;Lo;0;L;;;;;N;;;;;
12438 A5B3;VAI SYLLABLE YU;Lo;0;L;;;;;N;;;;;
12439 A5B4;VAI SYLLABLE KU;Lo;0;L;;;;;N;;;;;
12440 A5B5;VAI SYLLABLE NGGU;Lo;0;L;;;;;N;;;;;
12441 A5B6;VAI SYLLABLE GU;Lo;0;L;;;;;N;;;;;
12442 A5B7;VAI SYLLABLE MU;Lo;0;L;;;;;N;;;;;
12443 A5B8;VAI SYLLABLE NU;Lo;0;L;;;;;N;;;;;
12444 A5B9;VAI SYLLABLE NYU;Lo;0;L;;;;;N;;;;;
12445 A5BA;VAI SYLLABLE O;Lo;0;L;;;;;N;;;;;
12446 A5BB;VAI SYLLABLE ON;Lo;0;L;;;;;N;;;;;
12447 A5BC;VAI SYLLABLE NGON;Lo;0;L;;;;;N;;;;;
12448 A5BD;VAI SYLLABLE HO;Lo;0;L;;;;;N;;;;;
12449 A5BE;VAI SYLLABLE HON;Lo;0;L;;;;;N;;;;;
12450 A5BF;VAI SYLLABLE WO;Lo;0;L;;;;;N;;;;;
12451 A5C0;VAI SYLLABLE WON;Lo;0;L;;;;;N;;;;;
12452 A5C1;VAI SYLLABLE PO;Lo;0;L;;;;;N;;;;;
12453 A5C2;VAI SYLLABLE BHO;Lo;0;L;;;;;N;;;;;
12454 A5C3;VAI SYLLABLE BO;Lo;0;L;;;;;N;;;;;
12455 A5C4;VAI SYLLABLE MBO;Lo;0;L;;;;;N;;;;;
12456 A5C5;VAI SYLLABLE KPO;Lo;0;L;;;;;N;;;;;
12457 A5C6;VAI SYLLABLE MGBO;Lo;0;L;;;;;N;;;;;
12458 A5C7;VAI SYLLABLE GBO;Lo;0;L;;;;;N;;;;;
12459 A5C8;VAI SYLLABLE GBON;Lo;0;L;;;;;N;;;;;
12460 A5C9;VAI SYLLABLE FO;Lo;0;L;;;;;N;;;;;
12461 A5CA;VAI SYLLABLE VO;Lo;0;L;;;;;N;;;;;
12462 A5CB;VAI SYLLABLE TO;Lo;0;L;;;;;N;;;;;
12463 A5CC;VAI SYLLABLE THO;Lo;0;L;;;;;N;;;;;
12464 A5CD;VAI SYLLABLE DHO;Lo;0;L;;;;;N;;;;;
12465 A5CE;VAI SYLLABLE DHHO;Lo;0;L;;;;;N;;;;;
12466 A5CF;VAI SYLLABLE LO;Lo;0;L;;;;;N;;;;;
12467 A5D0;VAI SYLLABLE RO;Lo;0;L;;;;;N;;;;;
12468 A5D1;VAI SYLLABLE DO;Lo;0;L;;;;;N;;;;;
12469 A5D2;VAI SYLLABLE NDO;Lo;0;L;;;;;N;;;;;
12470 A5D3;VAI SYLLABLE SO;Lo;0;L;;;;;N;;;;;
12471 A5D4;VAI SYLLABLE SHO;Lo;0;L;;;;;N;;;;;
12472 A5D5;VAI SYLLABLE ZO;Lo;0;L;;;;;N;;;;;
12473 A5D6;VAI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;;
12474 A5D7;VAI SYLLABLE CO;Lo;0;L;;;;;N;;;;;
12475 A5D8;VAI SYLLABLE JO;Lo;0;L;;;;;N;;;;;
12476 A5D9;VAI SYLLABLE NJO;Lo;0;L;;;;;N;;;;;
12477 A5DA;VAI SYLLABLE YO;Lo;0;L;;;;;N;;;;;
12478 A5DB;VAI SYLLABLE KO;Lo;0;L;;;;;N;;;;;
12479 A5DC;VAI SYLLABLE NGGO;Lo;0;L;;;;;N;;;;;
12480 A5DD;VAI SYLLABLE GO;Lo;0;L;;;;;N;;;;;
12481 A5DE;VAI SYLLABLE MO;Lo;0;L;;;;;N;;;;;
12482 A5DF;VAI SYLLABLE NO;Lo;0;L;;;;;N;;;;;
12483 A5E0;VAI SYLLABLE NYO;Lo;0;L;;;;;N;;;;;
12484 A5E1;VAI SYLLABLE E;Lo;0;L;;;;;N;;;;;
12485 A5E2;VAI SYLLABLE EN;Lo;0;L;;;;;N;;;;;
12486 A5E3;VAI SYLLABLE NGEN;Lo;0;L;;;;;N;;;;;
12487 A5E4;VAI SYLLABLE HE;Lo;0;L;;;;;N;;;;;
12488 A5E5;VAI SYLLABLE HEN;Lo;0;L;;;;;N;;;;;
12489 A5E6;VAI SYLLABLE WE;Lo;0;L;;;;;N;;;;;
12490 A5E7;VAI SYLLABLE WEN;Lo;0;L;;;;;N;;;;;
12491 A5E8;VAI SYLLABLE PE;Lo;0;L;;;;;N;;;;;
12492 A5E9;VAI SYLLABLE BHE;Lo;0;L;;;;;N;;;;;
12493 A5EA;VAI SYLLABLE BE;Lo;0;L;;;;;N;;;;;
12494 A5EB;VAI SYLLABLE MBE;Lo;0;L;;;;;N;;;;;
12495 A5EC;VAI SYLLABLE KPE;Lo;0;L;;;;;N;;;;;
12496 A5ED;VAI SYLLABLE KPEN;Lo;0;L;;;;;N;;;;;
12497 A5EE;VAI SYLLABLE MGBE;Lo;0;L;;;;;N;;;;;
12498 A5EF;VAI SYLLABLE GBE;Lo;0;L;;;;;N;;;;;
12499 A5F0;VAI SYLLABLE GBEN;Lo;0;L;;;;;N;;;;;
12500 A5F1;VAI SYLLABLE FE;Lo;0;L;;;;;N;;;;;
12501 A5F2;VAI SYLLABLE VE;Lo;0;L;;;;;N;;;;;
12502 A5F3;VAI SYLLABLE TE;Lo;0;L;;;;;N;;;;;
12503 A5F4;VAI SYLLABLE THE;Lo;0;L;;;;;N;;;;;
12504 A5F5;VAI SYLLABLE DHE;Lo;0;L;;;;;N;;;;;
12505 A5F6;VAI SYLLABLE DHHE;Lo;0;L;;;;;N;;;;;
12506 A5F7;VAI SYLLABLE LE;Lo;0;L;;;;;N;;;;;
12507 A5F8;VAI SYLLABLE RE;Lo;0;L;;;;;N;;;;;
12508 A5F9;VAI SYLLABLE DE;Lo;0;L;;;;;N;;;;;
12509 A5FA;VAI SYLLABLE NDE;Lo;0;L;;;;;N;;;;;
12510 A5FB;VAI SYLLABLE SE;Lo;0;L;;;;;N;;;;;
12511 A5FC;VAI SYLLABLE SHE;Lo;0;L;;;;;N;;;;;
12512 A5FD;VAI SYLLABLE ZE;Lo;0;L;;;;;N;;;;;
12513 A5FE;VAI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;;
12514 A5FF;VAI SYLLABLE CE;Lo;0;L;;;;;N;;;;;
12515 A600;VAI SYLLABLE JE;Lo;0;L;;;;;N;;;;;
12516 A601;VAI SYLLABLE NJE;Lo;0;L;;;;;N;;;;;
12517 A602;VAI SYLLABLE YE;Lo;0;L;;;;;N;;;;;
12518 A603;VAI SYLLABLE KE;Lo;0;L;;;;;N;;;;;
12519 A604;VAI SYLLABLE NGGE;Lo;0;L;;;;;N;;;;;
12520 A605;VAI SYLLABLE NGGEN;Lo;0;L;;;;;N;;;;;
12521 A606;VAI SYLLABLE GE;Lo;0;L;;;;;N;;;;;
12522 A607;VAI SYLLABLE GEN;Lo;0;L;;;;;N;;;;;
12523 A608;VAI SYLLABLE ME;Lo;0;L;;;;;N;;;;;
12524 A609;VAI SYLLABLE NE;Lo;0;L;;;;;N;;;;;
12525 A60A;VAI SYLLABLE NYE;Lo;0;L;;;;;N;;;;;
12526 A60B;VAI SYLLABLE NG;Lo;0;L;;;;;N;;;;;
12527 A60C;VAI SYLLABLE LENGTHENER;Lm;0;L;;;;;N;;;;;
12528 A60D;VAI COMMA;Po;0;ON;;;;;N;;;;;
12529 A60E;VAI FULL STOP;Po;0;ON;;;;;N;;;;;
12530 A60F;VAI QUESTION MARK;Po;0;ON;;;;;N;;;;;
12531 A610;VAI SYLLABLE NDOLE FA;Lo;0;L;;;;;N;;;;;
12532 A611;VAI SYLLABLE NDOLE KA;Lo;0;L;;;;;N;;;;;
12533 A612;VAI SYLLABLE NDOLE SOO;Lo;0;L;;;;;N;;;;;
12534 A613;VAI SYMBOL FEENG;Lo;0;L;;;;;N;;;;;
12535 A614;VAI SYMBOL KEENG;Lo;0;L;;;;;N;;;;;
12536 A615;VAI SYMBOL TING;Lo;0;L;;;;;N;;;;;
12537 A616;VAI SYMBOL NII;Lo;0;L;;;;;N;;;;;
12538 A617;VAI SYMBOL BANG;Lo;0;L;;;;;N;;;;;
12539 A618;VAI SYMBOL FAA;Lo;0;L;;;;;N;;;;;
12540 A619;VAI SYMBOL TAA;Lo;0;L;;;;;N;;;;;
12541 A61A;VAI SYMBOL DANG;Lo;0;L;;;;;N;;;;;
12542 A61B;VAI SYMBOL DOONG;Lo;0;L;;;;;N;;;;;
12543 A61C;VAI SYMBOL KUNG;Lo;0;L;;;;;N;;;;;
12544 A61D;VAI SYMBOL TONG;Lo;0;L;;;;;N;;;;;
12545 A61E;VAI SYMBOL DO-O;Lo;0;L;;;;;N;;;;;
12546 A61F;VAI SYMBOL JONG;Lo;0;L;;;;;N;;;;;
12547 A620;VAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
12548 A621;VAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
12549 A622;VAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
12550 A623;VAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
12551 A624;VAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
12552 A625;VAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
12553 A626;VAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
12554 A627;VAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
12555 A628;VAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
12556 A629;VAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
12557 A62A;VAI SYLLABLE NDOLE MA;Lo;0;L;;;;;N;;;;;
12558 A62B;VAI SYLLABLE NDOLE DO;Lo;0;L;;;;;N;;;;;
12559 A640;CYRILLIC CAPITAL LETTER ZEMLYA;Lu;0;L;;;;;N;;;;A641;
12560 A641;CYRILLIC SMALL LETTER ZEMLYA;Ll;0;L;;;;;N;;;A640;;A640
12561 A642;CYRILLIC CAPITAL LETTER DZELO;Lu;0;L;;;;;N;;;;A643;
12562 A643;CYRILLIC SMALL LETTER DZELO;Ll;0;L;;;;;N;;;A642;;A642
12563 A644;CYRILLIC CAPITAL LETTER REVERSED DZE;Lu;0;L;;;;;N;;;;A645;
12564 A645;CYRILLIC SMALL LETTER REVERSED DZE;Ll;0;L;;;;;N;;;A644;;A644
12565 A646;CYRILLIC CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;A647;
12566 A647;CYRILLIC SMALL LETTER IOTA;Ll;0;L;;;;;N;;;A646;;A646
12567 A648;CYRILLIC CAPITAL LETTER DJERV;Lu;0;L;;;;;N;;;;A649;
12568 A649;CYRILLIC SMALL LETTER DJERV;Ll;0;L;;;;;N;;;A648;;A648
12569 A64A;CYRILLIC CAPITAL LETTER MONOGRAPH UK;Lu;0;L;;;;;N;;;;A64B;
12570 A64B;CYRILLIC SMALL LETTER MONOGRAPH UK;Ll;0;L;;;;;N;;;A64A;;A64A
12571 A64C;CYRILLIC CAPITAL LETTER BROAD OMEGA;Lu;0;L;;;;;N;;;;A64D;
12572 A64D;CYRILLIC SMALL LETTER BROAD OMEGA;Ll;0;L;;;;;N;;;A64C;;A64C
12573 A64E;CYRILLIC CAPITAL LETTER NEUTRAL YER;Lu;0;L;;;;;N;;;;A64F;
12574 A64F;CYRILLIC SMALL LETTER NEUTRAL YER;Ll;0;L;;;;;N;;;A64E;;A64E
12575 A650;CYRILLIC CAPITAL LETTER YERU WITH BACK YER;Lu;0;L;;;;;N;;;;A651;
12576 A651;CYRILLIC SMALL LETTER YERU WITH BACK YER;Ll;0;L;;;;;N;;;A650;;A650
12577 A652;CYRILLIC CAPITAL LETTER IOTIFIED YAT;Lu;0;L;;;;;N;;;;A653;
12578 A653;CYRILLIC SMALL LETTER IOTIFIED YAT;Ll;0;L;;;;;N;;;A652;;A652
12579 A654;CYRILLIC CAPITAL LETTER REVERSED YU;Lu;0;L;;;;;N;;;;A655;
12580 A655;CYRILLIC SMALL LETTER REVERSED YU;Ll;0;L;;;;;N;;;A654;;A654
12581 A656;CYRILLIC CAPITAL LETTER IOTIFIED A;Lu;0;L;;;;;N;;;;A657;
12582 A657;CYRILLIC SMALL LETTER IOTIFIED A;Ll;0;L;;;;;N;;;A656;;A656
12583 A658;CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A659;
12584 A659;CYRILLIC SMALL LETTER CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A658;;A658
12585 A65A;CYRILLIC CAPITAL LETTER BLENDED YUS;Lu;0;L;;;;;N;;;;A65B;
12586 A65B;CYRILLIC SMALL LETTER BLENDED YUS;Ll;0;L;;;;;N;;;A65A;;A65A
12587 A65C;CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A65D;
12588 A65D;CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A65C;;A65C
12589 A65E;CYRILLIC CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;A65F;
12590 A65F;CYRILLIC SMALL LETTER YN;Ll;0;L;;;;;N;;;A65E;;A65E
12591 A662;CYRILLIC CAPITAL LETTER SOFT DE;Lu;0;L;;;;;N;;;;A663;
12592 A663;CYRILLIC SMALL LETTER SOFT DE;Ll;0;L;;;;;N;;;A662;;A662
12593 A664;CYRILLIC CAPITAL LETTER SOFT EL;Lu;0;L;;;;;N;;;;A665;
12594 A665;CYRILLIC SMALL LETTER SOFT EL;Ll;0;L;;;;;N;;;A664;;A664
12595 A666;CYRILLIC CAPITAL LETTER SOFT EM;Lu;0;L;;;;;N;;;;A667;
12596 A667;CYRILLIC SMALL LETTER SOFT EM;Ll;0;L;;;;;N;;;A666;;A666
12597 A668;CYRILLIC CAPITAL LETTER MONOCULAR O;Lu;0;L;;;;;N;;;;A669;
12598 A669;CYRILLIC SMALL LETTER MONOCULAR O;Ll;0;L;;;;;N;;;A668;;A668
12599 A66A;CYRILLIC CAPITAL LETTER BINOCULAR O;Lu;0;L;;;;;N;;;;A66B;
12600 A66B;CYRILLIC SMALL LETTER BINOCULAR O;Ll;0;L;;;;;N;;;A66A;;A66A
12601 A66C;CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O;Lu;0;L;;;;;N;;;;A66D;
12602 A66D;CYRILLIC SMALL LETTER DOUBLE MONOCULAR O;Ll;0;L;;;;;N;;;A66C;;A66C
12603 A66E;CYRILLIC LETTER MULTIOCULAR O;Lo;0;L;;;;;N;;;;;
12604 A66F;COMBINING CYRILLIC VZMET;Mn;230;NSM;;;;;N;;;;;
12605 A670;COMBINING CYRILLIC TEN MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
12606 A671;COMBINING CYRILLIC HUNDRED MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
12607 A672;COMBINING CYRILLIC THOUSAND MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;
12608 A673;SLAVONIC ASTERISK;Po;0;ON;;;;;N;;;;;
12609 A67C;COMBINING CYRILLIC KAVYKA;Mn;230;NSM;;;;;N;;;;;
12610 A67D;COMBINING CYRILLIC PAYEROK;Mn;230;NSM;;;;;N;;;;;
12611 A67E;CYRILLIC KAVYKA;Po;0;ON;;;;;N;;;;;
12612 A67F;CYRILLIC PAYEROK;Lm;0;ON;;;;;N;;;;;
12613 A680;CYRILLIC CAPITAL LETTER DWE;Lu;0;L;;;;;N;;;;A681;
12614 A681;CYRILLIC SMALL LETTER DWE;Ll;0;L;;;;;N;;;A680;;A680
12615 A682;CYRILLIC CAPITAL LETTER DZWE;Lu;0;L;;;;;N;;;;A683;
12616 A683;CYRILLIC SMALL LETTER DZWE;Ll;0;L;;;;;N;;;A682;;A682
12617 A684;CYRILLIC CAPITAL LETTER ZHWE;Lu;0;L;;;;;N;;;;A685;
12618 A685;CYRILLIC SMALL LETTER ZHWE;Ll;0;L;;;;;N;;;A684;;A684
12619 A686;CYRILLIC CAPITAL LETTER CCHE;Lu;0;L;;;;;N;;;;A687;
12620 A687;CYRILLIC SMALL LETTER CCHE;Ll;0;L;;;;;N;;;A686;;A686
12621 A688;CYRILLIC CAPITAL LETTER DZZE;Lu;0;L;;;;;N;;;;A689;
12622 A689;CYRILLIC SMALL LETTER DZZE;Ll;0;L;;;;;N;;;A688;;A688
12623 A68A;CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;A68B;
12624 A68B;CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;A68A;;A68A
12625 A68C;CYRILLIC CAPITAL LETTER TWE;Lu;0;L;;;;;N;;;;A68D;
12626 A68D;CYRILLIC SMALL LETTER TWE;Ll;0;L;;;;;N;;;A68C;;A68C
12627 A68E;CYRILLIC CAPITAL LETTER TSWE;Lu;0;L;;;;;N;;;;A68F;
12628 A68F;CYRILLIC SMALL LETTER TSWE;Ll;0;L;;;;;N;;;A68E;;A68E
12629 A690;CYRILLIC CAPITAL LETTER TSSE;Lu;0;L;;;;;N;;;;A691;
12630 A691;CYRILLIC SMALL LETTER TSSE;Ll;0;L;;;;;N;;;A690;;A690
12631 A692;CYRILLIC CAPITAL LETTER TCHE;Lu;0;L;;;;;N;;;;A693;
12632 A693;CYRILLIC SMALL LETTER TCHE;Ll;0;L;;;;;N;;;A692;;A692
12633 A694;CYRILLIC CAPITAL LETTER HWE;Lu;0;L;;;;;N;;;;A695;
12634 A695;CYRILLIC SMALL LETTER HWE;Ll;0;L;;;;;N;;;A694;;A694
12635 A696;CYRILLIC CAPITAL LETTER SHWE;Lu;0;L;;;;;N;;;;A697;
12636 A697;CYRILLIC SMALL LETTER SHWE;Ll;0;L;;;;;N;;;A696;;A696
12637 A700;MODIFIER LETTER CHINESE TONE YIN PING;Sk;0;ON;;;;;N;;;;;
12638 A701;MODIFIER LETTER CHINESE TONE YANG PING;Sk;0;ON;;;;;N;;;;;
12639 A702;MODIFIER LETTER CHINESE TONE YIN SHANG;Sk;0;ON;;;;;N;;;;;
12640 A703;MODIFIER LETTER CHINESE TONE YANG SHANG;Sk;0;ON;;;;;N;;;;;
12641 A704;MODIFIER LETTER CHINESE TONE YIN QU;Sk;0;ON;;;;;N;;;;;
12642 A705;MODIFIER LETTER CHINESE TONE YANG QU;Sk;0;ON;;;;;N;;;;;
12643 A706;MODIFIER LETTER CHINESE TONE YIN RU;Sk;0;ON;;;;;N;;;;;
12644 A707;MODIFIER LETTER CHINESE TONE YANG RU;Sk;0;ON;;;;;N;;;;;
12645 A708;MODIFIER LETTER EXTRA-HIGH DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
12646 A709;MODIFIER LETTER HIGH DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
12647 A70A;MODIFIER LETTER MID DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
12648 A70B;MODIFIER LETTER LOW DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
12649 A70C;MODIFIER LETTER EXTRA-LOW DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;
12650 A70D;MODIFIER LETTER EXTRA-HIGH DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
12651 A70E;MODIFIER LETTER HIGH DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
12652 A70F;MODIFIER LETTER MID DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
12653 A710;MODIFIER LETTER LOW DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
12654 A711;MODIFIER LETTER EXTRA-LOW DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
12655 A712;MODIFIER LETTER EXTRA-HIGH LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
12656 A713;MODIFIER LETTER HIGH LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
12657 A714;MODIFIER LETTER MID LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
12658 A715;MODIFIER LETTER LOW LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
12659 A716;MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;
12660 A717;MODIFIER LETTER DOT VERTICAL BAR;Lm;0;ON;;;;;N;;;;;
12661 A718;MODIFIER LETTER DOT SLASH;Lm;0;ON;;;;;N;;;;;
12662 A719;MODIFIER LETTER DOT HORIZONTAL BAR;Lm;0;ON;;;;;N;;;;;
12663 A71A;MODIFIER LETTER LOWER RIGHT CORNER ANGLE;Lm;0;ON;;;;;N;;;;;
12664 A71B;MODIFIER LETTER RAISED UP ARROW;Lm;0;ON;;;;;N;;;;;
12665 A71C;MODIFIER LETTER RAISED DOWN ARROW;Lm;0;ON;;;;;N;;;;;
12666 A71D;MODIFIER LETTER RAISED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;;
12667 A71E;MODIFIER LETTER RAISED INVERTED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;;
12668 A71F;MODIFIER LETTER LOW INVERTED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;;
12669 A720;MODIFIER LETTER STRESS AND HIGH TONE;Sk;0;ON;;;;;N;;;;;
12670 A721;MODIFIER LETTER STRESS AND LOW TONE;Sk;0;ON;;;;;N;;;;;
12671 A722;LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF;Lu;0;L;;;;;N;;;;A723;
12672 A723;LATIN SMALL LETTER EGYPTOLOGICAL ALEF;Ll;0;L;;;;;N;;;A722;;A722
12673 A724;LATIN CAPITAL LETTER EGYPTOLOGICAL AIN;Lu;0;L;;;;;N;;;;A725;
12674 A725;LATIN SMALL LETTER EGYPTOLOGICAL AIN;Ll;0;L;;;;;N;;;A724;;A724
12675 A726;LATIN CAPITAL LETTER HENG;Lu;0;L;;;;;N;;;;A727;
12676 A727;LATIN SMALL LETTER HENG;Ll;0;L;;;;;N;;;A726;;A726
12677 A728;LATIN CAPITAL LETTER TZ;Lu;0;L;;;;;N;;;;A729;
12678 A729;LATIN SMALL LETTER TZ;Ll;0;L;;;;;N;;;A728;;A728
12679 A72A;LATIN CAPITAL LETTER TRESILLO;Lu;0;L;;;;;N;;;;A72B;
12680 A72B;LATIN SMALL LETTER TRESILLO;Ll;0;L;;;;;N;;;A72A;;A72A
12681 A72C;LATIN CAPITAL LETTER CUATRILLO;Lu;0;L;;;;;N;;;;A72D;
12682 A72D;LATIN SMALL LETTER CUATRILLO;Ll;0;L;;;;;N;;;A72C;;A72C
12683 A72E;LATIN CAPITAL LETTER CUATRILLO WITH COMMA;Lu;0;L;;;;;N;;;;A72F;
12684 A72F;LATIN SMALL LETTER CUATRILLO WITH COMMA;Ll;0;L;;;;;N;;;A72E;;A72E
12685 A730;LATIN LETTER SMALL CAPITAL F;Ll;0;L;;;;;N;;;;;
12686 A731;LATIN LETTER SMALL CAPITAL S;Ll;0;L;;;;;N;;;;;
12687 A732;LATIN CAPITAL LETTER AA;Lu;0;L;;;;;N;;;;A733;
12688 A733;LATIN SMALL LETTER AA;Ll;0;L;;;;;N;;;A732;;A732
12689 A734;LATIN CAPITAL LETTER AO;Lu;0;L;;;;;N;;;;A735;
12690 A735;LATIN SMALL LETTER AO;Ll;0;L;;;;;N;;;A734;;A734
12691 A736;LATIN CAPITAL LETTER AU;Lu;0;L;;;;;N;;;;A737;
12692 A737;LATIN SMALL LETTER AU;Ll;0;L;;;;;N;;;A736;;A736
12693 A738;LATIN CAPITAL LETTER AV;Lu;0;L;;;;;N;;;;A739;
12694 A739;LATIN SMALL LETTER AV;Ll;0;L;;;;;N;;;A738;;A738
12695 A73A;LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR;Lu;0;L;;;;;N;;;;A73B;
12696 A73B;LATIN SMALL LETTER AV WITH HORIZONTAL BAR;Ll;0;L;;;;;N;;;A73A;;A73A
12697 A73C;LATIN CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;A73D;
12698 A73D;LATIN SMALL LETTER AY;Ll;0;L;;;;;N;;;A73C;;A73C
12699 A73E;LATIN CAPITAL LETTER REVERSED C WITH DOT;Lu;0;L;;;;;N;;;;A73F;
12700 A73F;LATIN SMALL LETTER REVERSED C WITH DOT;Ll;0;L;;;;;N;;;A73E;;A73E
12701 A740;LATIN CAPITAL LETTER K WITH STROKE;Lu;0;L;;;;;N;;;;A741;
12702 A741;LATIN SMALL LETTER K WITH STROKE;Ll;0;L;;;;;N;;;A740;;A740
12703 A742;LATIN CAPITAL LETTER K WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A743;
12704 A743;LATIN SMALL LETTER K WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A742;;A742
12705 A744;LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A745;
12706 A745;LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE;Ll;0;L;;;;;N;;;A744;;A744
12707 A746;LATIN CAPITAL LETTER BROKEN L;Lu;0;L;;;;;N;;;;A747;
12708 A747;LATIN SMALL LETTER BROKEN L;Ll;0;L;;;;;N;;;A746;;A746
12709 A748;LATIN CAPITAL LETTER L WITH HIGH STROKE;Lu;0;L;;;;;N;;;;A749;
12710 A749;LATIN SMALL LETTER L WITH HIGH STROKE;Ll;0;L;;;;;N;;;A748;;A748
12711 A74A;LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY;Lu;0;L;;;;;N;;;;A74B;
12712 A74B;LATIN SMALL LETTER O WITH LONG STROKE OVERLAY;Ll;0;L;;;;;N;;;A74A;;A74A
12713 A74C;LATIN CAPITAL LETTER O WITH LOOP;Lu;0;L;;;;;N;;;;A74D;
12714 A74D;LATIN SMALL LETTER O WITH LOOP;Ll;0;L;;;;;N;;;A74C;;A74C
12715 A74E;LATIN CAPITAL LETTER OO;Lu;0;L;;;;;N;;;;A74F;
12716 A74F;LATIN SMALL LETTER OO;Ll;0;L;;;;;N;;;A74E;;A74E
12717 A750;LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A751;
12718 A751;LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A750;;A750
12719 A752;LATIN CAPITAL LETTER P WITH FLOURISH;Lu;0;L;;;;;N;;;;A753;
12720 A753;LATIN SMALL LETTER P WITH FLOURISH;Ll;0;L;;;;;N;;;A752;;A752
12721 A754;LATIN CAPITAL LETTER P WITH SQUIRREL TAIL;Lu;0;L;;;;;N;;;;A755;
12722 A755;LATIN SMALL LETTER P WITH SQUIRREL TAIL;Ll;0;L;;;;;N;;;A754;;A754
12723 A756;LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A757;
12724 A757;LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A756;;A756
12725 A758;LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A759;
12726 A759;LATIN SMALL LETTER Q WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A758;;A758
12727 A75A;LATIN CAPITAL LETTER R ROTUNDA;Lu;0;L;;;;;N;;;;A75B;
12728 A75B;LATIN SMALL LETTER R ROTUNDA;Ll;0;L;;;;;N;;;A75A;;A75A
12729 A75C;LATIN CAPITAL LETTER RUM ROTUNDA;Lu;0;L;;;;;N;;;;A75D;
12730 A75D;LATIN SMALL LETTER RUM ROTUNDA;Ll;0;L;;;;;N;;;A75C;;A75C
12731 A75E;LATIN CAPITAL LETTER V WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A75F;
12732 A75F;LATIN SMALL LETTER V WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A75E;;A75E
12733 A760;LATIN CAPITAL LETTER VY;Lu;0;L;;;;;N;;;;A761;
12734 A761;LATIN SMALL LETTER VY;Ll;0;L;;;;;N;;;A760;;A760
12735 A762;LATIN CAPITAL LETTER VISIGOTHIC Z;Lu;0;L;;;;;N;;;;A763;
12736 A763;LATIN SMALL LETTER VISIGOTHIC Z;Ll;0;L;;;;;N;;;A762;;A762
12737 A764;LATIN CAPITAL LETTER THORN WITH STROKE;Lu;0;L;;;;;N;;;;A765;
12738 A765;LATIN SMALL LETTER THORN WITH STROKE;Ll;0;L;;;;;N;;;A764;;A764
12739 A766;LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A767;
12740 A767;LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A766;;A766
12741 A768;LATIN CAPITAL LETTER VEND;Lu;0;L;;;;;N;;;;A769;
12742 A769;LATIN SMALL LETTER VEND;Ll;0;L;;;;;N;;;A768;;A768
12743 A76A;LATIN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;A76B;
12744 A76B;LATIN SMALL LETTER ET;Ll;0;L;;;;;N;;;A76A;;A76A
12745 A76C;LATIN CAPITAL LETTER IS;Lu;0;L;;;;;N;;;;A76D;
12746 A76D;LATIN SMALL LETTER IS;Ll;0;L;;;;;N;;;A76C;;A76C
12747 A76E;LATIN CAPITAL LETTER CON;Lu;0;L;;;;;N;;;;A76F;
12748 A76F;LATIN SMALL LETTER CON;Ll;0;L;;;;;N;;;A76E;;A76E
12749 A770;MODIFIER LETTER US;Lm;0;L;<super> A76F;;;;N;;;;;
12750 A771;LATIN SMALL LETTER DUM;Ll;0;L;;;;;N;;;;;
12751 A772;LATIN SMALL LETTER LUM;Ll;0;L;;;;;N;;;;;
12752 A773;LATIN SMALL LETTER MUM;Ll;0;L;;;;;N;;;;;
12753 A774;LATIN SMALL LETTER NUM;Ll;0;L;;;;;N;;;;;
12754 A775;LATIN SMALL LETTER RUM;Ll;0;L;;;;;N;;;;;
12755 A776;LATIN LETTER SMALL CAPITAL RUM;Ll;0;L;;;;;N;;;;;
12756 A777;LATIN SMALL LETTER TUM;Ll;0;L;;;;;N;;;;;
12757 A778;LATIN SMALL LETTER UM;Ll;0;L;;;;;N;;;;;
12758 A779;LATIN CAPITAL LETTER INSULAR D;Lu;0;L;;;;;N;;;;A77A;
12759 A77A;LATIN SMALL LETTER INSULAR D;Ll;0;L;;;;;N;;;A779;;A779
12760 A77B;LATIN CAPITAL LETTER INSULAR F;Lu;0;L;;;;;N;;;;A77C;
12761 A77C;LATIN SMALL LETTER INSULAR F;Ll;0;L;;;;;N;;;A77B;;A77B
12762 A77D;LATIN CAPITAL LETTER INSULAR G;Lu;0;L;;;;;N;;;;1D79;
12763 A77E;LATIN CAPITAL LETTER TURNED INSULAR G;Lu;0;L;;;;;N;;;;A77F;
12764 A77F;LATIN SMALL LETTER TURNED INSULAR G;Ll;0;L;;;;;N;;;A77E;;A77E
12765 A780;LATIN CAPITAL LETTER TURNED L;Lu;0;L;;;;;N;;;;A781;
12766 A781;LATIN SMALL LETTER TURNED L;Ll;0;L;;;;;N;;;A780;;A780
12767 A782;LATIN CAPITAL LETTER INSULAR R;Lu;0;L;;;;;N;;;;A783;
12768 A783;LATIN SMALL LETTER INSULAR R;Ll;0;L;;;;;N;;;A782;;A782
12769 A784;LATIN CAPITAL LETTER INSULAR S;Lu;0;L;;;;;N;;;;A785;
12770 A785;LATIN SMALL LETTER INSULAR S;Ll;0;L;;;;;N;;;A784;;A784
12771 A786;LATIN CAPITAL LETTER INSULAR T;Lu;0;L;;;;;N;;;;A787;
12772 A787;LATIN SMALL LETTER INSULAR T;Ll;0;L;;;;;N;;;A786;;A786
12773 A788;MODIFIER LETTER LOW CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;;;;;
12774 A789;MODIFIER LETTER COLON;Sk;0;L;;;;;N;;;;;
12775 A78A;MODIFIER LETTER SHORT EQUALS SIGN;Sk;0;L;;;;;N;;;;;
12776 A78B;LATIN CAPITAL LETTER SALTILLO;Lu;0;L;;;;;N;;;;A78C;
12777 A78C;LATIN SMALL LETTER SALTILLO;Ll;0;L;;;;;N;;;A78B;;A78B
12778 A7FB;LATIN EPIGRAPHIC LETTER REVERSED F;Lo;0;L;;;;;N;;;;;
12779 A7FC;LATIN EPIGRAPHIC LETTER REVERSED P;Lo;0;L;;;;;N;;;;;
12780 A7FD;LATIN EPIGRAPHIC LETTER INVERTED M;Lo;0;L;;;;;N;;;;;
12781 A7FE;LATIN EPIGRAPHIC LETTER I LONGA;Lo;0;L;;;;;N;;;;;
12782 A7FF;LATIN EPIGRAPHIC LETTER ARCHAIC M;Lo;0;L;;;;;N;;;;;
12783 A800;SYLOTI NAGRI LETTER A;Lo;0;L;;;;;N;;;;;
12784 A801;SYLOTI NAGRI LETTER I;Lo;0;L;;;;;N;;;;;
12785 A802;SYLOTI NAGRI SIGN DVISVARA;Mn;0;NSM;;;;;N;;;;;
12786 A803;SYLOTI NAGRI LETTER U;Lo;0;L;;;;;N;;;;;
12787 A804;SYLOTI NAGRI LETTER E;Lo;0;L;;;;;N;;;;;
12788 A805;SYLOTI NAGRI LETTER O;Lo;0;L;;;;;N;;;;;
12789 A806;SYLOTI NAGRI SIGN HASANTA;Mn;9;NSM;;;;;N;;;;;
12790 A807;SYLOTI NAGRI LETTER KO;Lo;0;L;;;;;N;;;;;
12791 A808;SYLOTI NAGRI LETTER KHO;Lo;0;L;;;;;N;;;;;
12792 A809;SYLOTI NAGRI LETTER GO;Lo;0;L;;;;;N;;;;;
12793 A80A;SYLOTI NAGRI LETTER GHO;Lo;0;L;;;;;N;;;;;
12794 A80B;SYLOTI NAGRI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
12795 A80C;SYLOTI NAGRI LETTER CO;Lo;0;L;;;;;N;;;;;
12796 A80D;SYLOTI NAGRI LETTER CHO;Lo;0;L;;;;;N;;;;;
12797 A80E;SYLOTI NAGRI LETTER JO;Lo;0;L;;;;;N;;;;;
12798 A80F;SYLOTI NAGRI LETTER JHO;Lo;0;L;;;;;N;;;;;
12799 A810;SYLOTI NAGRI LETTER TTO;Lo;0;L;;;;;N;;;;;
12800 A811;SYLOTI NAGRI LETTER TTHO;Lo;0;L;;;;;N;;;;;
12801 A812;SYLOTI NAGRI LETTER DDO;Lo;0;L;;;;;N;;;;;
12802 A813;SYLOTI NAGRI LETTER DDHO;Lo;0;L;;;;;N;;;;;
12803 A814;SYLOTI NAGRI LETTER TO;Lo;0;L;;;;;N;;;;;
12804 A815;SYLOTI NAGRI LETTER THO;Lo;0;L;;;;;N;;;;;
12805 A816;SYLOTI NAGRI LETTER DO;Lo;0;L;;;;;N;;;;;
12806 A817;SYLOTI NAGRI LETTER DHO;Lo;0;L;;;;;N;;;;;
12807 A818;SYLOTI NAGRI LETTER NO;Lo;0;L;;;;;N;;;;;
12808 A819;SYLOTI NAGRI LETTER PO;Lo;0;L;;;;;N;;;;;
12809 A81A;SYLOTI NAGRI LETTER PHO;Lo;0;L;;;;;N;;;;;
12810 A81B;SYLOTI NAGRI LETTER BO;Lo;0;L;;;;;N;;;;;
12811 A81C;SYLOTI NAGRI LETTER BHO;Lo;0;L;;;;;N;;;;;
12812 A81D;SYLOTI NAGRI LETTER MO;Lo;0;L;;;;;N;;;;;
12813 A81E;SYLOTI NAGRI LETTER RO;Lo;0;L;;;;;N;;;;;
12814 A81F;SYLOTI NAGRI LETTER LO;Lo;0;L;;;;;N;;;;;
12815 A820;SYLOTI NAGRI LETTER RRO;Lo;0;L;;;;;N;;;;;
12816 A821;SYLOTI NAGRI LETTER SO;Lo;0;L;;;;;N;;;;;
12817 A822;SYLOTI NAGRI LETTER HO;Lo;0;L;;;;;N;;;;;
12818 A823;SYLOTI NAGRI VOWEL SIGN A;Mc;0;L;;;;;N;;;;;
12819 A824;SYLOTI NAGRI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
12820 A825;SYLOTI NAGRI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
12821 A826;SYLOTI NAGRI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
12822 A827;SYLOTI NAGRI VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
12823 A828;SYLOTI NAGRI POETRY MARK-1;So;0;ON;;;;;N;;;;;
12824 A829;SYLOTI NAGRI POETRY MARK-2;So;0;ON;;;;;N;;;;;
12825 A82A;SYLOTI NAGRI POETRY MARK-3;So;0;ON;;;;;N;;;;;
12826 A82B;SYLOTI NAGRI POETRY MARK-4;So;0;ON;;;;;N;;;;;
12827 A840;PHAGS-PA LETTER KA;Lo;0;L;;;;;N;;;;;
12828 A841;PHAGS-PA LETTER KHA;Lo;0;L;;;;;N;;;;;
12829 A842;PHAGS-PA LETTER GA;Lo;0;L;;;;;N;;;;;
12830 A843;PHAGS-PA LETTER NGA;Lo;0;L;;;;;N;;;;;
12831 A844;PHAGS-PA LETTER CA;Lo;0;L;;;;;N;;;;;
12832 A845;PHAGS-PA LETTER CHA;Lo;0;L;;;;;N;;;;;
12833 A846;PHAGS-PA LETTER JA;Lo;0;L;;;;;N;;;;;
12834 A847;PHAGS-PA LETTER NYA;Lo;0;L;;;;;N;;;;;
12835 A848;PHAGS-PA LETTER TA;Lo;0;L;;;;;N;;;;;
12836 A849;PHAGS-PA LETTER THA;Lo;0;L;;;;;N;;;;;
12837 A84A;PHAGS-PA LETTER DA;Lo;0;L;;;;;N;;;;;
12838 A84B;PHAGS-PA LETTER NA;Lo;0;L;;;;;N;;;;;
12839 A84C;PHAGS-PA LETTER PA;Lo;0;L;;;;;N;;;;;
12840 A84D;PHAGS-PA LETTER PHA;Lo;0;L;;;;;N;;;;;
12841 A84E;PHAGS-PA LETTER BA;Lo;0;L;;;;;N;;;;;
12842 A84F;PHAGS-PA LETTER MA;Lo;0;L;;;;;N;;;;;
12843 A850;PHAGS-PA LETTER TSA;Lo;0;L;;;;;N;;;;;
12844 A851;PHAGS-PA LETTER TSHA;Lo;0;L;;;;;N;;;;;
12845 A852;PHAGS-PA LETTER DZA;Lo;0;L;;;;;N;;;;;
12846 A853;PHAGS-PA LETTER WA;Lo;0;L;;;;;N;;;;;
12847 A854;PHAGS-PA LETTER ZHA;Lo;0;L;;;;;N;;;;;
12848 A855;PHAGS-PA LETTER ZA;Lo;0;L;;;;;N;;;;;
12849 A856;PHAGS-PA LETTER SMALL A;Lo;0;L;;;;;N;;;;;
12850 A857;PHAGS-PA LETTER YA;Lo;0;L;;;;;N;;;;;
12851 A858;PHAGS-PA LETTER RA;Lo;0;L;;;;;N;;;;;
12852 A859;PHAGS-PA LETTER LA;Lo;0;L;;;;;N;;;;;
12853 A85A;PHAGS-PA LETTER SHA;Lo;0;L;;;;;N;;;;;
12854 A85B;PHAGS-PA LETTER SA;Lo;0;L;;;;;N;;;;;
12855 A85C;PHAGS-PA LETTER HA;Lo;0;L;;;;;N;;;;;
12856 A85D;PHAGS-PA LETTER A;Lo;0;L;;;;;N;;;;;
12857 A85E;PHAGS-PA LETTER I;Lo;0;L;;;;;N;;;;;
12858 A85F;PHAGS-PA LETTER U;Lo;0;L;;;;;N;;;;;
12859 A860;PHAGS-PA LETTER E;Lo;0;L;;;;;N;;;;;
12860 A861;PHAGS-PA LETTER O;Lo;0;L;;;;;N;;;;;
12861 A862;PHAGS-PA LETTER QA;Lo;0;L;;;;;N;;;;;
12862 A863;PHAGS-PA LETTER XA;Lo;0;L;;;;;N;;;;;
12863 A864;PHAGS-PA LETTER FA;Lo;0;L;;;;;N;;;;;
12864 A865;PHAGS-PA LETTER GGA;Lo;0;L;;;;;N;;;;;
12865 A866;PHAGS-PA LETTER EE;Lo;0;L;;;;;N;;;;;
12866 A867;PHAGS-PA SUBJOINED LETTER WA;Lo;0;L;;;;;N;;;;;
12867 A868;PHAGS-PA SUBJOINED LETTER YA;Lo;0;L;;;;;N;;;;;
12868 A869;PHAGS-PA LETTER TTA;Lo;0;L;;;;;N;;;;;
12869 A86A;PHAGS-PA LETTER TTHA;Lo;0;L;;;;;N;;;;;
12870 A86B;PHAGS-PA LETTER DDA;Lo;0;L;;;;;N;;;;;
12871 A86C;PHAGS-PA LETTER NNA;Lo;0;L;;;;;N;;;;;
12872 A86D;PHAGS-PA LETTER ALTERNATE YA;Lo;0;L;;;;;N;;;;;
12873 A86E;PHAGS-PA LETTER VOICELESS SHA;Lo;0;L;;;;;N;;;;;
12874 A86F;PHAGS-PA LETTER VOICED HA;Lo;0;L;;;;;N;;;;;
12875 A870;PHAGS-PA LETTER ASPIRATED FA;Lo;0;L;;;;;N;;;;;
12876 A871;PHAGS-PA SUBJOINED LETTER RA;Lo;0;L;;;;;N;;;;;
12877 A872;PHAGS-PA SUPERFIXED LETTER RA;Lo;0;L;;;;;N;;;;;
12878 A873;PHAGS-PA LETTER CANDRABINDU;Lo;0;L;;;;;N;;;;;
12879 A874;PHAGS-PA SINGLE HEAD MARK;Po;0;ON;;;;;N;;;;;
12880 A875;PHAGS-PA DOUBLE HEAD MARK;Po;0;ON;;;;;N;;;;;
12881 A876;PHAGS-PA MARK SHAD;Po;0;ON;;;;;N;;;;;
12882 A877;PHAGS-PA MARK DOUBLE SHAD;Po;0;ON;;;;;N;;;;;
12883 A880;SAURASHTRA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;
12884 A881;SAURASHTRA SIGN VISARGA;Mc;0;L;;;;;N;;;;;
12885 A882;SAURASHTRA LETTER A;Lo;0;L;;;;;N;;;;;
12886 A883;SAURASHTRA LETTER AA;Lo;0;L;;;;;N;;;;;
12887 A884;SAURASHTRA LETTER I;Lo;0;L;;;;;N;;;;;
12888 A885;SAURASHTRA LETTER II;Lo;0;L;;;;;N;;;;;
12889 A886;SAURASHTRA LETTER U;Lo;0;L;;;;;N;;;;;
12890 A887;SAURASHTRA LETTER UU;Lo;0;L;;;;;N;;;;;
12891 A888;SAURASHTRA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;
12892 A889;SAURASHTRA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;
12893 A88A;SAURASHTRA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;
12894 A88B;SAURASHTRA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;
12895 A88C;SAURASHTRA LETTER E;Lo;0;L;;;;;N;;;;;
12896 A88D;SAURASHTRA LETTER EE;Lo;0;L;;;;;N;;;;;
12897 A88E;SAURASHTRA LETTER AI;Lo;0;L;;;;;N;;;;;
12898 A88F;SAURASHTRA LETTER O;Lo;0;L;;;;;N;;;;;
12899 A890;SAURASHTRA LETTER OO;Lo;0;L;;;;;N;;;;;
12900 A891;SAURASHTRA LETTER AU;Lo;0;L;;;;;N;;;;;
12901 A892;SAURASHTRA LETTER KA;Lo;0;L;;;;;N;;;;;
12902 A893;SAURASHTRA LETTER KHA;Lo;0;L;;;;;N;;;;;
12903 A894;SAURASHTRA LETTER GA;Lo;0;L;;;;;N;;;;;
12904 A895;SAURASHTRA LETTER GHA;Lo;0;L;;;;;N;;;;;
12905 A896;SAURASHTRA LETTER NGA;Lo;0;L;;;;;N;;;;;
12906 A897;SAURASHTRA LETTER CA;Lo;0;L;;;;;N;;;;;
12907 A898;SAURASHTRA LETTER CHA;Lo;0;L;;;;;N;;;;;
12908 A899;SAURASHTRA LETTER JA;Lo;0;L;;;;;N;;;;;
12909 A89A;SAURASHTRA LETTER JHA;Lo;0;L;;;;;N;;;;;
12910 A89B;SAURASHTRA LETTER NYA;Lo;0;L;;;;;N;;;;;
12911 A89C;SAURASHTRA LETTER TTA;Lo;0;L;;;;;N;;;;;
12912 A89D;SAURASHTRA LETTER TTHA;Lo;0;L;;;;;N;;;;;
12913 A89E;SAURASHTRA LETTER DDA;Lo;0;L;;;;;N;;;;;
12914 A89F;SAURASHTRA LETTER DDHA;Lo;0;L;;;;;N;;;;;
12915 A8A0;SAURASHTRA LETTER NNA;Lo;0;L;;;;;N;;;;;
12916 A8A1;SAURASHTRA LETTER TA;Lo;0;L;;;;;N;;;;;
12917 A8A2;SAURASHTRA LETTER THA;Lo;0;L;;;;;N;;;;;
12918 A8A3;SAURASHTRA LETTER DA;Lo;0;L;;;;;N;;;;;
12919 A8A4;SAURASHTRA LETTER DHA;Lo;0;L;;;;;N;;;;;
12920 A8A5;SAURASHTRA LETTER NA;Lo;0;L;;;;;N;;;;;
12921 A8A6;SAURASHTRA LETTER PA;Lo;0;L;;;;;N;;;;;
12922 A8A7;SAURASHTRA LETTER PHA;Lo;0;L;;;;;N;;;;;
12923 A8A8;SAURASHTRA LETTER BA;Lo;0;L;;;;;N;;;;;
12924 A8A9;SAURASHTRA LETTER BHA;Lo;0;L;;;;;N;;;;;
12925 A8AA;SAURASHTRA LETTER MA;Lo;0;L;;;;;N;;;;;
12926 A8AB;SAURASHTRA LETTER YA;Lo;0;L;;;;;N;;;;;
12927 A8AC;SAURASHTRA LETTER RA;Lo;0;L;;;;;N;;;;;
12928 A8AD;SAURASHTRA LETTER LA;Lo;0;L;;;;;N;;;;;
12929 A8AE;SAURASHTRA LETTER VA;Lo;0;L;;;;;N;;;;;
12930 A8AF;SAURASHTRA LETTER SHA;Lo;0;L;;;;;N;;;;;
12931 A8B0;SAURASHTRA LETTER SSA;Lo;0;L;;;;;N;;;;;
12932 A8B1;SAURASHTRA LETTER SA;Lo;0;L;;;;;N;;;;;
12933 A8B2;SAURASHTRA LETTER HA;Lo;0;L;;;;;N;;;;;
12934 A8B3;SAURASHTRA LETTER LLA;Lo;0;L;;;;;N;;;;;
12935 A8B4;SAURASHTRA CONSONANT SIGN HAARU;Mc;0;L;;;;;N;;;;;
12936 A8B5;SAURASHTRA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;
12937 A8B6;SAURASHTRA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;
12938 A8B7;SAURASHTRA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;
12939 A8B8;SAURASHTRA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;
12940 A8B9;SAURASHTRA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;
12941 A8BA;SAURASHTRA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;
12942 A8BB;SAURASHTRA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;
12943 A8BC;SAURASHTRA VOWEL SIGN VOCALIC L;Mc;0;L;;;;;N;;;;;
12944 A8BD;SAURASHTRA VOWEL SIGN VOCALIC LL;Mc;0;L;;;;;N;;;;;
12945 A8BE;SAURASHTRA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;
12946 A8BF;SAURASHTRA VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;
12947 A8C0;SAURASHTRA VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
12948 A8C1;SAURASHTRA VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
12949 A8C2;SAURASHTRA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;
12950 A8C3;SAURASHTRA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;
12951 A8C4;SAURASHTRA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;
12952 A8CE;SAURASHTRA DANDA;Po;0;L;;;;;N;;;;;
12953 A8CF;SAURASHTRA DOUBLE DANDA;Po;0;L;;;;;N;;;;;
12954 A8D0;SAURASHTRA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
12955 A8D1;SAURASHTRA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
12956 A8D2;SAURASHTRA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
12957 A8D3;SAURASHTRA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
12958 A8D4;SAURASHTRA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
12959 A8D5;SAURASHTRA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
12960 A8D6;SAURASHTRA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
12961 A8D7;SAURASHTRA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
12962 A8D8;SAURASHTRA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
12963 A8D9;SAURASHTRA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
12964 A900;KAYAH LI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
12965 A901;KAYAH LI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
12966 A902;KAYAH LI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
12967 A903;KAYAH LI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
12968 A904;KAYAH LI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
12969 A905;KAYAH LI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
12970 A906;KAYAH LI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
12971 A907;KAYAH LI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
12972 A908;KAYAH LI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
12973 A909;KAYAH LI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
12974 A90A;KAYAH LI LETTER KA;Lo;0;L;;;;;N;;;;;
12975 A90B;KAYAH LI LETTER KHA;Lo;0;L;;;;;N;;;;;
12976 A90C;KAYAH LI LETTER GA;Lo;0;L;;;;;N;;;;;
12977 A90D;KAYAH LI LETTER NGA;Lo;0;L;;;;;N;;;;;
12978 A90E;KAYAH LI LETTER SA;Lo;0;L;;;;;N;;;;;
12979 A90F;KAYAH LI LETTER SHA;Lo;0;L;;;;;N;;;;;
12980 A910;KAYAH LI LETTER ZA;Lo;0;L;;;;;N;;;;;
12981 A911;KAYAH LI LETTER NYA;Lo;0;L;;;;;N;;;;;
12982 A912;KAYAH LI LETTER TA;Lo;0;L;;;;;N;;;;;
12983 A913;KAYAH LI LETTER HTA;Lo;0;L;;;;;N;;;;;
12984 A914;KAYAH LI LETTER NA;Lo;0;L;;;;;N;;;;;
12985 A915;KAYAH LI LETTER PA;Lo;0;L;;;;;N;;;;;
12986 A916;KAYAH LI LETTER PHA;Lo;0;L;;;;;N;;;;;
12987 A917;KAYAH LI LETTER MA;Lo;0;L;;;;;N;;;;;
12988 A918;KAYAH LI LETTER DA;Lo;0;L;;;;;N;;;;;
12989 A919;KAYAH LI LETTER BA;Lo;0;L;;;;;N;;;;;
12990 A91A;KAYAH LI LETTER RA;Lo;0;L;;;;;N;;;;;
12991 A91B;KAYAH LI LETTER YA;Lo;0;L;;;;;N;;;;;
12992 A91C;KAYAH LI LETTER LA;Lo;0;L;;;;;N;;;;;
12993 A91D;KAYAH LI LETTER WA;Lo;0;L;;;;;N;;;;;
12994 A91E;KAYAH LI LETTER THA;Lo;0;L;;;;;N;;;;;
12995 A91F;KAYAH LI LETTER HA;Lo;0;L;;;;;N;;;;;
12996 A920;KAYAH LI LETTER VA;Lo;0;L;;;;;N;;;;;
12997 A921;KAYAH LI LETTER CA;Lo;0;L;;;;;N;;;;;
12998 A922;KAYAH LI LETTER A;Lo;0;L;;;;;N;;;;;
12999 A923;KAYAH LI LETTER OE;Lo;0;L;;;;;N;;;;;
13000 A924;KAYAH LI LETTER I;Lo;0;L;;;;;N;;;;;
13001 A925;KAYAH LI LETTER OO;Lo;0;L;;;;;N;;;;;
13002 A926;KAYAH LI VOWEL UE;Mn;0;NSM;;;;;N;;;;;
13003 A927;KAYAH LI VOWEL E;Mn;0;NSM;;;;;N;;;;;
13004 A928;KAYAH LI VOWEL U;Mn;0;NSM;;;;;N;;;;;
13005 A929;KAYAH LI VOWEL EE;Mn;0;NSM;;;;;N;;;;;
13006 A92A;KAYAH LI VOWEL O;Mn;0;NSM;;;;;N;;;;;
13007 A92B;KAYAH LI TONE PLOPHU;Mn;220;NSM;;;;;N;;;;;
13008 A92C;KAYAH LI TONE CALYA;Mn;220;NSM;;;;;N;;;;;
13009 A92D;KAYAH LI TONE CALYA PLOPHU;Mn;220;NSM;;;;;N;;;;;
13010 A92E;KAYAH LI SIGN CWI;Po;0;L;;;;;N;;;;;
13011 A92F;KAYAH LI SIGN SHYA;Po;0;L;;;;;N;;;;;
13012 A930;REJANG LETTER KA;Lo;0;L;;;;;N;;;;;
13013 A931;REJANG LETTER GA;Lo;0;L;;;;;N;;;;;
13014 A932;REJANG LETTER NGA;Lo;0;L;;;;;N;;;;;
13015 A933;REJANG LETTER TA;Lo;0;L;;;;;N;;;;;
13016 A934;REJANG LETTER DA;Lo;0;L;;;;;N;;;;;
13017 A935;REJANG LETTER NA;Lo;0;L;;;;;N;;;;;
13018 A936;REJANG LETTER PA;Lo;0;L;;;;;N;;;;;
13019 A937;REJANG LETTER BA;Lo;0;L;;;;;N;;;;;
13020 A938;REJANG LETTER MA;Lo;0;L;;;;;N;;;;;
13021 A939;REJANG LETTER CA;Lo;0;L;;;;;N;;;;;
13022 A93A;REJANG LETTER JA;Lo;0;L;;;;;N;;;;;
13023 A93B;REJANG LETTER NYA;Lo;0;L;;;;;N;;;;;
13024 A93C;REJANG LETTER SA;Lo;0;L;;;;;N;;;;;
13025 A93D;REJANG LETTER RA;Lo;0;L;;;;;N;;;;;
13026 A93E;REJANG LETTER LA;Lo;0;L;;;;;N;;;;;
13027 A93F;REJANG LETTER YA;Lo;0;L;;;;;N;;;;;
13028 A940;REJANG LETTER WA;Lo;0;L;;;;;N;;;;;
13029 A941;REJANG LETTER HA;Lo;0;L;;;;;N;;;;;
13030 A942;REJANG LETTER MBA;Lo;0;L;;;;;N;;;;;
13031 A943;REJANG LETTER NGGA;Lo;0;L;;;;;N;;;;;
13032 A944;REJANG LETTER NDA;Lo;0;L;;;;;N;;;;;
13033 A945;REJANG LETTER NYJA;Lo;0;L;;;;;N;;;;;
13034 A946;REJANG LETTER A;Lo;0;L;;;;;N;;;;;
13035 A947;REJANG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
13036 A948;REJANG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
13037 A949;REJANG VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
13038 A94A;REJANG VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;
13039 A94B;REJANG VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
13040 A94C;REJANG VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
13041 A94D;REJANG VOWEL SIGN EU;Mn;0;NSM;;;;;N;;;;;
13042 A94E;REJANG VOWEL SIGN EA;Mn;0;NSM;;;;;N;;;;;
13043 A94F;REJANG CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;;
13044 A950;REJANG CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;;
13045 A951;REJANG CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;;
13046 A952;REJANG CONSONANT SIGN H;Mc;0;L;;;;;N;;;;;
13047 A953;REJANG VIRAMA;Mc;9;L;;;;;N;;;;;
13048 A95F;REJANG SECTION MARK;Po;0;L;;;;;N;;;;;
13049 AA00;CHAM LETTER A;Lo;0;L;;;;;N;;;;;
13050 AA01;CHAM LETTER I;Lo;0;L;;;;;N;;;;;
13051 AA02;CHAM LETTER U;Lo;0;L;;;;;N;;;;;
13052 AA03;CHAM LETTER E;Lo;0;L;;;;;N;;;;;
13053 AA04;CHAM LETTER AI;Lo;0;L;;;;;N;;;;;
13054 AA05;CHAM LETTER O;Lo;0;L;;;;;N;;;;;
13055 AA06;CHAM LETTER KA;Lo;0;L;;;;;N;;;;;
13056 AA07;CHAM LETTER KHA;Lo;0;L;;;;;N;;;;;
13057 AA08;CHAM LETTER GA;Lo;0;L;;;;;N;;;;;
13058 AA09;CHAM LETTER GHA;Lo;0;L;;;;;N;;;;;
13059 AA0A;CHAM LETTER NGUE;Lo;0;L;;;;;N;;;;;
13060 AA0B;CHAM LETTER NGA;Lo;0;L;;;;;N;;;;;
13061 AA0C;CHAM LETTER CHA;Lo;0;L;;;;;N;;;;;
13062 AA0D;CHAM LETTER CHHA;Lo;0;L;;;;;N;;;;;
13063 AA0E;CHAM LETTER JA;Lo;0;L;;;;;N;;;;;
13064 AA0F;CHAM LETTER JHA;Lo;0;L;;;;;N;;;;;
13065 AA10;CHAM LETTER NHUE;Lo;0;L;;;;;N;;;;;
13066 AA11;CHAM LETTER NHA;Lo;0;L;;;;;N;;;;;
13067 AA12;CHAM LETTER NHJA;Lo;0;L;;;;;N;;;;;
13068 AA13;CHAM LETTER TA;Lo;0;L;;;;;N;;;;;
13069 AA14;CHAM LETTER THA;Lo;0;L;;;;;N;;;;;
13070 AA15;CHAM LETTER DA;Lo;0;L;;;;;N;;;;;
13071 AA16;CHAM LETTER DHA;Lo;0;L;;;;;N;;;;;
13072 AA17;CHAM LETTER NUE;Lo;0;L;;;;;N;;;;;
13073 AA18;CHAM LETTER NA;Lo;0;L;;;;;N;;;;;
13074 AA19;CHAM LETTER DDA;Lo;0;L;;;;;N;;;;;
13075 AA1A;CHAM LETTER PA;Lo;0;L;;;;;N;;;;;
13076 AA1B;CHAM LETTER PPA;Lo;0;L;;;;;N;;;;;
13077 AA1C;CHAM LETTER PHA;Lo;0;L;;;;;N;;;;;
13078 AA1D;CHAM LETTER BA;Lo;0;L;;;;;N;;;;;
13079 AA1E;CHAM LETTER BHA;Lo;0;L;;;;;N;;;;;
13080 AA1F;CHAM LETTER MUE;Lo;0;L;;;;;N;;;;;
13081 AA20;CHAM LETTER MA;Lo;0;L;;;;;N;;;;;
13082 AA21;CHAM LETTER BBA;Lo;0;L;;;;;N;;;;;
13083 AA22;CHAM LETTER YA;Lo;0;L;;;;;N;;;;;
13084 AA23;CHAM LETTER RA;Lo;0;L;;;;;N;;;;;
13085 AA24;CHAM LETTER LA;Lo;0;L;;;;;N;;;;;
13086 AA25;CHAM LETTER VA;Lo;0;L;;;;;N;;;;;
13087 AA26;CHAM LETTER SSA;Lo;0;L;;;;;N;;;;;
13088 AA27;CHAM LETTER SA;Lo;0;L;;;;;N;;;;;
13089 AA28;CHAM LETTER HA;Lo;0;L;;;;;N;;;;;
13090 AA29;CHAM VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;
13091 AA2A;CHAM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
13092 AA2B;CHAM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;
13093 AA2C;CHAM VOWEL SIGN EI;Mn;0;NSM;;;;;N;;;;;
13094 AA2D;CHAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
13095 AA2E;CHAM VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;;
13096 AA2F;CHAM VOWEL SIGN O;Mc;0;L;;;;;N;;;;;
13097 AA30;CHAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;
13098 AA31;CHAM VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;
13099 AA32;CHAM VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;
13100 AA33;CHAM CONSONANT SIGN YA;Mc;0;L;;;;;N;;;;;
13101 AA34;CHAM CONSONANT SIGN RA;Mc;0;L;;;;;N;;;;;
13102 AA35;CHAM CONSONANT SIGN LA;Mn;0;NSM;;;;;N;;;;;
13103 AA36;CHAM CONSONANT SIGN WA;Mn;0;NSM;;;;;N;;;;;
13104 AA40;CHAM LETTER FINAL K;Lo;0;L;;;;;N;;;;;
13105 AA41;CHAM LETTER FINAL G;Lo;0;L;;;;;N;;;;;
13106 AA42;CHAM LETTER FINAL NG;Lo;0;L;;;;;N;;;;;
13107 AA43;CHAM CONSONANT SIGN FINAL NG;Mn;0;NSM;;;;;N;;;;;
13108 AA44;CHAM LETTER FINAL CH;Lo;0;L;;;;;N;;;;;
13109 AA45;CHAM LETTER FINAL T;Lo;0;L;;;;;N;;;;;
13110 AA46;CHAM LETTER FINAL N;Lo;0;L;;;;;N;;;;;
13111 AA47;CHAM LETTER FINAL P;Lo;0;L;;;;;N;;;;;
13112 AA48;CHAM LETTER FINAL Y;Lo;0;L;;;;;N;;;;;
13113 AA49;CHAM LETTER FINAL R;Lo;0;L;;;;;N;;;;;
13114 AA4A;CHAM LETTER FINAL L;Lo;0;L;;;;;N;;;;;
13115 AA4B;CHAM LETTER FINAL SS;Lo;0;L;;;;;N;;;;;
13116 AA4C;CHAM CONSONANT SIGN FINAL M;Mn;0;NSM;;;;;N;;;;;
13117 AA4D;CHAM CONSONANT SIGN FINAL H;Mc;0;L;;;;;N;;;;;
13118 AA50;CHAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
13119 AA51;CHAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
13120 AA52;CHAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
13121 AA53;CHAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
13122 AA54;CHAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
13123 AA55;CHAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
13124 AA56;CHAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
13125 AA57;CHAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
13126 AA58;CHAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
13127 AA59;CHAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
13128 AA5C;CHAM PUNCTUATION SPIRAL;Po;0;L;;;;;N;;;;;
13129 AA5D;CHAM PUNCTUATION DANDA;Po;0;L;;;;;N;;;;;
13130 AA5E;CHAM PUNCTUATION DOUBLE DANDA;Po;0;L;;;;;N;;;;;
13131 AA5F;CHAM PUNCTUATION TRIPLE DANDA;Po;0;L;;;;;N;;;;;
13132 AC00;<Hangul Syllable, First>;Lo;0;L;;;;;N;;;;;
13133 D7A3;<Hangul Syllable, Last>;Lo;0;L;;;;;N;;;;;
13134 D800;<Non Private Use High Surrogate, First>;Cs;0;L;;;;;N;;;;;
13135 DB7F;<Non Private Use High Surrogate, Last>;Cs;0;L;;;;;N;;;;;
13136 DB80;<Private Use High Surrogate, First>;Cs;0;L;;;;;N;;;;;
13137 DBFF;<Private Use High Surrogate, Last>;Cs;0;L;;;;;N;;;;;
13138 DC00;<Low Surrogate, First>;Cs;0;L;;;;;N;;;;;
13139 DFFF;<Low Surrogate, Last>;Cs;0;L;;;;;N;;;;;
13140 E000;<Private Use, First>;Co;0;L;;;;;N;;;;;
13141 F8FF;<Private Use, Last>;Co;0;L;;;;;N;;;;;
13142 F900;CJK COMPATIBILITY IDEOGRAPH-F900;Lo;0;L;8C48;;;;N;;;;;
13143 F901;CJK COMPATIBILITY IDEOGRAPH-F901;Lo;0;L;66F4;;;;N;;;;;
13144 F902;CJK COMPATIBILITY IDEOGRAPH-F902;Lo;0;L;8ECA;;;;N;;;;;
13145 F903;CJK COMPATIBILITY IDEOGRAPH-F903;Lo;0;L;8CC8;;;;N;;;;;
13146 F904;CJK COMPATIBILITY IDEOGRAPH-F904;Lo;0;L;6ED1;;;;N;;;;;
13147 F905;CJK COMPATIBILITY IDEOGRAPH-F905;Lo;0;L;4E32;;;;N;;;;;
13148 F906;CJK COMPATIBILITY IDEOGRAPH-F906;Lo;0;L;53E5;;;;N;;;;;
13149 F907;CJK COMPATIBILITY IDEOGRAPH-F907;Lo;0;L;9F9C;;;;N;;;;;
13150 F908;CJK COMPATIBILITY IDEOGRAPH-F908;Lo;0;L;9F9C;;;;N;;;;;
13151 F909;CJK COMPATIBILITY IDEOGRAPH-F909;Lo;0;L;5951;;;;N;;;;;
13152 F90A;CJK COMPATIBILITY IDEOGRAPH-F90A;Lo;0;L;91D1;;;;N;;;;;
13153 F90B;CJK COMPATIBILITY IDEOGRAPH-F90B;Lo;0;L;5587;;;;N;;;;;
13154 F90C;CJK COMPATIBILITY IDEOGRAPH-F90C;Lo;0;L;5948;;;;N;;;;;
13155 F90D;CJK COMPATIBILITY IDEOGRAPH-F90D;Lo;0;L;61F6;;;;N;;;;;
13156 F90E;CJK COMPATIBILITY IDEOGRAPH-F90E;Lo;0;L;7669;;;;N;;;;;
13157 F90F;CJK COMPATIBILITY IDEOGRAPH-F90F;Lo;0;L;7F85;;;;N;;;;;
13158 F910;CJK COMPATIBILITY IDEOGRAPH-F910;Lo;0;L;863F;;;;N;;;;;
13159 F911;CJK COMPATIBILITY IDEOGRAPH-F911;Lo;0;L;87BA;;;;N;;;;;
13160 F912;CJK COMPATIBILITY IDEOGRAPH-F912;Lo;0;L;88F8;;;;N;;;;;
13161 F913;CJK COMPATIBILITY IDEOGRAPH-F913;Lo;0;L;908F;;;;N;;;;;
13162 F914;CJK COMPATIBILITY IDEOGRAPH-F914;Lo;0;L;6A02;;;;N;;;;;
13163 F915;CJK COMPATIBILITY IDEOGRAPH-F915;Lo;0;L;6D1B;;;;N;;;;;
13164 F916;CJK COMPATIBILITY IDEOGRAPH-F916;Lo;0;L;70D9;;;;N;;;;;
13165 F917;CJK COMPATIBILITY IDEOGRAPH-F917;Lo;0;L;73DE;;;;N;;;;;
13166 F918;CJK COMPATIBILITY IDEOGRAPH-F918;Lo;0;L;843D;;;;N;;;;;
13167 F919;CJK COMPATIBILITY IDEOGRAPH-F919;Lo;0;L;916A;;;;N;;;;;
13168 F91A;CJK COMPATIBILITY IDEOGRAPH-F91A;Lo;0;L;99F1;;;;N;;;;;
13169 F91B;CJK COMPATIBILITY IDEOGRAPH-F91B;Lo;0;L;4E82;;;;N;;;;;
13170 F91C;CJK COMPATIBILITY IDEOGRAPH-F91C;Lo;0;L;5375;;;;N;;;;;
13171 F91D;CJK COMPATIBILITY IDEOGRAPH-F91D;Lo;0;L;6B04;;;;N;;;;;
13172 F91E;CJK COMPATIBILITY IDEOGRAPH-F91E;Lo;0;L;721B;;;;N;;;;;
13173 F91F;CJK COMPATIBILITY IDEOGRAPH-F91F;Lo;0;L;862D;;;;N;;;;;
13174 F920;CJK COMPATIBILITY IDEOGRAPH-F920;Lo;0;L;9E1E;;;;N;;;;;
13175 F921;CJK COMPATIBILITY IDEOGRAPH-F921;Lo;0;L;5D50;;;;N;;;;;
13176 F922;CJK COMPATIBILITY IDEOGRAPH-F922;Lo;0;L;6FEB;;;;N;;;;;
13177 F923;CJK COMPATIBILITY IDEOGRAPH-F923;Lo;0;L;85CD;;;;N;;;;;
13178 F924;CJK COMPATIBILITY IDEOGRAPH-F924;Lo;0;L;8964;;;;N;;;;;
13179 F925;CJK COMPATIBILITY IDEOGRAPH-F925;Lo;0;L;62C9;;;;N;;;;;
13180 F926;CJK COMPATIBILITY IDEOGRAPH-F926;Lo;0;L;81D8;;;;N;;;;;
13181 F927;CJK COMPATIBILITY IDEOGRAPH-F927;Lo;0;L;881F;;;;N;;;;;
13182 F928;CJK COMPATIBILITY IDEOGRAPH-F928;Lo;0;L;5ECA;;;;N;;;;;
13183 F929;CJK COMPATIBILITY IDEOGRAPH-F929;Lo;0;L;6717;;;;N;;;;;
13184 F92A;CJK COMPATIBILITY IDEOGRAPH-F92A;Lo;0;L;6D6A;;;;N;;;;;
13185 F92B;CJK COMPATIBILITY IDEOGRAPH-F92B;Lo;0;L;72FC;;;;N;;;;;
13186 F92C;CJK COMPATIBILITY IDEOGRAPH-F92C;Lo;0;L;90CE;;;;N;;;;;
13187 F92D;CJK COMPATIBILITY IDEOGRAPH-F92D;Lo;0;L;4F86;;;;N;;;;;
13188 F92E;CJK COMPATIBILITY IDEOGRAPH-F92E;Lo;0;L;51B7;;;;N;;;;;
13189 F92F;CJK COMPATIBILITY IDEOGRAPH-F92F;Lo;0;L;52DE;;;;N;;;;;
13190 F930;CJK COMPATIBILITY IDEOGRAPH-F930;Lo;0;L;64C4;;;;N;;;;;
13191 F931;CJK COMPATIBILITY IDEOGRAPH-F931;Lo;0;L;6AD3;;;;N;;;;;
13192 F932;CJK COMPATIBILITY IDEOGRAPH-F932;Lo;0;L;7210;;;;N;;;;;
13193 F933;CJK COMPATIBILITY IDEOGRAPH-F933;Lo;0;L;76E7;;;;N;;;;;
13194 F934;CJK COMPATIBILITY IDEOGRAPH-F934;Lo;0;L;8001;;;;N;;;;;
13195 F935;CJK COMPATIBILITY IDEOGRAPH-F935;Lo;0;L;8606;;;;N;;;;;
13196 F936;CJK COMPATIBILITY IDEOGRAPH-F936;Lo;0;L;865C;;;;N;;;;;
13197 F937;CJK COMPATIBILITY IDEOGRAPH-F937;Lo;0;L;8DEF;;;;N;;;;;
13198 F938;CJK COMPATIBILITY IDEOGRAPH-F938;Lo;0;L;9732;;;;N;;;;;
13199 F939;CJK COMPATIBILITY IDEOGRAPH-F939;Lo;0;L;9B6F;;;;N;;;;;
13200 F93A;CJK COMPATIBILITY IDEOGRAPH-F93A;Lo;0;L;9DFA;;;;N;;;;;
13201 F93B;CJK COMPATIBILITY IDEOGRAPH-F93B;Lo;0;L;788C;;;;N;;;;;
13202 F93C;CJK COMPATIBILITY IDEOGRAPH-F93C;Lo;0;L;797F;;;;N;;;;;
13203 F93D;CJK COMPATIBILITY IDEOGRAPH-F93D;Lo;0;L;7DA0;;;;N;;;;;
13204 F93E;CJK COMPATIBILITY IDEOGRAPH-F93E;Lo;0;L;83C9;;;;N;;;;;
13205 F93F;CJK COMPATIBILITY IDEOGRAPH-F93F;Lo;0;L;9304;;;;N;;;;;
13206 F940;CJK COMPATIBILITY IDEOGRAPH-F940;Lo;0;L;9E7F;;;;N;;;;;
13207 F941;CJK COMPATIBILITY IDEOGRAPH-F941;Lo;0;L;8AD6;;;;N;;;;;
13208 F942;CJK COMPATIBILITY IDEOGRAPH-F942;Lo;0;L;58DF;;;;N;;;;;
13209 F943;CJK COMPATIBILITY IDEOGRAPH-F943;Lo;0;L;5F04;;;;N;;;;;
13210 F944;CJK COMPATIBILITY IDEOGRAPH-F944;Lo;0;L;7C60;;;;N;;;;;
13211 F945;CJK COMPATIBILITY IDEOGRAPH-F945;Lo;0;L;807E;;;;N;;;;;
13212 F946;CJK COMPATIBILITY IDEOGRAPH-F946;Lo;0;L;7262;;;;N;;;;;
13213 F947;CJK COMPATIBILITY IDEOGRAPH-F947;Lo;0;L;78CA;;;;N;;;;;
13214 F948;CJK COMPATIBILITY IDEOGRAPH-F948;Lo;0;L;8CC2;;;;N;;;;;
13215 F949;CJK COMPATIBILITY IDEOGRAPH-F949;Lo;0;L;96F7;;;;N;;;;;
13216 F94A;CJK COMPATIBILITY IDEOGRAPH-F94A;Lo;0;L;58D8;;;;N;;;;;
13217 F94B;CJK COMPATIBILITY IDEOGRAPH-F94B;Lo;0;L;5C62;;;;N;;;;;
13218 F94C;CJK COMPATIBILITY IDEOGRAPH-F94C;Lo;0;L;6A13;;;;N;;;;;
13219 F94D;CJK COMPATIBILITY IDEOGRAPH-F94D;Lo;0;L;6DDA;;;;N;;;;;
13220 F94E;CJK COMPATIBILITY IDEOGRAPH-F94E;Lo;0;L;6F0F;;;;N;;;;;
13221 F94F;CJK COMPATIBILITY IDEOGRAPH-F94F;Lo;0;L;7D2F;;;;N;;;;;
13222 F950;CJK COMPATIBILITY IDEOGRAPH-F950;Lo;0;L;7E37;;;;N;;;;;
13223 F951;CJK COMPATIBILITY IDEOGRAPH-F951;Lo;0;L;964B;;;;N;;;;;
13224 F952;CJK COMPATIBILITY IDEOGRAPH-F952;Lo;0;L;52D2;;;;N;;;;;
13225 F953;CJK COMPATIBILITY IDEOGRAPH-F953;Lo;0;L;808B;;;;N;;;;;
13226 F954;CJK COMPATIBILITY IDEOGRAPH-F954;Lo;0;L;51DC;;;;N;;;;;
13227 F955;CJK COMPATIBILITY IDEOGRAPH-F955;Lo;0;L;51CC;;;;N;;;;;
13228 F956;CJK COMPATIBILITY IDEOGRAPH-F956;Lo;0;L;7A1C;;;;N;;;;;
13229 F957;CJK COMPATIBILITY IDEOGRAPH-F957;Lo;0;L;7DBE;;;;N;;;;;
13230 F958;CJK COMPATIBILITY IDEOGRAPH-F958;Lo;0;L;83F1;;;;N;;;;;
13231 F959;CJK COMPATIBILITY IDEOGRAPH-F959;Lo;0;L;9675;;;;N;;;;;
13232 F95A;CJK COMPATIBILITY IDEOGRAPH-F95A;Lo;0;L;8B80;;;;N;;;;;
13233 F95B;CJK COMPATIBILITY IDEOGRAPH-F95B;Lo;0;L;62CF;;;;N;;;;;
13234 F95C;CJK COMPATIBILITY IDEOGRAPH-F95C;Lo;0;L;6A02;;;;N;;;;;
13235 F95D;CJK COMPATIBILITY IDEOGRAPH-F95D;Lo;0;L;8AFE;;;;N;;;;;
13236 F95E;CJK COMPATIBILITY IDEOGRAPH-F95E;Lo;0;L;4E39;;;;N;;;;;
13237 F95F;CJK COMPATIBILITY IDEOGRAPH-F95F;Lo;0;L;5BE7;;;;N;;;;;
13238 F960;CJK COMPATIBILITY IDEOGRAPH-F960;Lo;0;L;6012;;;;N;;;;;
13239 F961;CJK COMPATIBILITY IDEOGRAPH-F961;Lo;0;L;7387;;;;N;;;;;
13240 F962;CJK COMPATIBILITY IDEOGRAPH-F962;Lo;0;L;7570;;;;N;;;;;
13241 F963;CJK COMPATIBILITY IDEOGRAPH-F963;Lo;0;L;5317;;;;N;;;;;
13242 F964;CJK COMPATIBILITY IDEOGRAPH-F964;Lo;0;L;78FB;;;;N;;;;;
13243 F965;CJK COMPATIBILITY IDEOGRAPH-F965;Lo;0;L;4FBF;;;;N;;;;;
13244 F966;CJK COMPATIBILITY IDEOGRAPH-F966;Lo;0;L;5FA9;;;;N;;;;;
13245 F967;CJK COMPATIBILITY IDEOGRAPH-F967;Lo;0;L;4E0D;;;;N;;;;;
13246 F968;CJK COMPATIBILITY IDEOGRAPH-F968;Lo;0;L;6CCC;;;;N;;;;;
13247 F969;CJK COMPATIBILITY IDEOGRAPH-F969;Lo;0;L;6578;;;;N;;;;;
13248 F96A;CJK COMPATIBILITY IDEOGRAPH-F96A;Lo;0;L;7D22;;;;N;;;;;
13249 F96B;CJK COMPATIBILITY IDEOGRAPH-F96B;Lo;0;L;53C3;;;3;N;;;;;
13250 F96C;CJK COMPATIBILITY IDEOGRAPH-F96C;Lo;0;L;585E;;;;N;;;;;
13251 F96D;CJK COMPATIBILITY IDEOGRAPH-F96D;Lo;0;L;7701;;;;N;;;;;
13252 F96E;CJK COMPATIBILITY IDEOGRAPH-F96E;Lo;0;L;8449;;;;N;;;;;
13253 F96F;CJK COMPATIBILITY IDEOGRAPH-F96F;Lo;0;L;8AAA;;;;N;;;;;
13254 F970;CJK COMPATIBILITY IDEOGRAPH-F970;Lo;0;L;6BBA;;;;N;;;;;
13255 F971;CJK COMPATIBILITY IDEOGRAPH-F971;Lo;0;L;8FB0;;;;N;;;;;
13256 F972;CJK COMPATIBILITY IDEOGRAPH-F972;Lo;0;L;6C88;;;;N;;;;;
13257 F973;CJK COMPATIBILITY IDEOGRAPH-F973;Lo;0;L;62FE;;;10;N;;;;;
13258 F974;CJK COMPATIBILITY IDEOGRAPH-F974;Lo;0;L;82E5;;;;N;;;;;
13259 F975;CJK COMPATIBILITY IDEOGRAPH-F975;Lo;0;L;63A0;;;;N;;;;;
13260 F976;CJK COMPATIBILITY IDEOGRAPH-F976;Lo;0;L;7565;;;;N;;;;;
13261 F977;CJK COMPATIBILITY IDEOGRAPH-F977;Lo;0;L;4EAE;;;;N;;;;;
13262 F978;CJK COMPATIBILITY IDEOGRAPH-F978;Lo;0;L;5169;;;2;N;;;;;
13263 F979;CJK COMPATIBILITY IDEOGRAPH-F979;Lo;0;L;51C9;;;;N;;;;;
13264 F97A;CJK COMPATIBILITY IDEOGRAPH-F97A;Lo;0;L;6881;;;;N;;;;;
13265 F97B;CJK COMPATIBILITY IDEOGRAPH-F97B;Lo;0;L;7CE7;;;;N;;;;;
13266 F97C;CJK COMPATIBILITY IDEOGRAPH-F97C;Lo;0;L;826F;;;;N;;;;;
13267 F97D;CJK COMPATIBILITY IDEOGRAPH-F97D;Lo;0;L;8AD2;;;;N;;;;;
13268 F97E;CJK COMPATIBILITY IDEOGRAPH-F97E;Lo;0;L;91CF;;;;N;;;;;
13269 F97F;CJK COMPATIBILITY IDEOGRAPH-F97F;Lo;0;L;52F5;;;;N;;;;;
13270 F980;CJK COMPATIBILITY IDEOGRAPH-F980;Lo;0;L;5442;;;;N;;;;;
13271 F981;CJK COMPATIBILITY IDEOGRAPH-F981;Lo;0;L;5973;;;;N;;;;;
13272 F982;CJK COMPATIBILITY IDEOGRAPH-F982;Lo;0;L;5EEC;;;;N;;;;;
13273 F983;CJK COMPATIBILITY IDEOGRAPH-F983;Lo;0;L;65C5;;;;N;;;;;
13274 F984;CJK COMPATIBILITY IDEOGRAPH-F984;Lo;0;L;6FFE;;;;N;;;;;
13275 F985;CJK COMPATIBILITY IDEOGRAPH-F985;Lo;0;L;792A;;;;N;;;;;
13276 F986;CJK COMPATIBILITY IDEOGRAPH-F986;Lo;0;L;95AD;;;;N;;;;;
13277 F987;CJK COMPATIBILITY IDEOGRAPH-F987;Lo;0;L;9A6A;;;;N;;;;;
13278 F988;CJK COMPATIBILITY IDEOGRAPH-F988;Lo;0;L;9E97;;;;N;;;;;
13279 F989;CJK COMPATIBILITY IDEOGRAPH-F989;Lo;0;L;9ECE;;;;N;;;;;
13280 F98A;CJK COMPATIBILITY IDEOGRAPH-F98A;Lo;0;L;529B;;;;N;;;;;
13281 F98B;CJK COMPATIBILITY IDEOGRAPH-F98B;Lo;0;L;66C6;;;;N;;;;;
13282 F98C;CJK COMPATIBILITY IDEOGRAPH-F98C;Lo;0;L;6B77;;;;N;;;;;
13283 F98D;CJK COMPATIBILITY IDEOGRAPH-F98D;Lo;0;L;8F62;;;;N;;;;;
13284 F98E;CJK COMPATIBILITY IDEOGRAPH-F98E;Lo;0;L;5E74;;;;N;;;;;
13285 F98F;CJK COMPATIBILITY IDEOGRAPH-F98F;Lo;0;L;6190;;;;N;;;;;
13286 F990;CJK COMPATIBILITY IDEOGRAPH-F990;Lo;0;L;6200;;;;N;;;;;
13287 F991;CJK COMPATIBILITY IDEOGRAPH-F991;Lo;0;L;649A;;;;N;;;;;
13288 F992;CJK COMPATIBILITY IDEOGRAPH-F992;Lo;0;L;6F23;;;;N;;;;;
13289 F993;CJK COMPATIBILITY IDEOGRAPH-F993;Lo;0;L;7149;;;;N;;;;;
13290 F994;CJK COMPATIBILITY IDEOGRAPH-F994;Lo;0;L;7489;;;;N;;;;;
13291 F995;CJK COMPATIBILITY IDEOGRAPH-F995;Lo;0;L;79CA;;;;N;;;;;
13292 F996;CJK COMPATIBILITY IDEOGRAPH-F996;Lo;0;L;7DF4;;;;N;;;;;
13293 F997;CJK COMPATIBILITY IDEOGRAPH-F997;Lo;0;L;806F;;;;N;;;;;
13294 F998;CJK COMPATIBILITY IDEOGRAPH-F998;Lo;0;L;8F26;;;;N;;;;;
13295 F999;CJK COMPATIBILITY IDEOGRAPH-F999;Lo;0;L;84EE;;;;N;;;;;
13296 F99A;CJK COMPATIBILITY IDEOGRAPH-F99A;Lo;0;L;9023;;;;N;;;;;
13297 F99B;CJK COMPATIBILITY IDEOGRAPH-F99B;Lo;0;L;934A;;;;N;;;;;
13298 F99C;CJK COMPATIBILITY IDEOGRAPH-F99C;Lo;0;L;5217;;;;N;;;;;
13299 F99D;CJK COMPATIBILITY IDEOGRAPH-F99D;Lo;0;L;52A3;;;;N;;;;;
13300 F99E;CJK COMPATIBILITY IDEOGRAPH-F99E;Lo;0;L;54BD;;;;N;;;;;
13301 F99F;CJK COMPATIBILITY IDEOGRAPH-F99F;Lo;0;L;70C8;;;;N;;;;;
13302 F9A0;CJK COMPATIBILITY IDEOGRAPH-F9A0;Lo;0;L;88C2;;;;N;;;;;
13303 F9A1;CJK COMPATIBILITY IDEOGRAPH-F9A1;Lo;0;L;8AAA;;;;N;;;;;
13304 F9A2;CJK COMPATIBILITY IDEOGRAPH-F9A2;Lo;0;L;5EC9;;;;N;;;;;
13305 F9A3;CJK COMPATIBILITY IDEOGRAPH-F9A3;Lo;0;L;5FF5;;;;N;;;;;
13306 F9A4;CJK COMPATIBILITY IDEOGRAPH-F9A4;Lo;0;L;637B;;;;N;;;;;
13307 F9A5;CJK COMPATIBILITY IDEOGRAPH-F9A5;Lo;0;L;6BAE;;;;N;;;;;
13308 F9A6;CJK COMPATIBILITY IDEOGRAPH-F9A6;Lo;0;L;7C3E;;;;N;;;;;
13309 F9A7;CJK COMPATIBILITY IDEOGRAPH-F9A7;Lo;0;L;7375;;;;N;;;;;
13310 F9A8;CJK COMPATIBILITY IDEOGRAPH-F9A8;Lo;0;L;4EE4;;;;N;;;;;
13311 F9A9;CJK COMPATIBILITY IDEOGRAPH-F9A9;Lo;0;L;56F9;;;;N;;;;;
13312 F9AA;CJK COMPATIBILITY IDEOGRAPH-F9AA;Lo;0;L;5BE7;;;;N;;;;;
13313 F9AB;CJK COMPATIBILITY IDEOGRAPH-F9AB;Lo;0;L;5DBA;;;;N;;;;;
13314 F9AC;CJK COMPATIBILITY IDEOGRAPH-F9AC;Lo;0;L;601C;;;;N;;;;;
13315 F9AD;CJK COMPATIBILITY IDEOGRAPH-F9AD;Lo;0;L;73B2;;;;N;;;;;
13316 F9AE;CJK COMPATIBILITY IDEOGRAPH-F9AE;Lo;0;L;7469;;;;N;;;;;
13317 F9AF;CJK COMPATIBILITY IDEOGRAPH-F9AF;Lo;0;L;7F9A;;;;N;;;;;
13318 F9B0;CJK COMPATIBILITY IDEOGRAPH-F9B0;Lo;0;L;8046;;;;N;;;;;
13319 F9B1;CJK COMPATIBILITY IDEOGRAPH-F9B1;Lo;0;L;9234;;;;N;;;;;
13320 F9B2;CJK COMPATIBILITY IDEOGRAPH-F9B2;Lo;0;L;96F6;;;0;N;;;;;
13321 F9B3;CJK COMPATIBILITY IDEOGRAPH-F9B3;Lo;0;L;9748;;;;N;;;;;
13322 F9B4;CJK COMPATIBILITY IDEOGRAPH-F9B4;Lo;0;L;9818;;;;N;;;;;
13323 F9B5;CJK COMPATIBILITY IDEOGRAPH-F9B5;Lo;0;L;4F8B;;;;N;;;;;
13324 F9B6;CJK COMPATIBILITY IDEOGRAPH-F9B6;Lo;0;L;79AE;;;;N;;;;;
13325 F9B7;CJK COMPATIBILITY IDEOGRAPH-F9B7;Lo;0;L;91B4;;;;N;;;;;
13326 F9B8;CJK COMPATIBILITY IDEOGRAPH-F9B8;Lo;0;L;96B8;;;;N;;;;;
13327 F9B9;CJK COMPATIBILITY IDEOGRAPH-F9B9;Lo;0;L;60E1;;;;N;;;;;
13328 F9BA;CJK COMPATIBILITY IDEOGRAPH-F9BA;Lo;0;L;4E86;;;;N;;;;;
13329 F9BB;CJK COMPATIBILITY IDEOGRAPH-F9BB;Lo;0;L;50DA;;;;N;;;;;
13330 F9BC;CJK COMPATIBILITY IDEOGRAPH-F9BC;Lo;0;L;5BEE;;;;N;;;;;
13331 F9BD;CJK COMPATIBILITY IDEOGRAPH-F9BD;Lo;0;L;5C3F;;;;N;;;;;
13332 F9BE;CJK COMPATIBILITY IDEOGRAPH-F9BE;Lo;0;L;6599;;;;N;;;;;
13333 F9BF;CJK COMPATIBILITY IDEOGRAPH-F9BF;Lo;0;L;6A02;;;;N;;;;;
13334 F9C0;CJK COMPATIBILITY IDEOGRAPH-F9C0;Lo;0;L;71CE;;;;N;;;;;
13335 F9C1;CJK COMPATIBILITY IDEOGRAPH-F9C1;Lo;0;L;7642;;;;N;;;;;
13336 F9C2;CJK COMPATIBILITY IDEOGRAPH-F9C2;Lo;0;L;84FC;;;;N;;;;;
13337 F9C3;CJK COMPATIBILITY IDEOGRAPH-F9C3;Lo;0;L;907C;;;;N;;;;;
13338 F9C4;CJK COMPATIBILITY IDEOGRAPH-F9C4;Lo;0;L;9F8D;;;;N;;;;;
13339 F9C5;CJK COMPATIBILITY IDEOGRAPH-F9C5;Lo;0;L;6688;;;;N;;;;;
13340 F9C6;CJK COMPATIBILITY IDEOGRAPH-F9C6;Lo;0;L;962E;;;;N;;;;;
13341 F9C7;CJK COMPATIBILITY IDEOGRAPH-F9C7;Lo;0;L;5289;;;;N;;;;;
13342 F9C8;CJK COMPATIBILITY IDEOGRAPH-F9C8;Lo;0;L;677B;;;;N;;;;;
13343 F9C9;CJK COMPATIBILITY IDEOGRAPH-F9C9;Lo;0;L;67F3;;;;N;;;;;
13344 F9CA;CJK COMPATIBILITY IDEOGRAPH-F9CA;Lo;0;L;6D41;;;;N;;;;;
13345 F9CB;CJK COMPATIBILITY IDEOGRAPH-F9CB;Lo;0;L;6E9C;;;;N;;;;;
13346 F9CC;CJK COMPATIBILITY IDEOGRAPH-F9CC;Lo;0;L;7409;;;;N;;;;;
13347 F9CD;CJK COMPATIBILITY IDEOGRAPH-F9CD;Lo;0;L;7559;;;;N;;;;;
13348 F9CE;CJK COMPATIBILITY IDEOGRAPH-F9CE;Lo;0;L;786B;;;;N;;;;;
13349 F9CF;CJK COMPATIBILITY IDEOGRAPH-F9CF;Lo;0;L;7D10;;;;N;;;;;
13350 F9D0;CJK COMPATIBILITY IDEOGRAPH-F9D0;Lo;0;L;985E;;;;N;;;;;
13351 F9D1;CJK COMPATIBILITY IDEOGRAPH-F9D1;Lo;0;L;516D;;;6;N;;;;;
13352 F9D2;CJK COMPATIBILITY IDEOGRAPH-F9D2;Lo;0;L;622E;;;;N;;;;;
13353 F9D3;CJK COMPATIBILITY IDEOGRAPH-F9D3;Lo;0;L;9678;;;6;N;;;;;
13354 F9D4;CJK COMPATIBILITY IDEOGRAPH-F9D4;Lo;0;L;502B;;;;N;;;;;
13355 F9D5;CJK COMPATIBILITY IDEOGRAPH-F9D5;Lo;0;L;5D19;;;;N;;;;;
13356 F9D6;CJK COMPATIBILITY IDEOGRAPH-F9D6;Lo;0;L;6DEA;;;;N;;;;;
13357 F9D7;CJK COMPATIBILITY IDEOGRAPH-F9D7;Lo;0;L;8F2A;;;;N;;;;;
13358 F9D8;CJK COMPATIBILITY IDEOGRAPH-F9D8;Lo;0;L;5F8B;;;;N;;;;;
13359 F9D9;CJK COMPATIBILITY IDEOGRAPH-F9D9;Lo;0;L;6144;;;;N;;;;;
13360 F9DA;CJK COMPATIBILITY IDEOGRAPH-F9DA;Lo;0;L;6817;;;;N;;;;;
13361 F9DB;CJK COMPATIBILITY IDEOGRAPH-F9DB;Lo;0;L;7387;;;;N;;;;;
13362 F9DC;CJK COMPATIBILITY IDEOGRAPH-F9DC;Lo;0;L;9686;;;;N;;;;;
13363 F9DD;CJK COMPATIBILITY IDEOGRAPH-F9DD;Lo;0;L;5229;;;;N;;;;;
13364 F9DE;CJK COMPATIBILITY IDEOGRAPH-F9DE;Lo;0;L;540F;;;;N;;;;;
13365 F9DF;CJK COMPATIBILITY IDEOGRAPH-F9DF;Lo;0;L;5C65;;;;N;;;;;
13366 F9E0;CJK COMPATIBILITY IDEOGRAPH-F9E0;Lo;0;L;6613;;;;N;;;;;
13367 F9E1;CJK COMPATIBILITY IDEOGRAPH-F9E1;Lo;0;L;674E;;;;N;;;;;
13368 F9E2;CJK COMPATIBILITY IDEOGRAPH-F9E2;Lo;0;L;68A8;;;;N;;;;;
13369 F9E3;CJK COMPATIBILITY IDEOGRAPH-F9E3;Lo;0;L;6CE5;;;;N;;;;;
13370 F9E4;CJK COMPATIBILITY IDEOGRAPH-F9E4;Lo;0;L;7406;;;;N;;;;;
13371 F9E5;CJK COMPATIBILITY IDEOGRAPH-F9E5;Lo;0;L;75E2;;;;N;;;;;
13372 F9E6;CJK COMPATIBILITY IDEOGRAPH-F9E6;Lo;0;L;7F79;;;;N;;;;;
13373 F9E7;CJK COMPATIBILITY IDEOGRAPH-F9E7;Lo;0;L;88CF;;;;N;;;;;
13374 F9E8;CJK COMPATIBILITY IDEOGRAPH-F9E8;Lo;0;L;88E1;;;;N;;;;;
13375 F9E9;CJK COMPATIBILITY IDEOGRAPH-F9E9;Lo;0;L;91CC;;;;N;;;;;
13376 F9EA;CJK COMPATIBILITY IDEOGRAPH-F9EA;Lo;0;L;96E2;;;;N;;;;;
13377 F9EB;CJK COMPATIBILITY IDEOGRAPH-F9EB;Lo;0;L;533F;;;;N;;;;;
13378 F9EC;CJK COMPATIBILITY IDEOGRAPH-F9EC;Lo;0;L;6EBA;;;;N;;;;;
13379 F9ED;CJK COMPATIBILITY IDEOGRAPH-F9ED;Lo;0;L;541D;;;;N;;;;;
13380 F9EE;CJK COMPATIBILITY IDEOGRAPH-F9EE;Lo;0;L;71D0;;;;N;;;;;
13381 F9EF;CJK COMPATIBILITY IDEOGRAPH-F9EF;Lo;0;L;7498;;;;N;;;;;
13382 F9F0;CJK COMPATIBILITY IDEOGRAPH-F9F0;Lo;0;L;85FA;;;;N;;;;;
13383 F9F1;CJK COMPATIBILITY IDEOGRAPH-F9F1;Lo;0;L;96A3;;;;N;;;;;
13384 F9F2;CJK COMPATIBILITY IDEOGRAPH-F9F2;Lo;0;L;9C57;;;;N;;;;;
13385 F9F3;CJK COMPATIBILITY IDEOGRAPH-F9F3;Lo;0;L;9E9F;;;;N;;;;;
13386 F9F4;CJK COMPATIBILITY IDEOGRAPH-F9F4;Lo;0;L;6797;;;;N;;;;;
13387 F9F5;CJK COMPATIBILITY IDEOGRAPH-F9F5;Lo;0;L;6DCB;;;;N;;;;;
13388 F9F6;CJK COMPATIBILITY IDEOGRAPH-F9F6;Lo;0;L;81E8;;;;N;;;;;
13389 F9F7;CJK COMPATIBILITY IDEOGRAPH-F9F7;Lo;0;L;7ACB;;;;N;;;;;
13390 F9F8;CJK COMPATIBILITY IDEOGRAPH-F9F8;Lo;0;L;7B20;;;;N;;;;;
13391 F9F9;CJK COMPATIBILITY IDEOGRAPH-F9F9;Lo;0;L;7C92;;;;N;;;;;
13392 F9FA;CJK COMPATIBILITY IDEOGRAPH-F9FA;Lo;0;L;72C0;;;;N;;;;;
13393 F9FB;CJK COMPATIBILITY IDEOGRAPH-F9FB;Lo;0;L;7099;;;;N;;;;;
13394 F9FC;CJK COMPATIBILITY IDEOGRAPH-F9FC;Lo;0;L;8B58;;;;N;;;;;
13395 F9FD;CJK COMPATIBILITY IDEOGRAPH-F9FD;Lo;0;L;4EC0;;;10;N;;;;;
13396 F9FE;CJK COMPATIBILITY IDEOGRAPH-F9FE;Lo;0;L;8336;;;;N;;;;;
13397 F9FF;CJK COMPATIBILITY IDEOGRAPH-F9FF;Lo;0;L;523A;;;;N;;;;;
13398 FA00;CJK COMPATIBILITY IDEOGRAPH-FA00;Lo;0;L;5207;;;;N;;;;;
13399 FA01;CJK COMPATIBILITY IDEOGRAPH-FA01;Lo;0;L;5EA6;;;;N;;;;;
13400 FA02;CJK COMPATIBILITY IDEOGRAPH-FA02;Lo;0;L;62D3;;;;N;;;;;
13401 FA03;CJK COMPATIBILITY IDEOGRAPH-FA03;Lo;0;L;7CD6;;;;N;;;;;
13402 FA04;CJK COMPATIBILITY IDEOGRAPH-FA04;Lo;0;L;5B85;;;;N;;;;;
13403 FA05;CJK COMPATIBILITY IDEOGRAPH-FA05;Lo;0;L;6D1E;;;;N;;;;;
13404 FA06;CJK COMPATIBILITY IDEOGRAPH-FA06;Lo;0;L;66B4;;;;N;;;;;
13405 FA07;CJK COMPATIBILITY IDEOGRAPH-FA07;Lo;0;L;8F3B;;;;N;;;;;
13406 FA08;CJK COMPATIBILITY IDEOGRAPH-FA08;Lo;0;L;884C;;;;N;;;;;
13407 FA09;CJK COMPATIBILITY IDEOGRAPH-FA09;Lo;0;L;964D;;;;N;;;;;
13408 FA0A;CJK COMPATIBILITY IDEOGRAPH-FA0A;Lo;0;L;898B;;;;N;;;;;
13409 FA0B;CJK COMPATIBILITY IDEOGRAPH-FA0B;Lo;0;L;5ED3;;;;N;;;;;
13410 FA0C;CJK COMPATIBILITY IDEOGRAPH-FA0C;Lo;0;L;5140;;;;N;;;;;
13411 FA0D;CJK COMPATIBILITY IDEOGRAPH-FA0D;Lo;0;L;55C0;;;;N;;;;;
13412 FA0E;CJK COMPATIBILITY IDEOGRAPH-FA0E;Lo;0;L;;;;;N;;;;;
13413 FA0F;CJK COMPATIBILITY IDEOGRAPH-FA0F;Lo;0;L;;;;;N;;;;;
13414 FA10;CJK COMPATIBILITY IDEOGRAPH-FA10;Lo;0;L;585A;;;;N;;;;;
13415 FA11;CJK COMPATIBILITY IDEOGRAPH-FA11;Lo;0;L;;;;;N;;;;;
13416 FA12;CJK COMPATIBILITY IDEOGRAPH-FA12;Lo;0;L;6674;;;;N;;;;;
13417 FA13;CJK COMPATIBILITY IDEOGRAPH-FA13;Lo;0;L;;;;;N;;;;;
13418 FA14;CJK COMPATIBILITY IDEOGRAPH-FA14;Lo;0;L;;;;;N;;;;;
13419 FA15;CJK COMPATIBILITY IDEOGRAPH-FA15;Lo;0;L;51DE;;;;N;;;;;
13420 FA16;CJK COMPATIBILITY IDEOGRAPH-FA16;Lo;0;L;732A;;;;N;;;;;
13421 FA17;CJK COMPATIBILITY IDEOGRAPH-FA17;Lo;0;L;76CA;;;;N;;;;;
13422 FA18;CJK COMPATIBILITY IDEOGRAPH-FA18;Lo;0;L;793C;;;;N;;;;;
13423 FA19;CJK COMPATIBILITY IDEOGRAPH-FA19;Lo;0;L;795E;;;;N;;;;;
13424 FA1A;CJK COMPATIBILITY IDEOGRAPH-FA1A;Lo;0;L;7965;;;;N;;;;;
13425 FA1B;CJK COMPATIBILITY IDEOGRAPH-FA1B;Lo;0;L;798F;;;;N;;;;;
13426 FA1C;CJK COMPATIBILITY IDEOGRAPH-FA1C;Lo;0;L;9756;;;;N;;;;;
13427 FA1D;CJK COMPATIBILITY IDEOGRAPH-FA1D;Lo;0;L;7CBE;;;;N;;;;;
13428 FA1E;CJK COMPATIBILITY IDEOGRAPH-FA1E;Lo;0;L;7FBD;;;;N;;;;;
13429 FA1F;CJK COMPATIBILITY IDEOGRAPH-FA1F;Lo;0;L;;;;;N;;*;;;
13430 FA20;CJK COMPATIBILITY IDEOGRAPH-FA20;Lo;0;L;8612;;;;N;;;;;
13431 FA21;CJK COMPATIBILITY IDEOGRAPH-FA21;Lo;0;L;;;;;N;;;;;
13432 FA22;CJK COMPATIBILITY IDEOGRAPH-FA22;Lo;0;L;8AF8;;;;N;;;;;
13433 FA23;CJK COMPATIBILITY IDEOGRAPH-FA23;Lo;0;L;;;;;N;;*;;;
13434 FA24;CJK COMPATIBILITY IDEOGRAPH-FA24;Lo;0;L;;;;;N;;;;;
13435 FA25;CJK COMPATIBILITY IDEOGRAPH-FA25;Lo;0;L;9038;;;;N;;;;;
13436 FA26;CJK COMPATIBILITY IDEOGRAPH-FA26;Lo;0;L;90FD;;;;N;;;;;
13437 FA27;CJK COMPATIBILITY IDEOGRAPH-FA27;Lo;0;L;;;;;N;;;;;
13438 FA28;CJK COMPATIBILITY IDEOGRAPH-FA28;Lo;0;L;;;;;N;;;;;
13439 FA29;CJK COMPATIBILITY IDEOGRAPH-FA29;Lo;0;L;;;;;N;;;;;
13440 FA2A;CJK COMPATIBILITY IDEOGRAPH-FA2A;Lo;0;L;98EF;;;;N;;;;;
13441 FA2B;CJK COMPATIBILITY IDEOGRAPH-FA2B;Lo;0;L;98FC;;;;N;;;;;
13442 FA2C;CJK COMPATIBILITY IDEOGRAPH-FA2C;Lo;0;L;9928;;;;N;;;;;
13443 FA2D;CJK COMPATIBILITY IDEOGRAPH-FA2D;Lo;0;L;9DB4;;;;N;;;;;
13444 FA30;CJK COMPATIBILITY IDEOGRAPH-FA30;Lo;0;L;4FAE;;;;N;;;;;
13445 FA31;CJK COMPATIBILITY IDEOGRAPH-FA31;Lo;0;L;50E7;;;;N;;;;;
13446 FA32;CJK COMPATIBILITY IDEOGRAPH-FA32;Lo;0;L;514D;;;;N;;;;;
13447 FA33;CJK COMPATIBILITY IDEOGRAPH-FA33;Lo;0;L;52C9;;;;N;;;;;
13448 FA34;CJK COMPATIBILITY IDEOGRAPH-FA34;Lo;0;L;52E4;;;;N;;;;;
13449 FA35;CJK COMPATIBILITY IDEOGRAPH-FA35;Lo;0;L;5351;;;;N;;;;;
13450 FA36;CJK COMPATIBILITY IDEOGRAPH-FA36;Lo;0;L;559D;;;;N;;;;;
13451 FA37;CJK COMPATIBILITY IDEOGRAPH-FA37;Lo;0;L;5606;;;;N;;;;;
13452 FA38;CJK COMPATIBILITY IDEOGRAPH-FA38;Lo;0;L;5668;;;;N;;;;;
13453 FA39;CJK COMPATIBILITY IDEOGRAPH-FA39;Lo;0;L;5840;;;;N;;;;;
13454 FA3A;CJK COMPATIBILITY IDEOGRAPH-FA3A;Lo;0;L;58A8;;;;N;;;;;
13455 FA3B;CJK COMPATIBILITY IDEOGRAPH-FA3B;Lo;0;L;5C64;;;;N;;;;;
13456 FA3C;CJK COMPATIBILITY IDEOGRAPH-FA3C;Lo;0;L;5C6E;;;;N;;;;;
13457 FA3D;CJK COMPATIBILITY IDEOGRAPH-FA3D;Lo;0;L;6094;;;;N;;;;;
13458 FA3E;CJK COMPATIBILITY IDEOGRAPH-FA3E;Lo;0;L;6168;;;;N;;;;;
13459 FA3F;CJK COMPATIBILITY IDEOGRAPH-FA3F;Lo;0;L;618E;;;;N;;;;;
13460 FA40;CJK COMPATIBILITY IDEOGRAPH-FA40;Lo;0;L;61F2;;;;N;;;;;
13461 FA41;CJK COMPATIBILITY IDEOGRAPH-FA41;Lo;0;L;654F;;;;N;;;;;
13462 FA42;CJK COMPATIBILITY IDEOGRAPH-FA42;Lo;0;L;65E2;;;;N;;;;;
13463 FA43;CJK COMPATIBILITY IDEOGRAPH-FA43;Lo;0;L;6691;;;;N;;;;;
13464 FA44;CJK COMPATIBILITY IDEOGRAPH-FA44;Lo;0;L;6885;;;;N;;;;;
13465 FA45;CJK COMPATIBILITY IDEOGRAPH-FA45;Lo;0;L;6D77;;;;N;;;;;
13466 FA46;CJK COMPATIBILITY IDEOGRAPH-FA46;Lo;0;L;6E1A;;;;N;;;;;
13467 FA47;CJK COMPATIBILITY IDEOGRAPH-FA47;Lo;0;L;6F22;;;;N;;;;;
13468 FA48;CJK COMPATIBILITY IDEOGRAPH-FA48;Lo;0;L;716E;;;;N;;;;;
13469 FA49;CJK COMPATIBILITY IDEOGRAPH-FA49;Lo;0;L;722B;;;;N;;;;;
13470 FA4A;CJK COMPATIBILITY IDEOGRAPH-FA4A;Lo;0;L;7422;;;;N;;;;;
13471 FA4B;CJK COMPATIBILITY IDEOGRAPH-FA4B;Lo;0;L;7891;;;;N;;;;;
13472 FA4C;CJK COMPATIBILITY IDEOGRAPH-FA4C;Lo;0;L;793E;;;;N;;;;;
13473 FA4D;CJK COMPATIBILITY IDEOGRAPH-FA4D;Lo;0;L;7949;;;;N;;;;;
13474 FA4E;CJK COMPATIBILITY IDEOGRAPH-FA4E;Lo;0;L;7948;;;;N;;;;;
13475 FA4F;CJK COMPATIBILITY IDEOGRAPH-FA4F;Lo;0;L;7950;;;;N;;;;;
13476 FA50;CJK COMPATIBILITY IDEOGRAPH-FA50;Lo;0;L;7956;;;;N;;;;;
13477 FA51;CJK COMPATIBILITY IDEOGRAPH-FA51;Lo;0;L;795D;;;;N;;;;;
13478 FA52;CJK COMPATIBILITY IDEOGRAPH-FA52;Lo;0;L;798D;;;;N;;;;;
13479 FA53;CJK COMPATIBILITY IDEOGRAPH-FA53;Lo;0;L;798E;;;;N;;;;;
13480 FA54;CJK COMPATIBILITY IDEOGRAPH-FA54;Lo;0;L;7A40;;;;N;;;;;
13481 FA55;CJK COMPATIBILITY IDEOGRAPH-FA55;Lo;0;L;7A81;;;;N;;;;;
13482 FA56;CJK COMPATIBILITY IDEOGRAPH-FA56;Lo;0;L;7BC0;;;;N;;;;;
13483 FA57;CJK COMPATIBILITY IDEOGRAPH-FA57;Lo;0;L;7DF4;;;;N;;;;;
13484 FA58;CJK COMPATIBILITY IDEOGRAPH-FA58;Lo;0;L;7E09;;;;N;;;;;
13485 FA59;CJK COMPATIBILITY IDEOGRAPH-FA59;Lo;0;L;7E41;;;;N;;;;;
13486 FA5A;CJK COMPATIBILITY IDEOGRAPH-FA5A;Lo;0;L;7F72;;;;N;;;;;
13487 FA5B;CJK COMPATIBILITY IDEOGRAPH-FA5B;Lo;0;L;8005;;;;N;;;;;
13488 FA5C;CJK COMPATIBILITY IDEOGRAPH-FA5C;Lo;0;L;81ED;;;;N;;;;;
13489 FA5D;CJK COMPATIBILITY IDEOGRAPH-FA5D;Lo;0;L;8279;;;;N;;;;;
13490 FA5E;CJK COMPATIBILITY IDEOGRAPH-FA5E;Lo;0;L;8279;;;;N;;;;;
13491 FA5F;CJK COMPATIBILITY IDEOGRAPH-FA5F;Lo;0;L;8457;;;;N;;;;;
13492 FA60;CJK COMPATIBILITY IDEOGRAPH-FA60;Lo;0;L;8910;;;;N;;;;;
13493 FA61;CJK COMPATIBILITY IDEOGRAPH-FA61;Lo;0;L;8996;;;;N;;;;;
13494 FA62;CJK COMPATIBILITY IDEOGRAPH-FA62;Lo;0;L;8B01;;;;N;;;;;
13495 FA63;CJK COMPATIBILITY IDEOGRAPH-FA63;Lo;0;L;8B39;;;;N;;;;;
13496 FA64;CJK COMPATIBILITY IDEOGRAPH-FA64;Lo;0;L;8CD3;;;;N;;;;;
13497 FA65;CJK COMPATIBILITY IDEOGRAPH-FA65;Lo;0;L;8D08;;;;N;;;;;
13498 FA66;CJK COMPATIBILITY IDEOGRAPH-FA66;Lo;0;L;8FB6;;;;N;;;;;
13499 FA67;CJK COMPATIBILITY IDEOGRAPH-FA67;Lo;0;L;9038;;;;N;;;;;
13500 FA68;CJK COMPATIBILITY IDEOGRAPH-FA68;Lo;0;L;96E3;;;;N;;;;;
13501 FA69;CJK COMPATIBILITY IDEOGRAPH-FA69;Lo;0;L;97FF;;;;N;;;;;
13502 FA6A;CJK COMPATIBILITY IDEOGRAPH-FA6A;Lo;0;L;983B;;;;N;;;;;
13503 FA70;CJK COMPATIBILITY IDEOGRAPH-FA70;Lo;0;L;4E26;;;;N;;;;;
13504 FA71;CJK COMPATIBILITY IDEOGRAPH-FA71;Lo;0;L;51B5;;;;N;;;;;
13505 FA72;CJK COMPATIBILITY IDEOGRAPH-FA72;Lo;0;L;5168;;;;N;;;;;
13506 FA73;CJK COMPATIBILITY IDEOGRAPH-FA73;Lo;0;L;4F80;;;;N;;;;;
13507 FA74;CJK COMPATIBILITY IDEOGRAPH-FA74;Lo;0;L;5145;;;;N;;;;;
13508 FA75;CJK COMPATIBILITY IDEOGRAPH-FA75;Lo;0;L;5180;;;;N;;;;;
13509 FA76;CJK COMPATIBILITY IDEOGRAPH-FA76;Lo;0;L;52C7;;;;N;;;;;
13510 FA77;CJK COMPATIBILITY IDEOGRAPH-FA77;Lo;0;L;52FA;;;;N;;;;;
13511 FA78;CJK COMPATIBILITY IDEOGRAPH-FA78;Lo;0;L;559D;;;;N;;;;;
13512 FA79;CJK COMPATIBILITY IDEOGRAPH-FA79;Lo;0;L;5555;;;;N;;;;;
13513 FA7A;CJK COMPATIBILITY IDEOGRAPH-FA7A;Lo;0;L;5599;;;;N;;;;;
13514 FA7B;CJK COMPATIBILITY IDEOGRAPH-FA7B;Lo;0;L;55E2;;;;N;;;;;
13515 FA7C;CJK COMPATIBILITY IDEOGRAPH-FA7C;Lo;0;L;585A;;;;N;;;;;
13516 FA7D;CJK COMPATIBILITY IDEOGRAPH-FA7D;Lo;0;L;58B3;;;;N;;;;;
13517 FA7E;CJK COMPATIBILITY IDEOGRAPH-FA7E;Lo;0;L;5944;;;;N;;;;;
13518 FA7F;CJK COMPATIBILITY IDEOGRAPH-FA7F;Lo;0;L;5954;;;;N;;;;;
13519 FA80;CJK COMPATIBILITY IDEOGRAPH-FA80;Lo;0;L;5A62;;;;N;;;;;
13520 FA81;CJK COMPATIBILITY IDEOGRAPH-FA81;Lo;0;L;5B28;;;;N;;;;;
13521 FA82;CJK COMPATIBILITY IDEOGRAPH-FA82;Lo;0;L;5ED2;;;;N;;;;;
13522 FA83;CJK COMPATIBILITY IDEOGRAPH-FA83;Lo;0;L;5ED9;;;;N;;;;;
13523 FA84;CJK COMPATIBILITY IDEOGRAPH-FA84;Lo;0;L;5F69;;;;N;;;;;
13524 FA85;CJK COMPATIBILITY IDEOGRAPH-FA85;Lo;0;L;5FAD;;;;N;;;;;
13525 FA86;CJK COMPATIBILITY IDEOGRAPH-FA86;Lo;0;L;60D8;;;;N;;;;;
13526 FA87;CJK COMPATIBILITY IDEOGRAPH-FA87;Lo;0;L;614E;;;;N;;;;;
13527 FA88;CJK COMPATIBILITY IDEOGRAPH-FA88;Lo;0;L;6108;;;;N;;;;;
13528 FA89;CJK COMPATIBILITY IDEOGRAPH-FA89;Lo;0;L;618E;;;;N;;;;;
13529 FA8A;CJK COMPATIBILITY IDEOGRAPH-FA8A;Lo;0;L;6160;;;;N;;;;;
13530 FA8B;CJK COMPATIBILITY IDEOGRAPH-FA8B;Lo;0;L;61F2;;;;N;;;;;
13531 FA8C;CJK COMPATIBILITY IDEOGRAPH-FA8C;Lo;0;L;6234;;;;N;;;;;
13532 FA8D;CJK COMPATIBILITY IDEOGRAPH-FA8D;Lo;0;L;63C4;;;;N;;;;;
13533 FA8E;CJK COMPATIBILITY IDEOGRAPH-FA8E;Lo;0;L;641C;;;;N;;;;;
13534 FA8F;CJK COMPATIBILITY IDEOGRAPH-FA8F;Lo;0;L;6452;;;;N;;;;;
13535 FA90;CJK COMPATIBILITY IDEOGRAPH-FA90;Lo;0;L;6556;;;;N;;;;;
13536 FA91;CJK COMPATIBILITY IDEOGRAPH-FA91;Lo;0;L;6674;;;;N;;;;;
13537 FA92;CJK COMPATIBILITY IDEOGRAPH-FA92;Lo;0;L;6717;;;;N;;;;;
13538 FA93;CJK COMPATIBILITY IDEOGRAPH-FA93;Lo;0;L;671B;;;;N;;;;;
13539 FA94;CJK COMPATIBILITY IDEOGRAPH-FA94;Lo;0;L;6756;;;;N;;;;;
13540 FA95;CJK COMPATIBILITY IDEOGRAPH-FA95;Lo;0;L;6B79;;;;N;;;;;
13541 FA96;CJK COMPATIBILITY IDEOGRAPH-FA96;Lo;0;L;6BBA;;;;N;;;;;
13542 FA97;CJK COMPATIBILITY IDEOGRAPH-FA97;Lo;0;L;6D41;;;;N;;;;;
13543 FA98;CJK COMPATIBILITY IDEOGRAPH-FA98;Lo;0;L;6EDB;;;;N;;;;;
13544 FA99;CJK COMPATIBILITY IDEOGRAPH-FA99;Lo;0;L;6ECB;;;;N;;;;;
13545 FA9A;CJK COMPATIBILITY IDEOGRAPH-FA9A;Lo;0;L;6F22;;;;N;;;;;
13546 FA9B;CJK COMPATIBILITY IDEOGRAPH-FA9B;Lo;0;L;701E;;;;N;;;;;
13547 FA9C;CJK COMPATIBILITY IDEOGRAPH-FA9C;Lo;0;L;716E;;;;N;;;;;
13548 FA9D;CJK COMPATIBILITY IDEOGRAPH-FA9D;Lo;0;L;77A7;;;;N;;;;;
13549 FA9E;CJK COMPATIBILITY IDEOGRAPH-FA9E;Lo;0;L;7235;;;;N;;;;;
13550 FA9F;CJK COMPATIBILITY IDEOGRAPH-FA9F;Lo;0;L;72AF;;;;N;;;;;
13551 FAA0;CJK COMPATIBILITY IDEOGRAPH-FAA0;Lo;0;L;732A;;;;N;;;;;
13552 FAA1;CJK COMPATIBILITY IDEOGRAPH-FAA1;Lo;0;L;7471;;;;N;;;;;
13553 FAA2;CJK COMPATIBILITY IDEOGRAPH-FAA2;Lo;0;L;7506;;;;N;;;;;
13554 FAA3;CJK COMPATIBILITY IDEOGRAPH-FAA3;Lo;0;L;753B;;;;N;;;;;
13555 FAA4;CJK COMPATIBILITY IDEOGRAPH-FAA4;Lo;0;L;761D;;;;N;;;;;
13556 FAA5;CJK COMPATIBILITY IDEOGRAPH-FAA5;Lo;0;L;761F;;;;N;;;;;
13557 FAA6;CJK COMPATIBILITY IDEOGRAPH-FAA6;Lo;0;L;76CA;;;;N;;;;;
13558 FAA7;CJK COMPATIBILITY IDEOGRAPH-FAA7;Lo;0;L;76DB;;;;N;;;;;
13559 FAA8;CJK COMPATIBILITY IDEOGRAPH-FAA8;Lo;0;L;76F4;;;;N;;;;;
13560 FAA9;CJK COMPATIBILITY IDEOGRAPH-FAA9;Lo;0;L;774A;;;;N;;;;;
13561 FAAA;CJK COMPATIBILITY IDEOGRAPH-FAAA;Lo;0;L;7740;;;;N;;;;;
13562 FAAB;CJK COMPATIBILITY IDEOGRAPH-FAAB;Lo;0;L;78CC;;;;N;;;;;
13563 FAAC;CJK COMPATIBILITY IDEOGRAPH-FAAC;Lo;0;L;7AB1;;;;N;;;;;
13564 FAAD;CJK COMPATIBILITY IDEOGRAPH-FAAD;Lo;0;L;7BC0;;;;N;;;;;
13565 FAAE;CJK COMPATIBILITY IDEOGRAPH-FAAE;Lo;0;L;7C7B;;;;N;;;;;
13566 FAAF;CJK COMPATIBILITY IDEOGRAPH-FAAF;Lo;0;L;7D5B;;;;N;;;;;
13567 FAB0;CJK COMPATIBILITY IDEOGRAPH-FAB0;Lo;0;L;7DF4;;;;N;;;;;
13568 FAB1;CJK COMPATIBILITY IDEOGRAPH-FAB1;Lo;0;L;7F3E;;;;N;;;;;
13569 FAB2;CJK COMPATIBILITY IDEOGRAPH-FAB2;Lo;0;L;8005;;;;N;;;;;
13570 FAB3;CJK COMPATIBILITY IDEOGRAPH-FAB3;Lo;0;L;8352;;;;N;;;;;
13571 FAB4;CJK COMPATIBILITY IDEOGRAPH-FAB4;Lo;0;L;83EF;;;;N;;;;;
13572 FAB5;CJK COMPATIBILITY IDEOGRAPH-FAB5;Lo;0;L;8779;;;;N;;;;;
13573 FAB6;CJK COMPATIBILITY IDEOGRAPH-FAB6;Lo;0;L;8941;;;;N;;;;;
13574 FAB7;CJK COMPATIBILITY IDEOGRAPH-FAB7;Lo;0;L;8986;;;;N;;;;;
13575 FAB8;CJK COMPATIBILITY IDEOGRAPH-FAB8;Lo;0;L;8996;;;;N;;;;;
13576 FAB9;CJK COMPATIBILITY IDEOGRAPH-FAB9;Lo;0;L;8ABF;;;;N;;;;;
13577 FABA;CJK COMPATIBILITY IDEOGRAPH-FABA;Lo;0;L;8AF8;;;;N;;;;;
13578 FABB;CJK COMPATIBILITY IDEOGRAPH-FABB;Lo;0;L;8ACB;;;;N;;;;;
13579 FABC;CJK COMPATIBILITY IDEOGRAPH-FABC;Lo;0;L;8B01;;;;N;;;;;
13580 FABD;CJK COMPATIBILITY IDEOGRAPH-FABD;Lo;0;L;8AFE;;;;N;;;;;
13581 FABE;CJK COMPATIBILITY IDEOGRAPH-FABE;Lo;0;L;8AED;;;;N;;;;;
13582 FABF;CJK COMPATIBILITY IDEOGRAPH-FABF;Lo;0;L;8B39;;;;N;;;;;
13583 FAC0;CJK COMPATIBILITY IDEOGRAPH-FAC0;Lo;0;L;8B8A;;;;N;;;;;
13584 FAC1;CJK COMPATIBILITY IDEOGRAPH-FAC1;Lo;0;L;8D08;;;;N;;;;;
13585 FAC2;CJK COMPATIBILITY IDEOGRAPH-FAC2;Lo;0;L;8F38;;;;N;;;;;
13586 FAC3;CJK COMPATIBILITY IDEOGRAPH-FAC3;Lo;0;L;9072;;;;N;;;;;
13587 FAC4;CJK COMPATIBILITY IDEOGRAPH-FAC4;Lo;0;L;9199;;;;N;;;;;
13588 FAC5;CJK COMPATIBILITY IDEOGRAPH-FAC5;Lo;0;L;9276;;;;N;;;;;
13589 FAC6;CJK COMPATIBILITY IDEOGRAPH-FAC6;Lo;0;L;967C;;;;N;;;;;
13590 FAC7;CJK COMPATIBILITY IDEOGRAPH-FAC7;Lo;0;L;96E3;;;;N;;;;;
13591 FAC8;CJK COMPATIBILITY IDEOGRAPH-FAC8;Lo;0;L;9756;;;;N;;;;;
13592 FAC9;CJK COMPATIBILITY IDEOGRAPH-FAC9;Lo;0;L;97DB;;;;N;;;;;
13593 FACA;CJK COMPATIBILITY IDEOGRAPH-FACA;Lo;0;L;97FF;;;;N;;;;;
13594 FACB;CJK COMPATIBILITY IDEOGRAPH-FACB;Lo;0;L;980B;;;;N;;;;;
13595 FACC;CJK COMPATIBILITY IDEOGRAPH-FACC;Lo;0;L;983B;;;;N;;;;;
13596 FACD;CJK COMPATIBILITY IDEOGRAPH-FACD;Lo;0;L;9B12;;;;N;;;;;
13597 FACE;CJK COMPATIBILITY IDEOGRAPH-FACE;Lo;0;L;9F9C;;;;N;;;;;
13598 FACF;CJK COMPATIBILITY IDEOGRAPH-FACF;Lo;0;L;2284A;;;;N;;;;;
13599 FAD0;CJK COMPATIBILITY IDEOGRAPH-FAD0;Lo;0;L;22844;;;;N;;;;;
13600 FAD1;CJK COMPATIBILITY IDEOGRAPH-FAD1;Lo;0;L;233D5;;;;N;;;;;
13601 FAD2;CJK COMPATIBILITY IDEOGRAPH-FAD2;Lo;0;L;3B9D;;;;N;;;;;
13602 FAD3;CJK COMPATIBILITY IDEOGRAPH-FAD3;Lo;0;L;4018;;;;N;;;;;
13603 FAD4;CJK COMPATIBILITY IDEOGRAPH-FAD4;Lo;0;L;4039;;;;N;;;;;
13604 FAD5;CJK COMPATIBILITY IDEOGRAPH-FAD5;Lo;0;L;25249;;;;N;;;;;
13605 FAD6;CJK COMPATIBILITY IDEOGRAPH-FAD6;Lo;0;L;25CD0;;;;N;;;;;
13606 FAD7;CJK COMPATIBILITY IDEOGRAPH-FAD7;Lo;0;L;27ED3;;;;N;;;;;
13607 FAD8;CJK COMPATIBILITY IDEOGRAPH-FAD8;Lo;0;L;9F43;;;;N;;;;;
13608 FAD9;CJK COMPATIBILITY IDEOGRAPH-FAD9;Lo;0;L;9F8E;;;;N;;;;;
13609 FB00;LATIN SMALL LIGATURE FF;Ll;0;L;<compat> 0066 0066;;;;N;;;;;
13610 FB01;LATIN SMALL LIGATURE FI;Ll;0;L;<compat> 0066 0069;;;;N;;;;;
13611 FB02;LATIN SMALL LIGATURE FL;Ll;0;L;<compat> 0066 006C;;;;N;;;;;
13612 FB03;LATIN SMALL LIGATURE FFI;Ll;0;L;<compat> 0066 0066 0069;;;;N;;;;;
13613 FB04;LATIN SMALL LIGATURE FFL;Ll;0;L;<compat> 0066 0066 006C;;;;N;;;;;
13614 FB05;LATIN SMALL LIGATURE LONG S T;Ll;0;L;<compat> 017F 0074;;;;N;;;;;
13615 FB06;LATIN SMALL LIGATURE ST;Ll;0;L;<compat> 0073 0074;;;;N;;;;;
13616 FB13;ARMENIAN SMALL LIGATURE MEN NOW;Ll;0;L;<compat> 0574 0576;;;;N;;;;;
13617 FB14;ARMENIAN SMALL LIGATURE MEN ECH;Ll;0;L;<compat> 0574 0565;;;;N;;;;;
13618 FB15;ARMENIAN SMALL LIGATURE MEN INI;Ll;0;L;<compat> 0574 056B;;;;N;;;;;
13619 FB16;ARMENIAN SMALL LIGATURE VEW NOW;Ll;0;L;<compat> 057E 0576;;;;N;;;;;
13620 FB17;ARMENIAN SMALL LIGATURE MEN XEH;Ll;0;L;<compat> 0574 056D;;;;N;;;;;
13621 FB1D;HEBREW LETTER YOD WITH HIRIQ;Lo;0;R;05D9 05B4;;;;N;;;;;
13622 FB1E;HEBREW POINT JUDEO-SPANISH VARIKA;Mn;26;NSM;;;;;N;HEBREW POINT VARIKA;;;;
13623 FB1F;HEBREW LIGATURE YIDDISH YOD YOD PATAH;Lo;0;R;05F2 05B7;;;;N;;;;;
13624 FB20;HEBREW LETTER ALTERNATIVE AYIN;Lo;0;R;<font> 05E2;;;;N;;;;;
13625 FB21;HEBREW LETTER WIDE ALEF;Lo;0;R;<font> 05D0;;;;N;;;;;
13626 FB22;HEBREW LETTER WIDE DALET;Lo;0;R;<font> 05D3;;;;N;;;;;
13627 FB23;HEBREW LETTER WIDE HE;Lo;0;R;<font> 05D4;;;;N;;;;;
13628 FB24;HEBREW LETTER WIDE KAF;Lo;0;R;<font> 05DB;;;;N;;;;;
13629 FB25;HEBREW LETTER WIDE LAMED;Lo;0;R;<font> 05DC;;;;N;;;;;
13630 FB26;HEBREW LETTER WIDE FINAL MEM;Lo;0;R;<font> 05DD;;;;N;;;;;
13631 FB27;HEBREW LETTER WIDE RESH;Lo;0;R;<font> 05E8;;;;N;;;;;
13632 FB28;HEBREW LETTER WIDE TAV;Lo;0;R;<font> 05EA;;;;N;;;;;
13633 FB29;HEBREW LETTER ALTERNATIVE PLUS SIGN;Sm;0;ES;<font> 002B;;;;N;;;;;
13634 FB2A;HEBREW LETTER SHIN WITH SHIN DOT;Lo;0;R;05E9 05C1;;;;N;;;;;
13635 FB2B;HEBREW LETTER SHIN WITH SIN DOT;Lo;0;R;05E9 05C2;;;;N;;;;;
13636 FB2C;HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT;Lo;0;R;FB49 05C1;;;;N;;;;;
13637 FB2D;HEBREW LETTER SHIN WITH DAGESH AND SIN DOT;Lo;0;R;FB49 05C2;;;;N;;;;;
13638 FB2E;HEBREW LETTER ALEF WITH PATAH;Lo;0;R;05D0 05B7;;;;N;;;;;
13639 FB2F;HEBREW LETTER ALEF WITH QAMATS;Lo;0;R;05D0 05B8;;;;N;;;;;
13640 FB30;HEBREW LETTER ALEF WITH MAPIQ;Lo;0;R;05D0 05BC;;;;N;;;;;
13641 FB31;HEBREW LETTER BET WITH DAGESH;Lo;0;R;05D1 05BC;;;;N;;;;;
13642 FB32;HEBREW LETTER GIMEL WITH DAGESH;Lo;0;R;05D2 05BC;;;;N;;;;;
13643 FB33;HEBREW LETTER DALET WITH DAGESH;Lo;0;R;05D3 05BC;;;;N;;;;;
13644 FB34;HEBREW LETTER HE WITH MAPIQ;Lo;0;R;05D4 05BC;;;;N;;;;;
13645 FB35;HEBREW LETTER VAV WITH DAGESH;Lo;0;R;05D5 05BC;;;;N;;;;;
13646 FB36;HEBREW LETTER ZAYIN WITH DAGESH;Lo;0;R;05D6 05BC;;;;N;;;;;
13647 FB38;HEBREW LETTER TET WITH DAGESH;Lo;0;R;05D8 05BC;;;;N;;;;;
13648 FB39;HEBREW LETTER YOD WITH DAGESH;Lo;0;R;05D9 05BC;;;;N;;;;;
13649 FB3A;HEBREW LETTER FINAL KAF WITH DAGESH;Lo;0;R;05DA 05BC;;;;N;;;;;
13650 FB3B;HEBREW LETTER KAF WITH DAGESH;Lo;0;R;05DB 05BC;;;;N;;;;;
13651 FB3C;HEBREW LETTER LAMED WITH DAGESH;Lo;0;R;05DC 05BC;;;;N;;;;;
13652 FB3E;HEBREW LETTER MEM WITH DAGESH;Lo;0;R;05DE 05BC;;;;N;;;;;
13653 FB40;HEBREW LETTER NUN WITH DAGESH;Lo;0;R;05E0 05BC;;;;N;;;;;
13654 FB41;HEBREW LETTER SAMEKH WITH DAGESH;Lo;0;R;05E1 05BC;;;;N;;;;;
13655 FB43;HEBREW LETTER FINAL PE WITH DAGESH;Lo;0;R;05E3 05BC;;;;N;;;;;
13656 FB44;HEBREW LETTER PE WITH DAGESH;Lo;0;R;05E4 05BC;;;;N;;;;;
13657 FB46;HEBREW LETTER TSADI WITH DAGESH;Lo;0;R;05E6 05BC;;;;N;;;;;
13658 FB47;HEBREW LETTER QOF WITH DAGESH;Lo;0;R;05E7 05BC;;;;N;;;;;
13659 FB48;HEBREW LETTER RESH WITH DAGESH;Lo;0;R;05E8 05BC;;;;N;;;;;
13660 FB49;HEBREW LETTER SHIN WITH DAGESH;Lo;0;R;05E9 05BC;;;;N;;;;;
13661 FB4A;HEBREW LETTER TAV WITH DAGESH;Lo;0;R;05EA 05BC;;;;N;;;;;
13662 FB4B;HEBREW LETTER VAV WITH HOLAM;Lo;0;R;05D5 05B9;;;;N;;;;;
13663 FB4C;HEBREW LETTER BET WITH RAFE;Lo;0;R;05D1 05BF;;;;N;;;;;
13664 FB4D;HEBREW LETTER KAF WITH RAFE;Lo;0;R;05DB 05BF;;;;N;;;;;
13665 FB4E;HEBREW LETTER PE WITH RAFE;Lo;0;R;05E4 05BF;;;;N;;;;;
13666 FB4F;HEBREW LIGATURE ALEF LAMED;Lo;0;R;<compat> 05D0 05DC;;;;N;;;;;
13667 FB50;ARABIC LETTER ALEF WASLA ISOLATED FORM;Lo;0;AL;<isolated> 0671;;;;N;;;;;
13668 FB51;ARABIC LETTER ALEF WASLA FINAL FORM;Lo;0;AL;<final> 0671;;;;N;;;;;
13669 FB52;ARABIC LETTER BEEH ISOLATED FORM;Lo;0;AL;<isolated> 067B;;;;N;;;;;
13670 FB53;ARABIC LETTER BEEH FINAL FORM;Lo;0;AL;<final> 067B;;;;N;;;;;
13671 FB54;ARABIC LETTER BEEH INITIAL FORM;Lo;0;AL;<initial> 067B;;;;N;;;;;
13672 FB55;ARABIC LETTER BEEH MEDIAL FORM;Lo;0;AL;<medial> 067B;;;;N;;;;;
13673 FB56;ARABIC LETTER PEH ISOLATED FORM;Lo;0;AL;<isolated> 067E;;;;N;;;;;
13674 FB57;ARABIC LETTER PEH FINAL FORM;Lo;0;AL;<final> 067E;;;;N;;;;;
13675 FB58;ARABIC LETTER PEH INITIAL FORM;Lo;0;AL;<initial> 067E;;;;N;;;;;
13676 FB59;ARABIC LETTER PEH MEDIAL FORM;Lo;0;AL;<medial> 067E;;;;N;;;;;
13677 FB5A;ARABIC LETTER BEHEH ISOLATED FORM;Lo;0;AL;<isolated> 0680;;;;N;;;;;
13678 FB5B;ARABIC LETTER BEHEH FINAL FORM;Lo;0;AL;<final> 0680;;;;N;;;;;
13679 FB5C;ARABIC LETTER BEHEH INITIAL FORM;Lo;0;AL;<initial> 0680;;;;N;;;;;
13680 FB5D;ARABIC LETTER BEHEH MEDIAL FORM;Lo;0;AL;<medial> 0680;;;;N;;;;;
13681 FB5E;ARABIC LETTER TTEHEH ISOLATED FORM;Lo;0;AL;<isolated> 067A;;;;N;;;;;
13682 FB5F;ARABIC LETTER TTEHEH FINAL FORM;Lo;0;AL;<final> 067A;;;;N;;;;;
13683 FB60;ARABIC LETTER TTEHEH INITIAL FORM;Lo;0;AL;<initial> 067A;;;;N;;;;;
13684 FB61;ARABIC LETTER TTEHEH MEDIAL FORM;Lo;0;AL;<medial> 067A;;;;N;;;;;
13685 FB62;ARABIC LETTER TEHEH ISOLATED FORM;Lo;0;AL;<isolated> 067F;;;;N;;;;;
13686 FB63;ARABIC LETTER TEHEH FINAL FORM;Lo;0;AL;<final> 067F;;;;N;;;;;
13687 FB64;ARABIC LETTER TEHEH INITIAL FORM;Lo;0;AL;<initial> 067F;;;;N;;;;;
13688 FB65;ARABIC LETTER TEHEH MEDIAL FORM;Lo;0;AL;<medial> 067F;;;;N;;;;;
13689 FB66;ARABIC LETTER TTEH ISOLATED FORM;Lo;0;AL;<isolated> 0679;;;;N;;;;;
13690 FB67;ARABIC LETTER TTEH FINAL FORM;Lo;0;AL;<final> 0679;;;;N;;;;;
13691 FB68;ARABIC LETTER TTEH INITIAL FORM;Lo;0;AL;<initial> 0679;;;;N;;;;;
13692 FB69;ARABIC LETTER TTEH MEDIAL FORM;Lo;0;AL;<medial> 0679;;;;N;;;;;
13693 FB6A;ARABIC LETTER VEH ISOLATED FORM;Lo;0;AL;<isolated> 06A4;;;;N;;;;;
13694 FB6B;ARABIC LETTER VEH FINAL FORM;Lo;0;AL;<final> 06A4;;;;N;;;;;
13695 FB6C;ARABIC LETTER VEH INITIAL FORM;Lo;0;AL;<initial> 06A4;;;;N;;;;;
13696 FB6D;ARABIC LETTER VEH MEDIAL FORM;Lo;0;AL;<medial> 06A4;;;;N;;;;;
13697 FB6E;ARABIC LETTER PEHEH ISOLATED FORM;Lo;0;AL;<isolated> 06A6;;;;N;;;;;
13698 FB6F;ARABIC LETTER PEHEH FINAL FORM;Lo;0;AL;<final> 06A6;;;;N;;;;;
13699 FB70;ARABIC LETTER PEHEH INITIAL FORM;Lo;0;AL;<initial> 06A6;;;;N;;;;;
13700 FB71;ARABIC LETTER PEHEH MEDIAL FORM;Lo;0;AL;<medial> 06A6;;;;N;;;;;
13701 FB72;ARABIC LETTER DYEH ISOLATED FORM;Lo;0;AL;<isolated> 0684;;;;N;;;;;
13702 FB73;ARABIC LETTER DYEH FINAL FORM;Lo;0;AL;<final> 0684;;;;N;;;;;
13703 FB74;ARABIC LETTER DYEH INITIAL FORM;Lo;0;AL;<initial> 0684;;;;N;;;;;
13704 FB75;ARABIC LETTER DYEH MEDIAL FORM;Lo;0;AL;<medial> 0684;;;;N;;;;;
13705 FB76;ARABIC LETTER NYEH ISOLATED FORM;Lo;0;AL;<isolated> 0683;;;;N;;;;;
13706 FB77;ARABIC LETTER NYEH FINAL FORM;Lo;0;AL;<final> 0683;;;;N;;;;;
13707 FB78;ARABIC LETTER NYEH INITIAL FORM;Lo;0;AL;<initial> 0683;;;;N;;;;;
13708 FB79;ARABIC LETTER NYEH MEDIAL FORM;Lo;0;AL;<medial> 0683;;;;N;;;;;
13709 FB7A;ARABIC LETTER TCHEH ISOLATED FORM;Lo;0;AL;<isolated> 0686;;;;N;;;;;
13710 FB7B;ARABIC LETTER TCHEH FINAL FORM;Lo;0;AL;<final> 0686;;;;N;;;;;
13711 FB7C;ARABIC LETTER TCHEH INITIAL FORM;Lo;0;AL;<initial> 0686;;;;N;;;;;
13712 FB7D;ARABIC LETTER TCHEH MEDIAL FORM;Lo;0;AL;<medial> 0686;;;;N;;;;;
13713 FB7E;ARABIC LETTER TCHEHEH ISOLATED FORM;Lo;0;AL;<isolated> 0687;;;;N;;;;;
13714 FB7F;ARABIC LETTER TCHEHEH FINAL FORM;Lo;0;AL;<final> 0687;;;;N;;;;;
13715 FB80;ARABIC LETTER TCHEHEH INITIAL FORM;Lo;0;AL;<initial> 0687;;;;N;;;;;
13716 FB81;ARABIC LETTER TCHEHEH MEDIAL FORM;Lo;0;AL;<medial> 0687;;;;N;;;;;
13717 FB82;ARABIC LETTER DDAHAL ISOLATED FORM;Lo;0;AL;<isolated> 068D;;;;N;;;;;
13718 FB83;ARABIC LETTER DDAHAL FINAL FORM;Lo;0;AL;<final> 068D;;;;N;;;;;
13719 FB84;ARABIC LETTER DAHAL ISOLATED FORM;Lo;0;AL;<isolated> 068C;;;;N;;;;;
13720 FB85;ARABIC LETTER DAHAL FINAL FORM;Lo;0;AL;<final> 068C;;;;N;;;;;
13721 FB86;ARABIC LETTER DUL ISOLATED FORM;Lo;0;AL;<isolated> 068E;;;;N;;;;;
13722 FB87;ARABIC LETTER DUL FINAL FORM;Lo;0;AL;<final> 068E;;;;N;;;;;
13723 FB88;ARABIC LETTER DDAL ISOLATED FORM;Lo;0;AL;<isolated> 0688;;;;N;;;;;
13724 FB89;ARABIC LETTER DDAL FINAL FORM;Lo;0;AL;<final> 0688;;;;N;;;;;
13725 FB8A;ARABIC LETTER JEH ISOLATED FORM;Lo;0;AL;<isolated> 0698;;;;N;;;;;
13726 FB8B;ARABIC LETTER JEH FINAL FORM;Lo;0;AL;<final> 0698;;;;N;;;;;
13727 FB8C;ARABIC LETTER RREH ISOLATED FORM;Lo;0;AL;<isolated> 0691;;;;N;;;;;
13728 FB8D;ARABIC LETTER RREH FINAL FORM;Lo;0;AL;<final> 0691;;;;N;;;;;
13729 FB8E;ARABIC LETTER KEHEH ISOLATED FORM;Lo;0;AL;<isolated> 06A9;;;;N;;;;;
13730 FB8F;ARABIC LETTER KEHEH FINAL FORM;Lo;0;AL;<final> 06A9;;;;N;;;;;
13731 FB90;ARABIC LETTER KEHEH INITIAL FORM;Lo;0;AL;<initial> 06A9;;;;N;;;;;
13732 FB91;ARABIC LETTER KEHEH MEDIAL FORM;Lo;0;AL;<medial> 06A9;;;;N;;;;;
13733 FB92;ARABIC LETTER GAF ISOLATED FORM;Lo;0;AL;<isolated> 06AF;;;;N;;;;;
13734 FB93;ARABIC LETTER GAF FINAL FORM;Lo;0;AL;<final> 06AF;;;;N;;;;;
13735 FB94;ARABIC LETTER GAF INITIAL FORM;Lo;0;AL;<initial> 06AF;;;;N;;;;;
13736 FB95;ARABIC LETTER GAF MEDIAL FORM;Lo;0;AL;<medial> 06AF;;;;N;;;;;
13737 FB96;ARABIC LETTER GUEH ISOLATED FORM;Lo;0;AL;<isolated> 06B3;;;;N;;;;;
13738 FB97;ARABIC LETTER GUEH FINAL FORM;Lo;0;AL;<final> 06B3;;;;N;;;;;
13739 FB98;ARABIC LETTER GUEH INITIAL FORM;Lo;0;AL;<initial> 06B3;;;;N;;;;;
13740 FB99;ARABIC LETTER GUEH MEDIAL FORM;Lo;0;AL;<medial> 06B3;;;;N;;;;;
13741 FB9A;ARABIC LETTER NGOEH ISOLATED FORM;Lo;0;AL;<isolated> 06B1;;;;N;;;;;
13742 FB9B;ARABIC LETTER NGOEH FINAL FORM;Lo;0;AL;<final> 06B1;;;;N;;;;;
13743 FB9C;ARABIC LETTER NGOEH INITIAL FORM;Lo;0;AL;<initial> 06B1;;;;N;;;;;
13744 FB9D;ARABIC LETTER NGOEH MEDIAL FORM;Lo;0;AL;<medial> 06B1;;;;N;;;;;
13745 FB9E;ARABIC LETTER NOON GHUNNA ISOLATED FORM;Lo;0;AL;<isolated> 06BA;;;;N;;;;;
13746 FB9F;ARABIC LETTER NOON GHUNNA FINAL FORM;Lo;0;AL;<final> 06BA;;;;N;;;;;
13747 FBA0;ARABIC LETTER RNOON ISOLATED FORM;Lo;0;AL;<isolated> 06BB;;;;N;;;;;
13748 FBA1;ARABIC LETTER RNOON FINAL FORM;Lo;0;AL;<final> 06BB;;;;N;;;;;
13749 FBA2;ARABIC LETTER RNOON INITIAL FORM;Lo;0;AL;<initial> 06BB;;;;N;;;;;
13750 FBA3;ARABIC LETTER RNOON MEDIAL FORM;Lo;0;AL;<medial> 06BB;;;;N;;;;;
13751 FBA4;ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 06C0;;;;N;;;;;
13752 FBA5;ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM;Lo;0;AL;<final> 06C0;;;;N;;;;;
13753 FBA6;ARABIC LETTER HEH GOAL ISOLATED FORM;Lo;0;AL;<isolated> 06C1;;;;N;;;;;
13754 FBA7;ARABIC LETTER HEH GOAL FINAL FORM;Lo;0;AL;<final> 06C1;;;;N;;;;;
13755 FBA8;ARABIC LETTER HEH GOAL INITIAL FORM;Lo;0;AL;<initial> 06C1;;;;N;;;;;
13756 FBA9;ARABIC LETTER HEH GOAL MEDIAL FORM;Lo;0;AL;<medial> 06C1;;;;N;;;;;
13757 FBAA;ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM;Lo;0;AL;<isolated> 06BE;;;;N;;;;;
13758 FBAB;ARABIC LETTER HEH DOACHASHMEE FINAL FORM;Lo;0;AL;<final> 06BE;;;;N;;;;;
13759 FBAC;ARABIC LETTER HEH DOACHASHMEE INITIAL FORM;Lo;0;AL;<initial> 06BE;;;;N;;;;;
13760 FBAD;ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM;Lo;0;AL;<medial> 06BE;;;;N;;;;;
13761 FBAE;ARABIC LETTER YEH BARREE ISOLATED FORM;Lo;0;AL;<isolated> 06D2;;;;N;;;;;
13762 FBAF;ARABIC LETTER YEH BARREE FINAL FORM;Lo;0;AL;<final> 06D2;;;;N;;;;;
13763 FBB0;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 06D3;;;;N;;;;;
13764 FBB1;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 06D3;;;;N;;;;;
13765 FBD3;ARABIC LETTER NG ISOLATED FORM;Lo;0;AL;<isolated> 06AD;;;;N;;;;;
13766 FBD4;ARABIC LETTER NG FINAL FORM;Lo;0;AL;<final> 06AD;;;;N;;;;;
13767 FBD5;ARABIC LETTER NG INITIAL FORM;Lo;0;AL;<initial> 06AD;;;;N;;;;;
13768 FBD6;ARABIC LETTER NG MEDIAL FORM;Lo;0;AL;<medial> 06AD;;;;N;;;;;
13769 FBD7;ARABIC LETTER U ISOLATED FORM;Lo;0;AL;<isolated> 06C7;;;;N;;;;;
13770 FBD8;ARABIC LETTER U FINAL FORM;Lo;0;AL;<final> 06C7;;;;N;;;;;
13771 FBD9;ARABIC LETTER OE ISOLATED FORM;Lo;0;AL;<isolated> 06C6;;;;N;;;;;
13772 FBDA;ARABIC LETTER OE FINAL FORM;Lo;0;AL;<final> 06C6;;;;N;;;;;
13773 FBDB;ARABIC LETTER YU ISOLATED FORM;Lo;0;AL;<isolated> 06C8;;;;N;;;;;
13774 FBDC;ARABIC LETTER YU FINAL FORM;Lo;0;AL;<final> 06C8;;;;N;;;;;
13775 FBDD;ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0677;;;;N;;;;;
13776 FBDE;ARABIC LETTER VE ISOLATED FORM;Lo;0;AL;<isolated> 06CB;;;;N;;;;;
13777 FBDF;ARABIC LETTER VE FINAL FORM;Lo;0;AL;<final> 06CB;;;;N;;;;;
13778 FBE0;ARABIC LETTER KIRGHIZ OE ISOLATED FORM;Lo;0;AL;<isolated> 06C5;;;;N;;;;;
13779 FBE1;ARABIC LETTER KIRGHIZ OE FINAL FORM;Lo;0;AL;<final> 06C5;;;;N;;;;;
13780 FBE2;ARABIC LETTER KIRGHIZ YU ISOLATED FORM;Lo;0;AL;<isolated> 06C9;;;;N;;;;;
13781 FBE3;ARABIC LETTER KIRGHIZ YU FINAL FORM;Lo;0;AL;<final> 06C9;;;;N;;;;;
13782 FBE4;ARABIC LETTER E ISOLATED FORM;Lo;0;AL;<isolated> 06D0;;;;N;;;;;
13783 FBE5;ARABIC LETTER E FINAL FORM;Lo;0;AL;<final> 06D0;;;;N;;;;;
13784 FBE6;ARABIC LETTER E INITIAL FORM;Lo;0;AL;<initial> 06D0;;;;N;;;;;
13785 FBE7;ARABIC LETTER E MEDIAL FORM;Lo;0;AL;<medial> 06D0;;;;N;;;;;
13786 FBE8;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM;Lo;0;AL;<initial> 0649;;;;N;;;;;
13787 FBE9;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM;Lo;0;AL;<medial> 0649;;;;N;;;;;
13788 FBEA;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0626 0627;;;;N;;;;;
13789 FBEB;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM;Lo;0;AL;<final> 0626 0627;;;;N;;;;;
13790 FBEC;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM;Lo;0;AL;<isolated> 0626 06D5;;;;N;;;;;
13791 FBED;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM;Lo;0;AL;<final> 0626 06D5;;;;N;;;;;
13792 FBEE;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM;Lo;0;AL;<isolated> 0626 0648;;;;N;;;;;
13793 FBEF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM;Lo;0;AL;<final> 0626 0648;;;;N;;;;;
13794 FBF0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C7;;;;N;;;;;
13795 FBF1;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM;Lo;0;AL;<final> 0626 06C7;;;;N;;;;;
13796 FBF2;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C6;;;;N;;;;;
13797 FBF3;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM;Lo;0;AL;<final> 0626 06C6;;;;N;;;;;
13798 FBF4;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C8;;;;N;;;;;
13799 FBF5;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM;Lo;0;AL;<final> 0626 06C8;;;;N;;;;;
13800 FBF6;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM;Lo;0;AL;<isolated> 0626 06D0;;;;N;;;;;
13801 FBF7;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM;Lo;0;AL;<final> 0626 06D0;;;;N;;;;;
13802 FBF8;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM;Lo;0;AL;<initial> 0626 06D0;;;;N;;;;;
13803 FBF9;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0626 0649;;;;N;;;;;
13804 FBFA;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0626 0649;;;;N;;;;;
13805 FBFB;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM;Lo;0;AL;<initial> 0626 0649;;;;N;;;;;
13806 FBFC;ARABIC LETTER FARSI YEH ISOLATED FORM;Lo;0;AL;<isolated> 06CC;;;;N;;;;;
13807 FBFD;ARABIC LETTER FARSI YEH FINAL FORM;Lo;0;AL;<final> 06CC;;;;N;;;;;
13808 FBFE;ARABIC LETTER FARSI YEH INITIAL FORM;Lo;0;AL;<initial> 06CC;;;;N;;;;;
13809 FBFF;ARABIC LETTER FARSI YEH MEDIAL FORM;Lo;0;AL;<medial> 06CC;;;;N;;;;;
13810 FC00;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0626 062C;;;;N;;;;;
13811 FC01;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0626 062D;;;;N;;;;;
13812 FC02;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0626 0645;;;;N;;;;;
13813 FC03;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0626 0649;;;;N;;;;;
13814 FC04;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0626 064A;;;;N;;;;;
13815 FC05;ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0628 062C;;;;N;;;;;
13816 FC06;ARABIC LIGATURE BEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0628 062D;;;;N;;;;;
13817 FC07;ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0628 062E;;;;N;;;;;
13818 FC08;ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0628 0645;;;;N;;;;;
13819 FC09;ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0628 0649;;;;N;;;;;
13820 FC0A;ARABIC LIGATURE BEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0628 064A;;;;N;;;;;
13821 FC0B;ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062A 062C;;;;N;;;;;
13822 FC0C;ARABIC LIGATURE TEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062A 062D;;;;N;;;;;
13823 FC0D;ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 062A 062E;;;;N;;;;;
13824 FC0E;ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062A 0645;;;;N;;;;;
13825 FC0F;ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062A 0649;;;;N;;;;;
13826 FC10;ARABIC LIGATURE TEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062A 064A;;;;N;;;;;
13827 FC11;ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062B 062C;;;;N;;;;;
13828 FC12;ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062B 0645;;;;N;;;;;
13829 FC13;ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062B 0649;;;;N;;;;;
13830 FC14;ARABIC LIGATURE THEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062B 064A;;;;N;;;;;
13831 FC15;ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062C 062D;;;;N;;;;;
13832 FC16;ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062C 0645;;;;N;;;;;
13833 FC17;ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062D 062C;;;;N;;;;;
13834 FC18;ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062D 0645;;;;N;;;;;
13835 FC19;ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062E 062C;;;;N;;;;;
13836 FC1A;ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062E 062D;;;;N;;;;;
13837 FC1B;ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062E 0645;;;;N;;;;;
13838 FC1C;ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0633 062C;;;;N;;;;;
13839 FC1D;ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0633 062D;;;;N;;;;;
13840 FC1E;ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0633 062E;;;;N;;;;;
13841 FC1F;ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0633 0645;;;;N;;;;;
13842 FC20;ARABIC LIGATURE SAD WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0635 062D;;;;N;;;;;
13843 FC21;ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0635 0645;;;;N;;;;;
13844 FC22;ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0636 062C;;;;N;;;;;
13845 FC23;ARABIC LIGATURE DAD WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0636 062D;;;;N;;;;;
13846 FC24;ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0636 062E;;;;N;;;;;
13847 FC25;ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0636 0645;;;;N;;;;;
13848 FC26;ARABIC LIGATURE TAH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0637 062D;;;;N;;;;;
13849 FC27;ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0637 0645;;;;N;;;;;
13850 FC28;ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0638 0645;;;;N;;;;;
13851 FC29;ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0639 062C;;;;N;;;;;
13852 FC2A;ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0639 0645;;;;N;;;;;
13853 FC2B;ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 063A 062C;;;;N;;;;;
13854 FC2C;ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 063A 0645;;;;N;;;;;
13855 FC2D;ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0641 062C;;;;N;;;;;
13856 FC2E;ARABIC LIGATURE FEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0641 062D;;;;N;;;;;
13857 FC2F;ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0641 062E;;;;N;;;;;
13858 FC30;ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0641 0645;;;;N;;;;;
13859 FC31;ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0641 0649;;;;N;;;;;
13860 FC32;ARABIC LIGATURE FEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0641 064A;;;;N;;;;;
13861 FC33;ARABIC LIGATURE QAF WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0642 062D;;;;N;;;;;
13862 FC34;ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0642 0645;;;;N;;;;;
13863 FC35;ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0642 0649;;;;N;;;;;
13864 FC36;ARABIC LIGATURE QAF WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0642 064A;;;;N;;;;;
13865 FC37;ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0643 0627;;;;N;;;;;
13866 FC38;ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0643 062C;;;;N;;;;;
13867 FC39;ARABIC LIGATURE KAF WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0643 062D;;;;N;;;;;
13868 FC3A;ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0643 062E;;;;N;;;;;
13869 FC3B;ARABIC LIGATURE KAF WITH LAM ISOLATED FORM;Lo;0;AL;<isolated> 0643 0644;;;;N;;;;;
13870 FC3C;ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0643 0645;;;;N;;;;;
13871 FC3D;ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0643 0649;;;;N;;;;;
13872 FC3E;ARABIC LIGATURE KAF WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0643 064A;;;;N;;;;;
13873 FC3F;ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0644 062C;;;;N;;;;;
13874 FC40;ARABIC LIGATURE LAM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0644 062D;;;;N;;;;;
13875 FC41;ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0644 062E;;;;N;;;;;
13876 FC42;ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0644 0645;;;;N;;;;;
13877 FC43;ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0644 0649;;;;N;;;;;
13878 FC44;ARABIC LIGATURE LAM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0644 064A;;;;N;;;;;
13879 FC45;ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645 062C;;;;N;;;;;
13880 FC46;ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0645 062D;;;;N;;;;;
13881 FC47;ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0645 062E;;;;N;;;;;
13882 FC48;ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645 0645;;;;N;;;;;
13883 FC49;ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0645 0649;;;;N;;;;;
13884 FC4A;ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0645 064A;;;;N;;;;;
13885 FC4B;ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0646 062C;;;;N;;;;;
13886 FC4C;ARABIC LIGATURE NOON WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0646 062D;;;;N;;;;;
13887 FC4D;ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0646 062E;;;;N;;;;;
13888 FC4E;ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0646 0645;;;;N;;;;;
13889 FC4F;ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0646 0649;;;;N;;;;;
13890 FC50;ARABIC LIGATURE NOON WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0646 064A;;;;N;;;;;
13891 FC51;ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0647 062C;;;;N;;;;;
13892 FC52;ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0647 0645;;;;N;;;;;
13893 FC53;ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0647 0649;;;;N;;;;;
13894 FC54;ARABIC LIGATURE HEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0647 064A;;;;N;;;;;
13895 FC55;ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 064A 062C;;;;N;;;;;
13896 FC56;ARABIC LIGATURE YEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 064A 062D;;;;N;;;;;
13897 FC57;ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 064A 062E;;;;N;;;;;
13898 FC58;ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 064A 0645;;;;N;;;;;
13899 FC59;ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 064A 0649;;;;N;;;;;
13900 FC5A;ARABIC LIGATURE YEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 064A 064A;;;;N;;;;;
13901 FC5B;ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0630 0670;;;;N;;;;;
13902 FC5C;ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0631 0670;;;;N;;;;;
13903 FC5D;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0649 0670;;;;N;;;;;
13904 FC5E;ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064C 0651;;;;N;;;;;
13905 FC5F;ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064D 0651;;;;N;;;;;
13906 FC60;ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064E 0651;;;;N;;;;;
13907 FC61;ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064F 0651;;;;N;;;;;
13908 FC62;ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0650 0651;;;;N;;;;;
13909 FC63;ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0020 0651 0670;;;;N;;;;;
13910 FC64;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM;Lo;0;AL;<final> 0626 0631;;;;N;;;;;
13911 FC65;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0626 0632;;;;N;;;;;
13912 FC66;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM;Lo;0;AL;<final> 0626 0645;;;;N;;;;;
13913 FC67;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM;Lo;0;AL;<final> 0626 0646;;;;N;;;;;
13914 FC68;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0626 0649;;;;N;;;;;
13915 FC69;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM;Lo;0;AL;<final> 0626 064A;;;;N;;;;;
13916 FC6A;ARABIC LIGATURE BEH WITH REH FINAL FORM;Lo;0;AL;<final> 0628 0631;;;;N;;;;;
13917 FC6B;ARABIC LIGATURE BEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0628 0632;;;;N;;;;;
13918 FC6C;ARABIC LIGATURE BEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0628 0645;;;;N;;;;;
13919 FC6D;ARABIC LIGATURE BEH WITH NOON FINAL FORM;Lo;0;AL;<final> 0628 0646;;;;N;;;;;
13920 FC6E;ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0628 0649;;;;N;;;;;
13921 FC6F;ARABIC LIGATURE BEH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 064A;;;;N;;;;;
13922 FC70;ARABIC LIGATURE TEH WITH REH FINAL FORM;Lo;0;AL;<final> 062A 0631;;;;N;;;;;
13923 FC71;ARABIC LIGATURE TEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 062A 0632;;;;N;;;;;
13924 FC72;ARABIC LIGATURE TEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 062A 0645;;;;N;;;;;
13925 FC73;ARABIC LIGATURE TEH WITH NOON FINAL FORM;Lo;0;AL;<final> 062A 0646;;;;N;;;;;
13926 FC74;ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 0649;;;;N;;;;;
13927 FC75;ARABIC LIGATURE TEH WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 064A;;;;N;;;;;
13928 FC76;ARABIC LIGATURE THEH WITH REH FINAL FORM;Lo;0;AL;<final> 062B 0631;;;;N;;;;;
13929 FC77;ARABIC LIGATURE THEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 062B 0632;;;;N;;;;;
13930 FC78;ARABIC LIGATURE THEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 062B 0645;;;;N;;;;;
13931 FC79;ARABIC LIGATURE THEH WITH NOON FINAL FORM;Lo;0;AL;<final> 062B 0646;;;;N;;;;;
13932 FC7A;ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062B 0649;;;;N;;;;;
13933 FC7B;ARABIC LIGATURE THEH WITH YEH FINAL FORM;Lo;0;AL;<final> 062B 064A;;;;N;;;;;
13934 FC7C;ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0641 0649;;;;N;;;;;
13935 FC7D;ARABIC LIGATURE FEH WITH YEH FINAL FORM;Lo;0;AL;<final> 0641 064A;;;;N;;;;;
13936 FC7E;ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0642 0649;;;;N;;;;;
13937 FC7F;ARABIC LIGATURE QAF WITH YEH FINAL FORM;Lo;0;AL;<final> 0642 064A;;;;N;;;;;
13938 FC80;ARABIC LIGATURE KAF WITH ALEF FINAL FORM;Lo;0;AL;<final> 0643 0627;;;;N;;;;;
13939 FC81;ARABIC LIGATURE KAF WITH LAM FINAL FORM;Lo;0;AL;<final> 0643 0644;;;;N;;;;;
13940 FC82;ARABIC LIGATURE KAF WITH MEEM FINAL FORM;Lo;0;AL;<final> 0643 0645;;;;N;;;;;
13941 FC83;ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0643 0649;;;;N;;;;;
13942 FC84;ARABIC LIGATURE KAF WITH YEH FINAL FORM;Lo;0;AL;<final> 0643 064A;;;;N;;;;;
13943 FC85;ARABIC LIGATURE LAM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 0645;;;;N;;;;;
13944 FC86;ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0644 0649;;;;N;;;;;
13945 FC87;ARABIC LIGATURE LAM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 064A;;;;N;;;;;
13946 FC88;ARABIC LIGATURE MEEM WITH ALEF FINAL FORM;Lo;0;AL;<final> 0645 0627;;;;N;;;;;
13947 FC89;ARABIC LIGATURE MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0645 0645;;;;N;;;;;
13948 FC8A;ARABIC LIGATURE NOON WITH REH FINAL FORM;Lo;0;AL;<final> 0646 0631;;;;N;;;;;
13949 FC8B;ARABIC LIGATURE NOON WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0646 0632;;;;N;;;;;
13950 FC8C;ARABIC LIGATURE NOON WITH MEEM FINAL FORM;Lo;0;AL;<final> 0646 0645;;;;N;;;;;
13951 FC8D;ARABIC LIGATURE NOON WITH NOON FINAL FORM;Lo;0;AL;<final> 0646 0646;;;;N;;;;;
13952 FC8E;ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 0649;;;;N;;;;;
13953 FC8F;ARABIC LIGATURE NOON WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 064A;;;;N;;;;;
13954 FC90;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM;Lo;0;AL;<final> 0649 0670;;;;N;;;;;
13955 FC91;ARABIC LIGATURE YEH WITH REH FINAL FORM;Lo;0;AL;<final> 064A 0631;;;;N;;;;;
13956 FC92;ARABIC LIGATURE YEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 064A 0632;;;;N;;;;;
13957 FC93;ARABIC LIGATURE YEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 064A 0645;;;;N;;;;;
13958 FC94;ARABIC LIGATURE YEH WITH NOON FINAL FORM;Lo;0;AL;<final> 064A 0646;;;;N;;;;;
13959 FC95;ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 064A 0649;;;;N;;;;;
13960 FC96;ARABIC LIGATURE YEH WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 064A;;;;N;;;;;
13961 FC97;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0626 062C;;;;N;;;;;
13962 FC98;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0626 062D;;;;N;;;;;
13963 FC99;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0626 062E;;;;N;;;;;
13964 FC9A;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0626 0645;;;;N;;;;;
13965 FC9B;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0626 0647;;;;N;;;;;
13966 FC9C;ARABIC LIGATURE BEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0628 062C;;;;N;;;;;
13967 FC9D;ARABIC LIGATURE BEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0628 062D;;;;N;;;;;
13968 FC9E;ARABIC LIGATURE BEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0628 062E;;;;N;;;;;
13969 FC9F;ARABIC LIGATURE BEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0628 0645;;;;N;;;;;
13970 FCA0;ARABIC LIGATURE BEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0628 0647;;;;N;;;;;
13971 FCA1;ARABIC LIGATURE TEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062C;;;;N;;;;;
13972 FCA2;ARABIC LIGATURE TEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062A 062D;;;;N;;;;;
13973 FCA3;ARABIC LIGATURE TEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 062A 062E;;;;N;;;;;
13974 FCA4;ARABIC LIGATURE TEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 0645;;;;N;;;;;
13975 FCA5;ARABIC LIGATURE TEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 062A 0647;;;;N;;;;;
13976 FCA6;ARABIC LIGATURE THEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062B 0645;;;;N;;;;;
13977 FCA7;ARABIC LIGATURE JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062C 062D;;;;N;;;;;
13978 FCA8;ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062C 0645;;;;N;;;;;
13979 FCA9;ARABIC LIGATURE HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062D 062C;;;;N;;;;;
13980 FCAA;ARABIC LIGATURE HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062D 0645;;;;N;;;;;
13981 FCAB;ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062E 062C;;;;N;;;;;
13982 FCAC;ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062E 0645;;;;N;;;;;
13983 FCAD;ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 062C;;;;N;;;;;
13984 FCAE;ARABIC LIGATURE SEEN WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 062D;;;;N;;;;;
13985 FCAF;ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0633 062E;;;;N;;;;;
13986 FCB0;ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645;;;;N;;;;;
13987 FCB1;ARABIC LIGATURE SAD WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0635 062D;;;;N;;;;;
13988 FCB2;ARABIC LIGATURE SAD WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0635 062E;;;;N;;;;;
13989 FCB3;ARABIC LIGATURE SAD WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0635 0645;;;;N;;;;;
13990 FCB4;ARABIC LIGATURE DAD WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0636 062C;;;;N;;;;;
13991 FCB5;ARABIC LIGATURE DAD WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0636 062D;;;;N;;;;;
13992 FCB6;ARABIC LIGATURE DAD WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0636 062E;;;;N;;;;;
13993 FCB7;ARABIC LIGATURE DAD WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0636 0645;;;;N;;;;;
13994 FCB8;ARABIC LIGATURE TAH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0637 062D;;;;N;;;;;
13995 FCB9;ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0638 0645;;;;N;;;;;
13996 FCBA;ARABIC LIGATURE AIN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0639 062C;;;;N;;;;;
13997 FCBB;ARABIC LIGATURE AIN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 0645;;;;N;;;;;
13998 FCBC;ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 063A 062C;;;;N;;;;;
13999 FCBD;ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 063A 0645;;;;N;;;;;
14000 FCBE;ARABIC LIGATURE FEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0641 062C;;;;N;;;;;
14001 FCBF;ARABIC LIGATURE FEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0641 062D;;;;N;;;;;
14002 FCC0;ARABIC LIGATURE FEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0641 062E;;;;N;;;;;
14003 FCC1;ARABIC LIGATURE FEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0641 0645;;;;N;;;;;
14004 FCC2;ARABIC LIGATURE QAF WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0642 062D;;;;N;;;;;
14005 FCC3;ARABIC LIGATURE QAF WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0642 0645;;;;N;;;;;
14006 FCC4;ARABIC LIGATURE KAF WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0643 062C;;;;N;;;;;
14007 FCC5;ARABIC LIGATURE KAF WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0643 062D;;;;N;;;;;
14008 FCC6;ARABIC LIGATURE KAF WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0643 062E;;;;N;;;;;
14009 FCC7;ARABIC LIGATURE KAF WITH LAM INITIAL FORM;Lo;0;AL;<initial> 0643 0644;;;;N;;;;;
14010 FCC8;ARABIC LIGATURE KAF WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0643 0645;;;;N;;;;;
14011 FCC9;ARABIC LIGATURE LAM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C;;;;N;;;;;
14012 FCCA;ARABIC LIGATURE LAM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0644 062D;;;;N;;;;;
14013 FCCB;ARABIC LIGATURE LAM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0644 062E;;;;N;;;;;
14014 FCCC;ARABIC LIGATURE LAM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 0645;;;;N;;;;;
14015 FCCD;ARABIC LIGATURE LAM WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0644 0647;;;;N;;;;;
14016 FCCE;ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062C;;;;N;;;;;
14017 FCCF;ARABIC LIGATURE MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0645 062D;;;;N;;;;;
14018 FCD0;ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0645 062E;;;;N;;;;;
14019 FCD1;ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 0645;;;;N;;;;;
14020 FCD2;ARABIC LIGATURE NOON WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062C;;;;N;;;;;
14021 FCD3;ARABIC LIGATURE NOON WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0646 062D;;;;N;;;;;
14022 FCD4;ARABIC LIGATURE NOON WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0646 062E;;;;N;;;;;
14023 FCD5;ARABIC LIGATURE NOON WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 0645;;;;N;;;;;
14024 FCD6;ARABIC LIGATURE NOON WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0646 0647;;;;N;;;;;
14025 FCD7;ARABIC LIGATURE HEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0647 062C;;;;N;;;;;
14026 FCD8;ARABIC LIGATURE HEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645;;;;N;;;;;
14027 FCD9;ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM;Lo;0;AL;<initial> 0647 0670;;;;N;;;;;
14028 FCDA;ARABIC LIGATURE YEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 064A 062C;;;;N;;;;;
14029 FCDB;ARABIC LIGATURE YEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 064A 062D;;;;N;;;;;
14030 FCDC;ARABIC LIGATURE YEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 064A 062E;;;;N;;;;;
14031 FCDD;ARABIC LIGATURE YEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 064A 0645;;;;N;;;;;
14032 FCDE;ARABIC LIGATURE YEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 064A 0647;;;;N;;;;;
14033 FCDF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0626 0645;;;;N;;;;;
14034 FCE0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0626 0647;;;;N;;;;;
14035 FCE1;ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0628 0645;;;;N;;;;;
14036 FCE2;ARABIC LIGATURE BEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0628 0647;;;;N;;;;;
14037 FCE3;ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 062A 0645;;;;N;;;;;
14038 FCE4;ARABIC LIGATURE TEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 062A 0647;;;;N;;;;;
14039 FCE5;ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 062B 0645;;;;N;;;;;
14040 FCE6;ARABIC LIGATURE THEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 062B 0647;;;;N;;;;;
14041 FCE7;ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0633 0645;;;;N;;;;;
14042 FCE8;ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0633 0647;;;;N;;;;;
14043 FCE9;ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0634 0645;;;;N;;;;;
14044 FCEA;ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0634 0647;;;;N;;;;;
14045 FCEB;ARABIC LIGATURE KAF WITH LAM MEDIAL FORM;Lo;0;AL;<medial> 0643 0644;;;;N;;;;;
14046 FCEC;ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0643 0645;;;;N;;;;;
14047 FCED;ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0644 0645;;;;N;;;;;
14048 FCEE;ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0646 0645;;;;N;;;;;
14049 FCEF;ARABIC LIGATURE NOON WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0646 0647;;;;N;;;;;
14050 FCF0;ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 064A 0645;;;;N;;;;;
14051 FCF1;ARABIC LIGATURE YEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 064A 0647;;;;N;;;;;
14052 FCF2;ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM;Lo;0;AL;<medial> 0640 064E 0651;;;;N;;;;;
14053 FCF3;ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM;Lo;0;AL;<medial> 0640 064F 0651;;;;N;;;;;
14054 FCF4;ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM;Lo;0;AL;<medial> 0640 0650 0651;;;;N;;;;;
14055 FCF5;ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0637 0649;;;;N;;;;;
14056 FCF6;ARABIC LIGATURE TAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0637 064A;;;;N;;;;;
14057 FCF7;ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0639 0649;;;;N;;;;;
14058 FCF8;ARABIC LIGATURE AIN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0639 064A;;;;N;;;;;
14059 FCF9;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 063A 0649;;;;N;;;;;
14060 FCFA;ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 063A 064A;;;;N;;;;;
14061 FCFB;ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0633 0649;;;;N;;;;;
14062 FCFC;ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0633 064A;;;;N;;;;;
14063 FCFD;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0634 0649;;;;N;;;;;
14064 FCFE;ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0634 064A;;;;N;;;;;
14065 FCFF;ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062D 0649;;;;N;;;;;
14066 FD00;ARABIC LIGATURE HAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062D 064A;;;;N;;;;;
14067 FD01;ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062C 0649;;;;N;;;;;
14068 FD02;ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062C 064A;;;;N;;;;;
14069 FD03;ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062E 0649;;;;N;;;;;
14070 FD04;ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062E 064A;;;;N;;;;;
14071 FD05;ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0635 0649;;;;N;;;;;
14072 FD06;ARABIC LIGATURE SAD WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0635 064A;;;;N;;;;;
14073 FD07;ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0636 0649;;;;N;;;;;
14074 FD08;ARABIC LIGATURE DAD WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0636 064A;;;;N;;;;;
14075 FD09;ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0634 062C;;;;N;;;;;
14076 FD0A;ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0634 062D;;;;N;;;;;
14077 FD0B;ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0634 062E;;;;N;;;;;
14078 FD0C;ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0634 0645;;;;N;;;;;
14079 FD0D;ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0634 0631;;;;N;;;;;
14080 FD0E;ARABIC LIGATURE SEEN WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0633 0631;;;;N;;;;;
14081 FD0F;ARABIC LIGATURE SAD WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0635 0631;;;;N;;;;;
14082 FD10;ARABIC LIGATURE DAD WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0636 0631;;;;N;;;;;
14083 FD11;ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0637 0649;;;;N;;;;;
14084 FD12;ARABIC LIGATURE TAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0637 064A;;;;N;;;;;
14085 FD13;ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0639 0649;;;;N;;;;;
14086 FD14;ARABIC LIGATURE AIN WITH YEH FINAL FORM;Lo;0;AL;<final> 0639 064A;;;;N;;;;;
14087 FD15;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 063A 0649;;;;N;;;;;
14088 FD16;ARABIC LIGATURE GHAIN WITH YEH FINAL FORM;Lo;0;AL;<final> 063A 064A;;;;N;;;;;
14089 FD17;ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 0649;;;;N;;;;;
14090 FD18;ARABIC LIGATURE SEEN WITH YEH FINAL FORM;Lo;0;AL;<final> 0633 064A;;;;N;;;;;
14091 FD19;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0634 0649;;;;N;;;;;
14092 FD1A;ARABIC LIGATURE SHEEN WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 064A;;;;N;;;;;
14093 FD1B;ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062D 0649;;;;N;;;;;
14094 FD1C;ARABIC LIGATURE HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 064A;;;;N;;;;;
14095 FD1D;ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 0649;;;;N;;;;;
14096 FD1E;ARABIC LIGATURE JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 064A;;;;N;;;;;
14097 FD1F;ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062E 0649;;;;N;;;;;
14098 FD20;ARABIC LIGATURE KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062E 064A;;;;N;;;;;
14099 FD21;ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0635 0649;;;;N;;;;;
14100 FD22;ARABIC LIGATURE SAD WITH YEH FINAL FORM;Lo;0;AL;<final> 0635 064A;;;;N;;;;;
14101 FD23;ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0636 0649;;;;N;;;;;
14102 FD24;ARABIC LIGATURE DAD WITH YEH FINAL FORM;Lo;0;AL;<final> 0636 064A;;;;N;;;;;
14103 FD25;ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM;Lo;0;AL;<final> 0634 062C;;;;N;;;;;
14104 FD26;ARABIC LIGATURE SHEEN WITH HAH FINAL FORM;Lo;0;AL;<final> 0634 062D;;;;N;;;;;
14105 FD27;ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM;Lo;0;AL;<final> 0634 062E;;;;N;;;;;
14106 FD28;ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 0645;;;;N;;;;;
14107 FD29;ARABIC LIGATURE SHEEN WITH REH FINAL FORM;Lo;0;AL;<final> 0634 0631;;;;N;;;;;
14108 FD2A;ARABIC LIGATURE SEEN WITH REH FINAL FORM;Lo;0;AL;<final> 0633 0631;;;;N;;;;;
14109 FD2B;ARABIC LIGATURE SAD WITH REH FINAL FORM;Lo;0;AL;<final> 0635 0631;;;;N;;;;;
14110 FD2C;ARABIC LIGATURE DAD WITH REH FINAL FORM;Lo;0;AL;<final> 0636 0631;;;;N;;;;;
14111 FD2D;ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0634 062C;;;;N;;;;;
14112 FD2E;ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0634 062D;;;;N;;;;;
14113 FD2F;ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0634 062E;;;;N;;;;;
14114 FD30;ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 0645;;;;N;;;;;
14115 FD31;ARABIC LIGATURE SEEN WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0633 0647;;;;N;;;;;
14116 FD32;ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0634 0647;;;;N;;;;;
14117 FD33;ARABIC LIGATURE TAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0637 0645;;;;N;;;;;
14118 FD34;ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM;Lo;0;AL;<medial> 0633 062C;;;;N;;;;;
14119 FD35;ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM;Lo;0;AL;<medial> 0633 062D;;;;N;;;;;
14120 FD36;ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM;Lo;0;AL;<medial> 0633 062E;;;;N;;;;;
14121 FD37;ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM;Lo;0;AL;<medial> 0634 062C;;;;N;;;;;
14122 FD38;ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM;Lo;0;AL;<medial> 0634 062D;;;;N;;;;;
14123 FD39;ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM;Lo;0;AL;<medial> 0634 062E;;;;N;;;;;
14124 FD3A;ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0637 0645;;;;N;;;;;
14125 FD3B;ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0638 0645;;;;N;;;;;
14126 FD3C;ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM;Lo;0;AL;<final> 0627 064B;;;;N;;;;;
14127 FD3D;ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0627 064B;;;;N;;;;;
14128 FD3E;ORNATE LEFT PARENTHESIS;Ps;0;ON;;;;;N;;;;;
14129 FD3F;ORNATE RIGHT PARENTHESIS;Pe;0;ON;;;;;N;;;;;
14130 FD50;ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062C 0645;;;;N;;;;;
14131 FD51;ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM;Lo;0;AL;<final> 062A 062D 062C;;;;N;;;;;
14132 FD52;ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062D 062C;;;;N;;;;;
14133 FD53;ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062D 0645;;;;N;;;;;
14134 FD54;ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062E 0645;;;;N;;;;;
14135 FD55;ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062C;;;;N;;;;;
14136 FD56;ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062D;;;;N;;;;;
14137 FD57;ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062E;;;;N;;;;;
14138 FD58;ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 062C 0645 062D;;;;N;;;;;
14139 FD59;ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062C 0645 062D;;;;N;;;;;
14140 FD5A;ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 0645 064A;;;;N;;;;;
14141 FD5B;ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062D 0645 0649;;;;N;;;;;
14142 FD5C;ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 062D 062C;;;;N;;;;;
14143 FD5D;ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 062C 062D;;;;N;;;;;
14144 FD5E;ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 062C 0649;;;;N;;;;;
14145 FD5F;ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0633 0645 062D;;;;N;;;;;
14146 FD60;ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 0645 062D;;;;N;;;;;
14147 FD61;ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645 062C;;;;N;;;;;
14148 FD62;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0633 0645 0645;;;;N;;;;;
14149 FD63;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645 0645;;;;N;;;;;
14150 FD64;ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM;Lo;0;AL;<final> 0635 062D 062D;;;;N;;;;;
14151 FD65;ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0635 062D 062D;;;;N;;;;;
14152 FD66;ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0635 0645 0645;;;;N;;;;;
14153 FD67;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 062D 0645;;;;N;;;;;
14154 FD68;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 062D 0645;;;;N;;;;;
14155 FD69;ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 062C 064A;;;;N;;;;;
14156 FD6A;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM;Lo;0;AL;<final> 0634 0645 062E;;;;N;;;;;
14157 FD6B;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0634 0645 062E;;;;N;;;;;
14158 FD6C;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 0645 0645;;;;N;;;;;
14159 FD6D;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 0645 0645;;;;N;;;;;
14160 FD6E;ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0636 062D 0649;;;;N;;;;;
14161 FD6F;ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0636 062E 0645;;;;N;;;;;
14162 FD70;ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0636 062E 0645;;;;N;;;;;
14163 FD71;ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0637 0645 062D;;;;N;;;;;
14164 FD72;ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0637 0645 062D;;;;N;;;;;
14165 FD73;ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0637 0645 0645;;;;N;;;;;
14166 FD74;ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0637 0645 064A;;;;N;;;;;
14167 FD75;ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0639 062C 0645;;;;N;;;;;
14168 FD76;ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0639 0645 0645;;;;N;;;;;
14169 FD77;ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 0645 0645;;;;N;;;;;
14170 FD78;ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0639 0645 0649;;;;N;;;;;
14171 FD79;ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 063A 0645 0645;;;;N;;;;;
14172 FD7A;ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 063A 0645 064A;;;;N;;;;;
14173 FD7B;ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 063A 0645 0649;;;;N;;;;;
14174 FD7C;ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0641 062E 0645;;;;N;;;;;
14175 FD7D;ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0641 062E 0645;;;;N;;;;;
14176 FD7E;ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0642 0645 062D;;;;N;;;;;
14177 FD7F;ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0642 0645 0645;;;;N;;;;;
14178 FD80;ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062D 0645;;;;N;;;;;
14179 FD81;ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 062D 064A;;;;N;;;;;
14180 FD82;ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0644 062D 0649;;;;N;;;;;
14181 FD83;ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C 062C;;;;N;;;;;
14182 FD84;ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM;Lo;0;AL;<final> 0644 062C 062C;;;;N;;;;;
14183 FD85;ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062E 0645;;;;N;;;;;
14184 FD86;ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062E 0645;;;;N;;;;;
14185 FD87;ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0644 0645 062D;;;;N;;;;;
14186 FD88;ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0644 0645 062D;;;;N;;;;;
14187 FD89;ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062D 062C;;;;N;;;;;
14188 FD8A;ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062D 0645;;;;N;;;;;
14189 FD8B;ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062D 064A;;;;N;;;;;
14190 FD8C;ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0645 062C 062D;;;;N;;;;;
14191 FD8D;ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062C 0645;;;;N;;;;;
14192 FD8E;ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062E 062C;;;;N;;;;;
14193 FD8F;ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062E 0645;;;;N;;;;;
14194 FD92;ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0645 062C 062E;;;;N;;;;;
14195 FD93;ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645 062C;;;;N;;;;;
14196 FD94;ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645 0645;;;;N;;;;;
14197 FD95;ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062D 0645;;;;N;;;;;
14198 FD96;ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 062D 0649;;;;N;;;;;
14199 FD97;ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0646 062C 0645;;;;N;;;;;
14200 FD98;ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062C 0645;;;;N;;;;;
14201 FD99;ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 062C 0649;;;;N;;;;;
14202 FD9A;ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 0645 064A;;;;N;;;;;
14203 FD9B;ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 0645 0649;;;;N;;;;;
14204 FD9C;ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 064A 0645 0645;;;;N;;;;;
14205 FD9D;ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 064A 0645 0645;;;;N;;;;;
14206 FD9E;ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 062E 064A;;;;N;;;;;
14207 FD9F;ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 062C 064A;;;;N;;;;;
14208 FDA0;ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 062C 0649;;;;N;;;;;
14209 FDA1;ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 062E 064A;;;;N;;;;;
14210 FDA2;ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 062E 0649;;;;N;;;;;
14211 FDA3;ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 0645 064A;;;;N;;;;;
14212 FDA4;ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 0645 0649;;;;N;;;;;
14213 FDA5;ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 0645 064A;;;;N;;;;;
14214 FDA6;ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 062D 0649;;;;N;;;;;
14215 FDA7;ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 0645 0649;;;;N;;;;;
14216 FDA8;ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 062E 0649;;;;N;;;;;
14217 FDA9;ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0635 062D 064A;;;;N;;;;;
14218 FDAA;ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 062D 064A;;;;N;;;;;
14219 FDAB;ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0636 062D 064A;;;;N;;;;;
14220 FDAC;ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 062C 064A;;;;N;;;;;
14221 FDAD;ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 0645 064A;;;;N;;;;;
14222 FDAE;ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 062D 064A;;;;N;;;;;
14223 FDAF;ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 062C 064A;;;;N;;;;;
14224 FDB0;ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 0645 064A;;;;N;;;;;
14225 FDB1;ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 0645 064A;;;;N;;;;;
14226 FDB2;ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0642 0645 064A;;;;N;;;;;
14227 FDB3;ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 062D 064A;;;;N;;;;;
14228 FDB4;ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0642 0645 062D;;;;N;;;;;
14229 FDB5;ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062D 0645;;;;N;;;;;
14230 FDB6;ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0639 0645 064A;;;;N;;;;;
14231 FDB7;ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0643 0645 064A;;;;N;;;;;
14232 FDB8;ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0646 062C 062D;;;;N;;;;;
14233 FDB9;ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062E 064A;;;;N;;;;;
14234 FDBA;ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C 0645;;;;N;;;;;
14235 FDBB;ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0643 0645 0645;;;;N;;;;;
14236 FDBC;ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062C 0645;;;;N;;;;;
14237 FDBD;ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0646 062C 062D;;;;N;;;;;
14238 FDBE;ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 062D 064A;;;;N;;;;;
14239 FDBF;ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 062C 064A;;;;N;;;;;
14240 FDC0;ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062C 064A;;;;N;;;;;
14241 FDC1;ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0641 0645 064A;;;;N;;;;;
14242 FDC2;ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 062D 064A;;;;N;;;;;
14243 FDC3;ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0643 0645 0645;;;;N;;;;;
14244 FDC4;ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 062C 0645;;;;N;;;;;
14245 FDC5;ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0635 0645 0645;;;;N;;;;;
14246 FDC6;ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0633 062E 064A;;;;N;;;;;
14247 FDC7;ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 062C 064A;;;;N;;;;;
14248 FDF0;ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 06D2;;;;N;;;;;
14249 FDF1;ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL;<isolated> 0642 0644 06D2;;;;N;;;;;
14250 FDF2;ARABIC LIGATURE ALLAH ISOLATED FORM;Lo;0;AL;<isolated> 0627 0644 0644 0647;;;;N;;;;;
14251 FDF3;ARABIC LIGATURE AKBAR ISOLATED FORM;Lo;0;AL;<isolated> 0627 0643 0628 0631;;;;N;;;;;
14252 FDF4;ARABIC LIGATURE MOHAMMAD ISOLATED FORM;Lo;0;AL;<isolated> 0645 062D 0645 062F;;;;N;;;;;
14253 FDF5;ARABIC LIGATURE SALAM ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 0639 0645;;;;N;;;;;
14254 FDF6;ARABIC LIGATURE RASOUL ISOLATED FORM;Lo;0;AL;<isolated> 0631 0633 0648 0644;;;;N;;;;;
14255 FDF7;ARABIC LIGATURE ALAYHE ISOLATED FORM;Lo;0;AL;<isolated> 0639 0644 064A 0647;;;;N;;;;;
14256 FDF8;ARABIC LIGATURE WASALLAM ISOLATED FORM;Lo;0;AL;<isolated> 0648 0633 0644 0645;;;;N;;;;;
14257 FDF9;ARABIC LIGATURE SALLA ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 0649;;;;N;;;;;
14258 FDFA;ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM;Lo;0;AL;<isolated> 0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645;;;;N;ARABIC LETTER SALLALLAHOU ALAYHE WASALLAM;;;;
14259 FDFB;ARABIC LIGATURE JALLAJALALOUHOU;Lo;0;AL;<isolated> 062C 0644 0020 062C 0644 0627 0644 0647;;;;N;ARABIC LETTER JALLAJALALOUHOU;;;;
14260 FDFC;RIAL SIGN;Sc;0;AL;<isolated> 0631 06CC 0627 0644;;;;N;;;;;
14261 FDFD;ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM;So;0;ON;;;;;N;;;;;
14262 FE00;VARIATION SELECTOR-1;Mn;0;NSM;;;;;N;;;;;
14263 FE01;VARIATION SELECTOR-2;Mn;0;NSM;;;;;N;;;;;
14264 FE02;VARIATION SELECTOR-3;Mn;0;NSM;;;;;N;;;;;
14265 FE03;VARIATION SELECTOR-4;Mn;0;NSM;;;;;N;;;;;
14266 FE04;VARIATION SELECTOR-5;Mn;0;NSM;;;;;N;;;;;
14267 FE05;VARIATION SELECTOR-6;Mn;0;NSM;;;;;N;;;;;
14268 FE06;VARIATION SELECTOR-7;Mn;0;NSM;;;;;N;;;;;
14269 FE07;VARIATION SELECTOR-8;Mn;0;NSM;;;;;N;;;;;
14270 FE08;VARIATION SELECTOR-9;Mn;0;NSM;;;;;N;;;;;
14271 FE09;VARIATION SELECTOR-10;Mn;0;NSM;;;;;N;;;;;
14272 FE0A;VARIATION SELECTOR-11;Mn;0;NSM;;;;;N;;;;;
14273 FE0B;VARIATION SELECTOR-12;Mn;0;NSM;;;;;N;;;;;
14274 FE0C;VARIATION SELECTOR-13;Mn;0;NSM;;;;;N;;;;;
14275 FE0D;VARIATION SELECTOR-14;Mn;0;NSM;;;;;N;;;;;
14276 FE0E;VARIATION SELECTOR-15;Mn;0;NSM;;;;;N;;;;;
14277 FE0F;VARIATION SELECTOR-16;Mn;0;NSM;;;;;N;;;;;
14278 FE10;PRESENTATION FORM FOR VERTICAL COMMA;Po;0;ON;<vertical> 002C;;;;N;;;;;
14279 FE11;PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA;Po;0;ON;<vertical> 3001;;;;N;;;;;
14280 FE12;PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP;Po;0;ON;<vertical> 3002;;;;N;;;;;
14281 FE13;PRESENTATION FORM FOR VERTICAL COLON;Po;0;ON;<vertical> 003A;;;;N;;;;;
14282 FE14;PRESENTATION FORM FOR VERTICAL SEMICOLON;Po;0;ON;<vertical> 003B;;;;N;;;;;
14283 FE15;PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK;Po;0;ON;<vertical> 0021;;;;N;;;;;
14284 FE16;PRESENTATION FORM FOR VERTICAL QUESTION MARK;Po;0;ON;<vertical> 003F;;;;N;;;;;
14285 FE17;PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET;Ps;0;ON;<vertical> 3016;;;;N;;;;;
14286 FE18;PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET;Pe;0;ON;<vertical> 3017;;;;N;;;;;
14287 FE19;PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS;Po;0;ON;<vertical> 2026;;;;N;;;;;
14288 FE20;COMBINING LIGATURE LEFT HALF;Mn;230;NSM;;;;;N;;;;;
14289 FE21;COMBINING LIGATURE RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
14290 FE22;COMBINING DOUBLE TILDE LEFT HALF;Mn;230;NSM;;;;;N;;;;;
14291 FE23;COMBINING DOUBLE TILDE RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
14292 FE24;COMBINING MACRON LEFT HALF;Mn;230;NSM;;;;;N;;;;;
14293 FE25;COMBINING MACRON RIGHT HALF;Mn;230;NSM;;;;;N;;;;;
14294 FE26;COMBINING CONJOINING MACRON;Mn;230;NSM;;;;;N;;;;;
14295 FE30;PRESENTATION FORM FOR VERTICAL TWO DOT LEADER;Po;0;ON;<vertical> 2025;;;;N;GLYPH FOR VERTICAL TWO DOT LEADER;;;;
14296 FE31;PRESENTATION FORM FOR VERTICAL EM DASH;Pd;0;ON;<vertical> 2014;;;;N;GLYPH FOR VERTICAL EM DASH;;;;
14297 FE32;PRESENTATION FORM FOR VERTICAL EN DASH;Pd;0;ON;<vertical> 2013;;;;N;GLYPH FOR VERTICAL EN DASH;;;;
14298 FE33;PRESENTATION FORM FOR VERTICAL LOW LINE;Pc;0;ON;<vertical> 005F;;;;N;GLYPH FOR VERTICAL SPACING UNDERSCORE;;;;
14299 FE34;PRESENTATION FORM FOR VERTICAL WAVY LOW LINE;Pc;0;ON;<vertical> 005F;;;;N;GLYPH FOR VERTICAL SPACING WAVY UNDERSCORE;;;;
14300 FE35;PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS;Ps;0;ON;<vertical> 0028;;;;N;GLYPH FOR VERTICAL OPENING PARENTHESIS;;;;
14301 FE36;PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS;Pe;0;ON;<vertical> 0029;;;;N;GLYPH FOR VERTICAL CLOSING PARENTHESIS;;;;
14302 FE37;PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET;Ps;0;ON;<vertical> 007B;;;;N;GLYPH FOR VERTICAL OPENING CURLY BRACKET;;;;
14303 FE38;PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET;Pe;0;ON;<vertical> 007D;;;;N;GLYPH FOR VERTICAL CLOSING CURLY BRACKET;;;;
14304 FE39;PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET;Ps;0;ON;<vertical> 3014;;;;N;GLYPH FOR VERTICAL OPENING TORTOISE SHELL BRACKET;;;;
14305 FE3A;PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;<vertical> 3015;;;;N;GLYPH FOR VERTICAL CLOSING TORTOISE SHELL BRACKET;;;;
14306 FE3B;PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;<vertical> 3010;;;;N;GLYPH FOR VERTICAL OPENING BLACK LENTICULAR BRACKET;;;;
14307 FE3C;PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;<vertical> 3011;;;;N;GLYPH FOR VERTICAL CLOSING BLACK LENTICULAR BRACKET;;;;
14308 FE3D;PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;<vertical> 300A;;;;N;GLYPH FOR VERTICAL OPENING DOUBLE ANGLE BRACKET;;;;
14309 FE3E;PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;<vertical> 300B;;;;N;GLYPH FOR VERTICAL CLOSING DOUBLE ANGLE BRACKET;;;;
14310 FE3F;PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET;Ps;0;ON;<vertical> 3008;;;;N;GLYPH FOR VERTICAL OPENING ANGLE BRACKET;;;;
14311 FE40;PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET;Pe;0;ON;<vertical> 3009;;;;N;GLYPH FOR VERTICAL CLOSING ANGLE BRACKET;;;;
14312 FE41;PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET;Ps;0;ON;<vertical> 300C;;;;N;GLYPH FOR VERTICAL OPENING CORNER BRACKET;;;;
14313 FE42;PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET;Pe;0;ON;<vertical> 300D;;;;N;GLYPH FOR VERTICAL CLOSING CORNER BRACKET;;;;
14314 FE43;PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET;Ps;0;ON;<vertical> 300E;;;;N;GLYPH FOR VERTICAL OPENING WHITE CORNER BRACKET;;;;
14315 FE44;PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET;Pe;0;ON;<vertical> 300F;;;;N;GLYPH FOR VERTICAL CLOSING WHITE CORNER BRACKET;;;;
14316 FE45;SESAME DOT;Po;0;ON;;;;;N;;;;;
14317 FE46;WHITE SESAME DOT;Po;0;ON;;;;;N;;;;;
14318 FE47;PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET;Ps;0;ON;<vertical> 005B;;;;N;;;;;
14319 FE48;PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET;Pe;0;ON;<vertical> 005D;;;;N;;;;;
14320 FE49;DASHED OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING DASHED OVERSCORE;;;;
14321 FE4A;CENTRELINE OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING CENTERLINE OVERSCORE;;;;
14322 FE4B;WAVY OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING WAVY OVERSCORE;;;;
14323 FE4C;DOUBLE WAVY OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING DOUBLE WAVY OVERSCORE;;;;
14324 FE4D;DASHED LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING DASHED UNDERSCORE;;;;
14325 FE4E;CENTRELINE LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING CENTERLINE UNDERSCORE;;;;
14326 FE4F;WAVY LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING WAVY UNDERSCORE;;;;
14327 FE50;SMALL COMMA;Po;0;CS;<small> 002C;;;;N;;;;;
14328 FE51;SMALL IDEOGRAPHIC COMMA;Po;0;ON;<small> 3001;;;;N;;;;;
14329 FE52;SMALL FULL STOP;Po;0;CS;<small> 002E;;;;N;SMALL PERIOD;;;;
14330 FE54;SMALL SEMICOLON;Po;0;ON;<small> 003B;;;;N;;;;;
14331 FE55;SMALL COLON;Po;0;CS;<small> 003A;;;;N;;;;;
14332 FE56;SMALL QUESTION MARK;Po;0;ON;<small> 003F;;;;N;;;;;
14333 FE57;SMALL EXCLAMATION MARK;Po;0;ON;<small> 0021;;;;N;;;;;
14334 FE58;SMALL EM DASH;Pd;0;ON;<small> 2014;;;;N;;;;;
14335 FE59;SMALL LEFT PARENTHESIS;Ps;0;ON;<small> 0028;;;;Y;SMALL OPENING PARENTHESIS;;;;
14336 FE5A;SMALL RIGHT PARENTHESIS;Pe;0;ON;<small> 0029;;;;Y;SMALL CLOSING PARENTHESIS;;;;
14337 FE5B;SMALL LEFT CURLY BRACKET;Ps;0;ON;<small> 007B;;;;Y;SMALL OPENING CURLY BRACKET;;;;
14338 FE5C;SMALL RIGHT CURLY BRACKET;Pe;0;ON;<small> 007D;;;;Y;SMALL CLOSING CURLY BRACKET;;;;
14339 FE5D;SMALL LEFT TORTOISE SHELL BRACKET;Ps;0;ON;<small> 3014;;;;Y;SMALL OPENING TORTOISE SHELL BRACKET;;;;
14340 FE5E;SMALL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;<small> 3015;;;;Y;SMALL CLOSING TORTOISE SHELL BRACKET;;;;
14341 FE5F;SMALL NUMBER SIGN;Po;0;ET;<small> 0023;;;;N;;;;;
14342 FE60;SMALL AMPERSAND;Po;0;ON;<small> 0026;;;;N;;;;;
14343 FE61;SMALL ASTERISK;Po;0;ON;<small> 002A;;;;N;;;;;
14344 FE62;SMALL PLUS SIGN;Sm;0;ES;<small> 002B;;;;N;;;;;
14345 FE63;SMALL HYPHEN-MINUS;Pd;0;ES;<small> 002D;;;;N;;;;;
14346 FE64;SMALL LESS-THAN SIGN;Sm;0;ON;<small> 003C;;;;Y;;;;;
14347 FE65;SMALL GREATER-THAN SIGN;Sm;0;ON;<small> 003E;;;;Y;;;;;
14348 FE66;SMALL EQUALS SIGN;Sm;0;ON;<small> 003D;;;;N;;;;;
14349 FE68;SMALL REVERSE SOLIDUS;Po;0;ON;<small> 005C;;;;N;SMALL BACKSLASH;;;;
14350 FE69;SMALL DOLLAR SIGN;Sc;0;ET;<small> 0024;;;;N;;;;;
14351 FE6A;SMALL PERCENT SIGN;Po;0;ET;<small> 0025;;;;N;;;;;
14352 FE6B;SMALL COMMERCIAL AT;Po;0;ON;<small> 0040;;;;N;;;;;
14353 FE70;ARABIC FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064B;;;;N;ARABIC SPACING FATHATAN;;;;
14354 FE71;ARABIC TATWEEL WITH FATHATAN ABOVE;Lo;0;AL;<medial> 0640 064B;;;;N;ARABIC FATHATAN ON TATWEEL;;;;
14355 FE72;ARABIC DAMMATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064C;;;;N;ARABIC SPACING DAMMATAN;;;;
14356 FE73;ARABIC TAIL FRAGMENT;Lo;0;AL;;;;;N;;;;;
14357 FE74;ARABIC KASRATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064D;;;;N;ARABIC SPACING KASRATAN;;;;
14358 FE76;ARABIC FATHA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064E;;;;N;ARABIC SPACING FATHAH;;;;
14359 FE77;ARABIC FATHA MEDIAL FORM;Lo;0;AL;<medial> 0640 064E;;;;N;ARABIC FATHAH ON TATWEEL;;;;
14360 FE78;ARABIC DAMMA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064F;;;;N;ARABIC SPACING DAMMAH;;;;
14361 FE79;ARABIC DAMMA MEDIAL FORM;Lo;0;AL;<medial> 0640 064F;;;;N;ARABIC DAMMAH ON TATWEEL;;;;
14362 FE7A;ARABIC KASRA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0650;;;;N;ARABIC SPACING KASRAH;;;;
14363 FE7B;ARABIC KASRA MEDIAL FORM;Lo;0;AL;<medial> 0640 0650;;;;N;ARABIC KASRAH ON TATWEEL;;;;
14364 FE7C;ARABIC SHADDA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0651;;;;N;ARABIC SPACING SHADDAH;;;;
14365 FE7D;ARABIC SHADDA MEDIAL FORM;Lo;0;AL;<medial> 0640 0651;;;;N;ARABIC SHADDAH ON TATWEEL;;;;
14366 FE7E;ARABIC SUKUN ISOLATED FORM;Lo;0;AL;<isolated> 0020 0652;;;;N;ARABIC SPACING SUKUN;;;;
14367 FE7F;ARABIC SUKUN MEDIAL FORM;Lo;0;AL;<medial> 0640 0652;;;;N;ARABIC SUKUN ON TATWEEL;;;;
14368 FE80;ARABIC LETTER HAMZA ISOLATED FORM;Lo;0;AL;<isolated> 0621;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH;;;;
14369 FE81;ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON ALEF;;;;
14370 FE82;ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL;<final> 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON ALEF;;;;
14371 FE83;ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON ALEF;;;;
14372 FE84;ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON ALEF;;;;
14373 FE85;ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0624;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON WAW;;;;
14374 FE86;ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0624;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON WAW;;;;
14375 FE87;ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL;<isolated> 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER ALEF;;;;
14376 FE88;ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL;<final> 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER ALEF;;;;
14377 FE89;ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0626;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON YA;;;;
14378 FE8A;ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0626;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON YA;;;;
14379 FE8B;ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM;Lo;0;AL;<initial> 0626;;;;N;GLYPH FOR INITIAL ARABIC HAMZAH ON YA;;;;
14380 FE8C;ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM;Lo;0;AL;<medial> 0626;;;;N;GLYPH FOR MEDIAL ARABIC HAMZAH ON YA;;;;
14381 FE8D;ARABIC LETTER ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0627;;;;N;GLYPH FOR ISOLATE ARABIC ALEF;;;;
14382 FE8E;ARABIC LETTER ALEF FINAL FORM;Lo;0;AL;<final> 0627;;;;N;GLYPH FOR FINAL ARABIC ALEF;;;;
14383 FE8F;ARABIC LETTER BEH ISOLATED FORM;Lo;0;AL;<isolated> 0628;;;;N;GLYPH FOR ISOLATE ARABIC BAA;;;;
14384 FE90;ARABIC LETTER BEH FINAL FORM;Lo;0;AL;<final> 0628;;;;N;GLYPH FOR FINAL ARABIC BAA;;;;
14385 FE91;ARABIC LETTER BEH INITIAL FORM;Lo;0;AL;<initial> 0628;;;;N;GLYPH FOR INITIAL ARABIC BAA;;;;
14386 FE92;ARABIC LETTER BEH MEDIAL FORM;Lo;0;AL;<medial> 0628;;;;N;GLYPH FOR MEDIAL ARABIC BAA;;;;
14387 FE93;ARABIC LETTER TEH MARBUTA ISOLATED FORM;Lo;0;AL;<isolated> 0629;;;;N;GLYPH FOR ISOLATE ARABIC TAA MARBUTAH;;;;
14388 FE94;ARABIC LETTER TEH MARBUTA FINAL FORM;Lo;0;AL;<final> 0629;;;;N;GLYPH FOR FINAL ARABIC TAA MARBUTAH;;;;
14389 FE95;ARABIC LETTER TEH ISOLATED FORM;Lo;0;AL;<isolated> 062A;;;;N;GLYPH FOR ISOLATE ARABIC TAA;;;;
14390 FE96;ARABIC LETTER TEH FINAL FORM;Lo;0;AL;<final> 062A;;;;N;GLYPH FOR FINAL ARABIC TAA;;;;
14391 FE97;ARABIC LETTER TEH INITIAL FORM;Lo;0;AL;<initial> 062A;;;;N;GLYPH FOR INITIAL ARABIC TAA;;;;
14392 FE98;ARABIC LETTER TEH MEDIAL FORM;Lo;0;AL;<medial> 062A;;;;N;GLYPH FOR MEDIAL ARABIC TAA;;;;
14393 FE99;ARABIC LETTER THEH ISOLATED FORM;Lo;0;AL;<isolated> 062B;;;;N;GLYPH FOR ISOLATE ARABIC THAA;;;;
14394 FE9A;ARABIC LETTER THEH FINAL FORM;Lo;0;AL;<final> 062B;;;;N;GLYPH FOR FINAL ARABIC THAA;;;;
14395 FE9B;ARABIC LETTER THEH INITIAL FORM;Lo;0;AL;<initial> 062B;;;;N;GLYPH FOR INITIAL ARABIC THAA;;;;
14396 FE9C;ARABIC LETTER THEH MEDIAL FORM;Lo;0;AL;<medial> 062B;;;;N;GLYPH FOR MEDIAL ARABIC THAA;;;;
14397 FE9D;ARABIC LETTER JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062C;;;;N;GLYPH FOR ISOLATE ARABIC JEEM;;;;
14398 FE9E;ARABIC LETTER JEEM FINAL FORM;Lo;0;AL;<final> 062C;;;;N;GLYPH FOR FINAL ARABIC JEEM;;;;
14399 FE9F;ARABIC LETTER JEEM INITIAL FORM;Lo;0;AL;<initial> 062C;;;;N;GLYPH FOR INITIAL ARABIC JEEM;;;;
14400 FEA0;ARABIC LETTER JEEM MEDIAL FORM;Lo;0;AL;<medial> 062C;;;;N;GLYPH FOR MEDIAL ARABIC JEEM;;;;
14401 FEA1;ARABIC LETTER HAH ISOLATED FORM;Lo;0;AL;<isolated> 062D;;;;N;GLYPH FOR ISOLATE ARABIC HAA;;;;
14402 FEA2;ARABIC LETTER HAH FINAL FORM;Lo;0;AL;<final> 062D;;;;N;GLYPH FOR FINAL ARABIC HAA;;;;
14403 FEA3;ARABIC LETTER HAH INITIAL FORM;Lo;0;AL;<initial> 062D;;;;N;GLYPH FOR INITIAL ARABIC HAA;;;;
14404 FEA4;ARABIC LETTER HAH MEDIAL FORM;Lo;0;AL;<medial> 062D;;;;N;GLYPH FOR MEDIAL ARABIC HAA;;;;
14405 FEA5;ARABIC LETTER KHAH ISOLATED FORM;Lo;0;AL;<isolated> 062E;;;;N;GLYPH FOR ISOLATE ARABIC KHAA;;;;
14406 FEA6;ARABIC LETTER KHAH FINAL FORM;Lo;0;AL;<final> 062E;;;;N;GLYPH FOR FINAL ARABIC KHAA;;;;
14407 FEA7;ARABIC LETTER KHAH INITIAL FORM;Lo;0;AL;<initial> 062E;;;;N;GLYPH FOR INITIAL ARABIC KHAA;;;;
14408 FEA8;ARABIC LETTER KHAH MEDIAL FORM;Lo;0;AL;<medial> 062E;;;;N;GLYPH FOR MEDIAL ARABIC KHAA;;;;
14409 FEA9;ARABIC LETTER DAL ISOLATED FORM;Lo;0;AL;<isolated> 062F;;;;N;GLYPH FOR ISOLATE ARABIC DAL;;;;
14410 FEAA;ARABIC LETTER DAL FINAL FORM;Lo;0;AL;<final> 062F;;;;N;GLYPH FOR FINAL ARABIC DAL;;;;
14411 FEAB;ARABIC LETTER THAL ISOLATED FORM;Lo;0;AL;<isolated> 0630;;;;N;GLYPH FOR ISOLATE ARABIC THAL;;;;
14412 FEAC;ARABIC LETTER THAL FINAL FORM;Lo;0;AL;<final> 0630;;;;N;GLYPH FOR FINAL ARABIC THAL;;;;
14413 FEAD;ARABIC LETTER REH ISOLATED FORM;Lo;0;AL;<isolated> 0631;;;;N;GLYPH FOR ISOLATE ARABIC RA;;;;
14414 FEAE;ARABIC LETTER REH FINAL FORM;Lo;0;AL;<final> 0631;;;;N;GLYPH FOR FINAL ARABIC RA;;;;
14415 FEAF;ARABIC LETTER ZAIN ISOLATED FORM;Lo;0;AL;<isolated> 0632;;;;N;GLYPH FOR ISOLATE ARABIC ZAIN;;;;
14416 FEB0;ARABIC LETTER ZAIN FINAL FORM;Lo;0;AL;<final> 0632;;;;N;GLYPH FOR FINAL ARABIC ZAIN;;;;
14417 FEB1;ARABIC LETTER SEEN ISOLATED FORM;Lo;0;AL;<isolated> 0633;;;;N;GLYPH FOR ISOLATE ARABIC SEEN;;;;
14418 FEB2;ARABIC LETTER SEEN FINAL FORM;Lo;0;AL;<final> 0633;;;;N;GLYPH FOR FINAL ARABIC SEEN;;;;
14419 FEB3;ARABIC LETTER SEEN INITIAL FORM;Lo;0;AL;<initial> 0633;;;;N;GLYPH FOR INITIAL ARABIC SEEN;;;;
14420 FEB4;ARABIC LETTER SEEN MEDIAL FORM;Lo;0;AL;<medial> 0633;;;;N;GLYPH FOR MEDIAL ARABIC SEEN;;;;
14421 FEB5;ARABIC LETTER SHEEN ISOLATED FORM;Lo;0;AL;<isolated> 0634;;;;N;GLYPH FOR ISOLATE ARABIC SHEEN;;;;
14422 FEB6;ARABIC LETTER SHEEN FINAL FORM;Lo;0;AL;<final> 0634;;;;N;GLYPH FOR FINAL ARABIC SHEEN;;;;
14423 FEB7;ARABIC LETTER SHEEN INITIAL FORM;Lo;0;AL;<initial> 0634;;;;N;GLYPH FOR INITIAL ARABIC SHEEN;;;;
14424 FEB8;ARABIC LETTER SHEEN MEDIAL FORM;Lo;0;AL;<medial> 0634;;;;N;GLYPH FOR MEDIAL ARABIC SHEEN;;;;
14425 FEB9;ARABIC LETTER SAD ISOLATED FORM;Lo;0;AL;<isolated> 0635;;;;N;GLYPH FOR ISOLATE ARABIC SAD;;;;
14426 FEBA;ARABIC LETTER SAD FINAL FORM;Lo;0;AL;<final> 0635;;;;N;GLYPH FOR FINAL ARABIC SAD;;;;
14427 FEBB;ARABIC LETTER SAD INITIAL FORM;Lo;0;AL;<initial> 0635;;;;N;GLYPH FOR INITIAL ARABIC SAD;;;;
14428 FEBC;ARABIC LETTER SAD MEDIAL FORM;Lo;0;AL;<medial> 0635;;;;N;GLYPH FOR MEDIAL ARABIC SAD;;;;
14429 FEBD;ARABIC LETTER DAD ISOLATED FORM;Lo;0;AL;<isolated> 0636;;;;N;GLYPH FOR ISOLATE ARABIC DAD;;;;
14430 FEBE;ARABIC LETTER DAD FINAL FORM;Lo;0;AL;<final> 0636;;;;N;GLYPH FOR FINAL ARABIC DAD;;;;
14431 FEBF;ARABIC LETTER DAD INITIAL FORM;Lo;0;AL;<initial> 0636;;;;N;GLYPH FOR INITIAL ARABIC DAD;;;;
14432 FEC0;ARABIC LETTER DAD MEDIAL FORM;Lo;0;AL;<medial> 0636;;;;N;GLYPH FOR MEDIAL ARABIC DAD;;;;
14433 FEC1;ARABIC LETTER TAH ISOLATED FORM;Lo;0;AL;<isolated> 0637;;;;N;GLYPH FOR ISOLATE ARABIC TAH;;;;
14434 FEC2;ARABIC LETTER TAH FINAL FORM;Lo;0;AL;<final> 0637;;;;N;GLYPH FOR FINAL ARABIC TAH;;;;
14435 FEC3;ARABIC LETTER TAH INITIAL FORM;Lo;0;AL;<initial> 0637;;;;N;GLYPH FOR INITIAL ARABIC TAH;;;;
14436 FEC4;ARABIC LETTER TAH MEDIAL FORM;Lo;0;AL;<medial> 0637;;;;N;GLYPH FOR MEDIAL ARABIC TAH;;;;
14437 FEC5;ARABIC LETTER ZAH ISOLATED FORM;Lo;0;AL;<isolated> 0638;;;;N;GLYPH FOR ISOLATE ARABIC DHAH;;;;
14438 FEC6;ARABIC LETTER ZAH FINAL FORM;Lo;0;AL;<final> 0638;;;;N;GLYPH FOR FINAL ARABIC DHAH;;;;
14439 FEC7;ARABIC LETTER ZAH INITIAL FORM;Lo;0;AL;<initial> 0638;;;;N;GLYPH FOR INITIAL ARABIC DHAH;;;;
14440 FEC8;ARABIC LETTER ZAH MEDIAL FORM;Lo;0;AL;<medial> 0638;;;;N;GLYPH FOR MEDIAL ARABIC DHAH;;;;
14441 FEC9;ARABIC LETTER AIN ISOLATED FORM;Lo;0;AL;<isolated> 0639;;;;N;GLYPH FOR ISOLATE ARABIC AIN;;;;
14442 FECA;ARABIC LETTER AIN FINAL FORM;Lo;0;AL;<final> 0639;;;;N;GLYPH FOR FINAL ARABIC AIN;;;;
14443 FECB;ARABIC LETTER AIN INITIAL FORM;Lo;0;AL;<initial> 0639;;;;N;GLYPH FOR INITIAL ARABIC AIN;;;;
14444 FECC;ARABIC LETTER AIN MEDIAL FORM;Lo;0;AL;<medial> 0639;;;;N;GLYPH FOR MEDIAL ARABIC AIN;;;;
14445 FECD;ARABIC LETTER GHAIN ISOLATED FORM;Lo;0;AL;<isolated> 063A;;;;N;GLYPH FOR ISOLATE ARABIC GHAIN;;;;
14446 FECE;ARABIC LETTER GHAIN FINAL FORM;Lo;0;AL;<final> 063A;;;;N;GLYPH FOR FINAL ARABIC GHAIN;;;;
14447 FECF;ARABIC LETTER GHAIN INITIAL FORM;Lo;0;AL;<initial> 063A;;;;N;GLYPH FOR INITIAL ARABIC GHAIN;;;;
14448 FED0;ARABIC LETTER GHAIN MEDIAL FORM;Lo;0;AL;<medial> 063A;;;;N;GLYPH FOR MEDIAL ARABIC GHAIN;;;;
14449 FED1;ARABIC LETTER FEH ISOLATED FORM;Lo;0;AL;<isolated> 0641;;;;N;GLYPH FOR ISOLATE ARABIC FA;;;;
14450 FED2;ARABIC LETTER FEH FINAL FORM;Lo;0;AL;<final> 0641;;;;N;GLYPH FOR FINAL ARABIC FA;;;;
14451 FED3;ARABIC LETTER FEH INITIAL FORM;Lo;0;AL;<initial> 0641;;;;N;GLYPH FOR INITIAL ARABIC FA;;;;
14452 FED4;ARABIC LETTER FEH MEDIAL FORM;Lo;0;AL;<medial> 0641;;;;N;GLYPH FOR MEDIAL ARABIC FA;;;;
14453 FED5;ARABIC LETTER QAF ISOLATED FORM;Lo;0;AL;<isolated> 0642;;;;N;GLYPH FOR ISOLATE ARABIC QAF;;;;
14454 FED6;ARABIC LETTER QAF FINAL FORM;Lo;0;AL;<final> 0642;;;;N;GLYPH FOR FINAL ARABIC QAF;;;;
14455 FED7;ARABIC LETTER QAF INITIAL FORM;Lo;0;AL;<initial> 0642;;;;N;GLYPH FOR INITIAL ARABIC QAF;;;;
14456 FED8;ARABIC LETTER QAF MEDIAL FORM;Lo;0;AL;<medial> 0642;;;;N;GLYPH FOR MEDIAL ARABIC QAF;;;;
14457 FED9;ARABIC LETTER KAF ISOLATED FORM;Lo;0;AL;<isolated> 0643;;;;N;GLYPH FOR ISOLATE ARABIC CAF;;;;
14458 FEDA;ARABIC LETTER KAF FINAL FORM;Lo;0;AL;<final> 0643;;;;N;GLYPH FOR FINAL ARABIC CAF;;;;
14459 FEDB;ARABIC LETTER KAF INITIAL FORM;Lo;0;AL;<initial> 0643;;;;N;GLYPH FOR INITIAL ARABIC CAF;;;;
14460 FEDC;ARABIC LETTER KAF MEDIAL FORM;Lo;0;AL;<medial> 0643;;;;N;GLYPH FOR MEDIAL ARABIC CAF;;;;
14461 FEDD;ARABIC LETTER LAM ISOLATED FORM;Lo;0;AL;<isolated> 0644;;;;N;GLYPH FOR ISOLATE ARABIC LAM;;;;
14462 FEDE;ARABIC LETTER LAM FINAL FORM;Lo;0;AL;<final> 0644;;;;N;GLYPH FOR FINAL ARABIC LAM;;;;
14463 FEDF;ARABIC LETTER LAM INITIAL FORM;Lo;0;AL;<initial> 0644;;;;N;GLYPH FOR INITIAL ARABIC LAM;;;;
14464 FEE0;ARABIC LETTER LAM MEDIAL FORM;Lo;0;AL;<medial> 0644;;;;N;GLYPH FOR MEDIAL ARABIC LAM;;;;
14465 FEE1;ARABIC LETTER MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645;;;;N;GLYPH FOR ISOLATE ARABIC MEEM;;;;
14466 FEE2;ARABIC LETTER MEEM FINAL FORM;Lo;0;AL;<final> 0645;;;;N;GLYPH FOR FINAL ARABIC MEEM;;;;
14467 FEE3;ARABIC LETTER MEEM INITIAL FORM;Lo;0;AL;<initial> 0645;;;;N;GLYPH FOR INITIAL ARABIC MEEM;;;;
14468 FEE4;ARABIC LETTER MEEM MEDIAL FORM;Lo;0;AL;<medial> 0645;;;;N;GLYPH FOR MEDIAL ARABIC MEEM;;;;
14469 FEE5;ARABIC LETTER NOON ISOLATED FORM;Lo;0;AL;<isolated> 0646;;;;N;GLYPH FOR ISOLATE ARABIC NOON;;;;
14470 FEE6;ARABIC LETTER NOON FINAL FORM;Lo;0;AL;<final> 0646;;;;N;GLYPH FOR FINAL ARABIC NOON;;;;
14471 FEE7;ARABIC LETTER NOON INITIAL FORM;Lo;0;AL;<initial> 0646;;;;N;GLYPH FOR INITIAL ARABIC NOON;;;;
14472 FEE8;ARABIC LETTER NOON MEDIAL FORM;Lo;0;AL;<medial> 0646;;;;N;GLYPH FOR MEDIAL ARABIC NOON;;;;
14473 FEE9;ARABIC LETTER HEH ISOLATED FORM;Lo;0;AL;<isolated> 0647;;;;N;GLYPH FOR ISOLATE ARABIC HA;;;;
14474 FEEA;ARABIC LETTER HEH FINAL FORM;Lo;0;AL;<final> 0647;;;;N;GLYPH FOR FINAL ARABIC HA;;;;
14475 FEEB;ARABIC LETTER HEH INITIAL FORM;Lo;0;AL;<initial> 0647;;;;N;GLYPH FOR INITIAL ARABIC HA;;;;
14476 FEEC;ARABIC LETTER HEH MEDIAL FORM;Lo;0;AL;<medial> 0647;;;;N;GLYPH FOR MEDIAL ARABIC HA;;;;
14477 FEED;ARABIC LETTER WAW ISOLATED FORM;Lo;0;AL;<isolated> 0648;;;;N;GLYPH FOR ISOLATE ARABIC WAW;;;;
14478 FEEE;ARABIC LETTER WAW FINAL FORM;Lo;0;AL;<final> 0648;;;;N;GLYPH FOR FINAL ARABIC WAW;;;;
14479 FEEF;ARABIC LETTER ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0649;;;;N;GLYPH FOR ISOLATE ARABIC ALEF MAQSURAH;;;;
14480 FEF0;ARABIC LETTER ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0649;;;;N;GLYPH FOR FINAL ARABIC ALEF MAQSURAH;;;;
14481 FEF1;ARABIC LETTER YEH ISOLATED FORM;Lo;0;AL;<isolated> 064A;;;;N;GLYPH FOR ISOLATE ARABIC YA;;;;
14482 FEF2;ARABIC LETTER YEH FINAL FORM;Lo;0;AL;<final> 064A;;;;N;GLYPH FOR FINAL ARABIC YA;;;;
14483 FEF3;ARABIC LETTER YEH INITIAL FORM;Lo;0;AL;<initial> 064A;;;;N;GLYPH FOR INITIAL ARABIC YA;;;;
14484 FEF4;ARABIC LETTER YEH MEDIAL FORM;Lo;0;AL;<medial> 064A;;;;N;GLYPH FOR MEDIAL ARABIC YA;;;;
14485 FEF5;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0644 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON LIGATURE LAM ALEF;;;;
14486 FEF6;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL;<final> 0644 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON LIGATURE LAM ALEF;;;;
14487 FEF7;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0644 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON LIGATURE LAM ALEF;;;;
14488 FEF8;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0644 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON LIGATURE LAM ALEF;;;;
14489 FEF9;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL;<isolated> 0644 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;;
14490 FEFA;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL;<final> 0644 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;;
14491 FEFB;ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0644 0627;;;;N;GLYPH FOR ISOLATE ARABIC LIGATURE LAM ALEF;;;;
14492 FEFC;ARABIC LIGATURE LAM WITH ALEF FINAL FORM;Lo;0;AL;<final> 0644 0627;;;;N;GLYPH FOR FINAL ARABIC LIGATURE LAM ALEF;;;;
14493 FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;;
14494 FF01;FULLWIDTH EXCLAMATION MARK;Po;0;ON;<wide> 0021;;;;N;;;;;
14495 FF02;FULLWIDTH QUOTATION MARK;Po;0;ON;<wide> 0022;;;;N;;;;;
14496 FF03;FULLWIDTH NUMBER SIGN;Po;0;ET;<wide> 0023;;;;N;;;;;
14497 FF04;FULLWIDTH DOLLAR SIGN;Sc;0;ET;<wide> 0024;;;;N;;;;;
14498 FF05;FULLWIDTH PERCENT SIGN;Po;0;ET;<wide> 0025;;;;N;;;;;
14499 FF06;FULLWIDTH AMPERSAND;Po;0;ON;<wide> 0026;;;;N;;;;;
14500 FF07;FULLWIDTH APOSTROPHE;Po;0;ON;<wide> 0027;;;;N;;;;;
14501 FF08;FULLWIDTH LEFT PARENTHESIS;Ps;0;ON;<wide> 0028;;;;Y;FULLWIDTH OPENING PARENTHESIS;;;;
14502 FF09;FULLWIDTH RIGHT PARENTHESIS;Pe;0;ON;<wide> 0029;;;;Y;FULLWIDTH CLOSING PARENTHESIS;;;;
14503 FF0A;FULLWIDTH ASTERISK;Po;0;ON;<wide> 002A;;;;N;;;;;
14504 FF0B;FULLWIDTH PLUS SIGN;Sm;0;ES;<wide> 002B;;;;N;;;;;
14505 FF0C;FULLWIDTH COMMA;Po;0;CS;<wide> 002C;;;;N;;;;;
14506 FF0D;FULLWIDTH HYPHEN-MINUS;Pd;0;ES;<wide> 002D;;;;N;;;;;
14507 FF0E;FULLWIDTH FULL STOP;Po;0;CS;<wide> 002E;;;;N;FULLWIDTH PERIOD;;;;
14508 FF0F;FULLWIDTH SOLIDUS;Po;0;CS;<wide> 002F;;;;N;FULLWIDTH SLASH;;;;
14509 FF10;FULLWIDTH DIGIT ZERO;Nd;0;EN;<wide> 0030;0;0;0;N;;;;;
14510 FF11;FULLWIDTH DIGIT ONE;Nd;0;EN;<wide> 0031;1;1;1;N;;;;;
14511 FF12;FULLWIDTH DIGIT TWO;Nd;0;EN;<wide> 0032;2;2;2;N;;;;;
14512 FF13;FULLWIDTH DIGIT THREE;Nd;0;EN;<wide> 0033;3;3;3;N;;;;;
14513 FF14;FULLWIDTH DIGIT FOUR;Nd;0;EN;<wide> 0034;4;4;4;N;;;;;
14514 FF15;FULLWIDTH DIGIT FIVE;Nd;0;EN;<wide> 0035;5;5;5;N;;;;;
14515 FF16;FULLWIDTH DIGIT SIX;Nd;0;EN;<wide> 0036;6;6;6;N;;;;;
14516 FF17;FULLWIDTH DIGIT SEVEN;Nd;0;EN;<wide> 0037;7;7;7;N;;;;;
14517 FF18;FULLWIDTH DIGIT EIGHT;Nd;0;EN;<wide> 0038;8;8;8;N;;;;;
14518 FF19;FULLWIDTH DIGIT NINE;Nd;0;EN;<wide> 0039;9;9;9;N;;;;;
14519 FF1A;FULLWIDTH COLON;Po;0;CS;<wide> 003A;;;;N;;;;;
14520 FF1B;FULLWIDTH SEMICOLON;Po;0;ON;<wide> 003B;;;;N;;;;;
14521 FF1C;FULLWIDTH LESS-THAN SIGN;Sm;0;ON;<wide> 003C;;;;Y;;;;;
14522 FF1D;FULLWIDTH EQUALS SIGN;Sm;0;ON;<wide> 003D;;;;N;;;;;
14523 FF1E;FULLWIDTH GREATER-THAN SIGN;Sm;0;ON;<wide> 003E;;;;Y;;;;;
14524 FF1F;FULLWIDTH QUESTION MARK;Po;0;ON;<wide> 003F;;;;N;;;;;
14525 FF20;FULLWIDTH COMMERCIAL AT;Po;0;ON;<wide> 0040;;;;N;;;;;
14526 FF21;FULLWIDTH LATIN CAPITAL LETTER A;Lu;0;L;<wide> 0041;;;;N;;;;FF41;
14527 FF22;FULLWIDTH LATIN CAPITAL LETTER B;Lu;0;L;<wide> 0042;;;;N;;;;FF42;
14528 FF23;FULLWIDTH LATIN CAPITAL LETTER C;Lu;0;L;<wide> 0043;;;;N;;;;FF43;
14529 FF24;FULLWIDTH LATIN CAPITAL LETTER D;Lu;0;L;<wide> 0044;;;;N;;;;FF44;
14530 FF25;FULLWIDTH LATIN CAPITAL LETTER E;Lu;0;L;<wide> 0045;;;;N;;;;FF45;
14531 FF26;FULLWIDTH LATIN CAPITAL LETTER F;Lu;0;L;<wide> 0046;;;;N;;;;FF46;
14532 FF27;FULLWIDTH LATIN CAPITAL LETTER G;Lu;0;L;<wide> 0047;;;;N;;;;FF47;
14533 FF28;FULLWIDTH LATIN CAPITAL LETTER H;Lu;0;L;<wide> 0048;;;;N;;;;FF48;
14534 FF29;FULLWIDTH LATIN CAPITAL LETTER I;Lu;0;L;<wide> 0049;;;;N;;;;FF49;
14535 FF2A;FULLWIDTH LATIN CAPITAL LETTER J;Lu;0;L;<wide> 004A;;;;N;;;;FF4A;
14536 FF2B;FULLWIDTH LATIN CAPITAL LETTER K;Lu;0;L;<wide> 004B;;;;N;;;;FF4B;
14537 FF2C;FULLWIDTH LATIN CAPITAL LETTER L;Lu;0;L;<wide> 004C;;;;N;;;;FF4C;
14538 FF2D;FULLWIDTH LATIN CAPITAL LETTER M;Lu;0;L;<wide> 004D;;;;N;;;;FF4D;
14539 FF2E;FULLWIDTH LATIN CAPITAL LETTER N;Lu;0;L;<wide> 004E;;;;N;;;;FF4E;
14540 FF2F;FULLWIDTH LATIN CAPITAL LETTER O;Lu;0;L;<wide> 004F;;;;N;;;;FF4F;
14541 FF30;FULLWIDTH LATIN CAPITAL LETTER P;Lu;0;L;<wide> 0050;;;;N;;;;FF50;
14542 FF31;FULLWIDTH LATIN CAPITAL LETTER Q;Lu;0;L;<wide> 0051;;;;N;;;;FF51;
14543 FF32;FULLWIDTH LATIN CAPITAL LETTER R;Lu;0;L;<wide> 0052;;;;N;;;;FF52;
14544 FF33;FULLWIDTH LATIN CAPITAL LETTER S;Lu;0;L;<wide> 0053;;;;N;;;;FF53;
14545 FF34;FULLWIDTH LATIN CAPITAL LETTER T;Lu;0;L;<wide> 0054;;;;N;;;;FF54;
14546 FF35;FULLWIDTH LATIN CAPITAL LETTER U;Lu;0;L;<wide> 0055;;;;N;;;;FF55;
14547 FF36;FULLWIDTH LATIN CAPITAL LETTER V;Lu;0;L;<wide> 0056;;;;N;;;;FF56;
14548 FF37;FULLWIDTH LATIN CAPITAL LETTER W;Lu;0;L;<wide> 0057;;;;N;;;;FF57;
14549 FF38;FULLWIDTH LATIN CAPITAL LETTER X;Lu;0;L;<wide> 0058;;;;N;;;;FF58;
14550 FF39;FULLWIDTH LATIN CAPITAL LETTER Y;Lu;0;L;<wide> 0059;;;;N;;;;FF59;
14551 FF3A;FULLWIDTH LATIN CAPITAL LETTER Z;Lu;0;L;<wide> 005A;;;;N;;;;FF5A;
14552 FF3B;FULLWIDTH LEFT SQUARE BRACKET;Ps;0;ON;<wide> 005B;;;;Y;FULLWIDTH OPENING SQUARE BRACKET;;;;
14553 FF3C;FULLWIDTH REVERSE SOLIDUS;Po;0;ON;<wide> 005C;;;;N;FULLWIDTH BACKSLASH;;;;
14554 FF3D;FULLWIDTH RIGHT SQUARE BRACKET;Pe;0;ON;<wide> 005D;;;;Y;FULLWIDTH CLOSING SQUARE BRACKET;;;;
14555 FF3E;FULLWIDTH CIRCUMFLEX ACCENT;Sk;0;ON;<wide> 005E;;;;N;FULLWIDTH SPACING CIRCUMFLEX;;;;
14556 FF3F;FULLWIDTH LOW LINE;Pc;0;ON;<wide> 005F;;;;N;FULLWIDTH SPACING UNDERSCORE;;;;
14557 FF40;FULLWIDTH GRAVE ACCENT;Sk;0;ON;<wide> 0060;;;;N;FULLWIDTH SPACING GRAVE;;;;
14558 FF41;FULLWIDTH LATIN SMALL LETTER A;Ll;0;L;<wide> 0061;;;;N;;;FF21;;FF21
14559 FF42;FULLWIDTH LATIN SMALL LETTER B;Ll;0;L;<wide> 0062;;;;N;;;FF22;;FF22
14560 FF43;FULLWIDTH LATIN SMALL LETTER C;Ll;0;L;<wide> 0063;;;;N;;;FF23;;FF23
14561 FF44;FULLWIDTH LATIN SMALL LETTER D;Ll;0;L;<wide> 0064;;;;N;;;FF24;;FF24
14562 FF45;FULLWIDTH LATIN SMALL LETTER E;Ll;0;L;<wide> 0065;;;;N;;;FF25;;FF25
14563 FF46;FULLWIDTH LATIN SMALL LETTER F;Ll;0;L;<wide> 0066;;;;N;;;FF26;;FF26
14564 FF47;FULLWIDTH LATIN SMALL LETTER G;Ll;0;L;<wide> 0067;;;;N;;;FF27;;FF27
14565 FF48;FULLWIDTH LATIN SMALL LETTER H;Ll;0;L;<wide> 0068;;;;N;;;FF28;;FF28
14566 FF49;FULLWIDTH LATIN SMALL LETTER I;Ll;0;L;<wide> 0069;;;;N;;;FF29;;FF29
14567 FF4A;FULLWIDTH LATIN SMALL LETTER J;Ll;0;L;<wide> 006A;;;;N;;;FF2A;;FF2A
14568 FF4B;FULLWIDTH LATIN SMALL LETTER K;Ll;0;L;<wide> 006B;;;;N;;;FF2B;;FF2B
14569 FF4C;FULLWIDTH LATIN SMALL LETTER L;Ll;0;L;<wide> 006C;;;;N;;;FF2C;;FF2C
14570 FF4D;FULLWIDTH LATIN SMALL LETTER M;Ll;0;L;<wide> 006D;;;;N;;;FF2D;;FF2D
14571 FF4E;FULLWIDTH LATIN SMALL LETTER N;Ll;0;L;<wide> 006E;;;;N;;;FF2E;;FF2E
14572 FF4F;FULLWIDTH LATIN SMALL LETTER O;Ll;0;L;<wide> 006F;;;;N;;;FF2F;;FF2F
14573 FF50;FULLWIDTH LATIN SMALL LETTER P;Ll;0;L;<wide> 0070;;;;N;;;FF30;;FF30
14574 FF51;FULLWIDTH LATIN SMALL LETTER Q;Ll;0;L;<wide> 0071;;;;N;;;FF31;;FF31
14575 FF52;FULLWIDTH LATIN SMALL LETTER R;Ll;0;L;<wide> 0072;;;;N;;;FF32;;FF32
14576 FF53;FULLWIDTH LATIN SMALL LETTER S;Ll;0;L;<wide> 0073;;;;N;;;FF33;;FF33
14577 FF54;FULLWIDTH LATIN SMALL LETTER T;Ll;0;L;<wide> 0074;;;;N;;;FF34;;FF34
14578 FF55;FULLWIDTH LATIN SMALL LETTER U;Ll;0;L;<wide> 0075;;;;N;;;FF35;;FF35
14579 FF56;FULLWIDTH LATIN SMALL LETTER V;Ll;0;L;<wide> 0076;;;;N;;;FF36;;FF36
14580 FF57;FULLWIDTH LATIN SMALL LETTER W;Ll;0;L;<wide> 0077;;;;N;;;FF37;;FF37
14581 FF58;FULLWIDTH LATIN SMALL LETTER X;Ll;0;L;<wide> 0078;;;;N;;;FF38;;FF38
14582 FF59;FULLWIDTH LATIN SMALL LETTER Y;Ll;0;L;<wide> 0079;;;;N;;;FF39;;FF39
14583 FF5A;FULLWIDTH LATIN SMALL LETTER Z;Ll;0;L;<wide> 007A;;;;N;;;FF3A;;FF3A
14584 FF5B;FULLWIDTH LEFT CURLY BRACKET;Ps;0;ON;<wide> 007B;;;;Y;FULLWIDTH OPENING CURLY BRACKET;;;;
14585 FF5C;FULLWIDTH VERTICAL LINE;Sm;0;ON;<wide> 007C;;;;N;FULLWIDTH VERTICAL BAR;;;;
14586 FF5D;FULLWIDTH RIGHT CURLY BRACKET;Pe;0;ON;<wide> 007D;;;;Y;FULLWIDTH CLOSING CURLY BRACKET;;;;
14587 FF5E;FULLWIDTH TILDE;Sm;0;ON;<wide> 007E;;;;N;FULLWIDTH SPACING TILDE;;;;
14588 FF5F;FULLWIDTH LEFT WHITE PARENTHESIS;Ps;0;ON;<wide> 2985;;;;Y;;*;;;
14589 FF60;FULLWIDTH RIGHT WHITE PARENTHESIS;Pe;0;ON;<wide> 2986;;;;Y;;*;;;
14590 FF61;HALFWIDTH IDEOGRAPHIC FULL STOP;Po;0;ON;<narrow> 3002;;;;N;HALFWIDTH IDEOGRAPHIC PERIOD;;;;
14591 FF62;HALFWIDTH LEFT CORNER BRACKET;Ps;0;ON;<narrow> 300C;;;;Y;HALFWIDTH OPENING CORNER BRACKET;;;;
14592 FF63;HALFWIDTH RIGHT CORNER BRACKET;Pe;0;ON;<narrow> 300D;;;;Y;HALFWIDTH CLOSING CORNER BRACKET;;;;
14593 FF64;HALFWIDTH IDEOGRAPHIC COMMA;Po;0;ON;<narrow> 3001;;;;N;;;;;
14594 FF65;HALFWIDTH KATAKANA MIDDLE DOT;Po;0;ON;<narrow> 30FB;;;;N;;;;;
14595 FF66;HALFWIDTH KATAKANA LETTER WO;Lo;0;L;<narrow> 30F2;;;;N;;;;;
14596 FF67;HALFWIDTH KATAKANA LETTER SMALL A;Lo;0;L;<narrow> 30A1;;;;N;;;;;
14597 FF68;HALFWIDTH KATAKANA LETTER SMALL I;Lo;0;L;<narrow> 30A3;;;;N;;;;;
14598 FF69;HALFWIDTH KATAKANA LETTER SMALL U;Lo;0;L;<narrow> 30A5;;;;N;;;;;
14599 FF6A;HALFWIDTH KATAKANA LETTER SMALL E;Lo;0;L;<narrow> 30A7;;;;N;;;;;
14600 FF6B;HALFWIDTH KATAKANA LETTER SMALL O;Lo;0;L;<narrow> 30A9;;;;N;;;;;
14601 FF6C;HALFWIDTH KATAKANA LETTER SMALL YA;Lo;0;L;<narrow> 30E3;;;;N;;;;;
14602 FF6D;HALFWIDTH KATAKANA LETTER SMALL YU;Lo;0;L;<narrow> 30E5;;;;N;;;;;
14603 FF6E;HALFWIDTH KATAKANA LETTER SMALL YO;Lo;0;L;<narrow> 30E7;;;;N;;;;;
14604 FF6F;HALFWIDTH KATAKANA LETTER SMALL TU;Lo;0;L;<narrow> 30C3;;;;N;;;;;
14605 FF70;HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;<narrow> 30FC;;;;N;;;;;
14606 FF71;HALFWIDTH KATAKANA LETTER A;Lo;0;L;<narrow> 30A2;;;;N;;;;;
14607 FF72;HALFWIDTH KATAKANA LETTER I;Lo;0;L;<narrow> 30A4;;;;N;;;;;
14608 FF73;HALFWIDTH KATAKANA LETTER U;Lo;0;L;<narrow> 30A6;;;;N;;;;;
14609 FF74;HALFWIDTH KATAKANA LETTER E;Lo;0;L;<narrow> 30A8;;;;N;;;;;
14610 FF75;HALFWIDTH KATAKANA LETTER O;Lo;0;L;<narrow> 30AA;;;;N;;;;;
14611 FF76;HALFWIDTH KATAKANA LETTER KA;Lo;0;L;<narrow> 30AB;;;;N;;;;;
14612 FF77;HALFWIDTH KATAKANA LETTER KI;Lo;0;L;<narrow> 30AD;;;;N;;;;;
14613 FF78;HALFWIDTH KATAKANA LETTER KU;Lo;0;L;<narrow> 30AF;;;;N;;;;;
14614 FF79;HALFWIDTH KATAKANA LETTER KE;Lo;0;L;<narrow> 30B1;;;;N;;;;;
14615 FF7A;HALFWIDTH KATAKANA LETTER KO;Lo;0;L;<narrow> 30B3;;;;N;;;;;
14616 FF7B;HALFWIDTH KATAKANA LETTER SA;Lo;0;L;<narrow> 30B5;;;;N;;;;;
14617 FF7C;HALFWIDTH KATAKANA LETTER SI;Lo;0;L;<narrow> 30B7;;;;N;;;;;
14618 FF7D;HALFWIDTH KATAKANA LETTER SU;Lo;0;L;<narrow> 30B9;;;;N;;;;;
14619 FF7E;HALFWIDTH KATAKANA LETTER SE;Lo;0;L;<narrow> 30BB;;;;N;;;;;
14620 FF7F;HALFWIDTH KATAKANA LETTER SO;Lo;0;L;<narrow> 30BD;;;;N;;;;;
14621 FF80;HALFWIDTH KATAKANA LETTER TA;Lo;0;L;<narrow> 30BF;;;;N;;;;;
14622 FF81;HALFWIDTH KATAKANA LETTER TI;Lo;0;L;<narrow> 30C1;;;;N;;;;;
14623 FF82;HALFWIDTH KATAKANA LETTER TU;Lo;0;L;<narrow> 30C4;;;;N;;;;;
14624 FF83;HALFWIDTH KATAKANA LETTER TE;Lo;0;L;<narrow> 30C6;;;;N;;;;;
14625 FF84;HALFWIDTH KATAKANA LETTER TO;Lo;0;L;<narrow> 30C8;;;;N;;;;;
14626 FF85;HALFWIDTH KATAKANA LETTER NA;Lo;0;L;<narrow> 30CA;;;;N;;;;;
14627 FF86;HALFWIDTH KATAKANA LETTER NI;Lo;0;L;<narrow> 30CB;;;;N;;;;;
14628 FF87;HALFWIDTH KATAKANA LETTER NU;Lo;0;L;<narrow> 30CC;;;;N;;;;;
14629 FF88;HALFWIDTH KATAKANA LETTER NE;Lo;0;L;<narrow> 30CD;;;;N;;;;;
14630 FF89;HALFWIDTH KATAKANA LETTER NO;Lo;0;L;<narrow> 30CE;;;;N;;;;;
14631 FF8A;HALFWIDTH KATAKANA LETTER HA;Lo;0;L;<narrow> 30CF;;;;N;;;;;
14632 FF8B;HALFWIDTH KATAKANA LETTER HI;Lo;0;L;<narrow> 30D2;;;;N;;;;;
14633 FF8C;HALFWIDTH KATAKANA LETTER HU;Lo;0;L;<narrow> 30D5;;;;N;;;;;
14634 FF8D;HALFWIDTH KATAKANA LETTER HE;Lo;0;L;<narrow> 30D8;;;;N;;;;;
14635 FF8E;HALFWIDTH KATAKANA LETTER HO;Lo;0;L;<narrow> 30DB;;;;N;;;;;
14636 FF8F;HALFWIDTH KATAKANA LETTER MA;Lo;0;L;<narrow> 30DE;;;;N;;;;;
14637 FF90;HALFWIDTH KATAKANA LETTER MI;Lo;0;L;<narrow> 30DF;;;;N;;;;;
14638 FF91;HALFWIDTH KATAKANA LETTER MU;Lo;0;L;<narrow> 30E0;;;;N;;;;;
14639 FF92;HALFWIDTH KATAKANA LETTER ME;Lo;0;L;<narrow> 30E1;;;;N;;;;;
14640 FF93;HALFWIDTH KATAKANA LETTER MO;Lo;0;L;<narrow> 30E2;;;;N;;;;;
14641 FF94;HALFWIDTH KATAKANA LETTER YA;Lo;0;L;<narrow> 30E4;;;;N;;;;;
14642 FF95;HALFWIDTH KATAKANA LETTER YU;Lo;0;L;<narrow> 30E6;;;;N;;;;;
14643 FF96;HALFWIDTH KATAKANA LETTER YO;Lo;0;L;<narrow> 30E8;;;;N;;;;;
14644 FF97;HALFWIDTH KATAKANA LETTER RA;Lo;0;L;<narrow> 30E9;;;;N;;;;;
14645 FF98;HALFWIDTH KATAKANA LETTER RI;Lo;0;L;<narrow> 30EA;;;;N;;;;;
14646 FF99;HALFWIDTH KATAKANA LETTER RU;Lo;0;L;<narrow> 30EB;;;;N;;;;;
14647 FF9A;HALFWIDTH KATAKANA LETTER RE;Lo;0;L;<narrow> 30EC;;;;N;;;;;
14648 FF9B;HALFWIDTH KATAKANA LETTER RO;Lo;0;L;<narrow> 30ED;;;;N;;;;;
14649 FF9C;HALFWIDTH KATAKANA LETTER WA;Lo;0;L;<narrow> 30EF;;;;N;;;;;
14650 FF9D;HALFWIDTH KATAKANA LETTER N;Lo;0;L;<narrow> 30F3;;;;N;;;;;
14651 FF9E;HALFWIDTH KATAKANA VOICED SOUND MARK;Lm;0;L;<narrow> 3099;;;;N;;halfwidth katakana-hiragana voiced sound mark;;;
14652 FF9F;HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK;Lm;0;L;<narrow> 309A;;;;N;;halfwidth katakana-hiragana semi-voiced sound mark;;;
14653 FFA0;HALFWIDTH HANGUL FILLER;Lo;0;L;<narrow> 3164;;;;N;HALFWIDTH HANGUL CAE OM;;;;
14654 FFA1;HALFWIDTH HANGUL LETTER KIYEOK;Lo;0;L;<narrow> 3131;;;;N;HALFWIDTH HANGUL LETTER GIYEOG;;;;
14655 FFA2;HALFWIDTH HANGUL LETTER SSANGKIYEOK;Lo;0;L;<narrow> 3132;;;;N;HALFWIDTH HANGUL LETTER SSANG GIYEOG;;;;
14656 FFA3;HALFWIDTH HANGUL LETTER KIYEOK-SIOS;Lo;0;L;<narrow> 3133;;;;N;HALFWIDTH HANGUL LETTER GIYEOG SIOS;;;;
14657 FFA4;HALFWIDTH HANGUL LETTER NIEUN;Lo;0;L;<narrow> 3134;;;;N;;;;;
14658 FFA5;HALFWIDTH HANGUL LETTER NIEUN-CIEUC;Lo;0;L;<narrow> 3135;;;;N;HALFWIDTH HANGUL LETTER NIEUN JIEUJ;;;;
14659 FFA6;HALFWIDTH HANGUL LETTER NIEUN-HIEUH;Lo;0;L;<narrow> 3136;;;;N;HALFWIDTH HANGUL LETTER NIEUN HIEUH;;;;
14660 FFA7;HALFWIDTH HANGUL LETTER TIKEUT;Lo;0;L;<narrow> 3137;;;;N;HALFWIDTH HANGUL LETTER DIGEUD;;;;
14661 FFA8;HALFWIDTH HANGUL LETTER SSANGTIKEUT;Lo;0;L;<narrow> 3138;;;;N;HALFWIDTH HANGUL LETTER SSANG DIGEUD;;;;
14662 FFA9;HALFWIDTH HANGUL LETTER RIEUL;Lo;0;L;<narrow> 3139;;;;N;HALFWIDTH HANGUL LETTER LIEUL;;;;
14663 FFAA;HALFWIDTH HANGUL LETTER RIEUL-KIYEOK;Lo;0;L;<narrow> 313A;;;;N;HALFWIDTH HANGUL LETTER LIEUL GIYEOG;;;;
14664 FFAB;HALFWIDTH HANGUL LETTER RIEUL-MIEUM;Lo;0;L;<narrow> 313B;;;;N;HALFWIDTH HANGUL LETTER LIEUL MIEUM;;;;
14665 FFAC;HALFWIDTH HANGUL LETTER RIEUL-PIEUP;Lo;0;L;<narrow> 313C;;;;N;HALFWIDTH HANGUL LETTER LIEUL BIEUB;;;;
14666 FFAD;HALFWIDTH HANGUL LETTER RIEUL-SIOS;Lo;0;L;<narrow> 313D;;;;N;HALFWIDTH HANGUL LETTER LIEUL SIOS;;;;
14667 FFAE;HALFWIDTH HANGUL LETTER RIEUL-THIEUTH;Lo;0;L;<narrow> 313E;;;;N;HALFWIDTH HANGUL LETTER LIEUL TIEUT;;;;
14668 FFAF;HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L;<narrow> 313F;;;;N;HALFWIDTH HANGUL LETTER LIEUL PIEUP;;;;
14669 FFB0;HALFWIDTH HANGUL LETTER RIEUL-HIEUH;Lo;0;L;<narrow> 3140;;;;N;HALFWIDTH HANGUL LETTER LIEUL HIEUH;;;;
14670 FFB1;HALFWIDTH HANGUL LETTER MIEUM;Lo;0;L;<narrow> 3141;;;;N;;;;;
14671 FFB2;HALFWIDTH HANGUL LETTER PIEUP;Lo;0;L;<narrow> 3142;;;;N;HALFWIDTH HANGUL LETTER BIEUB;;;;
14672 FFB3;HALFWIDTH HANGUL LETTER SSANGPIEUP;Lo;0;L;<narrow> 3143;;;;N;HALFWIDTH HANGUL LETTER SSANG BIEUB;;;;
14673 FFB4;HALFWIDTH HANGUL LETTER PIEUP-SIOS;Lo;0;L;<narrow> 3144;;;;N;HALFWIDTH HANGUL LETTER BIEUB SIOS;;;;
14674 FFB5;HALFWIDTH HANGUL LETTER SIOS;Lo;0;L;<narrow> 3145;;;;N;;;;;
14675 FFB6;HALFWIDTH HANGUL LETTER SSANGSIOS;Lo;0;L;<narrow> 3146;;;;N;HALFWIDTH HANGUL LETTER SSANG SIOS;;;;
14676 FFB7;HALFWIDTH HANGUL LETTER IEUNG;Lo;0;L;<narrow> 3147;;;;N;;;;;
14677 FFB8;HALFWIDTH HANGUL LETTER CIEUC;Lo;0;L;<narrow> 3148;;;;N;HALFWIDTH HANGUL LETTER JIEUJ;;;;
14678 FFB9;HALFWIDTH HANGUL LETTER SSANGCIEUC;Lo;0;L;<narrow> 3149;;;;N;HALFWIDTH HANGUL LETTER SSANG JIEUJ;;;;
14679 FFBA;HALFWIDTH HANGUL LETTER CHIEUCH;Lo;0;L;<narrow> 314A;;;;N;HALFWIDTH HANGUL LETTER CIEUC;;;;
14680 FFBB;HALFWIDTH HANGUL LETTER KHIEUKH;Lo;0;L;<narrow> 314B;;;;N;HALFWIDTH HANGUL LETTER KIYEOK;;;;
14681 FFBC;HALFWIDTH HANGUL LETTER THIEUTH;Lo;0;L;<narrow> 314C;;;;N;HALFWIDTH HANGUL LETTER TIEUT;;;;
14682 FFBD;HALFWIDTH HANGUL LETTER PHIEUPH;Lo;0;L;<narrow> 314D;;;;N;HALFWIDTH HANGUL LETTER PIEUP;;;;
14683 FFBE;HALFWIDTH HANGUL LETTER HIEUH;Lo;0;L;<narrow> 314E;;;;N;;;;;
14684 FFC2;HALFWIDTH HANGUL LETTER A;Lo;0;L;<narrow> 314F;;;;N;;;;;
14685 FFC3;HALFWIDTH HANGUL LETTER AE;Lo;0;L;<narrow> 3150;;;;N;;;;;
14686 FFC4;HALFWIDTH HANGUL LETTER YA;Lo;0;L;<narrow> 3151;;;;N;;;;;
14687 FFC5;HALFWIDTH HANGUL LETTER YAE;Lo;0;L;<narrow> 3152;;;;N;;;;;
14688 FFC6;HALFWIDTH HANGUL LETTER EO;Lo;0;L;<narrow> 3153;;;;N;;;;;
14689 FFC7;HALFWIDTH HANGUL LETTER E;Lo;0;L;<narrow> 3154;;;;N;;;;;
14690 FFCA;HALFWIDTH HANGUL LETTER YEO;Lo;0;L;<narrow> 3155;;;;N;;;;;
14691 FFCB;HALFWIDTH HANGUL LETTER YE;Lo;0;L;<narrow> 3156;;;;N;;;;;
14692 FFCC;HALFWIDTH HANGUL LETTER O;Lo;0;L;<narrow> 3157;;;;N;;;;;
14693 FFCD;HALFWIDTH HANGUL LETTER WA;Lo;0;L;<narrow> 3158;;;;N;;;;;
14694 FFCE;HALFWIDTH HANGUL LETTER WAE;Lo;0;L;<narrow> 3159;;;;N;;;;;
14695 FFCF;HALFWIDTH HANGUL LETTER OE;Lo;0;L;<narrow> 315A;;;;N;;;;;
14696 FFD2;HALFWIDTH HANGUL LETTER YO;Lo;0;L;<narrow> 315B;;;;N;;;;;
14697 FFD3;HALFWIDTH HANGUL LETTER U;Lo;0;L;<narrow> 315C;;;;N;;;;;
14698 FFD4;HALFWIDTH HANGUL LETTER WEO;Lo;0;L;<narrow> 315D;;;;N;;;;;
14699 FFD5;HALFWIDTH HANGUL LETTER WE;Lo;0;L;<narrow> 315E;;;;N;;;;;
14700 FFD6;HALFWIDTH HANGUL LETTER WI;Lo;0;L;<narrow> 315F;;;;N;;;;;
14701 FFD7;HALFWIDTH HANGUL LETTER YU;Lo;0;L;<narrow> 3160;;;;N;;;;;
14702 FFDA;HALFWIDTH HANGUL LETTER EU;Lo;0;L;<narrow> 3161;;;;N;;;;;
14703 FFDB;HALFWIDTH HANGUL LETTER YI;Lo;0;L;<narrow> 3162;;;;N;;;;;
14704 FFDC;HALFWIDTH HANGUL LETTER I;Lo;0;L;<narrow> 3163;;;;N;;;;;
14705 FFE0;FULLWIDTH CENT SIGN;Sc;0;ET;<wide> 00A2;;;;N;;;;;
14706 FFE1;FULLWIDTH POUND SIGN;Sc;0;ET;<wide> 00A3;;;;N;;;;;
14707 FFE2;FULLWIDTH NOT SIGN;Sm;0;ON;<wide> 00AC;;;;N;;;;;
14708 FFE3;FULLWIDTH MACRON;Sk;0;ON;<wide> 00AF;;;;N;FULLWIDTH SPACING MACRON;*;;;
14709 FFE4;FULLWIDTH BROKEN BAR;So;0;ON;<wide> 00A6;;;;N;FULLWIDTH BROKEN VERTICAL BAR;;;;
14710 FFE5;FULLWIDTH YEN SIGN;Sc;0;ET;<wide> 00A5;;;;N;;;;;
14711 FFE6;FULLWIDTH WON SIGN;Sc;0;ET;<wide> 20A9;;;;N;;;;;
14712 FFE8;HALFWIDTH FORMS LIGHT VERTICAL;So;0;ON;<narrow> 2502;;;;N;;;;;
14713 FFE9;HALFWIDTH LEFTWARDS ARROW;Sm;0;ON;<narrow> 2190;;;;N;;;;;
14714 FFEA;HALFWIDTH UPWARDS ARROW;Sm;0;ON;<narrow> 2191;;;;N;;;;;
14715 FFEB;HALFWIDTH RIGHTWARDS ARROW;Sm;0;ON;<narrow> 2192;;;;N;;;;;
14716 FFEC;HALFWIDTH DOWNWARDS ARROW;Sm;0;ON;<narrow> 2193;;;;N;;;;;
14717 FFED;HALFWIDTH BLACK SQUARE;So;0;ON;<narrow> 25A0;;;;N;;;;;
14718 FFEE;HALFWIDTH WHITE CIRCLE;So;0;ON;<narrow> 25CB;;;;N;;;;;
14719 FFF9;INTERLINEAR ANNOTATION ANCHOR;Cf;0;ON;;;;;N;;;;;
14720 FFFA;INTERLINEAR ANNOTATION SEPARATOR;Cf;0;ON;;;;;N;;;;;
14721 FFFB;INTERLINEAR ANNOTATION TERMINATOR;Cf;0;ON;;;;;N;;;;;
14722 FFFC;OBJECT REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
14723 FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;
14724 10000;LINEAR B SYLLABLE B008 A;Lo;0;L;;;;;N;;;;;
14725 10001;LINEAR B SYLLABLE B038 E;Lo;0;L;;;;;N;;;;;
14726 10002;LINEAR B SYLLABLE B028 I;Lo;0;L;;;;;N;;;;;
14727 10003;LINEAR B SYLLABLE B061 O;Lo;0;L;;;;;N;;;;;
14728 10004;LINEAR B SYLLABLE B010 U;Lo;0;L;;;;;N;;;;;
14729 10005;LINEAR B SYLLABLE B001 DA;Lo;0;L;;;;;N;;;;;
14730 10006;LINEAR B SYLLABLE B045 DE;Lo;0;L;;;;;N;;;;;
14731 10007;LINEAR B SYLLABLE B007 DI;Lo;0;L;;;;;N;;;;;
14732 10008;LINEAR B SYLLABLE B014 DO;Lo;0;L;;;;;N;;;;;
14733 10009;LINEAR B SYLLABLE B051 DU;Lo;0;L;;;;;N;;;;;
14734 1000A;LINEAR B SYLLABLE B057 JA;Lo;0;L;;;;;N;;;;;
14735 1000B;LINEAR B SYLLABLE B046 JE;Lo;0;L;;;;;N;;;;;
14736 1000D;LINEAR B SYLLABLE B036 JO;Lo;0;L;;;;;N;;;;;
14737 1000E;LINEAR B SYLLABLE B065 JU;Lo;0;L;;;;;N;;;;;
14738 1000F;LINEAR B SYLLABLE B077 KA;Lo;0;L;;;;;N;;;;;
14739 10010;LINEAR B SYLLABLE B044 KE;Lo;0;L;;;;;N;;;;;
14740 10011;LINEAR B SYLLABLE B067 KI;Lo;0;L;;;;;N;;;;;
14741 10012;LINEAR B SYLLABLE B070 KO;Lo;0;L;;;;;N;;;;;
14742 10013;LINEAR B SYLLABLE B081 KU;Lo;0;L;;;;;N;;;;;
14743 10014;LINEAR B SYLLABLE B080 MA;Lo;0;L;;;;;N;;;;;
14744 10015;LINEAR B SYLLABLE B013 ME;Lo;0;L;;;;;N;;;;;
14745 10016;LINEAR B SYLLABLE B073 MI;Lo;0;L;;;;;N;;;;;
14746 10017;LINEAR B SYLLABLE B015 MO;Lo;0;L;;;;;N;;;;;
14747 10018;LINEAR B SYLLABLE B023 MU;Lo;0;L;;;;;N;;;;;
14748 10019;LINEAR B SYLLABLE B006 NA;Lo;0;L;;;;;N;;;;;
14749 1001A;LINEAR B SYLLABLE B024 NE;Lo;0;L;;;;;N;;;;;
14750 1001B;LINEAR B SYLLABLE B030 NI;Lo;0;L;;;;;N;;;;;
14751 1001C;LINEAR B SYLLABLE B052 NO;Lo;0;L;;;;;N;;;;;
14752 1001D;LINEAR B SYLLABLE B055 NU;Lo;0;L;;;;;N;;;;;
14753 1001E;LINEAR B SYLLABLE B003 PA;Lo;0;L;;;;;N;;;;;
14754 1001F;LINEAR B SYLLABLE B072 PE;Lo;0;L;;;;;N;;;;;
14755 10020;LINEAR B SYLLABLE B039 PI;Lo;0;L;;;;;N;;;;;
14756 10021;LINEAR B SYLLABLE B011 PO;Lo;0;L;;;;;N;;;;;
14757 10022;LINEAR B SYLLABLE B050 PU;Lo;0;L;;;;;N;;;;;
14758 10023;LINEAR B SYLLABLE B016 QA;Lo;0;L;;;;;N;;;;;
14759 10024;LINEAR B SYLLABLE B078 QE;Lo;0;L;;;;;N;;;;;
14760 10025;LINEAR B SYLLABLE B021 QI;Lo;0;L;;;;;N;;;;;
14761 10026;LINEAR B SYLLABLE B032 QO;Lo;0;L;;;;;N;;;;;
14762 10028;LINEAR B SYLLABLE B060 RA;Lo;0;L;;;;;N;;;;;
14763 10029;LINEAR B SYLLABLE B027 RE;Lo;0;L;;;;;N;;;;;
14764 1002A;LINEAR B SYLLABLE B053 RI;Lo;0;L;;;;;N;;;;;
14765 1002B;LINEAR B SYLLABLE B002 RO;Lo;0;L;;;;;N;;;;;
14766 1002C;LINEAR B SYLLABLE B026 RU;Lo;0;L;;;;;N;;;;;
14767 1002D;LINEAR B SYLLABLE B031 SA;Lo;0;L;;;;;N;;;;;
14768 1002E;LINEAR B SYLLABLE B009 SE;Lo;0;L;;;;;N;;;;;
14769 1002F;LINEAR B SYLLABLE B041 SI;Lo;0;L;;;;;N;;;;;
14770 10030;LINEAR B SYLLABLE B012 SO;Lo;0;L;;;;;N;;;;;
14771 10031;LINEAR B SYLLABLE B058 SU;Lo;0;L;;;;;N;;;;;
14772 10032;LINEAR B SYLLABLE B059 TA;Lo;0;L;;;;;N;;;;;
14773 10033;LINEAR B SYLLABLE B004 TE;Lo;0;L;;;;;N;;;;;
14774 10034;LINEAR B SYLLABLE B037 TI;Lo;0;L;;;;;N;;;;;
14775 10035;LINEAR B SYLLABLE B005 TO;Lo;0;L;;;;;N;;;;;
14776 10036;LINEAR B SYLLABLE B069 TU;Lo;0;L;;;;;N;;;;;
14777 10037;LINEAR B SYLLABLE B054 WA;Lo;0;L;;;;;N;;;;;
14778 10038;LINEAR B SYLLABLE B075 WE;Lo;0;L;;;;;N;;;;;
14779 10039;LINEAR B SYLLABLE B040 WI;Lo;0;L;;;;;N;;;;;
14780 1003A;LINEAR B SYLLABLE B042 WO;Lo;0;L;;;;;N;;;;;
14781 1003C;LINEAR B SYLLABLE B017 ZA;Lo;0;L;;;;;N;;;;;
14782 1003D;LINEAR B SYLLABLE B074 ZE;Lo;0;L;;;;;N;;;;;
14783 1003F;LINEAR B SYLLABLE B020 ZO;Lo;0;L;;;;;N;;;;;
14784 10040;LINEAR B SYLLABLE B025 A2;Lo;0;L;;;;;N;;;;;
14785 10041;LINEAR B SYLLABLE B043 A3;Lo;0;L;;;;;N;;;;;
14786 10042;LINEAR B SYLLABLE B085 AU;Lo;0;L;;;;;N;;;;;
14787 10043;LINEAR B SYLLABLE B071 DWE;Lo;0;L;;;;;N;;;;;
14788 10044;LINEAR B SYLLABLE B090 DWO;Lo;0;L;;;;;N;;;;;
14789 10045;LINEAR B SYLLABLE B048 NWA;Lo;0;L;;;;;N;;;;;
14790 10046;LINEAR B SYLLABLE B029 PU2;Lo;0;L;;;;;N;;;;;
14791 10047;LINEAR B SYLLABLE B062 PTE;Lo;0;L;;;;;N;;;;;
14792 10048;LINEAR B SYLLABLE B076 RA2;Lo;0;L;;;;;N;;;;;
14793 10049;LINEAR B SYLLABLE B033 RA3;Lo;0;L;;;;;N;;;;;
14794 1004A;LINEAR B SYLLABLE B068 RO2;Lo;0;L;;;;;N;;;;;
14795 1004B;LINEAR B SYLLABLE B066 TA2;Lo;0;L;;;;;N;;;;;
14796 1004C;LINEAR B SYLLABLE B087 TWE;Lo;0;L;;;;;N;;;;;
14797 1004D;LINEAR B SYLLABLE B091 TWO;Lo;0;L;;;;;N;;;;;
14798 10050;LINEAR B SYMBOL B018;Lo;0;L;;;;;N;;;;;
14799 10051;LINEAR B SYMBOL B019;Lo;0;L;;;;;N;;;;;
14800 10052;LINEAR B SYMBOL B022;Lo;0;L;;;;;N;;;;;
14801 10053;LINEAR B SYMBOL B034;Lo;0;L;;;;;N;;;;;
14802 10054;LINEAR B SYMBOL B047;Lo;0;L;;;;;N;;;;;
14803 10055;LINEAR B SYMBOL B049;Lo;0;L;;;;;N;;;;;
14804 10056;LINEAR B SYMBOL B056;Lo;0;L;;;;;N;;;;;
14805 10057;LINEAR B SYMBOL B063;Lo;0;L;;;;;N;;;;;
14806 10058;LINEAR B SYMBOL B064;Lo;0;L;;;;;N;;;;;
14807 10059;LINEAR B SYMBOL B079;Lo;0;L;;;;;N;;;;;
14808 1005A;LINEAR B SYMBOL B082;Lo;0;L;;;;;N;;;;;
14809 1005B;LINEAR B SYMBOL B083;Lo;0;L;;;;;N;;;;;
14810 1005C;LINEAR B SYMBOL B086;Lo;0;L;;;;;N;;;;;
14811 1005D;LINEAR B SYMBOL B089;Lo;0;L;;;;;N;;;;;
14812 10080;LINEAR B IDEOGRAM B100 MAN;Lo;0;L;;;;;N;;;;;
14813 10081;LINEAR B IDEOGRAM B102 WOMAN;Lo;0;L;;;;;N;;;;;
14814 10082;LINEAR B IDEOGRAM B104 DEER;Lo;0;L;;;;;N;;;;;
14815 10083;LINEAR B IDEOGRAM B105 EQUID;Lo;0;L;;;;;N;;;;;
14816 10084;LINEAR B IDEOGRAM B105F MARE;Lo;0;L;;;;;N;;;;;
14817 10085;LINEAR B IDEOGRAM B105M STALLION;Lo;0;L;;;;;N;;;;;
14818 10086;LINEAR B IDEOGRAM B106F EWE;Lo;0;L;;;;;N;;;;;
14819 10087;LINEAR B IDEOGRAM B106M RAM;Lo;0;L;;;;;N;;;;;
14820 10088;LINEAR B IDEOGRAM B107F SHE-GOAT;Lo;0;L;;;;;N;;;;;
14821 10089;LINEAR B IDEOGRAM B107M HE-GOAT;Lo;0;L;;;;;N;;;;;
14822 1008A;LINEAR B IDEOGRAM B108F SOW;Lo;0;L;;;;;N;;;;;
14823 1008B;LINEAR B IDEOGRAM B108M BOAR;Lo;0;L;;;;;N;;;;;
14824 1008C;LINEAR B IDEOGRAM B109F COW;Lo;0;L;;;;;N;;;;;
14825 1008D;LINEAR B IDEOGRAM B109M BULL;Lo;0;L;;;;;N;;;;;
14826 1008E;LINEAR B IDEOGRAM B120 WHEAT;Lo;0;L;;;;;N;;;;;
14827 1008F;LINEAR B IDEOGRAM B121 BARLEY;Lo;0;L;;;;;N;;;;;
14828 10090;LINEAR B IDEOGRAM B122 OLIVE;Lo;0;L;;;;;N;;;;;
14829 10091;LINEAR B IDEOGRAM B123 SPICE;Lo;0;L;;;;;N;;;;;
14830 10092;LINEAR B IDEOGRAM B125 CYPERUS;Lo;0;L;;;;;N;;;;;
14831 10093;LINEAR B MONOGRAM B127 KAPO;Lo;0;L;;;;;N;;;;;
14832 10094;LINEAR B MONOGRAM B128 KANAKO;Lo;0;L;;;;;N;;;;;
14833 10095;LINEAR B IDEOGRAM B130 OIL;Lo;0;L;;;;;N;;;;;
14834 10096;LINEAR B IDEOGRAM B131 WINE;Lo;0;L;;;;;N;;;;;
14835 10097;LINEAR B IDEOGRAM B132;Lo;0;L;;;;;N;;;;;
14836 10098;LINEAR B MONOGRAM B133 AREPA;Lo;0;L;;;;;N;;;;;
14837 10099;LINEAR B MONOGRAM B135 MERI;Lo;0;L;;;;;N;;;;;
14838 1009A;LINEAR B IDEOGRAM B140 BRONZE;Lo;0;L;;;;;N;;;;;
14839 1009B;LINEAR B IDEOGRAM B141 GOLD;Lo;0;L;;;;;N;;;;;
14840 1009C;LINEAR B IDEOGRAM B142;Lo;0;L;;;;;N;;;;;
14841 1009D;LINEAR B IDEOGRAM B145 WOOL;Lo;0;L;;;;;N;;;;;
14842 1009E;LINEAR B IDEOGRAM B146;Lo;0;L;;;;;N;;;;;
14843 1009F;LINEAR B IDEOGRAM B150;Lo;0;L;;;;;N;;;;;
14844 100A0;LINEAR B IDEOGRAM B151 HORN;Lo;0;L;;;;;N;;;;;
14845 100A1;LINEAR B IDEOGRAM B152;Lo;0;L;;;;;N;;;;;
14846 100A2;LINEAR B IDEOGRAM B153;Lo;0;L;;;;;N;;;;;
14847 100A3;LINEAR B IDEOGRAM B154;Lo;0;L;;;;;N;;;;;
14848 100A4;LINEAR B MONOGRAM B156 TURO2;Lo;0;L;;;;;N;;;;;
14849 100A5;LINEAR B IDEOGRAM B157;Lo;0;L;;;;;N;;;;;
14850 100A6;LINEAR B IDEOGRAM B158;Lo;0;L;;;;;N;;;;;
14851 100A7;LINEAR B IDEOGRAM B159 CLOTH;Lo;0;L;;;;;N;;;;;
14852 100A8;LINEAR B IDEOGRAM B160;Lo;0;L;;;;;N;;;;;
14853 100A9;LINEAR B IDEOGRAM B161;Lo;0;L;;;;;N;;;;;
14854 100AA;LINEAR B IDEOGRAM B162 GARMENT;Lo;0;L;;;;;N;;;;;
14855 100AB;LINEAR B IDEOGRAM B163 ARMOUR;Lo;0;L;;;;;N;;;;;
14856 100AC;LINEAR B IDEOGRAM B164;Lo;0;L;;;;;N;;;;;
14857 100AD;LINEAR B IDEOGRAM B165;Lo;0;L;;;;;N;;;;;
14858 100AE;LINEAR B IDEOGRAM B166;Lo;0;L;;;;;N;;;;;
14859 100AF;LINEAR B IDEOGRAM B167;Lo;0;L;;;;;N;;;;;
14860 100B0;LINEAR B IDEOGRAM B168;Lo;0;L;;;;;N;;;;;
14861 100B1;LINEAR B IDEOGRAM B169;Lo;0;L;;;;;N;;;;;
14862 100B2;LINEAR B IDEOGRAM B170;Lo;0;L;;;;;N;;;;;
14863 100B3;LINEAR B IDEOGRAM B171;Lo;0;L;;;;;N;;;;;
14864 100B4;LINEAR B IDEOGRAM B172;Lo;0;L;;;;;N;;;;;
14865 100B5;LINEAR B IDEOGRAM B173 MONTH;Lo;0;L;;;;;N;;;;;
14866 100B6;LINEAR B IDEOGRAM B174;Lo;0;L;;;;;N;;;;;
14867 100B7;LINEAR B IDEOGRAM B176 TREE;Lo;0;L;;;;;N;;;;;
14868 100B8;LINEAR B IDEOGRAM B177;Lo;0;L;;;;;N;;;;;
14869 100B9;LINEAR B IDEOGRAM B178;Lo;0;L;;;;;N;;;;;
14870 100BA;LINEAR B IDEOGRAM B179;Lo;0;L;;;;;N;;;;;
14871 100BB;LINEAR B IDEOGRAM B180;Lo;0;L;;;;;N;;;;;
14872 100BC;LINEAR B IDEOGRAM B181;Lo;0;L;;;;;N;;;;;
14873 100BD;LINEAR B IDEOGRAM B182;Lo;0;L;;;;;N;;;;;
14874 100BE;LINEAR B IDEOGRAM B183;Lo;0;L;;;;;N;;;;;
14875 100BF;LINEAR B IDEOGRAM B184;Lo;0;L;;;;;N;;;;;
14876 100C0;LINEAR B IDEOGRAM B185;Lo;0;L;;;;;N;;;;;
14877 100C1;LINEAR B IDEOGRAM B189;Lo;0;L;;;;;N;;;;;
14878 100C2;LINEAR B IDEOGRAM B190;Lo;0;L;;;;;N;;;;;
14879 100C3;LINEAR B IDEOGRAM B191 HELMET;Lo;0;L;;;;;N;;;;;
14880 100C4;LINEAR B IDEOGRAM B220 FOOTSTOOL;Lo;0;L;;;;;N;;;;;
14881 100C5;LINEAR B IDEOGRAM B225 BATHTUB;Lo;0;L;;;;;N;;;;;
14882 100C6;LINEAR B IDEOGRAM B230 SPEAR;Lo;0;L;;;;;N;;;;;
14883 100C7;LINEAR B IDEOGRAM B231 ARROW;Lo;0;L;;;;;N;;;;;
14884 100C8;LINEAR B IDEOGRAM B232;Lo;0;L;;;;;N;;;;;
14885 100C9;LINEAR B IDEOGRAM B233 SWORD;Lo;0;L;;;;;N;;pug;;;
14886 100CA;LINEAR B IDEOGRAM B234;Lo;0;L;;;;;N;;;;;
14887 100CB;LINEAR B IDEOGRAM B236;Lo;0;L;;;;;N;;gup;;;
14888 100CC;LINEAR B IDEOGRAM B240 WHEELED CHARIOT;Lo;0;L;;;;;N;;;;;
14889 100CD;LINEAR B IDEOGRAM B241 CHARIOT;Lo;0;L;;;;;N;;;;;
14890 100CE;LINEAR B IDEOGRAM B242 CHARIOT FRAME;Lo;0;L;;;;;N;;;;;
14891 100CF;LINEAR B IDEOGRAM B243 WHEEL;Lo;0;L;;;;;N;;;;;
14892 100D0;LINEAR B IDEOGRAM B245;Lo;0;L;;;;;N;;;;;
14893 100D1;LINEAR B IDEOGRAM B246;Lo;0;L;;;;;N;;;;;
14894 100D2;LINEAR B MONOGRAM B247 DIPTE;Lo;0;L;;;;;N;;;;;
14895 100D3;LINEAR B IDEOGRAM B248;Lo;0;L;;;;;N;;;;;
14896 100D4;LINEAR B IDEOGRAM B249;Lo;0;L;;;;;N;;;;;
14897 100D5;LINEAR B IDEOGRAM B251;Lo;0;L;;;;;N;;;;;
14898 100D6;LINEAR B IDEOGRAM B252;Lo;0;L;;;;;N;;;;;
14899 100D7;LINEAR B IDEOGRAM B253;Lo;0;L;;;;;N;;;;;
14900 100D8;LINEAR B IDEOGRAM B254 DART;Lo;0;L;;;;;N;;;;;
14901 100D9;LINEAR B IDEOGRAM B255;Lo;0;L;;;;;N;;;;;
14902 100DA;LINEAR B IDEOGRAM B256;Lo;0;L;;;;;N;;;;;
14903 100DB;LINEAR B IDEOGRAM B257;Lo;0;L;;;;;N;;;;;
14904 100DC;LINEAR B IDEOGRAM B258;Lo;0;L;;;;;N;;;;;
14905 100DD;LINEAR B IDEOGRAM B259;Lo;0;L;;;;;N;;;;;
14906 100DE;LINEAR B IDEOGRAM VESSEL B155;Lo;0;L;;;;;N;;;;;
14907 100DF;LINEAR B IDEOGRAM VESSEL B200;Lo;0;L;;;;;N;;;;;
14908 100E0;LINEAR B IDEOGRAM VESSEL B201;Lo;0;L;;;;;N;;;;;
14909 100E1;LINEAR B IDEOGRAM VESSEL B202;Lo;0;L;;;;;N;;;;;
14910 100E2;LINEAR B IDEOGRAM VESSEL B203;Lo;0;L;;;;;N;;;;;
14911 100E3;LINEAR B IDEOGRAM VESSEL B204;Lo;0;L;;;;;N;;;;;
14912 100E4;LINEAR B IDEOGRAM VESSEL B205;Lo;0;L;;;;;N;;;;;
14913 100E5;LINEAR B IDEOGRAM VESSEL B206;Lo;0;L;;;;;N;;;;;
14914 100E6;LINEAR B IDEOGRAM VESSEL B207;Lo;0;L;;;;;N;;;;;
14915 100E7;LINEAR B IDEOGRAM VESSEL B208;Lo;0;L;;;;;N;;;;;
14916 100E8;LINEAR B IDEOGRAM VESSEL B209;Lo;0;L;;;;;N;;;;;
14917 100E9;LINEAR B IDEOGRAM VESSEL B210;Lo;0;L;;;;;N;;;;;
14918 100EA;LINEAR B IDEOGRAM VESSEL B211;Lo;0;L;;;;;N;;;;;
14919 100EB;LINEAR B IDEOGRAM VESSEL B212;Lo;0;L;;;;;N;;;;;
14920 100EC;LINEAR B IDEOGRAM VESSEL B213;Lo;0;L;;;;;N;;;;;
14921 100ED;LINEAR B IDEOGRAM VESSEL B214;Lo;0;L;;;;;N;;;;;
14922 100EE;LINEAR B IDEOGRAM VESSEL B215;Lo;0;L;;;;;N;;;;;
14923 100EF;LINEAR B IDEOGRAM VESSEL B216;Lo;0;L;;;;;N;;;;;
14924 100F0;LINEAR B IDEOGRAM VESSEL B217;Lo;0;L;;;;;N;;;;;
14925 100F1;LINEAR B IDEOGRAM VESSEL B218;Lo;0;L;;;;;N;;;;;
14926 100F2;LINEAR B IDEOGRAM VESSEL B219;Lo;0;L;;;;;N;;;;;
14927 100F3;LINEAR B IDEOGRAM VESSEL B221;Lo;0;L;;;;;N;;;;;
14928 100F4;LINEAR B IDEOGRAM VESSEL B222;Lo;0;L;;;;;N;;;;;
14929 100F5;LINEAR B IDEOGRAM VESSEL B226;Lo;0;L;;;;;N;;;;;
14930 100F6;LINEAR B IDEOGRAM VESSEL B227;Lo;0;L;;;;;N;;;;;
14931 100F7;LINEAR B IDEOGRAM VESSEL B228;Lo;0;L;;;;;N;;;;;
14932 100F8;LINEAR B IDEOGRAM VESSEL B229;Lo;0;L;;;;;N;;;;;
14933 100F9;LINEAR B IDEOGRAM VESSEL B250;Lo;0;L;;;;;N;;;;;
14934 100FA;LINEAR B IDEOGRAM VESSEL B305;Lo;0;L;;;;;N;;;;;
14935 10100;AEGEAN WORD SEPARATOR LINE;Po;0;L;;;;;N;;;;;
14936 10101;AEGEAN WORD SEPARATOR DOT;Po;0;ON;;;;;N;;;;;
14937 10102;AEGEAN CHECK MARK;So;0;L;;;;;N;;;;;
14938 10107;AEGEAN NUMBER ONE;No;0;L;;;;1;N;;;;;
14939 10108;AEGEAN NUMBER TWO;No;0;L;;;;2;N;;;;;
14940 10109;AEGEAN NUMBER THREE;No;0;L;;;;3;N;;;;;
14941 1010A;AEGEAN NUMBER FOUR;No;0;L;;;;4;N;;;;;
14942 1010B;AEGEAN NUMBER FIVE;No;0;L;;;;5;N;;;;;
14943 1010C;AEGEAN NUMBER SIX;No;0;L;;;;6;N;;;;;
14944 1010D;AEGEAN NUMBER SEVEN;No;0;L;;;;7;N;;;;;
14945 1010E;AEGEAN NUMBER EIGHT;No;0;L;;;;8;N;;;;;
14946 1010F;AEGEAN NUMBER NINE;No;0;L;;;;9;N;;;;;
14947 10110;AEGEAN NUMBER TEN;No;0;L;;;;10;N;;;;;
14948 10111;AEGEAN NUMBER TWENTY;No;0;L;;;;20;N;;;;;
14949 10112;AEGEAN NUMBER THIRTY;No;0;L;;;;30;N;;;;;
14950 10113;AEGEAN NUMBER FORTY;No;0;L;;;;40;N;;;;;
14951 10114;AEGEAN NUMBER FIFTY;No;0;L;;;;50;N;;;;;
14952 10115;AEGEAN NUMBER SIXTY;No;0;L;;;;60;N;;;;;
14953 10116;AEGEAN NUMBER SEVENTY;No;0;L;;;;70;N;;;;;
14954 10117;AEGEAN NUMBER EIGHTY;No;0;L;;;;80;N;;;;;
14955 10118;AEGEAN NUMBER NINETY;No;0;L;;;;90;N;;;;;
14956 10119;AEGEAN NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;
14957 1011A;AEGEAN NUMBER TWO HUNDRED;No;0;L;;;;200;N;;;;;
14958 1011B;AEGEAN NUMBER THREE HUNDRED;No;0;L;;;;300;N;;;;;
14959 1011C;AEGEAN NUMBER FOUR HUNDRED;No;0;L;;;;400;N;;;;;
14960 1011D;AEGEAN NUMBER FIVE HUNDRED;No;0;L;;;;500;N;;;;;
14961 1011E;AEGEAN NUMBER SIX HUNDRED;No;0;L;;;;600;N;;;;;
14962 1011F;AEGEAN NUMBER SEVEN HUNDRED;No;0;L;;;;700;N;;;;;
14963 10120;AEGEAN NUMBER EIGHT HUNDRED;No;0;L;;;;800;N;;;;;
14964 10121;AEGEAN NUMBER NINE HUNDRED;No;0;L;;;;900;N;;;;;
14965 10122;AEGEAN NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;
14966 10123;AEGEAN NUMBER TWO THOUSAND;No;0;L;;;;2000;N;;;;;
14967 10124;AEGEAN NUMBER THREE THOUSAND;No;0;L;;;;3000;N;;;;;
14968 10125;AEGEAN NUMBER FOUR THOUSAND;No;0;L;;;;4000;N;;;;;
14969 10126;AEGEAN NUMBER FIVE THOUSAND;No;0;L;;;;5000;N;;;;;
14970 10127;AEGEAN NUMBER SIX THOUSAND;No;0;L;;;;6000;N;;;;;
14971 10128;AEGEAN NUMBER SEVEN THOUSAND;No;0;L;;;;7000;N;;;;;
14972 10129;AEGEAN NUMBER EIGHT THOUSAND;No;0;L;;;;8000;N;;;;;
14973 1012A;AEGEAN NUMBER NINE THOUSAND;No;0;L;;;;9000;N;;;;;
14974 1012B;AEGEAN NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;;
14975 1012C;AEGEAN NUMBER TWENTY THOUSAND;No;0;L;;;;20000;N;;;;;
14976 1012D;AEGEAN NUMBER THIRTY THOUSAND;No;0;L;;;;30000;N;;;;;
14977 1012E;AEGEAN NUMBER FORTY THOUSAND;No;0;L;;;;40000;N;;;;;
14978 1012F;AEGEAN NUMBER FIFTY THOUSAND;No;0;L;;;;50000;N;;;;;
14979 10130;AEGEAN NUMBER SIXTY THOUSAND;No;0;L;;;;60000;N;;;;;
14980 10131;AEGEAN NUMBER SEVENTY THOUSAND;No;0;L;;;;70000;N;;;;;
14981 10132;AEGEAN NUMBER EIGHTY THOUSAND;No;0;L;;;;80000;N;;;;;
14982 10133;AEGEAN NUMBER NINETY THOUSAND;No;0;L;;;;90000;N;;;;;
14983 10137;AEGEAN WEIGHT BASE UNIT;So;0;L;;;;;N;;;;;
14984 10138;AEGEAN WEIGHT FIRST SUBUNIT;So;0;L;;;;;N;;;;;
14985 10139;AEGEAN WEIGHT SECOND SUBUNIT;So;0;L;;;;;N;;;;;
14986 1013A;AEGEAN WEIGHT THIRD SUBUNIT;So;0;L;;;;;N;;;;;
14987 1013B;AEGEAN WEIGHT FOURTH SUBUNIT;So;0;L;;;;;N;;;;;
14988 1013C;AEGEAN DRY MEASURE FIRST SUBUNIT;So;0;L;;;;;N;;;;;
14989 1013D;AEGEAN LIQUID MEASURE FIRST SUBUNIT;So;0;L;;;;;N;;;;;
14990 1013E;AEGEAN MEASURE SECOND SUBUNIT;So;0;L;;;;;N;;;;;
14991 1013F;AEGEAN MEASURE THIRD SUBUNIT;So;0;L;;;;;N;;;;;
14992 10140;GREEK ACROPHONIC ATTIC ONE QUARTER;Nl;0;ON;;;;1/4;N;;;;;
14993 10141;GREEK ACROPHONIC ATTIC ONE HALF;Nl;0;ON;;;;1/2;N;;;;;
14994 10142;GREEK ACROPHONIC ATTIC ONE DRACHMA;Nl;0;ON;;;;1;N;;;;;
14995 10143;GREEK ACROPHONIC ATTIC FIVE;Nl;0;ON;;;;5;N;;;;;
14996 10144;GREEK ACROPHONIC ATTIC FIFTY;Nl;0;ON;;;;50;N;;;;;
14997 10145;GREEK ACROPHONIC ATTIC FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
14998 10146;GREEK ACROPHONIC ATTIC FIVE THOUSAND;Nl;0;ON;;;;5000;N;;;;;
14999 10147;GREEK ACROPHONIC ATTIC FIFTY THOUSAND;Nl;0;ON;;;;50000;N;;;;;
15000 10148;GREEK ACROPHONIC ATTIC FIVE TALENTS;Nl;0;ON;;;;5;N;;;;;
15001 10149;GREEK ACROPHONIC ATTIC TEN TALENTS;Nl;0;ON;;;;10;N;;;;;
15002 1014A;GREEK ACROPHONIC ATTIC FIFTY TALENTS;Nl;0;ON;;;;50;N;;;;;
15003 1014B;GREEK ACROPHONIC ATTIC ONE HUNDRED TALENTS;Nl;0;ON;;;;100;N;;;;;
15004 1014C;GREEK ACROPHONIC ATTIC FIVE HUNDRED TALENTS;Nl;0;ON;;;;500;N;;;;;
15005 1014D;GREEK ACROPHONIC ATTIC ONE THOUSAND TALENTS;Nl;0;ON;;;;1000;N;;;;;
15006 1014E;GREEK ACROPHONIC ATTIC FIVE THOUSAND TALENTS;Nl;0;ON;;;;5000;N;;;;;
15007 1014F;GREEK ACROPHONIC ATTIC FIVE STATERS;Nl;0;ON;;;;5;N;;;;;
15008 10150;GREEK ACROPHONIC ATTIC TEN STATERS;Nl;0;ON;;;;10;N;;;;;
15009 10151;GREEK ACROPHONIC ATTIC FIFTY STATERS;Nl;0;ON;;;;50;N;;;;;
15010 10152;GREEK ACROPHONIC ATTIC ONE HUNDRED STATERS;Nl;0;ON;;;;100;N;;;;;
15011 10153;GREEK ACROPHONIC ATTIC FIVE HUNDRED STATERS;Nl;0;ON;;;;500;N;;;;;
15012 10154;GREEK ACROPHONIC ATTIC ONE THOUSAND STATERS;Nl;0;ON;;;;1000;N;;;;;
15013 10155;GREEK ACROPHONIC ATTIC TEN THOUSAND STATERS;Nl;0;ON;;;;10000;N;;;;;
15014 10156;GREEK ACROPHONIC ATTIC FIFTY THOUSAND STATERS;Nl;0;ON;;;;50000;N;;;;;
15015 10157;GREEK ACROPHONIC ATTIC TEN MNAS;Nl;0;ON;;;;10;N;;;;;
15016 10158;GREEK ACROPHONIC HERAEUM ONE PLETHRON;Nl;0;ON;;;;1;N;;;;;
15017 10159;GREEK ACROPHONIC THESPIAN ONE;Nl;0;ON;;;;1;N;;;;;
15018 1015A;GREEK ACROPHONIC HERMIONIAN ONE;Nl;0;ON;;;;1;N;;;;;
15019 1015B;GREEK ACROPHONIC EPIDAUREAN TWO;Nl;0;ON;;;;2;N;;;;;
15020 1015C;GREEK ACROPHONIC THESPIAN TWO;Nl;0;ON;;;;2;N;;;;;
15021 1015D;GREEK ACROPHONIC CYRENAIC TWO DRACHMAS;Nl;0;ON;;;;2;N;;;;;
15022 1015E;GREEK ACROPHONIC EPIDAUREAN TWO DRACHMAS;Nl;0;ON;;;;2;N;;;;;
15023 1015F;GREEK ACROPHONIC TROEZENIAN FIVE;Nl;0;ON;;;;5;N;;;;;
15024 10160;GREEK ACROPHONIC TROEZENIAN TEN;Nl;0;ON;;;;10;N;;;;;
15025 10161;GREEK ACROPHONIC TROEZENIAN TEN ALTERNATE FORM;Nl;0;ON;;;;10;N;;;;;
15026 10162;GREEK ACROPHONIC HERMIONIAN TEN;Nl;0;ON;;;;10;N;;;;;
15027 10163;GREEK ACROPHONIC MESSENIAN TEN;Nl;0;ON;;;;10;N;;;;;
15028 10164;GREEK ACROPHONIC THESPIAN TEN;Nl;0;ON;;;;10;N;;;;;
15029 10165;GREEK ACROPHONIC THESPIAN THIRTY;Nl;0;ON;;;;30;N;;;;;
15030 10166;GREEK ACROPHONIC TROEZENIAN FIFTY;Nl;0;ON;;;;50;N;;;;;
15031 10167;GREEK ACROPHONIC TROEZENIAN FIFTY ALTERNATE FORM;Nl;0;ON;;;;50;N;;;;;
15032 10168;GREEK ACROPHONIC HERMIONIAN FIFTY;Nl;0;ON;;;;50;N;;;;;
15033 10169;GREEK ACROPHONIC THESPIAN FIFTY;Nl;0;ON;;;;50;N;;;;;
15034 1016A;GREEK ACROPHONIC THESPIAN ONE HUNDRED;Nl;0;ON;;;;100;N;;;;;
15035 1016B;GREEK ACROPHONIC THESPIAN THREE HUNDRED;Nl;0;ON;;;;300;N;;;;;
15036 1016C;GREEK ACROPHONIC EPIDAUREAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
15037 1016D;GREEK ACROPHONIC TROEZENIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
15038 1016E;GREEK ACROPHONIC THESPIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
15039 1016F;GREEK ACROPHONIC CARYSTIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
15040 10170;GREEK ACROPHONIC NAXIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;
15041 10171;GREEK ACROPHONIC THESPIAN ONE THOUSAND;Nl;0;ON;;;;1000;N;;;;;
15042 10172;GREEK ACROPHONIC THESPIAN FIVE THOUSAND;Nl;0;ON;;;;5000;N;;;;;
15043 10173;GREEK ACROPHONIC DELPHIC FIVE MNAS;Nl;0;ON;;;;5;N;;;;;
15044 10174;GREEK ACROPHONIC STRATIAN FIFTY MNAS;Nl;0;ON;;;;50;N;;;;;
15045 10175;GREEK ONE HALF SIGN;No;0;ON;;;;1/2;N;;;;;
15046 10176;GREEK ONE HALF SIGN ALTERNATE FORM;No;0;ON;;;;1/2;N;;;;;
15047 10177;GREEK TWO THIRDS SIGN;No;0;ON;;;;2/3;N;;;;;
15048 10178;GREEK THREE QUARTERS SIGN;No;0;ON;;;;3/4;N;;;;;
15049 10179;GREEK YEAR SIGN;So;0;ON;;;;;N;;;;;
15050 1017A;GREEK TALENT SIGN;So;0;ON;;;;;N;;;;;
15051 1017B;GREEK DRACHMA SIGN;So;0;ON;;;;;N;;;;;
15052 1017C;GREEK OBOL SIGN;So;0;ON;;;;;N;;;;;
15053 1017D;GREEK TWO OBOLS SIGN;So;0;ON;;;;;N;;;;;
15054 1017E;GREEK THREE OBOLS SIGN;So;0;ON;;;;;N;;;;;
15055 1017F;GREEK FOUR OBOLS SIGN;So;0;ON;;;;;N;;;;;
15056 10180;GREEK FIVE OBOLS SIGN;So;0;ON;;;;;N;;;;;
15057 10181;GREEK METRETES SIGN;So;0;ON;;;;;N;;;;;
15058 10182;GREEK KYATHOS BASE SIGN;So;0;ON;;;;;N;;;;;
15059 10183;GREEK LITRA SIGN;So;0;ON;;;;;N;;;;;
15060 10184;GREEK OUNKIA SIGN;So;0;ON;;;;;N;;;;;
15061 10185;GREEK XESTES SIGN;So;0;ON;;;;;N;;;;;
15062 10186;GREEK ARTABE SIGN;So;0;ON;;;;;N;;;;;
15063 10187;GREEK AROURA SIGN;So;0;ON;;;;;N;;;;;
15064 10188;GREEK GRAMMA SIGN;So;0;ON;;;;;N;;;;;
15065 10189;GREEK TRYBLION BASE SIGN;So;0;ON;;;;;N;;;;;
15066 1018A;GREEK ZERO SIGN;No;0;ON;;;;0;N;;;;;
15067 10190;ROMAN SEXTANS SIGN;So;0;ON;;;;;N;;;;;
15068 10191;ROMAN UNCIA SIGN;So;0;ON;;;;;N;;;;;
15069 10192;ROMAN SEMUNCIA SIGN;So;0;ON;;;;;N;;;;;
15070 10193;ROMAN SEXTULA SIGN;So;0;ON;;;;;N;;;;;
15071 10194;ROMAN DIMIDIA SEXTULA SIGN;So;0;ON;;;;;N;;;;;
15072 10195;ROMAN SILIQUA SIGN;So;0;ON;;;;;N;;;;;
15073 10196;ROMAN DENARIUS SIGN;So;0;ON;;;;;N;;;;;
15074 10197;ROMAN QUINARIUS SIGN;So;0;ON;;;;;N;;;;;
15075 10198;ROMAN SESTERTIUS SIGN;So;0;ON;;;;;N;;;;;
15076 10199;ROMAN DUPONDIUS SIGN;So;0;ON;;;;;N;;;;;
15077 1019A;ROMAN AS SIGN;So;0;ON;;;;;N;;;;;
15078 1019B;ROMAN CENTURIAL SIGN;So;0;ON;;;;;N;;;;;
15079 101D0;PHAISTOS DISC SIGN PEDESTRIAN;So;0;L;;;;;N;;;;;
15080 101D1;PHAISTOS DISC SIGN PLUMED HEAD;So;0;L;;;;;N;;;;;
15081 101D2;PHAISTOS DISC SIGN TATTOOED HEAD;So;0;L;;;;;N;;;;;
15082 101D3;PHAISTOS DISC SIGN CAPTIVE;So;0;L;;;;;N;;;;;
15083 101D4;PHAISTOS DISC SIGN CHILD;So;0;L;;;;;N;;;;;
15084 101D5;PHAISTOS DISC SIGN WOMAN;So;0;L;;;;;N;;;;;
15085 101D6;PHAISTOS DISC SIGN HELMET;So;0;L;;;;;N;;;;;
15086 101D7;PHAISTOS DISC SIGN GAUNTLET;So;0;L;;;;;N;;;;;
15087 101D8;PHAISTOS DISC SIGN TIARA;So;0;L;;;;;N;;;;;
15088 101D9;PHAISTOS DISC SIGN ARROW;So;0;L;;;;;N;;;;;
15089 101DA;PHAISTOS DISC SIGN BOW;So;0;L;;;;;N;;;;;
15090 101DB;PHAISTOS DISC SIGN SHIELD;So;0;L;;;;;N;;;;;
15091 101DC;PHAISTOS DISC SIGN CLUB;So;0;L;;;;;N;;;;;
15092 101DD;PHAISTOS DISC SIGN MANACLES;So;0;L;;;;;N;;;;;
15093 101DE;PHAISTOS DISC SIGN MATTOCK;So;0;L;;;;;N;;;;;
15094 101DF;PHAISTOS DISC SIGN SAW;So;0;L;;;;;N;;;;;
15095 101E0;PHAISTOS DISC SIGN LID;So;0;L;;;;;N;;;;;
15096 101E1;PHAISTOS DISC SIGN BOOMERANG;So;0;L;;;;;N;;;;;
15097 101E2;PHAISTOS DISC SIGN CARPENTRY PLANE;So;0;L;;;;;N;;;;;
15098 101E3;PHAISTOS DISC SIGN DOLIUM;So;0;L;;;;;N;;;;;
15099 101E4;PHAISTOS DISC SIGN COMB;So;0;L;;;;;N;;;;;
15100 101E5;PHAISTOS DISC SIGN SLING;So;0;L;;;;;N;;;;;
15101 101E6;PHAISTOS DISC SIGN COLUMN;So;0;L;;;;;N;;;;;
15102 101E7;PHAISTOS DISC SIGN BEEHIVE;So;0;L;;;;;N;;;;;
15103 101E8;PHAISTOS DISC SIGN SHIP;So;0;L;;;;;N;;;;;
15104 101E9;PHAISTOS DISC SIGN HORN;So;0;L;;;;;N;;;;;
15105 101EA;PHAISTOS DISC SIGN HIDE;So;0;L;;;;;N;;;;;
15106 101EB;PHAISTOS DISC SIGN BULLS LEG;So;0;L;;;;;N;;;;;
15107 101EC;PHAISTOS DISC SIGN CAT;So;0;L;;;;;N;;;;;
15108 101ED;PHAISTOS DISC SIGN RAM;So;0;L;;;;;N;;;;;
15109 101EE;PHAISTOS DISC SIGN EAGLE;So;0;L;;;;;N;;;;;
15110 101EF;PHAISTOS DISC SIGN DOVE;So;0;L;;;;;N;;;;;
15111 101F0;PHAISTOS DISC SIGN TUNNY;So;0;L;;;;;N;;;;;
15112 101F1;PHAISTOS DISC SIGN BEE;So;0;L;;;;;N;;;;;
15113 101F2;PHAISTOS DISC SIGN PLANE TREE;So;0;L;;;;;N;;;;;
15114 101F3;PHAISTOS DISC SIGN VINE;So;0;L;;;;;N;;;;;
15115 101F4;PHAISTOS DISC SIGN PAPYRUS;So;0;L;;;;;N;;;;;
15116 101F5;PHAISTOS DISC SIGN ROSETTE;So;0;L;;;;;N;;;;;
15117 101F6;PHAISTOS DISC SIGN LILY;So;0;L;;;;;N;;;;;
15118 101F7;PHAISTOS DISC SIGN OX BACK;So;0;L;;;;;N;;;;;
15119 101F8;PHAISTOS DISC SIGN FLUTE;So;0;L;;;;;N;;;;;
15120 101F9;PHAISTOS DISC SIGN GRATER;So;0;L;;;;;N;;;;;
15121 101FA;PHAISTOS DISC SIGN STRAINER;So;0;L;;;;;N;;;;;
15122 101FB;PHAISTOS DISC SIGN SMALL AXE;So;0;L;;;;;N;;;;;
15123 101FC;PHAISTOS DISC SIGN WAVY BAND;So;0;L;;;;;N;;;;;
15124 101FD;PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE;Mn;220;NSM;;;;;N;;;;;
15125 10280;LYCIAN LETTER A;Lo;0;L;;;;;N;;;;;
15126 10281;LYCIAN LETTER E;Lo;0;L;;;;;N;;;;;
15127 10282;LYCIAN LETTER B;Lo;0;L;;;;;N;;;;;
15128 10283;LYCIAN LETTER BH;Lo;0;L;;;;;N;;;;;
15129 10284;LYCIAN LETTER G;Lo;0;L;;;;;N;;;;;
15130 10285;LYCIAN LETTER D;Lo;0;L;;;;;N;;;;;
15131 10286;LYCIAN LETTER I;Lo;0;L;;;;;N;;;;;
15132 10287;LYCIAN LETTER W;Lo;0;L;;;;;N;;;;;
15133 10288;LYCIAN LETTER Z;Lo;0;L;;;;;N;;;;;
15134 10289;LYCIAN LETTER TH;Lo;0;L;;;;;N;;;;;
15135 1028A;LYCIAN LETTER J;Lo;0;L;;;;;N;;;;;
15136 1028B;LYCIAN LETTER K;Lo;0;L;;;;;N;;;;;
15137 1028C;LYCIAN LETTER Q;Lo;0;L;;;;;N;;;;;
15138 1028D;LYCIAN LETTER L;Lo;0;L;;;;;N;;;;;
15139 1028E;LYCIAN LETTER M;Lo;0;L;;;;;N;;;;;
15140 1028F;LYCIAN LETTER N;Lo;0;L;;;;;N;;;;;
15141 10290;LYCIAN LETTER MM;Lo;0;L;;;;;N;;;;;
15142 10291;LYCIAN LETTER NN;Lo;0;L;;;;;N;;;;;
15143 10292;LYCIAN LETTER U;Lo;0;L;;;;;N;;;;;
15144 10293;LYCIAN LETTER P;Lo;0;L;;;;;N;;;;;
15145 10294;LYCIAN LETTER KK;Lo;0;L;;;;;N;;;;;
15146 10295;LYCIAN LETTER R;Lo;0;L;;;;;N;;;;;
15147 10296;LYCIAN LETTER S;Lo;0;L;;;;;N;;;;;
15148 10297;LYCIAN LETTER T;Lo;0;L;;;;;N;;;;;
15149 10298;LYCIAN LETTER TT;Lo;0;L;;;;;N;;;;;
15150 10299;LYCIAN LETTER AN;Lo;0;L;;;;;N;;;;;
15151 1029A;LYCIAN LETTER EN;Lo;0;L;;;;;N;;;;;
15152 1029B;LYCIAN LETTER H;Lo;0;L;;;;;N;;;;;
15153 1029C;LYCIAN LETTER X;Lo;0;L;;;;;N;;;;;
15154 102A0;CARIAN LETTER A;Lo;0;L;;;;;N;;;;;
15155 102A1;CARIAN LETTER P2;Lo;0;L;;;;;N;;;;;
15156 102A2;CARIAN LETTER D;Lo;0;L;;;;;N;;;;;
15157 102A3;CARIAN LETTER L;Lo;0;L;;;;;N;;;;;
15158 102A4;CARIAN LETTER UUU;Lo;0;L;;;;;N;;;;;
15159 102A5;CARIAN LETTER R;Lo;0;L;;;;;N;;;;;
15160 102A6;CARIAN LETTER LD;Lo;0;L;;;;;N;;;;;
15161 102A7;CARIAN LETTER A2;Lo;0;L;;;;;N;;;;;
15162 102A8;CARIAN LETTER Q;Lo;0;L;;;;;N;;;;;
15163 102A9;CARIAN LETTER B;Lo;0;L;;;;;N;;;;;
15164 102AA;CARIAN LETTER M;Lo;0;L;;;;;N;;;;;
15165 102AB;CARIAN LETTER O;Lo;0;L;;;;;N;;;;;
15166 102AC;CARIAN LETTER D2;Lo;0;L;;;;;N;;;;;
15167 102AD;CARIAN LETTER T;Lo;0;L;;;;;N;;;;;
15168 102AE;CARIAN LETTER SH;Lo;0;L;;;;;N;;;;;
15169 102AF;CARIAN LETTER SH2;Lo;0;L;;;;;N;;;;;
15170 102B0;CARIAN LETTER S;Lo;0;L;;;;;N;;;;;
15171 102B1;CARIAN LETTER C-18;Lo;0;L;;;;;N;;;;;
15172 102B2;CARIAN LETTER U;Lo;0;L;;;;;N;;;;;
15173 102B3;CARIAN LETTER NN;Lo;0;L;;;;;N;;;;;
15174 102B4;CARIAN LETTER X;Lo;0;L;;;;;N;;;;;
15175 102B5;CARIAN LETTER N;Lo;0;L;;;;;N;;;;;
15176 102B6;CARIAN LETTER TT2;Lo;0;L;;;;;N;;;;;
15177 102B7;CARIAN LETTER P;Lo;0;L;;;;;N;;;;;
15178 102B8;CARIAN LETTER SS;Lo;0;L;;;;;N;;;;;
15179 102B9;CARIAN LETTER I;Lo;0;L;;;;;N;;;;;
15180 102BA;CARIAN LETTER E;Lo;0;L;;;;;N;;;;;
15181 102BB;CARIAN LETTER UUUU;Lo;0;L;;;;;N;;;;;
15182 102BC;CARIAN LETTER K;Lo;0;L;;;;;N;;;;;
15183 102BD;CARIAN LETTER K2;Lo;0;L;;;;;N;;;;;
15184 102BE;CARIAN LETTER ND;Lo;0;L;;;;;N;;;;;
15185 102BF;CARIAN LETTER UU;Lo;0;L;;;;;N;;;;;
15186 102C0;CARIAN LETTER G;Lo;0;L;;;;;N;;;;;
15187 102C1;CARIAN LETTER G2;Lo;0;L;;;;;N;;;;;
15188 102C2;CARIAN LETTER ST;Lo;0;L;;;;;N;;;;;
15189 102C3;CARIAN LETTER ST2;Lo;0;L;;;;;N;;;;;
15190 102C4;CARIAN LETTER NG;Lo;0;L;;;;;N;;;;;
15191 102C5;CARIAN LETTER II;Lo;0;L;;;;;N;;;;;
15192 102C6;CARIAN LETTER C-39;Lo;0;L;;;;;N;;;;;
15193 102C7;CARIAN LETTER TT;Lo;0;L;;;;;N;;;;;
15194 102C8;CARIAN LETTER UUU2;Lo;0;L;;;;;N;;;;;
15195 102C9;CARIAN LETTER RR;Lo;0;L;;;;;N;;;;;
15196 102CA;CARIAN LETTER MB;Lo;0;L;;;;;N;;;;;
15197 102CB;CARIAN LETTER MB2;Lo;0;L;;;;;N;;;;;
15198 102CC;CARIAN LETTER MB3;Lo;0;L;;;;;N;;;;;
15199 102CD;CARIAN LETTER MB4;Lo;0;L;;;;;N;;;;;
15200 102CE;CARIAN LETTER LD2;Lo;0;L;;;;;N;;;;;
15201 102CF;CARIAN LETTER E2;Lo;0;L;;;;;N;;;;;
15202 102D0;CARIAN LETTER UUU3;Lo;0;L;;;;;N;;;;;
15203 10300;OLD ITALIC LETTER A;Lo;0;L;;;;;N;;;;;
15204 10301;OLD ITALIC LETTER BE;Lo;0;L;;;;;N;;;;;
15205 10302;OLD ITALIC LETTER KE;Lo;0;L;;;;;N;;;;;
15206 10303;OLD ITALIC LETTER DE;Lo;0;L;;;;;N;;;;;
15207 10304;OLD ITALIC LETTER E;Lo;0;L;;;;;N;;;;;
15208 10305;OLD ITALIC LETTER VE;Lo;0;L;;;;;N;;;;;
15209 10306;OLD ITALIC LETTER ZE;Lo;0;L;;;;;N;;;;;
15210 10307;OLD ITALIC LETTER HE;Lo;0;L;;;;;N;;;;;
15211 10308;OLD ITALIC LETTER THE;Lo;0;L;;;;;N;;;;;
15212 10309;OLD ITALIC LETTER I;Lo;0;L;;;;;N;;;;;
15213 1030A;OLD ITALIC LETTER KA;Lo;0;L;;;;;N;;;;;
15214 1030B;OLD ITALIC LETTER EL;Lo;0;L;;;;;N;;;;;
15215 1030C;OLD ITALIC LETTER EM;Lo;0;L;;;;;N;;;;;
15216 1030D;OLD ITALIC LETTER EN;Lo;0;L;;;;;N;;;;;
15217 1030E;OLD ITALIC LETTER ESH;Lo;0;L;;;;;N;;;;;
15218 1030F;OLD ITALIC LETTER O;Lo;0;L;;;;;N;;Faliscan;;;
15219 10310;OLD ITALIC LETTER PE;Lo;0;L;;;;;N;;;;;
15220 10311;OLD ITALIC LETTER SHE;Lo;0;L;;;;;N;;;;;
15221 10312;OLD ITALIC LETTER KU;Lo;0;L;;;;;N;;;;;
15222 10313;OLD ITALIC LETTER ER;Lo;0;L;;;;;N;;;;;
15223 10314;OLD ITALIC LETTER ES;Lo;0;L;;;;;N;;;;;
15224 10315;OLD ITALIC LETTER TE;Lo;0;L;;;;;N;;;;;
15225 10316;OLD ITALIC LETTER U;Lo;0;L;;;;;N;;;;;
15226 10317;OLD ITALIC LETTER EKS;Lo;0;L;;;;;N;;Faliscan;;;
15227 10318;OLD ITALIC LETTER PHE;Lo;0;L;;;;;N;;;;;
15228 10319;OLD ITALIC LETTER KHE;Lo;0;L;;;;;N;;;;;
15229 1031A;OLD ITALIC LETTER EF;Lo;0;L;;;;;N;;;;;
15230 1031B;OLD ITALIC LETTER ERS;Lo;0;L;;;;;N;;Umbrian;;;
15231 1031C;OLD ITALIC LETTER CHE;Lo;0;L;;;;;N;;Umbrian;;;
15232 1031D;OLD ITALIC LETTER II;Lo;0;L;;;;;N;;Oscan;;;
15233 1031E;OLD ITALIC LETTER UU;Lo;0;L;;;;;N;;Oscan;;;
15234 10320;OLD ITALIC NUMERAL ONE;No;0;L;;;;1;N;;;;;
15235 10321;OLD ITALIC NUMERAL FIVE;No;0;L;;;;5;N;;;;;
15236 10322;OLD ITALIC NUMERAL TEN;No;0;L;;;;10;N;;;;;
15237 10323;OLD ITALIC NUMERAL FIFTY;No;0;L;;;;50;N;;;;;
15238 10330;GOTHIC LETTER AHSA;Lo;0;L;;;;;N;;;;;
15239 10331;GOTHIC LETTER BAIRKAN;Lo;0;L;;;;;N;;;;;
15240 10332;GOTHIC LETTER GIBA;Lo;0;L;;;;;N;;;;;
15241 10333;GOTHIC LETTER DAGS;Lo;0;L;;;;;N;;;;;
15242 10334;GOTHIC LETTER AIHVUS;Lo;0;L;;;;;N;;;;;
15243 10335;GOTHIC LETTER QAIRTHRA;Lo;0;L;;;;;N;;;;;
15244 10336;GOTHIC LETTER IUJA;Lo;0;L;;;;;N;;;;;
15245 10337;GOTHIC LETTER HAGL;Lo;0;L;;;;;N;;;;;
15246 10338;GOTHIC LETTER THIUTH;Lo;0;L;;;;;N;;;;;
15247 10339;GOTHIC LETTER EIS;Lo;0;L;;;;;N;;;;;
15248 1033A;GOTHIC LETTER KUSMA;Lo;0;L;;;;;N;;;;;
15249 1033B;GOTHIC LETTER LAGUS;Lo;0;L;;;;;N;;;;;
15250 1033C;GOTHIC LETTER MANNA;Lo;0;L;;;;;N;;;;;
15251 1033D;GOTHIC LETTER NAUTHS;Lo;0;L;;;;;N;;;;;
15252 1033E;GOTHIC LETTER JER;Lo;0;L;;;;;N;;;;;
15253 1033F;GOTHIC LETTER URUS;Lo;0;L;;;;;N;;;;;
15254 10340;GOTHIC LETTER PAIRTHRA;Lo;0;L;;;;;N;;;;;
15255 10341;GOTHIC LETTER NINETY;Nl;0;L;;;;90;N;;;;;
15256 10342;GOTHIC LETTER RAIDA;Lo;0;L;;;;;N;;;;;
15257 10343;GOTHIC LETTER SAUIL;Lo;0;L;;;;;N;;;;;
15258 10344;GOTHIC LETTER TEIWS;Lo;0;L;;;;;N;;;;;
15259 10345;GOTHIC LETTER WINJA;Lo;0;L;;;;;N;;;;;
15260 10346;GOTHIC LETTER FAIHU;Lo;0;L;;;;;N;;;;;
15261 10347;GOTHIC LETTER IGGWS;Lo;0;L;;;;;N;;;;;
15262 10348;GOTHIC LETTER HWAIR;Lo;0;L;;;;;N;;;;;
15263 10349;GOTHIC LETTER OTHAL;Lo;0;L;;;;;N;;;;;
15264 1034A;GOTHIC LETTER NINE HUNDRED;Nl;0;L;;;;900;N;;;;;
15265 10380;UGARITIC LETTER ALPA;Lo;0;L;;;;;N;;;;;
15266 10381;UGARITIC LETTER BETA;Lo;0;L;;;;;N;;;;;
15267 10382;UGARITIC LETTER GAMLA;Lo;0;L;;;;;N;;;;;
15268 10383;UGARITIC LETTER KHA;Lo;0;L;;;;;N;;;;;
15269 10384;UGARITIC LETTER DELTA;Lo;0;L;;;;;N;;;;;
15270 10385;UGARITIC LETTER HO;Lo;0;L;;;;;N;;;;;
15271 10386;UGARITIC LETTER WO;Lo;0;L;;;;;N;;;;;
15272 10387;UGARITIC LETTER ZETA;Lo;0;L;;;;;N;;;;;
15273 10388;UGARITIC LETTER HOTA;Lo;0;L;;;;;N;;;;;
15274 10389;UGARITIC LETTER TET;Lo;0;L;;;;;N;;;;;
15275 1038A;UGARITIC LETTER YOD;Lo;0;L;;;;;N;;;;;
15276 1038B;UGARITIC LETTER KAF;Lo;0;L;;;;;N;;;;;
15277 1038C;UGARITIC LETTER SHIN;Lo;0;L;;;;;N;;;;;
15278 1038D;UGARITIC LETTER LAMDA;Lo;0;L;;;;;N;;;;;
15279 1038E;UGARITIC LETTER MEM;Lo;0;L;;;;;N;;;;;
15280 1038F;UGARITIC LETTER DHAL;Lo;0;L;;;;;N;;;;;
15281 10390;UGARITIC LETTER NUN;Lo;0;L;;;;;N;;;;;
15282 10391;UGARITIC LETTER ZU;Lo;0;L;;;;;N;;;;;
15283 10392;UGARITIC LETTER SAMKA;Lo;0;L;;;;;N;;;;;
15284 10393;UGARITIC LETTER AIN;Lo;0;L;;;;;N;;;;;
15285 10394;UGARITIC LETTER PU;Lo;0;L;;;;;N;;;;;
15286 10395;UGARITIC LETTER SADE;Lo;0;L;;;;;N;;;;;
15287 10396;UGARITIC LETTER QOPA;Lo;0;L;;;;;N;;;;;
15288 10397;UGARITIC LETTER RASHA;Lo;0;L;;;;;N;;;;;
15289 10398;UGARITIC LETTER THANNA;Lo;0;L;;;;;N;;;;;
15290 10399;UGARITIC LETTER GHAIN;Lo;0;L;;;;;N;;;;;
15291 1039A;UGARITIC LETTER TO;Lo;0;L;;;;;N;;;;;
15292 1039B;UGARITIC LETTER I;Lo;0;L;;;;;N;;;;;
15293 1039C;UGARITIC LETTER U;Lo;0;L;;;;;N;;;;;
15294 1039D;UGARITIC LETTER SSU;Lo;0;L;;;;;N;;;;;
15295 1039F;UGARITIC WORD DIVIDER;Po;0;L;;;;;N;;;;;
15296 103A0;OLD PERSIAN SIGN A;Lo;0;L;;;;;N;;;;;
15297 103A1;OLD PERSIAN SIGN I;Lo;0;L;;;;;N;;;;;
15298 103A2;OLD PERSIAN SIGN U;Lo;0;L;;;;;N;;;;;
15299 103A3;OLD PERSIAN SIGN KA;Lo;0;L;;;;;N;;;;;
15300 103A4;OLD PERSIAN SIGN KU;Lo;0;L;;;;;N;;;;;
15301 103A5;OLD PERSIAN SIGN GA;Lo;0;L;;;;;N;;;;;
15302 103A6;OLD PERSIAN SIGN GU;Lo;0;L;;;;;N;;;;;
15303 103A7;OLD PERSIAN SIGN XA;Lo;0;L;;;;;N;;;;;
15304 103A8;OLD PERSIAN SIGN CA;Lo;0;L;;;;;N;;;;;
15305 103A9;OLD PERSIAN SIGN JA;Lo;0;L;;;;;N;;;;;
15306 103AA;OLD PERSIAN SIGN JI;Lo;0;L;;;;;N;;;;;
15307 103AB;OLD PERSIAN SIGN TA;Lo;0;L;;;;;N;;;;;
15308 103AC;OLD PERSIAN SIGN TU;Lo;0;L;;;;;N;;;;;
15309 103AD;OLD PERSIAN SIGN DA;Lo;0;L;;;;;N;;;;;
15310 103AE;OLD PERSIAN SIGN DI;Lo;0;L;;;;;N;;;;;
15311 103AF;OLD PERSIAN SIGN DU;Lo;0;L;;;;;N;;;;;
15312 103B0;OLD PERSIAN SIGN THA;Lo;0;L;;;;;N;;;;;
15313 103B1;OLD PERSIAN SIGN PA;Lo;0;L;;;;;N;;;;;
15314 103B2;OLD PERSIAN SIGN BA;Lo;0;L;;;;;N;;;;;
15315 103B3;OLD PERSIAN SIGN FA;Lo;0;L;;;;;N;;;;;
15316 103B4;OLD PERSIAN SIGN NA;Lo;0;L;;;;;N;;;;;
15317 103B5;OLD PERSIAN SIGN NU;Lo;0;L;;;;;N;;;;;
15318 103B6;OLD PERSIAN SIGN MA;Lo;0;L;;;;;N;;;;;
15319 103B7;OLD PERSIAN SIGN MI;Lo;0;L;;;;;N;;;;;
15320 103B8;OLD PERSIAN SIGN MU;Lo;0;L;;;;;N;;;;;
15321 103B9;OLD PERSIAN SIGN YA;Lo;0;L;;;;;N;;;;;
15322 103BA;OLD PERSIAN SIGN VA;Lo;0;L;;;;;N;;;;;
15323 103BB;OLD PERSIAN SIGN VI;Lo;0;L;;;;;N;;;;;
15324 103BC;OLD PERSIAN SIGN RA;Lo;0;L;;;;;N;;;;;
15325 103BD;OLD PERSIAN SIGN RU;Lo;0;L;;;;;N;;;;;
15326 103BE;OLD PERSIAN SIGN LA;Lo;0;L;;;;;N;;;;;
15327 103BF;OLD PERSIAN SIGN SA;Lo;0;L;;;;;N;;;;;
15328 103C0;OLD PERSIAN SIGN ZA;Lo;0;L;;;;;N;;;;;
15329 103C1;OLD PERSIAN SIGN SHA;Lo;0;L;;;;;N;;;;;
15330 103C2;OLD PERSIAN SIGN SSA;Lo;0;L;;;;;N;;;;;
15331 103C3;OLD PERSIAN SIGN HA;Lo;0;L;;;;;N;;;;;
15332 103C8;OLD PERSIAN SIGN AURAMAZDAA;Lo;0;L;;;;;N;;;;;
15333 103C9;OLD PERSIAN SIGN AURAMAZDAA-2;Lo;0;L;;;;;N;;;;;
15334 103CA;OLD PERSIAN SIGN AURAMAZDAAHA;Lo;0;L;;;;;N;;;;;
15335 103CB;OLD PERSIAN SIGN XSHAAYATHIYA;Lo;0;L;;;;;N;;;;;
15336 103CC;OLD PERSIAN SIGN DAHYAAUSH;Lo;0;L;;;;;N;;;;;
15337 103CD;OLD PERSIAN SIGN DAHYAAUSH-2;Lo;0;L;;;;;N;;;;;
15338 103CE;OLD PERSIAN SIGN BAGA;Lo;0;L;;;;;N;;;;;
15339 103CF;OLD PERSIAN SIGN BUUMISH;Lo;0;L;;;;;N;;;;;
15340 103D0;OLD PERSIAN WORD DIVIDER;Po;0;L;;;;;N;;;;;
15341 103D1;OLD PERSIAN NUMBER ONE;Nl;0;L;;;;1;N;;;;;
15342 103D2;OLD PERSIAN NUMBER TWO;Nl;0;L;;;;2;N;;;;;
15343 103D3;OLD PERSIAN NUMBER TEN;Nl;0;L;;;;10;N;;;;;
15344 103D4;OLD PERSIAN NUMBER TWENTY;Nl;0;L;;;;20;N;;;;;
15345 103D5;OLD PERSIAN NUMBER HUNDRED;Nl;0;L;;;;100;N;;;;;
15346 10400;DESERET CAPITAL LETTER LONG I;Lu;0;L;;;;;N;;;;10428;
15347 10401;DESERET CAPITAL LETTER LONG E;Lu;0;L;;;;;N;;;;10429;
15348 10402;DESERET CAPITAL LETTER LONG A;Lu;0;L;;;;;N;;;;1042A;
15349 10403;DESERET CAPITAL LETTER LONG AH;Lu;0;L;;;;;N;;;;1042B;
15350 10404;DESERET CAPITAL LETTER LONG O;Lu;0;L;;;;;N;;;;1042C;
15351 10405;DESERET CAPITAL LETTER LONG OO;Lu;0;L;;;;;N;;;;1042D;
15352 10406;DESERET CAPITAL LETTER SHORT I;Lu;0;L;;;;;N;;;;1042E;
15353 10407;DESERET CAPITAL LETTER SHORT E;Lu;0;L;;;;;N;;;;1042F;
15354 10408;DESERET CAPITAL LETTER SHORT A;Lu;0;L;;;;;N;;;;10430;
15355 10409;DESERET CAPITAL LETTER SHORT AH;Lu;0;L;;;;;N;;;;10431;
15356 1040A;DESERET CAPITAL LETTER SHORT O;Lu;0;L;;;;;N;;;;10432;
15357 1040B;DESERET CAPITAL LETTER SHORT OO;Lu;0;L;;;;;N;;;;10433;
15358 1040C;DESERET CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;10434;
15359 1040D;DESERET CAPITAL LETTER OW;Lu;0;L;;;;;N;;;;10435;
15360 1040E;DESERET CAPITAL LETTER WU;Lu;0;L;;;;;N;;;;10436;
15361 1040F;DESERET CAPITAL LETTER YEE;Lu;0;L;;;;;N;;;;10437;
15362 10410;DESERET CAPITAL LETTER H;Lu;0;L;;;;;N;;;;10438;
15363 10411;DESERET CAPITAL LETTER PEE;Lu;0;L;;;;;N;;;;10439;
15364 10412;DESERET CAPITAL LETTER BEE;Lu;0;L;;;;;N;;;;1043A;
15365 10413;DESERET CAPITAL LETTER TEE;Lu;0;L;;;;;N;;;;1043B;
15366 10414;DESERET CAPITAL LETTER DEE;Lu;0;L;;;;;N;;;;1043C;
15367 10415;DESERET CAPITAL LETTER CHEE;Lu;0;L;;;;;N;;;;1043D;
15368 10416;DESERET CAPITAL LETTER JEE;Lu;0;L;;;;;N;;;;1043E;
15369 10417;DESERET CAPITAL LETTER KAY;Lu;0;L;;;;;N;;;;1043F;
15370 10418;DESERET CAPITAL LETTER GAY;Lu;0;L;;;;;N;;;;10440;
15371 10419;DESERET CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;10441;
15372 1041A;DESERET CAPITAL LETTER VEE;Lu;0;L;;;;;N;;;;10442;
15373 1041B;DESERET CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;10443;
15374 1041C;DESERET CAPITAL LETTER THEE;Lu;0;L;;;;;N;;;;10444;
15375 1041D;DESERET CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;10445;
15376 1041E;DESERET CAPITAL LETTER ZEE;Lu;0;L;;;;;N;;;;10446;
15377 1041F;DESERET CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;10447;
15378 10420;DESERET CAPITAL LETTER ZHEE;Lu;0;L;;;;;N;;;;10448;
15379 10421;DESERET CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;10449;
15380 10422;DESERET CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;1044A;
15381 10423;DESERET CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;1044B;
15382 10424;DESERET CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;1044C;
15383 10425;DESERET CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;1044D;
15384 10426;DESERET CAPITAL LETTER OI;Lu;0;L;;;;;N;;;;1044E;
15385 10427;DESERET CAPITAL LETTER EW;Lu;0;L;;;;;N;;;;1044F;
15386 10428;DESERET SMALL LETTER LONG I;Ll;0;L;;;;;N;;;10400;;10400
15387 10429;DESERET SMALL LETTER LONG E;Ll;0;L;;;;;N;;;10401;;10401
15388 1042A;DESERET SMALL LETTER LONG A;Ll;0;L;;;;;N;;;10402;;10402
15389 1042B;DESERET SMALL LETTER LONG AH;Ll;0;L;;;;;N;;;10403;;10403
15390 1042C;DESERET SMALL LETTER LONG O;Ll;0;L;;;;;N;;;10404;;10404
15391 1042D;DESERET SMALL LETTER LONG OO;Ll;0;L;;;;;N;;;10405;;10405
15392 1042E;DESERET SMALL LETTER SHORT I;Ll;0;L;;;;;N;;;10406;;10406
15393 1042F;DESERET SMALL LETTER SHORT E;Ll;0;L;;;;;N;;;10407;;10407
15394 10430;DESERET SMALL LETTER SHORT A;Ll;0;L;;;;;N;;;10408;;10408
15395 10431;DESERET SMALL LETTER SHORT AH;Ll;0;L;;;;;N;;;10409;;10409
15396 10432;DESERET SMALL LETTER SHORT O;Ll;0;L;;;;;N;;;1040A;;1040A
15397 10433;DESERET SMALL LETTER SHORT OO;Ll;0;L;;;;;N;;;1040B;;1040B
15398 10434;DESERET SMALL LETTER AY;Ll;0;L;;;;;N;;;1040C;;1040C
15399 10435;DESERET SMALL LETTER OW;Ll;0;L;;;;;N;;;1040D;;1040D
15400 10436;DESERET SMALL LETTER WU;Ll;0;L;;;;;N;;;1040E;;1040E
15401 10437;DESERET SMALL LETTER YEE;Ll;0;L;;;;;N;;;1040F;;1040F
15402 10438;DESERET SMALL LETTER H;Ll;0;L;;;;;N;;;10410;;10410
15403 10439;DESERET SMALL LETTER PEE;Ll;0;L;;;;;N;;;10411;;10411
15404 1043A;DESERET SMALL LETTER BEE;Ll;0;L;;;;;N;;;10412;;10412
15405 1043B;DESERET SMALL LETTER TEE;Ll;0;L;;;;;N;;;10413;;10413
15406 1043C;DESERET SMALL LETTER DEE;Ll;0;L;;;;;N;;;10414;;10414
15407 1043D;DESERET SMALL LETTER CHEE;Ll;0;L;;;;;N;;;10415;;10415
15408 1043E;DESERET SMALL LETTER JEE;Ll;0;L;;;;;N;;;10416;;10416
15409 1043F;DESERET SMALL LETTER KAY;Ll;0;L;;;;;N;;;10417;;10417
15410 10440;DESERET SMALL LETTER GAY;Ll;0;L;;;;;N;;;10418;;10418
15411 10441;DESERET SMALL LETTER EF;Ll;0;L;;;;;N;;;10419;;10419
15412 10442;DESERET SMALL LETTER VEE;Ll;0;L;;;;;N;;;1041A;;1041A
15413 10443;DESERET SMALL LETTER ETH;Ll;0;L;;;;;N;;;1041B;;1041B
15414 10444;DESERET SMALL LETTER THEE;Ll;0;L;;;;;N;;;1041C;;1041C
15415 10445;DESERET SMALL LETTER ES;Ll;0;L;;;;;N;;;1041D;;1041D
15416 10446;DESERET SMALL LETTER ZEE;Ll;0;L;;;;;N;;;1041E;;1041E
15417 10447;DESERET SMALL LETTER ESH;Ll;0;L;;;;;N;;;1041F;;1041F
15418 10448;DESERET SMALL LETTER ZHEE;Ll;0;L;;;;;N;;;10420;;10420
15419 10449;DESERET SMALL LETTER ER;Ll;0;L;;;;;N;;;10421;;10421
15420 1044A;DESERET SMALL LETTER EL;Ll;0;L;;;;;N;;;10422;;10422
15421 1044B;DESERET SMALL LETTER EM;Ll;0;L;;;;;N;;;10423;;10423
15422 1044C;DESERET SMALL LETTER EN;Ll;0;L;;;;;N;;;10424;;10424
15423 1044D;DESERET SMALL LETTER ENG;Ll;0;L;;;;;N;;;10425;;10425
15424 1044E;DESERET SMALL LETTER OI;Ll;0;L;;;;;N;;;10426;;10426
15425 1044F;DESERET SMALL LETTER EW;Ll;0;L;;;;;N;;;10427;;10427
15426 10450;SHAVIAN LETTER PEEP;Lo;0;L;;;;;N;;;;;
15427 10451;SHAVIAN LETTER TOT;Lo;0;L;;;;;N;;;;;
15428 10452;SHAVIAN LETTER KICK;Lo;0;L;;;;;N;;;;;
15429 10453;SHAVIAN LETTER FEE;Lo;0;L;;;;;N;;;;;
15430 10454;SHAVIAN LETTER THIGH;Lo;0;L;;;;;N;;;;;
15431 10455;SHAVIAN LETTER SO;Lo;0;L;;;;;N;;;;;
15432 10456;SHAVIAN LETTER SURE;Lo;0;L;;;;;N;;;;;
15433 10457;SHAVIAN LETTER CHURCH;Lo;0;L;;;;;N;;;;;
15434 10458;SHAVIAN LETTER YEA;Lo;0;L;;;;;N;;;;;
15435 10459;SHAVIAN LETTER HUNG;Lo;0;L;;;;;N;;;;;
15436 1045A;SHAVIAN LETTER BIB;Lo;0;L;;;;;N;;;;;
15437 1045B;SHAVIAN LETTER DEAD;Lo;0;L;;;;;N;;;;;
15438 1045C;SHAVIAN LETTER GAG;Lo;0;L;;;;;N;;;;;
15439 1045D;SHAVIAN LETTER VOW;Lo;0;L;;;;;N;;;;;
15440 1045E;SHAVIAN LETTER THEY;Lo;0;L;;;;;N;;;;;
15441 1045F;SHAVIAN LETTER ZOO;Lo;0;L;;;;;N;;;;;
15442 10460;SHAVIAN LETTER MEASURE;Lo;0;L;;;;;N;;;;;
15443 10461;SHAVIAN LETTER JUDGE;Lo;0;L;;;;;N;;;;;
15444 10462;SHAVIAN LETTER WOE;Lo;0;L;;;;;N;;;;;
15445 10463;SHAVIAN LETTER HA-HA;Lo;0;L;;;;;N;;;;;
15446 10464;SHAVIAN LETTER LOLL;Lo;0;L;;;;;N;;;;;
15447 10465;SHAVIAN LETTER MIME;Lo;0;L;;;;;N;;;;;
15448 10466;SHAVIAN LETTER IF;Lo;0;L;;;;;N;;;;;
15449 10467;SHAVIAN LETTER EGG;Lo;0;L;;;;;N;;;;;
15450 10468;SHAVIAN LETTER ASH;Lo;0;L;;;;;N;;;;;
15451 10469;SHAVIAN LETTER ADO;Lo;0;L;;;;;N;;;;;
15452 1046A;SHAVIAN LETTER ON;Lo;0;L;;;;;N;;;;;
15453 1046B;SHAVIAN LETTER WOOL;Lo;0;L;;;;;N;;;;;
15454 1046C;SHAVIAN LETTER OUT;Lo;0;L;;;;;N;;;;;
15455 1046D;SHAVIAN LETTER AH;Lo;0;L;;;;;N;;;;;
15456 1046E;SHAVIAN LETTER ROAR;Lo;0;L;;;;;N;;;;;
15457 1046F;SHAVIAN LETTER NUN;Lo;0;L;;;;;N;;;;;
15458 10470;SHAVIAN LETTER EAT;Lo;0;L;;;;;N;;;;;
15459 10471;SHAVIAN LETTER AGE;Lo;0;L;;;;;N;;;;;
15460 10472;SHAVIAN LETTER ICE;Lo;0;L;;;;;N;;;;;
15461 10473;SHAVIAN LETTER UP;Lo;0;L;;;;;N;;;;;
15462 10474;SHAVIAN LETTER OAK;Lo;0;L;;;;;N;;;;;
15463 10475;SHAVIAN LETTER OOZE;Lo;0;L;;;;;N;;;;;
15464 10476;SHAVIAN LETTER OIL;Lo;0;L;;;;;N;;;;;
15465 10477;SHAVIAN LETTER AWE;Lo;0;L;;;;;N;;;;;
15466 10478;SHAVIAN LETTER ARE;Lo;0;L;;;;;N;;;;;
15467 10479;SHAVIAN LETTER OR;Lo;0;L;;;;;N;;;;;
15468 1047A;SHAVIAN LETTER AIR;Lo;0;L;;;;;N;;;;;
15469 1047B;SHAVIAN LETTER ERR;Lo;0;L;;;;;N;;;;;
15470 1047C;SHAVIAN LETTER ARRAY;Lo;0;L;;;;;N;;;;;
15471 1047D;SHAVIAN LETTER EAR;Lo;0;L;;;;;N;;;;;
15472 1047E;SHAVIAN LETTER IAN;Lo;0;L;;;;;N;;;;;
15473 1047F;SHAVIAN LETTER YEW;Lo;0;L;;;;;N;;;;;
15474 10480;OSMANYA LETTER ALEF;Lo;0;L;;;;;N;;;;;
15475 10481;OSMANYA LETTER BA;Lo;0;L;;;;;N;;;;;
15476 10482;OSMANYA LETTER TA;Lo;0;L;;;;;N;;;;;
15477 10483;OSMANYA LETTER JA;Lo;0;L;;;;;N;;;;;
15478 10484;OSMANYA LETTER XA;Lo;0;L;;;;;N;;;;;
15479 10485;OSMANYA LETTER KHA;Lo;0;L;;;;;N;;;;;
15480 10486;OSMANYA LETTER DEEL;Lo;0;L;;;;;N;;;;;
15481 10487;OSMANYA LETTER RA;Lo;0;L;;;;;N;;;;;
15482 10488;OSMANYA LETTER SA;Lo;0;L;;;;;N;;;;;
15483 10489;OSMANYA LETTER SHIIN;Lo;0;L;;;;;N;;;;;
15484 1048A;OSMANYA LETTER DHA;Lo;0;L;;;;;N;;;;;
15485 1048B;OSMANYA LETTER CAYN;Lo;0;L;;;;;N;;;;;
15486 1048C;OSMANYA LETTER GA;Lo;0;L;;;;;N;;;;;
15487 1048D;OSMANYA LETTER FA;Lo;0;L;;;;;N;;;;;
15488 1048E;OSMANYA LETTER QAAF;Lo;0;L;;;;;N;;;;;
15489 1048F;OSMANYA LETTER KAAF;Lo;0;L;;;;;N;;;;;
15490 10490;OSMANYA LETTER LAAN;Lo;0;L;;;;;N;;;;;
15491 10491;OSMANYA LETTER MIIN;Lo;0;L;;;;;N;;;;;
15492 10492;OSMANYA LETTER NUUN;Lo;0;L;;;;;N;;;;;
15493 10493;OSMANYA LETTER WAW;Lo;0;L;;;;;N;;;;;
15494 10494;OSMANYA LETTER HA;Lo;0;L;;;;;N;;;;;
15495 10495;OSMANYA LETTER YA;Lo;0;L;;;;;N;;;;;
15496 10496;OSMANYA LETTER A;Lo;0;L;;;;;N;;;;;
15497 10497;OSMANYA LETTER E;Lo;0;L;;;;;N;;;;;
15498 10498;OSMANYA LETTER I;Lo;0;L;;;;;N;;;;;
15499 10499;OSMANYA LETTER O;Lo;0;L;;;;;N;;;;;
15500 1049A;OSMANYA LETTER U;Lo;0;L;;;;;N;;;;;
15501 1049B;OSMANYA LETTER AA;Lo;0;L;;;;;N;;;;;
15502 1049C;OSMANYA LETTER EE;Lo;0;L;;;;;N;;;;;
15503 1049D;OSMANYA LETTER OO;Lo;0;L;;;;;N;;;;;
15504 104A0;OSMANYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;
15505 104A1;OSMANYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
15506 104A2;OSMANYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;
15507 104A3;OSMANYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;
15508 104A4;OSMANYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;
15509 104A5;OSMANYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;
15510 104A6;OSMANYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;
15511 104A7;OSMANYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
15512 104A8;OSMANYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
15513 104A9;OSMANYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
15514 10800;CYPRIOT SYLLABLE A;Lo;0;R;;;;;N;;;;;
15515 10801;CYPRIOT SYLLABLE E;Lo;0;R;;;;;N;;;;;
15516 10802;CYPRIOT SYLLABLE I;Lo;0;R;;;;;N;;;;;
15517 10803;CYPRIOT SYLLABLE O;Lo;0;R;;;;;N;;;;;
15518 10804;CYPRIOT SYLLABLE U;Lo;0;R;;;;;N;;;;;
15519 10805;CYPRIOT SYLLABLE JA;Lo;0;R;;;;;N;;;;;
15520 10808;CYPRIOT SYLLABLE JO;Lo;0;R;;;;;N;;;;;
15521 1080A;CYPRIOT SYLLABLE KA;Lo;0;R;;;;;N;;;;;
15522 1080B;CYPRIOT SYLLABLE KE;Lo;0;R;;;;;N;;;;;
15523 1080C;CYPRIOT SYLLABLE KI;Lo;0;R;;;;;N;;;;;
15524 1080D;CYPRIOT SYLLABLE KO;Lo;0;R;;;;;N;;;;;
15525 1080E;CYPRIOT SYLLABLE KU;Lo;0;R;;;;;N;;;;;
15526 1080F;CYPRIOT SYLLABLE LA;Lo;0;R;;;;;N;;;;;
15527 10810;CYPRIOT SYLLABLE LE;Lo;0;R;;;;;N;;;;;
15528 10811;CYPRIOT SYLLABLE LI;Lo;0;R;;;;;N;;;;;
15529 10812;CYPRIOT SYLLABLE LO;Lo;0;R;;;;;N;;;;;
15530 10813;CYPRIOT SYLLABLE LU;Lo;0;R;;;;;N;;;;;
15531 10814;CYPRIOT SYLLABLE MA;Lo;0;R;;;;;N;;;;;
15532 10815;CYPRIOT SYLLABLE ME;Lo;0;R;;;;;N;;;;;
15533 10816;CYPRIOT SYLLABLE MI;Lo;0;R;;;;;N;;;;;
15534 10817;CYPRIOT SYLLABLE MO;Lo;0;R;;;;;N;;;;;
15535 10818;CYPRIOT SYLLABLE MU;Lo;0;R;;;;;N;;;;;
15536 10819;CYPRIOT SYLLABLE NA;Lo;0;R;;;;;N;;;;;
15537 1081A;CYPRIOT SYLLABLE NE;Lo;0;R;;;;;N;;;;;
15538 1081B;CYPRIOT SYLLABLE NI;Lo;0;R;;;;;N;;;;;
15539 1081C;CYPRIOT SYLLABLE NO;Lo;0;R;;;;;N;;;;;
15540 1081D;CYPRIOT SYLLABLE NU;Lo;0;R;;;;;N;;;;;
15541 1081E;CYPRIOT SYLLABLE PA;Lo;0;R;;;;;N;;;;;
15542 1081F;CYPRIOT SYLLABLE PE;Lo;0;R;;;;;N;;;;;
15543 10820;CYPRIOT SYLLABLE PI;Lo;0;R;;;;;N;;;;;
15544 10821;CYPRIOT SYLLABLE PO;Lo;0;R;;;;;N;;;;;
15545 10822;CYPRIOT SYLLABLE PU;Lo;0;R;;;;;N;;;;;
15546 10823;CYPRIOT SYLLABLE RA;Lo;0;R;;;;;N;;;;;
15547 10824;CYPRIOT SYLLABLE RE;Lo;0;R;;;;;N;;;;;
15548 10825;CYPRIOT SYLLABLE RI;Lo;0;R;;;;;N;;;;;
15549 10826;CYPRIOT SYLLABLE RO;Lo;0;R;;;;;N;;;;;
15550 10827;CYPRIOT SYLLABLE RU;Lo;0;R;;;;;N;;;;;
15551 10828;CYPRIOT SYLLABLE SA;Lo;0;R;;;;;N;;;;;
15552 10829;CYPRIOT SYLLABLE SE;Lo;0;R;;;;;N;;;;;
15553 1082A;CYPRIOT SYLLABLE SI;Lo;0;R;;;;;N;;;;;
15554 1082B;CYPRIOT SYLLABLE SO;Lo;0;R;;;;;N;;;;;
15555 1082C;CYPRIOT SYLLABLE SU;Lo;0;R;;;;;N;;;;;
15556 1082D;CYPRIOT SYLLABLE TA;Lo;0;R;;;;;N;;;;;
15557 1082E;CYPRIOT SYLLABLE TE;Lo;0;R;;;;;N;;;;;
15558 1082F;CYPRIOT SYLLABLE TI;Lo;0;R;;;;;N;;;;;
15559 10830;CYPRIOT SYLLABLE TO;Lo;0;R;;;;;N;;;;;
15560 10831;CYPRIOT SYLLABLE TU;Lo;0;R;;;;;N;;;;;
15561 10832;CYPRIOT SYLLABLE WA;Lo;0;R;;;;;N;;;;;
15562 10833;CYPRIOT SYLLABLE WE;Lo;0;R;;;;;N;;;;;
15563 10834;CYPRIOT SYLLABLE WI;Lo;0;R;;;;;N;;;;;
15564 10835;CYPRIOT SYLLABLE WO;Lo;0;R;;;;;N;;;;;
15565 10837;CYPRIOT SYLLABLE XA;Lo;0;R;;;;;N;;;;;
15566 10838;CYPRIOT SYLLABLE XE;Lo;0;R;;;;;N;;;;;
15567 1083C;CYPRIOT SYLLABLE ZA;Lo;0;R;;;;;N;;;;;
15568 1083F;CYPRIOT SYLLABLE ZO;Lo;0;R;;;;;N;;;;;
15569 10900;PHOENICIAN LETTER ALF;Lo;0;R;;;;;N;;;;;
15570 10901;PHOENICIAN LETTER BET;Lo;0;R;;;;;N;;;;;
15571 10902;PHOENICIAN LETTER GAML;Lo;0;R;;;;;N;;;;;
15572 10903;PHOENICIAN LETTER DELT;Lo;0;R;;;;;N;;;;;
15573 10904;PHOENICIAN LETTER HE;Lo;0;R;;;;;N;;;;;
15574 10905;PHOENICIAN LETTER WAU;Lo;0;R;;;;;N;;;;;
15575 10906;PHOENICIAN LETTER ZAI;Lo;0;R;;;;;N;;;;;
15576 10907;PHOENICIAN LETTER HET;Lo;0;R;;;;;N;;;;;
15577 10908;PHOENICIAN LETTER TET;Lo;0;R;;;;;N;;;;;
15578 10909;PHOENICIAN LETTER YOD;Lo;0;R;;;;;N;;;;;
15579 1090A;PHOENICIAN LETTER KAF;Lo;0;R;;;;;N;;;;;
15580 1090B;PHOENICIAN LETTER LAMD;Lo;0;R;;;;;N;;;;;
15581 1090C;PHOENICIAN LETTER MEM;Lo;0;R;;;;;N;;;;;
15582 1090D;PHOENICIAN LETTER NUN;Lo;0;R;;;;;N;;;;;
15583 1090E;PHOENICIAN LETTER SEMK;Lo;0;R;;;;;N;;;;;
15584 1090F;PHOENICIAN LETTER AIN;Lo;0;R;;;;;N;;;;;
15585 10910;PHOENICIAN LETTER PE;Lo;0;R;;;;;N;;;;;
15586 10911;PHOENICIAN LETTER SADE;Lo;0;R;;;;;N;;;;;
15587 10912;PHOENICIAN LETTER QOF;Lo;0;R;;;;;N;;;;;
15588 10913;PHOENICIAN LETTER ROSH;Lo;0;R;;;;;N;;;;;
15589 10914;PHOENICIAN LETTER SHIN;Lo;0;R;;;;;N;;;;;
15590 10915;PHOENICIAN LETTER TAU;Lo;0;R;;;;;N;;;;;
15591 10916;PHOENICIAN NUMBER ONE;No;0;R;;;;1;N;;;;;
15592 10917;PHOENICIAN NUMBER TEN;No;0;R;;;;10;N;;;;;
15593 10918;PHOENICIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;
15594 10919;PHOENICIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
15595 1091F;PHOENICIAN WORD SEPARATOR;Po;0;ON;;;;;N;;;;;
15596 10920;LYDIAN LETTER A;Lo;0;R;;;;;N;;;;;
15597 10921;LYDIAN LETTER B;Lo;0;R;;;;;N;;;;;
15598 10922;LYDIAN LETTER G;Lo;0;R;;;;;N;;;;;
15599 10923;LYDIAN LETTER D;Lo;0;R;;;;;N;;;;;
15600 10924;LYDIAN LETTER E;Lo;0;R;;;;;N;;;;;
15601 10925;LYDIAN LETTER V;Lo;0;R;;;;;N;;;;;
15602 10926;LYDIAN LETTER I;Lo;0;R;;;;;N;;;;;
15603 10927;LYDIAN LETTER Y;Lo;0;R;;;;;N;;;;;
15604 10928;LYDIAN LETTER K;Lo;0;R;;;;;N;;;;;
15605 10929;LYDIAN LETTER L;Lo;0;R;;;;;N;;;;;
15606 1092A;LYDIAN LETTER M;Lo;0;R;;;;;N;;;;;
15607 1092B;LYDIAN LETTER N;Lo;0;R;;;;;N;;;;;
15608 1092C;LYDIAN LETTER O;Lo;0;R;;;;;N;;;;;
15609 1092D;LYDIAN LETTER R;Lo;0;R;;;;;N;;;;;
15610 1092E;LYDIAN LETTER SS;Lo;0;R;;;;;N;;;;;
15611 1092F;LYDIAN LETTER T;Lo;0;R;;;;;N;;;;;
15612 10930;LYDIAN LETTER U;Lo;0;R;;;;;N;;;;;
15613 10931;LYDIAN LETTER F;Lo;0;R;;;;;N;;;;;
15614 10932;LYDIAN LETTER Q;Lo;0;R;;;;;N;;;;;
15615 10933;LYDIAN LETTER S;Lo;0;R;;;;;N;;;;;
15616 10934;LYDIAN LETTER TT;Lo;0;R;;;;;N;;;;;
15617 10935;LYDIAN LETTER AN;Lo;0;R;;;;;N;;;;;
15618 10936;LYDIAN LETTER EN;Lo;0;R;;;;;N;;;;;
15619 10937;LYDIAN LETTER LY;Lo;0;R;;;;;N;;;;;
15620 10938;LYDIAN LETTER NN;Lo;0;R;;;;;N;;;;;
15621 10939;LYDIAN LETTER C;Lo;0;R;;;;;N;;;;;
15622 1093F;LYDIAN TRIANGULAR MARK;Po;0;R;;;;;N;;;;;
15623 10A00;KHAROSHTHI LETTER A;Lo;0;R;;;;;N;;;;;
15624 10A01;KHAROSHTHI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;
15625 10A02;KHAROSHTHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;
15626 10A03;KHAROSHTHI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;
15627 10A05;KHAROSHTHI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;
15628 10A06;KHAROSHTHI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;
15629 10A0C;KHAROSHTHI VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;;
15630 10A0D;KHAROSHTHI SIGN DOUBLE RING BELOW;Mn;220;NSM;;;;;N;;;;;
15631 10A0E;KHAROSHTHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;
15632 10A0F;KHAROSHTHI SIGN VISARGA;Mn;230;NSM;;;;;N;;;;;
15633 10A10;KHAROSHTHI LETTER KA;Lo;0;R;;;;;N;;;;;
15634 10A11;KHAROSHTHI LETTER KHA;Lo;0;R;;;;;N;;;;;
15635 10A12;KHAROSHTHI LETTER GA;Lo;0;R;;;;;N;;;;;
15636 10A13;KHAROSHTHI LETTER GHA;Lo;0;R;;;;;N;;;;;
15637 10A15;KHAROSHTHI LETTER CA;Lo;0;R;;;;;N;;;;;
15638 10A16;KHAROSHTHI LETTER CHA;Lo;0;R;;;;;N;;;;;
15639 10A17;KHAROSHTHI LETTER JA;Lo;0;R;;;;;N;;;;;
15640 10A19;KHAROSHTHI LETTER NYA;Lo;0;R;;;;;N;;;;;
15641 10A1A;KHAROSHTHI LETTER TTA;Lo;0;R;;;;;N;;;;;
15642 10A1B;KHAROSHTHI LETTER TTHA;Lo;0;R;;;;;N;;;;;
15643 10A1C;KHAROSHTHI LETTER DDA;Lo;0;R;;;;;N;;;;;
15644 10A1D;KHAROSHTHI LETTER DDHA;Lo;0;R;;;;;N;;;;;
15645 10A1E;KHAROSHTHI LETTER NNA;Lo;0;R;;;;;N;;;;;
15646 10A1F;KHAROSHTHI LETTER TA;Lo;0;R;;;;;N;;;;;
15647 10A20;KHAROSHTHI LETTER THA;Lo;0;R;;;;;N;;;;;
15648 10A21;KHAROSHTHI LETTER DA;Lo;0;R;;;;;N;;;;;
15649 10A22;KHAROSHTHI LETTER DHA;Lo;0;R;;;;;N;;;;;
15650 10A23;KHAROSHTHI LETTER NA;Lo;0;R;;;;;N;;;;;
15651 10A24;KHAROSHTHI LETTER PA;Lo;0;R;;;;;N;;;;;
15652 10A25;KHAROSHTHI LETTER PHA;Lo;0;R;;;;;N;;;;;
15653 10A26;KHAROSHTHI LETTER BA;Lo;0;R;;;;;N;;;;;
15654 10A27;KHAROSHTHI LETTER BHA;Lo;0;R;;;;;N;;;;;
15655 10A28;KHAROSHTHI LETTER MA;Lo;0;R;;;;;N;;;;;
15656 10A29;KHAROSHTHI LETTER YA;Lo;0;R;;;;;N;;;;;
15657 10A2A;KHAROSHTHI LETTER RA;Lo;0;R;;;;;N;;;;;
15658 10A2B;KHAROSHTHI LETTER LA;Lo;0;R;;;;;N;;;;;
15659 10A2C;KHAROSHTHI LETTER VA;Lo;0;R;;;;;N;;;;;
15660 10A2D;KHAROSHTHI LETTER SHA;Lo;0;R;;;;;N;;;;;
15661 10A2E;KHAROSHTHI LETTER SSA;Lo;0;R;;;;;N;;;;;
15662 10A2F;KHAROSHTHI LETTER SA;Lo;0;R;;;;;N;;;;;
15663 10A30;KHAROSHTHI LETTER ZA;Lo;0;R;;;;;N;;;;;
15664 10A31;KHAROSHTHI LETTER HA;Lo;0;R;;;;;N;;;;;
15665 10A32;KHAROSHTHI LETTER KKA;Lo;0;R;;;;;N;;;;;
15666 10A33;KHAROSHTHI LETTER TTTHA;Lo;0;R;;;;;N;;;;;
15667 10A38;KHAROSHTHI SIGN BAR ABOVE;Mn;230;NSM;;;;;N;;;;;
15668 10A39;KHAROSHTHI SIGN CAUDA;Mn;1;NSM;;;;;N;;;;;
15669 10A3A;KHAROSHTHI SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;;
15670 10A3F;KHAROSHTHI VIRAMA;Mn;9;NSM;;;;;N;;;;;
15671 10A40;KHAROSHTHI DIGIT ONE;No;0;R;;;1;1;N;;;;;
15672 10A41;KHAROSHTHI DIGIT TWO;No;0;R;;;2;2;N;;;;;
15673 10A42;KHAROSHTHI DIGIT THREE;No;0;R;;;3;3;N;;;;;
15674 10A43;KHAROSHTHI DIGIT FOUR;No;0;R;;;4;4;N;;;;;
15675 10A44;KHAROSHTHI NUMBER TEN;No;0;R;;;;10;N;;;;;
15676 10A45;KHAROSHTHI NUMBER TWENTY;No;0;R;;;;20;N;;;;;
15677 10A46;KHAROSHTHI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;
15678 10A47;KHAROSHTHI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;
15679 10A50;KHAROSHTHI PUNCTUATION DOT;Po;0;R;;;;;N;;;;;
15680 10A51;KHAROSHTHI PUNCTUATION SMALL CIRCLE;Po;0;R;;;;;N;;;;;
15681 10A52;KHAROSHTHI PUNCTUATION CIRCLE;Po;0;R;;;;;N;;;;;
15682 10A53;KHAROSHTHI PUNCTUATION CRESCENT BAR;Po;0;R;;;;;N;;;;;
15683 10A54;KHAROSHTHI PUNCTUATION MANGALAM;Po;0;R;;;;;N;;;;;
15684 10A55;KHAROSHTHI PUNCTUATION LOTUS;Po;0;R;;;;;N;;;;;
15685 10A56;KHAROSHTHI PUNCTUATION DANDA;Po;0;R;;;;;N;;;;;
15686 10A57;KHAROSHTHI PUNCTUATION DOUBLE DANDA;Po;0;R;;;;;N;;;;;
15687 10A58;KHAROSHTHI PUNCTUATION LINES;Po;0;R;;;;;N;;;;;
15688 12000;CUNEIFORM SIGN A;Lo;0;L;;;;;N;;;;;
15689 12001;CUNEIFORM SIGN A TIMES A;Lo;0;L;;;;;N;;;;;
15690 12002;CUNEIFORM SIGN A TIMES BAD;Lo;0;L;;;;;N;;;;;
15691 12003;CUNEIFORM SIGN A TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
15692 12004;CUNEIFORM SIGN A TIMES HA;Lo;0;L;;;;;N;;;;;
15693 12005;CUNEIFORM SIGN A TIMES IGI;Lo;0;L;;;;;N;;;;;
15694 12006;CUNEIFORM SIGN A TIMES LAGAR GUNU;Lo;0;L;;;;;N;;;;;
15695 12007;CUNEIFORM SIGN A TIMES MUSH;Lo;0;L;;;;;N;;;;;
15696 12008;CUNEIFORM SIGN A TIMES SAG;Lo;0;L;;;;;N;;;;;
15697 12009;CUNEIFORM SIGN A2;Lo;0;L;;;;;N;;;;;
15698 1200A;CUNEIFORM SIGN AB;Lo;0;L;;;;;N;;;;;
15699 1200B;CUNEIFORM SIGN AB TIMES ASH2;Lo;0;L;;;;;N;;;;;
15700 1200C;CUNEIFORM SIGN AB TIMES DUN3 GUNU;Lo;0;L;;;;;N;;;;;
15701 1200D;CUNEIFORM SIGN AB TIMES GAL;Lo;0;L;;;;;N;;;;;
15702 1200E;CUNEIFORM SIGN AB TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
15703 1200F;CUNEIFORM SIGN AB TIMES HA;Lo;0;L;;;;;N;;;;;
15704 12010;CUNEIFORM SIGN AB TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
15705 12011;CUNEIFORM SIGN AB TIMES IMIN;Lo;0;L;;;;;N;;;;;
15706 12012;CUNEIFORM SIGN AB TIMES LAGAB;Lo;0;L;;;;;N;;;;;
15707 12013;CUNEIFORM SIGN AB TIMES SHESH;Lo;0;L;;;;;N;;;;;
15708 12014;CUNEIFORM SIGN AB TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;;
15709 12015;CUNEIFORM SIGN AB GUNU;Lo;0;L;;;;;N;;;;;
15710 12016;CUNEIFORM SIGN AB2;Lo;0;L;;;;;N;;;;;
15711 12017;CUNEIFORM SIGN AB2 TIMES BALAG;Lo;0;L;;;;;N;;;;;
15712 12018;CUNEIFORM SIGN AB2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
15713 12019;CUNEIFORM SIGN AB2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;
15714 1201A;CUNEIFORM SIGN AB2 TIMES SHA3;Lo;0;L;;;;;N;;;;;
15715 1201B;CUNEIFORM SIGN AB2 TIMES TAK4;Lo;0;L;;;;;N;;;;;
15716 1201C;CUNEIFORM SIGN AD;Lo;0;L;;;;;N;;;;;
15717 1201D;CUNEIFORM SIGN AK;Lo;0;L;;;;;N;;;;;
15718 1201E;CUNEIFORM SIGN AK TIMES ERIN2;Lo;0;L;;;;;N;;;;;
15719 1201F;CUNEIFORM SIGN AK TIMES SHITA PLUS GISH;Lo;0;L;;;;;N;;;;;
15720 12020;CUNEIFORM SIGN AL;Lo;0;L;;;;;N;;;;;
15721 12021;CUNEIFORM SIGN AL TIMES AL;Lo;0;L;;;;;N;;;;;
15722 12022;CUNEIFORM SIGN AL TIMES DIM2;Lo;0;L;;;;;N;;;;;
15723 12023;CUNEIFORM SIGN AL TIMES GISH;Lo;0;L;;;;;N;;;;;
15724 12024;CUNEIFORM SIGN AL TIMES HA;Lo;0;L;;;;;N;;;;;
15725 12025;CUNEIFORM SIGN AL TIMES KAD3;Lo;0;L;;;;;N;;;;;
15726 12026;CUNEIFORM SIGN AL TIMES KI;Lo;0;L;;;;;N;;;;;
15727 12027;CUNEIFORM SIGN AL TIMES SHE;Lo;0;L;;;;;N;;;;;
15728 12028;CUNEIFORM SIGN AL TIMES USH;Lo;0;L;;;;;N;;;;;
15729 12029;CUNEIFORM SIGN ALAN;Lo;0;L;;;;;N;;;;;
15730 1202A;CUNEIFORM SIGN ALEPH;Lo;0;L;;;;;N;;;;;
15731 1202B;CUNEIFORM SIGN AMAR;Lo;0;L;;;;;N;;;;;
15732 1202C;CUNEIFORM SIGN AMAR TIMES SHE;Lo;0;L;;;;;N;;;;;
15733 1202D;CUNEIFORM SIGN AN;Lo;0;L;;;;;N;;;;;
15734 1202E;CUNEIFORM SIGN AN OVER AN;Lo;0;L;;;;;N;;;;;
15735 1202F;CUNEIFORM SIGN AN THREE TIMES;Lo;0;L;;;;;N;;;;;
15736 12030;CUNEIFORM SIGN AN PLUS NAGA OPPOSING AN PLUS NAGA;Lo;0;L;;;;;N;;;;;
15737 12031;CUNEIFORM SIGN AN PLUS NAGA SQUARED;Lo;0;L;;;;;N;;;;;
15738 12032;CUNEIFORM SIGN ANSHE;Lo;0;L;;;;;N;;;;;
15739 12033;CUNEIFORM SIGN APIN;Lo;0;L;;;;;N;;;;;
15740 12034;CUNEIFORM SIGN ARAD;Lo;0;L;;;;;N;;;;;
15741 12035;CUNEIFORM SIGN ARAD TIMES KUR;Lo;0;L;;;;;N;;;;;
15742 12036;CUNEIFORM SIGN ARKAB;Lo;0;L;;;;;N;;;;;
15743 12037;CUNEIFORM SIGN ASAL2;Lo;0;L;;;;;N;;;;;
15744 12038;CUNEIFORM SIGN ASH;Lo;0;L;;;;;N;;;;;
15745 12039;CUNEIFORM SIGN ASH ZIDA TENU;Lo;0;L;;;;;N;;;;;
15746 1203A;CUNEIFORM SIGN ASH KABA TENU;Lo;0;L;;;;;N;;;;;
15747 1203B;CUNEIFORM SIGN ASH OVER ASH TUG2 OVER TUG2 TUG2 OVER TUG2 PAP;Lo;0;L;;;;;N;;;;;
15748 1203C;CUNEIFORM SIGN ASH OVER ASH OVER ASH;Lo;0;L;;;;;N;;;;;
15749 1203D;CUNEIFORM SIGN ASH OVER ASH OVER ASH CROSSING ASH OVER ASH OVER ASH;Lo;0;L;;;;;N;;;;;
15750 1203E;CUNEIFORM SIGN ASH2;Lo;0;L;;;;;N;;;;;
15751 1203F;CUNEIFORM SIGN ASHGAB;Lo;0;L;;;;;N;;;;;
15752 12040;CUNEIFORM SIGN BA;Lo;0;L;;;;;N;;;;;
15753 12041;CUNEIFORM SIGN BAD;Lo;0;L;;;;;N;;;;;
15754 12042;CUNEIFORM SIGN BAG3;Lo;0;L;;;;;N;;;;;
15755 12043;CUNEIFORM SIGN BAHAR2;Lo;0;L;;;;;N;;;;;
15756 12044;CUNEIFORM SIGN BAL;Lo;0;L;;;;;N;;;;;
15757 12045;CUNEIFORM SIGN BAL OVER BAL;Lo;0;L;;;;;N;;;;;
15758 12046;CUNEIFORM SIGN BALAG;Lo;0;L;;;;;N;;;;;
15759 12047;CUNEIFORM SIGN BAR;Lo;0;L;;;;;N;;;;;
15760 12048;CUNEIFORM SIGN BARA2;Lo;0;L;;;;;N;;;;;
15761 12049;CUNEIFORM SIGN BI;Lo;0;L;;;;;N;;;;;
15762 1204A;CUNEIFORM SIGN BI TIMES A;Lo;0;L;;;;;N;;;;;
15763 1204B;CUNEIFORM SIGN BI TIMES GAR;Lo;0;L;;;;;N;;;;;
15764 1204C;CUNEIFORM SIGN BI TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
15765 1204D;CUNEIFORM SIGN BU;Lo;0;L;;;;;N;;;;;
15766 1204E;CUNEIFORM SIGN BU OVER BU AB;Lo;0;L;;;;;N;;;;;
15767 1204F;CUNEIFORM SIGN BU OVER BU UN;Lo;0;L;;;;;N;;;;;
15768 12050;CUNEIFORM SIGN BU CROSSING BU;Lo;0;L;;;;;N;;;;;
15769 12051;CUNEIFORM SIGN BULUG;Lo;0;L;;;;;N;;;;;
15770 12052;CUNEIFORM SIGN BULUG OVER BULUG;Lo;0;L;;;;;N;;;;;
15771 12053;CUNEIFORM SIGN BUR;Lo;0;L;;;;;N;;;;;
15772 12054;CUNEIFORM SIGN BUR2;Lo;0;L;;;;;N;;;;;
15773 12055;CUNEIFORM SIGN DA;Lo;0;L;;;;;N;;;;;
15774 12056;CUNEIFORM SIGN DAG;Lo;0;L;;;;;N;;;;;
15775 12057;CUNEIFORM SIGN DAG KISIM5 TIMES A PLUS MASH;Lo;0;L;;;;;N;;;;;
15776 12058;CUNEIFORM SIGN DAG KISIM5 TIMES AMAR;Lo;0;L;;;;;N;;;;;
15777 12059;CUNEIFORM SIGN DAG KISIM5 TIMES BALAG;Lo;0;L;;;;;N;;;;;
15778 1205A;CUNEIFORM SIGN DAG KISIM5 TIMES BI;Lo;0;L;;;;;N;;;;;
15779 1205B;CUNEIFORM SIGN DAG KISIM5 TIMES GA;Lo;0;L;;;;;N;;;;;
15780 1205C;CUNEIFORM SIGN DAG KISIM5 TIMES GA PLUS MASH;Lo;0;L;;;;;N;;;;;
15781 1205D;CUNEIFORM SIGN DAG KISIM5 TIMES GI;Lo;0;L;;;;;N;;;;;
15782 1205E;CUNEIFORM SIGN DAG KISIM5 TIMES GIR2;Lo;0;L;;;;;N;;;;;
15783 1205F;CUNEIFORM SIGN DAG KISIM5 TIMES GUD;Lo;0;L;;;;;N;;;;;
15784 12060;CUNEIFORM SIGN DAG KISIM5 TIMES HA;Lo;0;L;;;;;N;;;;;
15785 12061;CUNEIFORM SIGN DAG KISIM5 TIMES IR;Lo;0;L;;;;;N;;;;;
15786 12062;CUNEIFORM SIGN DAG KISIM5 TIMES IR PLUS LU;Lo;0;L;;;;;N;;;;;
15787 12063;CUNEIFORM SIGN DAG KISIM5 TIMES KAK;Lo;0;L;;;;;N;;;;;
15788 12064;CUNEIFORM SIGN DAG KISIM5 TIMES LA;Lo;0;L;;;;;N;;;;;
15789 12065;CUNEIFORM SIGN DAG KISIM5 TIMES LU;Lo;0;L;;;;;N;;;;;
15790 12066;CUNEIFORM SIGN DAG KISIM5 TIMES LU PLUS MASH2;Lo;0;L;;;;;N;;;;;
15791 12067;CUNEIFORM SIGN DAG KISIM5 TIMES LUM;Lo;0;L;;;;;N;;;;;
15792 12068;CUNEIFORM SIGN DAG KISIM5 TIMES NE;Lo;0;L;;;;;N;;;;;
15793 12069;CUNEIFORM SIGN DAG KISIM5 TIMES PAP PLUS PAP;Lo;0;L;;;;;N;;;;;
15794 1206A;CUNEIFORM SIGN DAG KISIM5 TIMES SI;Lo;0;L;;;;;N;;;;;
15795 1206B;CUNEIFORM SIGN DAG KISIM5 TIMES TAK4;Lo;0;L;;;;;N;;;;;
15796 1206C;CUNEIFORM SIGN DAG KISIM5 TIMES U2 PLUS GIR2;Lo;0;L;;;;;N;;;;;
15797 1206D;CUNEIFORM SIGN DAG KISIM5 TIMES USH;Lo;0;L;;;;;N;;;;;
15798 1206E;CUNEIFORM SIGN DAM;Lo;0;L;;;;;N;;;;;
15799 1206F;CUNEIFORM SIGN DAR;Lo;0;L;;;;;N;;;;;
15800 12070;CUNEIFORM SIGN DARA3;Lo;0;L;;;;;N;;;;;
15801 12071;CUNEIFORM SIGN DARA4;Lo;0;L;;;;;N;;;;;
15802 12072;CUNEIFORM SIGN DI;Lo;0;L;;;;;N;;;;;
15803 12073;CUNEIFORM SIGN DIB;Lo;0;L;;;;;N;;;;;
15804 12074;CUNEIFORM SIGN DIM;Lo;0;L;;;;;N;;;;;
15805 12075;CUNEIFORM SIGN DIM TIMES SHE;Lo;0;L;;;;;N;;;;;
15806 12076;CUNEIFORM SIGN DIM2;Lo;0;L;;;;;N;;;;;
15807 12077;CUNEIFORM SIGN DIN;Lo;0;L;;;;;N;;;;;
15808 12078;CUNEIFORM SIGN DIN KASKAL U GUNU DISH;Lo;0;L;;;;;N;;;;;
15809 12079;CUNEIFORM SIGN DISH;Lo;0;L;;;;;N;;;;;
15810 1207A;CUNEIFORM SIGN DU;Lo;0;L;;;;;N;;;;;
15811 1207B;CUNEIFORM SIGN DU OVER DU;Lo;0;L;;;;;N;;;;;
15812 1207C;CUNEIFORM SIGN DU GUNU;Lo;0;L;;;;;N;;;;;
15813 1207D;CUNEIFORM SIGN DU SHESHIG;Lo;0;L;;;;;N;;;;;
15814 1207E;CUNEIFORM SIGN DUB;Lo;0;L;;;;;N;;;;;
15815 1207F;CUNEIFORM SIGN DUB TIMES ESH2;Lo;0;L;;;;;N;;;;;
15816 12080;CUNEIFORM SIGN DUB2;Lo;0;L;;;;;N;;;;;
15817 12081;CUNEIFORM SIGN DUG;Lo;0;L;;;;;N;;;;;
15818 12082;CUNEIFORM SIGN DUGUD;Lo;0;L;;;;;N;;;;;
15819 12083;CUNEIFORM SIGN DUH;Lo;0;L;;;;;N;;;;;
15820 12084;CUNEIFORM SIGN DUN;Lo;0;L;;;;;N;;;;;
15821 12085;CUNEIFORM SIGN DUN3;Lo;0;L;;;;;N;;;;;
15822 12086;CUNEIFORM SIGN DUN3 GUNU;Lo;0;L;;;;;N;;;;;
15823 12087;CUNEIFORM SIGN DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;;
15824 12088;CUNEIFORM SIGN DUN4;Lo;0;L;;;;;N;;;;;
15825 12089;CUNEIFORM SIGN DUR2;Lo;0;L;;;;;N;;;;;
15826 1208A;CUNEIFORM SIGN E;Lo;0;L;;;;;N;;;;;
15827 1208B;CUNEIFORM SIGN E TIMES PAP;Lo;0;L;;;;;N;;;;;
15828 1208C;CUNEIFORM SIGN E OVER E NUN OVER NUN;Lo;0;L;;;;;N;;;;;
15829 1208D;CUNEIFORM SIGN E2;Lo;0;L;;;;;N;;;;;
15830 1208E;CUNEIFORM SIGN E2 TIMES A PLUS HA PLUS DA;Lo;0;L;;;;;N;;;;;
15831 1208F;CUNEIFORM SIGN E2 TIMES GAR;Lo;0;L;;;;;N;;;;;
15832 12090;CUNEIFORM SIGN E2 TIMES MI;Lo;0;L;;;;;N;;;;;
15833 12091;CUNEIFORM SIGN E2 TIMES SAL;Lo;0;L;;;;;N;;;;;
15834 12092;CUNEIFORM SIGN E2 TIMES SHE;Lo;0;L;;;;;N;;;;;
15835 12093;CUNEIFORM SIGN E2 TIMES U;Lo;0;L;;;;;N;;;;;
15836 12094;CUNEIFORM SIGN EDIN;Lo;0;L;;;;;N;;;;;
15837 12095;CUNEIFORM SIGN EGIR;Lo;0;L;;;;;N;;;;;
15838 12096;CUNEIFORM SIGN EL;Lo;0;L;;;;;N;;;;;
15839 12097;CUNEIFORM SIGN EN;Lo;0;L;;;;;N;;;;;
15840 12098;CUNEIFORM SIGN EN TIMES GAN2;Lo;0;L;;;;;N;;;;;
15841 12099;CUNEIFORM SIGN EN TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
15842 1209A;CUNEIFORM SIGN EN TIMES ME;Lo;0;L;;;;;N;;;;;
15843 1209B;CUNEIFORM SIGN EN CROSSING EN;Lo;0;L;;;;;N;;;;;
15844 1209C;CUNEIFORM SIGN EN OPPOSING EN;Lo;0;L;;;;;N;;;;;
15845 1209D;CUNEIFORM SIGN EN SQUARED;Lo;0;L;;;;;N;;;;;
15846 1209E;CUNEIFORM SIGN EREN;Lo;0;L;;;;;N;;;;;
15847 1209F;CUNEIFORM SIGN ERIN2;Lo;0;L;;;;;N;;;;;
15848 120A0;CUNEIFORM SIGN ESH2;Lo;0;L;;;;;N;;;;;
15849 120A1;CUNEIFORM SIGN EZEN;Lo;0;L;;;;;N;;;;;
15850 120A2;CUNEIFORM SIGN EZEN TIMES A;Lo;0;L;;;;;N;;;;;
15851 120A3;CUNEIFORM SIGN EZEN TIMES A PLUS LAL;Lo;0;L;;;;;N;;;;;
15852 120A4;CUNEIFORM SIGN EZEN TIMES A PLUS LAL TIMES LAL;Lo;0;L;;;;;N;;;;;
15853 120A5;CUNEIFORM SIGN EZEN TIMES AN;Lo;0;L;;;;;N;;;;;
15854 120A6;CUNEIFORM SIGN EZEN TIMES BAD;Lo;0;L;;;;;N;;;;;
15855 120A7;CUNEIFORM SIGN EZEN TIMES DUN3 GUNU;Lo;0;L;;;;;N;;;;;
15856 120A8;CUNEIFORM SIGN EZEN TIMES DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;;
15857 120A9;CUNEIFORM SIGN EZEN TIMES HA;Lo;0;L;;;;;N;;;;;
15858 120AA;CUNEIFORM SIGN EZEN TIMES HA GUNU;Lo;0;L;;;;;N;;;;;
15859 120AB;CUNEIFORM SIGN EZEN TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
15860 120AC;CUNEIFORM SIGN EZEN TIMES KASKAL;Lo;0;L;;;;;N;;;;;
15861 120AD;CUNEIFORM SIGN EZEN TIMES KASKAL SQUARED;Lo;0;L;;;;;N;;;;;
15862 120AE;CUNEIFORM SIGN EZEN TIMES KU3;Lo;0;L;;;;;N;;;;;
15863 120AF;CUNEIFORM SIGN EZEN TIMES LA;Lo;0;L;;;;;N;;;;;
15864 120B0;CUNEIFORM SIGN EZEN TIMES LAL TIMES LAL;Lo;0;L;;;;;N;;;;;
15865 120B1;CUNEIFORM SIGN EZEN TIMES LI;Lo;0;L;;;;;N;;;;;
15866 120B2;CUNEIFORM SIGN EZEN TIMES LU;Lo;0;L;;;;;N;;;;;
15867 120B3;CUNEIFORM SIGN EZEN TIMES U2;Lo;0;L;;;;;N;;;;;
15868 120B4;CUNEIFORM SIGN EZEN TIMES UD;Lo;0;L;;;;;N;;;;;
15869 120B5;CUNEIFORM SIGN GA;Lo;0;L;;;;;N;;;;;
15870 120B6;CUNEIFORM SIGN GA GUNU;Lo;0;L;;;;;N;;;;;
15871 120B7;CUNEIFORM SIGN GA2;Lo;0;L;;;;;N;;;;;
15872 120B8;CUNEIFORM SIGN GA2 TIMES A PLUS DA PLUS HA;Lo;0;L;;;;;N;;;;;
15873 120B9;CUNEIFORM SIGN GA2 TIMES A PLUS HA;Lo;0;L;;;;;N;;;;;
15874 120BA;CUNEIFORM SIGN GA2 TIMES A PLUS IGI;Lo;0;L;;;;;N;;;;;
15875 120BB;CUNEIFORM SIGN GA2 TIMES AB2 TENU PLUS TAB;Lo;0;L;;;;;N;;;;;
15876 120BC;CUNEIFORM SIGN GA2 TIMES AN;Lo;0;L;;;;;N;;;;;
15877 120BD;CUNEIFORM SIGN GA2 TIMES ASH;Lo;0;L;;;;;N;;;;;
15878 120BE;CUNEIFORM SIGN GA2 TIMES ASH2 PLUS GAL;Lo;0;L;;;;;N;;;;;
15879 120BF;CUNEIFORM SIGN GA2 TIMES BAD;Lo;0;L;;;;;N;;;;;
15880 120C0;CUNEIFORM SIGN GA2 TIMES BAR PLUS RA;Lo;0;L;;;;;N;;;;;
15881 120C1;CUNEIFORM SIGN GA2 TIMES BUR;Lo;0;L;;;;;N;;;;;
15882 120C2;CUNEIFORM SIGN GA2 TIMES BUR PLUS RA;Lo;0;L;;;;;N;;;;;
15883 120C3;CUNEIFORM SIGN GA2 TIMES DA;Lo;0;L;;;;;N;;;;;
15884 120C4;CUNEIFORM SIGN GA2 TIMES DI;Lo;0;L;;;;;N;;;;;
15885 120C5;CUNEIFORM SIGN GA2 TIMES DIM TIMES SHE;Lo;0;L;;;;;N;;;;;
15886 120C6;CUNEIFORM SIGN GA2 TIMES DUB;Lo;0;L;;;;;N;;;;;
15887 120C7;CUNEIFORM SIGN GA2 TIMES EL;Lo;0;L;;;;;N;;;;;
15888 120C8;CUNEIFORM SIGN GA2 TIMES EL PLUS LA;Lo;0;L;;;;;N;;;;;
15889 120C9;CUNEIFORM SIGN GA2 TIMES EN;Lo;0;L;;;;;N;;;;;
15890 120CA;CUNEIFORM SIGN GA2 TIMES EN TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
15891 120CB;CUNEIFORM SIGN GA2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
15892 120CC;CUNEIFORM SIGN GA2 TIMES GAR;Lo;0;L;;;;;N;;;;;
15893 120CD;CUNEIFORM SIGN GA2 TIMES GI;Lo;0;L;;;;;N;;;;;
15894 120CE;CUNEIFORM SIGN GA2 TIMES GI4;Lo;0;L;;;;;N;;;;;
15895 120CF;CUNEIFORM SIGN GA2 TIMES GI4 PLUS A;Lo;0;L;;;;;N;;;;;
15896 120D0;CUNEIFORM SIGN GA2 TIMES GIR2 PLUS SU;Lo;0;L;;;;;N;;;;;
15897 120D1;CUNEIFORM SIGN GA2 TIMES HA PLUS LU PLUS ESH2;Lo;0;L;;;;;N;;;;;
15898 120D2;CUNEIFORM SIGN GA2 TIMES HAL;Lo;0;L;;;;;N;;;;;
15899 120D3;CUNEIFORM SIGN GA2 TIMES HAL PLUS LA;Lo;0;L;;;;;N;;;;;
15900 120D4;CUNEIFORM SIGN GA2 TIMES HI PLUS LI;Lo;0;L;;;;;N;;;;;
15901 120D5;CUNEIFORM SIGN GA2 TIMES HUB2;Lo;0;L;;;;;N;;;;;
15902 120D6;CUNEIFORM SIGN GA2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
15903 120D7;CUNEIFORM SIGN GA2 TIMES ISH PLUS HU PLUS ASH;Lo;0;L;;;;;N;;;;;
15904 120D8;CUNEIFORM SIGN GA2 TIMES KAK;Lo;0;L;;;;;N;;;;;
15905 120D9;CUNEIFORM SIGN GA2 TIMES KASKAL;Lo;0;L;;;;;N;;;;;
15906 120DA;CUNEIFORM SIGN GA2 TIMES KID;Lo;0;L;;;;;N;;;;;
15907 120DB;CUNEIFORM SIGN GA2 TIMES KID PLUS LAL;Lo;0;L;;;;;N;;;;;
15908 120DC;CUNEIFORM SIGN GA2 TIMES KU3 PLUS AN;Lo;0;L;;;;;N;;;;;
15909 120DD;CUNEIFORM SIGN GA2 TIMES LA;Lo;0;L;;;;;N;;;;;
15910 120DE;CUNEIFORM SIGN GA2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;
15911 120DF;CUNEIFORM SIGN GA2 TIMES MI;Lo;0;L;;;;;N;;;;;
15912 120E0;CUNEIFORM SIGN GA2 TIMES NUN;Lo;0;L;;;;;N;;;;;
15913 120E1;CUNEIFORM SIGN GA2 TIMES NUN OVER NUN;Lo;0;L;;;;;N;;;;;
15914 120E2;CUNEIFORM SIGN GA2 TIMES PA;Lo;0;L;;;;;N;;;;;
15915 120E3;CUNEIFORM SIGN GA2 TIMES SAL;Lo;0;L;;;;;N;;;;;
15916 120E4;CUNEIFORM SIGN GA2 TIMES SAR;Lo;0;L;;;;;N;;;;;
15917 120E5;CUNEIFORM SIGN GA2 TIMES SHE;Lo;0;L;;;;;N;;;;;
15918 120E6;CUNEIFORM SIGN GA2 TIMES SHE PLUS TUR;Lo;0;L;;;;;N;;;;;
15919 120E7;CUNEIFORM SIGN GA2 TIMES SHID;Lo;0;L;;;;;N;;;;;
15920 120E8;CUNEIFORM SIGN GA2 TIMES SUM;Lo;0;L;;;;;N;;;;;
15921 120E9;CUNEIFORM SIGN GA2 TIMES TAK4;Lo;0;L;;;;;N;;;;;
15922 120EA;CUNEIFORM SIGN GA2 TIMES U;Lo;0;L;;;;;N;;;;;
15923 120EB;CUNEIFORM SIGN GA2 TIMES UD;Lo;0;L;;;;;N;;;;;
15924 120EC;CUNEIFORM SIGN GA2 TIMES UD PLUS DU;Lo;0;L;;;;;N;;;;;
15925 120ED;CUNEIFORM SIGN GA2 OVER GA2;Lo;0;L;;;;;N;;;;;
15926 120EE;CUNEIFORM SIGN GABA;Lo;0;L;;;;;N;;;;;
15927 120EF;CUNEIFORM SIGN GABA CROSSING GABA;Lo;0;L;;;;;N;;;;;
15928 120F0;CUNEIFORM SIGN GAD;Lo;0;L;;;;;N;;;;;
15929 120F1;CUNEIFORM SIGN GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;
15930 120F2;CUNEIFORM SIGN GAL;Lo;0;L;;;;;N;;;;;
15931 120F3;CUNEIFORM SIGN GAL GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;
15932 120F4;CUNEIFORM SIGN GALAM;Lo;0;L;;;;;N;;;;;
15933 120F5;CUNEIFORM SIGN GAM;Lo;0;L;;;;;N;;;;;
15934 120F6;CUNEIFORM SIGN GAN;Lo;0;L;;;;;N;;;;;
15935 120F7;CUNEIFORM SIGN GAN2;Lo;0;L;;;;;N;;;;;
15936 120F8;CUNEIFORM SIGN GAN2 TENU;Lo;0;L;;;;;N;;;;;
15937 120F9;CUNEIFORM SIGN GAN2 OVER GAN2;Lo;0;L;;;;;N;;;;;
15938 120FA;CUNEIFORM SIGN GAN2 CROSSING GAN2;Lo;0;L;;;;;N;;;;;
15939 120FB;CUNEIFORM SIGN GAR;Lo;0;L;;;;;N;;;;;
15940 120FC;CUNEIFORM SIGN GAR3;Lo;0;L;;;;;N;;;;;
15941 120FD;CUNEIFORM SIGN GASHAN;Lo;0;L;;;;;N;;;;;
15942 120FE;CUNEIFORM SIGN GESHTIN;Lo;0;L;;;;;N;;;;;
15943 120FF;CUNEIFORM SIGN GESHTIN TIMES KUR;Lo;0;L;;;;;N;;;;;
15944 12100;CUNEIFORM SIGN GI;Lo;0;L;;;;;N;;;;;
15945 12101;CUNEIFORM SIGN GI TIMES E;Lo;0;L;;;;;N;;;;;
15946 12102;CUNEIFORM SIGN GI TIMES U;Lo;0;L;;;;;N;;;;;
15947 12103;CUNEIFORM SIGN GI CROSSING GI;Lo;0;L;;;;;N;;;;;
15948 12104;CUNEIFORM SIGN GI4;Lo;0;L;;;;;N;;;;;
15949 12105;CUNEIFORM SIGN GI4 OVER GI4;Lo;0;L;;;;;N;;;;;
15950 12106;CUNEIFORM SIGN GI4 CROSSING GI4;Lo;0;L;;;;;N;;;;;
15951 12107;CUNEIFORM SIGN GIDIM;Lo;0;L;;;;;N;;;;;
15952 12108;CUNEIFORM SIGN GIR2;Lo;0;L;;;;;N;;;;;
15953 12109;CUNEIFORM SIGN GIR2 GUNU;Lo;0;L;;;;;N;;;;;
15954 1210A;CUNEIFORM SIGN GIR3;Lo;0;L;;;;;N;;;;;
15955 1210B;CUNEIFORM SIGN GIR3 TIMES A PLUS IGI;Lo;0;L;;;;;N;;;;;
15956 1210C;CUNEIFORM SIGN GIR3 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
15957 1210D;CUNEIFORM SIGN GIR3 TIMES IGI;Lo;0;L;;;;;N;;;;;
15958 1210E;CUNEIFORM SIGN GIR3 TIMES LU PLUS IGI;Lo;0;L;;;;;N;;;;;
15959 1210F;CUNEIFORM SIGN GIR3 TIMES PA;Lo;0;L;;;;;N;;;;;
15960 12110;CUNEIFORM SIGN GISAL;Lo;0;L;;;;;N;;;;;
15961 12111;CUNEIFORM SIGN GISH;Lo;0;L;;;;;N;;;;;
15962 12112;CUNEIFORM SIGN GISH CROSSING GISH;Lo;0;L;;;;;N;;;;;
15963 12113;CUNEIFORM SIGN GISH TIMES BAD;Lo;0;L;;;;;N;;;;;
15964 12114;CUNEIFORM SIGN GISH TIMES TAK4;Lo;0;L;;;;;N;;;;;
15965 12115;CUNEIFORM SIGN GISH TENU;Lo;0;L;;;;;N;;;;;
15966 12116;CUNEIFORM SIGN GU;Lo;0;L;;;;;N;;;;;
15967 12117;CUNEIFORM SIGN GU CROSSING GU;Lo;0;L;;;;;N;;;;;
15968 12118;CUNEIFORM SIGN GU2;Lo;0;L;;;;;N;;;;;
15969 12119;CUNEIFORM SIGN GU2 TIMES KAK;Lo;0;L;;;;;N;;;;;
15970 1211A;CUNEIFORM SIGN GU2 TIMES KAK TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
15971 1211B;CUNEIFORM SIGN GU2 TIMES NUN;Lo;0;L;;;;;N;;;;;
15972 1211C;CUNEIFORM SIGN GU2 TIMES SAL PLUS TUG2;Lo;0;L;;;;;N;;;;;
15973 1211D;CUNEIFORM SIGN GU2 GUNU;Lo;0;L;;;;;N;;;;;
15974 1211E;CUNEIFORM SIGN GUD;Lo;0;L;;;;;N;;;;;
15975 1211F;CUNEIFORM SIGN GUD TIMES A PLUS KUR;Lo;0;L;;;;;N;;;;;
15976 12120;CUNEIFORM SIGN GUD TIMES KUR;Lo;0;L;;;;;N;;;;;
15977 12121;CUNEIFORM SIGN GUD OVER GUD LUGAL;Lo;0;L;;;;;N;;;;;
15978 12122;CUNEIFORM SIGN GUL;Lo;0;L;;;;;N;;;;;
15979 12123;CUNEIFORM SIGN GUM;Lo;0;L;;;;;N;;;;;
15980 12124;CUNEIFORM SIGN GUM TIMES SHE;Lo;0;L;;;;;N;;;;;
15981 12125;CUNEIFORM SIGN GUR;Lo;0;L;;;;;N;;;;;
15982 12126;CUNEIFORM SIGN GUR7;Lo;0;L;;;;;N;;;;;
15983 12127;CUNEIFORM SIGN GURUN;Lo;0;L;;;;;N;;;;;
15984 12128;CUNEIFORM SIGN GURUSH;Lo;0;L;;;;;N;;;;;
15985 12129;CUNEIFORM SIGN HA;Lo;0;L;;;;;N;;;;;
15986 1212A;CUNEIFORM SIGN HA TENU;Lo;0;L;;;;;N;;;;;
15987 1212B;CUNEIFORM SIGN HA GUNU;Lo;0;L;;;;;N;;;;;
15988 1212C;CUNEIFORM SIGN HAL;Lo;0;L;;;;;N;;;;;
15989 1212D;CUNEIFORM SIGN HI;Lo;0;L;;;;;N;;;;;
15990 1212E;CUNEIFORM SIGN HI TIMES ASH;Lo;0;L;;;;;N;;;;;
15991 1212F;CUNEIFORM SIGN HI TIMES ASH2;Lo;0;L;;;;;N;;;;;
15992 12130;CUNEIFORM SIGN HI TIMES BAD;Lo;0;L;;;;;N;;;;;
15993 12131;CUNEIFORM SIGN HI TIMES DISH;Lo;0;L;;;;;N;;;;;
15994 12132;CUNEIFORM SIGN HI TIMES GAD;Lo;0;L;;;;;N;;;;;
15995 12133;CUNEIFORM SIGN HI TIMES KIN;Lo;0;L;;;;;N;;;;;
15996 12134;CUNEIFORM SIGN HI TIMES NUN;Lo;0;L;;;;;N;;;;;
15997 12135;CUNEIFORM SIGN HI TIMES SHE;Lo;0;L;;;;;N;;;;;
15998 12136;CUNEIFORM SIGN HI TIMES U;Lo;0;L;;;;;N;;;;;
15999 12137;CUNEIFORM SIGN HU;Lo;0;L;;;;;N;;;;;
16000 12138;CUNEIFORM SIGN HUB2;Lo;0;L;;;;;N;;;;;
16001 12139;CUNEIFORM SIGN HUB2 TIMES AN;Lo;0;L;;;;;N;;;;;
16002 1213A;CUNEIFORM SIGN HUB2 TIMES HAL;Lo;0;L;;;;;N;;;;;
16003 1213B;CUNEIFORM SIGN HUB2 TIMES KASKAL;Lo;0;L;;;;;N;;;;;
16004 1213C;CUNEIFORM SIGN HUB2 TIMES LISH;Lo;0;L;;;;;N;;;;;
16005 1213D;CUNEIFORM SIGN HUB2 TIMES UD;Lo;0;L;;;;;N;;;;;
16006 1213E;CUNEIFORM SIGN HUL2;Lo;0;L;;;;;N;;;;;
16007 1213F;CUNEIFORM SIGN I;Lo;0;L;;;;;N;;;;;
16008 12140;CUNEIFORM SIGN I A;Lo;0;L;;;;;N;;;;;
16009 12141;CUNEIFORM SIGN IB;Lo;0;L;;;;;N;;;;;
16010 12142;CUNEIFORM SIGN IDIM;Lo;0;L;;;;;N;;;;;
16011 12143;CUNEIFORM SIGN IDIM OVER IDIM BUR;Lo;0;L;;;;;N;;;;;
16012 12144;CUNEIFORM SIGN IDIM OVER IDIM SQUARED;Lo;0;L;;;;;N;;;;;
16013 12145;CUNEIFORM SIGN IG;Lo;0;L;;;;;N;;;;;
16014 12146;CUNEIFORM SIGN IGI;Lo;0;L;;;;;N;;;;;
16015 12147;CUNEIFORM SIGN IGI DIB;Lo;0;L;;;;;N;;;;;
16016 12148;CUNEIFORM SIGN IGI RI;Lo;0;L;;;;;N;;;;;
16017 12149;CUNEIFORM SIGN IGI OVER IGI SHIR OVER SHIR UD OVER UD;Lo;0;L;;;;;N;;;;;
16018 1214A;CUNEIFORM SIGN IGI GUNU;Lo;0;L;;;;;N;;;;;
16019 1214B;CUNEIFORM SIGN IL;Lo;0;L;;;;;N;;;;;
16020 1214C;CUNEIFORM SIGN IL TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
16021 1214D;CUNEIFORM SIGN IL2;Lo;0;L;;;;;N;;;;;
16022 1214E;CUNEIFORM SIGN IM;Lo;0;L;;;;;N;;;;;
16023 1214F;CUNEIFORM SIGN IM TIMES TAK4;Lo;0;L;;;;;N;;;;;
16024 12150;CUNEIFORM SIGN IM CROSSING IM;Lo;0;L;;;;;N;;;;;
16025 12151;CUNEIFORM SIGN IM OPPOSING IM;Lo;0;L;;;;;N;;;;;
16026 12152;CUNEIFORM SIGN IM SQUARED;Lo;0;L;;;;;N;;;;;
16027 12153;CUNEIFORM SIGN IMIN;Lo;0;L;;;;;N;;;;;
16028 12154;CUNEIFORM SIGN IN;Lo;0;L;;;;;N;;;;;
16029 12155;CUNEIFORM SIGN IR;Lo;0;L;;;;;N;;;;;
16030 12156;CUNEIFORM SIGN ISH;Lo;0;L;;;;;N;;;;;
16031 12157;CUNEIFORM SIGN KA;Lo;0;L;;;;;N;;;;;
16032 12158;CUNEIFORM SIGN KA TIMES A;Lo;0;L;;;;;N;;;;;
16033 12159;CUNEIFORM SIGN KA TIMES AD;Lo;0;L;;;;;N;;;;;
16034 1215A;CUNEIFORM SIGN KA TIMES AD PLUS KU3;Lo;0;L;;;;;N;;;;;
16035 1215B;CUNEIFORM SIGN KA TIMES ASH2;Lo;0;L;;;;;N;;;;;
16036 1215C;CUNEIFORM SIGN KA TIMES BAD;Lo;0;L;;;;;N;;;;;
16037 1215D;CUNEIFORM SIGN KA TIMES BALAG;Lo;0;L;;;;;N;;;;;
16038 1215E;CUNEIFORM SIGN KA TIMES BAR;Lo;0;L;;;;;N;;;;;
16039 1215F;CUNEIFORM SIGN KA TIMES BI;Lo;0;L;;;;;N;;;;;
16040 12160;CUNEIFORM SIGN KA TIMES ERIN2;Lo;0;L;;;;;N;;;;;
16041 12161;CUNEIFORM SIGN KA TIMES ESH2;Lo;0;L;;;;;N;;;;;
16042 12162;CUNEIFORM SIGN KA TIMES GA;Lo;0;L;;;;;N;;;;;
16043 12163;CUNEIFORM SIGN KA TIMES GAL;Lo;0;L;;;;;N;;;;;
16044 12164;CUNEIFORM SIGN KA TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
16045 12165;CUNEIFORM SIGN KA TIMES GAR;Lo;0;L;;;;;N;;;;;
16046 12166;CUNEIFORM SIGN KA TIMES GAR PLUS SHA3 PLUS A;Lo;0;L;;;;;N;;;;;
16047 12167;CUNEIFORM SIGN KA TIMES GI;Lo;0;L;;;;;N;;;;;
16048 12168;CUNEIFORM SIGN KA TIMES GIR2;Lo;0;L;;;;;N;;;;;
16049 12169;CUNEIFORM SIGN KA TIMES GISH PLUS SAR;Lo;0;L;;;;;N;;;;;
16050 1216A;CUNEIFORM SIGN KA TIMES GISH CROSSING GISH;Lo;0;L;;;;;N;;;;;
16051 1216B;CUNEIFORM SIGN KA TIMES GU;Lo;0;L;;;;;N;;;;;
16052 1216C;CUNEIFORM SIGN KA TIMES GUR7;Lo;0;L;;;;;N;;;;;
16053 1216D;CUNEIFORM SIGN KA TIMES IGI;Lo;0;L;;;;;N;;;;;
16054 1216E;CUNEIFORM SIGN KA TIMES IM;Lo;0;L;;;;;N;;;;;
16055 1216F;CUNEIFORM SIGN KA TIMES KAK;Lo;0;L;;;;;N;;;;;
16056 12170;CUNEIFORM SIGN KA TIMES KI;Lo;0;L;;;;;N;;;;;
16057 12171;CUNEIFORM SIGN KA TIMES KID;Lo;0;L;;;;;N;;;;;
16058 12172;CUNEIFORM SIGN KA TIMES LI;Lo;0;L;;;;;N;;;;;
16059 12173;CUNEIFORM SIGN KA TIMES LU;Lo;0;L;;;;;N;;;;;
16060 12174;CUNEIFORM SIGN KA TIMES ME;Lo;0;L;;;;;N;;;;;
16061 12175;CUNEIFORM SIGN KA TIMES ME PLUS DU;Lo;0;L;;;;;N;;;;;
16062 12176;CUNEIFORM SIGN KA TIMES ME PLUS GI;Lo;0;L;;;;;N;;;;;
16063 12177;CUNEIFORM SIGN KA TIMES ME PLUS TE;Lo;0;L;;;;;N;;;;;
16064 12178;CUNEIFORM SIGN KA TIMES MI;Lo;0;L;;;;;N;;;;;
16065 12179;CUNEIFORM SIGN KA TIMES MI PLUS NUNUZ;Lo;0;L;;;;;N;;;;;
16066 1217A;CUNEIFORM SIGN KA TIMES NE;Lo;0;L;;;;;N;;;;;
16067 1217B;CUNEIFORM SIGN KA TIMES NUN;Lo;0;L;;;;;N;;;;;
16068 1217C;CUNEIFORM SIGN KA TIMES PI;Lo;0;L;;;;;N;;;;;
16069 1217D;CUNEIFORM SIGN KA TIMES RU;Lo;0;L;;;;;N;;;;;
16070 1217E;CUNEIFORM SIGN KA TIMES SA;Lo;0;L;;;;;N;;;;;
16071 1217F;CUNEIFORM SIGN KA TIMES SAR;Lo;0;L;;;;;N;;;;;
16072 12180;CUNEIFORM SIGN KA TIMES SHA;Lo;0;L;;;;;N;;;;;
16073 12181;CUNEIFORM SIGN KA TIMES SHE;Lo;0;L;;;;;N;;;;;
16074 12182;CUNEIFORM SIGN KA TIMES SHID;Lo;0;L;;;;;N;;;;;
16075 12183;CUNEIFORM SIGN KA TIMES SHU;Lo;0;L;;;;;N;;;;;
16076 12184;CUNEIFORM SIGN KA TIMES SIG;Lo;0;L;;;;;N;;;;;
16077 12185;CUNEIFORM SIGN KA TIMES SUHUR;Lo;0;L;;;;;N;;;;;
16078 12186;CUNEIFORM SIGN KA TIMES TAR;Lo;0;L;;;;;N;;;;;
16079 12187;CUNEIFORM SIGN KA TIMES U;Lo;0;L;;;;;N;;;;;
16080 12188;CUNEIFORM SIGN KA TIMES U2;Lo;0;L;;;;;N;;;;;
16081 12189;CUNEIFORM SIGN KA TIMES UD;Lo;0;L;;;;;N;;;;;
16082 1218A;CUNEIFORM SIGN KA TIMES UMUM TIMES PA;Lo;0;L;;;;;N;;;;;
16083 1218B;CUNEIFORM SIGN KA TIMES USH;Lo;0;L;;;;;N;;;;;
16084 1218C;CUNEIFORM SIGN KA TIMES ZI;Lo;0;L;;;;;N;;;;;
16085 1218D;CUNEIFORM SIGN KA2;Lo;0;L;;;;;N;;;;;
16086 1218E;CUNEIFORM SIGN KA2 CROSSING KA2;Lo;0;L;;;;;N;;;;;
16087 1218F;CUNEIFORM SIGN KAB;Lo;0;L;;;;;N;;;;;
16088 12190;CUNEIFORM SIGN KAD2;Lo;0;L;;;;;N;;;;;
16089 12191;CUNEIFORM SIGN KAD3;Lo;0;L;;;;;N;;;;;
16090 12192;CUNEIFORM SIGN KAD4;Lo;0;L;;;;;N;;;;;
16091 12193;CUNEIFORM SIGN KAD5;Lo;0;L;;;;;N;;;;;
16092 12194;CUNEIFORM SIGN KAD5 OVER KAD5;Lo;0;L;;;;;N;;;;;
16093 12195;CUNEIFORM SIGN KAK;Lo;0;L;;;;;N;;;;;
16094 12196;CUNEIFORM SIGN KAK TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
16095 12197;CUNEIFORM SIGN KAL;Lo;0;L;;;;;N;;;;;
16096 12198;CUNEIFORM SIGN KAL TIMES BAD;Lo;0;L;;;;;N;;;;;
16097 12199;CUNEIFORM SIGN KAL CROSSING KAL;Lo;0;L;;;;;N;;;;;
16098 1219A;CUNEIFORM SIGN KAM2;Lo;0;L;;;;;N;;;;;
16099 1219B;CUNEIFORM SIGN KAM4;Lo;0;L;;;;;N;;;;;
16100 1219C;CUNEIFORM SIGN KASKAL;Lo;0;L;;;;;N;;;;;
16101 1219D;CUNEIFORM SIGN KASKAL LAGAB TIMES U OVER LAGAB TIMES U;Lo;0;L;;;;;N;;;;;
16102 1219E;CUNEIFORM SIGN KASKAL OVER KASKAL LAGAB TIMES U OVER LAGAB TIMES U;Lo;0;L;;;;;N;;;;;
16103 1219F;CUNEIFORM SIGN KESH2;Lo;0;L;;;;;N;;;;;
16104 121A0;CUNEIFORM SIGN KI;Lo;0;L;;;;;N;;;;;
16105 121A1;CUNEIFORM SIGN KI TIMES BAD;Lo;0;L;;;;;N;;;;;
16106 121A2;CUNEIFORM SIGN KI TIMES U;Lo;0;L;;;;;N;;;;;
16107 121A3;CUNEIFORM SIGN KI TIMES UD;Lo;0;L;;;;;N;;;;;
16108 121A4;CUNEIFORM SIGN KID;Lo;0;L;;;;;N;;;;;
16109 121A5;CUNEIFORM SIGN KIN;Lo;0;L;;;;;N;;;;;
16110 121A6;CUNEIFORM SIGN KISAL;Lo;0;L;;;;;N;;;;;
16111 121A7;CUNEIFORM SIGN KISH;Lo;0;L;;;;;N;;;;;
16112 121A8;CUNEIFORM SIGN KISIM5;Lo;0;L;;;;;N;;;;;
16113 121A9;CUNEIFORM SIGN KISIM5 OVER KISIM5;Lo;0;L;;;;;N;;;;;
16114 121AA;CUNEIFORM SIGN KU;Lo;0;L;;;;;N;;;;;
16115 121AB;CUNEIFORM SIGN KU OVER HI TIMES ASH2 KU OVER HI TIMES ASH2;Lo;0;L;;;;;N;;;;;
16116 121AC;CUNEIFORM SIGN KU3;Lo;0;L;;;;;N;;;;;
16117 121AD;CUNEIFORM SIGN KU4;Lo;0;L;;;;;N;;;;;
16118 121AE;CUNEIFORM SIGN KU4 VARIANT FORM;Lo;0;L;;;;;N;;;;;
16119 121AF;CUNEIFORM SIGN KU7;Lo;0;L;;;;;N;;;;;
16120 121B0;CUNEIFORM SIGN KUL;Lo;0;L;;;;;N;;;;;
16121 121B1;CUNEIFORM SIGN KUL GUNU;Lo;0;L;;;;;N;;;;;
16122 121B2;CUNEIFORM SIGN KUN;Lo;0;L;;;;;N;;;;;
16123 121B3;CUNEIFORM SIGN KUR;Lo;0;L;;;;;N;;;;;
16124 121B4;CUNEIFORM SIGN KUR OPPOSING KUR;Lo;0;L;;;;;N;;;;;
16125 121B5;CUNEIFORM SIGN KUSHU2;Lo;0;L;;;;;N;;;;;
16126 121B6;CUNEIFORM SIGN KWU318;Lo;0;L;;;;;N;;;;;
16127 121B7;CUNEIFORM SIGN LA;Lo;0;L;;;;;N;;;;;
16128 121B8;CUNEIFORM SIGN LAGAB;Lo;0;L;;;;;N;;;;;
16129 121B9;CUNEIFORM SIGN LAGAB TIMES A;Lo;0;L;;;;;N;;;;;
16130 121BA;CUNEIFORM SIGN LAGAB TIMES A PLUS DA PLUS HA;Lo;0;L;;;;;N;;;;;
16131 121BB;CUNEIFORM SIGN LAGAB TIMES A PLUS GAR;Lo;0;L;;;;;N;;;;;
16132 121BC;CUNEIFORM SIGN LAGAB TIMES A PLUS LAL;Lo;0;L;;;;;N;;;;;
16133 121BD;CUNEIFORM SIGN LAGAB TIMES AL;Lo;0;L;;;;;N;;;;;
16134 121BE;CUNEIFORM SIGN LAGAB TIMES AN;Lo;0;L;;;;;N;;;;;
16135 121BF;CUNEIFORM SIGN LAGAB TIMES ASH ZIDA TENU;Lo;0;L;;;;;N;;;;;
16136 121C0;CUNEIFORM SIGN LAGAB TIMES BAD;Lo;0;L;;;;;N;;;;;
16137 121C1;CUNEIFORM SIGN LAGAB TIMES BI;Lo;0;L;;;;;N;;;;;
16138 121C2;CUNEIFORM SIGN LAGAB TIMES DAR;Lo;0;L;;;;;N;;;;;
16139 121C3;CUNEIFORM SIGN LAGAB TIMES EN;Lo;0;L;;;;;N;;;;;
16140 121C4;CUNEIFORM SIGN LAGAB TIMES GA;Lo;0;L;;;;;N;;;;;
16141 121C5;CUNEIFORM SIGN LAGAB TIMES GAR;Lo;0;L;;;;;N;;;;;
16142 121C6;CUNEIFORM SIGN LAGAB TIMES GUD;Lo;0;L;;;;;N;;;;;
16143 121C7;CUNEIFORM SIGN LAGAB TIMES GUD PLUS GUD;Lo;0;L;;;;;N;;;;;
16144 121C8;CUNEIFORM SIGN LAGAB TIMES HA;Lo;0;L;;;;;N;;;;;
16145 121C9;CUNEIFORM SIGN LAGAB TIMES HAL;Lo;0;L;;;;;N;;;;;
16146 121CA;CUNEIFORM SIGN LAGAB TIMES HI TIMES NUN;Lo;0;L;;;;;N;;;;;
16147 121CB;CUNEIFORM SIGN LAGAB TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
16148 121CC;CUNEIFORM SIGN LAGAB TIMES IM;Lo;0;L;;;;;N;;;;;
16149 121CD;CUNEIFORM SIGN LAGAB TIMES IM PLUS HA;Lo;0;L;;;;;N;;;;;
16150 121CE;CUNEIFORM SIGN LAGAB TIMES IM PLUS LU;Lo;0;L;;;;;N;;;;;
16151 121CF;CUNEIFORM SIGN LAGAB TIMES KI;Lo;0;L;;;;;N;;;;;
16152 121D0;CUNEIFORM SIGN LAGAB TIMES KIN;Lo;0;L;;;;;N;;;;;
16153 121D1;CUNEIFORM SIGN LAGAB TIMES KU3;Lo;0;L;;;;;N;;;;;
16154 121D2;CUNEIFORM SIGN LAGAB TIMES KUL;Lo;0;L;;;;;N;;;;;
16155 121D3;CUNEIFORM SIGN LAGAB TIMES KUL PLUS HI PLUS A;Lo;0;L;;;;;N;;;;;
16156 121D4;CUNEIFORM SIGN LAGAB TIMES LAGAB;Lo;0;L;;;;;N;;;;;
16157 121D5;CUNEIFORM SIGN LAGAB TIMES LISH;Lo;0;L;;;;;N;;;;;
16158 121D6;CUNEIFORM SIGN LAGAB TIMES LU;Lo;0;L;;;;;N;;;;;
16159 121D7;CUNEIFORM SIGN LAGAB TIMES LUL;Lo;0;L;;;;;N;;;;;
16160 121D8;CUNEIFORM SIGN LAGAB TIMES ME;Lo;0;L;;;;;N;;;;;
16161 121D9;CUNEIFORM SIGN LAGAB TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;
16162 121DA;CUNEIFORM SIGN LAGAB TIMES MUSH;Lo;0;L;;;;;N;;;;;
16163 121DB;CUNEIFORM SIGN LAGAB TIMES NE;Lo;0;L;;;;;N;;;;;
16164 121DC;CUNEIFORM SIGN LAGAB TIMES SHE PLUS SUM;Lo;0;L;;;;;N;;;;;
16165 121DD;CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH PLUS ERIN2;Lo;0;L;;;;;N;;;;;
16166 121DE;CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH TENU;Lo;0;L;;;;;N;;;;;
16167 121DF;CUNEIFORM SIGN LAGAB TIMES SHU2;Lo;0;L;;;;;N;;;;;
16168 121E0;CUNEIFORM SIGN LAGAB TIMES SHU2 PLUS SHU2;Lo;0;L;;;;;N;;;;;
16169 121E1;CUNEIFORM SIGN LAGAB TIMES SUM;Lo;0;L;;;;;N;;;;;
16170 121E2;CUNEIFORM SIGN LAGAB TIMES TAG;Lo;0;L;;;;;N;;;;;
16171 121E3;CUNEIFORM SIGN LAGAB TIMES TAK4;Lo;0;L;;;;;N;;;;;
16172 121E4;CUNEIFORM SIGN LAGAB TIMES TE PLUS A PLUS SU PLUS NA;Lo;0;L;;;;;N;;;;;
16173 121E5;CUNEIFORM SIGN LAGAB TIMES U;Lo;0;L;;;;;N;;;;;
16174 121E6;CUNEIFORM SIGN LAGAB TIMES U PLUS A;Lo;0;L;;;;;N;;;;;
16175 121E7;CUNEIFORM SIGN LAGAB TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;;
16176 121E8;CUNEIFORM SIGN LAGAB TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;;
16177 121E9;CUNEIFORM SIGN LAGAB TIMES UD;Lo;0;L;;;;;N;;;;;
16178 121EA;CUNEIFORM SIGN LAGAB TIMES USH;Lo;0;L;;;;;N;;;;;
16179 121EB;CUNEIFORM SIGN LAGAB SQUARED;Lo;0;L;;;;;N;;;;;
16180 121EC;CUNEIFORM SIGN LAGAR;Lo;0;L;;;;;N;;;;;
16181 121ED;CUNEIFORM SIGN LAGAR TIMES SHE;Lo;0;L;;;;;N;;;;;
16182 121EE;CUNEIFORM SIGN LAGAR TIMES SHE PLUS SUM;Lo;0;L;;;;;N;;;;;
16183 121EF;CUNEIFORM SIGN LAGAR GUNU;Lo;0;L;;;;;N;;;;;
16184 121F0;CUNEIFORM SIGN LAGAR GUNU OVER LAGAR GUNU SHE;Lo;0;L;;;;;N;;;;;
16185 121F1;CUNEIFORM SIGN LAHSHU;Lo;0;L;;;;;N;;;;;
16186 121F2;CUNEIFORM SIGN LAL;Lo;0;L;;;;;N;;;;;
16187 121F3;CUNEIFORM SIGN LAL TIMES LAL;Lo;0;L;;;;;N;;;;;
16188 121F4;CUNEIFORM SIGN LAM;Lo;0;L;;;;;N;;;;;
16189 121F5;CUNEIFORM SIGN LAM TIMES KUR;Lo;0;L;;;;;N;;;;;
16190 121F6;CUNEIFORM SIGN LAM TIMES KUR PLUS RU;Lo;0;L;;;;;N;;;;;
16191 121F7;CUNEIFORM SIGN LI;Lo;0;L;;;;;N;;;;;
16192 121F8;CUNEIFORM SIGN LIL;Lo;0;L;;;;;N;;;;;
16193 121F9;CUNEIFORM SIGN LIMMU2;Lo;0;L;;;;;N;;;;;
16194 121FA;CUNEIFORM SIGN LISH;Lo;0;L;;;;;N;;;;;
16195 121FB;CUNEIFORM SIGN LU;Lo;0;L;;;;;N;;;;;
16196 121FC;CUNEIFORM SIGN LU TIMES BAD;Lo;0;L;;;;;N;;;;;
16197 121FD;CUNEIFORM SIGN LU2;Lo;0;L;;;;;N;;;;;
16198 121FE;CUNEIFORM SIGN LU2 TIMES AL;Lo;0;L;;;;;N;;;;;
16199 121FF;CUNEIFORM SIGN LU2 TIMES BAD;Lo;0;L;;;;;N;;;;;
16200 12200;CUNEIFORM SIGN LU2 TIMES ESH2;Lo;0;L;;;;;N;;;;;
16201 12201;CUNEIFORM SIGN LU2 TIMES ESH2 TENU;Lo;0;L;;;;;N;;;;;
16202 12202;CUNEIFORM SIGN LU2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
16203 12203;CUNEIFORM SIGN LU2 TIMES HI TIMES BAD;Lo;0;L;;;;;N;;;;;
16204 12204;CUNEIFORM SIGN LU2 TIMES IM;Lo;0;L;;;;;N;;;;;
16205 12205;CUNEIFORM SIGN LU2 TIMES KAD2;Lo;0;L;;;;;N;;;;;
16206 12206;CUNEIFORM SIGN LU2 TIMES KAD3;Lo;0;L;;;;;N;;;;;
16207 12207;CUNEIFORM SIGN LU2 TIMES KAD3 PLUS ASH;Lo;0;L;;;;;N;;;;;
16208 12208;CUNEIFORM SIGN LU2 TIMES KI;Lo;0;L;;;;;N;;;;;
16209 12209;CUNEIFORM SIGN LU2 TIMES LA PLUS ASH;Lo;0;L;;;;;N;;;;;
16210 1220A;CUNEIFORM SIGN LU2 TIMES LAGAB;Lo;0;L;;;;;N;;;;;
16211 1220B;CUNEIFORM SIGN LU2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;
16212 1220C;CUNEIFORM SIGN LU2 TIMES NE;Lo;0;L;;;;;N;;;;;
16213 1220D;CUNEIFORM SIGN LU2 TIMES NU;Lo;0;L;;;;;N;;;;;
16214 1220E;CUNEIFORM SIGN LU2 TIMES SI PLUS ASH;Lo;0;L;;;;;N;;;;;
16215 1220F;CUNEIFORM SIGN LU2 TIMES SIK2 PLUS BU;Lo;0;L;;;;;N;;;;;
16216 12210;CUNEIFORM SIGN LU2 TIMES TUG2;Lo;0;L;;;;;N;;;;;
16217 12211;CUNEIFORM SIGN LU2 TENU;Lo;0;L;;;;;N;;;;;
16218 12212;CUNEIFORM SIGN LU2 CROSSING LU2;Lo;0;L;;;;;N;;;;;
16219 12213;CUNEIFORM SIGN LU2 OPPOSING LU2;Lo;0;L;;;;;N;;;;;
16220 12214;CUNEIFORM SIGN LU2 SQUARED;Lo;0;L;;;;;N;;;;;
16221 12215;CUNEIFORM SIGN LU2 SHESHIG;Lo;0;L;;;;;N;;;;;
16222 12216;CUNEIFORM SIGN LU3;Lo;0;L;;;;;N;;;;;
16223 12217;CUNEIFORM SIGN LUGAL;Lo;0;L;;;;;N;;;;;
16224 12218;CUNEIFORM SIGN LUGAL OVER LUGAL;Lo;0;L;;;;;N;;;;;
16225 12219;CUNEIFORM SIGN LUGAL OPPOSING LUGAL;Lo;0;L;;;;;N;;;;;
16226 1221A;CUNEIFORM SIGN LUGAL SHESHIG;Lo;0;L;;;;;N;;;;;
16227 1221B;CUNEIFORM SIGN LUH;Lo;0;L;;;;;N;;;;;
16228 1221C;CUNEIFORM SIGN LUL;Lo;0;L;;;;;N;;;;;
16229 1221D;CUNEIFORM SIGN LUM;Lo;0;L;;;;;N;;;;;
16230 1221E;CUNEIFORM SIGN LUM OVER LUM;Lo;0;L;;;;;N;;;;;
16231 1221F;CUNEIFORM SIGN LUM OVER LUM GAR OVER GAR;Lo;0;L;;;;;N;;;;;
16232 12220;CUNEIFORM SIGN MA;Lo;0;L;;;;;N;;;;;
16233 12221;CUNEIFORM SIGN MA TIMES TAK4;Lo;0;L;;;;;N;;;;;
16234 12222;CUNEIFORM SIGN MA GUNU;Lo;0;L;;;;;N;;;;;
16235 12223;CUNEIFORM SIGN MA2;Lo;0;L;;;;;N;;;;;
16236 12224;CUNEIFORM SIGN MAH;Lo;0;L;;;;;N;;;;;
16237 12225;CUNEIFORM SIGN MAR;Lo;0;L;;;;;N;;;;;
16238 12226;CUNEIFORM SIGN MASH;Lo;0;L;;;;;N;;;;;
16239 12227;CUNEIFORM SIGN MASH2;Lo;0;L;;;;;N;;;;;
16240 12228;CUNEIFORM SIGN ME;Lo;0;L;;;;;N;;;;;
16241 12229;CUNEIFORM SIGN MES;Lo;0;L;;;;;N;;;;;
16242 1222A;CUNEIFORM SIGN MI;Lo;0;L;;;;;N;;;;;
16243 1222B;CUNEIFORM SIGN MIN;Lo;0;L;;;;;N;;;;;
16244 1222C;CUNEIFORM SIGN MU;Lo;0;L;;;;;N;;;;;
16245 1222D;CUNEIFORM SIGN MU OVER MU;Lo;0;L;;;;;N;;;;;
16246 1222E;CUNEIFORM SIGN MUG;Lo;0;L;;;;;N;;;;;
16247 1222F;CUNEIFORM SIGN MUG GUNU;Lo;0;L;;;;;N;;;;;
16248 12230;CUNEIFORM SIGN MUNSUB;Lo;0;L;;;;;N;;;;;
16249 12231;CUNEIFORM SIGN MURGU2;Lo;0;L;;;;;N;;;;;
16250 12232;CUNEIFORM SIGN MUSH;Lo;0;L;;;;;N;;;;;
16251 12233;CUNEIFORM SIGN MUSH TIMES A;Lo;0;L;;;;;N;;;;;
16252 12234;CUNEIFORM SIGN MUSH TIMES KUR;Lo;0;L;;;;;N;;;;;
16253 12235;CUNEIFORM SIGN MUSH TIMES ZA;Lo;0;L;;;;;N;;;;;
16254 12236;CUNEIFORM SIGN MUSH OVER MUSH;Lo;0;L;;;;;N;;;;;
16255 12237;CUNEIFORM SIGN MUSH OVER MUSH TIMES A PLUS NA;Lo;0;L;;;;;N;;;;;
16256 12238;CUNEIFORM SIGN MUSH CROSSING MUSH;Lo;0;L;;;;;N;;;;;
16257 12239;CUNEIFORM SIGN MUSH3;Lo;0;L;;;;;N;;;;;
16258 1223A;CUNEIFORM SIGN MUSH3 TIMES A;Lo;0;L;;;;;N;;;;;
16259 1223B;CUNEIFORM SIGN MUSH3 TIMES A PLUS DI;Lo;0;L;;;;;N;;;;;
16260 1223C;CUNEIFORM SIGN MUSH3 TIMES DI;Lo;0;L;;;;;N;;;;;
16261 1223D;CUNEIFORM SIGN MUSH3 GUNU;Lo;0;L;;;;;N;;;;;
16262 1223E;CUNEIFORM SIGN NA;Lo;0;L;;;;;N;;;;;
16263 1223F;CUNEIFORM SIGN NA2;Lo;0;L;;;;;N;;;;;
16264 12240;CUNEIFORM SIGN NAGA;Lo;0;L;;;;;N;;;;;
16265 12241;CUNEIFORM SIGN NAGA INVERTED;Lo;0;L;;;;;N;;;;;
16266 12242;CUNEIFORM SIGN NAGA TIMES SHU TENU;Lo;0;L;;;;;N;;;;;
16267 12243;CUNEIFORM SIGN NAGA OPPOSING NAGA;Lo;0;L;;;;;N;;;;;
16268 12244;CUNEIFORM SIGN NAGAR;Lo;0;L;;;;;N;;;;;
16269 12245;CUNEIFORM SIGN NAM NUTILLU;Lo;0;L;;;;;N;;;;;
16270 12246;CUNEIFORM SIGN NAM;Lo;0;L;;;;;N;;;;;
16271 12247;CUNEIFORM SIGN NAM2;Lo;0;L;;;;;N;;;;;
16272 12248;CUNEIFORM SIGN NE;Lo;0;L;;;;;N;;;;;
16273 12249;CUNEIFORM SIGN NE TIMES A;Lo;0;L;;;;;N;;;;;
16274 1224A;CUNEIFORM SIGN NE TIMES UD;Lo;0;L;;;;;N;;;;;
16275 1224B;CUNEIFORM SIGN NE SHESHIG;Lo;0;L;;;;;N;;;;;
16276 1224C;CUNEIFORM SIGN NI;Lo;0;L;;;;;N;;;;;
16277 1224D;CUNEIFORM SIGN NI TIMES E;Lo;0;L;;;;;N;;;;;
16278 1224E;CUNEIFORM SIGN NI2;Lo;0;L;;;;;N;;;;;
16279 1224F;CUNEIFORM SIGN NIM;Lo;0;L;;;;;N;;;;;
16280 12250;CUNEIFORM SIGN NIM TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
16281 12251;CUNEIFORM SIGN NIM TIMES GAR PLUS GAN2 TENU;Lo;0;L;;;;;N;;;;;
16282 12252;CUNEIFORM SIGN NINDA2;Lo;0;L;;;;;N;;;;;
16283 12253;CUNEIFORM SIGN NINDA2 TIMES AN;Lo;0;L;;;;;N;;;;;
16284 12254;CUNEIFORM SIGN NINDA2 TIMES ASH;Lo;0;L;;;;;N;;;;;
16285 12255;CUNEIFORM SIGN NINDA2 TIMES ASH PLUS ASH;Lo;0;L;;;;;N;;;;;
16286 12256;CUNEIFORM SIGN NINDA2 TIMES GUD;Lo;0;L;;;;;N;;;;;
16287 12257;CUNEIFORM SIGN NINDA2 TIMES ME PLUS GAN2 TENU;Lo;0;L;;;;;N;;;;;
16288 12258;CUNEIFORM SIGN NINDA2 TIMES NE;Lo;0;L;;;;;N;;;;;
16289 12259;CUNEIFORM SIGN NINDA2 TIMES NUN;Lo;0;L;;;;;N;;;;;
16290 1225A;CUNEIFORM SIGN NINDA2 TIMES SHE;Lo;0;L;;;;;N;;;;;
16291 1225B;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS A AN;Lo;0;L;;;;;N;;;;;
16292 1225C;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH;Lo;0;L;;;;;N;;;;;
16293 1225D;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH PLUS ASH;Lo;0;L;;;;;N;;;;;
16294 1225E;CUNEIFORM SIGN NINDA2 TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;;
16295 1225F;CUNEIFORM SIGN NINDA2 TIMES USH;Lo;0;L;;;;;N;;;;;
16296 12260;CUNEIFORM SIGN NISAG;Lo;0;L;;;;;N;;;;;
16297 12261;CUNEIFORM SIGN NU;Lo;0;L;;;;;N;;;;;
16298 12262;CUNEIFORM SIGN NU11;Lo;0;L;;;;;N;;;;;
16299 12263;CUNEIFORM SIGN NUN;Lo;0;L;;;;;N;;;;;
16300 12264;CUNEIFORM SIGN NUN LAGAR TIMES GAR;Lo;0;L;;;;;N;;;;;
16301 12265;CUNEIFORM SIGN NUN LAGAR TIMES MASH;Lo;0;L;;;;;N;;;;;
16302 12266;CUNEIFORM SIGN NUN LAGAR TIMES SAL;Lo;0;L;;;;;N;;;;;
16303 12267;CUNEIFORM SIGN NUN LAGAR TIMES SAL OVER NUN LAGAR TIMES SAL;Lo;0;L;;;;;N;;;;;
16304 12268;CUNEIFORM SIGN NUN LAGAR TIMES USH;Lo;0;L;;;;;N;;;;;
16305 12269;CUNEIFORM SIGN NUN TENU;Lo;0;L;;;;;N;;;;;
16306 1226A;CUNEIFORM SIGN NUN OVER NUN;Lo;0;L;;;;;N;;;;;
16307 1226B;CUNEIFORM SIGN NUN CROSSING NUN;Lo;0;L;;;;;N;;;;;
16308 1226C;CUNEIFORM SIGN NUN CROSSING NUN LAGAR OVER LAGAR;Lo;0;L;;;;;N;;;;;
16309 1226D;CUNEIFORM SIGN NUNUZ;Lo;0;L;;;;;N;;;;;
16310 1226E;CUNEIFORM SIGN NUNUZ AB2 TIMES ASHGAB;Lo;0;L;;;;;N;;;;;
16311 1226F;CUNEIFORM SIGN NUNUZ AB2 TIMES BI;Lo;0;L;;;;;N;;;;;
16312 12270;CUNEIFORM SIGN NUNUZ AB2 TIMES DUG;Lo;0;L;;;;;N;;;;;
16313 12271;CUNEIFORM SIGN NUNUZ AB2 TIMES GUD;Lo;0;L;;;;;N;;;;;
16314 12272;CUNEIFORM SIGN NUNUZ AB2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
16315 12273;CUNEIFORM SIGN NUNUZ AB2 TIMES KAD3;Lo;0;L;;;;;N;;;;;
16316 12274;CUNEIFORM SIGN NUNUZ AB2 TIMES LA;Lo;0;L;;;;;N;;;;;
16317 12275;CUNEIFORM SIGN NUNUZ AB2 TIMES NE;Lo;0;L;;;;;N;;;;;
16318 12276;CUNEIFORM SIGN NUNUZ AB2 TIMES SILA3;Lo;0;L;;;;;N;;;;;
16319 12277;CUNEIFORM SIGN NUNUZ AB2 TIMES U2;Lo;0;L;;;;;N;;;;;
16320 12278;CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI;Lo;0;L;;;;;N;;;;;
16321 12279;CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI U;Lo;0;L;;;;;N;;;;;
16322 1227A;CUNEIFORM SIGN PA;Lo;0;L;;;;;N;;;;;
16323 1227B;CUNEIFORM SIGN PAD;Lo;0;L;;;;;N;;;;;
16324 1227C;CUNEIFORM SIGN PAN;Lo;0;L;;;;;N;;;;;
16325 1227D;CUNEIFORM SIGN PAP;Lo;0;L;;;;;N;;;;;
16326 1227E;CUNEIFORM SIGN PESH2;Lo;0;L;;;;;N;;;;;
16327 1227F;CUNEIFORM SIGN PI;Lo;0;L;;;;;N;;;;;
16328 12280;CUNEIFORM SIGN PI TIMES A;Lo;0;L;;;;;N;;;;;
16329 12281;CUNEIFORM SIGN PI TIMES AB;Lo;0;L;;;;;N;;;;;
16330 12282;CUNEIFORM SIGN PI TIMES BI;Lo;0;L;;;;;N;;;;;
16331 12283;CUNEIFORM SIGN PI TIMES BU;Lo;0;L;;;;;N;;;;;
16332 12284;CUNEIFORM SIGN PI TIMES E;Lo;0;L;;;;;N;;;;;
16333 12285;CUNEIFORM SIGN PI TIMES I;Lo;0;L;;;;;N;;;;;
16334 12286;CUNEIFORM SIGN PI TIMES IB;Lo;0;L;;;;;N;;;;;
16335 12287;CUNEIFORM SIGN PI TIMES U;Lo;0;L;;;;;N;;;;;
16336 12288;CUNEIFORM SIGN PI TIMES U2;Lo;0;L;;;;;N;;;;;
16337 12289;CUNEIFORM SIGN PI CROSSING PI;Lo;0;L;;;;;N;;;;;
16338 1228A;CUNEIFORM SIGN PIRIG;Lo;0;L;;;;;N;;;;;
16339 1228B;CUNEIFORM SIGN PIRIG TIMES KAL;Lo;0;L;;;;;N;;;;;
16340 1228C;CUNEIFORM SIGN PIRIG TIMES UD;Lo;0;L;;;;;N;;;;;
16341 1228D;CUNEIFORM SIGN PIRIG TIMES ZA;Lo;0;L;;;;;N;;;;;
16342 1228E;CUNEIFORM SIGN PIRIG OPPOSING PIRIG;Lo;0;L;;;;;N;;;;;
16343 1228F;CUNEIFORM SIGN RA;Lo;0;L;;;;;N;;;;;
16344 12290;CUNEIFORM SIGN RAB;Lo;0;L;;;;;N;;;;;
16345 12291;CUNEIFORM SIGN RI;Lo;0;L;;;;;N;;;;;
16346 12292;CUNEIFORM SIGN RU;Lo;0;L;;;;;N;;;;;
16347 12293;CUNEIFORM SIGN SA;Lo;0;L;;;;;N;;;;;
16348 12294;CUNEIFORM SIGN SAG NUTILLU;Lo;0;L;;;;;N;;;;;
16349 12295;CUNEIFORM SIGN SAG;Lo;0;L;;;;;N;;;;;
16350 12296;CUNEIFORM SIGN SAG TIMES A;Lo;0;L;;;;;N;;;;;
16351 12297;CUNEIFORM SIGN SAG TIMES DU;Lo;0;L;;;;;N;;;;;
16352 12298;CUNEIFORM SIGN SAG TIMES DUB;Lo;0;L;;;;;N;;;;;
16353 12299;CUNEIFORM SIGN SAG TIMES HA;Lo;0;L;;;;;N;;;;;
16354 1229A;CUNEIFORM SIGN SAG TIMES KAK;Lo;0;L;;;;;N;;;;;
16355 1229B;CUNEIFORM SIGN SAG TIMES KUR;Lo;0;L;;;;;N;;;;;
16356 1229C;CUNEIFORM SIGN SAG TIMES LUM;Lo;0;L;;;;;N;;;;;
16357 1229D;CUNEIFORM SIGN SAG TIMES MI;Lo;0;L;;;;;N;;;;;
16358 1229E;CUNEIFORM SIGN SAG TIMES NUN;Lo;0;L;;;;;N;;;;;
16359 1229F;CUNEIFORM SIGN SAG TIMES SAL;Lo;0;L;;;;;N;;;;;
16360 122A0;CUNEIFORM SIGN SAG TIMES SHID;Lo;0;L;;;;;N;;;;;
16361 122A1;CUNEIFORM SIGN SAG TIMES TAB;Lo;0;L;;;;;N;;;;;
16362 122A2;CUNEIFORM SIGN SAG TIMES U2;Lo;0;L;;;;;N;;;;;
16363 122A3;CUNEIFORM SIGN SAG TIMES UB;Lo;0;L;;;;;N;;;;;
16364 122A4;CUNEIFORM SIGN SAG TIMES UM;Lo;0;L;;;;;N;;;;;
16365 122A5;CUNEIFORM SIGN SAG TIMES UR;Lo;0;L;;;;;N;;;;;
16366 122A6;CUNEIFORM SIGN SAG TIMES USH;Lo;0;L;;;;;N;;;;;
16367 122A7;CUNEIFORM SIGN SAG OVER SAG;Lo;0;L;;;;;N;;;;;
16368 122A8;CUNEIFORM SIGN SAG GUNU;Lo;0;L;;;;;N;;;;;
16369 122A9;CUNEIFORM SIGN SAL;Lo;0;L;;;;;N;;;;;
16370 122AA;CUNEIFORM SIGN SAL LAGAB TIMES ASH2;Lo;0;L;;;;;N;;;;;
16371 122AB;CUNEIFORM SIGN SANGA2;Lo;0;L;;;;;N;;;;;
16372 122AC;CUNEIFORM SIGN SAR;Lo;0;L;;;;;N;;;;;
16373 122AD;CUNEIFORM SIGN SHA;Lo;0;L;;;;;N;;;;;
16374 122AE;CUNEIFORM SIGN SHA3;Lo;0;L;;;;;N;;;;;
16375 122AF;CUNEIFORM SIGN SHA3 TIMES A;Lo;0;L;;;;;N;;;;;
16376 122B0;CUNEIFORM SIGN SHA3 TIMES BAD;Lo;0;L;;;;;N;;;;;
16377 122B1;CUNEIFORM SIGN SHA3 TIMES GISH;Lo;0;L;;;;;N;;;;;
16378 122B2;CUNEIFORM SIGN SHA3 TIMES NE;Lo;0;L;;;;;N;;;;;
16379 122B3;CUNEIFORM SIGN SHA3 TIMES SHU2;Lo;0;L;;;;;N;;;;;
16380 122B4;CUNEIFORM SIGN SHA3 TIMES TUR;Lo;0;L;;;;;N;;;;;
16381 122B5;CUNEIFORM SIGN SHA3 TIMES U;Lo;0;L;;;;;N;;;;;
16382 122B6;CUNEIFORM SIGN SHA3 TIMES U PLUS A;Lo;0;L;;;;;N;;;;;
16383 122B7;CUNEIFORM SIGN SHA6;Lo;0;L;;;;;N;;;;;
16384 122B8;CUNEIFORM SIGN SHAB6;Lo;0;L;;;;;N;;;;;
16385 122B9;CUNEIFORM SIGN SHAR2;Lo;0;L;;;;;N;;;;;
16386 122BA;CUNEIFORM SIGN SHE;Lo;0;L;;;;;N;;;;;
16387 122BB;CUNEIFORM SIGN SHE HU;Lo;0;L;;;;;N;;;;;
16388 122BC;CUNEIFORM SIGN SHE OVER SHE GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;
16389 122BD;CUNEIFORM SIGN SHE OVER SHE TAB OVER TAB GAR OVER GAR;Lo;0;L;;;;;N;;;;;
16390 122BE;CUNEIFORM SIGN SHEG9;Lo;0;L;;;;;N;;;;;
16391 122BF;CUNEIFORM SIGN SHEN;Lo;0;L;;;;;N;;;;;
16392 122C0;CUNEIFORM SIGN SHESH;Lo;0;L;;;;;N;;;;;
16393 122C1;CUNEIFORM SIGN SHESH2;Lo;0;L;;;;;N;;;;;
16394 122C2;CUNEIFORM SIGN SHESHLAM;Lo;0;L;;;;;N;;;;;
16395 122C3;CUNEIFORM SIGN SHID;Lo;0;L;;;;;N;;;;;
16396 122C4;CUNEIFORM SIGN SHID TIMES A;Lo;0;L;;;;;N;;;;;
16397 122C5;CUNEIFORM SIGN SHID TIMES IM;Lo;0;L;;;;;N;;;;;
16398 122C6;CUNEIFORM SIGN SHIM;Lo;0;L;;;;;N;;;;;
16399 122C7;CUNEIFORM SIGN SHIM TIMES A;Lo;0;L;;;;;N;;;;;
16400 122C8;CUNEIFORM SIGN SHIM TIMES BAL;Lo;0;L;;;;;N;;;;;
16401 122C9;CUNEIFORM SIGN SHIM TIMES BULUG;Lo;0;L;;;;;N;;;;;
16402 122CA;CUNEIFORM SIGN SHIM TIMES DIN;Lo;0;L;;;;;N;;;;;
16403 122CB;CUNEIFORM SIGN SHIM TIMES GAR;Lo;0;L;;;;;N;;;;;
16404 122CC;CUNEIFORM SIGN SHIM TIMES IGI;Lo;0;L;;;;;N;;;;;
16405 122CD;CUNEIFORM SIGN SHIM TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;
16406 122CE;CUNEIFORM SIGN SHIM TIMES KUSHU2;Lo;0;L;;;;;N;;;;;
16407 122CF;CUNEIFORM SIGN SHIM TIMES LUL;Lo;0;L;;;;;N;;;;;
16408 122D0;CUNEIFORM SIGN SHIM TIMES MUG;Lo;0;L;;;;;N;;;;;
16409 122D1;CUNEIFORM SIGN SHIM TIMES SAL;Lo;0;L;;;;;N;;;;;
16410 122D2;CUNEIFORM SIGN SHINIG;Lo;0;L;;;;;N;;;;;
16411 122D3;CUNEIFORM SIGN SHIR;Lo;0;L;;;;;N;;;;;
16412 122D4;CUNEIFORM SIGN SHIR TENU;Lo;0;L;;;;;N;;;;;
16413 122D5;CUNEIFORM SIGN SHIR OVER SHIR BUR OVER BUR;Lo;0;L;;;;;N;;;;;
16414 122D6;CUNEIFORM SIGN SHITA;Lo;0;L;;;;;N;;;;;
16415 122D7;CUNEIFORM SIGN SHU;Lo;0;L;;;;;N;;;;;
16416 122D8;CUNEIFORM SIGN SHU OVER INVERTED SHU;Lo;0;L;;;;;N;;;;;
16417 122D9;CUNEIFORM SIGN SHU2;Lo;0;L;;;;;N;;;;;
16418 122DA;CUNEIFORM SIGN SHUBUR;Lo;0;L;;;;;N;;;;;
16419 122DB;CUNEIFORM SIGN SI;Lo;0;L;;;;;N;;;;;
16420 122DC;CUNEIFORM SIGN SI GUNU;Lo;0;L;;;;;N;;;;;
16421 122DD;CUNEIFORM SIGN SIG;Lo;0;L;;;;;N;;;;;
16422 122DE;CUNEIFORM SIGN SIG4;Lo;0;L;;;;;N;;;;;
16423 122DF;CUNEIFORM SIGN SIG4 OVER SIG4 SHU2;Lo;0;L;;;;;N;;;;;
16424 122E0;CUNEIFORM SIGN SIK2;Lo;0;L;;;;;N;;;;;
16425 122E1;CUNEIFORM SIGN SILA3;Lo;0;L;;;;;N;;;;;
16426 122E2;CUNEIFORM SIGN SU;Lo;0;L;;;;;N;;;;;
16427 122E3;CUNEIFORM SIGN SU OVER SU;Lo;0;L;;;;;N;;;;;
16428 122E4;CUNEIFORM SIGN SUD;Lo;0;L;;;;;N;;;;;
16429 122E5;CUNEIFORM SIGN SUD2;Lo;0;L;;;;;N;;;;;
16430 122E6;CUNEIFORM SIGN SUHUR;Lo;0;L;;;;;N;;;;;
16431 122E7;CUNEIFORM SIGN SUM;Lo;0;L;;;;;N;;;;;
16432 122E8;CUNEIFORM SIGN SUMASH;Lo;0;L;;;;;N;;;;;
16433 122E9;CUNEIFORM SIGN SUR;Lo;0;L;;;;;N;;;;;
16434 122EA;CUNEIFORM SIGN SUR9;Lo;0;L;;;;;N;;;;;
16435 122EB;CUNEIFORM SIGN TA;Lo;0;L;;;;;N;;;;;
16436 122EC;CUNEIFORM SIGN TA ASTERISK;Lo;0;L;;;;;N;;;;;
16437 122ED;CUNEIFORM SIGN TA TIMES HI;Lo;0;L;;;;;N;;;;;
16438 122EE;CUNEIFORM SIGN TA TIMES MI;Lo;0;L;;;;;N;;;;;
16439 122EF;CUNEIFORM SIGN TA GUNU;Lo;0;L;;;;;N;;;;;
16440 122F0;CUNEIFORM SIGN TAB;Lo;0;L;;;;;N;;;;;
16441 122F1;CUNEIFORM SIGN TAB OVER TAB NI OVER NI DISH OVER DISH;Lo;0;L;;;;;N;;;;;
16442 122F2;CUNEIFORM SIGN TAB SQUARED;Lo;0;L;;;;;N;;;;;
16443 122F3;CUNEIFORM SIGN TAG;Lo;0;L;;;;;N;;;;;
16444 122F4;CUNEIFORM SIGN TAG TIMES BI;Lo;0;L;;;;;N;;;;;
16445 122F5;CUNEIFORM SIGN TAG TIMES GUD;Lo;0;L;;;;;N;;;;;
16446 122F6;CUNEIFORM SIGN TAG TIMES SHE;Lo;0;L;;;;;N;;;;;
16447 122F7;CUNEIFORM SIGN TAG TIMES SHU;Lo;0;L;;;;;N;;;;;
16448 122F8;CUNEIFORM SIGN TAG TIMES TUG2;Lo;0;L;;;;;N;;;;;
16449 122F9;CUNEIFORM SIGN TAG TIMES UD;Lo;0;L;;;;;N;;;;;
16450 122FA;CUNEIFORM SIGN TAK4;Lo;0;L;;;;;N;;;;;
16451 122FB;CUNEIFORM SIGN TAR;Lo;0;L;;;;;N;;;;;
16452 122FC;CUNEIFORM SIGN TE;Lo;0;L;;;;;N;;;;;
16453 122FD;CUNEIFORM SIGN TE GUNU;Lo;0;L;;;;;N;;;;;
16454 122FE;CUNEIFORM SIGN TI;Lo;0;L;;;;;N;;;;;
16455 122FF;CUNEIFORM SIGN TI TENU;Lo;0;L;;;;;N;;;;;
16456 12300;CUNEIFORM SIGN TIL;Lo;0;L;;;;;N;;;;;
16457 12301;CUNEIFORM SIGN TIR;Lo;0;L;;;;;N;;;;;
16458 12302;CUNEIFORM SIGN TIR TIMES TAK4;Lo;0;L;;;;;N;;;;;
16459 12303;CUNEIFORM SIGN TIR OVER TIR;Lo;0;L;;;;;N;;;;;
16460 12304;CUNEIFORM SIGN TIR OVER TIR GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;
16461 12305;CUNEIFORM SIGN TU;Lo;0;L;;;;;N;;;;;
16462 12306;CUNEIFORM SIGN TUG2;Lo;0;L;;;;;N;;;;;
16463 12307;CUNEIFORM SIGN TUK;Lo;0;L;;;;;N;;;;;
16464 12308;CUNEIFORM SIGN TUM;Lo;0;L;;;;;N;;;;;
16465 12309;CUNEIFORM SIGN TUR;Lo;0;L;;;;;N;;;;;
16466 1230A;CUNEIFORM SIGN TUR OVER TUR ZA OVER ZA;Lo;0;L;;;;;N;;;;;
16467 1230B;CUNEIFORM SIGN U;Lo;0;L;;;;;N;;;;;
16468 1230C;CUNEIFORM SIGN U GUD;Lo;0;L;;;;;N;;;;;
16469 1230D;CUNEIFORM SIGN U U U;Lo;0;L;;;;;N;;;;;
16470 1230E;CUNEIFORM SIGN U OVER U PA OVER PA GAR OVER GAR;Lo;0;L;;;;;N;;;;;
16471 1230F;CUNEIFORM SIGN U OVER U SUR OVER SUR;Lo;0;L;;;;;N;;;;;
16472 12310;CUNEIFORM SIGN U OVER U U REVERSED OVER U REVERSED;Lo;0;L;;;;;N;;;;;
16473 12311;CUNEIFORM SIGN U2;Lo;0;L;;;;;N;;;;;
16474 12312;CUNEIFORM SIGN UB;Lo;0;L;;;;;N;;;;;
16475 12313;CUNEIFORM SIGN UD;Lo;0;L;;;;;N;;;;;
16476 12314;CUNEIFORM SIGN UD KUSHU2;Lo;0;L;;;;;N;;;;;
16477 12315;CUNEIFORM SIGN UD TIMES BAD;Lo;0;L;;;;;N;;;;;
16478 12316;CUNEIFORM SIGN UD TIMES MI;Lo;0;L;;;;;N;;;;;
16479 12317;CUNEIFORM SIGN UD TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;;
16480 12318;CUNEIFORM SIGN UD TIMES U PLUS U PLUS U GUNU;Lo;0;L;;;;;N;;;;;
16481 12319;CUNEIFORM SIGN UD GUNU;Lo;0;L;;;;;N;;;;;
16482 1231A;CUNEIFORM SIGN UD SHESHIG;Lo;0;L;;;;;N;;;;;
16483 1231B;CUNEIFORM SIGN UD SHESHIG TIMES BAD;Lo;0;L;;;;;N;;;;;
16484 1231C;CUNEIFORM SIGN UDUG;Lo;0;L;;;;;N;;;;;
16485 1231D;CUNEIFORM SIGN UM;Lo;0;L;;;;;N;;;;;
16486 1231E;CUNEIFORM SIGN UM TIMES LAGAB;Lo;0;L;;;;;N;;;;;
16487 1231F;CUNEIFORM SIGN UM TIMES ME PLUS DA;Lo;0;L;;;;;N;;;;;
16488 12320;CUNEIFORM SIGN UM TIMES SHA3;Lo;0;L;;;;;N;;;;;
16489 12321;CUNEIFORM SIGN UM TIMES U;Lo;0;L;;;;;N;;;;;
16490 12322;CUNEIFORM SIGN UMBIN;Lo;0;L;;;;;N;;;;;
16491 12323;CUNEIFORM SIGN UMUM;Lo;0;L;;;;;N;;;;;
16492 12324;CUNEIFORM SIGN UMUM TIMES KASKAL;Lo;0;L;;;;;N;;;;;
16493 12325;CUNEIFORM SIGN UMUM TIMES PA;Lo;0;L;;;;;N;;;;;
16494 12326;CUNEIFORM SIGN UN;Lo;0;L;;;;;N;;;;;
16495 12327;CUNEIFORM SIGN UN GUNU;Lo;0;L;;;;;N;;;;;
16496 12328;CUNEIFORM SIGN UR;Lo;0;L;;;;;N;;;;;
16497 12329;CUNEIFORM SIGN UR CROSSING UR;Lo;0;L;;;;;N;;;;;
16498 1232A;CUNEIFORM SIGN UR SHESHIG;Lo;0;L;;;;;N;;;;;
16499 1232B;CUNEIFORM SIGN UR2;Lo;0;L;;;;;N;;;;;
16500 1232C;CUNEIFORM SIGN UR2 TIMES A PLUS HA;Lo;0;L;;;;;N;;;;;
16501 1232D;CUNEIFORM SIGN UR2 TIMES A PLUS NA;Lo;0;L;;;;;N;;;;;
16502 1232E;CUNEIFORM SIGN UR2 TIMES AL;Lo;0;L;;;;;N;;;;;
16503 1232F;CUNEIFORM SIGN UR2 TIMES HA;Lo;0;L;;;;;N;;;;;
16504 12330;CUNEIFORM SIGN UR2 TIMES NUN;Lo;0;L;;;;;N;;;;;
16505 12331;CUNEIFORM SIGN UR2 TIMES U2;Lo;0;L;;;;;N;;;;;
16506 12332;CUNEIFORM SIGN UR2 TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;;
16507 12333;CUNEIFORM SIGN UR2 TIMES U2 PLUS BI;Lo;0;L;;;;;N;;;;;
16508 12334;CUNEIFORM SIGN UR4;Lo;0;L;;;;;N;;;;;
16509 12335;CUNEIFORM SIGN URI;Lo;0;L;;;;;N;;;;;
16510 12336;CUNEIFORM SIGN URI3;Lo;0;L;;;;;N;;;;;
16511 12337;CUNEIFORM SIGN URU;Lo;0;L;;;;;N;;;;;
16512 12338;CUNEIFORM SIGN URU TIMES A;Lo;0;L;;;;;N;;;;;
16513 12339;CUNEIFORM SIGN URU TIMES ASHGAB;Lo;0;L;;;;;N;;;;;
16514 1233A;CUNEIFORM SIGN URU TIMES BAR;Lo;0;L;;;;;N;;;;;
16515 1233B;CUNEIFORM SIGN URU TIMES DUN;Lo;0;L;;;;;N;;;;;
16516 1233C;CUNEIFORM SIGN URU TIMES GA;Lo;0;L;;;;;N;;;;;
16517 1233D;CUNEIFORM SIGN URU TIMES GAL;Lo;0;L;;;;;N;;;;;
16518 1233E;CUNEIFORM SIGN URU TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;
16519 1233F;CUNEIFORM SIGN URU TIMES GAR;Lo;0;L;;;;;N;;;;;
16520 12340;CUNEIFORM SIGN URU TIMES GU;Lo;0;L;;;;;N;;;;;
16521 12341;CUNEIFORM SIGN URU TIMES HA;Lo;0;L;;;;;N;;;;;
16522 12342;CUNEIFORM SIGN URU TIMES IGI;Lo;0;L;;;;;N;;;;;
16523 12343;CUNEIFORM SIGN URU TIMES IM;Lo;0;L;;;;;N;;;;;
16524 12344;CUNEIFORM SIGN URU TIMES ISH;Lo;0;L;;;;;N;;;;;
16525 12345;CUNEIFORM SIGN URU TIMES KI;Lo;0;L;;;;;N;;;;;
16526 12346;CUNEIFORM SIGN URU TIMES LUM;Lo;0;L;;;;;N;;;;;
16527 12347;CUNEIFORM SIGN URU TIMES MIN;Lo;0;L;;;;;N;;;;;
16528 12348;CUNEIFORM SIGN URU TIMES PA;Lo;0;L;;;;;N;;;;;
16529 12349;CUNEIFORM SIGN URU TIMES SHE;Lo;0;L;;;;;N;;;;;
16530 1234A;CUNEIFORM SIGN URU TIMES SIG4;Lo;0;L;;;;;N;;;;;
16531 1234B;CUNEIFORM SIGN URU TIMES TU;Lo;0;L;;;;;N;;;;;
16532 1234C;CUNEIFORM SIGN URU TIMES U PLUS GUD;Lo;0;L;;;;;N;;;;;
16533 1234D;CUNEIFORM SIGN URU TIMES UD;Lo;0;L;;;;;N;;;;;
16534 1234E;CUNEIFORM SIGN URU TIMES URUDA;Lo;0;L;;;;;N;;;;;
16535 1234F;CUNEIFORM SIGN URUDA;Lo;0;L;;;;;N;;;;;
16536 12350;CUNEIFORM SIGN URUDA TIMES U;Lo;0;L;;;;;N;;;;;
16537 12351;CUNEIFORM SIGN USH;Lo;0;L;;;;;N;;;;;
16538 12352;CUNEIFORM SIGN USH TIMES A;Lo;0;L;;;;;N;;;;;
16539 12353;CUNEIFORM SIGN USH TIMES KU;Lo;0;L;;;;;N;;;;;
16540 12354;CUNEIFORM SIGN USH TIMES KUR;Lo;0;L;;;;;N;;;;;
16541 12355;CUNEIFORM SIGN USH TIMES TAK4;Lo;0;L;;;;;N;;;;;
16542 12356;CUNEIFORM SIGN USHX;Lo;0;L;;;;;N;;;;;
16543 12357;CUNEIFORM SIGN USH2;Lo;0;L;;;;;N;;;;;
16544 12358;CUNEIFORM SIGN USHUMX;Lo;0;L;;;;;N;;;;;
16545 12359;CUNEIFORM SIGN UTUKI;Lo;0;L;;;;;N;;;;;
16546 1235A;CUNEIFORM SIGN UZ3;Lo;0;L;;;;;N;;;;;
16547 1235B;CUNEIFORM SIGN UZ3 TIMES KASKAL;Lo;0;L;;;;;N;;;;;
16548 1235C;CUNEIFORM SIGN UZU;Lo;0;L;;;;;N;;;;;
16549 1235D;CUNEIFORM SIGN ZA;Lo;0;L;;;;;N;;;;;
16550 1235E;CUNEIFORM SIGN ZA TENU;Lo;0;L;;;;;N;;;;;
16551 1235F;CUNEIFORM SIGN ZA SQUARED TIMES KUR;Lo;0;L;;;;;N;;;;;
16552 12360;CUNEIFORM SIGN ZAG;Lo;0;L;;;;;N;;;;;
16553 12361;CUNEIFORM SIGN ZAMX;Lo;0;L;;;;;N;;;;;
16554 12362;CUNEIFORM SIGN ZE2;Lo;0;L;;;;;N;;;;;
16555 12363;CUNEIFORM SIGN ZI;Lo;0;L;;;;;N;;;;;
16556 12364;CUNEIFORM SIGN ZI OVER ZI;Lo;0;L;;;;;N;;;;;
16557 12365;CUNEIFORM SIGN ZI3;Lo;0;L;;;;;N;;;;;
16558 12366;CUNEIFORM SIGN ZIB;Lo;0;L;;;;;N;;;;;
16559 12367;CUNEIFORM SIGN ZIB KABA TENU;Lo;0;L;;;;;N;;;;;
16560 12368;CUNEIFORM SIGN ZIG;Lo;0;L;;;;;N;;;;;
16561 12369;CUNEIFORM SIGN ZIZ2;Lo;0;L;;;;;N;;;;;
16562 1236A;CUNEIFORM SIGN ZU;Lo;0;L;;;;;N;;;;;
16563 1236B;CUNEIFORM SIGN ZU5;Lo;0;L;;;;;N;;;;;
16564 1236C;CUNEIFORM SIGN ZU5 TIMES A;Lo;0;L;;;;;N;;;;;
16565 1236D;CUNEIFORM SIGN ZUBUR;Lo;0;L;;;;;N;;;;;
16566 1236E;CUNEIFORM SIGN ZUM;Lo;0;L;;;;;N;;;;;
16567 12400;CUNEIFORM NUMERIC SIGN TWO ASH;Nl;0;L;;;;2;N;;;;;
16568 12401;CUNEIFORM NUMERIC SIGN THREE ASH;Nl;0;L;;;;3;N;;;;;
16569 12402;CUNEIFORM NUMERIC SIGN FOUR ASH;Nl;0;L;;;;4;N;;;;;
16570 12403;CUNEIFORM NUMERIC SIGN FIVE ASH;Nl;0;L;;;;5;N;;;;;
16571 12404;CUNEIFORM NUMERIC SIGN SIX ASH;Nl;0;L;;;;6;N;;;;;
16572 12405;CUNEIFORM NUMERIC SIGN SEVEN ASH;Nl;0;L;;;;7;N;;;;;
16573 12406;CUNEIFORM NUMERIC SIGN EIGHT ASH;Nl;0;L;;;;8;N;;;;;
16574 12407;CUNEIFORM NUMERIC SIGN NINE ASH;Nl;0;L;;;;9;N;;;;;
16575 12408;CUNEIFORM NUMERIC SIGN THREE DISH;Nl;0;L;;;;3;N;;;;;
16576 12409;CUNEIFORM NUMERIC SIGN FOUR DISH;Nl;0;L;;;;4;N;;;;;
16577 1240A;CUNEIFORM NUMERIC SIGN FIVE DISH;Nl;0;L;;;;5;N;;;;;
16578 1240B;CUNEIFORM NUMERIC SIGN SIX DISH;Nl;0;L;;;;6;N;;;;;
16579 1240C;CUNEIFORM NUMERIC SIGN SEVEN DISH;Nl;0;L;;;;7;N;;;;;
16580 1240D;CUNEIFORM NUMERIC SIGN EIGHT DISH;Nl;0;L;;;;8;N;;;;;
16581 1240E;CUNEIFORM NUMERIC SIGN NINE DISH;Nl;0;L;;;;9;N;;;;;
16582 1240F;CUNEIFORM NUMERIC SIGN FOUR U;Nl;0;L;;;;4;N;;;;;
16583 12410;CUNEIFORM NUMERIC SIGN FIVE U;Nl;0;L;;;;5;N;;;;;
16584 12411;CUNEIFORM NUMERIC SIGN SIX U;Nl;0;L;;;;6;N;;;;;
16585 12412;CUNEIFORM NUMERIC SIGN SEVEN U;Nl;0;L;;;;7;N;;;;;
16586 12413;CUNEIFORM NUMERIC SIGN EIGHT U;Nl;0;L;;;;8;N;;;;;
16587 12414;CUNEIFORM NUMERIC SIGN NINE U;Nl;0;L;;;;9;N;;;;;
16588 12415;CUNEIFORM NUMERIC SIGN ONE GESH2;Nl;0;L;;;;1;N;;;;;
16589 12416;CUNEIFORM NUMERIC SIGN TWO GESH2;Nl;0;L;;;;2;N;;;;;
16590 12417;CUNEIFORM NUMERIC SIGN THREE GESH2;Nl;0;L;;;;3;N;;;;;
16591 12418;CUNEIFORM NUMERIC SIGN FOUR GESH2;Nl;0;L;;;;4;N;;;;;
16592 12419;CUNEIFORM NUMERIC SIGN FIVE GESH2;Nl;0;L;;;;5;N;;;;;
16593 1241A;CUNEIFORM NUMERIC SIGN SIX GESH2;Nl;0;L;;;;6;N;;;;;
16594 1241B;CUNEIFORM NUMERIC SIGN SEVEN GESH2;Nl;0;L;;;;7;N;;;;;
16595 1241C;CUNEIFORM NUMERIC SIGN EIGHT GESH2;Nl;0;L;;;;8;N;;;;;
16596 1241D;CUNEIFORM NUMERIC SIGN NINE GESH2;Nl;0;L;;;;9;N;;;;;
16597 1241E;CUNEIFORM NUMERIC SIGN ONE GESHU;Nl;0;L;;;;1;N;;;;;
16598 1241F;CUNEIFORM NUMERIC SIGN TWO GESHU;Nl;0;L;;;;2;N;;;;;
16599 12420;CUNEIFORM NUMERIC SIGN THREE GESHU;Nl;0;L;;;;3;N;;;;;
16600 12421;CUNEIFORM NUMERIC SIGN FOUR GESHU;Nl;0;L;;;;4;N;;;;;
16601 12422;CUNEIFORM NUMERIC SIGN FIVE GESHU;Nl;0;L;;;;5;N;;;;;
16602 12423;CUNEIFORM NUMERIC SIGN TWO SHAR2;Nl;0;L;;;;2;N;;;;;
16603 12424;CUNEIFORM NUMERIC SIGN THREE SHAR2;Nl;0;L;;;;3;N;;;;;
16604 12425;CUNEIFORM NUMERIC SIGN THREE SHAR2 VARIANT FORM;Nl;0;L;;;;3;N;;;;;
16605 12426;CUNEIFORM NUMERIC SIGN FOUR SHAR2;Nl;0;L;;;;4;N;;;;;
16606 12427;CUNEIFORM NUMERIC SIGN FIVE SHAR2;Nl;0;L;;;;5;N;;;;;
16607 12428;CUNEIFORM NUMERIC SIGN SIX SHAR2;Nl;0;L;;;;6;N;;;;;
16608 12429;CUNEIFORM NUMERIC SIGN SEVEN SHAR2;Nl;0;L;;;;7;N;;;;;
16609 1242A;CUNEIFORM NUMERIC SIGN EIGHT SHAR2;Nl;0;L;;;;8;N;;;;;
16610 1242B;CUNEIFORM NUMERIC SIGN NINE SHAR2;Nl;0;L;;;;9;N;;;;;
16611 1242C;CUNEIFORM NUMERIC SIGN ONE SHARU;Nl;0;L;;;;1;N;;;;;
16612 1242D;CUNEIFORM NUMERIC SIGN TWO SHARU;Nl;0;L;;;;2;N;;;;;
16613 1242E;CUNEIFORM NUMERIC SIGN THREE SHARU;Nl;0;L;;;;3;N;;;;;
16614 1242F;CUNEIFORM NUMERIC SIGN THREE SHARU VARIANT FORM;Nl;0;L;;;;3;N;;;;;
16615 12430;CUNEIFORM NUMERIC SIGN FOUR SHARU;Nl;0;L;;;;4;N;;;;;
16616 12431;CUNEIFORM NUMERIC SIGN FIVE SHARU;Nl;0;L;;;;5;N;;;;;
16617 12432;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS DISH;Nl;0;L;;;;;N;;;;;
16618 12433;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS MIN;Nl;0;L;;;;;N;;;;;
16619 12434;CUNEIFORM NUMERIC SIGN ONE BURU;Nl;0;L;;;;1;N;;;;;
16620 12435;CUNEIFORM NUMERIC SIGN TWO BURU;Nl;0;L;;;;2;N;;;;;
16621 12436;CUNEIFORM NUMERIC SIGN THREE BURU;Nl;0;L;;;;3;N;;;;;
16622 12437;CUNEIFORM NUMERIC SIGN THREE BURU VARIANT FORM;Nl;0;L;;;;3;N;;;;;
16623 12438;CUNEIFORM NUMERIC SIGN FOUR BURU;Nl;0;L;;;;4;N;;;;;
16624 12439;CUNEIFORM NUMERIC SIGN FIVE BURU;Nl;0;L;;;;5;N;;;;;
16625 1243A;CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH16;Nl;0;L;;;;3;N;;;;;
16626 1243B;CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH21;Nl;0;L;;;;3;N;;;;;
16627 1243C;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU;Nl;0;L;;;;4;N;;;;;
16628 1243D;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU4;Nl;0;L;;;;4;N;;;;;
16629 1243E;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU A;Nl;0;L;;;;4;N;;;;;
16630 1243F;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU B;Nl;0;L;;;;4;N;;;;;
16631 12440;CUNEIFORM NUMERIC SIGN SIX VARIANT FORM ASH9;Nl;0;L;;;;6;N;;;;;
16632 12441;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN3;Nl;0;L;;;;7;N;;;;;
16633 12442;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN A;Nl;0;L;;;;7;N;;;;;
16634 12443;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN B;Nl;0;L;;;;7;N;;;;;
16635 12444;CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU;Nl;0;L;;;;8;N;;;;;
16636 12445;CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU3;Nl;0;L;;;;8;N;;;;;
16637 12446;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU;Nl;0;L;;;;9;N;;;;;
16638 12447;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU3;Nl;0;L;;;;9;N;;;;;
16639 12448;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU4;Nl;0;L;;;;9;N;;;;;
16640 12449;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU A;Nl;0;L;;;;9;N;;;;;
16641 1244A;CUNEIFORM NUMERIC SIGN TWO ASH TENU;Nl;0;L;;;;2;N;;;;;
16642 1244B;CUNEIFORM NUMERIC SIGN THREE ASH TENU;Nl;0;L;;;;3;N;;;;;
16643 1244C;CUNEIFORM NUMERIC SIGN FOUR ASH TENU;Nl;0;L;;;;4;N;;;;;
16644 1244D;CUNEIFORM NUMERIC SIGN FIVE ASH TENU;Nl;0;L;;;;5;N;;;;;
16645 1244E;CUNEIFORM NUMERIC SIGN SIX ASH TENU;Nl;0;L;;;;6;N;;;;;
16646 1244F;CUNEIFORM NUMERIC SIGN ONE BAN2;Nl;0;L;;;;1;N;;;;;
16647 12450;CUNEIFORM NUMERIC SIGN TWO BAN2;Nl;0;L;;;;2;N;;;;;
16648 12451;CUNEIFORM NUMERIC SIGN THREE BAN2;Nl;0;L;;;;3;N;;;;;
16649 12452;CUNEIFORM NUMERIC SIGN FOUR BAN2;Nl;0;L;;;;4;N;;;;;
16650 12453;CUNEIFORM NUMERIC SIGN FOUR BAN2 VARIANT FORM;Nl;0;L;;;;4;N;;;;;
16651 12454;CUNEIFORM NUMERIC SIGN FIVE BAN2;Nl;0;L;;;;5;N;;;;;
16652 12455;CUNEIFORM NUMERIC SIGN FIVE BAN2 VARIANT FORM;Nl;0;L;;;;5;N;;;;;
16653 12456;CUNEIFORM NUMERIC SIGN NIGIDAMIN;Nl;0;L;;;;;N;;;;;
16654 12457;CUNEIFORM NUMERIC SIGN NIGIDAESH;Nl;0;L;;;;;N;;;;;
16655 12458;CUNEIFORM NUMERIC SIGN ONE ESHE3;Nl;0;L;;;;1;N;;;;;
16656 12459;CUNEIFORM NUMERIC SIGN TWO ESHE3;Nl;0;L;;;;2;N;;;;;
16657 1245A;CUNEIFORM NUMERIC SIGN ONE THIRD DISH;Nl;0;L;;;;1/3;N;;;;;
16658 1245B;CUNEIFORM NUMERIC SIGN TWO THIRDS DISH;Nl;0;L;;;;2/3;N;;;;;
16659 1245C;CUNEIFORM NUMERIC SIGN FIVE SIXTHS DISH;Nl;0;L;;;;5/6;N;;;;;
16660 1245D;CUNEIFORM NUMERIC SIGN ONE THIRD VARIANT FORM A;Nl;0;L;;;;1/3;N;;;;;
16661 1245E;CUNEIFORM NUMERIC SIGN TWO THIRDS VARIANT FORM A;Nl;0;L;;;;2/3;N;;;;;
16662 1245F;CUNEIFORM NUMERIC SIGN ONE EIGHTH ASH;Nl;0;L;;;;1/8;N;;;;;
16663 12460;CUNEIFORM NUMERIC SIGN ONE QUARTER ASH;Nl;0;L;;;;1/4;N;;;;;
16664 12461;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE SIXTH;Nl;0;L;;;;1/6;N;;;;;
16665 12462;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER;Nl;0;L;;;;1/4;N;;;;;
16666 12470;CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER;Po;0;L;;;;;N;;;;;
16667 12471;CUNEIFORM PUNCTUATION SIGN VERTICAL COLON;Po;0;L;;;;;N;;;;;
16668 12472;CUNEIFORM PUNCTUATION SIGN DIAGONAL COLON;Po;0;L;;;;;N;;;;;
16669 12473;CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON;Po;0;L;;;;;N;;;;;
16670 1D000;BYZANTINE MUSICAL SYMBOL PSILI;So;0;L;;;;;N;;;;;
16671 1D001;BYZANTINE MUSICAL SYMBOL DASEIA;So;0;L;;;;;N;;;;;
16672 1D002;BYZANTINE MUSICAL SYMBOL PERISPOMENI;So;0;L;;;;;N;;;;;
16673 1D003;BYZANTINE MUSICAL SYMBOL OXEIA EKFONITIKON;So;0;L;;;;;N;;;;;
16674 1D004;BYZANTINE MUSICAL SYMBOL OXEIA DIPLI;So;0;L;;;;;N;;;;;
16675 1D005;BYZANTINE MUSICAL SYMBOL VAREIA EKFONITIKON;So;0;L;;;;;N;;;;;
16676 1D006;BYZANTINE MUSICAL SYMBOL VAREIA DIPLI;So;0;L;;;;;N;;;;;
16677 1D007;BYZANTINE MUSICAL SYMBOL KATHISTI;So;0;L;;;;;N;;;;;
16678 1D008;BYZANTINE MUSICAL SYMBOL SYRMATIKI;So;0;L;;;;;N;;;;;
16679 1D009;BYZANTINE MUSICAL SYMBOL PARAKLITIKI;So;0;L;;;;;N;;;;;
16680 1D00A;BYZANTINE MUSICAL SYMBOL YPOKRISIS;So;0;L;;;;;N;;;;;
16681 1D00B;BYZANTINE MUSICAL SYMBOL YPOKRISIS DIPLI;So;0;L;;;;;N;;;;;
16682 1D00C;BYZANTINE MUSICAL SYMBOL KREMASTI;So;0;L;;;;;N;;;;;
16683 1D00D;BYZANTINE MUSICAL SYMBOL APESO EKFONITIKON;So;0;L;;;;;N;;;;;
16684 1D00E;BYZANTINE MUSICAL SYMBOL EXO EKFONITIKON;So;0;L;;;;;N;;;;;
16685 1D00F;BYZANTINE MUSICAL SYMBOL TELEIA;So;0;L;;;;;N;;;;;
16686 1D010;BYZANTINE MUSICAL SYMBOL KENTIMATA;So;0;L;;;;;N;;;;;
16687 1D011;BYZANTINE MUSICAL SYMBOL APOSTROFOS;So;0;L;;;;;N;;;;;
16688 1D012;BYZANTINE MUSICAL SYMBOL APOSTROFOS DIPLI;So;0;L;;;;;N;;;;;
16689 1D013;BYZANTINE MUSICAL SYMBOL SYNEVMA;So;0;L;;;;;N;;;;;
16690 1D014;BYZANTINE MUSICAL SYMBOL THITA;So;0;L;;;;;N;;;;;
16691 1D015;BYZANTINE MUSICAL SYMBOL OLIGON ARCHAION;So;0;L;;;;;N;;;;;
16692 1D016;BYZANTINE MUSICAL SYMBOL GORGON ARCHAION;So;0;L;;;;;N;;;;;
16693 1D017;BYZANTINE MUSICAL SYMBOL PSILON;So;0;L;;;;;N;;;;;
16694 1D018;BYZANTINE MUSICAL SYMBOL CHAMILON;So;0;L;;;;;N;;;;;
16695 1D019;BYZANTINE MUSICAL SYMBOL VATHY;So;0;L;;;;;N;;;;;
16696 1D01A;BYZANTINE MUSICAL SYMBOL ISON ARCHAION;So;0;L;;;;;N;;;;;
16697 1D01B;BYZANTINE MUSICAL SYMBOL KENTIMA ARCHAION;So;0;L;;;;;N;;;;;
16698 1D01C;BYZANTINE MUSICAL SYMBOL KENTIMATA ARCHAION;So;0;L;;;;;N;;;;;
16699 1D01D;BYZANTINE MUSICAL SYMBOL SAXIMATA;So;0;L;;;;;N;;;;;
16700 1D01E;BYZANTINE MUSICAL SYMBOL PARICHON;So;0;L;;;;;N;;;;;
16701 1D01F;BYZANTINE MUSICAL SYMBOL STAVROS APODEXIA;So;0;L;;;;;N;;;;;
16702 1D020;BYZANTINE MUSICAL SYMBOL OXEIAI ARCHAION;So;0;L;;;;;N;;;;;
16703 1D021;BYZANTINE MUSICAL SYMBOL VAREIAI ARCHAION;So;0;L;;;;;N;;;;;
16704 1D022;BYZANTINE MUSICAL SYMBOL APODERMA ARCHAION;So;0;L;;;;;N;;;;;
16705 1D023;BYZANTINE MUSICAL SYMBOL APOTHEMA;So;0;L;;;;;N;;;;;
16706 1D024;BYZANTINE MUSICAL SYMBOL KLASMA;So;0;L;;;;;N;;;;;
16707 1D025;BYZANTINE MUSICAL SYMBOL REVMA;So;0;L;;;;;N;;;;;
16708 1D026;BYZANTINE MUSICAL SYMBOL PIASMA ARCHAION;So;0;L;;;;;N;;;;;
16709 1D027;BYZANTINE MUSICAL SYMBOL TINAGMA;So;0;L;;;;;N;;;;;
16710 1D028;BYZANTINE MUSICAL SYMBOL ANATRICHISMA;So;0;L;;;;;N;;;;;
16711 1D029;BYZANTINE MUSICAL SYMBOL SEISMA;So;0;L;;;;;N;;;;;
16712 1D02A;BYZANTINE MUSICAL SYMBOL SYNAGMA ARCHAION;So;0;L;;;;;N;;;;;
16713 1D02B;BYZANTINE MUSICAL SYMBOL SYNAGMA META STAVROU;So;0;L;;;;;N;;;;;
16714 1D02C;BYZANTINE MUSICAL SYMBOL OYRANISMA ARCHAION;So;0;L;;;;;N;;;;;
16715 1D02D;BYZANTINE MUSICAL SYMBOL THEMA;So;0;L;;;;;N;;;;;
16716 1D02E;BYZANTINE MUSICAL SYMBOL LEMOI;So;0;L;;;;;N;;;;;
16717 1D02F;BYZANTINE MUSICAL SYMBOL DYO;So;0;L;;;;;N;;;;;
16718 1D030;BYZANTINE MUSICAL SYMBOL TRIA;So;0;L;;;;;N;;;;;
16719 1D031;BYZANTINE MUSICAL SYMBOL TESSERA;So;0;L;;;;;N;;;;;
16720 1D032;BYZANTINE MUSICAL SYMBOL KRATIMATA;So;0;L;;;;;N;;;;;
16721 1D033;BYZANTINE MUSICAL SYMBOL APESO EXO NEO;So;0;L;;;;;N;;;;;
16722 1D034;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION;So;0;L;;;;;N;;;;;
16723 1D035;BYZANTINE MUSICAL SYMBOL IMIFTHORA;So;0;L;;;;;N;;;;;
16724 1D036;BYZANTINE MUSICAL SYMBOL TROMIKON ARCHAION;So;0;L;;;;;N;;;;;
16725 1D037;BYZANTINE MUSICAL SYMBOL KATAVA TROMIKON;So;0;L;;;;;N;;;;;
16726 1D038;BYZANTINE MUSICAL SYMBOL PELASTON;So;0;L;;;;;N;;;;;
16727 1D039;BYZANTINE MUSICAL SYMBOL PSIFISTON;So;0;L;;;;;N;;;;;
16728 1D03A;BYZANTINE MUSICAL SYMBOL KONTEVMA;So;0;L;;;;;N;;;;;
16729 1D03B;BYZANTINE MUSICAL SYMBOL CHOREVMA ARCHAION;So;0;L;;;;;N;;;;;
16730 1D03C;BYZANTINE MUSICAL SYMBOL RAPISMA;So;0;L;;;;;N;;;;;
16731 1D03D;BYZANTINE MUSICAL SYMBOL PARAKALESMA ARCHAION;So;0;L;;;;;N;;;;;
16732 1D03E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI ARCHAION;So;0;L;;;;;N;;;;;
16733 1D03F;BYZANTINE MUSICAL SYMBOL ICHADIN;So;0;L;;;;;N;;;;;
16734 1D040;BYZANTINE MUSICAL SYMBOL NANA;So;0;L;;;;;N;;;;;
16735 1D041;BYZANTINE MUSICAL SYMBOL PETASMA;So;0;L;;;;;N;;;;;
16736 1D042;BYZANTINE MUSICAL SYMBOL KONTEVMA ALLO;So;0;L;;;;;N;;;;;
16737 1D043;BYZANTINE MUSICAL SYMBOL TROMIKON ALLO;So;0;L;;;;;N;;;;;
16738 1D044;BYZANTINE MUSICAL SYMBOL STRAGGISMATA;So;0;L;;;;;N;;;;;
16739 1D045;BYZANTINE MUSICAL SYMBOL GRONTHISMATA;So;0;L;;;;;N;;;;;
16740 1D046;BYZANTINE MUSICAL SYMBOL ISON NEO;So;0;L;;;;;N;;;;;
16741 1D047;BYZANTINE MUSICAL SYMBOL OLIGON NEO;So;0;L;;;;;N;;;;;
16742 1D048;BYZANTINE MUSICAL SYMBOL OXEIA NEO;So;0;L;;;;;N;;;;;
16743 1D049;BYZANTINE MUSICAL SYMBOL PETASTI;So;0;L;;;;;N;;;;;
16744 1D04A;BYZANTINE MUSICAL SYMBOL KOUFISMA;So;0;L;;;;;N;;;;;
16745 1D04B;BYZANTINE MUSICAL SYMBOL PETASTOKOUFISMA;So;0;L;;;;;N;;;;;
16746 1D04C;BYZANTINE MUSICAL SYMBOL KRATIMOKOUFISMA;So;0;L;;;;;N;;;;;
16747 1D04D;BYZANTINE MUSICAL SYMBOL PELASTON NEO;So;0;L;;;;;N;;;;;
16748 1D04E;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO ANO;So;0;L;;;;;N;;;;;
16749 1D04F;BYZANTINE MUSICAL SYMBOL KENTIMA NEO ANO;So;0;L;;;;;N;;;;;
16750 1D050;BYZANTINE MUSICAL SYMBOL YPSILI;So;0;L;;;;;N;;;;;
16751 1D051;BYZANTINE MUSICAL SYMBOL APOSTROFOS NEO;So;0;L;;;;;N;;;;;
16752 1D052;BYZANTINE MUSICAL SYMBOL APOSTROFOI SYNDESMOS NEO;So;0;L;;;;;N;;;;;
16753 1D053;BYZANTINE MUSICAL SYMBOL YPORROI;So;0;L;;;;;N;;;;;
16754 1D054;BYZANTINE MUSICAL SYMBOL KRATIMOYPORROON;So;0;L;;;;;N;;;;;
16755 1D055;BYZANTINE MUSICAL SYMBOL ELAFRON;So;0;L;;;;;N;;;;;
16756 1D056;BYZANTINE MUSICAL SYMBOL CHAMILI;So;0;L;;;;;N;;;;;
16757 1D057;BYZANTINE MUSICAL SYMBOL MIKRON ISON;So;0;L;;;;;N;;;;;
16758 1D058;BYZANTINE MUSICAL SYMBOL VAREIA NEO;So;0;L;;;;;N;;;;;
16759 1D059;BYZANTINE MUSICAL SYMBOL PIASMA NEO;So;0;L;;;;;N;;;;;
16760 1D05A;BYZANTINE MUSICAL SYMBOL PSIFISTON NEO;So;0;L;;;;;N;;;;;
16761 1D05B;BYZANTINE MUSICAL SYMBOL OMALON;So;0;L;;;;;N;;;;;
16762 1D05C;BYZANTINE MUSICAL SYMBOL ANTIKENOMA;So;0;L;;;;;N;;;;;
16763 1D05D;BYZANTINE MUSICAL SYMBOL LYGISMA;So;0;L;;;;;N;;;;;
16764 1D05E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI NEO;So;0;L;;;;;N;;;;;
16765 1D05F;BYZANTINE MUSICAL SYMBOL PARAKALESMA NEO;So;0;L;;;;;N;;;;;
16766 1D060;BYZANTINE MUSICAL SYMBOL ETERON PARAKALESMA;So;0;L;;;;;N;;;;;
16767 1D061;BYZANTINE MUSICAL SYMBOL KYLISMA;So;0;L;;;;;N;;;;;
16768 1D062;BYZANTINE MUSICAL SYMBOL ANTIKENOKYLISMA;So;0;L;;;;;N;;;;;
16769 1D063;BYZANTINE MUSICAL SYMBOL TROMIKON NEO;So;0;L;;;;;N;;;;;
16770 1D064;BYZANTINE MUSICAL SYMBOL EKSTREPTON;So;0;L;;;;;N;;;;;
16771 1D065;BYZANTINE MUSICAL SYMBOL SYNAGMA NEO;So;0;L;;;;;N;;;;;
16772 1D066;BYZANTINE MUSICAL SYMBOL SYRMA;So;0;L;;;;;N;;;;;
16773 1D067;BYZANTINE MUSICAL SYMBOL CHOREVMA NEO;So;0;L;;;;;N;;;;;
16774 1D068;BYZANTINE MUSICAL SYMBOL EPEGERMA;So;0;L;;;;;N;;;;;
16775 1D069;BYZANTINE MUSICAL SYMBOL SEISMA NEO;So;0;L;;;;;N;;;;;
16776 1D06A;BYZANTINE MUSICAL SYMBOL XIRON KLASMA;So;0;L;;;;;N;;;;;
16777 1D06B;BYZANTINE MUSICAL SYMBOL TROMIKOPSIFISTON;So;0;L;;;;;N;;;;;
16778 1D06C;BYZANTINE MUSICAL SYMBOL PSIFISTOLYGISMA;So;0;L;;;;;N;;;;;
16779 1D06D;BYZANTINE MUSICAL SYMBOL TROMIKOLYGISMA;So;0;L;;;;;N;;;;;
16780 1D06E;BYZANTINE MUSICAL SYMBOL TROMIKOPARAKALESMA;So;0;L;;;;;N;;;;;
16781 1D06F;BYZANTINE MUSICAL SYMBOL PSIFISTOPARAKALESMA;So;0;L;;;;;N;;;;;
16782 1D070;BYZANTINE MUSICAL SYMBOL TROMIKOSYNAGMA;So;0;L;;;;;N;;;;;
16783 1D071;BYZANTINE MUSICAL SYMBOL PSIFISTOSYNAGMA;So;0;L;;;;;N;;;;;
16784 1D072;BYZANTINE MUSICAL SYMBOL GORGOSYNTHETON;So;0;L;;;;;N;;;;;
16785 1D073;BYZANTINE MUSICAL SYMBOL ARGOSYNTHETON;So;0;L;;;;;N;;;;;
16786 1D074;BYZANTINE MUSICAL SYMBOL ETERON ARGOSYNTHETON;So;0;L;;;;;N;;;;;
16787 1D075;BYZANTINE MUSICAL SYMBOL OYRANISMA NEO;So;0;L;;;;;N;;;;;
16788 1D076;BYZANTINE MUSICAL SYMBOL THEMATISMOS ESO;So;0;L;;;;;N;;;;;
16789 1D077;BYZANTINE MUSICAL SYMBOL THEMATISMOS EXO;So;0;L;;;;;N;;;;;
16790 1D078;BYZANTINE MUSICAL SYMBOL THEMA APLOUN;So;0;L;;;;;N;;;;;
16791 1D079;BYZANTINE MUSICAL SYMBOL THES KAI APOTHES;So;0;L;;;;;N;;;;;
16792 1D07A;BYZANTINE MUSICAL SYMBOL KATAVASMA;So;0;L;;;;;N;;;;;
16793 1D07B;BYZANTINE MUSICAL SYMBOL ENDOFONON;So;0;L;;;;;N;;;;;
16794 1D07C;BYZANTINE MUSICAL SYMBOL YFEN KATO;So;0;L;;;;;N;;;;;
16795 1D07D;BYZANTINE MUSICAL SYMBOL YFEN ANO;So;0;L;;;;;N;;;;;
16796 1D07E;BYZANTINE MUSICAL SYMBOL STAVROS;So;0;L;;;;;N;;;;;
16797 1D07F;BYZANTINE MUSICAL SYMBOL KLASMA ANO;So;0;L;;;;;N;;;;;
16798 1D080;BYZANTINE MUSICAL SYMBOL DIPLI ARCHAION;So;0;L;;;;;N;;;;;
16799 1D081;BYZANTINE MUSICAL SYMBOL KRATIMA ARCHAION;So;0;L;;;;;N;;;;;
16800 1D082;BYZANTINE MUSICAL SYMBOL KRATIMA ALLO;So;0;L;;;;;N;;;;;
16801 1D083;BYZANTINE MUSICAL SYMBOL KRATIMA NEO;So;0;L;;;;;N;;;;;
16802 1D084;BYZANTINE MUSICAL SYMBOL APODERMA NEO;So;0;L;;;;;N;;;;;
16803 1D085;BYZANTINE MUSICAL SYMBOL APLI;So;0;L;;;;;N;;;;;
16804 1D086;BYZANTINE MUSICAL SYMBOL DIPLI;So;0;L;;;;;N;;;;;
16805 1D087;BYZANTINE MUSICAL SYMBOL TRIPLI;So;0;L;;;;;N;;;;;
16806 1D088;BYZANTINE MUSICAL SYMBOL TETRAPLI;So;0;L;;;;;N;;;;;
16807 1D089;BYZANTINE MUSICAL SYMBOL KORONIS;So;0;L;;;;;N;;;;;
16808 1D08A;BYZANTINE MUSICAL SYMBOL LEIMMA ENOS CHRONOU;So;0;L;;;;;N;;;;;
16809 1D08B;BYZANTINE MUSICAL SYMBOL LEIMMA DYO CHRONON;So;0;L;;;;;N;;;;;
16810 1D08C;BYZANTINE MUSICAL SYMBOL LEIMMA TRION CHRONON;So;0;L;;;;;N;;;;;
16811 1D08D;BYZANTINE MUSICAL SYMBOL LEIMMA TESSARON CHRONON;So;0;L;;;;;N;;;;;
16812 1D08E;BYZANTINE MUSICAL SYMBOL LEIMMA IMISEOS CHRONOU;So;0;L;;;;;N;;;;;
16813 1D08F;BYZANTINE MUSICAL SYMBOL GORGON NEO ANO;So;0;L;;;;;N;;;;;
16814 1D090;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON ARISTERA;So;0;L;;;;;N;;;;;
16815 1D091;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;;
16816 1D092;BYZANTINE MUSICAL SYMBOL DIGORGON;So;0;L;;;;;N;;;;;
16817 1D093;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA KATO;So;0;L;;;;;N;;;;;
16818 1D094;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA ANO;So;0;L;;;;;N;;;;;
16819 1D095;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;;
16820 1D096;BYZANTINE MUSICAL SYMBOL TRIGORGON;So;0;L;;;;;N;;;;;
16821 1D097;BYZANTINE MUSICAL SYMBOL ARGON;So;0;L;;;;;N;;;;;
16822 1D098;BYZANTINE MUSICAL SYMBOL IMIDIARGON;So;0;L;;;;;N;;;;;
16823 1D099;BYZANTINE MUSICAL SYMBOL DIARGON;So;0;L;;;;;N;;;;;
16824 1D09A;BYZANTINE MUSICAL SYMBOL AGOGI POLI ARGI;So;0;L;;;;;N;;;;;
16825 1D09B;BYZANTINE MUSICAL SYMBOL AGOGI ARGOTERI;So;0;L;;;;;N;;;;;
16826 1D09C;BYZANTINE MUSICAL SYMBOL AGOGI ARGI;So;0;L;;;;;N;;;;;
16827 1D09D;BYZANTINE MUSICAL SYMBOL AGOGI METRIA;So;0;L;;;;;N;;;;;
16828 1D09E;BYZANTINE MUSICAL SYMBOL AGOGI MESI;So;0;L;;;;;N;;;;;
16829 1D09F;BYZANTINE MUSICAL SYMBOL AGOGI GORGI;So;0;L;;;;;N;;;;;
16830 1D0A0;BYZANTINE MUSICAL SYMBOL AGOGI GORGOTERI;So;0;L;;;;;N;;;;;
16831 1D0A1;BYZANTINE MUSICAL SYMBOL AGOGI POLI GORGI;So;0;L;;;;;N;;;;;
16832 1D0A2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOS ICHOS;So;0;L;;;;;N;;;;;
16833 1D0A3;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI PROTOS ICHOS;So;0;L;;;;;N;;;;;
16834 1D0A4;BYZANTINE MUSICAL SYMBOL MARTYRIA DEYTEROS ICHOS;So;0;L;;;;;N;;;;;
16835 1D0A5;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI DEYTEROS ICHOS;So;0;L;;;;;N;;;;;
16836 1D0A6;BYZANTINE MUSICAL SYMBOL MARTYRIA TRITOS ICHOS;So;0;L;;;;;N;;;;;
16837 1D0A7;BYZANTINE MUSICAL SYMBOL MARTYRIA TRIFONIAS;So;0;L;;;;;N;;;;;
16838 1D0A8;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS ICHOS;So;0;L;;;;;N;;;;;
16839 1D0A9;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS LEGETOS ICHOS;So;0;L;;;;;N;;;;;
16840 1D0AA;BYZANTINE MUSICAL SYMBOL MARTYRIA LEGETOS ICHOS;So;0;L;;;;;N;;;;;
16841 1D0AB;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS ICHOS;So;0;L;;;;;N;;;;;
16842 1D0AC;BYZANTINE MUSICAL SYMBOL ISAKIA TELOUS ICHIMATOS;So;0;L;;;;;N;;;;;
16843 1D0AD;BYZANTINE MUSICAL SYMBOL APOSTROFOI TELOUS ICHIMATOS;So;0;L;;;;;N;;;;;
16844 1D0AE;BYZANTINE MUSICAL SYMBOL FANEROSIS TETRAFONIAS;So;0;L;;;;;N;;;;;
16845 1D0AF;BYZANTINE MUSICAL SYMBOL FANEROSIS MONOFONIAS;So;0;L;;;;;N;;;;;
16846 1D0B0;BYZANTINE MUSICAL SYMBOL FANEROSIS DIFONIAS;So;0;L;;;;;N;;;;;
16847 1D0B1;BYZANTINE MUSICAL SYMBOL MARTYRIA VARYS ICHOS;So;0;L;;;;;N;;;;;
16848 1D0B2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOVARYS ICHOS;So;0;L;;;;;N;;;;;
16849 1D0B3;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS TETARTOS ICHOS;So;0;L;;;;;N;;;;;
16850 1D0B4;BYZANTINE MUSICAL SYMBOL GORTHMIKON N APLOUN;So;0;L;;;;;N;;;;;
16851 1D0B5;BYZANTINE MUSICAL SYMBOL GORTHMIKON N DIPLOUN;So;0;L;;;;;N;;;;;
16852 1D0B6;BYZANTINE MUSICAL SYMBOL ENARXIS KAI FTHORA VOU;So;0;L;;;;;N;;;;;
16853 1D0B7;BYZANTINE MUSICAL SYMBOL IMIFONON;So;0;L;;;;;N;;;;;
16854 1D0B8;BYZANTINE MUSICAL SYMBOL IMIFTHORON;So;0;L;;;;;N;;;;;
16855 1D0B9;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION DEYTEROU ICHOU;So;0;L;;;;;N;;;;;
16856 1D0BA;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI PA;So;0;L;;;;;N;;;;;
16857 1D0BB;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NANA;So;0;L;;;;;N;;;;;
16858 1D0BC;BYZANTINE MUSICAL SYMBOL FTHORA NAOS ICHOS;So;0;L;;;;;N;;;;;
16859 1D0BD;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI DI;So;0;L;;;;;N;;;;;
16860 1D0BE;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON DIATONON DI;So;0;L;;;;;N;;;;;
16861 1D0BF;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI KE;So;0;L;;;;;N;;;;;
16862 1D0C0;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI ZO;So;0;L;;;;;N;;;;;
16863 1D0C1;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI KATO;So;0;L;;;;;N;;;;;
16864 1D0C2;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI ANO;So;0;L;;;;;N;;;;;
16865 1D0C3;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA DIFONIAS;So;0;L;;;;;N;;;;;
16866 1D0C4;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA MONOFONIAS;So;0;L;;;;;N;;;;;
16867 1D0C5;BYZANTINE MUSICAL SYMBOL FHTORA SKLIRON CHROMA VASIS;So;0;L;;;;;N;;;;;
16868 1D0C6;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON CHROMA SYNAFI;So;0;L;;;;;N;;;;;
16869 1D0C7;BYZANTINE MUSICAL SYMBOL FTHORA NENANO;So;0;L;;;;;N;;;;;
16870 1D0C8;BYZANTINE MUSICAL SYMBOL CHROA ZYGOS;So;0;L;;;;;N;;;;;
16871 1D0C9;BYZANTINE MUSICAL SYMBOL CHROA KLITON;So;0;L;;;;;N;;;;;
16872 1D0CA;BYZANTINE MUSICAL SYMBOL CHROA SPATHI;So;0;L;;;;;N;;;;;
16873 1D0CB;BYZANTINE MUSICAL SYMBOL FTHORA I YFESIS TETARTIMORION;So;0;L;;;;;N;;;;;
16874 1D0CC;BYZANTINE MUSICAL SYMBOL FTHORA ENARMONIOS ANTIFONIA;So;0;L;;;;;N;;;;;
16875 1D0CD;BYZANTINE MUSICAL SYMBOL YFESIS TRITIMORION;So;0;L;;;;;N;;;;;
16876 1D0CE;BYZANTINE MUSICAL SYMBOL DIESIS TRITIMORION;So;0;L;;;;;N;;;;;
16877 1D0CF;BYZANTINE MUSICAL SYMBOL DIESIS TETARTIMORION;So;0;L;;;;;N;;;;;
16878 1D0D0;BYZANTINE MUSICAL SYMBOL DIESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;;
16879 1D0D1;BYZANTINE MUSICAL SYMBOL DIESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;;
16880 1D0D2;BYZANTINE MUSICAL SYMBOL DIESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;;
16881 1D0D3;BYZANTINE MUSICAL SYMBOL DIESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;;
16882 1D0D4;BYZANTINE MUSICAL SYMBOL YFESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;;
16883 1D0D5;BYZANTINE MUSICAL SYMBOL YFESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;;
16884 1D0D6;BYZANTINE MUSICAL SYMBOL YFESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;;
16885 1D0D7;BYZANTINE MUSICAL SYMBOL YFESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;;
16886 1D0D8;BYZANTINE MUSICAL SYMBOL GENIKI DIESIS;So;0;L;;;;;N;;;;;
16887 1D0D9;BYZANTINE MUSICAL SYMBOL GENIKI YFESIS;So;0;L;;;;;N;;;;;
16888 1D0DA;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MIKRI;So;0;L;;;;;N;;;;;
16889 1D0DB;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MEGALI;So;0;L;;;;;N;;;;;
16890 1D0DC;BYZANTINE MUSICAL SYMBOL DIASTOLI DIPLI;So;0;L;;;;;N;;;;;
16891 1D0DD;BYZANTINE MUSICAL SYMBOL DIASTOLI THESEOS;So;0;L;;;;;N;;;;;
16892 1D0DE;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS;So;0;L;;;;;N;;;;;
16893 1D0DF;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS DISIMOU;So;0;L;;;;;N;;;;;
16894 1D0E0;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TRISIMOU;So;0;L;;;;;N;;;;;
16895 1D0E1;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TETRASIMOU;So;0;L;;;;;N;;;;;
16896 1D0E2;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS;So;0;L;;;;;N;;;;;
16897 1D0E3;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS DISIMOU;So;0;L;;;;;N;;;;;
16898 1D0E4;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TRISIMOU;So;0;L;;;;;N;;;;;
16899 1D0E5;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TETRASIMOU;So;0;L;;;;;N;;;;;
16900 1D0E6;BYZANTINE MUSICAL SYMBOL DIGRAMMA GG;So;0;L;;;;;N;;;;;
16901 1D0E7;BYZANTINE MUSICAL SYMBOL DIFTOGGOS OU;So;0;L;;;;;N;;;;;
16902 1D0E8;BYZANTINE MUSICAL SYMBOL STIGMA;So;0;L;;;;;N;;;;;
16903 1D0E9;BYZANTINE MUSICAL SYMBOL ARKTIKO PA;So;0;L;;;;;N;;;;;
16904 1D0EA;BYZANTINE MUSICAL SYMBOL ARKTIKO VOU;So;0;L;;;;;N;;;;;
16905 1D0EB;BYZANTINE MUSICAL SYMBOL ARKTIKO GA;So;0;L;;;;;N;;;;;
16906 1D0EC;BYZANTINE MUSICAL SYMBOL ARKTIKO DI;So;0;L;;;;;N;;;;;
16907 1D0ED;BYZANTINE MUSICAL SYMBOL ARKTIKO KE;So;0;L;;;;;N;;;;;
16908 1D0EE;BYZANTINE MUSICAL SYMBOL ARKTIKO ZO;So;0;L;;;;;N;;;;;
16909 1D0EF;BYZANTINE MUSICAL SYMBOL ARKTIKO NI;So;0;L;;;;;N;;;;;
16910 1D0F0;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO MESO;So;0;L;;;;;N;;;;;
16911 1D0F1;BYZANTINE MUSICAL SYMBOL KENTIMA NEO MESO;So;0;L;;;;;N;;;;;
16912 1D0F2;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO KATO;So;0;L;;;;;N;;;;;
16913 1D0F3;BYZANTINE MUSICAL SYMBOL KENTIMA NEO KATO;So;0;L;;;;;N;;;;;
16914 1D0F4;BYZANTINE MUSICAL SYMBOL KLASMA KATO;So;0;L;;;;;N;;;;;
16915 1D0F5;BYZANTINE MUSICAL SYMBOL GORGON NEO KATO;So;0;L;;;;;N;;;;;
16916 1D100;MUSICAL SYMBOL SINGLE BARLINE;So;0;L;;;;;N;;;;;
16917 1D101;MUSICAL SYMBOL DOUBLE BARLINE;So;0;L;;;;;N;;;;;
16918 1D102;MUSICAL SYMBOL FINAL BARLINE;So;0;L;;;;;N;;;;;
16919 1D103;MUSICAL SYMBOL REVERSE FINAL BARLINE;So;0;L;;;;;N;;;;;
16920 1D104;MUSICAL SYMBOL DASHED BARLINE;So;0;L;;;;;N;;;;;
16921 1D105;MUSICAL SYMBOL SHORT BARLINE;So;0;L;;;;;N;;;;;
16922 1D106;MUSICAL SYMBOL LEFT REPEAT SIGN;So;0;L;;;;;N;;;;;
16923 1D107;MUSICAL SYMBOL RIGHT REPEAT SIGN;So;0;L;;;;;N;;;;;
16924 1D108;MUSICAL SYMBOL REPEAT DOTS;So;0;L;;;;;N;;;;;
16925 1D109;MUSICAL SYMBOL DAL SEGNO;So;0;L;;;;;N;;;;;
16926 1D10A;MUSICAL SYMBOL DA CAPO;So;0;L;;;;;N;;;;;
16927 1D10B;MUSICAL SYMBOL SEGNO;So;0;L;;;;;N;;;;;
16928 1D10C;MUSICAL SYMBOL CODA;So;0;L;;;;;N;;;;;
16929 1D10D;MUSICAL SYMBOL REPEATED FIGURE-1;So;0;L;;;;;N;;;;;
16930 1D10E;MUSICAL SYMBOL REPEATED FIGURE-2;So;0;L;;;;;N;;;;;
16931 1D10F;MUSICAL SYMBOL REPEATED FIGURE-3;So;0;L;;;;;N;;;;;
16932 1D110;MUSICAL SYMBOL FERMATA;So;0;L;;;;;N;;;;;
16933 1D111;MUSICAL SYMBOL FERMATA BELOW;So;0;L;;;;;N;;;;;
16934 1D112;MUSICAL SYMBOL BREATH MARK;So;0;L;;;;;N;;;;;
16935 1D113;MUSICAL SYMBOL CAESURA;So;0;L;;;;;N;;;;;
16936 1D114;MUSICAL SYMBOL BRACE;So;0;L;;;;;N;;;;;
16937 1D115;MUSICAL SYMBOL BRACKET;So;0;L;;;;;N;;;;;
16938 1D116;MUSICAL SYMBOL ONE-LINE STAFF;So;0;L;;;;;N;;;;;
16939 1D117;MUSICAL SYMBOL TWO-LINE STAFF;So;0;L;;;;;N;;;;;
16940 1D118;MUSICAL SYMBOL THREE-LINE STAFF;So;0;L;;;;;N;;;;;
16941 1D119;MUSICAL SYMBOL FOUR-LINE STAFF;So;0;L;;;;;N;;;;;
16942 1D11A;MUSICAL SYMBOL FIVE-LINE STAFF;So;0;L;;;;;N;;;;;
16943 1D11B;MUSICAL SYMBOL SIX-LINE STAFF;So;0;L;;;;;N;;;;;
16944 1D11C;MUSICAL SYMBOL SIX-STRING FRETBOARD;So;0;L;;;;;N;;;;;
16945 1D11D;MUSICAL SYMBOL FOUR-STRING FRETBOARD;So;0;L;;;;;N;;;;;
16946 1D11E;MUSICAL SYMBOL G CLEF;So;0;L;;;;;N;;;;;
16947 1D11F;MUSICAL SYMBOL G CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;;
16948 1D120;MUSICAL SYMBOL G CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;;
16949 1D121;MUSICAL SYMBOL C CLEF;So;0;L;;;;;N;;;;;
16950 1D122;MUSICAL SYMBOL F CLEF;So;0;L;;;;;N;;;;;
16951 1D123;MUSICAL SYMBOL F CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;;
16952 1D124;MUSICAL SYMBOL F CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;;
16953 1D125;MUSICAL SYMBOL DRUM CLEF-1;So;0;L;;;;;N;;;;;
16954 1D126;MUSICAL SYMBOL DRUM CLEF-2;So;0;L;;;;;N;;;;;
16955 1D129;MUSICAL SYMBOL MULTIPLE MEASURE REST;So;0;L;;;;;N;;;;;
16956 1D12A;MUSICAL SYMBOL DOUBLE SHARP;So;0;L;;;;;N;;;;;
16957 1D12B;MUSICAL SYMBOL DOUBLE FLAT;So;0;L;;;;;N;;;;;
16958 1D12C;MUSICAL SYMBOL FLAT UP;So;0;L;;;;;N;;;;;
16959 1D12D;MUSICAL SYMBOL FLAT DOWN;So;0;L;;;;;N;;;;;
16960 1D12E;MUSICAL SYMBOL NATURAL UP;So;0;L;;;;;N;;;;;
16961 1D12F;MUSICAL SYMBOL NATURAL DOWN;So;0;L;;;;;N;;;;;
16962 1D130;MUSICAL SYMBOL SHARP UP;So;0;L;;;;;N;;;;;
16963 1D131;MUSICAL SYMBOL SHARP DOWN;So;0;L;;;;;N;;;;;
16964 1D132;MUSICAL SYMBOL QUARTER TONE SHARP;So;0;L;;;;;N;;;;;
16965 1D133;MUSICAL SYMBOL QUARTER TONE FLAT;So;0;L;;;;;N;;;;;
16966 1D134;MUSICAL SYMBOL COMMON TIME;So;0;L;;;;;N;;;;;
16967 1D135;MUSICAL SYMBOL CUT TIME;So;0;L;;;;;N;;;;;
16968 1D136;MUSICAL SYMBOL OTTAVA ALTA;So;0;L;;;;;N;;;;;
16969 1D137;MUSICAL SYMBOL OTTAVA BASSA;So;0;L;;;;;N;;;;;
16970 1D138;MUSICAL SYMBOL QUINDICESIMA ALTA;So;0;L;;;;;N;;;;;
16971 1D139;MUSICAL SYMBOL QUINDICESIMA BASSA;So;0;L;;;;;N;;;;;
16972 1D13A;MUSICAL SYMBOL MULTI REST;So;0;L;;;;;N;;;;;
16973 1D13B;MUSICAL SYMBOL WHOLE REST;So;0;L;;;;;N;;;;;
16974 1D13C;MUSICAL SYMBOL HALF REST;So;0;L;;;;;N;;;;;
16975 1D13D;MUSICAL SYMBOL QUARTER REST;So;0;L;;;;;N;;;;;
16976 1D13E;MUSICAL SYMBOL EIGHTH REST;So;0;L;;;;;N;;;;;
16977 1D13F;MUSICAL SYMBOL SIXTEENTH REST;So;0;L;;;;;N;;;;;
16978 1D140;MUSICAL SYMBOL THIRTY-SECOND REST;So;0;L;;;;;N;;;;;
16979 1D141;MUSICAL SYMBOL SIXTY-FOURTH REST;So;0;L;;;;;N;;;;;
16980 1D142;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH REST;So;0;L;;;;;N;;;;;
16981 1D143;MUSICAL SYMBOL X NOTEHEAD;So;0;L;;;;;N;;;;;
16982 1D144;MUSICAL SYMBOL PLUS NOTEHEAD;So;0;L;;;;;N;;;;;
16983 1D145;MUSICAL SYMBOL CIRCLE X NOTEHEAD;So;0;L;;;;;N;;;;;
16984 1D146;MUSICAL SYMBOL SQUARE NOTEHEAD WHITE;So;0;L;;;;;N;;;;;
16985 1D147;MUSICAL SYMBOL SQUARE NOTEHEAD BLACK;So;0;L;;;;;N;;;;;
16986 1D148;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP WHITE;So;0;L;;;;;N;;;;;
16987 1D149;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP BLACK;So;0;L;;;;;N;;;;;
16988 1D14A;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT WHITE;So;0;L;;;;;N;;;;;
16989 1D14B;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT BLACK;So;0;L;;;;;N;;;;;
16990 1D14C;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT WHITE;So;0;L;;;;;N;;;;;
16991 1D14D;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT BLACK;So;0;L;;;;;N;;;;;
16992 1D14E;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;;
16993 1D14F;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;;
16994 1D150;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT WHITE;So;0;L;;;;;N;;;;;
16995 1D151;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT BLACK;So;0;L;;;;;N;;;;;
16996 1D152;MUSICAL SYMBOL MOON NOTEHEAD WHITE;So;0;L;;;;;N;;;;;
16997 1D153;MUSICAL SYMBOL MOON NOTEHEAD BLACK;So;0;L;;;;;N;;;;;
16998 1D154;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;;
16999 1D155;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;;
17000 1D156;MUSICAL SYMBOL PARENTHESIS NOTEHEAD;So;0;L;;;;;N;;;;;
17001 1D157;MUSICAL SYMBOL VOID NOTEHEAD;So;0;L;;;;;N;;;;;
17002 1D158;MUSICAL SYMBOL NOTEHEAD BLACK;So;0;L;;;;;N;;;;;
17003 1D159;MUSICAL SYMBOL NULL NOTEHEAD;So;0;L;;;;;N;;;;;
17004 1D15A;MUSICAL SYMBOL CLUSTER NOTEHEAD WHITE;So;0;L;;;;;N;;;;;
17005 1D15B;MUSICAL SYMBOL CLUSTER NOTEHEAD BLACK;So;0;L;;;;;N;;;;;
17006 1D15C;MUSICAL SYMBOL BREVE;So;0;L;;;;;N;;;;;
17007 1D15D;MUSICAL SYMBOL WHOLE NOTE;So;0;L;;;;;N;;;;;
17008 1D15E;MUSICAL SYMBOL HALF NOTE;So;0;L;1D157 1D165;;;;N;;;;;
17009 1D15F;MUSICAL SYMBOL QUARTER NOTE;So;0;L;1D158 1D165;;;;N;;;;;
17010 1D160;MUSICAL SYMBOL EIGHTH NOTE;So;0;L;1D15F 1D16E;;;;N;;;;;
17011 1D161;MUSICAL SYMBOL SIXTEENTH NOTE;So;0;L;1D15F 1D16F;;;;N;;;;;
17012 1D162;MUSICAL SYMBOL THIRTY-SECOND NOTE;So;0;L;1D15F 1D170;;;;N;;;;;
17013 1D163;MUSICAL SYMBOL SIXTY-FOURTH NOTE;So;0;L;1D15F 1D171;;;;N;;;;;
17014 1D164;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE;So;0;L;1D15F 1D172;;;;N;;;;;
17015 1D165;MUSICAL SYMBOL COMBINING STEM;Mc;216;L;;;;;N;;;;;
17016 1D166;MUSICAL SYMBOL COMBINING SPRECHGESANG STEM;Mc;216;L;;;;;N;;;;;
17017 1D167;MUSICAL SYMBOL COMBINING TREMOLO-1;Mn;1;NSM;;;;;N;;;;;
17018 1D168;MUSICAL SYMBOL COMBINING TREMOLO-2;Mn;1;NSM;;;;;N;;;;;
17019 1D169;MUSICAL SYMBOL COMBINING TREMOLO-3;Mn;1;NSM;;;;;N;;;;;
17020 1D16A;MUSICAL SYMBOL FINGERED TREMOLO-1;So;0;L;;;;;N;;;;;
17021 1D16B;MUSICAL SYMBOL FINGERED TREMOLO-2;So;0;L;;;;;N;;;;;
17022 1D16C;MUSICAL SYMBOL FINGERED TREMOLO-3;So;0;L;;;;;N;;;;;
17023 1D16D;MUSICAL SYMBOL COMBINING AUGMENTATION DOT;Mc;226;L;;;;;N;;;;;
17024 1D16E;MUSICAL SYMBOL COMBINING FLAG-1;Mc;216;L;;;;;N;;;;;
17025 1D16F;MUSICAL SYMBOL COMBINING FLAG-2;Mc;216;L;;;;;N;;;;;
17026 1D170;MUSICAL SYMBOL COMBINING FLAG-3;Mc;216;L;;;;;N;;;;;
17027 1D171;MUSICAL SYMBOL COMBINING FLAG-4;Mc;216;L;;;;;N;;;;;
17028 1D172;MUSICAL SYMBOL COMBINING FLAG-5;Mc;216;L;;;;;N;;;;;
17029 1D173;MUSICAL SYMBOL BEGIN BEAM;Cf;0;BN;;;;;N;;;;;
17030 1D174;MUSICAL SYMBOL END BEAM;Cf;0;BN;;;;;N;;;;;
17031 1D175;MUSICAL SYMBOL BEGIN TIE;Cf;0;BN;;;;;N;;;;;
17032 1D176;MUSICAL SYMBOL END TIE;Cf;0;BN;;;;;N;;;;;
17033 1D177;MUSICAL SYMBOL BEGIN SLUR;Cf;0;BN;;;;;N;;;;;
17034 1D178;MUSICAL SYMBOL END SLUR;Cf;0;BN;;;;;N;;;;;
17035 1D179;MUSICAL SYMBOL BEGIN PHRASE;Cf;0;BN;;;;;N;;;;;
17036 1D17A;MUSICAL SYMBOL END PHRASE;Cf;0;BN;;;;;N;;;;;
17037 1D17B;MUSICAL SYMBOL COMBINING ACCENT;Mn;220;NSM;;;;;N;;;;;
17038 1D17C;MUSICAL SYMBOL COMBINING STACCATO;Mn;220;NSM;;;;;N;;;;;
17039 1D17D;MUSICAL SYMBOL COMBINING TENUTO;Mn;220;NSM;;;;;N;;;;;
17040 1D17E;MUSICAL SYMBOL COMBINING STACCATISSIMO;Mn;220;NSM;;;;;N;;;;;
17041 1D17F;MUSICAL SYMBOL COMBINING MARCATO;Mn;220;NSM;;;;;N;;;;;
17042 1D180;MUSICAL SYMBOL COMBINING MARCATO-STACCATO;Mn;220;NSM;;;;;N;;;;;
17043 1D181;MUSICAL SYMBOL COMBINING ACCENT-STACCATO;Mn;220;NSM;;;;;N;;;;;
17044 1D182;MUSICAL SYMBOL COMBINING LOURE;Mn;220;NSM;;;;;N;;;;;
17045 1D183;MUSICAL SYMBOL ARPEGGIATO UP;So;0;L;;;;;N;;;;;
17046 1D184;MUSICAL SYMBOL ARPEGGIATO DOWN;So;0;L;;;;;N;;;;;
17047 1D185;MUSICAL SYMBOL COMBINING DOIT;Mn;230;NSM;;;;;N;;;;;
17048 1D186;MUSICAL SYMBOL COMBINING RIP;Mn;230;NSM;;;;;N;;;;;
17049 1D187;MUSICAL SYMBOL COMBINING FLIP;Mn;230;NSM;;;;;N;;;;;
17050 1D188;MUSICAL SYMBOL COMBINING SMEAR;Mn;230;NSM;;;;;N;;;;;
17051 1D189;MUSICAL SYMBOL COMBINING BEND;Mn;230;NSM;;;;;N;;;;;
17052 1D18A;MUSICAL SYMBOL COMBINING DOUBLE TONGUE;Mn;220;NSM;;;;;N;;;;;
17053 1D18B;MUSICAL SYMBOL COMBINING TRIPLE TONGUE;Mn;220;NSM;;;;;N;;;;;
17054 1D18C;MUSICAL SYMBOL RINFORZANDO;So;0;L;;;;;N;;;;;
17055 1D18D;MUSICAL SYMBOL SUBITO;So;0;L;;;;;N;;;;;
17056 1D18E;MUSICAL SYMBOL Z;So;0;L;;;;;N;;;;;
17057 1D18F;MUSICAL SYMBOL PIANO;So;0;L;;;;;N;;;;;
17058 1D190;MUSICAL SYMBOL MEZZO;So;0;L;;;;;N;;;;;
17059 1D191;MUSICAL SYMBOL FORTE;So;0;L;;;;;N;;;;;
17060 1D192;MUSICAL SYMBOL CRESCENDO;So;0;L;;;;;N;;;;;
17061 1D193;MUSICAL SYMBOL DECRESCENDO;So;0;L;;;;;N;;;;;
17062 1D194;MUSICAL SYMBOL GRACE NOTE SLASH;So;0;L;;;;;N;;;;;
17063 1D195;MUSICAL SYMBOL GRACE NOTE NO SLASH;So;0;L;;;;;N;;;;;
17064 1D196;MUSICAL SYMBOL TR;So;0;L;;;;;N;;;;;
17065 1D197;MUSICAL SYMBOL TURN;So;0;L;;;;;N;;;;;
17066 1D198;MUSICAL SYMBOL INVERTED TURN;So;0;L;;;;;N;;;;;
17067 1D199;MUSICAL SYMBOL TURN SLASH;So;0;L;;;;;N;;;;;
17068 1D19A;MUSICAL SYMBOL TURN UP;So;0;L;;;;;N;;;;;
17069 1D19B;MUSICAL SYMBOL ORNAMENT STROKE-1;So;0;L;;;;;N;;;;;
17070 1D19C;MUSICAL SYMBOL ORNAMENT STROKE-2;So;0;L;;;;;N;;;;;
17071 1D19D;MUSICAL SYMBOL ORNAMENT STROKE-3;So;0;L;;;;;N;;;;;
17072 1D19E;MUSICAL SYMBOL ORNAMENT STROKE-4;So;0;L;;;;;N;;;;;
17073 1D19F;MUSICAL SYMBOL ORNAMENT STROKE-5;So;0;L;;;;;N;;;;;
17074 1D1A0;MUSICAL SYMBOL ORNAMENT STROKE-6;So;0;L;;;;;N;;;;;
17075 1D1A1;MUSICAL SYMBOL ORNAMENT STROKE-7;So;0;L;;;;;N;;;;;
17076 1D1A2;MUSICAL SYMBOL ORNAMENT STROKE-8;So;0;L;;;;;N;;;;;
17077 1D1A3;MUSICAL SYMBOL ORNAMENT STROKE-9;So;0;L;;;;;N;;;;;
17078 1D1A4;MUSICAL SYMBOL ORNAMENT STROKE-10;So;0;L;;;;;N;;;;;
17079 1D1A5;MUSICAL SYMBOL ORNAMENT STROKE-11;So;0;L;;;;;N;;;;;
17080 1D1A6;MUSICAL SYMBOL HAUPTSTIMME;So;0;L;;;;;N;;;;;
17081 1D1A7;MUSICAL SYMBOL NEBENSTIMME;So;0;L;;;;;N;;;;;
17082 1D1A8;MUSICAL SYMBOL END OF STIMME;So;0;L;;;;;N;;;;;
17083 1D1A9;MUSICAL SYMBOL DEGREE SLASH;So;0;L;;;;;N;;;;;
17084 1D1AA;MUSICAL SYMBOL COMBINING DOWN BOW;Mn;230;NSM;;;;;N;;;;;
17085 1D1AB;MUSICAL SYMBOL COMBINING UP BOW;Mn;230;NSM;;;;;N;;;;;
17086 1D1AC;MUSICAL SYMBOL COMBINING HARMONIC;Mn;230;NSM;;;;;N;;;;;
17087 1D1AD;MUSICAL SYMBOL COMBINING SNAP PIZZICATO;Mn;230;NSM;;;;;N;;;;;
17088 1D1AE;MUSICAL SYMBOL PEDAL MARK;So;0;L;;;;;N;;;;;
17089 1D1AF;MUSICAL SYMBOL PEDAL UP MARK;So;0;L;;;;;N;;;;;
17090 1D1B0;MUSICAL SYMBOL HALF PEDAL MARK;So;0;L;;;;;N;;;;;
17091 1D1B1;MUSICAL SYMBOL GLISSANDO UP;So;0;L;;;;;N;;;;;
17092 1D1B2;MUSICAL SYMBOL GLISSANDO DOWN;So;0;L;;;;;N;;;;;
17093 1D1B3;MUSICAL SYMBOL WITH FINGERNAILS;So;0;L;;;;;N;;;;;
17094 1D1B4;MUSICAL SYMBOL DAMP;So;0;L;;;;;N;;;;;
17095 1D1B5;MUSICAL SYMBOL DAMP ALL;So;0;L;;;;;N;;;;;
17096 1D1B6;MUSICAL SYMBOL MAXIMA;So;0;L;;;;;N;;;;;
17097 1D1B7;MUSICAL SYMBOL LONGA;So;0;L;;;;;N;;;;;
17098 1D1B8;MUSICAL SYMBOL BREVIS;So;0;L;;;;;N;;;;;
17099 1D1B9;MUSICAL SYMBOL SEMIBREVIS WHITE;So;0;L;;;;;N;;;;;
17100 1D1BA;MUSICAL SYMBOL SEMIBREVIS BLACK;So;0;L;;;;;N;;;;;
17101 1D1BB;MUSICAL SYMBOL MINIMA;So;0;L;1D1B9 1D165;;;;N;;;;;
17102 1D1BC;MUSICAL SYMBOL MINIMA BLACK;So;0;L;1D1BA 1D165;;;;N;;;;;
17103 1D1BD;MUSICAL SYMBOL SEMIMINIMA WHITE;So;0;L;1D1BB 1D16E;;;;N;;;;;
17104 1D1BE;MUSICAL SYMBOL SEMIMINIMA BLACK;So;0;L;1D1BC 1D16E;;;;N;;;;;
17105 1D1BF;MUSICAL SYMBOL FUSA WHITE;So;0;L;1D1BB 1D16F;;;;N;;;;;
17106 1D1C0;MUSICAL SYMBOL FUSA BLACK;So;0;L;1D1BC 1D16F;;;;N;;;;;
17107 1D1C1;MUSICAL SYMBOL LONGA PERFECTA REST;So;0;L;;;;;N;;;;;
17108 1D1C2;MUSICAL SYMBOL LONGA IMPERFECTA REST;So;0;L;;;;;N;;;;;
17109 1D1C3;MUSICAL SYMBOL BREVIS REST;So;0;L;;;;;N;;;;;
17110 1D1C4;MUSICAL SYMBOL SEMIBREVIS REST;So;0;L;;;;;N;;;;;
17111 1D1C5;MUSICAL SYMBOL MINIMA REST;So;0;L;;;;;N;;;;;
17112 1D1C6;MUSICAL SYMBOL SEMIMINIMA REST;So;0;L;;;;;N;;;;;
17113 1D1C7;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;;
17114 1D1C8;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;;
17115 1D1C9;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;;
17116 1D1CA;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;;
17117 1D1CB;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;;
17118 1D1CC;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;;
17119 1D1CD;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-2;So;0;L;;;;;N;;;;;
17120 1D1CE;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-3;So;0;L;;;;;N;;;;;
17121 1D1CF;MUSICAL SYMBOL CROIX;So;0;L;;;;;N;;;;;
17122 1D1D0;MUSICAL SYMBOL GREGORIAN C CLEF;So;0;L;;;;;N;;;;;
17123 1D1D1;MUSICAL SYMBOL GREGORIAN F CLEF;So;0;L;;;;;N;;;;;
17124 1D1D2;MUSICAL SYMBOL SQUARE B;So;0;L;;;;;N;;;;;
17125 1D1D3;MUSICAL SYMBOL VIRGA;So;0;L;;;;;N;;;;;
17126 1D1D4;MUSICAL SYMBOL PODATUS;So;0;L;;;;;N;;;;;
17127 1D1D5;MUSICAL SYMBOL CLIVIS;So;0;L;;;;;N;;;;;
17128 1D1D6;MUSICAL SYMBOL SCANDICUS;So;0;L;;;;;N;;;;;
17129 1D1D7;MUSICAL SYMBOL CLIMACUS;So;0;L;;;;;N;;;;;
17130 1D1D8;MUSICAL SYMBOL TORCULUS;So;0;L;;;;;N;;;;;
17131 1D1D9;MUSICAL SYMBOL PORRECTUS;So;0;L;;;;;N;;;;;
17132 1D1DA;MUSICAL SYMBOL PORRECTUS FLEXUS;So;0;L;;;;;N;;;;;
17133 1D1DB;MUSICAL SYMBOL SCANDICUS FLEXUS;So;0;L;;;;;N;;;;;
17134 1D1DC;MUSICAL SYMBOL TORCULUS RESUPINUS;So;0;L;;;;;N;;;;;
17135 1D1DD;MUSICAL SYMBOL PES SUBPUNCTIS;So;0;L;;;;;N;;;;;
17136 1D200;GREEK VOCAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;;
17137 1D201;GREEK VOCAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;;
17138 1D202;GREEK VOCAL NOTATION SYMBOL-3;So;0;ON;;;;;N;;;;;
17139 1D203;GREEK VOCAL NOTATION SYMBOL-4;So;0;ON;;;;;N;;;;;
17140 1D204;GREEK VOCAL NOTATION SYMBOL-5;So;0;ON;;;;;N;;;;;
17141 1D205;GREEK VOCAL NOTATION SYMBOL-6;So;0;ON;;;;;N;;;;;
17142 1D206;GREEK VOCAL NOTATION SYMBOL-7;So;0;ON;;;;;N;;;;;
17143 1D207;GREEK VOCAL NOTATION SYMBOL-8;So;0;ON;;;;;N;;;;;
17144 1D208;GREEK VOCAL NOTATION SYMBOL-9;So;0;ON;;;;;N;;;;;
17145 1D209;GREEK VOCAL NOTATION SYMBOL-10;So;0;ON;;;;;N;;;;;
17146 1D20A;GREEK VOCAL NOTATION SYMBOL-11;So;0;ON;;;;;N;;;;;
17147 1D20B;GREEK VOCAL NOTATION SYMBOL-12;So;0;ON;;;;;N;;;;;
17148 1D20C;GREEK VOCAL NOTATION SYMBOL-13;So;0;ON;;;;;N;;;;;
17149 1D20D;GREEK VOCAL NOTATION SYMBOL-14;So;0;ON;;;;;N;;;;;
17150 1D20E;GREEK VOCAL NOTATION SYMBOL-15;So;0;ON;;;;;N;;;;;
17151 1D20F;GREEK VOCAL NOTATION SYMBOL-16;So;0;ON;;;;;N;;;;;
17152 1D210;GREEK VOCAL NOTATION SYMBOL-17;So;0;ON;;;;;N;;;;;
17153 1D211;GREEK VOCAL NOTATION SYMBOL-18;So;0;ON;;;;;N;;;;;
17154 1D212;GREEK VOCAL NOTATION SYMBOL-19;So;0;ON;;;;;N;;;;;
17155 1D213;GREEK VOCAL NOTATION SYMBOL-20;So;0;ON;;;;;N;;;;;
17156 1D214;GREEK VOCAL NOTATION SYMBOL-21;So;0;ON;;;;;N;;;;;
17157 1D215;GREEK VOCAL NOTATION SYMBOL-22;So;0;ON;;;;;N;;;;;
17158 1D216;GREEK VOCAL NOTATION SYMBOL-23;So;0;ON;;;;;N;;;;;
17159 1D217;GREEK VOCAL NOTATION SYMBOL-24;So;0;ON;;;;;N;;;;;
17160 1D218;GREEK VOCAL NOTATION SYMBOL-50;So;0;ON;;;;;N;;;;;
17161 1D219;GREEK VOCAL NOTATION SYMBOL-51;So;0;ON;;;;;N;;;;;
17162 1D21A;GREEK VOCAL NOTATION SYMBOL-52;So;0;ON;;;;;N;;;;;
17163 1D21B;GREEK VOCAL NOTATION SYMBOL-53;So;0;ON;;;;;N;;;;;
17164 1D21C;GREEK VOCAL NOTATION SYMBOL-54;So;0;ON;;;;;N;;;;;
17165 1D21D;GREEK INSTRUMENTAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;;
17166 1D21E;GREEK INSTRUMENTAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;;
17167 1D21F;GREEK INSTRUMENTAL NOTATION SYMBOL-4;So;0;ON;;;;;N;;;;;
17168 1D220;GREEK INSTRUMENTAL NOTATION SYMBOL-5;So;0;ON;;;;;N;;;;;
17169 1D221;GREEK INSTRUMENTAL NOTATION SYMBOL-7;So;0;ON;;;;;N;;;;;
17170 1D222;GREEK INSTRUMENTAL NOTATION SYMBOL-8;So;0;ON;;;;;N;;;;;
17171 1D223;GREEK INSTRUMENTAL NOTATION SYMBOL-11;So;0;ON;;;;;N;;;;;
17172 1D224;GREEK INSTRUMENTAL NOTATION SYMBOL-12;So;0;ON;;;;;N;;;;;
17173 1D225;GREEK INSTRUMENTAL NOTATION SYMBOL-13;So;0;ON;;;;;N;;;;;
17174 1D226;GREEK INSTRUMENTAL NOTATION SYMBOL-14;So;0;ON;;;;;N;;;;;
17175 1D227;GREEK INSTRUMENTAL NOTATION SYMBOL-17;So;0;ON;;;;;N;;;;;
17176 1D228;GREEK INSTRUMENTAL NOTATION SYMBOL-18;So;0;ON;;;;;N;;;;;
17177 1D229;GREEK INSTRUMENTAL NOTATION SYMBOL-19;So;0;ON;;;;;N;;;;;
17178 1D22A;GREEK INSTRUMENTAL NOTATION SYMBOL-23;So;0;ON;;;;;N;;;;;
17179 1D22B;GREEK INSTRUMENTAL NOTATION SYMBOL-24;So;0;ON;;;;;N;;;;;
17180 1D22C;GREEK INSTRUMENTAL NOTATION SYMBOL-25;So;0;ON;;;;;N;;;;;
17181 1D22D;GREEK INSTRUMENTAL NOTATION SYMBOL-26;So;0;ON;;;;;N;;;;;
17182 1D22E;GREEK INSTRUMENTAL NOTATION SYMBOL-27;So;0;ON;;;;;N;;;;;
17183 1D22F;GREEK INSTRUMENTAL NOTATION SYMBOL-29;So;0;ON;;;;;N;;;;;
17184 1D230;GREEK INSTRUMENTAL NOTATION SYMBOL-30;So;0;ON;;;;;N;;;;;
17185 1D231;GREEK INSTRUMENTAL NOTATION SYMBOL-32;So;0;ON;;;;;N;;;;;
17186 1D232;GREEK INSTRUMENTAL NOTATION SYMBOL-36;So;0;ON;;;;;N;;;;;
17187 1D233;GREEK INSTRUMENTAL NOTATION SYMBOL-37;So;0;ON;;;;;N;;;;;
17188 1D234;GREEK INSTRUMENTAL NOTATION SYMBOL-38;So;0;ON;;;;;N;;;;;
17189 1D235;GREEK INSTRUMENTAL NOTATION SYMBOL-39;So;0;ON;;;;;N;;;;;
17190 1D236;GREEK INSTRUMENTAL NOTATION SYMBOL-40;So;0;ON;;;;;N;;;;;
17191 1D237;GREEK INSTRUMENTAL NOTATION SYMBOL-42;So;0;ON;;;;;N;;;;;
17192 1D238;GREEK INSTRUMENTAL NOTATION SYMBOL-43;So;0;ON;;;;;N;;;;;
17193 1D239;GREEK INSTRUMENTAL NOTATION SYMBOL-45;So;0;ON;;;;;N;;;;;
17194 1D23A;GREEK INSTRUMENTAL NOTATION SYMBOL-47;So;0;ON;;;;;N;;;;;
17195 1D23B;GREEK INSTRUMENTAL NOTATION SYMBOL-48;So;0;ON;;;;;N;;;;;
17196 1D23C;GREEK INSTRUMENTAL NOTATION SYMBOL-49;So;0;ON;;;;;N;;;;;
17197 1D23D;GREEK INSTRUMENTAL NOTATION SYMBOL-50;So;0;ON;;;;;N;;;;;
17198 1D23E;GREEK INSTRUMENTAL NOTATION SYMBOL-51;So;0;ON;;;;;N;;;;;
17199 1D23F;GREEK INSTRUMENTAL NOTATION SYMBOL-52;So;0;ON;;;;;N;;;;;
17200 1D240;GREEK INSTRUMENTAL NOTATION SYMBOL-53;So;0;ON;;;;;N;;;;;
17201 1D241;GREEK INSTRUMENTAL NOTATION SYMBOL-54;So;0;ON;;;;;N;;;;;
17202 1D242;COMBINING GREEK MUSICAL TRISEME;Mn;230;NSM;;;;;N;;;;;
17203 1D243;COMBINING GREEK MUSICAL TETRASEME;Mn;230;NSM;;;;;N;;;;;
17204 1D244;COMBINING GREEK MUSICAL PENTASEME;Mn;230;NSM;;;;;N;;;;;
17205 1D245;GREEK MUSICAL LEIMMA;So;0;ON;;;;;N;;;;;
17206 1D300;MONOGRAM FOR EARTH;So;0;ON;;;;;N;;ren *;;;
17207 1D301;DIGRAM FOR HEAVENLY EARTH;So;0;ON;;;;;N;;tian ren *;;;
17208 1D302;DIGRAM FOR HUMAN EARTH;So;0;ON;;;;;N;;di ren *;;;
17209 1D303;DIGRAM FOR EARTHLY HEAVEN;So;0;ON;;;;;N;;ren tian *;;;
17210 1D304;DIGRAM FOR EARTHLY HUMAN;So;0;ON;;;;;N;;ren di *;;;
17211 1D305;DIGRAM FOR EARTH;So;0;ON;;;;;N;;ren ren *;;;
17212 1D306;TETRAGRAM FOR CENTRE;So;0;ON;;;;;N;;;;;
17213 1D307;TETRAGRAM FOR FULL CIRCLE;So;0;ON;;;;;N;;;;;
17214 1D308;TETRAGRAM FOR MIRED;So;0;ON;;;;;N;;;;;
17215 1D309;TETRAGRAM FOR BARRIER;So;0;ON;;;;;N;;;;;
17216 1D30A;TETRAGRAM FOR KEEPING SMALL;So;0;ON;;;;;N;;;;;
17217 1D30B;TETRAGRAM FOR CONTRARIETY;So;0;ON;;;;;N;;;;;
17218 1D30C;TETRAGRAM FOR ASCENT;So;0;ON;;;;;N;;;;;
17219 1D30D;TETRAGRAM FOR OPPOSITION;So;0;ON;;;;;N;;;;;
17220 1D30E;TETRAGRAM FOR BRANCHING OUT;So;0;ON;;;;;N;;;;;
17221 1D30F;TETRAGRAM FOR DEFECTIVENESS OR DISTORTION;So;0;ON;;;;;N;;;;;
17222 1D310;TETRAGRAM FOR DIVERGENCE;So;0;ON;;;;;N;;;;;
17223 1D311;TETRAGRAM FOR YOUTHFULNESS;So;0;ON;;;;;N;;;;;
17224 1D312;TETRAGRAM FOR INCREASE;So;0;ON;;;;;N;;;;;
17225 1D313;TETRAGRAM FOR PENETRATION;So;0;ON;;;;;N;;;;;
17226 1D314;TETRAGRAM FOR REACH;So;0;ON;;;;;N;;;;;
17227 1D315;TETRAGRAM FOR CONTACT;So;0;ON;;;;;N;;;;;
17228 1D316;TETRAGRAM FOR HOLDING BACK;So;0;ON;;;;;N;;;;;
17229 1D317;TETRAGRAM FOR WAITING;So;0;ON;;;;;N;;;;;
17230 1D318;TETRAGRAM FOR FOLLOWING;So;0;ON;;;;;N;;;;;
17231 1D319;TETRAGRAM FOR ADVANCE;So;0;ON;;;;;N;;;;;
17232 1D31A;TETRAGRAM FOR RELEASE;So;0;ON;;;;;N;;;;;
17233 1D31B;TETRAGRAM FOR RESISTANCE;So;0;ON;;;;;N;;;;;
17234 1D31C;TETRAGRAM FOR EASE;So;0;ON;;;;;N;;;;;
17235 1D31D;TETRAGRAM FOR JOY;So;0;ON;;;;;N;;;;;
17236 1D31E;TETRAGRAM FOR CONTENTION;So;0;ON;;;;;N;;;;;
17237 1D31F;TETRAGRAM FOR ENDEAVOUR;So;0;ON;;;;;N;;;;;
17238 1D320;TETRAGRAM FOR DUTIES;So;0;ON;;;;;N;;;;;
17239 1D321;TETRAGRAM FOR CHANGE;So;0;ON;;;;;N;;;;;
17240 1D322;TETRAGRAM FOR DECISIVENESS;So;0;ON;;;;;N;;;;;
17241 1D323;TETRAGRAM FOR BOLD RESOLUTION;So;0;ON;;;;;N;;;;;
17242 1D324;TETRAGRAM FOR PACKING;So;0;ON;;;;;N;;;;;
17243 1D325;TETRAGRAM FOR LEGION;So;0;ON;;;;;N;;;;;
17244 1D326;TETRAGRAM FOR CLOSENESS;So;0;ON;;;;;N;;;;;
17245 1D327;TETRAGRAM FOR KINSHIP;So;0;ON;;;;;N;;;;;
17246 1D328;TETRAGRAM FOR GATHERING;So;0;ON;;;;;N;;;;;
17247 1D329;TETRAGRAM FOR STRENGTH;So;0;ON;;;;;N;;;;;
17248 1D32A;TETRAGRAM FOR PURITY;So;0;ON;;;;;N;;;;;
17249 1D32B;TETRAGRAM FOR FULLNESS;So;0;ON;;;;;N;;;;;
17250 1D32C;TETRAGRAM FOR RESIDENCE;So;0;ON;;;;;N;;;;;
17251 1D32D;TETRAGRAM FOR LAW OR MODEL;So;0;ON;;;;;N;;;;;
17252 1D32E;TETRAGRAM FOR RESPONSE;So;0;ON;;;;;N;;;;;
17253 1D32F;TETRAGRAM FOR GOING TO MEET;So;0;ON;;;;;N;;;;;
17254 1D330;TETRAGRAM FOR ENCOUNTERS;So;0;ON;;;;;N;;;;;
17255 1D331;TETRAGRAM FOR STOVE;So;0;ON;;;;;N;;;;;
17256 1D332;TETRAGRAM FOR GREATNESS;So;0;ON;;;;;N;;;;;
17257 1D333;TETRAGRAM FOR ENLARGEMENT;So;0;ON;;;;;N;;;;;
17258 1D334;TETRAGRAM FOR PATTERN;So;0;ON;;;;;N;;;;;
17259 1D335;TETRAGRAM FOR RITUAL;So;0;ON;;;;;N;;;;;
17260 1D336;TETRAGRAM FOR FLIGHT;So;0;ON;;;;;N;;;;;
17261 1D337;TETRAGRAM FOR VASTNESS OR WASTING;So;0;ON;;;;;N;;;;;
17262 1D338;TETRAGRAM FOR CONSTANCY;So;0;ON;;;;;N;;;;;
17263 1D339;TETRAGRAM FOR MEASURE;So;0;ON;;;;;N;;;;;
17264 1D33A;TETRAGRAM FOR ETERNITY;So;0;ON;;;;;N;;;;;
17265 1D33B;TETRAGRAM FOR UNITY;So;0;ON;;;;;N;;;;;
17266 1D33C;TETRAGRAM FOR DIMINISHMENT;So;0;ON;;;;;N;;;;;
17267 1D33D;TETRAGRAM FOR CLOSED MOUTH;So;0;ON;;;;;N;;;;;
17268 1D33E;TETRAGRAM FOR GUARDEDNESS;So;0;ON;;;;;N;;;;;
17269 1D33F;TETRAGRAM FOR GATHERING IN;So;0;ON;;;;;N;;;;;
17270 1D340;TETRAGRAM FOR MASSING;So;0;ON;;;;;N;;;;;
17271 1D341;TETRAGRAM FOR ACCUMULATION;So;0;ON;;;;;N;;;;;
17272 1D342;TETRAGRAM FOR EMBELLISHMENT;So;0;ON;;;;;N;;;;;
17273 1D343;TETRAGRAM FOR DOUBT;So;0;ON;;;;;N;;;;;
17274 1D344;TETRAGRAM FOR WATCH;So;0;ON;;;;;N;;;;;
17275 1D345;TETRAGRAM FOR SINKING;So;0;ON;;;;;N;;;;;
17276 1D346;TETRAGRAM FOR INNER;So;0;ON;;;;;N;;;;;
17277 1D347;TETRAGRAM FOR DEPARTURE;So;0;ON;;;;;N;;;;;
17278 1D348;TETRAGRAM FOR DARKENING;So;0;ON;;;;;N;;;;;
17279 1D349;TETRAGRAM FOR DIMMING;So;0;ON;;;;;N;;;;;
17280 1D34A;TETRAGRAM FOR EXHAUSTION;So;0;ON;;;;;N;;;;;
17281 1D34B;TETRAGRAM FOR SEVERANCE;So;0;ON;;;;;N;;;;;
17282 1D34C;TETRAGRAM FOR STOPPAGE;So;0;ON;;;;;N;;;;;
17283 1D34D;TETRAGRAM FOR HARDNESS;So;0;ON;;;;;N;;;;;
17284 1D34E;TETRAGRAM FOR COMPLETION;So;0;ON;;;;;N;;;;;
17285 1D34F;TETRAGRAM FOR CLOSURE;So;0;ON;;;;;N;;;;;
17286 1D350;TETRAGRAM FOR FAILURE;So;0;ON;;;;;N;;;;;
17287 1D351;TETRAGRAM FOR AGGRAVATION;So;0;ON;;;;;N;;;;;
17288 1D352;TETRAGRAM FOR COMPLIANCE;So;0;ON;;;;;N;;;;;
17289 1D353;TETRAGRAM FOR ON THE VERGE;So;0;ON;;;;;N;;;;;
17290 1D354;TETRAGRAM FOR DIFFICULTIES;So;0;ON;;;;;N;;;;;
17291 1D355;TETRAGRAM FOR LABOURING;So;0;ON;;;;;N;;;;;
17292 1D356;TETRAGRAM FOR FOSTERING;So;0;ON;;;;;N;;;;;
17293 1D360;COUNTING ROD UNIT DIGIT ONE;No;0;L;;;;1;N;;;;;
17294 1D361;COUNTING ROD UNIT DIGIT TWO;No;0;L;;;;2;N;;;;;
17295 1D362;COUNTING ROD UNIT DIGIT THREE;No;0;L;;;;3;N;;;;;
17296 1D363;COUNTING ROD UNIT DIGIT FOUR;No;0;L;;;;4;N;;;;;
17297 1D364;COUNTING ROD UNIT DIGIT FIVE;No;0;L;;;;5;N;;;;;
17298 1D365;COUNTING ROD UNIT DIGIT SIX;No;0;L;;;;6;N;;;;;
17299 1D366;COUNTING ROD UNIT DIGIT SEVEN;No;0;L;;;;7;N;;;;;
17300 1D367;COUNTING ROD UNIT DIGIT EIGHT;No;0;L;;;;8;N;;;;;
17301 1D368;COUNTING ROD UNIT DIGIT NINE;No;0;L;;;;9;N;;;;;
17302 1D369;COUNTING ROD TENS DIGIT ONE;No;0;L;;;;10;N;;;;;
17303 1D36A;COUNTING ROD TENS DIGIT TWO;No;0;L;;;;20;N;;;;;
17304 1D36B;COUNTING ROD TENS DIGIT THREE;No;0;L;;;;30;N;;;;;
17305 1D36C;COUNTING ROD TENS DIGIT FOUR;No;0;L;;;;40;N;;;;;
17306 1D36D;COUNTING ROD TENS DIGIT FIVE;No;0;L;;;;50;N;;;;;
17307 1D36E;COUNTING ROD TENS DIGIT SIX;No;0;L;;;;60;N;;;;;
17308 1D36F;COUNTING ROD TENS DIGIT SEVEN;No;0;L;;;;70;N;;;;;
17309 1D370;COUNTING ROD TENS DIGIT EIGHT;No;0;L;;;;80;N;;;;;
17310 1D371;COUNTING ROD TENS DIGIT NINE;No;0;L;;;;90;N;;;;;
17311 1D400;MATHEMATICAL BOLD CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
17312 1D401;MATHEMATICAL BOLD CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
17313 1D402;MATHEMATICAL BOLD CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
17314 1D403;MATHEMATICAL BOLD CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
17315 1D404;MATHEMATICAL BOLD CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
17316 1D405;MATHEMATICAL BOLD CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
17317 1D406;MATHEMATICAL BOLD CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
17318 1D407;MATHEMATICAL BOLD CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
17319 1D408;MATHEMATICAL BOLD CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
17320 1D409;MATHEMATICAL BOLD CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
17321 1D40A;MATHEMATICAL BOLD CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
17322 1D40B;MATHEMATICAL BOLD CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
17323 1D40C;MATHEMATICAL BOLD CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
17324 1D40D;MATHEMATICAL BOLD CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
17325 1D40E;MATHEMATICAL BOLD CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
17326 1D40F;MATHEMATICAL BOLD CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
17327 1D410;MATHEMATICAL BOLD CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
17328 1D411;MATHEMATICAL BOLD CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
17329 1D412;MATHEMATICAL BOLD CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
17330 1D413;MATHEMATICAL BOLD CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
17331 1D414;MATHEMATICAL BOLD CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
17332 1D415;MATHEMATICAL BOLD CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
17333 1D416;MATHEMATICAL BOLD CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
17334 1D417;MATHEMATICAL BOLD CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
17335 1D418;MATHEMATICAL BOLD CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
17336 1D419;MATHEMATICAL BOLD CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
17337 1D41A;MATHEMATICAL BOLD SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
17338 1D41B;MATHEMATICAL BOLD SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
17339 1D41C;MATHEMATICAL BOLD SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
17340 1D41D;MATHEMATICAL BOLD SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
17341 1D41E;MATHEMATICAL BOLD SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
17342 1D41F;MATHEMATICAL BOLD SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
17343 1D420;MATHEMATICAL BOLD SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
17344 1D421;MATHEMATICAL BOLD SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
17345 1D422;MATHEMATICAL BOLD SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
17346 1D423;MATHEMATICAL BOLD SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
17347 1D424;MATHEMATICAL BOLD SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
17348 1D425;MATHEMATICAL BOLD SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
17349 1D426;MATHEMATICAL BOLD SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
17350 1D427;MATHEMATICAL BOLD SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
17351 1D428;MATHEMATICAL BOLD SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
17352 1D429;MATHEMATICAL BOLD SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
17353 1D42A;MATHEMATICAL BOLD SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
17354 1D42B;MATHEMATICAL BOLD SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
17355 1D42C;MATHEMATICAL BOLD SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
17356 1D42D;MATHEMATICAL BOLD SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
17357 1D42E;MATHEMATICAL BOLD SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
17358 1D42F;MATHEMATICAL BOLD SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
17359 1D430;MATHEMATICAL BOLD SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
17360 1D431;MATHEMATICAL BOLD SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
17361 1D432;MATHEMATICAL BOLD SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
17362 1D433;MATHEMATICAL BOLD SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
17363 1D434;MATHEMATICAL ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
17364 1D435;MATHEMATICAL ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
17365 1D436;MATHEMATICAL ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
17366 1D437;MATHEMATICAL ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
17367 1D438;MATHEMATICAL ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
17368 1D439;MATHEMATICAL ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
17369 1D43A;MATHEMATICAL ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
17370 1D43B;MATHEMATICAL ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
17371 1D43C;MATHEMATICAL ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
17372 1D43D;MATHEMATICAL ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
17373 1D43E;MATHEMATICAL ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
17374 1D43F;MATHEMATICAL ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
17375 1D440;MATHEMATICAL ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
17376 1D441;MATHEMATICAL ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
17377 1D442;MATHEMATICAL ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
17378 1D443;MATHEMATICAL ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
17379 1D444;MATHEMATICAL ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
17380 1D445;MATHEMATICAL ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
17381 1D446;MATHEMATICAL ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
17382 1D447;MATHEMATICAL ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
17383 1D448;MATHEMATICAL ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
17384 1D449;MATHEMATICAL ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
17385 1D44A;MATHEMATICAL ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
17386 1D44B;MATHEMATICAL ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
17387 1D44C;MATHEMATICAL ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
17388 1D44D;MATHEMATICAL ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
17389 1D44E;MATHEMATICAL ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
17390 1D44F;MATHEMATICAL ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
17391 1D450;MATHEMATICAL ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
17392 1D451;MATHEMATICAL ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
17393 1D452;MATHEMATICAL ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
17394 1D453;MATHEMATICAL ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
17395 1D454;MATHEMATICAL ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
17396 1D456;MATHEMATICAL ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
17397 1D457;MATHEMATICAL ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
17398 1D458;MATHEMATICAL ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
17399 1D459;MATHEMATICAL ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
17400 1D45A;MATHEMATICAL ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
17401 1D45B;MATHEMATICAL ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
17402 1D45C;MATHEMATICAL ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
17403 1D45D;MATHEMATICAL ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
17404 1D45E;MATHEMATICAL ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
17405 1D45F;MATHEMATICAL ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
17406 1D460;MATHEMATICAL ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
17407 1D461;MATHEMATICAL ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
17408 1D462;MATHEMATICAL ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
17409 1D463;MATHEMATICAL ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
17410 1D464;MATHEMATICAL ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
17411 1D465;MATHEMATICAL ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
17412 1D466;MATHEMATICAL ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
17413 1D467;MATHEMATICAL ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
17414 1D468;MATHEMATICAL BOLD ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
17415 1D469;MATHEMATICAL BOLD ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
17416 1D46A;MATHEMATICAL BOLD ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
17417 1D46B;MATHEMATICAL BOLD ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
17418 1D46C;MATHEMATICAL BOLD ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
17419 1D46D;MATHEMATICAL BOLD ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
17420 1D46E;MATHEMATICAL BOLD ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
17421 1D46F;MATHEMATICAL BOLD ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
17422 1D470;MATHEMATICAL BOLD ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
17423 1D471;MATHEMATICAL BOLD ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
17424 1D472;MATHEMATICAL BOLD ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
17425 1D473;MATHEMATICAL BOLD ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
17426 1D474;MATHEMATICAL BOLD ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
17427 1D475;MATHEMATICAL BOLD ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
17428 1D476;MATHEMATICAL BOLD ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
17429 1D477;MATHEMATICAL BOLD ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
17430 1D478;MATHEMATICAL BOLD ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
17431 1D479;MATHEMATICAL BOLD ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
17432 1D47A;MATHEMATICAL BOLD ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
17433 1D47B;MATHEMATICAL BOLD ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
17434 1D47C;MATHEMATICAL BOLD ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
17435 1D47D;MATHEMATICAL BOLD ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
17436 1D47E;MATHEMATICAL BOLD ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
17437 1D47F;MATHEMATICAL BOLD ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
17438 1D480;MATHEMATICAL BOLD ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
17439 1D481;MATHEMATICAL BOLD ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
17440 1D482;MATHEMATICAL BOLD ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
17441 1D483;MATHEMATICAL BOLD ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
17442 1D484;MATHEMATICAL BOLD ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
17443 1D485;MATHEMATICAL BOLD ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
17444 1D486;MATHEMATICAL BOLD ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
17445 1D487;MATHEMATICAL BOLD ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
17446 1D488;MATHEMATICAL BOLD ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
17447 1D489;MATHEMATICAL BOLD ITALIC SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
17448 1D48A;MATHEMATICAL BOLD ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
17449 1D48B;MATHEMATICAL BOLD ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
17450 1D48C;MATHEMATICAL BOLD ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
17451 1D48D;MATHEMATICAL BOLD ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
17452 1D48E;MATHEMATICAL BOLD ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
17453 1D48F;MATHEMATICAL BOLD ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
17454 1D490;MATHEMATICAL BOLD ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
17455 1D491;MATHEMATICAL BOLD ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
17456 1D492;MATHEMATICAL BOLD ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
17457 1D493;MATHEMATICAL BOLD ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
17458 1D494;MATHEMATICAL BOLD ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
17459 1D495;MATHEMATICAL BOLD ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
17460 1D496;MATHEMATICAL BOLD ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
17461 1D497;MATHEMATICAL BOLD ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
17462 1D498;MATHEMATICAL BOLD ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
17463 1D499;MATHEMATICAL BOLD ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
17464 1D49A;MATHEMATICAL BOLD ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
17465 1D49B;MATHEMATICAL BOLD ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
17466 1D49C;MATHEMATICAL SCRIPT CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
17467 1D49E;MATHEMATICAL SCRIPT CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
17468 1D49F;MATHEMATICAL SCRIPT CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
17469 1D4A2;MATHEMATICAL SCRIPT CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
17470 1D4A5;MATHEMATICAL SCRIPT CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
17471 1D4A6;MATHEMATICAL SCRIPT CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
17472 1D4A9;MATHEMATICAL SCRIPT CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
17473 1D4AA;MATHEMATICAL SCRIPT CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
17474 1D4AB;MATHEMATICAL SCRIPT CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
17475 1D4AC;MATHEMATICAL SCRIPT CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
17476 1D4AE;MATHEMATICAL SCRIPT CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
17477 1D4AF;MATHEMATICAL SCRIPT CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
17478 1D4B0;MATHEMATICAL SCRIPT CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
17479 1D4B1;MATHEMATICAL SCRIPT CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
17480 1D4B2;MATHEMATICAL SCRIPT CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
17481 1D4B3;MATHEMATICAL SCRIPT CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
17482 1D4B4;MATHEMATICAL SCRIPT CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
17483 1D4B5;MATHEMATICAL SCRIPT CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
17484 1D4B6;MATHEMATICAL SCRIPT SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
17485 1D4B7;MATHEMATICAL SCRIPT SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
17486 1D4B8;MATHEMATICAL SCRIPT SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
17487 1D4B9;MATHEMATICAL SCRIPT SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
17488 1D4BB;MATHEMATICAL SCRIPT SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
17489 1D4BD;MATHEMATICAL SCRIPT SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
17490 1D4BE;MATHEMATICAL SCRIPT SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
17491 1D4BF;MATHEMATICAL SCRIPT SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
17492 1D4C0;MATHEMATICAL SCRIPT SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
17493 1D4C1;MATHEMATICAL SCRIPT SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
17494 1D4C2;MATHEMATICAL SCRIPT SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
17495 1D4C3;MATHEMATICAL SCRIPT SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
17496 1D4C5;MATHEMATICAL SCRIPT SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
17497 1D4C6;MATHEMATICAL SCRIPT SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
17498 1D4C7;MATHEMATICAL SCRIPT SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
17499 1D4C8;MATHEMATICAL SCRIPT SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
17500 1D4C9;MATHEMATICAL SCRIPT SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
17501 1D4CA;MATHEMATICAL SCRIPT SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
17502 1D4CB;MATHEMATICAL SCRIPT SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
17503 1D4CC;MATHEMATICAL SCRIPT SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
17504 1D4CD;MATHEMATICAL SCRIPT SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
17505 1D4CE;MATHEMATICAL SCRIPT SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
17506 1D4CF;MATHEMATICAL SCRIPT SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
17507 1D4D0;MATHEMATICAL BOLD SCRIPT CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
17508 1D4D1;MATHEMATICAL BOLD SCRIPT CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
17509 1D4D2;MATHEMATICAL BOLD SCRIPT CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
17510 1D4D3;MATHEMATICAL BOLD SCRIPT CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
17511 1D4D4;MATHEMATICAL BOLD SCRIPT CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
17512 1D4D5;MATHEMATICAL BOLD SCRIPT CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
17513 1D4D6;MATHEMATICAL BOLD SCRIPT CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
17514 1D4D7;MATHEMATICAL BOLD SCRIPT CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
17515 1D4D8;MATHEMATICAL BOLD SCRIPT CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
17516 1D4D9;MATHEMATICAL BOLD SCRIPT CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
17517 1D4DA;MATHEMATICAL BOLD SCRIPT CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
17518 1D4DB;MATHEMATICAL BOLD SCRIPT CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
17519 1D4DC;MATHEMATICAL BOLD SCRIPT CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
17520 1D4DD;MATHEMATICAL BOLD SCRIPT CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
17521 1D4DE;MATHEMATICAL BOLD SCRIPT CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
17522 1D4DF;MATHEMATICAL BOLD SCRIPT CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
17523 1D4E0;MATHEMATICAL BOLD SCRIPT CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
17524 1D4E1;MATHEMATICAL BOLD SCRIPT CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
17525 1D4E2;MATHEMATICAL BOLD SCRIPT CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
17526 1D4E3;MATHEMATICAL BOLD SCRIPT CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
17527 1D4E4;MATHEMATICAL BOLD SCRIPT CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
17528 1D4E5;MATHEMATICAL BOLD SCRIPT CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
17529 1D4E6;MATHEMATICAL BOLD SCRIPT CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
17530 1D4E7;MATHEMATICAL BOLD SCRIPT CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
17531 1D4E8;MATHEMATICAL BOLD SCRIPT CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
17532 1D4E9;MATHEMATICAL BOLD SCRIPT CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
17533 1D4EA;MATHEMATICAL BOLD SCRIPT SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
17534 1D4EB;MATHEMATICAL BOLD SCRIPT SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
17535 1D4EC;MATHEMATICAL BOLD SCRIPT SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
17536 1D4ED;MATHEMATICAL BOLD SCRIPT SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
17537 1D4EE;MATHEMATICAL BOLD SCRIPT SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
17538 1D4EF;MATHEMATICAL BOLD SCRIPT SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
17539 1D4F0;MATHEMATICAL BOLD SCRIPT SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
17540 1D4F1;MATHEMATICAL BOLD SCRIPT SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
17541 1D4F2;MATHEMATICAL BOLD SCRIPT SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
17542 1D4F3;MATHEMATICAL BOLD SCRIPT SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
17543 1D4F4;MATHEMATICAL BOLD SCRIPT SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
17544 1D4F5;MATHEMATICAL BOLD SCRIPT SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
17545 1D4F6;MATHEMATICAL BOLD SCRIPT SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
17546 1D4F7;MATHEMATICAL BOLD SCRIPT SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
17547 1D4F8;MATHEMATICAL BOLD SCRIPT SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
17548 1D4F9;MATHEMATICAL BOLD SCRIPT SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
17549 1D4FA;MATHEMATICAL BOLD SCRIPT SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
17550 1D4FB;MATHEMATICAL BOLD SCRIPT SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
17551 1D4FC;MATHEMATICAL BOLD SCRIPT SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
17552 1D4FD;MATHEMATICAL BOLD SCRIPT SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
17553 1D4FE;MATHEMATICAL BOLD SCRIPT SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
17554 1D4FF;MATHEMATICAL BOLD SCRIPT SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
17555 1D500;MATHEMATICAL BOLD SCRIPT SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
17556 1D501;MATHEMATICAL BOLD SCRIPT SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
17557 1D502;MATHEMATICAL BOLD SCRIPT SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
17558 1D503;MATHEMATICAL BOLD SCRIPT SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
17559 1D504;MATHEMATICAL FRAKTUR CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
17560 1D505;MATHEMATICAL FRAKTUR CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
17561 1D507;MATHEMATICAL FRAKTUR CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
17562 1D508;MATHEMATICAL FRAKTUR CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
17563 1D509;MATHEMATICAL FRAKTUR CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
17564 1D50A;MATHEMATICAL FRAKTUR CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
17565 1D50D;MATHEMATICAL FRAKTUR CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
17566 1D50E;MATHEMATICAL FRAKTUR CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
17567 1D50F;MATHEMATICAL FRAKTUR CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
17568 1D510;MATHEMATICAL FRAKTUR CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
17569 1D511;MATHEMATICAL FRAKTUR CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
17570 1D512;MATHEMATICAL FRAKTUR CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
17571 1D513;MATHEMATICAL FRAKTUR CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
17572 1D514;MATHEMATICAL FRAKTUR CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
17573 1D516;MATHEMATICAL FRAKTUR CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
17574 1D517;MATHEMATICAL FRAKTUR CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
17575 1D518;MATHEMATICAL FRAKTUR CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
17576 1D519;MATHEMATICAL FRAKTUR CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
17577 1D51A;MATHEMATICAL FRAKTUR CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
17578 1D51B;MATHEMATICAL FRAKTUR CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
17579 1D51C;MATHEMATICAL FRAKTUR CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
17580 1D51E;MATHEMATICAL FRAKTUR SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
17581 1D51F;MATHEMATICAL FRAKTUR SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
17582 1D520;MATHEMATICAL FRAKTUR SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
17583 1D521;MATHEMATICAL FRAKTUR SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
17584 1D522;MATHEMATICAL FRAKTUR SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
17585 1D523;MATHEMATICAL FRAKTUR SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
17586 1D524;MATHEMATICAL FRAKTUR SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
17587 1D525;MATHEMATICAL FRAKTUR SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
17588 1D526;MATHEMATICAL FRAKTUR SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
17589 1D527;MATHEMATICAL FRAKTUR SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
17590 1D528;MATHEMATICAL FRAKTUR SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
17591 1D529;MATHEMATICAL FRAKTUR SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
17592 1D52A;MATHEMATICAL FRAKTUR SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
17593 1D52B;MATHEMATICAL FRAKTUR SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
17594 1D52C;MATHEMATICAL FRAKTUR SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
17595 1D52D;MATHEMATICAL FRAKTUR SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
17596 1D52E;MATHEMATICAL FRAKTUR SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
17597 1D52F;MATHEMATICAL FRAKTUR SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
17598 1D530;MATHEMATICAL FRAKTUR SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
17599 1D531;MATHEMATICAL FRAKTUR SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
17600 1D532;MATHEMATICAL FRAKTUR SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
17601 1D533;MATHEMATICAL FRAKTUR SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
17602 1D534;MATHEMATICAL FRAKTUR SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
17603 1D535;MATHEMATICAL FRAKTUR SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
17604 1D536;MATHEMATICAL FRAKTUR SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
17605 1D537;MATHEMATICAL FRAKTUR SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
17606 1D538;MATHEMATICAL DOUBLE-STRUCK CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
17607 1D539;MATHEMATICAL DOUBLE-STRUCK CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
17608 1D53B;MATHEMATICAL DOUBLE-STRUCK CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
17609 1D53C;MATHEMATICAL DOUBLE-STRUCK CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
17610 1D53D;MATHEMATICAL DOUBLE-STRUCK CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
17611 1D53E;MATHEMATICAL DOUBLE-STRUCK CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
17612 1D540;MATHEMATICAL DOUBLE-STRUCK CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
17613 1D541;MATHEMATICAL DOUBLE-STRUCK CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
17614 1D542;MATHEMATICAL DOUBLE-STRUCK CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
17615 1D543;MATHEMATICAL DOUBLE-STRUCK CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
17616 1D544;MATHEMATICAL DOUBLE-STRUCK CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
17617 1D546;MATHEMATICAL DOUBLE-STRUCK CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
17618 1D54A;MATHEMATICAL DOUBLE-STRUCK CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
17619 1D54B;MATHEMATICAL DOUBLE-STRUCK CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
17620 1D54C;MATHEMATICAL DOUBLE-STRUCK CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
17621 1D54D;MATHEMATICAL DOUBLE-STRUCK CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
17622 1D54E;MATHEMATICAL DOUBLE-STRUCK CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
17623 1D54F;MATHEMATICAL DOUBLE-STRUCK CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
17624 1D550;MATHEMATICAL DOUBLE-STRUCK CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
17625 1D552;MATHEMATICAL DOUBLE-STRUCK SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
17626 1D553;MATHEMATICAL DOUBLE-STRUCK SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
17627 1D554;MATHEMATICAL DOUBLE-STRUCK SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
17628 1D555;MATHEMATICAL DOUBLE-STRUCK SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
17629 1D556;MATHEMATICAL DOUBLE-STRUCK SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
17630 1D557;MATHEMATICAL DOUBLE-STRUCK SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
17631 1D558;MATHEMATICAL DOUBLE-STRUCK SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
17632 1D559;MATHEMATICAL DOUBLE-STRUCK SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
17633 1D55A;MATHEMATICAL DOUBLE-STRUCK SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
17634 1D55B;MATHEMATICAL DOUBLE-STRUCK SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
17635 1D55C;MATHEMATICAL DOUBLE-STRUCK SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
17636 1D55D;MATHEMATICAL DOUBLE-STRUCK SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
17637 1D55E;MATHEMATICAL DOUBLE-STRUCK SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
17638 1D55F;MATHEMATICAL DOUBLE-STRUCK SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
17639 1D560;MATHEMATICAL DOUBLE-STRUCK SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
17640 1D561;MATHEMATICAL DOUBLE-STRUCK SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
17641 1D562;MATHEMATICAL DOUBLE-STRUCK SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
17642 1D563;MATHEMATICAL DOUBLE-STRUCK SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
17643 1D564;MATHEMATICAL DOUBLE-STRUCK SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
17644 1D565;MATHEMATICAL DOUBLE-STRUCK SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
17645 1D566;MATHEMATICAL DOUBLE-STRUCK SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
17646 1D567;MATHEMATICAL DOUBLE-STRUCK SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
17647 1D568;MATHEMATICAL DOUBLE-STRUCK SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
17648 1D569;MATHEMATICAL DOUBLE-STRUCK SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
17649 1D56A;MATHEMATICAL DOUBLE-STRUCK SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
17650 1D56B;MATHEMATICAL DOUBLE-STRUCK SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
17651 1D56C;MATHEMATICAL BOLD FRAKTUR CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
17652 1D56D;MATHEMATICAL BOLD FRAKTUR CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
17653 1D56E;MATHEMATICAL BOLD FRAKTUR CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
17654 1D56F;MATHEMATICAL BOLD FRAKTUR CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
17655 1D570;MATHEMATICAL BOLD FRAKTUR CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
17656 1D571;MATHEMATICAL BOLD FRAKTUR CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
17657 1D572;MATHEMATICAL BOLD FRAKTUR CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
17658 1D573;MATHEMATICAL BOLD FRAKTUR CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
17659 1D574;MATHEMATICAL BOLD FRAKTUR CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
17660 1D575;MATHEMATICAL BOLD FRAKTUR CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
17661 1D576;MATHEMATICAL BOLD FRAKTUR CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
17662 1D577;MATHEMATICAL BOLD FRAKTUR CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
17663 1D578;MATHEMATICAL BOLD FRAKTUR CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
17664 1D579;MATHEMATICAL BOLD FRAKTUR CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
17665 1D57A;MATHEMATICAL BOLD FRAKTUR CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
17666 1D57B;MATHEMATICAL BOLD FRAKTUR CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
17667 1D57C;MATHEMATICAL BOLD FRAKTUR CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
17668 1D57D;MATHEMATICAL BOLD FRAKTUR CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
17669 1D57E;MATHEMATICAL BOLD FRAKTUR CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
17670 1D57F;MATHEMATICAL BOLD FRAKTUR CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
17671 1D580;MATHEMATICAL BOLD FRAKTUR CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
17672 1D581;MATHEMATICAL BOLD FRAKTUR CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
17673 1D582;MATHEMATICAL BOLD FRAKTUR CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
17674 1D583;MATHEMATICAL BOLD FRAKTUR CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
17675 1D584;MATHEMATICAL BOLD FRAKTUR CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
17676 1D585;MATHEMATICAL BOLD FRAKTUR CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
17677 1D586;MATHEMATICAL BOLD FRAKTUR SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
17678 1D587;MATHEMATICAL BOLD FRAKTUR SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
17679 1D588;MATHEMATICAL BOLD FRAKTUR SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
17680 1D589;MATHEMATICAL BOLD FRAKTUR SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
17681 1D58A;MATHEMATICAL BOLD FRAKTUR SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
17682 1D58B;MATHEMATICAL BOLD FRAKTUR SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
17683 1D58C;MATHEMATICAL BOLD FRAKTUR SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
17684 1D58D;MATHEMATICAL BOLD FRAKTUR SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
17685 1D58E;MATHEMATICAL BOLD FRAKTUR SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
17686 1D58F;MATHEMATICAL BOLD FRAKTUR SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
17687 1D590;MATHEMATICAL BOLD FRAKTUR SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
17688 1D591;MATHEMATICAL BOLD FRAKTUR SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
17689 1D592;MATHEMATICAL BOLD FRAKTUR SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
17690 1D593;MATHEMATICAL BOLD FRAKTUR SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
17691 1D594;MATHEMATICAL BOLD FRAKTUR SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
17692 1D595;MATHEMATICAL BOLD FRAKTUR SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
17693 1D596;MATHEMATICAL BOLD FRAKTUR SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
17694 1D597;MATHEMATICAL BOLD FRAKTUR SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
17695 1D598;MATHEMATICAL BOLD FRAKTUR SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
17696 1D599;MATHEMATICAL BOLD FRAKTUR SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
17697 1D59A;MATHEMATICAL BOLD FRAKTUR SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
17698 1D59B;MATHEMATICAL BOLD FRAKTUR SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
17699 1D59C;MATHEMATICAL BOLD FRAKTUR SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
17700 1D59D;MATHEMATICAL BOLD FRAKTUR SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
17701 1D59E;MATHEMATICAL BOLD FRAKTUR SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
17702 1D59F;MATHEMATICAL BOLD FRAKTUR SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
17703 1D5A0;MATHEMATICAL SANS-SERIF CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
17704 1D5A1;MATHEMATICAL SANS-SERIF CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
17705 1D5A2;MATHEMATICAL SANS-SERIF CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
17706 1D5A3;MATHEMATICAL SANS-SERIF CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
17707 1D5A4;MATHEMATICAL SANS-SERIF CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
17708 1D5A5;MATHEMATICAL SANS-SERIF CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
17709 1D5A6;MATHEMATICAL SANS-SERIF CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
17710 1D5A7;MATHEMATICAL SANS-SERIF CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
17711 1D5A8;MATHEMATICAL SANS-SERIF CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
17712 1D5A9;MATHEMATICAL SANS-SERIF CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
17713 1D5AA;MATHEMATICAL SANS-SERIF CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
17714 1D5AB;MATHEMATICAL SANS-SERIF CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
17715 1D5AC;MATHEMATICAL SANS-SERIF CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
17716 1D5AD;MATHEMATICAL SANS-SERIF CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
17717 1D5AE;MATHEMATICAL SANS-SERIF CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
17718 1D5AF;MATHEMATICAL SANS-SERIF CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
17719 1D5B0;MATHEMATICAL SANS-SERIF CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
17720 1D5B1;MATHEMATICAL SANS-SERIF CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
17721 1D5B2;MATHEMATICAL SANS-SERIF CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
17722 1D5B3;MATHEMATICAL SANS-SERIF CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
17723 1D5B4;MATHEMATICAL SANS-SERIF CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
17724 1D5B5;MATHEMATICAL SANS-SERIF CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
17725 1D5B6;MATHEMATICAL SANS-SERIF CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
17726 1D5B7;MATHEMATICAL SANS-SERIF CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
17727 1D5B8;MATHEMATICAL SANS-SERIF CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
17728 1D5B9;MATHEMATICAL SANS-SERIF CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
17729 1D5BA;MATHEMATICAL SANS-SERIF SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
17730 1D5BB;MATHEMATICAL SANS-SERIF SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
17731 1D5BC;MATHEMATICAL SANS-SERIF SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
17732 1D5BD;MATHEMATICAL SANS-SERIF SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
17733 1D5BE;MATHEMATICAL SANS-SERIF SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
17734 1D5BF;MATHEMATICAL SANS-SERIF SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
17735 1D5C0;MATHEMATICAL SANS-SERIF SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
17736 1D5C1;MATHEMATICAL SANS-SERIF SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
17737 1D5C2;MATHEMATICAL SANS-SERIF SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
17738 1D5C3;MATHEMATICAL SANS-SERIF SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
17739 1D5C4;MATHEMATICAL SANS-SERIF SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
17740 1D5C5;MATHEMATICAL SANS-SERIF SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
17741 1D5C6;MATHEMATICAL SANS-SERIF SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
17742 1D5C7;MATHEMATICAL SANS-SERIF SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
17743 1D5C8;MATHEMATICAL SANS-SERIF SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
17744 1D5C9;MATHEMATICAL SANS-SERIF SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
17745 1D5CA;MATHEMATICAL SANS-SERIF SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
17746 1D5CB;MATHEMATICAL SANS-SERIF SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
17747 1D5CC;MATHEMATICAL SANS-SERIF SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
17748 1D5CD;MATHEMATICAL SANS-SERIF SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
17749 1D5CE;MATHEMATICAL SANS-SERIF SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
17750 1D5CF;MATHEMATICAL SANS-SERIF SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
17751 1D5D0;MATHEMATICAL SANS-SERIF SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
17752 1D5D1;MATHEMATICAL SANS-SERIF SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
17753 1D5D2;MATHEMATICAL SANS-SERIF SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
17754 1D5D3;MATHEMATICAL SANS-SERIF SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
17755 1D5D4;MATHEMATICAL SANS-SERIF BOLD CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
17756 1D5D5;MATHEMATICAL SANS-SERIF BOLD CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
17757 1D5D6;MATHEMATICAL SANS-SERIF BOLD CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
17758 1D5D7;MATHEMATICAL SANS-SERIF BOLD CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
17759 1D5D8;MATHEMATICAL SANS-SERIF BOLD CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
17760 1D5D9;MATHEMATICAL SANS-SERIF BOLD CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
17761 1D5DA;MATHEMATICAL SANS-SERIF BOLD CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
17762 1D5DB;MATHEMATICAL SANS-SERIF BOLD CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
17763 1D5DC;MATHEMATICAL SANS-SERIF BOLD CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
17764 1D5DD;MATHEMATICAL SANS-SERIF BOLD CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
17765 1D5DE;MATHEMATICAL SANS-SERIF BOLD CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
17766 1D5DF;MATHEMATICAL SANS-SERIF BOLD CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
17767 1D5E0;MATHEMATICAL SANS-SERIF BOLD CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
17768 1D5E1;MATHEMATICAL SANS-SERIF BOLD CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
17769 1D5E2;MATHEMATICAL SANS-SERIF BOLD CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
17770 1D5E3;MATHEMATICAL SANS-SERIF BOLD CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
17771 1D5E4;MATHEMATICAL SANS-SERIF BOLD CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
17772 1D5E5;MATHEMATICAL SANS-SERIF BOLD CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
17773 1D5E6;MATHEMATICAL SANS-SERIF BOLD CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
17774 1D5E7;MATHEMATICAL SANS-SERIF BOLD CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
17775 1D5E8;MATHEMATICAL SANS-SERIF BOLD CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
17776 1D5E9;MATHEMATICAL SANS-SERIF BOLD CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
17777 1D5EA;MATHEMATICAL SANS-SERIF BOLD CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
17778 1D5EB;MATHEMATICAL SANS-SERIF BOLD CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
17779 1D5EC;MATHEMATICAL SANS-SERIF BOLD CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
17780 1D5ED;MATHEMATICAL SANS-SERIF BOLD CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
17781 1D5EE;MATHEMATICAL SANS-SERIF BOLD SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
17782 1D5EF;MATHEMATICAL SANS-SERIF BOLD SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
17783 1D5F0;MATHEMATICAL SANS-SERIF BOLD SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
17784 1D5F1;MATHEMATICAL SANS-SERIF BOLD SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
17785 1D5F2;MATHEMATICAL SANS-SERIF BOLD SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
17786 1D5F3;MATHEMATICAL SANS-SERIF BOLD SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
17787 1D5F4;MATHEMATICAL SANS-SERIF BOLD SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
17788 1D5F5;MATHEMATICAL SANS-SERIF BOLD SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
17789 1D5F6;MATHEMATICAL SANS-SERIF BOLD SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
17790 1D5F7;MATHEMATICAL SANS-SERIF BOLD SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
17791 1D5F8;MATHEMATICAL SANS-SERIF BOLD SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
17792 1D5F9;MATHEMATICAL SANS-SERIF BOLD SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
17793 1D5FA;MATHEMATICAL SANS-SERIF BOLD SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
17794 1D5FB;MATHEMATICAL SANS-SERIF BOLD SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
17795 1D5FC;MATHEMATICAL SANS-SERIF BOLD SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
17796 1D5FD;MATHEMATICAL SANS-SERIF BOLD SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
17797 1D5FE;MATHEMATICAL SANS-SERIF BOLD SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
17798 1D5FF;MATHEMATICAL SANS-SERIF BOLD SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
17799 1D600;MATHEMATICAL SANS-SERIF BOLD SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
17800 1D601;MATHEMATICAL SANS-SERIF BOLD SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
17801 1D602;MATHEMATICAL SANS-SERIF BOLD SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
17802 1D603;MATHEMATICAL SANS-SERIF BOLD SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
17803 1D604;MATHEMATICAL SANS-SERIF BOLD SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
17804 1D605;MATHEMATICAL SANS-SERIF BOLD SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
17805 1D606;MATHEMATICAL SANS-SERIF BOLD SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
17806 1D607;MATHEMATICAL SANS-SERIF BOLD SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
17807 1D608;MATHEMATICAL SANS-SERIF ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
17808 1D609;MATHEMATICAL SANS-SERIF ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
17809 1D60A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
17810 1D60B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
17811 1D60C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
17812 1D60D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
17813 1D60E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
17814 1D60F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
17815 1D610;MATHEMATICAL SANS-SERIF ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
17816 1D611;MATHEMATICAL SANS-SERIF ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
17817 1D612;MATHEMATICAL SANS-SERIF ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
17818 1D613;MATHEMATICAL SANS-SERIF ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
17819 1D614;MATHEMATICAL SANS-SERIF ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
17820 1D615;MATHEMATICAL SANS-SERIF ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
17821 1D616;MATHEMATICAL SANS-SERIF ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
17822 1D617;MATHEMATICAL SANS-SERIF ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
17823 1D618;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
17824 1D619;MATHEMATICAL SANS-SERIF ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
17825 1D61A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
17826 1D61B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
17827 1D61C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
17828 1D61D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
17829 1D61E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
17830 1D61F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
17831 1D620;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
17832 1D621;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
17833 1D622;MATHEMATICAL SANS-SERIF ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
17834 1D623;MATHEMATICAL SANS-SERIF ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
17835 1D624;MATHEMATICAL SANS-SERIF ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
17836 1D625;MATHEMATICAL SANS-SERIF ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
17837 1D626;MATHEMATICAL SANS-SERIF ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
17838 1D627;MATHEMATICAL SANS-SERIF ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
17839 1D628;MATHEMATICAL SANS-SERIF ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
17840 1D629;MATHEMATICAL SANS-SERIF ITALIC SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
17841 1D62A;MATHEMATICAL SANS-SERIF ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
17842 1D62B;MATHEMATICAL SANS-SERIF ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
17843 1D62C;MATHEMATICAL SANS-SERIF ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
17844 1D62D;MATHEMATICAL SANS-SERIF ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
17845 1D62E;MATHEMATICAL SANS-SERIF ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
17846 1D62F;MATHEMATICAL SANS-SERIF ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
17847 1D630;MATHEMATICAL SANS-SERIF ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
17848 1D631;MATHEMATICAL SANS-SERIF ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
17849 1D632;MATHEMATICAL SANS-SERIF ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
17850 1D633;MATHEMATICAL SANS-SERIF ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
17851 1D634;MATHEMATICAL SANS-SERIF ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
17852 1D635;MATHEMATICAL SANS-SERIF ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
17853 1D636;MATHEMATICAL SANS-SERIF ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
17854 1D637;MATHEMATICAL SANS-SERIF ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
17855 1D638;MATHEMATICAL SANS-SERIF ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
17856 1D639;MATHEMATICAL SANS-SERIF ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
17857 1D63A;MATHEMATICAL SANS-SERIF ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
17858 1D63B;MATHEMATICAL SANS-SERIF ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
17859 1D63C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
17860 1D63D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
17861 1D63E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
17862 1D63F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
17863 1D640;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
17864 1D641;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
17865 1D642;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
17866 1D643;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
17867 1D644;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
17868 1D645;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
17869 1D646;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
17870 1D647;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
17871 1D648;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
17872 1D649;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
17873 1D64A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
17874 1D64B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
17875 1D64C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
17876 1D64D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
17877 1D64E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
17878 1D64F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
17879 1D650;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
17880 1D651;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
17881 1D652;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
17882 1D653;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
17883 1D654;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
17884 1D655;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
17885 1D656;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
17886 1D657;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
17887 1D658;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
17888 1D659;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
17889 1D65A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
17890 1D65B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
17891 1D65C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
17892 1D65D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
17893 1D65E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
17894 1D65F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
17895 1D660;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
17896 1D661;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
17897 1D662;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
17898 1D663;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
17899 1D664;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
17900 1D665;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
17901 1D666;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
17902 1D667;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
17903 1D668;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
17904 1D669;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
17905 1D66A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
17906 1D66B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
17907 1D66C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
17908 1D66D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
17909 1D66E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
17910 1D66F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
17911 1D670;MATHEMATICAL MONOSPACE CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;
17912 1D671;MATHEMATICAL MONOSPACE CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;
17913 1D672;MATHEMATICAL MONOSPACE CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;
17914 1D673;MATHEMATICAL MONOSPACE CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;
17915 1D674;MATHEMATICAL MONOSPACE CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;
17916 1D675;MATHEMATICAL MONOSPACE CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;
17917 1D676;MATHEMATICAL MONOSPACE CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;
17918 1D677;MATHEMATICAL MONOSPACE CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;
17919 1D678;MATHEMATICAL MONOSPACE CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;
17920 1D679;MATHEMATICAL MONOSPACE CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;
17921 1D67A;MATHEMATICAL MONOSPACE CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;
17922 1D67B;MATHEMATICAL MONOSPACE CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;
17923 1D67C;MATHEMATICAL MONOSPACE CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;
17924 1D67D;MATHEMATICAL MONOSPACE CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;
17925 1D67E;MATHEMATICAL MONOSPACE CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;
17926 1D67F;MATHEMATICAL MONOSPACE CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;
17927 1D680;MATHEMATICAL MONOSPACE CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;
17928 1D681;MATHEMATICAL MONOSPACE CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;
17929 1D682;MATHEMATICAL MONOSPACE CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;
17930 1D683;MATHEMATICAL MONOSPACE CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;
17931 1D684;MATHEMATICAL MONOSPACE CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;
17932 1D685;MATHEMATICAL MONOSPACE CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;
17933 1D686;MATHEMATICAL MONOSPACE CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;
17934 1D687;MATHEMATICAL MONOSPACE CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;
17935 1D688;MATHEMATICAL MONOSPACE CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;
17936 1D689;MATHEMATICAL MONOSPACE CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;
17937 1D68A;MATHEMATICAL MONOSPACE SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;
17938 1D68B;MATHEMATICAL MONOSPACE SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;
17939 1D68C;MATHEMATICAL MONOSPACE SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;
17940 1D68D;MATHEMATICAL MONOSPACE SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;
17941 1D68E;MATHEMATICAL MONOSPACE SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;
17942 1D68F;MATHEMATICAL MONOSPACE SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;
17943 1D690;MATHEMATICAL MONOSPACE SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;
17944 1D691;MATHEMATICAL MONOSPACE SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;
17945 1D692;MATHEMATICAL MONOSPACE SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;
17946 1D693;MATHEMATICAL MONOSPACE SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;
17947 1D694;MATHEMATICAL MONOSPACE SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;
17948 1D695;MATHEMATICAL MONOSPACE SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;
17949 1D696;MATHEMATICAL MONOSPACE SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;
17950 1D697;MATHEMATICAL MONOSPACE SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;
17951 1D698;MATHEMATICAL MONOSPACE SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;
17952 1D699;MATHEMATICAL MONOSPACE SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;
17953 1D69A;MATHEMATICAL MONOSPACE SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;
17954 1D69B;MATHEMATICAL MONOSPACE SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;
17955 1D69C;MATHEMATICAL MONOSPACE SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;
17956 1D69D;MATHEMATICAL MONOSPACE SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;
17957 1D69E;MATHEMATICAL MONOSPACE SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;
17958 1D69F;MATHEMATICAL MONOSPACE SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;
17959 1D6A0;MATHEMATICAL MONOSPACE SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;
17960 1D6A1;MATHEMATICAL MONOSPACE SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;
17961 1D6A2;MATHEMATICAL MONOSPACE SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;
17962 1D6A3;MATHEMATICAL MONOSPACE SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;
17963 1D6A4;MATHEMATICAL ITALIC SMALL DOTLESS I;Ll;0;L;<font> 0131;;;;N;;;;;
17964 1D6A5;MATHEMATICAL ITALIC SMALL DOTLESS J;Ll;0;L;<font> 0237;;;;N;;;;;
17965 1D6A8;MATHEMATICAL BOLD CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
17966 1D6A9;MATHEMATICAL BOLD CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
17967 1D6AA;MATHEMATICAL BOLD CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
17968 1D6AB;MATHEMATICAL BOLD CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
17969 1D6AC;MATHEMATICAL BOLD CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
17970 1D6AD;MATHEMATICAL BOLD CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
17971 1D6AE;MATHEMATICAL BOLD CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
17972 1D6AF;MATHEMATICAL BOLD CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
17973 1D6B0;MATHEMATICAL BOLD CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
17974 1D6B1;MATHEMATICAL BOLD CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
17975 1D6B2;MATHEMATICAL BOLD CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
17976 1D6B3;MATHEMATICAL BOLD CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
17977 1D6B4;MATHEMATICAL BOLD CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
17978 1D6B5;MATHEMATICAL BOLD CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
17979 1D6B6;MATHEMATICAL BOLD CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
17980 1D6B7;MATHEMATICAL BOLD CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
17981 1D6B8;MATHEMATICAL BOLD CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
17982 1D6B9;MATHEMATICAL BOLD CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
17983 1D6BA;MATHEMATICAL BOLD CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
17984 1D6BB;MATHEMATICAL BOLD CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
17985 1D6BC;MATHEMATICAL BOLD CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
17986 1D6BD;MATHEMATICAL BOLD CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
17987 1D6BE;MATHEMATICAL BOLD CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
17988 1D6BF;MATHEMATICAL BOLD CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
17989 1D6C0;MATHEMATICAL BOLD CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
17990 1D6C1;MATHEMATICAL BOLD NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
17991 1D6C2;MATHEMATICAL BOLD SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
17992 1D6C3;MATHEMATICAL BOLD SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
17993 1D6C4;MATHEMATICAL BOLD SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
17994 1D6C5;MATHEMATICAL BOLD SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
17995 1D6C6;MATHEMATICAL BOLD SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
17996 1D6C7;MATHEMATICAL BOLD SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
17997 1D6C8;MATHEMATICAL BOLD SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
17998 1D6C9;MATHEMATICAL BOLD SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
17999 1D6CA;MATHEMATICAL BOLD SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
18000 1D6CB;MATHEMATICAL BOLD SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
18001 1D6CC;MATHEMATICAL BOLD SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
18002 1D6CD;MATHEMATICAL BOLD SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
18003 1D6CE;MATHEMATICAL BOLD SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
18004 1D6CF;MATHEMATICAL BOLD SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
18005 1D6D0;MATHEMATICAL BOLD SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
18006 1D6D1;MATHEMATICAL BOLD SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
18007 1D6D2;MATHEMATICAL BOLD SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
18008 1D6D3;MATHEMATICAL BOLD SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
18009 1D6D4;MATHEMATICAL BOLD SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
18010 1D6D5;MATHEMATICAL BOLD SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
18011 1D6D6;MATHEMATICAL BOLD SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
18012 1D6D7;MATHEMATICAL BOLD SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
18013 1D6D8;MATHEMATICAL BOLD SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
18014 1D6D9;MATHEMATICAL BOLD SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
18015 1D6DA;MATHEMATICAL BOLD SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
18016 1D6DB;MATHEMATICAL BOLD PARTIAL DIFFERENTIAL;Sm;0;L;<font> 2202;;;;Y;;;;;
18017 1D6DC;MATHEMATICAL BOLD EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
18018 1D6DD;MATHEMATICAL BOLD THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
18019 1D6DE;MATHEMATICAL BOLD KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
18020 1D6DF;MATHEMATICAL BOLD PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
18021 1D6E0;MATHEMATICAL BOLD RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
18022 1D6E1;MATHEMATICAL BOLD PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
18023 1D6E2;MATHEMATICAL ITALIC CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
18024 1D6E3;MATHEMATICAL ITALIC CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
18025 1D6E4;MATHEMATICAL ITALIC CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
18026 1D6E5;MATHEMATICAL ITALIC CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
18027 1D6E6;MATHEMATICAL ITALIC CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
18028 1D6E7;MATHEMATICAL ITALIC CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
18029 1D6E8;MATHEMATICAL ITALIC CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
18030 1D6E9;MATHEMATICAL ITALIC CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
18031 1D6EA;MATHEMATICAL ITALIC CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
18032 1D6EB;MATHEMATICAL ITALIC CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
18033 1D6EC;MATHEMATICAL ITALIC CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
18034 1D6ED;MATHEMATICAL ITALIC CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
18035 1D6EE;MATHEMATICAL ITALIC CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
18036 1D6EF;MATHEMATICAL ITALIC CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
18037 1D6F0;MATHEMATICAL ITALIC CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
18038 1D6F1;MATHEMATICAL ITALIC CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
18039 1D6F2;MATHEMATICAL ITALIC CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
18040 1D6F3;MATHEMATICAL ITALIC CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
18041 1D6F4;MATHEMATICAL ITALIC CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
18042 1D6F5;MATHEMATICAL ITALIC CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
18043 1D6F6;MATHEMATICAL ITALIC CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
18044 1D6F7;MATHEMATICAL ITALIC CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
18045 1D6F8;MATHEMATICAL ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
18046 1D6F9;MATHEMATICAL ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
18047 1D6FA;MATHEMATICAL ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
18048 1D6FB;MATHEMATICAL ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
18049 1D6FC;MATHEMATICAL ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
18050 1D6FD;MATHEMATICAL ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
18051 1D6FE;MATHEMATICAL ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
18052 1D6FF;MATHEMATICAL ITALIC SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
18053 1D700;MATHEMATICAL ITALIC SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
18054 1D701;MATHEMATICAL ITALIC SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
18055 1D702;MATHEMATICAL ITALIC SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
18056 1D703;MATHEMATICAL ITALIC SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
18057 1D704;MATHEMATICAL ITALIC SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
18058 1D705;MATHEMATICAL ITALIC SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
18059 1D706;MATHEMATICAL ITALIC SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
18060 1D707;MATHEMATICAL ITALIC SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
18061 1D708;MATHEMATICAL ITALIC SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
18062 1D709;MATHEMATICAL ITALIC SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
18063 1D70A;MATHEMATICAL ITALIC SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
18064 1D70B;MATHEMATICAL ITALIC SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
18065 1D70C;MATHEMATICAL ITALIC SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
18066 1D70D;MATHEMATICAL ITALIC SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
18067 1D70E;MATHEMATICAL ITALIC SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
18068 1D70F;MATHEMATICAL ITALIC SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
18069 1D710;MATHEMATICAL ITALIC SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
18070 1D711;MATHEMATICAL ITALIC SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
18071 1D712;MATHEMATICAL ITALIC SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
18072 1D713;MATHEMATICAL ITALIC SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
18073 1D714;MATHEMATICAL ITALIC SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
18074 1D715;MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL;Sm;0;L;<font> 2202;;;;Y;;;;;
18075 1D716;MATHEMATICAL ITALIC EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
18076 1D717;MATHEMATICAL ITALIC THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
18077 1D718;MATHEMATICAL ITALIC KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
18078 1D719;MATHEMATICAL ITALIC PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
18079 1D71A;MATHEMATICAL ITALIC RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
18080 1D71B;MATHEMATICAL ITALIC PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
18081 1D71C;MATHEMATICAL BOLD ITALIC CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
18082 1D71D;MATHEMATICAL BOLD ITALIC CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
18083 1D71E;MATHEMATICAL BOLD ITALIC CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
18084 1D71F;MATHEMATICAL BOLD ITALIC CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
18085 1D720;MATHEMATICAL BOLD ITALIC CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
18086 1D721;MATHEMATICAL BOLD ITALIC CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
18087 1D722;MATHEMATICAL BOLD ITALIC CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
18088 1D723;MATHEMATICAL BOLD ITALIC CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
18089 1D724;MATHEMATICAL BOLD ITALIC CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
18090 1D725;MATHEMATICAL BOLD ITALIC CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
18091 1D726;MATHEMATICAL BOLD ITALIC CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
18092 1D727;MATHEMATICAL BOLD ITALIC CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
18093 1D728;MATHEMATICAL BOLD ITALIC CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
18094 1D729;MATHEMATICAL BOLD ITALIC CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
18095 1D72A;MATHEMATICAL BOLD ITALIC CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
18096 1D72B;MATHEMATICAL BOLD ITALIC CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
18097 1D72C;MATHEMATICAL BOLD ITALIC CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
18098 1D72D;MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
18099 1D72E;MATHEMATICAL BOLD ITALIC CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
18100 1D72F;MATHEMATICAL BOLD ITALIC CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
18101 1D730;MATHEMATICAL BOLD ITALIC CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
18102 1D731;MATHEMATICAL BOLD ITALIC CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
18103 1D732;MATHEMATICAL BOLD ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
18104 1D733;MATHEMATICAL BOLD ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
18105 1D734;MATHEMATICAL BOLD ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
18106 1D735;MATHEMATICAL BOLD ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
18107 1D736;MATHEMATICAL BOLD ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
18108 1D737;MATHEMATICAL BOLD ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
18109 1D738;MATHEMATICAL BOLD ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
18110 1D739;MATHEMATICAL BOLD ITALIC SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
18111 1D73A;MATHEMATICAL BOLD ITALIC SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
18112 1D73B;MATHEMATICAL BOLD ITALIC SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
18113 1D73C;MATHEMATICAL BOLD ITALIC SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
18114 1D73D;MATHEMATICAL BOLD ITALIC SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
18115 1D73E;MATHEMATICAL BOLD ITALIC SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
18116 1D73F;MATHEMATICAL BOLD ITALIC SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
18117 1D740;MATHEMATICAL BOLD ITALIC SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
18118 1D741;MATHEMATICAL BOLD ITALIC SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
18119 1D742;MATHEMATICAL BOLD ITALIC SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
18120 1D743;MATHEMATICAL BOLD ITALIC SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
18121 1D744;MATHEMATICAL BOLD ITALIC SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
18122 1D745;MATHEMATICAL BOLD ITALIC SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
18123 1D746;MATHEMATICAL BOLD ITALIC SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
18124 1D747;MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
18125 1D748;MATHEMATICAL BOLD ITALIC SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
18126 1D749;MATHEMATICAL BOLD ITALIC SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
18127 1D74A;MATHEMATICAL BOLD ITALIC SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
18128 1D74B;MATHEMATICAL BOLD ITALIC SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
18129 1D74C;MATHEMATICAL BOLD ITALIC SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
18130 1D74D;MATHEMATICAL BOLD ITALIC SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
18131 1D74E;MATHEMATICAL BOLD ITALIC SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
18132 1D74F;MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;L;<font> 2202;;;;Y;;;;;
18133 1D750;MATHEMATICAL BOLD ITALIC EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
18134 1D751;MATHEMATICAL BOLD ITALIC THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
18135 1D752;MATHEMATICAL BOLD ITALIC KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
18136 1D753;MATHEMATICAL BOLD ITALIC PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
18137 1D754;MATHEMATICAL BOLD ITALIC RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
18138 1D755;MATHEMATICAL BOLD ITALIC PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
18139 1D756;MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
18140 1D757;MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
18141 1D758;MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
18142 1D759;MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
18143 1D75A;MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
18144 1D75B;MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
18145 1D75C;MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
18146 1D75D;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
18147 1D75E;MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
18148 1D75F;MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
18149 1D760;MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
18150 1D761;MATHEMATICAL SANS-SERIF BOLD CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
18151 1D762;MATHEMATICAL SANS-SERIF BOLD CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
18152 1D763;MATHEMATICAL SANS-SERIF BOLD CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
18153 1D764;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
18154 1D765;MATHEMATICAL SANS-SERIF BOLD CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
18155 1D766;MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
18156 1D767;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
18157 1D768;MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
18158 1D769;MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
18159 1D76A;MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
18160 1D76B;MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
18161 1D76C;MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
18162 1D76D;MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
18163 1D76E;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
18164 1D76F;MATHEMATICAL SANS-SERIF BOLD NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
18165 1D770;MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
18166 1D771;MATHEMATICAL SANS-SERIF BOLD SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
18167 1D772;MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
18168 1D773;MATHEMATICAL SANS-SERIF BOLD SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
18169 1D774;MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
18170 1D775;MATHEMATICAL SANS-SERIF BOLD SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
18171 1D776;MATHEMATICAL SANS-SERIF BOLD SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
18172 1D777;MATHEMATICAL SANS-SERIF BOLD SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
18173 1D778;MATHEMATICAL SANS-SERIF BOLD SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
18174 1D779;MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
18175 1D77A;MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
18176 1D77B;MATHEMATICAL SANS-SERIF BOLD SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
18177 1D77C;MATHEMATICAL SANS-SERIF BOLD SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
18178 1D77D;MATHEMATICAL SANS-SERIF BOLD SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
18179 1D77E;MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
18180 1D77F;MATHEMATICAL SANS-SERIF BOLD SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
18181 1D780;MATHEMATICAL SANS-SERIF BOLD SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
18182 1D781;MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
18183 1D782;MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
18184 1D783;MATHEMATICAL SANS-SERIF BOLD SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
18185 1D784;MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
18186 1D785;MATHEMATICAL SANS-SERIF BOLD SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
18187 1D786;MATHEMATICAL SANS-SERIF BOLD SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
18188 1D787;MATHEMATICAL SANS-SERIF BOLD SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
18189 1D788;MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
18190 1D789;MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL;Sm;0;L;<font> 2202;;;;Y;;;;;
18191 1D78A;MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
18192 1D78B;MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
18193 1D78C;MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
18194 1D78D;MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
18195 1D78E;MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
18196 1D78F;MATHEMATICAL SANS-SERIF BOLD PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
18197 1D790;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;
18198 1D791;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;
18199 1D792;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;
18200 1D793;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;
18201 1D794;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;
18202 1D795;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;
18203 1D796;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;
18204 1D797;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;
18205 1D798;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;
18206 1D799;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;
18207 1D79A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;
18208 1D79B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;
18209 1D79C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;
18210 1D79D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;
18211 1D79E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;
18212 1D79F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;
18213 1D7A0;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;
18214 1D7A1;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;
18215 1D7A2;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;
18216 1D7A3;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;
18217 1D7A4;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;
18218 1D7A5;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;
18219 1D7A6;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;
18220 1D7A7;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;
18221 1D7A8;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;
18222 1D7A9;MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;;
18223 1D7AA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;
18224 1D7AB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;
18225 1D7AC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;
18226 1D7AD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;
18227 1D7AE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;
18228 1D7AF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;
18229 1D7B0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;
18230 1D7B1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;
18231 1D7B2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;
18232 1D7B3;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;
18233 1D7B4;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;
18234 1D7B5;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;
18235 1D7B6;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;
18236 1D7B7;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;
18237 1D7B8;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;
18238 1D7B9;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;
18239 1D7BA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;
18240 1D7BB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;
18241 1D7BC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;
18242 1D7BD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;
18243 1D7BE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;
18244 1D7BF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;
18245 1D7C0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;
18246 1D7C1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;
18247 1D7C2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;
18248 1D7C3;MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;L;<font> 2202;;;;Y;;;;;
18249 1D7C4;MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;
18250 1D7C5;MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;
18251 1D7C6;MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;
18252 1D7C7;MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;
18253 1D7C8;MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;
18254 1D7C9;MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;
18255 1D7CA;MATHEMATICAL BOLD CAPITAL DIGAMMA;Lu;0;L;<font> 03DC;;;;N;;;;;
18256 1D7CB;MATHEMATICAL BOLD SMALL DIGAMMA;Ll;0;L;<font> 03DD;;;;N;;;;;
18257 1D7CE;MATHEMATICAL BOLD DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
18258 1D7CF;MATHEMATICAL BOLD DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
18259 1D7D0;MATHEMATICAL BOLD DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
18260 1D7D1;MATHEMATICAL BOLD DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
18261 1D7D2;MATHEMATICAL BOLD DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
18262 1D7D3;MATHEMATICAL BOLD DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
18263 1D7D4;MATHEMATICAL BOLD DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
18264 1D7D5;MATHEMATICAL BOLD DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
18265 1D7D6;MATHEMATICAL BOLD DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
18266 1D7D7;MATHEMATICAL BOLD DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
18267 1D7D8;MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
18268 1D7D9;MATHEMATICAL DOUBLE-STRUCK DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
18269 1D7DA;MATHEMATICAL DOUBLE-STRUCK DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
18270 1D7DB;MATHEMATICAL DOUBLE-STRUCK DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
18271 1D7DC;MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
18272 1D7DD;MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
18273 1D7DE;MATHEMATICAL DOUBLE-STRUCK DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
18274 1D7DF;MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
18275 1D7E0;MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
18276 1D7E1;MATHEMATICAL DOUBLE-STRUCK DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
18277 1D7E2;MATHEMATICAL SANS-SERIF DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
18278 1D7E3;MATHEMATICAL SANS-SERIF DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
18279 1D7E4;MATHEMATICAL SANS-SERIF DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
18280 1D7E5;MATHEMATICAL SANS-SERIF DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
18281 1D7E6;MATHEMATICAL SANS-SERIF DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
18282 1D7E7;MATHEMATICAL SANS-SERIF DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
18283 1D7E8;MATHEMATICAL SANS-SERIF DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
18284 1D7E9;MATHEMATICAL SANS-SERIF DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
18285 1D7EA;MATHEMATICAL SANS-SERIF DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
18286 1D7EB;MATHEMATICAL SANS-SERIF DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
18287 1D7EC;MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
18288 1D7ED;MATHEMATICAL SANS-SERIF BOLD DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
18289 1D7EE;MATHEMATICAL SANS-SERIF BOLD DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
18290 1D7EF;MATHEMATICAL SANS-SERIF BOLD DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
18291 1D7F0;MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
18292 1D7F1;MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
18293 1D7F2;MATHEMATICAL SANS-SERIF BOLD DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
18294 1D7F3;MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
18295 1D7F4;MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
18296 1D7F5;MATHEMATICAL SANS-SERIF BOLD DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
18297 1D7F6;MATHEMATICAL MONOSPACE DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;
18298 1D7F7;MATHEMATICAL MONOSPACE DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;
18299 1D7F8;MATHEMATICAL MONOSPACE DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;
18300 1D7F9;MATHEMATICAL MONOSPACE DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;
18301 1D7FA;MATHEMATICAL MONOSPACE DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;
18302 1D7FB;MATHEMATICAL MONOSPACE DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;
18303 1D7FC;MATHEMATICAL MONOSPACE DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;
18304 1D7FD;MATHEMATICAL MONOSPACE DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;
18305 1D7FE;MATHEMATICAL MONOSPACE DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;
18306 1D7FF;MATHEMATICAL MONOSPACE DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;
18307 1F000;MAHJONG TILE EAST WIND;So;0;ON;;;;;N;;;;;
18308 1F001;MAHJONG TILE SOUTH WIND;So;0;ON;;;;;N;;;;;
18309 1F002;MAHJONG TILE WEST WIND;So;0;ON;;;;;N;;;;;
18310 1F003;MAHJONG TILE NORTH WIND;So;0;ON;;;;;N;;;;;
18311 1F004;MAHJONG TILE RED DRAGON;So;0;ON;;;;;N;;;;;
18312 1F005;MAHJONG TILE GREEN DRAGON;So;0;ON;;;;;N;;;;;
18313 1F006;MAHJONG TILE WHITE DRAGON;So;0;ON;;;;;N;;;;;
18314 1F007;MAHJONG TILE ONE OF CHARACTERS;So;0;ON;;;;;N;;;;;
18315 1F008;MAHJONG TILE TWO OF CHARACTERS;So;0;ON;;;;;N;;;;;
18316 1F009;MAHJONG TILE THREE OF CHARACTERS;So;0;ON;;;;;N;;;;;
18317 1F00A;MAHJONG TILE FOUR OF CHARACTERS;So;0;ON;;;;;N;;;;;
18318 1F00B;MAHJONG TILE FIVE OF CHARACTERS;So;0;ON;;;;;N;;;;;
18319 1F00C;MAHJONG TILE SIX OF CHARACTERS;So;0;ON;;;;;N;;;;;
18320 1F00D;MAHJONG TILE SEVEN OF CHARACTERS;So;0;ON;;;;;N;;;;;
18321 1F00E;MAHJONG TILE EIGHT OF CHARACTERS;So;0;ON;;;;;N;;;;;
18322 1F00F;MAHJONG TILE NINE OF CHARACTERS;So;0;ON;;;;;N;;;;;
18323 1F010;MAHJONG TILE ONE OF BAMBOOS;So;0;ON;;;;;N;;;;;
18324 1F011;MAHJONG TILE TWO OF BAMBOOS;So;0;ON;;;;;N;;;;;
18325 1F012;MAHJONG TILE THREE OF BAMBOOS;So;0;ON;;;;;N;;;;;
18326 1F013;MAHJONG TILE FOUR OF BAMBOOS;So;0;ON;;;;;N;;;;;
18327 1F014;MAHJONG TILE FIVE OF BAMBOOS;So;0;ON;;;;;N;;;;;
18328 1F015;MAHJONG TILE SIX OF BAMBOOS;So;0;ON;;;;;N;;;;;
18329 1F016;MAHJONG TILE SEVEN OF BAMBOOS;So;0;ON;;;;;N;;;;;
18330 1F017;MAHJONG TILE EIGHT OF BAMBOOS;So;0;ON;;;;;N;;;;;
18331 1F018;MAHJONG TILE NINE OF BAMBOOS;So;0;ON;;;;;N;;;;;
18332 1F019;MAHJONG TILE ONE OF CIRCLES;So;0;ON;;;;;N;;;;;
18333 1F01A;MAHJONG TILE TWO OF CIRCLES;So;0;ON;;;;;N;;;;;
18334 1F01B;MAHJONG TILE THREE OF CIRCLES;So;0;ON;;;;;N;;;;;
18335 1F01C;MAHJONG TILE FOUR OF CIRCLES;So;0;ON;;;;;N;;;;;
18336 1F01D;MAHJONG TILE FIVE OF CIRCLES;So;0;ON;;;;;N;;;;;
18337 1F01E;MAHJONG TILE SIX OF CIRCLES;So;0;ON;;;;;N;;;;;
18338 1F01F;MAHJONG TILE SEVEN OF CIRCLES;So;0;ON;;;;;N;;;;;
18339 1F020;MAHJONG TILE EIGHT OF CIRCLES;So;0;ON;;;;;N;;;;;
18340 1F021;MAHJONG TILE NINE OF CIRCLES;So;0;ON;;;;;N;;;;;
18341 1F022;MAHJONG TILE PLUM;So;0;ON;;;;;N;;;;;
18342 1F023;MAHJONG TILE ORCHID;So;0;ON;;;;;N;;;;;
18343 1F024;MAHJONG TILE BAMBOO;So;0;ON;;;;;N;;;;;
18344 1F025;MAHJONG TILE CHRYSANTHEMUM;So;0;ON;;;;;N;;;;;
18345 1F026;MAHJONG TILE SPRING;So;0;ON;;;;;N;;;;;
18346 1F027;MAHJONG TILE SUMMER;So;0;ON;;;;;N;;;;;
18347 1F028;MAHJONG TILE AUTUMN;So;0;ON;;;;;N;;;;;
18348 1F029;MAHJONG TILE WINTER;So;0;ON;;;;;N;;;;;
18349 1F02A;MAHJONG TILE JOKER;So;0;ON;;;;;N;;;;;
18350 1F02B;MAHJONG TILE BACK;So;0;ON;;;;;N;;;;;
18351 1F030;DOMINO TILE HORIZONTAL BACK;So;0;ON;;;;;N;;;;;
18352 1F031;DOMINO TILE HORIZONTAL-00-00;So;0;ON;;;;;N;;;;;
18353 1F032;DOMINO TILE HORIZONTAL-00-01;So;0;ON;;;;;N;;;;;
18354 1F033;DOMINO TILE HORIZONTAL-00-02;So;0;ON;;;;;N;;;;;
18355 1F034;DOMINO TILE HORIZONTAL-00-03;So;0;ON;;;;;N;;;;;
18356 1F035;DOMINO TILE HORIZONTAL-00-04;So;0;ON;;;;;N;;;;;
18357 1F036;DOMINO TILE HORIZONTAL-00-05;So;0;ON;;;;;N;;;;;
18358 1F037;DOMINO TILE HORIZONTAL-00-06;So;0;ON;;;;;N;;;;;
18359 1F038;DOMINO TILE HORIZONTAL-01-00;So;0;ON;;;;;N;;;;;
18360 1F039;DOMINO TILE HORIZONTAL-01-01;So;0;ON;;;;;N;;;;;
18361 1F03A;DOMINO TILE HORIZONTAL-01-02;So;0;ON;;;;;N;;;;;
18362 1F03B;DOMINO TILE HORIZONTAL-01-03;So;0;ON;;;;;N;;;;;
18363 1F03C;DOMINO TILE HORIZONTAL-01-04;So;0;ON;;;;;N;;;;;
18364 1F03D;DOMINO TILE HORIZONTAL-01-05;So;0;ON;;;;;N;;;;;
18365 1F03E;DOMINO TILE HORIZONTAL-01-06;So;0;ON;;;;;N;;;;;
18366 1F03F;DOMINO TILE HORIZONTAL-02-00;So;0;ON;;;;;N;;;;;
18367 1F040;DOMINO TILE HORIZONTAL-02-01;So;0;ON;;;;;N;;;;;
18368 1F041;DOMINO TILE HORIZONTAL-02-02;So;0;ON;;;;;N;;;;;
18369 1F042;DOMINO TILE HORIZONTAL-02-03;So;0;ON;;;;;N;;;;;
18370 1F043;DOMINO TILE HORIZONTAL-02-04;So;0;ON;;;;;N;;;;;
18371 1F044;DOMINO TILE HORIZONTAL-02-05;So;0;ON;;;;;N;;;;;
18372 1F045;DOMINO TILE HORIZONTAL-02-06;So;0;ON;;;;;N;;;;;
18373 1F046;DOMINO TILE HORIZONTAL-03-00;So;0;ON;;;;;N;;;;;
18374 1F047;DOMINO TILE HORIZONTAL-03-01;So;0;ON;;;;;N;;;;;
18375 1F048;DOMINO TILE HORIZONTAL-03-02;So;0;ON;;;;;N;;;;;
18376 1F049;DOMINO TILE HORIZONTAL-03-03;So;0;ON;;;;;N;;;;;
18377 1F04A;DOMINO TILE HORIZONTAL-03-04;So;0;ON;;;;;N;;;;;
18378 1F04B;DOMINO TILE HORIZONTAL-03-05;So;0;ON;;;;;N;;;;;
18379 1F04C;DOMINO TILE HORIZONTAL-03-06;So;0;ON;;;;;N;;;;;
18380 1F04D;DOMINO TILE HORIZONTAL-04-00;So;0;ON;;;;;N;;;;;
18381 1F04E;DOMINO TILE HORIZONTAL-04-01;So;0;ON;;;;;N;;;;;
18382 1F04F;DOMINO TILE HORIZONTAL-04-02;So;0;ON;;;;;N;;;;;
18383 1F050;DOMINO TILE HORIZONTAL-04-03;So;0;ON;;;;;N;;;;;
18384 1F051;DOMINO TILE HORIZONTAL-04-04;So;0;ON;;;;;N;;;;;
18385 1F052;DOMINO TILE HORIZONTAL-04-05;So;0;ON;;;;;N;;;;;
18386 1F053;DOMINO TILE HORIZONTAL-04-06;So;0;ON;;;;;N;;;;;
18387 1F054;DOMINO TILE HORIZONTAL-05-00;So;0;ON;;;;;N;;;;;
18388 1F055;DOMINO TILE HORIZONTAL-05-01;So;0;ON;;;;;N;;;;;
18389 1F056;DOMINO TILE HORIZONTAL-05-02;So;0;ON;;;;;N;;;;;
18390 1F057;DOMINO TILE HORIZONTAL-05-03;So;0;ON;;;;;N;;;;;
18391 1F058;DOMINO TILE HORIZONTAL-05-04;So;0;ON;;;;;N;;;;;
18392 1F059;DOMINO TILE HORIZONTAL-05-05;So;0;ON;;;;;N;;;;;
18393 1F05A;DOMINO TILE HORIZONTAL-05-06;So;0;ON;;;;;N;;;;;
18394 1F05B;DOMINO TILE HORIZONTAL-06-00;So;0;ON;;;;;N;;;;;
18395 1F05C;DOMINO TILE HORIZONTAL-06-01;So;0;ON;;;;;N;;;;;
18396 1F05D;DOMINO TILE HORIZONTAL-06-02;So;0;ON;;;;;N;;;;;
18397 1F05E;DOMINO TILE HORIZONTAL-06-03;So;0;ON;;;;;N;;;;;
18398 1F05F;DOMINO TILE HORIZONTAL-06-04;So;0;ON;;;;;N;;;;;
18399 1F060;DOMINO TILE HORIZONTAL-06-05;So;0;ON;;;;;N;;;;;
18400 1F061;DOMINO TILE HORIZONTAL-06-06;So;0;ON;;;;;N;;;;;
18401 1F062;DOMINO TILE VERTICAL BACK;So;0;ON;;;;;N;;;;;
18402 1F063;DOMINO TILE VERTICAL-00-00;So;0;ON;;;;;N;;;;;
18403 1F064;DOMINO TILE VERTICAL-00-01;So;0;ON;;;;;N;;;;;
18404 1F065;DOMINO TILE VERTICAL-00-02;So;0;ON;;;;;N;;;;;
18405 1F066;DOMINO TILE VERTICAL-00-03;So;0;ON;;;;;N;;;;;
18406 1F067;DOMINO TILE VERTICAL-00-04;So;0;ON;;;;;N;;;;;
18407 1F068;DOMINO TILE VERTICAL-00-05;So;0;ON;;;;;N;;;;;
18408 1F069;DOMINO TILE VERTICAL-00-06;So;0;ON;;;;;N;;;;;
18409 1F06A;DOMINO TILE VERTICAL-01-00;So;0;ON;;;;;N;;;;;
18410 1F06B;DOMINO TILE VERTICAL-01-01;So;0;ON;;;;;N;;;;;
18411 1F06C;DOMINO TILE VERTICAL-01-02;So;0;ON;;;;;N;;;;;
18412 1F06D;DOMINO TILE VERTICAL-01-03;So;0;ON;;;;;N;;;;;
18413 1F06E;DOMINO TILE VERTICAL-01-04;So;0;ON;;;;;N;;;;;
18414 1F06F;DOMINO TILE VERTICAL-01-05;So;0;ON;;;;;N;;;;;
18415 1F070;DOMINO TILE VERTICAL-01-06;So;0;ON;;;;;N;;;;;
18416 1F071;DOMINO TILE VERTICAL-02-00;So;0;ON;;;;;N;;;;;
18417 1F072;DOMINO TILE VERTICAL-02-01;So;0;ON;;;;;N;;;;;
18418 1F073;DOMINO TILE VERTICAL-02-02;So;0;ON;;;;;N;;;;;
18419 1F074;DOMINO TILE VERTICAL-02-03;So;0;ON;;;;;N;;;;;
18420 1F075;DOMINO TILE VERTICAL-02-04;So;0;ON;;;;;N;;;;;
18421 1F076;DOMINO TILE VERTICAL-02-05;So;0;ON;;;;;N;;;;;
18422 1F077;DOMINO TILE VERTICAL-02-06;So;0;ON;;;;;N;;;;;
18423 1F078;DOMINO TILE VERTICAL-03-00;So;0;ON;;;;;N;;;;;
18424 1F079;DOMINO TILE VERTICAL-03-01;So;0;ON;;;;;N;;;;;
18425 1F07A;DOMINO TILE VERTICAL-03-02;So;0;ON;;;;;N;;;;;
18426 1F07B;DOMINO TILE VERTICAL-03-03;So;0;ON;;;;;N;;;;;
18427 1F07C;DOMINO TILE VERTICAL-03-04;So;0;ON;;;;;N;;;;;
18428 1F07D;DOMINO TILE VERTICAL-03-05;So;0;ON;;;;;N;;;;;
18429 1F07E;DOMINO TILE VERTICAL-03-06;So;0;ON;;;;;N;;;;;
18430 1F07F;DOMINO TILE VERTICAL-04-00;So;0;ON;;;;;N;;;;;
18431 1F080;DOMINO TILE VERTICAL-04-01;So;0;ON;;;;;N;;;;;
18432 1F081;DOMINO TILE VERTICAL-04-02;So;0;ON;;;;;N;;;;;
18433 1F082;DOMINO TILE VERTICAL-04-03;So;0;ON;;;;;N;;;;;
18434 1F083;DOMINO TILE VERTICAL-04-04;So;0;ON;;;;;N;;;;;
18435 1F084;DOMINO TILE VERTICAL-04-05;So;0;ON;;;;;N;;;;;
18436 1F085;DOMINO TILE VERTICAL-04-06;So;0;ON;;;;;N;;;;;
18437 1F086;DOMINO TILE VERTICAL-05-00;So;0;ON;;;;;N;;;;;
18438 1F087;DOMINO TILE VERTICAL-05-01;So;0;ON;;;;;N;;;;;
18439 1F088;DOMINO TILE VERTICAL-05-02;So;0;ON;;;;;N;;;;;
18440 1F089;DOMINO TILE VERTICAL-05-03;So;0;ON;;;;;N;;;;;
18441 1F08A;DOMINO TILE VERTICAL-05-04;So;0;ON;;;;;N;;;;;
18442 1F08B;DOMINO TILE VERTICAL-05-05;So;0;ON;;;;;N;;;;;
18443 1F08C;DOMINO TILE VERTICAL-05-06;So;0;ON;;;;;N;;;;;
18444 1F08D;DOMINO TILE VERTICAL-06-00;So;0;ON;;;;;N;;;;;
18445 1F08E;DOMINO TILE VERTICAL-06-01;So;0;ON;;;;;N;;;;;
18446 1F08F;DOMINO TILE VERTICAL-06-02;So;0;ON;;;;;N;;;;;
18447 1F090;DOMINO TILE VERTICAL-06-03;So;0;ON;;;;;N;;;;;
18448 1F091;DOMINO TILE VERTICAL-06-04;So;0;ON;;;;;N;;;;;
18449 1F092;DOMINO TILE VERTICAL-06-05;So;0;ON;;;;;N;;;;;
18450 1F093;DOMINO TILE VERTICAL-06-06;So;0;ON;;;;;N;;;;;
18451 20000;<CJK Ideograph Extension B, First>;Lo;0;L;;;;;N;;;;;
18452 2A6D6;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;;
18453 2F800;CJK COMPATIBILITY IDEOGRAPH-2F800;Lo;0;L;4E3D;;;;N;;;;;
18454 2F801;CJK COMPATIBILITY IDEOGRAPH-2F801;Lo;0;L;4E38;;;;N;;;;;
18455 2F802;CJK COMPATIBILITY IDEOGRAPH-2F802;Lo;0;L;4E41;;;;N;;;;;
18456 2F803;CJK COMPATIBILITY IDEOGRAPH-2F803;Lo;0;L;20122;;;;N;;;;;
18457 2F804;CJK COMPATIBILITY IDEOGRAPH-2F804;Lo;0;L;4F60;;;;N;;;;;
18458 2F805;CJK COMPATIBILITY IDEOGRAPH-2F805;Lo;0;L;4FAE;;;;N;;;;;
18459 2F806;CJK COMPATIBILITY IDEOGRAPH-2F806;Lo;0;L;4FBB;;;;N;;;;;
18460 2F807;CJK COMPATIBILITY IDEOGRAPH-2F807;Lo;0;L;5002;;;;N;;;;;
18461 2F808;CJK COMPATIBILITY IDEOGRAPH-2F808;Lo;0;L;507A;;;;N;;;;;
18462 2F809;CJK COMPATIBILITY IDEOGRAPH-2F809;Lo;0;L;5099;;;;N;;;;;
18463 2F80A;CJK COMPATIBILITY IDEOGRAPH-2F80A;Lo;0;L;50E7;;;;N;;;;;
18464 2F80B;CJK COMPATIBILITY IDEOGRAPH-2F80B;Lo;0;L;50CF;;;;N;;;;;
18465 2F80C;CJK COMPATIBILITY IDEOGRAPH-2F80C;Lo;0;L;349E;;;;N;;;;;
18466 2F80D;CJK COMPATIBILITY IDEOGRAPH-2F80D;Lo;0;L;2063A;;;;N;;;;;
18467 2F80E;CJK COMPATIBILITY IDEOGRAPH-2F80E;Lo;0;L;514D;;;;N;;;;;
18468 2F80F;CJK COMPATIBILITY IDEOGRAPH-2F80F;Lo;0;L;5154;;;;N;;;;;
18469 2F810;CJK COMPATIBILITY IDEOGRAPH-2F810;Lo;0;L;5164;;;;N;;;;;
18470 2F811;CJK COMPATIBILITY IDEOGRAPH-2F811;Lo;0;L;5177;;;;N;;;;;
18471 2F812;CJK COMPATIBILITY IDEOGRAPH-2F812;Lo;0;L;2051C;;;;N;;;;;
18472 2F813;CJK COMPATIBILITY IDEOGRAPH-2F813;Lo;0;L;34B9;;;;N;;;;;
18473 2F814;CJK COMPATIBILITY IDEOGRAPH-2F814;Lo;0;L;5167;;;;N;;;;;
18474 2F815;CJK COMPATIBILITY IDEOGRAPH-2F815;Lo;0;L;518D;;;;N;;;;;
18475 2F816;CJK COMPATIBILITY IDEOGRAPH-2F816;Lo;0;L;2054B;;;;N;;;;;
18476 2F817;CJK COMPATIBILITY IDEOGRAPH-2F817;Lo;0;L;5197;;;;N;;;;;
18477 2F818;CJK COMPATIBILITY IDEOGRAPH-2F818;Lo;0;L;51A4;;;;N;;;;;
18478 2F819;CJK COMPATIBILITY IDEOGRAPH-2F819;Lo;0;L;4ECC;;;;N;;;;;
18479 2F81A;CJK COMPATIBILITY IDEOGRAPH-2F81A;Lo;0;L;51AC;;;;N;;;;;
18480 2F81B;CJK COMPATIBILITY IDEOGRAPH-2F81B;Lo;0;L;51B5;;;;N;;;;;
18481 2F81C;CJK COMPATIBILITY IDEOGRAPH-2F81C;Lo;0;L;291DF;;;;N;;;;;
18482 2F81D;CJK COMPATIBILITY IDEOGRAPH-2F81D;Lo;0;L;51F5;;;;N;;;;;
18483 2F81E;CJK COMPATIBILITY IDEOGRAPH-2F81E;Lo;0;L;5203;;;;N;;;;;
18484 2F81F;CJK COMPATIBILITY IDEOGRAPH-2F81F;Lo;0;L;34DF;;;;N;;;;;
18485 2F820;CJK COMPATIBILITY IDEOGRAPH-2F820;Lo;0;L;523B;;;;N;;;;;
18486 2F821;CJK COMPATIBILITY IDEOGRAPH-2F821;Lo;0;L;5246;;;;N;;;;;
18487 2F822;CJK COMPATIBILITY IDEOGRAPH-2F822;Lo;0;L;5272;;;;N;;;;;
18488 2F823;CJK COMPATIBILITY IDEOGRAPH-2F823;Lo;0;L;5277;;;;N;;;;;
18489 2F824;CJK COMPATIBILITY IDEOGRAPH-2F824;Lo;0;L;3515;;;;N;;;;;
18490 2F825;CJK COMPATIBILITY IDEOGRAPH-2F825;Lo;0;L;52C7;;;;N;;;;;
18491 2F826;CJK COMPATIBILITY IDEOGRAPH-2F826;Lo;0;L;52C9;;;;N;;;;;
18492 2F827;CJK COMPATIBILITY IDEOGRAPH-2F827;Lo;0;L;52E4;;;;N;;;;;
18493 2F828;CJK COMPATIBILITY IDEOGRAPH-2F828;Lo;0;L;52FA;;;;N;;;;;
18494 2F829;CJK COMPATIBILITY IDEOGRAPH-2F829;Lo;0;L;5305;;;;N;;;;;
18495 2F82A;CJK COMPATIBILITY IDEOGRAPH-2F82A;Lo;0;L;5306;;;;N;;;;;
18496 2F82B;CJK COMPATIBILITY IDEOGRAPH-2F82B;Lo;0;L;5317;;;;N;;;;;
18497 2F82C;CJK COMPATIBILITY IDEOGRAPH-2F82C;Lo;0;L;5349;;;;N;;;;;
18498 2F82D;CJK COMPATIBILITY IDEOGRAPH-2F82D;Lo;0;L;5351;;;;N;;;;;
18499 2F82E;CJK COMPATIBILITY IDEOGRAPH-2F82E;Lo;0;L;535A;;;;N;;;;;
18500 2F82F;CJK COMPATIBILITY IDEOGRAPH-2F82F;Lo;0;L;5373;;;;N;;;;;
18501 2F830;CJK COMPATIBILITY IDEOGRAPH-2F830;Lo;0;L;537D;;;;N;;;;;
18502 2F831;CJK COMPATIBILITY IDEOGRAPH-2F831;Lo;0;L;537F;;;;N;;;;;
18503 2F832;CJK COMPATIBILITY IDEOGRAPH-2F832;Lo;0;L;537F;;;;N;;;;;
18504 2F833;CJK COMPATIBILITY IDEOGRAPH-2F833;Lo;0;L;537F;;;;N;;;;;
18505 2F834;CJK COMPATIBILITY IDEOGRAPH-2F834;Lo;0;L;20A2C;;;;N;;;;;
18506 2F835;CJK COMPATIBILITY IDEOGRAPH-2F835;Lo;0;L;7070;;;;N;;;;;
18507 2F836;CJK COMPATIBILITY IDEOGRAPH-2F836;Lo;0;L;53CA;;;;N;;;;;
18508 2F837;CJK COMPATIBILITY IDEOGRAPH-2F837;Lo;0;L;53DF;;;;N;;;;;
18509 2F838;CJK COMPATIBILITY IDEOGRAPH-2F838;Lo;0;L;20B63;;;;N;;;;;
18510 2F839;CJK COMPATIBILITY IDEOGRAPH-2F839;Lo;0;L;53EB;;;;N;;;;;
18511 2F83A;CJK COMPATIBILITY IDEOGRAPH-2F83A;Lo;0;L;53F1;;;;N;;;;;
18512 2F83B;CJK COMPATIBILITY IDEOGRAPH-2F83B;Lo;0;L;5406;;;;N;;;;;
18513 2F83C;CJK COMPATIBILITY IDEOGRAPH-2F83C;Lo;0;L;549E;;;;N;;;;;
18514 2F83D;CJK COMPATIBILITY IDEOGRAPH-2F83D;Lo;0;L;5438;;;;N;;;;;
18515 2F83E;CJK COMPATIBILITY IDEOGRAPH-2F83E;Lo;0;L;5448;;;;N;;;;;
18516 2F83F;CJK COMPATIBILITY IDEOGRAPH-2F83F;Lo;0;L;5468;;;;N;;;;;
18517 2F840;CJK COMPATIBILITY IDEOGRAPH-2F840;Lo;0;L;54A2;;;;N;;;;;
18518 2F841;CJK COMPATIBILITY IDEOGRAPH-2F841;Lo;0;L;54F6;;;;N;;;;;
18519 2F842;CJK COMPATIBILITY IDEOGRAPH-2F842;Lo;0;L;5510;;;;N;;;;;
18520 2F843;CJK COMPATIBILITY IDEOGRAPH-2F843;Lo;0;L;5553;;;;N;;;;;
18521 2F844;CJK COMPATIBILITY IDEOGRAPH-2F844;Lo;0;L;5563;;;;N;;;;;
18522 2F845;CJK COMPATIBILITY IDEOGRAPH-2F845;Lo;0;L;5584;;;;N;;;;;
18523 2F846;CJK COMPATIBILITY IDEOGRAPH-2F846;Lo;0;L;5584;;;;N;;;;;
18524 2F847;CJK COMPATIBILITY IDEOGRAPH-2F847;Lo;0;L;5599;;;;N;;;;;
18525 2F848;CJK COMPATIBILITY IDEOGRAPH-2F848;Lo;0;L;55AB;;;;N;;;;;
18526 2F849;CJK COMPATIBILITY IDEOGRAPH-2F849;Lo;0;L;55B3;;;;N;;;;;
18527 2F84A;CJK COMPATIBILITY IDEOGRAPH-2F84A;Lo;0;L;55C2;;;;N;;;;;
18528 2F84B;CJK COMPATIBILITY IDEOGRAPH-2F84B;Lo;0;L;5716;;;;N;;;;;
18529 2F84C;CJK COMPATIBILITY IDEOGRAPH-2F84C;Lo;0;L;5606;;;;N;;;;;
18530 2F84D;CJK COMPATIBILITY IDEOGRAPH-2F84D;Lo;0;L;5717;;;;N;;;;;
18531 2F84E;CJK COMPATIBILITY IDEOGRAPH-2F84E;Lo;0;L;5651;;;;N;;;;;
18532 2F84F;CJK COMPATIBILITY IDEOGRAPH-2F84F;Lo;0;L;5674;;;;N;;;;;
18533 2F850;CJK COMPATIBILITY IDEOGRAPH-2F850;Lo;0;L;5207;;;;N;;;;;
18534 2F851;CJK COMPATIBILITY IDEOGRAPH-2F851;Lo;0;L;58EE;;;;N;;;;;
18535 2F852;CJK COMPATIBILITY IDEOGRAPH-2F852;Lo;0;L;57CE;;;;N;;;;;
18536 2F853;CJK COMPATIBILITY IDEOGRAPH-2F853;Lo;0;L;57F4;;;;N;;;;;
18537 2F854;CJK COMPATIBILITY IDEOGRAPH-2F854;Lo;0;L;580D;;;;N;;;;;
18538 2F855;CJK COMPATIBILITY IDEOGRAPH-2F855;Lo;0;L;578B;;;;N;;;;;
18539 2F856;CJK COMPATIBILITY IDEOGRAPH-2F856;Lo;0;L;5832;;;;N;;;;;
18540 2F857;CJK COMPATIBILITY IDEOGRAPH-2F857;Lo;0;L;5831;;;;N;;;;;
18541 2F858;CJK COMPATIBILITY IDEOGRAPH-2F858;Lo;0;L;58AC;;;;N;;;;;
18542 2F859;CJK COMPATIBILITY IDEOGRAPH-2F859;Lo;0;L;214E4;;;;N;;;;;
18543 2F85A;CJK COMPATIBILITY IDEOGRAPH-2F85A;Lo;0;L;58F2;;;;N;;;;;
18544 2F85B;CJK COMPATIBILITY IDEOGRAPH-2F85B;Lo;0;L;58F7;;;;N;;;;;
18545 2F85C;CJK COMPATIBILITY IDEOGRAPH-2F85C;Lo;0;L;5906;;;;N;;;;;
18546 2F85D;CJK COMPATIBILITY IDEOGRAPH-2F85D;Lo;0;L;591A;;;;N;;;;;
18547 2F85E;CJK COMPATIBILITY IDEOGRAPH-2F85E;Lo;0;L;5922;;;;N;;;;;
18548 2F85F;CJK COMPATIBILITY IDEOGRAPH-2F85F;Lo;0;L;5962;;;;N;;;;;
18549 2F860;CJK COMPATIBILITY IDEOGRAPH-2F860;Lo;0;L;216A8;;;;N;;;;;
18550 2F861;CJK COMPATIBILITY IDEOGRAPH-2F861;Lo;0;L;216EA;;;;N;;;;;
18551 2F862;CJK COMPATIBILITY IDEOGRAPH-2F862;Lo;0;L;59EC;;;;N;;;;;
18552 2F863;CJK COMPATIBILITY IDEOGRAPH-2F863;Lo;0;L;5A1B;;;;N;;;;;
18553 2F864;CJK COMPATIBILITY IDEOGRAPH-2F864;Lo;0;L;5A27;;;;N;;;;;
18554 2F865;CJK COMPATIBILITY IDEOGRAPH-2F865;Lo;0;L;59D8;;;;N;;;;;
18555 2F866;CJK COMPATIBILITY IDEOGRAPH-2F866;Lo;0;L;5A66;;;;N;;;;;
18556 2F867;CJK COMPATIBILITY IDEOGRAPH-2F867;Lo;0;L;36EE;;;;N;;;;;
18557 2F868;CJK COMPATIBILITY IDEOGRAPH-2F868;Lo;0;L;36FC;;;;N;;;;;
18558 2F869;CJK COMPATIBILITY IDEOGRAPH-2F869;Lo;0;L;5B08;;;;N;;;;;
18559 2F86A;CJK COMPATIBILITY IDEOGRAPH-2F86A;Lo;0;L;5B3E;;;;N;;;;;
18560 2F86B;CJK COMPATIBILITY IDEOGRAPH-2F86B;Lo;0;L;5B3E;;;;N;;;;;
18561 2F86C;CJK COMPATIBILITY IDEOGRAPH-2F86C;Lo;0;L;219C8;;;;N;;;;;
18562 2F86D;CJK COMPATIBILITY IDEOGRAPH-2F86D;Lo;0;L;5BC3;;;;N;;;;;
18563 2F86E;CJK COMPATIBILITY IDEOGRAPH-2F86E;Lo;0;L;5BD8;;;;N;;;;;
18564 2F86F;CJK COMPATIBILITY IDEOGRAPH-2F86F;Lo;0;L;5BE7;;;;N;;;;;
18565 2F870;CJK COMPATIBILITY IDEOGRAPH-2F870;Lo;0;L;5BF3;;;;N;;;;;
18566 2F871;CJK COMPATIBILITY IDEOGRAPH-2F871;Lo;0;L;21B18;;;;N;;;;;
18567 2F872;CJK COMPATIBILITY IDEOGRAPH-2F872;Lo;0;L;5BFF;;;;N;;;;;
18568 2F873;CJK COMPATIBILITY IDEOGRAPH-2F873;Lo;0;L;5C06;;;;N;;;;;
18569 2F874;CJK COMPATIBILITY IDEOGRAPH-2F874;Lo;0;L;5F53;;;;N;;;;;
18570 2F875;CJK COMPATIBILITY IDEOGRAPH-2F875;Lo;0;L;5C22;;;;N;;;;;
18571 2F876;CJK COMPATIBILITY IDEOGRAPH-2F876;Lo;0;L;3781;;;;N;;;;;
18572 2F877;CJK COMPATIBILITY IDEOGRAPH-2F877;Lo;0;L;5C60;;;;N;;;;;
18573 2F878;CJK COMPATIBILITY IDEOGRAPH-2F878;Lo;0;L;5C6E;;;;N;;;;;
18574 2F879;CJK COMPATIBILITY IDEOGRAPH-2F879;Lo;0;L;5CC0;;;;N;;;;;
18575 2F87A;CJK COMPATIBILITY IDEOGRAPH-2F87A;Lo;0;L;5C8D;;;;N;;;;;
18576 2F87B;CJK COMPATIBILITY IDEOGRAPH-2F87B;Lo;0;L;21DE4;;;;N;;;;;
18577 2F87C;CJK COMPATIBILITY IDEOGRAPH-2F87C;Lo;0;L;5D43;;;;N;;;;;
18578 2F87D;CJK COMPATIBILITY IDEOGRAPH-2F87D;Lo;0;L;21DE6;;;;N;;;;;
18579 2F87E;CJK COMPATIBILITY IDEOGRAPH-2F87E;Lo;0;L;5D6E;;;;N;;;;;
18580 2F87F;CJK COMPATIBILITY IDEOGRAPH-2F87F;Lo;0;L;5D6B;;;;N;;;;;
18581 2F880;CJK COMPATIBILITY IDEOGRAPH-2F880;Lo;0;L;5D7C;;;;N;;;;;
18582 2F881;CJK COMPATIBILITY IDEOGRAPH-2F881;Lo;0;L;5DE1;;;;N;;;;;
18583 2F882;CJK COMPATIBILITY IDEOGRAPH-2F882;Lo;0;L;5DE2;;;;N;;;;;
18584 2F883;CJK COMPATIBILITY IDEOGRAPH-2F883;Lo;0;L;382F;;;;N;;;;;
18585 2F884;CJK COMPATIBILITY IDEOGRAPH-2F884;Lo;0;L;5DFD;;;;N;;;;;
18586 2F885;CJK COMPATIBILITY IDEOGRAPH-2F885;Lo;0;L;5E28;;;;N;;;;;
18587 2F886;CJK COMPATIBILITY IDEOGRAPH-2F886;Lo;0;L;5E3D;;;;N;;;;;
18588 2F887;CJK COMPATIBILITY IDEOGRAPH-2F887;Lo;0;L;5E69;;;;N;;;;;
18589 2F888;CJK COMPATIBILITY IDEOGRAPH-2F888;Lo;0;L;3862;;;;N;;;;;
18590 2F889;CJK COMPATIBILITY IDEOGRAPH-2F889;Lo;0;L;22183;;;;N;;;;;
18591 2F88A;CJK COMPATIBILITY IDEOGRAPH-2F88A;Lo;0;L;387C;;;;N;;;;;
18592 2F88B;CJK COMPATIBILITY IDEOGRAPH-2F88B;Lo;0;L;5EB0;;;;N;;;;;
18593 2F88C;CJK COMPATIBILITY IDEOGRAPH-2F88C;Lo;0;L;5EB3;;;;N;;;;;
18594 2F88D;CJK COMPATIBILITY IDEOGRAPH-2F88D;Lo;0;L;5EB6;;;;N;;;;;
18595 2F88E;CJK COMPATIBILITY IDEOGRAPH-2F88E;Lo;0;L;5ECA;;;;N;;;;;
18596 2F88F;CJK COMPATIBILITY IDEOGRAPH-2F88F;Lo;0;L;2A392;;;;N;;;;;
18597 2F890;CJK COMPATIBILITY IDEOGRAPH-2F890;Lo;0;L;5EFE;;;9;N;;;;;
18598 2F891;CJK COMPATIBILITY IDEOGRAPH-2F891;Lo;0;L;22331;;;;N;;;;;
18599 2F892;CJK COMPATIBILITY IDEOGRAPH-2F892;Lo;0;L;22331;;;;N;;;;;
18600 2F893;CJK COMPATIBILITY IDEOGRAPH-2F893;Lo;0;L;8201;;;;N;;;;;
18601 2F894;CJK COMPATIBILITY IDEOGRAPH-2F894;Lo;0;L;5F22;;;;N;;;;;
18602 2F895;CJK COMPATIBILITY IDEOGRAPH-2F895;Lo;0;L;5F22;;;;N;;;;;
18603 2F896;CJK COMPATIBILITY IDEOGRAPH-2F896;Lo;0;L;38C7;;;;N;;;;;
18604 2F897;CJK COMPATIBILITY IDEOGRAPH-2F897;Lo;0;L;232B8;;;;N;;;;;
18605 2F898;CJK COMPATIBILITY IDEOGRAPH-2F898;Lo;0;L;261DA;;;;N;;;;;
18606 2F899;CJK COMPATIBILITY IDEOGRAPH-2F899;Lo;0;L;5F62;;;;N;;;;;
18607 2F89A;CJK COMPATIBILITY IDEOGRAPH-2F89A;Lo;0;L;5F6B;;;;N;;;;;
18608 2F89B;CJK COMPATIBILITY IDEOGRAPH-2F89B;Lo;0;L;38E3;;;;N;;;;;
18609 2F89C;CJK COMPATIBILITY IDEOGRAPH-2F89C;Lo;0;L;5F9A;;;;N;;;;;
18610 2F89D;CJK COMPATIBILITY IDEOGRAPH-2F89D;Lo;0;L;5FCD;;;;N;;;;;
18611 2F89E;CJK COMPATIBILITY IDEOGRAPH-2F89E;Lo;0;L;5FD7;;;;N;;;;;
18612 2F89F;CJK COMPATIBILITY IDEOGRAPH-2F89F;Lo;0;L;5FF9;;;;N;;;;;
18613 2F8A0;CJK COMPATIBILITY IDEOGRAPH-2F8A0;Lo;0;L;6081;;;;N;;;;;
18614 2F8A1;CJK COMPATIBILITY IDEOGRAPH-2F8A1;Lo;0;L;393A;;;;N;;;;;
18615 2F8A2;CJK COMPATIBILITY IDEOGRAPH-2F8A2;Lo;0;L;391C;;;;N;;;;;
18616 2F8A3;CJK COMPATIBILITY IDEOGRAPH-2F8A3;Lo;0;L;6094;;;;N;;;;;
18617 2F8A4;CJK COMPATIBILITY IDEOGRAPH-2F8A4;Lo;0;L;226D4;;;;N;;;;;
18618 2F8A5;CJK COMPATIBILITY IDEOGRAPH-2F8A5;Lo;0;L;60C7;;;;N;;;;;
18619 2F8A6;CJK COMPATIBILITY IDEOGRAPH-2F8A6;Lo;0;L;6148;;;;N;;;;;
18620 2F8A7;CJK COMPATIBILITY IDEOGRAPH-2F8A7;Lo;0;L;614C;;;;N;;;;;
18621 2F8A8;CJK COMPATIBILITY IDEOGRAPH-2F8A8;Lo;0;L;614E;;;;N;;;;;
18622 2F8A9;CJK COMPATIBILITY IDEOGRAPH-2F8A9;Lo;0;L;614C;;;;N;;;;;
18623 2F8AA;CJK COMPATIBILITY IDEOGRAPH-2F8AA;Lo;0;L;617A;;;;N;;;;;
18624 2F8AB;CJK COMPATIBILITY IDEOGRAPH-2F8AB;Lo;0;L;618E;;;;N;;;;;
18625 2F8AC;CJK COMPATIBILITY IDEOGRAPH-2F8AC;Lo;0;L;61B2;;;;N;;;;;
18626 2F8AD;CJK COMPATIBILITY IDEOGRAPH-2F8AD;Lo;0;L;61A4;;;;N;;;;;
18627 2F8AE;CJK COMPATIBILITY IDEOGRAPH-2F8AE;Lo;0;L;61AF;;;;N;;;;;
18628 2F8AF;CJK COMPATIBILITY IDEOGRAPH-2F8AF;Lo;0;L;61DE;;;;N;;;;;
18629 2F8B0;CJK COMPATIBILITY IDEOGRAPH-2F8B0;Lo;0;L;61F2;;;;N;;;;;
18630 2F8B1;CJK COMPATIBILITY IDEOGRAPH-2F8B1;Lo;0;L;61F6;;;;N;;;;;
18631 2F8B2;CJK COMPATIBILITY IDEOGRAPH-2F8B2;Lo;0;L;6210;;;;N;;;;;
18632 2F8B3;CJK COMPATIBILITY IDEOGRAPH-2F8B3;Lo;0;L;621B;;;;N;;;;;
18633 2F8B4;CJK COMPATIBILITY IDEOGRAPH-2F8B4;Lo;0;L;625D;;;;N;;;;;
18634 2F8B5;CJK COMPATIBILITY IDEOGRAPH-2F8B5;Lo;0;L;62B1;;;;N;;;;;
18635 2F8B6;CJK COMPATIBILITY IDEOGRAPH-2F8B6;Lo;0;L;62D4;;;;N;;;;;
18636 2F8B7;CJK COMPATIBILITY IDEOGRAPH-2F8B7;Lo;0;L;6350;;;;N;;;;;
18637 2F8B8;CJK COMPATIBILITY IDEOGRAPH-2F8B8;Lo;0;L;22B0C;;;;N;;;;;
18638 2F8B9;CJK COMPATIBILITY IDEOGRAPH-2F8B9;Lo;0;L;633D;;;;N;;;;;
18639 2F8BA;CJK COMPATIBILITY IDEOGRAPH-2F8BA;Lo;0;L;62FC;;;;N;;;;;
18640 2F8BB;CJK COMPATIBILITY IDEOGRAPH-2F8BB;Lo;0;L;6368;;;;N;;;;;
18641 2F8BC;CJK COMPATIBILITY IDEOGRAPH-2F8BC;Lo;0;L;6383;;;;N;;;;;
18642 2F8BD;CJK COMPATIBILITY IDEOGRAPH-2F8BD;Lo;0;L;63E4;;;;N;;;;;
18643 2F8BE;CJK COMPATIBILITY IDEOGRAPH-2F8BE;Lo;0;L;22BF1;;;;N;;;;;
18644 2F8BF;CJK COMPATIBILITY IDEOGRAPH-2F8BF;Lo;0;L;6422;;;;N;;;;;
18645 2F8C0;CJK COMPATIBILITY IDEOGRAPH-2F8C0;Lo;0;L;63C5;;;;N;;;;;
18646 2F8C1;CJK COMPATIBILITY IDEOGRAPH-2F8C1;Lo;0;L;63A9;;;;N;;;;;
18647 2F8C2;CJK COMPATIBILITY IDEOGRAPH-2F8C2;Lo;0;L;3A2E;;;;N;;;;;
18648 2F8C3;CJK COMPATIBILITY IDEOGRAPH-2F8C3;Lo;0;L;6469;;;;N;;;;;
18649 2F8C4;CJK COMPATIBILITY IDEOGRAPH-2F8C4;Lo;0;L;647E;;;;N;;;;;
18650 2F8C5;CJK COMPATIBILITY IDEOGRAPH-2F8C5;Lo;0;L;649D;;;;N;;;;;
18651 2F8C6;CJK COMPATIBILITY IDEOGRAPH-2F8C6;Lo;0;L;6477;;;;N;;;;;
18652 2F8C7;CJK COMPATIBILITY IDEOGRAPH-2F8C7;Lo;0;L;3A6C;;;;N;;;;;
18653 2F8C8;CJK COMPATIBILITY IDEOGRAPH-2F8C8;Lo;0;L;654F;;;;N;;;;;
18654 2F8C9;CJK COMPATIBILITY IDEOGRAPH-2F8C9;Lo;0;L;656C;;;;N;;;;;
18655 2F8CA;CJK COMPATIBILITY IDEOGRAPH-2F8CA;Lo;0;L;2300A;;;;N;;;;;
18656 2F8CB;CJK COMPATIBILITY IDEOGRAPH-2F8CB;Lo;0;L;65E3;;;;N;;;;;
18657 2F8CC;CJK COMPATIBILITY IDEOGRAPH-2F8CC;Lo;0;L;66F8;;;;N;;;;;
18658 2F8CD;CJK COMPATIBILITY IDEOGRAPH-2F8CD;Lo;0;L;6649;;;;N;;;;;
18659 2F8CE;CJK COMPATIBILITY IDEOGRAPH-2F8CE;Lo;0;L;3B19;;;;N;;;;;
18660 2F8CF;CJK COMPATIBILITY IDEOGRAPH-2F8CF;Lo;0;L;6691;;;;N;;;;;
18661 2F8D0;CJK COMPATIBILITY IDEOGRAPH-2F8D0;Lo;0;L;3B08;;;;N;;;;;
18662 2F8D1;CJK COMPATIBILITY IDEOGRAPH-2F8D1;Lo;0;L;3AE4;;;;N;;;;;
18663 2F8D2;CJK COMPATIBILITY IDEOGRAPH-2F8D2;Lo;0;L;5192;;;;N;;;;;
18664 2F8D3;CJK COMPATIBILITY IDEOGRAPH-2F8D3;Lo;0;L;5195;;;;N;;;;;
18665 2F8D4;CJK COMPATIBILITY IDEOGRAPH-2F8D4;Lo;0;L;6700;;;;N;;;;;
18666 2F8D5;CJK COMPATIBILITY IDEOGRAPH-2F8D5;Lo;0;L;669C;;;;N;;;;;
18667 2F8D6;CJK COMPATIBILITY IDEOGRAPH-2F8D6;Lo;0;L;80AD;;;;N;;;;;
18668 2F8D7;CJK COMPATIBILITY IDEOGRAPH-2F8D7;Lo;0;L;43D9;;;;N;;;;;
18669 2F8D8;CJK COMPATIBILITY IDEOGRAPH-2F8D8;Lo;0;L;6717;;;;N;;;;;
18670 2F8D9;CJK COMPATIBILITY IDEOGRAPH-2F8D9;Lo;0;L;671B;;;;N;;;;;
18671 2F8DA;CJK COMPATIBILITY IDEOGRAPH-2F8DA;Lo;0;L;6721;;;;N;;;;;
18672 2F8DB;CJK COMPATIBILITY IDEOGRAPH-2F8DB;Lo;0;L;675E;;;;N;;;;;
18673 2F8DC;CJK COMPATIBILITY IDEOGRAPH-2F8DC;Lo;0;L;6753;;;;N;;;;;
18674 2F8DD;CJK COMPATIBILITY IDEOGRAPH-2F8DD;Lo;0;L;233C3;;;;N;;;;;
18675 2F8DE;CJK COMPATIBILITY IDEOGRAPH-2F8DE;Lo;0;L;3B49;;;;N;;;;;
18676 2F8DF;CJK COMPATIBILITY IDEOGRAPH-2F8DF;Lo;0;L;67FA;;;;N;;;;;
18677 2F8E0;CJK COMPATIBILITY IDEOGRAPH-2F8E0;Lo;0;L;6785;;;;N;;;;;
18678 2F8E1;CJK COMPATIBILITY IDEOGRAPH-2F8E1;Lo;0;L;6852;;;;N;;;;;
18679 2F8E2;CJK COMPATIBILITY IDEOGRAPH-2F8E2;Lo;0;L;6885;;;;N;;;;;
18680 2F8E3;CJK COMPATIBILITY IDEOGRAPH-2F8E3;Lo;0;L;2346D;;;;N;;;;;
18681 2F8E4;CJK COMPATIBILITY IDEOGRAPH-2F8E4;Lo;0;L;688E;;;;N;;;;;
18682 2F8E5;CJK COMPATIBILITY IDEOGRAPH-2F8E5;Lo;0;L;681F;;;;N;;;;;
18683 2F8E6;CJK COMPATIBILITY IDEOGRAPH-2F8E6;Lo;0;L;6914;;;;N;;;;;
18684 2F8E7;CJK COMPATIBILITY IDEOGRAPH-2F8E7;Lo;0;L;3B9D;;;;N;;;;;
18685 2F8E8;CJK COMPATIBILITY IDEOGRAPH-2F8E8;Lo;0;L;6942;;;;N;;;;;
18686 2F8E9;CJK COMPATIBILITY IDEOGRAPH-2F8E9;Lo;0;L;69A3;;;;N;;;;;
18687 2F8EA;CJK COMPATIBILITY IDEOGRAPH-2F8EA;Lo;0;L;69EA;;;;N;;;;;
18688 2F8EB;CJK COMPATIBILITY IDEOGRAPH-2F8EB;Lo;0;L;6AA8;;;;N;;;;;
18689 2F8EC;CJK COMPATIBILITY IDEOGRAPH-2F8EC;Lo;0;L;236A3;;;;N;;;;;
18690 2F8ED;CJK COMPATIBILITY IDEOGRAPH-2F8ED;Lo;0;L;6ADB;;;;N;;;;;
18691 2F8EE;CJK COMPATIBILITY IDEOGRAPH-2F8EE;Lo;0;L;3C18;;;;N;;;;;
18692 2F8EF;CJK COMPATIBILITY IDEOGRAPH-2F8EF;Lo;0;L;6B21;;;;N;;;;;
18693 2F8F0;CJK COMPATIBILITY IDEOGRAPH-2F8F0;Lo;0;L;238A7;;;;N;;;;;
18694 2F8F1;CJK COMPATIBILITY IDEOGRAPH-2F8F1;Lo;0;L;6B54;;;;N;;;;;
18695 2F8F2;CJK COMPATIBILITY IDEOGRAPH-2F8F2;Lo;0;L;3C4E;;;;N;;;;;
18696 2F8F3;CJK COMPATIBILITY IDEOGRAPH-2F8F3;Lo;0;L;6B72;;;;N;;;;;
18697 2F8F4;CJK COMPATIBILITY IDEOGRAPH-2F8F4;Lo;0;L;6B9F;;;;N;;;;;
18698 2F8F5;CJK COMPATIBILITY IDEOGRAPH-2F8F5;Lo;0;L;6BBA;;;;N;;;;;
18699 2F8F6;CJK COMPATIBILITY IDEOGRAPH-2F8F6;Lo;0;L;6BBB;;;;N;;;;;
18700 2F8F7;CJK COMPATIBILITY IDEOGRAPH-2F8F7;Lo;0;L;23A8D;;;;N;;;;;
18701 2F8F8;CJK COMPATIBILITY IDEOGRAPH-2F8F8;Lo;0;L;21D0B;;;;N;;;;;
18702 2F8F9;CJK COMPATIBILITY IDEOGRAPH-2F8F9;Lo;0;L;23AFA;;;;N;;;;;
18703 2F8FA;CJK COMPATIBILITY IDEOGRAPH-2F8FA;Lo;0;L;6C4E;;;;N;;;;;
18704 2F8FB;CJK COMPATIBILITY IDEOGRAPH-2F8FB;Lo;0;L;23CBC;;;;N;;;;;
18705 2F8FC;CJK COMPATIBILITY IDEOGRAPH-2F8FC;Lo;0;L;6CBF;;;;N;;;;;
18706 2F8FD;CJK COMPATIBILITY IDEOGRAPH-2F8FD;Lo;0;L;6CCD;;;;N;;;;;
18707 2F8FE;CJK COMPATIBILITY IDEOGRAPH-2F8FE;Lo;0;L;6C67;;;;N;;;;;
18708 2F8FF;CJK COMPATIBILITY IDEOGRAPH-2F8FF;Lo;0;L;6D16;;;;N;;;;;
18709 2F900;CJK COMPATIBILITY IDEOGRAPH-2F900;Lo;0;L;6D3E;;;;N;;;;;
18710 2F901;CJK COMPATIBILITY IDEOGRAPH-2F901;Lo;0;L;6D77;;;;N;;;;;
18711 2F902;CJK COMPATIBILITY IDEOGRAPH-2F902;Lo;0;L;6D41;;;;N;;;;;
18712 2F903;CJK COMPATIBILITY IDEOGRAPH-2F903;Lo;0;L;6D69;;;;N;;;;;
18713 2F904;CJK COMPATIBILITY IDEOGRAPH-2F904;Lo;0;L;6D78;;;;N;;;;;
18714 2F905;CJK COMPATIBILITY IDEOGRAPH-2F905;Lo;0;L;6D85;;;;N;;;;;
18715 2F906;CJK COMPATIBILITY IDEOGRAPH-2F906;Lo;0;L;23D1E;;;;N;;;;;
18716 2F907;CJK COMPATIBILITY IDEOGRAPH-2F907;Lo;0;L;6D34;;;;N;;;;;
18717 2F908;CJK COMPATIBILITY IDEOGRAPH-2F908;Lo;0;L;6E2F;;;;N;;;;;
18718 2F909;CJK COMPATIBILITY IDEOGRAPH-2F909;Lo;0;L;6E6E;;;;N;;;;;
18719 2F90A;CJK COMPATIBILITY IDEOGRAPH-2F90A;Lo;0;L;3D33;;;;N;;;;;
18720 2F90B;CJK COMPATIBILITY IDEOGRAPH-2F90B;Lo;0;L;6ECB;;;;N;;;;;
18721 2F90C;CJK COMPATIBILITY IDEOGRAPH-2F90C;Lo;0;L;6EC7;;;;N;;;;;
18722 2F90D;CJK COMPATIBILITY IDEOGRAPH-2F90D;Lo;0;L;23ED1;;;;N;;;;;
18723 2F90E;CJK COMPATIBILITY IDEOGRAPH-2F90E;Lo;0;L;6DF9;;;;N;;;;;
18724 2F90F;CJK COMPATIBILITY IDEOGRAPH-2F90F;Lo;0;L;6F6E;;;;N;;;;;
18725 2F910;CJK COMPATIBILITY IDEOGRAPH-2F910;Lo;0;L;23F5E;;;;N;;;;;
18726 2F911;CJK COMPATIBILITY IDEOGRAPH-2F911;Lo;0;L;23F8E;;;;N;;;;;
18727 2F912;CJK COMPATIBILITY IDEOGRAPH-2F912;Lo;0;L;6FC6;;;;N;;;;;
18728 2F913;CJK COMPATIBILITY IDEOGRAPH-2F913;Lo;0;L;7039;;;;N;;;;;
18729 2F914;CJK COMPATIBILITY IDEOGRAPH-2F914;Lo;0;L;701E;;;;N;;;;;
18730 2F915;CJK COMPATIBILITY IDEOGRAPH-2F915;Lo;0;L;701B;;;;N;;;;;
18731 2F916;CJK COMPATIBILITY IDEOGRAPH-2F916;Lo;0;L;3D96;;;;N;;;;;
18732 2F917;CJK COMPATIBILITY IDEOGRAPH-2F917;Lo;0;L;704A;;;;N;;;;;
18733 2F918;CJK COMPATIBILITY IDEOGRAPH-2F918;Lo;0;L;707D;;;;N;;;;;
18734 2F919;CJK COMPATIBILITY IDEOGRAPH-2F919;Lo;0;L;7077;;;;N;;;;;
18735 2F91A;CJK COMPATIBILITY IDEOGRAPH-2F91A;Lo;0;L;70AD;;;;N;;;;;
18736 2F91B;CJK COMPATIBILITY IDEOGRAPH-2F91B;Lo;0;L;20525;;;;N;;;;;
18737 2F91C;CJK COMPATIBILITY IDEOGRAPH-2F91C;Lo;0;L;7145;;;;N;;;;;
18738 2F91D;CJK COMPATIBILITY IDEOGRAPH-2F91D;Lo;0;L;24263;;;;N;;;;;
18739 2F91E;CJK COMPATIBILITY IDEOGRAPH-2F91E;Lo;0;L;719C;;;;N;;;;;
18740 2F91F;CJK COMPATIBILITY IDEOGRAPH-2F91F;Lo;0;L;243AB;;;;N;;;;;
18741 2F920;CJK COMPATIBILITY IDEOGRAPH-2F920;Lo;0;L;7228;;;;N;;;;;
18742 2F921;CJK COMPATIBILITY IDEOGRAPH-2F921;Lo;0;L;7235;;;;N;;;;;
18743 2F922;CJK COMPATIBILITY IDEOGRAPH-2F922;Lo;0;L;7250;;;;N;;;;;
18744 2F923;CJK COMPATIBILITY IDEOGRAPH-2F923;Lo;0;L;24608;;;;N;;;;;
18745 2F924;CJK COMPATIBILITY IDEOGRAPH-2F924;Lo;0;L;7280;;;;N;;;;;
18746 2F925;CJK COMPATIBILITY IDEOGRAPH-2F925;Lo;0;L;7295;;;;N;;;;;
18747 2F926;CJK COMPATIBILITY IDEOGRAPH-2F926;Lo;0;L;24735;;;;N;;;;;
18748 2F927;CJK COMPATIBILITY IDEOGRAPH-2F927;Lo;0;L;24814;;;;N;;;;;
18749 2F928;CJK COMPATIBILITY IDEOGRAPH-2F928;Lo;0;L;737A;;;;N;;;;;
18750 2F929;CJK COMPATIBILITY IDEOGRAPH-2F929;Lo;0;L;738B;;;;N;;;;;
18751 2F92A;CJK COMPATIBILITY IDEOGRAPH-2F92A;Lo;0;L;3EAC;;;;N;;;;;
18752 2F92B;CJK COMPATIBILITY IDEOGRAPH-2F92B;Lo;0;L;73A5;;;;N;;;;;
18753 2F92C;CJK COMPATIBILITY IDEOGRAPH-2F92C;Lo;0;L;3EB8;;;;N;;;;;
18754 2F92D;CJK COMPATIBILITY IDEOGRAPH-2F92D;Lo;0;L;3EB8;;;;N;;;;;
18755 2F92E;CJK COMPATIBILITY IDEOGRAPH-2F92E;Lo;0;L;7447;;;;N;;;;;
18756 2F92F;CJK COMPATIBILITY IDEOGRAPH-2F92F;Lo;0;L;745C;;;;N;;;;;
18757 2F930;CJK COMPATIBILITY IDEOGRAPH-2F930;Lo;0;L;7471;;;;N;;;;;
18758 2F931;CJK COMPATIBILITY IDEOGRAPH-2F931;Lo;0;L;7485;;;;N;;;;;
18759 2F932;CJK COMPATIBILITY IDEOGRAPH-2F932;Lo;0;L;74CA;;;;N;;;;;
18760 2F933;CJK COMPATIBILITY IDEOGRAPH-2F933;Lo;0;L;3F1B;;;;N;;;;;
18761 2F934;CJK COMPATIBILITY IDEOGRAPH-2F934;Lo;0;L;7524;;;;N;;;;;
18762 2F935;CJK COMPATIBILITY IDEOGRAPH-2F935;Lo;0;L;24C36;;;;N;;;;;
18763 2F936;CJK COMPATIBILITY IDEOGRAPH-2F936;Lo;0;L;753E;;;;N;;;;;
18764 2F937;CJK COMPATIBILITY IDEOGRAPH-2F937;Lo;0;L;24C92;;;;N;;;;;
18765 2F938;CJK COMPATIBILITY IDEOGRAPH-2F938;Lo;0;L;7570;;;;N;;;;;
18766 2F939;CJK COMPATIBILITY IDEOGRAPH-2F939;Lo;0;L;2219F;;;;N;;;;;
18767 2F93A;CJK COMPATIBILITY IDEOGRAPH-2F93A;Lo;0;L;7610;;;;N;;;;;
18768 2F93B;CJK COMPATIBILITY IDEOGRAPH-2F93B;Lo;0;L;24FA1;;;;N;;;;;
18769 2F93C;CJK COMPATIBILITY IDEOGRAPH-2F93C;Lo;0;L;24FB8;;;;N;;;;;
18770 2F93D;CJK COMPATIBILITY IDEOGRAPH-2F93D;Lo;0;L;25044;;;;N;;;;;
18771 2F93E;CJK COMPATIBILITY IDEOGRAPH-2F93E;Lo;0;L;3FFC;;;;N;;;;;
18772 2F93F;CJK COMPATIBILITY IDEOGRAPH-2F93F;Lo;0;L;4008;;;;N;;;;;
18773 2F940;CJK COMPATIBILITY IDEOGRAPH-2F940;Lo;0;L;76F4;;;;N;;;;;
18774 2F941;CJK COMPATIBILITY IDEOGRAPH-2F941;Lo;0;L;250F3;;;;N;;;;;
18775 2F942;CJK COMPATIBILITY IDEOGRAPH-2F942;Lo;0;L;250F2;;;;N;;;;;
18776 2F943;CJK COMPATIBILITY IDEOGRAPH-2F943;Lo;0;L;25119;;;;N;;;;;
18777 2F944;CJK COMPATIBILITY IDEOGRAPH-2F944;Lo;0;L;25133;;;;N;;;;;
18778 2F945;CJK COMPATIBILITY IDEOGRAPH-2F945;Lo;0;L;771E;;;;N;;;;;
18779 2F946;CJK COMPATIBILITY IDEOGRAPH-2F946;Lo;0;L;771F;;;;N;;;;;
18780 2F947;CJK COMPATIBILITY IDEOGRAPH-2F947;Lo;0;L;771F;;;;N;;;;;
18781 2F948;CJK COMPATIBILITY IDEOGRAPH-2F948;Lo;0;L;774A;;;;N;;;;;
18782 2F949;CJK COMPATIBILITY IDEOGRAPH-2F949;Lo;0;L;4039;;;;N;;;;;
18783 2F94A;CJK COMPATIBILITY IDEOGRAPH-2F94A;Lo;0;L;778B;;;;N;;;;;
18784 2F94B;CJK COMPATIBILITY IDEOGRAPH-2F94B;Lo;0;L;4046;;;;N;;;;;
18785 2F94C;CJK COMPATIBILITY IDEOGRAPH-2F94C;Lo;0;L;4096;;;;N;;;;;
18786 2F94D;CJK COMPATIBILITY IDEOGRAPH-2F94D;Lo;0;L;2541D;;;;N;;;;;
18787 2F94E;CJK COMPATIBILITY IDEOGRAPH-2F94E;Lo;0;L;784E;;;;N;;;;;
18788 2F94F;CJK COMPATIBILITY IDEOGRAPH-2F94F;Lo;0;L;788C;;;;N;;;;;
18789 2F950;CJK COMPATIBILITY IDEOGRAPH-2F950;Lo;0;L;78CC;;;;N;;;;;
18790 2F951;CJK COMPATIBILITY IDEOGRAPH-2F951;Lo;0;L;40E3;;;;N;;;;;
18791 2F952;CJK COMPATIBILITY IDEOGRAPH-2F952;Lo;0;L;25626;;;;N;;;;;
18792 2F953;CJK COMPATIBILITY IDEOGRAPH-2F953;Lo;0;L;7956;;;;N;;;;;
18793 2F954;CJK COMPATIBILITY IDEOGRAPH-2F954;Lo;0;L;2569A;;;;N;;;;;
18794 2F955;CJK COMPATIBILITY IDEOGRAPH-2F955;Lo;0;L;256C5;;;;N;;;;;
18795 2F956;CJK COMPATIBILITY IDEOGRAPH-2F956;Lo;0;L;798F;;;;N;;;;;
18796 2F957;CJK COMPATIBILITY IDEOGRAPH-2F957;Lo;0;L;79EB;;;;N;;;;;
18797 2F958;CJK COMPATIBILITY IDEOGRAPH-2F958;Lo;0;L;412F;;;;N;;;;;
18798 2F959;CJK COMPATIBILITY IDEOGRAPH-2F959;Lo;0;L;7A40;;;;N;;;;;
18799 2F95A;CJK COMPATIBILITY IDEOGRAPH-2F95A;Lo;0;L;7A4A;;;;N;;;;;
18800 2F95B;CJK COMPATIBILITY IDEOGRAPH-2F95B;Lo;0;L;7A4F;;;;N;;;;;
18801 2F95C;CJK COMPATIBILITY IDEOGRAPH-2F95C;Lo;0;L;2597C;;;;N;;;;;
18802 2F95D;CJK COMPATIBILITY IDEOGRAPH-2F95D;Lo;0;L;25AA7;;;;N;;;;;
18803 2F95E;CJK COMPATIBILITY IDEOGRAPH-2F95E;Lo;0;L;25AA7;;;;N;;;;;
18804 2F95F;CJK COMPATIBILITY IDEOGRAPH-2F95F;Lo;0;L;7AEE;;;;N;;;;;
18805 2F960;CJK COMPATIBILITY IDEOGRAPH-2F960;Lo;0;L;4202;;;;N;;;;;
18806 2F961;CJK COMPATIBILITY IDEOGRAPH-2F961;Lo;0;L;25BAB;;;;N;;;;;
18807 2F962;CJK COMPATIBILITY IDEOGRAPH-2F962;Lo;0;L;7BC6;;;;N;;;;;
18808 2F963;CJK COMPATIBILITY IDEOGRAPH-2F963;Lo;0;L;7BC9;;;;N;;;;;
18809 2F964;CJK COMPATIBILITY IDEOGRAPH-2F964;Lo;0;L;4227;;;;N;;;;;
18810 2F965;CJK COMPATIBILITY IDEOGRAPH-2F965;Lo;0;L;25C80;;;;N;;;;;
18811 2F966;CJK COMPATIBILITY IDEOGRAPH-2F966;Lo;0;L;7CD2;;;;N;;;;;
18812 2F967;CJK COMPATIBILITY IDEOGRAPH-2F967;Lo;0;L;42A0;;;;N;;;;;
18813 2F968;CJK COMPATIBILITY IDEOGRAPH-2F968;Lo;0;L;7CE8;;;;N;;;;;
18814 2F969;CJK COMPATIBILITY IDEOGRAPH-2F969;Lo;0;L;7CE3;;;;N;;;;;
18815 2F96A;CJK COMPATIBILITY IDEOGRAPH-2F96A;Lo;0;L;7D00;;;;N;;;;;
18816 2F96B;CJK COMPATIBILITY IDEOGRAPH-2F96B;Lo;0;L;25F86;;;;N;;;;;
18817 2F96C;CJK COMPATIBILITY IDEOGRAPH-2F96C;Lo;0;L;7D63;;;;N;;;;;
18818 2F96D;CJK COMPATIBILITY IDEOGRAPH-2F96D;Lo;0;L;4301;;;;N;;;;;
18819 2F96E;CJK COMPATIBILITY IDEOGRAPH-2F96E;Lo;0;L;7DC7;;;;N;;;;;
18820 2F96F;CJK COMPATIBILITY IDEOGRAPH-2F96F;Lo;0;L;7E02;;;;N;;;;;
18821 2F970;CJK COMPATIBILITY IDEOGRAPH-2F970;Lo;0;L;7E45;;;;N;;;;;
18822 2F971;CJK COMPATIBILITY IDEOGRAPH-2F971;Lo;0;L;4334;;;;N;;;;;
18823 2F972;CJK COMPATIBILITY IDEOGRAPH-2F972;Lo;0;L;26228;;;;N;;;;;
18824 2F973;CJK COMPATIBILITY IDEOGRAPH-2F973;Lo;0;L;26247;;;;N;;;;;
18825 2F974;CJK COMPATIBILITY IDEOGRAPH-2F974;Lo;0;L;4359;;;;N;;;;;
18826 2F975;CJK COMPATIBILITY IDEOGRAPH-2F975;Lo;0;L;262D9;;;;N;;;;;
18827 2F976;CJK COMPATIBILITY IDEOGRAPH-2F976;Lo;0;L;7F7A;;;;N;;;;;
18828 2F977;CJK COMPATIBILITY IDEOGRAPH-2F977;Lo;0;L;2633E;;;;N;;;;;
18829 2F978;CJK COMPATIBILITY IDEOGRAPH-2F978;Lo;0;L;7F95;;;;N;;;;;
18830 2F979;CJK COMPATIBILITY IDEOGRAPH-2F979;Lo;0;L;7FFA;;;;N;;;;;
18831 2F97A;CJK COMPATIBILITY IDEOGRAPH-2F97A;Lo;0;L;8005;;;;N;;;;;
18832 2F97B;CJK COMPATIBILITY IDEOGRAPH-2F97B;Lo;0;L;264DA;;;;N;;;;;
18833 2F97C;CJK COMPATIBILITY IDEOGRAPH-2F97C;Lo;0;L;26523;;;;N;;;;;
18834 2F97D;CJK COMPATIBILITY IDEOGRAPH-2F97D;Lo;0;L;8060;;;;N;;;;;
18835 2F97E;CJK COMPATIBILITY IDEOGRAPH-2F97E;Lo;0;L;265A8;;;;N;;;;;
18836 2F97F;CJK COMPATIBILITY IDEOGRAPH-2F97F;Lo;0;L;8070;;;;N;;;;;
18837 2F980;CJK COMPATIBILITY IDEOGRAPH-2F980;Lo;0;L;2335F;;;;N;;;;;
18838 2F981;CJK COMPATIBILITY IDEOGRAPH-2F981;Lo;0;L;43D5;;;;N;;;;;
18839 2F982;CJK COMPATIBILITY IDEOGRAPH-2F982;Lo;0;L;80B2;;;;N;;;;;
18840 2F983;CJK COMPATIBILITY IDEOGRAPH-2F983;Lo;0;L;8103;;;;N;;;;;
18841 2F984;CJK COMPATIBILITY IDEOGRAPH-2F984;Lo;0;L;440B;;;;N;;;;;
18842 2F985;CJK COMPATIBILITY IDEOGRAPH-2F985;Lo;0;L;813E;;;;N;;;;;
18843 2F986;CJK COMPATIBILITY IDEOGRAPH-2F986;Lo;0;L;5AB5;;;;N;;;;;
18844 2F987;CJK COMPATIBILITY IDEOGRAPH-2F987;Lo;0;L;267A7;;;;N;;;;;
18845 2F988;CJK COMPATIBILITY IDEOGRAPH-2F988;Lo;0;L;267B5;;;;N;;;;;
18846 2F989;CJK COMPATIBILITY IDEOGRAPH-2F989;Lo;0;L;23393;;;;N;;;;;
18847 2F98A;CJK COMPATIBILITY IDEOGRAPH-2F98A;Lo;0;L;2339C;;;;N;;;;;
18848 2F98B;CJK COMPATIBILITY IDEOGRAPH-2F98B;Lo;0;L;8201;;;;N;;;;;
18849 2F98C;CJK COMPATIBILITY IDEOGRAPH-2F98C;Lo;0;L;8204;;;;N;;;;;
18850 2F98D;CJK COMPATIBILITY IDEOGRAPH-2F98D;Lo;0;L;8F9E;;;;N;;;;;
18851 2F98E;CJK COMPATIBILITY IDEOGRAPH-2F98E;Lo;0;L;446B;;;;N;;;;;
18852 2F98F;CJK COMPATIBILITY IDEOGRAPH-2F98F;Lo;0;L;8291;;;;N;;;;;
18853 2F990;CJK COMPATIBILITY IDEOGRAPH-2F990;Lo;0;L;828B;;;;N;;;;;
18854 2F991;CJK COMPATIBILITY IDEOGRAPH-2F991;Lo;0;L;829D;;;;N;;;;;
18855 2F992;CJK COMPATIBILITY IDEOGRAPH-2F992;Lo;0;L;52B3;;;;N;;;;;
18856 2F993;CJK COMPATIBILITY IDEOGRAPH-2F993;Lo;0;L;82B1;;;;N;;;;;
18857 2F994;CJK COMPATIBILITY IDEOGRAPH-2F994;Lo;0;L;82B3;;;;N;;;;;
18858 2F995;CJK COMPATIBILITY IDEOGRAPH-2F995;Lo;0;L;82BD;;;;N;;;;;
18859 2F996;CJK COMPATIBILITY IDEOGRAPH-2F996;Lo;0;L;82E6;;;;N;;;;;
18860 2F997;CJK COMPATIBILITY IDEOGRAPH-2F997;Lo;0;L;26B3C;;;;N;;;;;
18861 2F998;CJK COMPATIBILITY IDEOGRAPH-2F998;Lo;0;L;82E5;;;;N;;;;;
18862 2F999;CJK COMPATIBILITY IDEOGRAPH-2F999;Lo;0;L;831D;;;;N;;;;;
18863 2F99A;CJK COMPATIBILITY IDEOGRAPH-2F99A;Lo;0;L;8363;;;;N;;;;;
18864 2F99B;CJK COMPATIBILITY IDEOGRAPH-2F99B;Lo;0;L;83AD;;;;N;;;;;
18865 2F99C;CJK COMPATIBILITY IDEOGRAPH-2F99C;Lo;0;L;8323;;;;N;;;;;
18866 2F99D;CJK COMPATIBILITY IDEOGRAPH-2F99D;Lo;0;L;83BD;;;;N;;;;;
18867 2F99E;CJK COMPATIBILITY IDEOGRAPH-2F99E;Lo;0;L;83E7;;;;N;;;;;
18868 2F99F;CJK COMPATIBILITY IDEOGRAPH-2F99F;Lo;0;L;8457;;;;N;;;;;
18869 2F9A0;CJK COMPATIBILITY IDEOGRAPH-2F9A0;Lo;0;L;8353;;;;N;;;;;
18870 2F9A1;CJK COMPATIBILITY IDEOGRAPH-2F9A1;Lo;0;L;83CA;;;;N;;;;;
18871 2F9A2;CJK COMPATIBILITY IDEOGRAPH-2F9A2;Lo;0;L;83CC;;;;N;;;;;
18872 2F9A3;CJK COMPATIBILITY IDEOGRAPH-2F9A3;Lo;0;L;83DC;;;;N;;;;;
18873 2F9A4;CJK COMPATIBILITY IDEOGRAPH-2F9A4;Lo;0;L;26C36;;;;N;;;;;
18874 2F9A5;CJK COMPATIBILITY IDEOGRAPH-2F9A5;Lo;0;L;26D6B;;;;N;;;;;
18875 2F9A6;CJK COMPATIBILITY IDEOGRAPH-2F9A6;Lo;0;L;26CD5;;;;N;;;;;
18876 2F9A7;CJK COMPATIBILITY IDEOGRAPH-2F9A7;Lo;0;L;452B;;;;N;;;;;
18877 2F9A8;CJK COMPATIBILITY IDEOGRAPH-2F9A8;Lo;0;L;84F1;;;;N;;;;;
18878 2F9A9;CJK COMPATIBILITY IDEOGRAPH-2F9A9;Lo;0;L;84F3;;;;N;;;;;
18879 2F9AA;CJK COMPATIBILITY IDEOGRAPH-2F9AA;Lo;0;L;8516;;;;N;;;;;
18880 2F9AB;CJK COMPATIBILITY IDEOGRAPH-2F9AB;Lo;0;L;273CA;;;;N;;;;;
18881 2F9AC;CJK COMPATIBILITY IDEOGRAPH-2F9AC;Lo;0;L;8564;;;;N;;;;;
18882 2F9AD;CJK COMPATIBILITY IDEOGRAPH-2F9AD;Lo;0;L;26F2C;;;;N;;;;;
18883 2F9AE;CJK COMPATIBILITY IDEOGRAPH-2F9AE;Lo;0;L;455D;;;;N;;;;;
18884 2F9AF;CJK COMPATIBILITY IDEOGRAPH-2F9AF;Lo;0;L;4561;;;;N;;;;;
18885 2F9B0;CJK COMPATIBILITY IDEOGRAPH-2F9B0;Lo;0;L;26FB1;;;;N;;;;;
18886 2F9B1;CJK COMPATIBILITY IDEOGRAPH-2F9B1;Lo;0;L;270D2;;;;N;;;;;
18887 2F9B2;CJK COMPATIBILITY IDEOGRAPH-2F9B2;Lo;0;L;456B;;;;N;;;;;
18888 2F9B3;CJK COMPATIBILITY IDEOGRAPH-2F9B3;Lo;0;L;8650;;;;N;;;;;
18889 2F9B4;CJK COMPATIBILITY IDEOGRAPH-2F9B4;Lo;0;L;865C;;;;N;;;;;
18890 2F9B5;CJK COMPATIBILITY IDEOGRAPH-2F9B5;Lo;0;L;8667;;;;N;;;;;
18891 2F9B6;CJK COMPATIBILITY IDEOGRAPH-2F9B6;Lo;0;L;8669;;;;N;;;;;
18892 2F9B7;CJK COMPATIBILITY IDEOGRAPH-2F9B7;Lo;0;L;86A9;;;;N;;;;;
18893 2F9B8;CJK COMPATIBILITY IDEOGRAPH-2F9B8;Lo;0;L;8688;;;;N;;;;;
18894 2F9B9;CJK COMPATIBILITY IDEOGRAPH-2F9B9;Lo;0;L;870E;;;;N;;;;;
18895 2F9BA;CJK COMPATIBILITY IDEOGRAPH-2F9BA;Lo;0;L;86E2;;;;N;;;;;
18896 2F9BB;CJK COMPATIBILITY IDEOGRAPH-2F9BB;Lo;0;L;8779;;;;N;;;;;
18897 2F9BC;CJK COMPATIBILITY IDEOGRAPH-2F9BC;Lo;0;L;8728;;;;N;;;;;
18898 2F9BD;CJK COMPATIBILITY IDEOGRAPH-2F9BD;Lo;0;L;876B;;;;N;;;;;
18899 2F9BE;CJK COMPATIBILITY IDEOGRAPH-2F9BE;Lo;0;L;8786;;;;N;;;;;
18900 2F9BF;CJK COMPATIBILITY IDEOGRAPH-2F9BF;Lo;0;L;45D7;;;;N;;;;;
18901 2F9C0;CJK COMPATIBILITY IDEOGRAPH-2F9C0;Lo;0;L;87E1;;;;N;;;;;
18902 2F9C1;CJK COMPATIBILITY IDEOGRAPH-2F9C1;Lo;0;L;8801;;;;N;;;;;
18903 2F9C2;CJK COMPATIBILITY IDEOGRAPH-2F9C2;Lo;0;L;45F9;;;;N;;;;;
18904 2F9C3;CJK COMPATIBILITY IDEOGRAPH-2F9C3;Lo;0;L;8860;;;;N;;;;;
18905 2F9C4;CJK COMPATIBILITY IDEOGRAPH-2F9C4;Lo;0;L;8863;;;;N;;;;;
18906 2F9C5;CJK COMPATIBILITY IDEOGRAPH-2F9C5;Lo;0;L;27667;;;;N;;;;;
18907 2F9C6;CJK COMPATIBILITY IDEOGRAPH-2F9C6;Lo;0;L;88D7;;;;N;;;;;
18908 2F9C7;CJK COMPATIBILITY IDEOGRAPH-2F9C7;Lo;0;L;88DE;;;;N;;;;;
18909 2F9C8;CJK COMPATIBILITY IDEOGRAPH-2F9C8;Lo;0;L;4635;;;;N;;;;;
18910 2F9C9;CJK COMPATIBILITY IDEOGRAPH-2F9C9;Lo;0;L;88FA;;;;N;;;;;
18911 2F9CA;CJK COMPATIBILITY IDEOGRAPH-2F9CA;Lo;0;L;34BB;;;;N;;;;;
18912 2F9CB;CJK COMPATIBILITY IDEOGRAPH-2F9CB;Lo;0;L;278AE;;;;N;;;;;
18913 2F9CC;CJK COMPATIBILITY IDEOGRAPH-2F9CC;Lo;0;L;27966;;;;N;;;;;
18914 2F9CD;CJK COMPATIBILITY IDEOGRAPH-2F9CD;Lo;0;L;46BE;;;;N;;;;;
18915 2F9CE;CJK COMPATIBILITY IDEOGRAPH-2F9CE;Lo;0;L;46C7;;;;N;;;;;
18916 2F9CF;CJK COMPATIBILITY IDEOGRAPH-2F9CF;Lo;0;L;8AA0;;;;N;;;;;
18917 2F9D0;CJK COMPATIBILITY IDEOGRAPH-2F9D0;Lo;0;L;8AED;;;;N;;;;;
18918 2F9D1;CJK COMPATIBILITY IDEOGRAPH-2F9D1;Lo;0;L;8B8A;;;;N;;;;;
18919 2F9D2;CJK COMPATIBILITY IDEOGRAPH-2F9D2;Lo;0;L;8C55;;;;N;;;;;
18920 2F9D3;CJK COMPATIBILITY IDEOGRAPH-2F9D3;Lo;0;L;27CA8;;;;N;;;;;
18921 2F9D4;CJK COMPATIBILITY IDEOGRAPH-2F9D4;Lo;0;L;8CAB;;;;N;;;;;
18922 2F9D5;CJK COMPATIBILITY IDEOGRAPH-2F9D5;Lo;0;L;8CC1;;;;N;;;;;
18923 2F9D6;CJK COMPATIBILITY IDEOGRAPH-2F9D6;Lo;0;L;8D1B;;;;N;;;;;
18924 2F9D7;CJK COMPATIBILITY IDEOGRAPH-2F9D7;Lo;0;L;8D77;;;;N;;;;;
18925 2F9D8;CJK COMPATIBILITY IDEOGRAPH-2F9D8;Lo;0;L;27F2F;;;;N;;;;;
18926 2F9D9;CJK COMPATIBILITY IDEOGRAPH-2F9D9;Lo;0;L;20804;;;;N;;;;;
18927 2F9DA;CJK COMPATIBILITY IDEOGRAPH-2F9DA;Lo;0;L;8DCB;;;;N;;;;;
18928 2F9DB;CJK COMPATIBILITY IDEOGRAPH-2F9DB;Lo;0;L;8DBC;;;;N;;;;;
18929 2F9DC;CJK COMPATIBILITY IDEOGRAPH-2F9DC;Lo;0;L;8DF0;;;;N;;;;;
18930 2F9DD;CJK COMPATIBILITY IDEOGRAPH-2F9DD;Lo;0;L;208DE;;;;N;;;;;
18931 2F9DE;CJK COMPATIBILITY IDEOGRAPH-2F9DE;Lo;0;L;8ED4;;;;N;;;;;
18932 2F9DF;CJK COMPATIBILITY IDEOGRAPH-2F9DF;Lo;0;L;8F38;;;;N;;;;;
18933 2F9E0;CJK COMPATIBILITY IDEOGRAPH-2F9E0;Lo;0;L;285D2;;;;N;;;;;
18934 2F9E1;CJK COMPATIBILITY IDEOGRAPH-2F9E1;Lo;0;L;285ED;;;;N;;;;;
18935 2F9E2;CJK COMPATIBILITY IDEOGRAPH-2F9E2;Lo;0;L;9094;;;;N;;;;;
18936 2F9E3;CJK COMPATIBILITY IDEOGRAPH-2F9E3;Lo;0;L;90F1;;;;N;;;;;
18937 2F9E4;CJK COMPATIBILITY IDEOGRAPH-2F9E4;Lo;0;L;9111;;;;N;;;;;
18938 2F9E5;CJK COMPATIBILITY IDEOGRAPH-2F9E5;Lo;0;L;2872E;;;;N;;;;;
18939 2F9E6;CJK COMPATIBILITY IDEOGRAPH-2F9E6;Lo;0;L;911B;;;;N;;;;;
18940 2F9E7;CJK COMPATIBILITY IDEOGRAPH-2F9E7;Lo;0;L;9238;;;;N;;;;;
18941 2F9E8;CJK COMPATIBILITY IDEOGRAPH-2F9E8;Lo;0;L;92D7;;;;N;;;;;
18942 2F9E9;CJK COMPATIBILITY IDEOGRAPH-2F9E9;Lo;0;L;92D8;;;;N;;;;;
18943 2F9EA;CJK COMPATIBILITY IDEOGRAPH-2F9EA;Lo;0;L;927C;;;;N;;;;;
18944 2F9EB;CJK COMPATIBILITY IDEOGRAPH-2F9EB;Lo;0;L;93F9;;;;N;;;;;
18945 2F9EC;CJK COMPATIBILITY IDEOGRAPH-2F9EC;Lo;0;L;9415;;;;N;;;;;
18946 2F9ED;CJK COMPATIBILITY IDEOGRAPH-2F9ED;Lo;0;L;28BFA;;;;N;;;;;
18947 2F9EE;CJK COMPATIBILITY IDEOGRAPH-2F9EE;Lo;0;L;958B;;;;N;;;;;
18948 2F9EF;CJK COMPATIBILITY IDEOGRAPH-2F9EF;Lo;0;L;4995;;;;N;;;;;
18949 2F9F0;CJK COMPATIBILITY IDEOGRAPH-2F9F0;Lo;0;L;95B7;;;;N;;;;;
18950 2F9F1;CJK COMPATIBILITY IDEOGRAPH-2F9F1;Lo;0;L;28D77;;;;N;;;;;
18951 2F9F2;CJK COMPATIBILITY IDEOGRAPH-2F9F2;Lo;0;L;49E6;;;;N;;;;;
18952 2F9F3;CJK COMPATIBILITY IDEOGRAPH-2F9F3;Lo;0;L;96C3;;;;N;;;;;
18953 2F9F4;CJK COMPATIBILITY IDEOGRAPH-2F9F4;Lo;0;L;5DB2;;;;N;;;;;
18954 2F9F5;CJK COMPATIBILITY IDEOGRAPH-2F9F5;Lo;0;L;9723;;;;N;;;;;
18955 2F9F6;CJK COMPATIBILITY IDEOGRAPH-2F9F6;Lo;0;L;29145;;;;N;;;;;
18956 2F9F7;CJK COMPATIBILITY IDEOGRAPH-2F9F7;Lo;0;L;2921A;;;;N;;;;;
18957 2F9F8;CJK COMPATIBILITY IDEOGRAPH-2F9F8;Lo;0;L;4A6E;;;;N;;;;;
18958 2F9F9;CJK COMPATIBILITY IDEOGRAPH-2F9F9;Lo;0;L;4A76;;;;N;;;;;
18959 2F9FA;CJK COMPATIBILITY IDEOGRAPH-2F9FA;Lo;0;L;97E0;;;;N;;;;;
18960 2F9FB;CJK COMPATIBILITY IDEOGRAPH-2F9FB;Lo;0;L;2940A;;;;N;;;;;
18961 2F9FC;CJK COMPATIBILITY IDEOGRAPH-2F9FC;Lo;0;L;4AB2;;;;N;;;;;
18962 2F9FD;CJK COMPATIBILITY IDEOGRAPH-2F9FD;Lo;0;L;29496;;;;N;;;;;
18963 2F9FE;CJK COMPATIBILITY IDEOGRAPH-2F9FE;Lo;0;L;980B;;;;N;;;;;
18964 2F9FF;CJK COMPATIBILITY IDEOGRAPH-2F9FF;Lo;0;L;980B;;;;N;;;;;
18965 2FA00;CJK COMPATIBILITY IDEOGRAPH-2FA00;Lo;0;L;9829;;;;N;;;;;
18966 2FA01;CJK COMPATIBILITY IDEOGRAPH-2FA01;Lo;0;L;295B6;;;;N;;;;;
18967 2FA02;CJK COMPATIBILITY IDEOGRAPH-2FA02;Lo;0;L;98E2;;;;N;;;;;
18968 2FA03;CJK COMPATIBILITY IDEOGRAPH-2FA03;Lo;0;L;4B33;;;;N;;;;;
18969 2FA04;CJK COMPATIBILITY IDEOGRAPH-2FA04;Lo;0;L;9929;;;;N;;;;;
18970 2FA05;CJK COMPATIBILITY IDEOGRAPH-2FA05;Lo;0;L;99A7;;;;N;;;;;
18971 2FA06;CJK COMPATIBILITY IDEOGRAPH-2FA06;Lo;0;L;99C2;;;;N;;;;;
18972 2FA07;CJK COMPATIBILITY IDEOGRAPH-2FA07;Lo;0;L;99FE;;;;N;;;;;
18973 2FA08;CJK COMPATIBILITY IDEOGRAPH-2FA08;Lo;0;L;4BCE;;;;N;;;;;
18974 2FA09;CJK COMPATIBILITY IDEOGRAPH-2FA09;Lo;0;L;29B30;;;;N;;;;;
18975 2FA0A;CJK COMPATIBILITY IDEOGRAPH-2FA0A;Lo;0;L;9B12;;;;N;;;;;
18976 2FA0B;CJK COMPATIBILITY IDEOGRAPH-2FA0B;Lo;0;L;9C40;;;;N;;;;;
18977 2FA0C;CJK COMPATIBILITY IDEOGRAPH-2FA0C;Lo;0;L;9CFD;;;;N;;;;;
18978 2FA0D;CJK COMPATIBILITY IDEOGRAPH-2FA0D;Lo;0;L;4CCE;;;;N;;;;;
18979 2FA0E;CJK COMPATIBILITY IDEOGRAPH-2FA0E;Lo;0;L;4CED;;;;N;;;;;
18980 2FA0F;CJK COMPATIBILITY IDEOGRAPH-2FA0F;Lo;0;L;9D67;;;;N;;;;;
18981 2FA10;CJK COMPATIBILITY IDEOGRAPH-2FA10;Lo;0;L;2A0CE;;;;N;;;;;
18982 2FA11;CJK COMPATIBILITY IDEOGRAPH-2FA11;Lo;0;L;4CF8;;;;N;;;;;
18983 2FA12;CJK COMPATIBILITY IDEOGRAPH-2FA12;Lo;0;L;2A105;;;;N;;;;;
18984 2FA13;CJK COMPATIBILITY IDEOGRAPH-2FA13;Lo;0;L;2A20E;;;;N;;;;;
18985 2FA14;CJK COMPATIBILITY IDEOGRAPH-2FA14;Lo;0;L;2A291;;;;N;;;;;
18986 2FA15;CJK COMPATIBILITY IDEOGRAPH-2FA15;Lo;0;L;9EBB;;;;N;;;;;
18987 2FA16;CJK COMPATIBILITY IDEOGRAPH-2FA16;Lo;0;L;4D56;;;;N;;;;;
18988 2FA17;CJK COMPATIBILITY IDEOGRAPH-2FA17;Lo;0;L;9EF9;;;;N;;;;;
18989 2FA18;CJK COMPATIBILITY IDEOGRAPH-2FA18;Lo;0;L;9EFE;;;;N;;;;;
18990 2FA19;CJK COMPATIBILITY IDEOGRAPH-2FA19;Lo;0;L;9F05;;;;N;;;;;
18991 2FA1A;CJK COMPATIBILITY IDEOGRAPH-2FA1A;Lo;0;L;9F0F;;;;N;;;;;
18992 2FA1B;CJK COMPATIBILITY IDEOGRAPH-2FA1B;Lo;0;L;9F16;;;;N;;;;;
18993 2FA1C;CJK COMPATIBILITY IDEOGRAPH-2FA1C;Lo;0;L;9F3B;;;;N;;;;;
18994 2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;;
18995 E0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;;
18996 E0020;TAG SPACE;Cf;0;BN;;;;;N;;;;;
18997 E0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;;
18998 E0022;TAG QUOTATION MARK;Cf;0;BN;;;;;N;;;;;
18999 E0023;TAG NUMBER SIGN;Cf;0;BN;;;;;N;;;;;
19000 E0024;TAG DOLLAR SIGN;Cf;0;BN;;;;;N;;;;;
19001 E0025;TAG PERCENT SIGN;Cf;0;BN;;;;;N;;;;;
19002 E0026;TAG AMPERSAND;Cf;0;BN;;;;;N;;;;;
19003 E0027;TAG APOSTROPHE;Cf;0;BN;;;;;N;;;;;
19004 E0028;TAG LEFT PARENTHESIS;Cf;0;BN;;;;;N;;;;;
19005 E0029;TAG RIGHT PARENTHESIS;Cf;0;BN;;;;;N;;;;;
19006 E002A;TAG ASTERISK;Cf;0;BN;;;;;N;;;;;
19007 E002B;TAG PLUS SIGN;Cf;0;BN;;;;;N;;;;;
19008 E002C;TAG COMMA;Cf;0;BN;;;;;N;;;;;
19009 E002D;TAG HYPHEN-MINUS;Cf;0;BN;;;;;N;;;;;
19010 E002E;TAG FULL STOP;Cf;0;BN;;;;;N;;;;;
19011 E002F;TAG SOLIDUS;Cf;0;BN;;;;;N;;;;;
19012 E0030;TAG DIGIT ZERO;Cf;0;BN;;;;;N;;;;;
19013 E0031;TAG DIGIT ONE;Cf;0;BN;;;;;N;;;;;
19014 E0032;TAG DIGIT TWO;Cf;0;BN;;;;;N;;;;;
19015 E0033;TAG DIGIT THREE;Cf;0;BN;;;;;N;;;;;
19016 E0034;TAG DIGIT FOUR;Cf;0;BN;;;;;N;;;;;
19017 E0035;TAG DIGIT FIVE;Cf;0;BN;;;;;N;;;;;
19018 E0036;TAG DIGIT SIX;Cf;0;BN;;;;;N;;;;;
19019 E0037;TAG DIGIT SEVEN;Cf;0;BN;;;;;N;;;;;
19020 E0038;TAG DIGIT EIGHT;Cf;0;BN;;;;;N;;;;;
19021 E0039;TAG DIGIT NINE;Cf;0;BN;;;;;N;;;;;
19022 E003A;TAG COLON;Cf;0;BN;;;;;N;;;;;
19023 E003B;TAG SEMICOLON;Cf;0;BN;;;;;N;;;;;
19024 E003C;TAG LESS-THAN SIGN;Cf;0;BN;;;;;N;;;;;
19025 E003D;TAG EQUALS SIGN;Cf;0;BN;;;;;N;;;;;
19026 E003E;TAG GREATER-THAN SIGN;Cf;0;BN;;;;;N;;;;;
19027 E003F;TAG QUESTION MARK;Cf;0;BN;;;;;N;;;;;
19028 E0040;TAG COMMERCIAL AT;Cf;0;BN;;;;;N;;;;;
19029 E0041;TAG LATIN CAPITAL LETTER A;Cf;0;BN;;;;;N;;;;;
19030 E0042;TAG LATIN CAPITAL LETTER B;Cf;0;BN;;;;;N;;;;;
19031 E0043;TAG LATIN CAPITAL LETTER C;Cf;0;BN;;;;;N;;;;;
19032 E0044;TAG LATIN CAPITAL LETTER D;Cf;0;BN;;;;;N;;;;;
19033 E0045;TAG LATIN CAPITAL LETTER E;Cf;0;BN;;;;;N;;;;;
19034 E0046;TAG LATIN CAPITAL LETTER F;Cf;0;BN;;;;;N;;;;;
19035 E0047;TAG LATIN CAPITAL LETTER G;Cf;0;BN;;;;;N;;;;;
19036 E0048;TAG LATIN CAPITAL LETTER H;Cf;0;BN;;;;;N;;;;;
19037 E0049;TAG LATIN CAPITAL LETTER I;Cf;0;BN;;;;;N;;;;;
19038 E004A;TAG LATIN CAPITAL LETTER J;Cf;0;BN;;;;;N;;;;;
19039 E004B;TAG LATIN CAPITAL LETTER K;Cf;0;BN;;;;;N;;;;;
19040 E004C;TAG LATIN CAPITAL LETTER L;Cf;0;BN;;;;;N;;;;;
19041 E004D;TAG LATIN CAPITAL LETTER M;Cf;0;BN;;;;;N;;;;;
19042 E004E;TAG LATIN CAPITAL LETTER N;Cf;0;BN;;;;;N;;;;;
19043 E004F;TAG LATIN CAPITAL LETTER O;Cf;0;BN;;;;;N;;;;;
19044 E0050;TAG LATIN CAPITAL LETTER P;Cf;0;BN;;;;;N;;;;;
19045 E0051;TAG LATIN CAPITAL LETTER Q;Cf;0;BN;;;;;N;;;;;
19046 E0052;TAG LATIN CAPITAL LETTER R;Cf;0;BN;;;;;N;;;;;
19047 E0053;TAG LATIN CAPITAL LETTER S;Cf;0;BN;;;;;N;;;;;
19048 E0054;TAG LATIN CAPITAL LETTER T;Cf;0;BN;;;;;N;;;;;
19049 E0055;TAG LATIN CAPITAL LETTER U;Cf;0;BN;;;;;N;;;;;
19050 E0056;TAG LATIN CAPITAL LETTER V;Cf;0;BN;;;;;N;;;;;
19051 E0057;TAG LATIN CAPITAL LETTER W;Cf;0;BN;;;;;N;;;;;
19052 E0058;TAG LATIN CAPITAL LETTER X;Cf;0;BN;;;;;N;;;;;
19053 E0059;TAG LATIN CAPITAL LETTER Y;Cf;0;BN;;;;;N;;;;;
19054 E005A;TAG LATIN CAPITAL LETTER Z;Cf;0;BN;;;;;N;;;;;
19055 E005B;TAG LEFT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;;
19056 E005C;TAG REVERSE SOLIDUS;Cf;0;BN;;;;;N;;;;;
19057 E005D;TAG RIGHT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;;
19058 E005E;TAG CIRCUMFLEX ACCENT;Cf;0;BN;;;;;N;;;;;
19059 E005F;TAG LOW LINE;Cf;0;BN;;;;;N;;;;;
19060 E0060;TAG GRAVE ACCENT;Cf;0;BN;;;;;N;;;;;
19061 E0061;TAG LATIN SMALL LETTER A;Cf;0;BN;;;;;N;;;;;
19062 E0062;TAG LATIN SMALL LETTER B;Cf;0;BN;;;;;N;;;;;
19063 E0063;TAG LATIN SMALL LETTER C;Cf;0;BN;;;;;N;;;;;
19064 E0064;TAG LATIN SMALL LETTER D;Cf;0;BN;;;;;N;;;;;
19065 E0065;TAG LATIN SMALL LETTER E;Cf;0;BN;;;;;N;;;;;
19066 E0066;TAG LATIN SMALL LETTER F;Cf;0;BN;;;;;N;;;;;
19067 E0067;TAG LATIN SMALL LETTER G;Cf;0;BN;;;;;N;;;;;
19068 E0068;TAG LATIN SMALL LETTER H;Cf;0;BN;;;;;N;;;;;
19069 E0069;TAG LATIN SMALL LETTER I;Cf;0;BN;;;;;N;;;;;
19070 E006A;TAG LATIN SMALL LETTER J;Cf;0;BN;;;;;N;;;;;
19071 E006B;TAG LATIN SMALL LETTER K;Cf;0;BN;;;;;N;;;;;
19072 E006C;TAG LATIN SMALL LETTER L;Cf;0;BN;;;;;N;;;;;
19073 E006D;TAG LATIN SMALL LETTER M;Cf;0;BN;;;;;N;;;;;
19074 E006E;TAG LATIN SMALL LETTER N;Cf;0;BN;;;;;N;;;;;
19075 E006F;TAG LATIN SMALL LETTER O;Cf;0;BN;;;;;N;;;;;
19076 E0070;TAG LATIN SMALL LETTER P;Cf;0;BN;;;;;N;;;;;
19077 E0071;TAG LATIN SMALL LETTER Q;Cf;0;BN;;;;;N;;;;;
19078 E0072;TAG LATIN SMALL LETTER R;Cf;0;BN;;;;;N;;;;;
19079 E0073;TAG LATIN SMALL LETTER S;Cf;0;BN;;;;;N;;;;;
19080 E0074;TAG LATIN SMALL LETTER T;Cf;0;BN;;;;;N;;;;;
19081 E0075;TAG LATIN SMALL LETTER U;Cf;0;BN;;;;;N;;;;;
19082 E0076;TAG LATIN SMALL LETTER V;Cf;0;BN;;;;;N;;;;;
19083 E0077;TAG LATIN SMALL LETTER W;Cf;0;BN;;;;;N;;;;;
19084 E0078;TAG LATIN SMALL LETTER X;Cf;0;BN;;;;;N;;;;;
19085 E0079;TAG LATIN SMALL LETTER Y;Cf;0;BN;;;;;N;;;;;
19086 E007A;TAG LATIN SMALL LETTER Z;Cf;0;BN;;;;;N;;;;;
19087 E007B;TAG LEFT CURLY BRACKET;Cf;0;BN;;;;;N;;;;;
19088 E007C;TAG VERTICAL LINE;Cf;0;BN;;;;;N;;;;;
19089 E007D;TAG RIGHT CURLY BRACKET;Cf;0;BN;;;;;N;;;;;
19090 E007E;TAG TILDE;Cf;0;BN;;;;;N;;;;;
19091 E007F;CANCEL TAG;Cf;0;BN;;;;;N;;;;;
19092 E0100;VARIATION SELECTOR-17;Mn;0;NSM;;;;;N;;;;;
19093 E0101;VARIATION SELECTOR-18;Mn;0;NSM;;;;;N;;;;;
19094 E0102;VARIATION SELECTOR-19;Mn;0;NSM;;;;;N;;;;;
19095 E0103;VARIATION SELECTOR-20;Mn;0;NSM;;;;;N;;;;;
19096 E0104;VARIATION SELECTOR-21;Mn;0;NSM;;;;;N;;;;;
19097 E0105;VARIATION SELECTOR-22;Mn;0;NSM;;;;;N;;;;;
19098 E0106;VARIATION SELECTOR-23;Mn;0;NSM;;;;;N;;;;;
19099 E0107;VARIATION SELECTOR-24;Mn;0;NSM;;;;;N;;;;;
19100 E0108;VARIATION SELECTOR-25;Mn;0;NSM;;;;;N;;;;;
19101 E0109;VARIATION SELECTOR-26;Mn;0;NSM;;;;;N;;;;;
19102 E010A;VARIATION SELECTOR-27;Mn;0;NSM;;;;;N;;;;;
19103 E010B;VARIATION SELECTOR-28;Mn;0;NSM;;;;;N;;;;;
19104 E010C;VARIATION SELECTOR-29;Mn;0;NSM;;;;;N;;;;;
19105 E010D;VARIATION SELECTOR-30;Mn;0;NSM;;;;;N;;;;;
19106 E010E;VARIATION SELECTOR-31;Mn;0;NSM;;;;;N;;;;;
19107 E010F;VARIATION SELECTOR-32;Mn;0;NSM;;;;;N;;;;;
19108 E0110;VARIATION SELECTOR-33;Mn;0;NSM;;;;;N;;;;;
19109 E0111;VARIATION SELECTOR-34;Mn;0;NSM;;;;;N;;;;;
19110 E0112;VARIATION SELECTOR-35;Mn;0;NSM;;;;;N;;;;;
19111 E0113;VARIATION SELECTOR-36;Mn;0;NSM;;;;;N;;;;;
19112 E0114;VARIATION SELECTOR-37;Mn;0;NSM;;;;;N;;;;;
19113 E0115;VARIATION SELECTOR-38;Mn;0;NSM;;;;;N;;;;;
19114 E0116;VARIATION SELECTOR-39;Mn;0;NSM;;;;;N;;;;;
19115 E0117;VARIATION SELECTOR-40;Mn;0;NSM;;;;;N;;;;;
19116 E0118;VARIATION SELECTOR-41;Mn;0;NSM;;;;;N;;;;;
19117 E0119;VARIATION SELECTOR-42;Mn;0;NSM;;;;;N;;;;;
19118 E011A;VARIATION SELECTOR-43;Mn;0;NSM;;;;;N;;;;;
19119 E011B;VARIATION SELECTOR-44;Mn;0;NSM;;;;;N;;;;;
19120 E011C;VARIATION SELECTOR-45;Mn;0;NSM;;;;;N;;;;;
19121 E011D;VARIATION SELECTOR-46;Mn;0;NSM;;;;;N;;;;;
19122 E011E;VARIATION SELECTOR-47;Mn;0;NSM;;;;;N;;;;;
19123 E011F;VARIATION SELECTOR-48;Mn;0;NSM;;;;;N;;;;;
19124 E0120;VARIATION SELECTOR-49;Mn;0;NSM;;;;;N;;;;;
19125 E0121;VARIATION SELECTOR-50;Mn;0;NSM;;;;;N;;;;;
19126 E0122;VARIATION SELECTOR-51;Mn;0;NSM;;;;;N;;;;;
19127 E0123;VARIATION SELECTOR-52;Mn;0;NSM;;;;;N;;;;;
19128 E0124;VARIATION SELECTOR-53;Mn;0;NSM;;;;;N;;;;;
19129 E0125;VARIATION SELECTOR-54;Mn;0;NSM;;;;;N;;;;;
19130 E0126;VARIATION SELECTOR-55;Mn;0;NSM;;;;;N;;;;;
19131 E0127;VARIATION SELECTOR-56;Mn;0;NSM;;;;;N;;;;;
19132 E0128;VARIATION SELECTOR-57;Mn;0;NSM;;;;;N;;;;;
19133 E0129;VARIATION SELECTOR-58;Mn;0;NSM;;;;;N;;;;;
19134 E012A;VARIATION SELECTOR-59;Mn;0;NSM;;;;;N;;;;;
19135 E012B;VARIATION SELECTOR-60;Mn;0;NSM;;;;;N;;;;;
19136 E012C;VARIATION SELECTOR-61;Mn;0;NSM;;;;;N;;;;;
19137 E012D;VARIATION SELECTOR-62;Mn;0;NSM;;;;;N;;;;;
19138 E012E;VARIATION SELECTOR-63;Mn;0;NSM;;;;;N;;;;;
19139 E012F;VARIATION SELECTOR-64;Mn;0;NSM;;;;;N;;;;;
19140 E0130;VARIATION SELECTOR-65;Mn;0;NSM;;;;;N;;;;;
19141 E0131;VARIATION SELECTOR-66;Mn;0;NSM;;;;;N;;;;;
19142 E0132;VARIATION SELECTOR-67;Mn;0;NSM;;;;;N;;;;;
19143 E0133;VARIATION SELECTOR-68;Mn;0;NSM;;;;;N;;;;;
19144 E0134;VARIATION SELECTOR-69;Mn;0;NSM;;;;;N;;;;;
19145 E0135;VARIATION SELECTOR-70;Mn;0;NSM;;;;;N;;;;;
19146 E0136;VARIATION SELECTOR-71;Mn;0;NSM;;;;;N;;;;;
19147 E0137;VARIATION SELECTOR-72;Mn;0;NSM;;;;;N;;;;;
19148 E0138;VARIATION SELECTOR-73;Mn;0;NSM;;;;;N;;;;;
19149 E0139;VARIATION SELECTOR-74;Mn;0;NSM;;;;;N;;;;;
19150 E013A;VARIATION SELECTOR-75;Mn;0;NSM;;;;;N;;;;;
19151 E013B;VARIATION SELECTOR-76;Mn;0;NSM;;;;;N;;;;;
19152 E013C;VARIATION SELECTOR-77;Mn;0;NSM;;;;;N;;;;;
19153 E013D;VARIATION SELECTOR-78;Mn;0;NSM;;;;;N;;;;;
19154 E013E;VARIATION SELECTOR-79;Mn;0;NSM;;;;;N;;;;;
19155 E013F;VARIATION SELECTOR-80;Mn;0;NSM;;;;;N;;;;;
19156 E0140;VARIATION SELECTOR-81;Mn;0;NSM;;;;;N;;;;;
19157 E0141;VARIATION SELECTOR-82;Mn;0;NSM;;;;;N;;;;;
19158 E0142;VARIATION SELECTOR-83;Mn;0;NSM;;;;;N;;;;;
19159 E0143;VARIATION SELECTOR-84;Mn;0;NSM;;;;;N;;;;;
19160 E0144;VARIATION SELECTOR-85;Mn;0;NSM;;;;;N;;;;;
19161 E0145;VARIATION SELECTOR-86;Mn;0;NSM;;;;;N;;;;;
19162 E0146;VARIATION SELECTOR-87;Mn;0;NSM;;;;;N;;;;;
19163 E0147;VARIATION SELECTOR-88;Mn;0;NSM;;;;;N;;;;;
19164 E0148;VARIATION SELECTOR-89;Mn;0;NSM;;;;;N;;;;;
19165 E0149;VARIATION SELECTOR-90;Mn;0;NSM;;;;;N;;;;;
19166 E014A;VARIATION SELECTOR-91;Mn;0;NSM;;;;;N;;;;;
19167 E014B;VARIATION SELECTOR-92;Mn;0;NSM;;;;;N;;;;;
19168 E014C;VARIATION SELECTOR-93;Mn;0;NSM;;;;;N;;;;;
19169 E014D;VARIATION SELECTOR-94;Mn;0;NSM;;;;;N;;;;;
19170 E014E;VARIATION SELECTOR-95;Mn;0;NSM;;;;;N;;;;;
19171 E014F;VARIATION SELECTOR-96;Mn;0;NSM;;;;;N;;;;;
19172 E0150;VARIATION SELECTOR-97;Mn;0;NSM;;;;;N;;;;;
19173 E0151;VARIATION SELECTOR-98;Mn;0;NSM;;;;;N;;;;;
19174 E0152;VARIATION SELECTOR-99;Mn;0;NSM;;;;;N;;;;;
19175 E0153;VARIATION SELECTOR-100;Mn;0;NSM;;;;;N;;;;;
19176 E0154;VARIATION SELECTOR-101;Mn;0;NSM;;;;;N;;;;;
19177 E0155;VARIATION SELECTOR-102;Mn;0;NSM;;;;;N;;;;;
19178 E0156;VARIATION SELECTOR-103;Mn;0;NSM;;;;;N;;;;;
19179 E0157;VARIATION SELECTOR-104;Mn;0;NSM;;;;;N;;;;;
19180 E0158;VARIATION SELECTOR-105;Mn;0;NSM;;;;;N;;;;;
19181 E0159;VARIATION SELECTOR-106;Mn;0;NSM;;;;;N;;;;;
19182 E015A;VARIATION SELECTOR-107;Mn;0;NSM;;;;;N;;;;;
19183 E015B;VARIATION SELECTOR-108;Mn;0;NSM;;;;;N;;;;;
19184 E015C;VARIATION SELECTOR-109;Mn;0;NSM;;;;;N;;;;;
19185 E015D;VARIATION SELECTOR-110;Mn;0;NSM;;;;;N;;;;;
19186 E015E;VARIATION SELECTOR-111;Mn;0;NSM;;;;;N;;;;;
19187 E015F;VARIATION SELECTOR-112;Mn;0;NSM;;;;;N;;;;;
19188 E0160;VARIATION SELECTOR-113;Mn;0;NSM;;;;;N;;;;;
19189 E0161;VARIATION SELECTOR-114;Mn;0;NSM;;;;;N;;;;;
19190 E0162;VARIATION SELECTOR-115;Mn;0;NSM;;;;;N;;;;;
19191 E0163;VARIATION SELECTOR-116;Mn;0;NSM;;;;;N;;;;;
19192 E0164;VARIATION SELECTOR-117;Mn;0;NSM;;;;;N;;;;;
19193 E0165;VARIATION SELECTOR-118;Mn;0;NSM;;;;;N;;;;;
19194 E0166;VARIATION SELECTOR-119;Mn;0;NSM;;;;;N;;;;;
19195 E0167;VARIATION SELECTOR-120;Mn;0;NSM;;;;;N;;;;;
19196 E0168;VARIATION SELECTOR-121;Mn;0;NSM;;;;;N;;;;;
19197 E0169;VARIATION SELECTOR-122;Mn;0;NSM;;;;;N;;;;;
19198 E016A;VARIATION SELECTOR-123;Mn;0;NSM;;;;;N;;;;;
19199 E016B;VARIATION SELECTOR-124;Mn;0;NSM;;;;;N;;;;;
19200 E016C;VARIATION SELECTOR-125;Mn;0;NSM;;;;;N;;;;;
19201 E016D;VARIATION SELECTOR-126;Mn;0;NSM;;;;;N;;;;;
19202 E016E;VARIATION SELECTOR-127;Mn;0;NSM;;;;;N;;;;;
19203 E016F;VARIATION SELECTOR-128;Mn;0;NSM;;;;;N;;;;;
19204 E0170;VARIATION SELECTOR-129;Mn;0;NSM;;;;;N;;;;;
19205 E0171;VARIATION SELECTOR-130;Mn;0;NSM;;;;;N;;;;;
19206 E0172;VARIATION SELECTOR-131;Mn;0;NSM;;;;;N;;;;;
19207 E0173;VARIATION SELECTOR-132;Mn;0;NSM;;;;;N;;;;;
19208 E0174;VARIATION SELECTOR-133;Mn;0;NSM;;;;;N;;;;;
19209 E0175;VARIATION SELECTOR-134;Mn;0;NSM;;;;;N;;;;;
19210 E0176;VARIATION SELECTOR-135;Mn;0;NSM;;;;;N;;;;;
19211 E0177;VARIATION SELECTOR-136;Mn;0;NSM;;;;;N;;;;;
19212 E0178;VARIATION SELECTOR-137;Mn;0;NSM;;;;;N;;;;;
19213 E0179;VARIATION SELECTOR-138;Mn;0;NSM;;;;;N;;;;;
19214 E017A;VARIATION SELECTOR-139;Mn;0;NSM;;;;;N;;;;;
19215 E017B;VARIATION SELECTOR-140;Mn;0;NSM;;;;;N;;;;;
19216 E017C;VARIATION SELECTOR-141;Mn;0;NSM;;;;;N;;;;;
19217 E017D;VARIATION SELECTOR-142;Mn;0;NSM;;;;;N;;;;;
19218 E017E;VARIATION SELECTOR-143;Mn;0;NSM;;;;;N;;;;;
19219 E017F;VARIATION SELECTOR-144;Mn;0;NSM;;;;;N;;;;;
19220 E0180;VARIATION SELECTOR-145;Mn;0;NSM;;;;;N;;;;;
19221 E0181;VARIATION SELECTOR-146;Mn;0;NSM;;;;;N;;;;;
19222 E0182;VARIATION SELECTOR-147;Mn;0;NSM;;;;;N;;;;;
19223 E0183;VARIATION SELECTOR-148;Mn;0;NSM;;;;;N;;;;;
19224 E0184;VARIATION SELECTOR-149;Mn;0;NSM;;;;;N;;;;;
19225 E0185;VARIATION SELECTOR-150;Mn;0;NSM;;;;;N;;;;;
19226 E0186;VARIATION SELECTOR-151;Mn;0;NSM;;;;;N;;;;;
19227 E0187;VARIATION SELECTOR-152;Mn;0;NSM;;;;;N;;;;;
19228 E0188;VARIATION SELECTOR-153;Mn;0;NSM;;;;;N;;;;;
19229 E0189;VARIATION SELECTOR-154;Mn;0;NSM;;;;;N;;;;;
19230 E018A;VARIATION SELECTOR-155;Mn;0;NSM;;;;;N;;;;;
19231 E018B;VARIATION SELECTOR-156;Mn;0;NSM;;;;;N;;;;;
19232 E018C;VARIATION SELECTOR-157;Mn;0;NSM;;;;;N;;;;;
19233 E018D;VARIATION SELECTOR-158;Mn;0;NSM;;;;;N;;;;;
19234 E018E;VARIATION SELECTOR-159;Mn;0;NSM;;;;;N;;;;;
19235 E018F;VARIATION SELECTOR-160;Mn;0;NSM;;;;;N;;;;;
19236 E0190;VARIATION SELECTOR-161;Mn;0;NSM;;;;;N;;;;;
19237 E0191;VARIATION SELECTOR-162;Mn;0;NSM;;;;;N;;;;;
19238 E0192;VARIATION SELECTOR-163;Mn;0;NSM;;;;;N;;;;;
19239 E0193;VARIATION SELECTOR-164;Mn;0;NSM;;;;;N;;;;;
19240 E0194;VARIATION SELECTOR-165;Mn;0;NSM;;;;;N;;;;;
19241 E0195;VARIATION SELECTOR-166;Mn;0;NSM;;;;;N;;;;;
19242 E0196;VARIATION SELECTOR-167;Mn;0;NSM;;;;;N;;;;;
19243 E0197;VARIATION SELECTOR-168;Mn;0;NSM;;;;;N;;;;;
19244 E0198;VARIATION SELECTOR-169;Mn;0;NSM;;;;;N;;;;;
19245 E0199;VARIATION SELECTOR-170;Mn;0;NSM;;;;;N;;;;;
19246 E019A;VARIATION SELECTOR-171;Mn;0;NSM;;;;;N;;;;;
19247 E019B;VARIATION SELECTOR-172;Mn;0;NSM;;;;;N;;;;;
19248 E019C;VARIATION SELECTOR-173;Mn;0;NSM;;;;;N;;;;;
19249 E019D;VARIATION SELECTOR-174;Mn;0;NSM;;;;;N;;;;;
19250 E019E;VARIATION SELECTOR-175;Mn;0;NSM;;;;;N;;;;;
19251 E019F;VARIATION SELECTOR-176;Mn;0;NSM;;;;;N;;;;;
19252 E01A0;VARIATION SELECTOR-177;Mn;0;NSM;;;;;N;;;;;
19253 E01A1;VARIATION SELECTOR-178;Mn;0;NSM;;;;;N;;;;;
19254 E01A2;VARIATION SELECTOR-179;Mn;0;NSM;;;;;N;;;;;
19255 E01A3;VARIATION SELECTOR-180;Mn;0;NSM;;;;;N;;;;;
19256 E01A4;VARIATION SELECTOR-181;Mn;0;NSM;;;;;N;;;;;
19257 E01A5;VARIATION SELECTOR-182;Mn;0;NSM;;;;;N;;;;;
19258 E01A6;VARIATION SELECTOR-183;Mn;0;NSM;;;;;N;;;;;
19259 E01A7;VARIATION SELECTOR-184;Mn;0;NSM;;;;;N;;;;;
19260 E01A8;VARIATION SELECTOR-185;Mn;0;NSM;;;;;N;;;;;
19261 E01A9;VARIATION SELECTOR-186;Mn;0;NSM;;;;;N;;;;;
19262 E01AA;VARIATION SELECTOR-187;Mn;0;NSM;;;;;N;;;;;
19263 E01AB;VARIATION SELECTOR-188;Mn;0;NSM;;;;;N;;;;;
19264 E01AC;VARIATION SELECTOR-189;Mn;0;NSM;;;;;N;;;;;
19265 E01AD;VARIATION SELECTOR-190;Mn;0;NSM;;;;;N;;;;;
19266 E01AE;VARIATION SELECTOR-191;Mn;0;NSM;;;;;N;;;;;
19267 E01AF;VARIATION SELECTOR-192;Mn;0;NSM;;;;;N;;;;;
19268 E01B0;VARIATION SELECTOR-193;Mn;0;NSM;;;;;N;;;;;
19269 E01B1;VARIATION SELECTOR-194;Mn;0;NSM;;;;;N;;;;;
19270 E01B2;VARIATION SELECTOR-195;Mn;0;NSM;;;;;N;;;;;
19271 E01B3;VARIATION SELECTOR-196;Mn;0;NSM;;;;;N;;;;;
19272 E01B4;VARIATION SELECTOR-197;Mn;0;NSM;;;;;N;;;;;
19273 E01B5;VARIATION SELECTOR-198;Mn;0;NSM;;;;;N;;;;;
19274 E01B6;VARIATION SELECTOR-199;Mn;0;NSM;;;;;N;;;;;
19275 E01B7;VARIATION SELECTOR-200;Mn;0;NSM;;;;;N;;;;;
19276 E01B8;VARIATION SELECTOR-201;Mn;0;NSM;;;;;N;;;;;
19277 E01B9;VARIATION SELECTOR-202;Mn;0;NSM;;;;;N;;;;;
19278 E01BA;VARIATION SELECTOR-203;Mn;0;NSM;;;;;N;;;;;
19279 E01BB;VARIATION SELECTOR-204;Mn;0;NSM;;;;;N;;;;;
19280 E01BC;VARIATION SELECTOR-205;Mn;0;NSM;;;;;N;;;;;
19281 E01BD;VARIATION SELECTOR-206;Mn;0;NSM;;;;;N;;;;;
19282 E01BE;VARIATION SELECTOR-207;Mn;0;NSM;;;;;N;;;;;
19283 E01BF;VARIATION SELECTOR-208;Mn;0;NSM;;;;;N;;;;;
19284 E01C0;VARIATION SELECTOR-209;Mn;0;NSM;;;;;N;;;;;
19285 E01C1;VARIATION SELECTOR-210;Mn;0;NSM;;;;;N;;;;;
19286 E01C2;VARIATION SELECTOR-211;Mn;0;NSM;;;;;N;;;;;
19287 E01C3;VARIATION SELECTOR-212;Mn;0;NSM;;;;;N;;;;;
19288 E01C4;VARIATION SELECTOR-213;Mn;0;NSM;;;;;N;;;;;
19289 E01C5;VARIATION SELECTOR-214;Mn;0;NSM;;;;;N;;;;;
19290 E01C6;VARIATION SELECTOR-215;Mn;0;NSM;;;;;N;;;;;
19291 E01C7;VARIATION SELECTOR-216;Mn;0;NSM;;;;;N;;;;;
19292 E01C8;VARIATION SELECTOR-217;Mn;0;NSM;;;;;N;;;;;
19293 E01C9;VARIATION SELECTOR-218;Mn;0;NSM;;;;;N;;;;;
19294 E01CA;VARIATION SELECTOR-219;Mn;0;NSM;;;;;N;;;;;
19295 E01CB;VARIATION SELECTOR-220;Mn;0;NSM;;;;;N;;;;;
19296 E01CC;VARIATION SELECTOR-221;Mn;0;NSM;;;;;N;;;;;
19297 E01CD;VARIATION SELECTOR-222;Mn;0;NSM;;;;;N;;;;;
19298 E01CE;VARIATION SELECTOR-223;Mn;0;NSM;;;;;N;;;;;
19299 E01CF;VARIATION SELECTOR-224;Mn;0;NSM;;;;;N;;;;;
19300 E01D0;VARIATION SELECTOR-225;Mn;0;NSM;;;;;N;;;;;
19301 E01D1;VARIATION SELECTOR-226;Mn;0;NSM;;;;;N;;;;;
19302 E01D2;VARIATION SELECTOR-227;Mn;0;NSM;;;;;N;;;;;
19303 E01D3;VARIATION SELECTOR-228;Mn;0;NSM;;;;;N;;;;;
19304 E01D4;VARIATION SELECTOR-229;Mn;0;NSM;;;;;N;;;;;
19305 E01D5;VARIATION SELECTOR-230;Mn;0;NSM;;;;;N;;;;;
19306 E01D6;VARIATION SELECTOR-231;Mn;0;NSM;;;;;N;;;;;
19307 E01D7;VARIATION SELECTOR-232;Mn;0;NSM;;;;;N;;;;;
19308 E01D8;VARIATION SELECTOR-233;Mn;0;NSM;;;;;N;;;;;
19309 E01D9;VARIATION SELECTOR-234;Mn;0;NSM;;;;;N;;;;;
19310 E01DA;VARIATION SELECTOR-235;Mn;0;NSM;;;;;N;;;;;
19311 E01DB;VARIATION SELECTOR-236;Mn;0;NSM;;;;;N;;;;;
19312 E01DC;VARIATION SELECTOR-237;Mn;0;NSM;;;;;N;;;;;
19313 E01DD;VARIATION SELECTOR-238;Mn;0;NSM;;;;;N;;;;;
19314 E01DE;VARIATION SELECTOR-239;Mn;0;NSM;;;;;N;;;;;
19315 E01DF;VARIATION SELECTOR-240;Mn;0;NSM;;;;;N;;;;;
19316 E01E0;VARIATION SELECTOR-241;Mn;0;NSM;;;;;N;;;;;
19317 E01E1;VARIATION SELECTOR-242;Mn;0;NSM;;;;;N;;;;;
19318 E01E2;VARIATION SELECTOR-243;Mn;0;NSM;;;;;N;;;;;
19319 E01E3;VARIATION SELECTOR-244;Mn;0;NSM;;;;;N;;;;;
19320 E01E4;VARIATION SELECTOR-245;Mn;0;NSM;;;;;N;;;;;
19321 E01E5;VARIATION SELECTOR-246;Mn;0;NSM;;;;;N;;;;;
19322 E01E6;VARIATION SELECTOR-247;Mn;0;NSM;;;;;N;;;;;
19323 E01E7;VARIATION SELECTOR-248;Mn;0;NSM;;;;;N;;;;;
19324 E01E8;VARIATION SELECTOR-249;Mn;0;NSM;;;;;N;;;;;
19325 E01E9;VARIATION SELECTOR-250;Mn;0;NSM;;;;;N;;;;;
19326 E01EA;VARIATION SELECTOR-251;Mn;0;NSM;;;;;N;;;;;
19327 E01EB;VARIATION SELECTOR-252;Mn;0;NSM;;;;;N;;;;;
19328 E01EC;VARIATION SELECTOR-253;Mn;0;NSM;;;;;N;;;;;
19329 E01ED;VARIATION SELECTOR-254;Mn;0;NSM;;;;;N;;;;;
19330 E01EE;VARIATION SELECTOR-255;Mn;0;NSM;;;;;N;;;;;
19331 E01EF;VARIATION SELECTOR-256;Mn;0;NSM;;;;;N;;;;;
19332 F0000;<Plane 15 Private Use, First>;Co;0;L;;;;;N;;;;;
19333 FFFFD;<Plane 15 Private Use, Last>;Co;0;L;;;;;N;;;;;
19334 100000;<Plane 16 Private Use, First>;Co;0;L;;;;;N;;;;;
19335 10FFFD;<Plane 16 Private Use, Last>;Co;0;L;;;;;N;;;;;
0 #!/usr/bin/perl
1 # Generate keysym2ucs.c file
2 #
3 # $XFree86: xc/programs/xterm/unicode/convmap.pl,v 1.5 2000/01/24 22:22:05 dawes Exp $
4
5 sub utf8 ($) {
6 my $c = shift(@_);
7
8 if ($c < 0x80) {
9 return sprintf("%c", $c);
10 } elsif ($c < 0x800) {
11 return sprintf("%c%c", 0xc0 | ($c >> 6), 0x80 | ($c & 0x3f));
12 } elsif ($c < 0x10000) {
13 return sprintf("%c%c%c",
14 0xe0 | ($c >> 12),
15 0x80 | (($c >> 6) & 0x3f),
16 0x80 | ( $c & 0x3f));
17 } elsif ($c < 0x200000) {
18 return sprintf("%c%c%c%c",
19 0xf0 | ($c >> 18),
20 0x80 | (($c >> 12) & 0x3f),
21 0x80 | (($c >> 6) & 0x3f),
22 0x80 | ( $c & 0x3f));
23 } elsif ($c < 0x4000000) {
24 return sprintf("%c%c%c%c%c",
25 0xf8 | ($c >> 24),
26 0x80 | (($c >> 18) & 0x3f),
27 0x80 | (($c >> 12) & 0x3f),
28 0x80 | (($c >> 6) & 0x3f),
29 0x80 | ( $c & 0x3f));
30
31 } elsif ($c < 0x80000000) {
32 return sprintf("%c%c%c%c%c%c",
33 0xfe | ($c >> 30),
34 0x80 | (($c >> 24) & 0x3f),
35 0x80 | (($c >> 18) & 0x3f),
36 0x80 | (($c >> 12) & 0x3f),
37 0x80 | (($c >> 6) & 0x3f),
38 0x80 | ( $c & 0x3f));
39 } else {
40 return utf8(0xfffd);
41 }
42 }
43
44 $unicodedata = "UnicodeData.txt";
45
46 # read list of all Unicode names
47 if (!open(UDATA, $unicodedata) && !open(UDATA, "$unicodedata")) {
48 die ("Can't open Unicode database '$unicodedata':\n$!\n\n" .
49 "Please make sure that you have downloaded the file\n" .
50 "ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData-Latest.txt\n");
51 }
52 while (<UDATA>) {
53 if (/^([0-9,A-F]{4});([^;]*);([^;]*);([^;]*);([^;]*);([^;]*);([^;]*);([^;]*);([^;]*);([^;]*);([^;]*);([^;]*);([^;]*);([^;]*);([^;]*)$/) {
54 $name{hex($1)} = $2;
55 } else {
56 next;
57 die("Syntax error in line '$_' in file '$unicodedata'");
58 }
59 }
60 close(UDATA);
61
62 # read mapping (from http://wsinwp07.win.tue.nl:1234/unicode/keysym.map)
63 open(LIST, "<keysym.map") || die ("Can't open map file:\n$!\n");
64 while (<LIST>) {
65 if (/^0x([0-9a-f]{4})\s+U([0-9a-f]{4})\s*(\#.*)?$/){
66 $keysym = hex($1);
67 $ucs = hex($2);
68 $keysym_to_ucs{$keysym} = $ucs;
69 } elsif (/^\s*\#/ || /^\s*$/) {
70 } else {
71 die("Syntax error in 'list' in line\n$_\n");
72 }
73 }
74 close(LIST);
75
76 # read entries in keysymdef.h
77 open(LIST, "</usr/include/X11/keysymdef.h") || die ("Can't open keysymdef.h:\n$!\n");
78 while (<LIST>) {
79 if (/^\#define\s+XK_([A-Za-z_0-9]+)\s+0x([0-9a-fA-F]+)\s*(\/.*)?$/) {
80 next if /\/\* deprecated \*\//;
81 $keysymname = $1;
82 $keysym = hex($2);
83 $keysym_to_keysymname{$keysym} = $keysymname;
84 }
85 }
86 close(LIST);
87
88 print <<EOT;
89 /* \$XFree86\$
90 * This module converts keysym values into the corresponding ISO 10646-1
91 * (UCS, Unicode) values.
92 *
93 * The array keysymtab[] contains pairs of X11 keysym values for graphical
94 * characters and the corresponding Unicode value. The function
95 * keysym2ucs() maps a keysym onto a Unicode value using a binary search,
96 * therefore keysymtab[] must remain SORTED by keysym value.
97 *
98 * The keysym -> UTF-8 conversion will hopefully one day be provided
99 * by Xlib via XmbLookupString() and should ideally not have to be
100 * done in X applications. But we are not there yet.
101 *
102 * We allow to represent any UCS character in the range U+00000000 to
103 * U+00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff.
104 * This admittedly does not cover the entire 31-bit space of UCS, but
105 * it does cover all of the characters up to U+10FFFF, which can be
106 * represented by UTF-16, and more, and it is very unlikely that higher
107 * UCS codes will ever be assigned by ISO. So to get Unicode character
108 * U+ABCD you can directly use keysym 0x1000abcd.
109 *
110 * NOTE: The comments in the table below contain the actual character
111 * encoded in UTF-8, so for viewing and editing best use an editor in
112 * UTF-8 mode.
113 *
114 * Author: Markus G. Kuhn <mkuhn\@acm.org>, University of Cambridge, June 1999
115 *
116 * Special thanks to Richard Verhoeven <river\@win.tue.nl> for preparing
117 * an initial draft of the mapping table.
118 *
119 * This software is in the public domain. Share and enjoy!
120 */
121
122 #include <keysym2ucs.h>
123
124 struct codepair {
125 unsigned short keysym;
126 unsigned short ucs;
127 } keysymtab[] = {
128 EOT
129
130 for $keysym (sort {$a <=> $b} keys(%keysym_to_keysymname)) {
131 $ucs = $keysym_to_ucs{$keysym};
132 next if $keysym >= 0xf000 || $keysym < 0x100;
133 if ($ucs) {
134 printf(" { 0x%04x, 0x%04x }, /*%28s %s %s */\n",
135 $keysym, $ucs, $keysym_to_keysymname{$keysym}, utf8($ucs),
136 defined($name{$ucs}) ? $name{$ucs} : "???" );
137 } else {
138 printf("/* 0x%04x %39s ? ??? */\n",
139 $keysym, $keysym_to_keysymname{$keysym});
140 }
141 }
142
143 print <<EOT;
144 };
145
146 long keysym2ucs(KeySym keysym)
147 {
148 int min = 0;
149 int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
150 int mid;
151
152 /* first check for Latin-1 characters (1:1 mapping) */
153 if ((keysym >= 0x0020 && keysym <= 0x007e) ||
154 (keysym >= 0x00a0 && keysym <= 0x00ff))
155 return keysym;
156
157 /* also check for directly encoded 24-bit UCS characters */
158 if ((keysym & 0xff000000) == 0x01000000)
159 return keysym & 0x00ffffff;
160
161 /* binary search in table */
162 while (max >= min) {
163 mid = (min + max) / 2;
164 if (keysymtab[mid].keysym < keysym)
165 min = mid + 1;
166 else if (keysymtab[mid].keysym > keysym)
167 max = mid - 1;
168 else {
169 /* found it */
170 return keysymtab[mid].ucs;
171 }
172 }
173
174 /* no matching Unicode value found */
175 return -1;
176 }
177 EOT
0 #pragma once
1
2 #include <config.h>
3
4 #include <err.h>
5
6 #define die(...) errx(EXIT_FAILURE, __VA_ARGS__);
7 #define FREE(pointer) \
8 do { \
9 free(pointer); \
10 pointer = NULL; \
11 } while (0)
12
13 extern xcb_window_t root;
0 # This list can be used to convert X11 Keysyms to Unicode 2.1 character.
1 # The list is not checked for correctness by Unicode officials. Use it
2 # at your own risk and the creator is not responsable for any damage that
3 # occurred due to using this list.
4 #
5 # The list is created by looking at the Keysym names and the Unicode data
6 # file. Other mapping tables were used as a reference where needed.
7 # Due to a lack of knowledge of the Hebrew, Thai and Hangul symbols,
8 # expect errors in these sections. The mapping of the keypad keys
9 # might also require some adjustments.
10 #
11 # The following fields are used:
12 # 1 The X11 keysym numbers from the include file keysymdef.h
13 # 2 The Unicode (2.1) position (U0000 means unknown Unicode position)
14 # #
15 # 3 the name of the X11 keysym (without XK_)
16 #
17 # Authors: Richard Verhoeven, TUE, <[email protected]>
18 # Markus Kuhn, University of Cambridge, <[email protected]>
19 #
20 # You are free to use and modify this table. If you introduce errors
21 # in the table, please remove the copyright line. If you remove errors,
22 # please let me know, so I can update my version.
23 #
24 # $XFree86: xc/programs/xterm/unicode/keysym.map,v 1.1 1999/06/12 15:37:24 dawes Exp $
25 #
26 0x0020 U0020 # space
27 0x0021 U0021 # exclam
28 0x0022 U0022 # quotedbl
29 0x0023 U0023 # numbersign
30 0x0024 U0024 # dollar
31 0x0025 U0025 # percent
32 0x0026 U0026 # ampersand
33 0x0027 U0027 # apostrophe
34 0x0027 U0027 # quoteright /* deprecated */
35 0x0028 U0028 # parenleft
36 0x0029 U0029 # parenright
37 0x002a U002a # asterisk
38 0x002b U002b # plus
39 0x002c U002c # comma
40 0x002d U002d # minus
41 0x002e U002e # period
42 0x002f U002f # slash
43 0x0030 U0030 # 0
44 0x0031 U0031 # 1
45 0x0032 U0032 # 2
46 0x0033 U0033 # 3
47 0x0034 U0034 # 4
48 0x0035 U0035 # 5
49 0x0036 U0036 # 6
50 0x0037 U0037 # 7
51 0x0038 U0038 # 8
52 0x0039 U0039 # 9
53 0x003a U003a # colon
54 0x003b U003b # semicolon
55 0x003c U003c # less
56 0x003d U003d # equal
57 0x003e U003e # greater
58 0x003f U003f # question
59 0x0040 U0040 # at
60 0x0041 U0041 # A
61 0x0042 U0042 # B
62 0x0043 U0043 # C
63 0x0044 U0044 # D
64 0x0045 U0045 # E
65 0x0046 U0046 # F
66 0x0047 U0047 # G
67 0x0048 U0048 # H
68 0x0049 U0049 # I
69 0x004a U004a # J
70 0x004b U004b # K
71 0x004c U004c # L
72 0x004d U004d # M
73 0x004e U004e # N
74 0x004f U004f # O
75 0x0050 U0050 # P
76 0x0051 U0051 # Q
77 0x0052 U0052 # R
78 0x0053 U0053 # S
79 0x0054 U0054 # T
80 0x0055 U0055 # U
81 0x0056 U0056 # V
82 0x0057 U0057 # W
83 0x0058 U0058 # X
84 0x0059 U0059 # Y
85 0x005a U005a # Z
86 0x005b U005b # bracketleft
87 0x005c U005c # backslash
88 0x005d U005d # bracketright
89 0x005e U005e # asciicircum
90 0x005f U005f # underscore
91 0x0060 U0060 # grave
92 0x0060 U0060 # quoteleft /* deprecated */
93 0x0061 U0061 # a
94 0x0062 U0062 # b
95 0x0063 U0063 # c
96 0x0064 U0064 # d
97 0x0065 U0065 # e
98 0x0066 U0066 # f
99 0x0067 U0067 # g
100 0x0068 U0068 # h
101 0x0069 U0069 # i
102 0x006a U006a # j
103 0x006b U006b # k
104 0x006c U006c # l
105 0x006d U006d # m
106 0x006e U006e # n
107 0x006f U006f # o
108 0x0070 U0070 # p
109 0x0071 U0071 # q
110 0x0072 U0072 # r
111 0x0073 U0073 # s
112 0x0074 U0074 # t
113 0x0075 U0075 # u
114 0x0076 U0076 # v
115 0x0077 U0077 # w
116 0x0078 U0078 # x
117 0x0079 U0079 # y
118 0x007a U007a # z
119 0x007b U007b # braceleft
120 0x007c U007c # bar
121 0x007d U007d # braceright
122 0x007e U007e # asciitilde
123 0x00a0 U00a0 # nobreakspace
124 0x00a1 U00a1 # exclamdown
125 0x00a2 U00a2 # cent
126 0x00a3 U00a3 # sterling
127 0x00a4 U00a4 # currency
128 0x00a5 U00a5 # yen
129 0x00a6 U00a6 # brokenbar
130 0x00a7 U00a7 # section
131 0x00a8 U00a8 # diaeresis
132 0x00a9 U00a9 # copyright
133 0x00aa U00aa # ordfeminine
134 0x00ab U00ab # guillemotleft /* left angle quotation mark */
135 0x00ac U00ac # notsign
136 0x00ad U00ad # hyphen
137 0x00ae U00ae # registered
138 0x00af U00af # macron
139 0x00b0 U00b0 # degree
140 0x00b1 U00b1 # plusminus
141 0x00b2 U00b2 # twosuperior
142 0x00b3 U00b3 # threesuperior
143 0x00b4 U00b4 # acute
144 0x00b5 U00b5 # mu
145 0x00b6 U00b6 # paragraph
146 0x00b7 U00b7 # periodcentered
147 0x00b8 U00b8 # cedilla
148 0x00b9 U00b9 # onesuperior
149 0x00ba U00ba # masculine
150 0x00bb U00bb # guillemotright /* right angle quotation mark */
151 0x00bc U00bc # onequarter
152 0x00bd U00bd # onehalf
153 0x00be U00be # threequarters
154 0x00bf U00bf # questiondown
155 0x00c0 U00c0 # Agrave
156 0x00c1 U00c1 # Aacute
157 0x00c2 U00c2 # Acircumflex
158 0x00c3 U00c3 # Atilde
159 0x00c4 U00c4 # Adiaeresis
160 0x00c5 U00c5 # Aring
161 0x00c6 U00c6 # AE
162 0x00c7 U00c7 # Ccedilla
163 0x00c8 U00c8 # Egrave
164 0x00c9 U00c9 # Eacute
165 0x00ca U00ca # Ecircumflex
166 0x00cb U00cb # Ediaeresis
167 0x00cc U00cc # Igrave
168 0x00cd U00cd # Iacute
169 0x00ce U00ce # Icircumflex
170 0x00cf U00cf # Idiaeresis
171 0x00d0 U00d0 # ETH
172 0x00d0 U00d0 # Eth /* deprecated */
173 0x00d1 U00d1 # Ntilde
174 0x00d2 U00d2 # Ograve
175 0x00d3 U00d3 # Oacute
176 0x00d4 U00d4 # Ocircumflex
177 0x00d5 U00d5 # Otilde
178 0x00d6 U00d6 # Odiaeresis
179 0x00d7 U00d7 # multiply
180 0x00d8 U00d8 # Ooblique
181 0x00d9 U00d9 # Ugrave
182 0x00da U00da # Uacute
183 0x00db U00db # Ucircumflex
184 0x00dc U00dc # Udiaeresis
185 0x00dd U00dd # Yacute
186 0x00de U00de # THORN
187 0x00de U00de # Thorn /* deprecated */
188 0x00df U00df # ssharp
189 0x00e0 U00e0 # agrave
190 0x00e1 U00e1 # aacute
191 0x00e2 U00e2 # acircumflex
192 0x00e3 U00e3 # atilde
193 0x00e4 U00e4 # adiaeresis
194 0x00e5 U00e5 # aring
195 0x00e6 U00e6 # ae
196 0x00e7 U00e7 # ccedilla
197 0x00e8 U00e8 # egrave
198 0x00e9 U00e9 # eacute
199 0x00ea U00ea # ecircumflex
200 0x00eb U00eb # ediaeresis
201 0x00ec U00ec # igrave
202 0x00ed U00ed # iacute
203 0x00ee U00ee # icircumflex
204 0x00ef U00ef # idiaeresis
205 0x00f0 U00f0 # eth
206 0x00f1 U00f1 # ntilde
207 0x00f2 U00f2 # ograve
208 0x00f3 U00f3 # oacute
209 0x00f4 U00f4 # ocircumflex
210 0x00f5 U00f5 # otilde
211 0x00f6 U00f6 # odiaeresis
212 0x00f7 U00f7 # division
213 0x00f8 U00f8 # oslash
214 0x00f9 U00f9 # ugrave
215 0x00fa U00fa # uacute
216 0x00fb U00fb # ucircumflex
217 0x00fc U00fc # udiaeresis
218 0x00fd U00fd # yacute
219 0x00fe U00fe # thorn
220 0x00ff U00ff # ydiaeresis
221 0x01a1 U0104 # Aogonek
222 0x01a2 U02d8 # breve
223 0x01a3 U0141 # Lstroke
224 0x01a5 U013d # Lcaron
225 0x01a6 U015a # Sacute
226 0x01a9 U0160 # Scaron
227 0x01aa U015e # Scedilla
228 0x01ab U0164 # Tcaron
229 0x01ac U0179 # Zacute
230 0x01ae U017d # Zcaron
231 0x01af U017b # Zabovedot
232 0x01b1 U0105 # aogonek
233 0x01b2 U02db # ogonek
234 0x01b3 U0142 # lstroke
235 0x01b5 U013e # lcaron
236 0x01b6 U015b # sacute
237 0x01b7 U02c7 # caron
238 0x01b9 U0161 # scaron
239 0x01ba U015f # scedilla
240 0x01bb U0165 # tcaron
241 0x01bc U017a # zacute
242 0x01bd U02dd # doubleacute
243 0x01be U017e # zcaron
244 0x01bf U017c # zabovedot
245 0x01c0 U0154 # Racute
246 0x01c3 U0102 # Abreve
247 0x01c5 U0139 # Lacute
248 0x01c6 U0106 # Cacute
249 0x01c8 U010c # Ccaron
250 0x01ca U0118 # Eogonek
251 0x01cc U011a # Ecaron
252 0x01cf U010e # Dcaron
253 0x01d0 U0110 # Dstroke
254 0x01d1 U0143 # Nacute
255 0x01d2 U0147 # Ncaron
256 0x01d5 U0150 # Odoubleacute
257 0x01d8 U0158 # Rcaron
258 0x01d9 U016e # Uring
259 0x01db U0170 # Udoubleacute
260 0x01de U0162 # Tcedilla
261 0x01e0 U0155 # racute
262 0x01e3 U0103 # abreve
263 0x01e5 U013a # lacute
264 0x01e6 U0107 # cacute
265 0x01e8 U010d # ccaron
266 0x01ea U0119 # eogonek
267 0x01ec U011b # ecaron
268 0x01ef U010f # dcaron
269 0x01f0 U0111 # dstroke
270 0x01f1 U0144 # nacute
271 0x01f2 U0148 # ncaron
272 0x01f5 U0151 # odoubleacute
273 0x01f8 U0159 # rcaron
274 0x01f9 U016f # uring
275 0x01fb U0171 # udoubleacute
276 0x01fe U0163 # tcedilla
277 0x01ff U02d9 # abovedot
278 0x02a1 U0126 # Hstroke
279 0x02a6 U0124 # Hcircumflex
280 0x02a9 U0130 # Iabovedot
281 0x02ab U011e # Gbreve
282 0x02ac U0134 # Jcircumflex
283 0x02b1 U0127 # hstroke
284 0x02b6 U0125 # hcircumflex
285 0x02b9 U0131 # idotless
286 0x02bb U011f # gbreve
287 0x02bc U0135 # jcircumflex
288 0x02c5 U010a # Cabovedot
289 0x02c6 U0108 # Ccircumflex
290 0x02d5 U0120 # Gabovedot
291 0x02d8 U011c # Gcircumflex
292 0x02dd U016c # Ubreve
293 0x02de U015c # Scircumflex
294 0x02e5 U010b # cabovedot
295 0x02e6 U0109 # ccircumflex
296 0x02f5 U0121 # gabovedot
297 0x02f8 U011d # gcircumflex
298 0x02fd U016d # ubreve
299 0x02fe U015d # scircumflex
300 0x03a2 U0138 # kra
301 0x03a3 U0156 # Rcedilla
302 0x03a5 U0128 # Itilde
303 0x03a6 U013b # Lcedilla
304 0x03aa U0112 # Emacron
305 0x03ab U0122 # Gcedilla
306 0x03ac U0166 # Tslash
307 0x03b3 U0157 # rcedilla
308 0x03b5 U0129 # itilde
309 0x03b6 U013c # lcedilla
310 0x03ba U0113 # emacron
311 0x03bb U0123 # gcedilla
312 0x03bc U0167 # tslash
313 0x03bd U014a # ENG
314 0x03bf U014b # eng
315 0x03c0 U0100 # Amacron
316 0x03c7 U012e # Iogonek
317 0x03cc U0116 # Eabovedot
318 0x03cf U012a # Imacron
319 0x03d1 U0145 # Ncedilla
320 0x03d2 U014c # Omacron
321 0x03d3 U0136 # Kcedilla
322 0x03d9 U0172 # Uogonek
323 0x03dd U0168 # Utilde
324 0x03de U016a # Umacron
325 0x03e0 U0101 # amacron
326 0x03e7 U012f # iogonek
327 0x03ec U0117 # eabovedot
328 0x03ef U012b # imacron
329 0x03f1 U0146 # ncedilla
330 0x03f2 U014d # omacron
331 0x03f3 U0137 # kcedilla
332 0x03f9 U0173 # uogonek
333 0x03fd U0169 # utilde
334 0x03fe U016b # umacron
335 0x13bc U0152 # OE
336 0x13bd U0153 # oe
337 0x13be U0178 # Ydiaeresis
338 0x047e U203e # overline
339 0x04a1 U3002 # kana_fullstop
340 0x04a2 U300c # kana_openingbracket
341 0x04a3 U300d # kana_closingbracket
342 0x04a4 U3001 # kana_comma
343 0x04a5 U30fb # kana_conjunctive
344 0x04a6 U30f2 # kana_WO
345 0x04a7 U30a1 # kana_a
346 0x04a8 U30a3 # kana_i
347 0x04a9 U30a5 # kana_u
348 0x04aa U30a7 # kana_e
349 0x04ab U30a9 # kana_o
350 0x04ac U30e3 # kana_ya
351 0x04ad U30e5 # kana_yu
352 0x04ae U30e7 # kana_yo
353 0x04af U30c3 # kana_tsu
354 0x04b0 U30fc # prolongedsound
355 0x04b1 U30a2 # kana_A
356 0x04b2 U30a4 # kana_I
357 0x04b3 U30a6 # kana_U
358 0x04b4 U30a8 # kana_E
359 0x04b5 U30aa # kana_O
360 0x04b6 U30ab # kana_KA
361 0x04b7 U30ad # kana_KI
362 0x04b8 U30af # kana_KU
363 0x04b9 U30b1 # kana_KE
364 0x04ba U30b3 # kana_KO
365 0x04bb U30b5 # kana_SA
366 0x04bc U30b7 # kana_SHI
367 0x04bd U30b9 # kana_SU
368 0x04be U30bb # kana_SE
369 0x04bf U30bd # kana_SO
370 0x04c0 U30bf # kana_TA
371 0x04c1 U30c1 # kana_CHI
372 0x04c2 U30c4 # kana_TSU
373 0x04c3 U30c6 # kana_TE
374 0x04c4 U30c8 # kana_TO
375 0x04c5 U30ca # kana_NA
376 0x04c6 U30cb # kana_NI
377 0x04c7 U30cc # kana_NU
378 0x04c8 U30cd # kana_NE
379 0x04c9 U30ce # kana_NO
380 0x04ca U30cf # kana_HA
381 0x04cb U30d2 # kana_HI
382 0x04cc U30d5 # kana_FU
383 0x04cd U30d8 # kana_HE
384 0x04ce U30db # kana_HO
385 0x04cf U30de # kana_MA
386 0x04d0 U30df # kana_MI
387 0x04d1 U30e0 # kana_MU
388 0x04d2 U30e1 # kana_ME
389 0x04d3 U30e2 # kana_MO
390 0x04d4 U30e4 # kana_YA
391 0x04d5 U30e6 # kana_YU
392 0x04d6 U30e8 # kana_YO
393 0x04d7 U30e9 # kana_RA
394 0x04d8 U30ea # kana_RI
395 0x04d9 U30eb # kana_RU
396 0x04da U30ec # kana_RE
397 0x04db U30ed # kana_RO
398 0x04dc U30ef # kana_WA
399 0x04dd U30f3 # kana_N
400 0x04de U309b # voicedsound
401 0x04df U309c # semivoicedsound
402 0x05ac U060c # Arabic_comma
403 0x05bb U061b # Arabic_semicolon
404 0x05bf U061f # Arabic_question_mark
405 0x05c1 U0621 # Arabic_hamza
406 0x05c2 U0622 # Arabic_maddaonalef
407 0x05c3 U0623 # Arabic_hamzaonalef
408 0x05c4 U0624 # Arabic_hamzaonwaw
409 0x05c5 U0625 # Arabic_hamzaunderalef
410 0x05c6 U0626 # Arabic_hamzaonyeh
411 0x05c7 U0627 # Arabic_alef
412 0x05c8 U0628 # Arabic_beh
413 0x05c9 U0629 # Arabic_tehmarbuta
414 0x05ca U062a # Arabic_teh
415 0x05cb U062b # Arabic_theh
416 0x05cc U062c # Arabic_jeem
417 0x05cd U062d # Arabic_hah
418 0x05ce U062e # Arabic_khah
419 0x05cf U062f # Arabic_dal
420 0x05d0 U0630 # Arabic_thal
421 0x05d1 U0631 # Arabic_ra
422 0x05d2 U0632 # Arabic_zain
423 0x05d3 U0633 # Arabic_seen
424 0x05d4 U0634 # Arabic_sheen
425 0x05d5 U0635 # Arabic_sad
426 0x05d6 U0636 # Arabic_dad
427 0x05d7 U0637 # Arabic_tah
428 0x05d8 U0638 # Arabic_zah
429 0x05d9 U0639 # Arabic_ain
430 0x05da U063a # Arabic_ghain
431 0x05e0 U0640 # Arabic_tatweel
432 0x05e1 U0641 # Arabic_feh
433 0x05e2 U0642 # Arabic_qaf
434 0x05e3 U0643 # Arabic_kaf
435 0x05e4 U0644 # Arabic_lam
436 0x05e5 U0645 # Arabic_meem
437 0x05e6 U0646 # Arabic_noon
438 0x05e7 U0647 # Arabic_ha
439 0x05e8 U0648 # Arabic_waw
440 0x05e9 U0649 # Arabic_alefmaksura
441 0x05ea U064a # Arabic_yeh
442 0x05eb U064b # Arabic_fathatan
443 0x05ec U064c # Arabic_dammatan
444 0x05ed U064d # Arabic_kasratan
445 0x05ee U064e # Arabic_fatha
446 0x05ef U064f # Arabic_damma
447 0x05f0 U0650 # Arabic_kasra
448 0x05f1 U0651 # Arabic_shadda
449 0x05f2 U0652 # Arabic_sukun
450 0x06a1 U0452 # Serbian_dje
451 0x06a2 U0453 # Macedonia_gje
452 0x06a3 U0451 # Cyrillic_io
453 0x06a4 U0454 # Ukrainian_ie
454 0x06a5 U0455 # Macedonia_dse
455 0x06a6 U0456 # Ukrainian_i
456 0x06a7 U0457 # Ukrainian_yi
457 0x06a8 U0458 # Cyrillic_je
458 0x06a9 U0459 # Cyrillic_lje
459 0x06aa U045a # Cyrillic_nje
460 0x06ab U045b # Serbian_tshe
461 0x06ac U045c # Macedonia_kje
462 0x06ae U045e # Byelorussian_shortu
463 0x06af U045f # Cyrillic_dzhe
464 0x06b0 U2116 # numerosign
465 0x06b1 U0402 # Serbian_DJE
466 0x06b2 U0403 # Macedonia_GJE
467 0x06b3 U0401 # Cyrillic_IO
468 0x06b4 U0404 # Ukrainian_IE
469 0x06b5 U0405 # Macedonia_DSE
470 0x06b6 U0406 # Ukrainian_I
471 0x06b7 U0407 # Ukrainian_YI
472 0x06b8 U0408 # Cyrillic_JE
473 0x06b9 U0409 # Cyrillic_LJE
474 0x06ba U040a # Cyrillic_NJE
475 0x06bb U040b # Serbian_TSHE
476 0x06bc U040c # Macedonia_KJE
477 0x06be U040e # Byelorussian_SHORTU
478 0x06bf U040f # Cyrillic_DZHE
479 0x06c0 U044e # Cyrillic_yu
480 0x06c1 U0430 # Cyrillic_a
481 0x06c2 U0431 # Cyrillic_be
482 0x06c3 U0446 # Cyrillic_tse
483 0x06c4 U0434 # Cyrillic_de
484 0x06c5 U0435 # Cyrillic_ie
485 0x06c6 U0444 # Cyrillic_ef
486 0x06c7 U0433 # Cyrillic_ghe
487 0x06c8 U0445 # Cyrillic_ha
488 0x06c9 U0438 # Cyrillic_i
489 0x06ca U0439 # Cyrillic_shorti
490 0x06cb U043a # Cyrillic_ka
491 0x06cc U043b # Cyrillic_el
492 0x06cd U043c # Cyrillic_em
493 0x06ce U043d # Cyrillic_en
494 0x06cf U043e # Cyrillic_o
495 0x06d0 U043f # Cyrillic_pe
496 0x06d1 U044f # Cyrillic_ya
497 0x06d2 U0440 # Cyrillic_er
498 0x06d3 U0441 # Cyrillic_es
499 0x06d4 U0442 # Cyrillic_te
500 0x06d5 U0443 # Cyrillic_u
501 0x06d6 U0436 # Cyrillic_zhe
502 0x06d7 U0432 # Cyrillic_ve
503 0x06d8 U044c # Cyrillic_softsign
504 0x06d9 U044b # Cyrillic_yeru
505 0x06da U0437 # Cyrillic_ze
506 0x06db U0448 # Cyrillic_sha
507 0x06dc U044d # Cyrillic_e
508 0x06dd U0449 # Cyrillic_shcha
509 0x06de U0447 # Cyrillic_che
510 0x06df U044a # Cyrillic_hardsign
511 0x06e0 U042e # Cyrillic_YU
512 0x06e1 U0410 # Cyrillic_A
513 0x06e2 U0411 # Cyrillic_BE
514 0x06e3 U0426 # Cyrillic_TSE
515 0x06e4 U0414 # Cyrillic_DE
516 0x06e5 U0415 # Cyrillic_IE
517 0x06e6 U0424 # Cyrillic_EF
518 0x06e7 U0413 # Cyrillic_GHE
519 0x06e8 U0425 # Cyrillic_HA
520 0x06e9 U0418 # Cyrillic_I
521 0x06ea U0419 # Cyrillic_SHORTI
522 0x06eb U041a # Cyrillic_KA
523 0x06ec U041b # Cyrillic_EL
524 0x06ed U041c # Cyrillic_EM
525 0x06ee U041d # Cyrillic_EN
526 0x06ef U041e # Cyrillic_O
527 0x06f0 U041f # Cyrillic_PE
528 0x06f1 U042f # Cyrillic_YA
529 0x06f2 U0420 # Cyrillic_ER
530 0x06f3 U0421 # Cyrillic_ES
531 0x06f4 U0422 # Cyrillic_TE
532 0x06f5 U0423 # Cyrillic_U
533 0x06f6 U0416 # Cyrillic_ZHE
534 0x06f7 U0412 # Cyrillic_VE
535 0x06f8 U042c # Cyrillic_SOFTSIGN
536 0x06f9 U042b # Cyrillic_YERU
537 0x06fa U0417 # Cyrillic_ZE
538 0x06fb U0428 # Cyrillic_SHA
539 0x06fc U042d # Cyrillic_E
540 0x06fd U0429 # Cyrillic_SHCHA
541 0x06fe U0427 # Cyrillic_CHE
542 0x06ff U042a # Cyrillic_HARDSIGN
543 0x07a1 U0386 # Greek_ALPHAaccent
544 0x07a2 U0388 # Greek_EPSILONaccent
545 0x07a3 U0389 # Greek_ETAaccent
546 0x07a4 U038a # Greek_IOTAaccent
547 0x07a5 U03aa # Greek_IOTAdiaeresis
548 0x07a7 U038c # Greek_OMICRONaccent
549 0x07a8 U038e # Greek_UPSILONaccent
550 0x07a9 U03ab # Greek_UPSILONdieresis
551 0x07ab U038f # Greek_OMEGAaccent
552 0x07ae U0385 # Greek_accentdieresis
553 0x07af U2015 # Greek_horizbar
554 0x07b1 U03ac # Greek_alphaaccent
555 0x07b2 U03ad # Greek_epsilonaccent
556 0x07b3 U03ae # Greek_etaaccent
557 0x07b4 U03af # Greek_iotaaccent
558 0x07b5 U03ca # Greek_iotadieresis
559 0x07b6 U0390 # Greek_iotaaccentdieresis
560 0x07b7 U03cc # Greek_omicronaccent
561 0x07b8 U03cd # Greek_upsilonaccent
562 0x07b9 U03cb # Greek_upsilondieresis
563 0x07ba U03b0 # Greek_upsilonaccentdieresis
564 0x07bb U03ce # Greek_omegaaccent
565 0x07c1 U0391 # Greek_ALPHA
566 0x07c2 U0392 # Greek_BETA
567 0x07c3 U0393 # Greek_GAMMA
568 0x07c4 U0394 # Greek_DELTA
569 0x07c5 U0395 # Greek_EPSILON
570 0x07c6 U0396 # Greek_ZETA
571 0x07c7 U0397 # Greek_ETA
572 0x07c8 U0398 # Greek_THETA
573 0x07c9 U0399 # Greek_IOTA
574 0x07ca U039a # Greek_KAPPA
575 0x07cb U039b # Greek_LAMBDA
576 0x07cb U039b # Greek_LAMDA
577 0x07cc U039c # Greek_MU
578 0x07cd U039d # Greek_NU
579 0x07ce U039e # Greek_XI
580 0x07cf U039f # Greek_OMICRON
581 0x07d0 U03a0 # Greek_PI
582 0x07d1 U03a1 # Greek_RHO
583 0x07d2 U03a3 # Greek_SIGMA
584 0x07d4 U03a4 # Greek_TAU
585 0x07d5 U03a5 # Greek_UPSILON
586 0x07d6 U03a6 # Greek_PHI
587 0x07d7 U03a7 # Greek_CHI
588 0x07d8 U03a8 # Greek_PSI
589 0x07d9 U03a9 # Greek_OMEGA
590 0x07e1 U03b1 # Greek_alpha
591 0x07e2 U03b2 # Greek_beta
592 0x07e3 U03b3 # Greek_gamma
593 0x07e4 U03b4 # Greek_delta
594 0x07e5 U03b5 # Greek_epsilon
595 0x07e6 U03b6 # Greek_zeta
596 0x07e7 U03b7 # Greek_eta
597 0x07e8 U03b8 # Greek_theta
598 0x07e9 U03b9 # Greek_iota
599 0x07ea U03ba # Greek_kappa
600 0x07eb U03bb # Greek_lambda
601 0x07ec U03bc # Greek_mu
602 0x07ed U03bd # Greek_nu
603 0x07ee U03be # Greek_xi
604 0x07ef U03bf # Greek_omicron
605 0x07f0 U03c0 # Greek_pi
606 0x07f1 U03c1 # Greek_rho
607 0x07f2 U03c3 # Greek_sigma
608 0x07f3 U03c2 # Greek_finalsmallsigma
609 0x07f4 U03c4 # Greek_tau
610 0x07f5 U03c5 # Greek_upsilon
611 0x07f6 U03c6 # Greek_phi
612 0x07f7 U03c7 # Greek_chi
613 0x07f8 U03c8 # Greek_psi
614 0x07f9 U03c9 # Greek_omega
615 0x08a1 U0000 # leftradical
616 0x08a2 U0000 # topleftradical
617 0x08a3 U0000 # horizconnector
618 0x08a4 U2320 # topintegral
619 0x08a5 U2321 # botintegral
620 0x08a6 U2502 # vertconnector
621 0x08a7 U0000 # topleftsqbracket
622 0x08a8 U0000 # botleftsqbracket
623 0x08a9 U0000 # toprightsqbracket
624 0x08aa U0000 # botrightsqbracket
625 0x08ab U0000 # topleftparens
626 0x08ac U0000 # botleftparens
627 0x08ad U0000 # toprightparens
628 0x08ae U0000 # botrightparens
629 0x08af U0000 # leftmiddlecurlybrace
630 0x08b0 U0000 # rightmiddlecurlybrace
631 0x08b1 U0000 # topleftsummation
632 0x08b2 U0000 # botleftsummation
633 0x08b3 U0000 # topvertsummationconnector
634 0x08b4 U0000 # botvertsummationconnector
635 0x08b5 U0000 # toprightsummation
636 0x08b6 U0000 # botrightsummation
637 0x08b7 U0000 # rightmiddlesummation
638 0x08bc U2264 # lessthanequal
639 0x08bd U2260 # notequal
640 0x08be U2265 # greaterthanequal
641 0x08bf U222b # integral
642 0x08c0 U2234 # therefore
643 0x08c1 U221d # variation
644 0x08c2 U221e # infinity
645 0x08c5 U2207 # nabla
646 0x08c8 U2245 # approximate
647 0x08c9 U0000 # similarequal
648 0x08cd U21d4 # ifonlyif
649 0x08ce U21d2 # implies
650 0x08cf U2261 # identical
651 0x08d6 U221a # radical
652 0x08da U2282 # includedin
653 0x08db U2283 # includes
654 0x08dc U2229 # intersection
655 0x08dd U222a # union
656 0x08de U2227 # logicaland
657 0x08df U2228 # logicalor
658 0x08ef U2202 # partialderivative
659 0x08f6 U0192 # function
660 0x08fb U2190 # leftarrow
661 0x08fc U2191 # uparrow
662 0x08fd U2192 # rightarrow
663 0x08fe U2193 # downarrow
664 0x09df U2422 # blank
665 0x09e0 U25c6 # soliddiamond
666 0x09e1 U2592 # checkerboard
667 0x09e2 U2409 # ht
668 0x09e3 U240c # ff
669 0x09e4 U240d # cr
670 0x09e5 U240a # lf
671 0x09e8 U2424 # nl
672 0x09e9 U240b # vt
673 0x09ea U2518 # lowrightcorner
674 0x09eb U2510 # uprightcorner
675 0x09ec U250c # upleftcorner
676 0x09ed U2514 # lowleftcorner
677 0x09ee U253c # crossinglines
678 0x09ef U0000 # horizlinescan1
679 0x09f0 U0000 # horizlinescan3
680 0x09f1 U2500 # horizlinescan5
681 0x09f2 U0000 # horizlinescan7
682 0x09f3 U0000 # horizlinescan9
683 0x09f4 U251c # leftt
684 0x09f5 U2524 # rightt
685 0x09f6 U2534 # bott
686 0x09f7 U252c # topt
687 0x09f8 U2502 # vertbar
688 0xfe50 U0300 # dead_grave
689 0xfe51 U0301 # dead_acute
690 0xfe52 U0302 # dead_circumflex
691 0xfe53 U0303 # dead_tilde
692 0xfe54 U0304 # dead_macron
693 0xfe55 U0306 # dead_breve
694 0xfe56 U0307 # dead_abovedot
695 0xfe57 U0308 # dead_diaeresis
696 0xfe58 U030a # dead_abovering
697 0xfe59 U030b # dead_doubleacute
698 0xfe5a U030c # dead_caron
699 0xfe5b U0327 # dead_cedilla
700 0xfe5c U0328 # dead_ogonek
701 0xfe5d U0345 # dead_iota
702 0xfe5e U3099 # dead_voiced_sound
703 0xfe5f U309a # dead_semivoiced_sound
704 0xff08 U0008 # BackSpace /* back space, back char */
705 0xff09 U0009 # Tab
706 0xff0a U000a # Linefeed /* Linefeed, LF */
707 0xff0b U000b # Clear
708 0xff0d U000d # Return /* Return, enter */
709 0xff13 U0013 # Pause /* Pause, hold */
710 0xff14 U0014 # Scroll_Lock
711 0xff15 U0015 # Sys_Req
712 0xff1b U001b # Escape
713 0xff80 U0032 # KP_Space /* space */
714 0xff89 U0009 # KP_Tab
715 0xff8d U000d # KP_Enter /* enter */
716 0xffaa U002a # KP_Multiply
717 0xffab U002b # KP_Add
718 0xffac U002c # KP_Separator /* separator, often comma */
719 0xffad U002d # KP_Subtract
720 0xffae U002e # KP_Decimal
721 0xffaf U002f # KP_Divide
722 0xffb0 U0030 # KP_0
723 0xffb1 U0031 # KP_1
724 0xffb2 U0032 # KP_2
725 0xffb3 U0033 # KP_3
726 0xffb4 U0034 # KP_4
727 0xffb5 U0035 # KP_5
728 0xffb6 U0036 # KP_6
729 0xffb7 U0037 # KP_7
730 0xffb8 U0038 # KP_8
731 0xffb9 U0039 # KP_9
732 0xffbd U003d # KP_Equal /* equals */
733 0x0aa1 U2003 # emspace
734 0x0aa2 U2002 # enspace
735 0x0aa3 U2004 # em3space
736 0x0aa4 U2005 # em4space
737 0x0aa5 U2007 # digitspace
738 0x0aa6 U2008 # punctspace
739 0x0aa7 U2009 # thinspace
740 0x0aa8 U200a # hairspace
741 0x0aa9 U2014 # emdash
742 0x0aaa U2013 # endash
743 0x0aac U0000 # signifblank
744 0x0aae U2026 # ellipsis
745 0x0aaf U0000 # doubbaselinedot
746 0x0ab0 U2153 # onethird
747 0x0ab1 U2154 # twothirds
748 0x0ab2 U2155 # onefifth
749 0x0ab3 U2156 # twofifths
750 0x0ab4 U2157 # threefifths
751 0x0ab5 U2158 # fourfifths
752 0x0ab6 U2159 # onesixth
753 0x0ab7 U215a # fivesixths
754 0x0ab8 U2105 # careof
755 0x0abb U2012 # figdash
756 0x0abc U2329 # leftanglebracket
757 0x0abd U002e # decimalpoint
758 0x0abe U232a # rightanglebracket
759 0x0abf U0000 # marker
760 0x0ac3 U215b # oneeighth
761 0x0ac4 U215c # threeeighths
762 0x0ac5 U215d # fiveeighths
763 0x0ac6 U215e # seveneighths
764 0x0ac9 U2122 # trademark
765 0x0aca U2613 # signaturemark
766 0x0acb U0000 # trademarkincircle
767 0x0acc U25c1 # leftopentriangle
768 0x0acd U25b7 # rightopentriangle
769 0x0ace U25cb # emopencircle
770 0x0acf U25a1 # emopenrectangle
771 0x0ad0 U2018 # leftsinglequotemark
772 0x0ad1 U2019 # rightsinglequotemark
773 0x0ad2 U201c # leftdoublequotemark
774 0x0ad3 U201d # rightdoublequotemark
775 0x0ad4 U211e # prescription
776 0x0ad6 U2032 # minutes
777 0x0ad7 U2033 # seconds
778 0x0ad9 U271d # latincross
779 0x0ada U0000 # hexagram
780 0x0adb U25ac # filledrectbullet
781 0x0adc U25c0 # filledlefttribullet
782 0x0add U25b6 # filledrighttribullet
783 0x0ade U25cf # emfilledcircle
784 0x0adf U25a0 # emfilledrect
785 0x0ae0 U25e6 # enopencircbullet
786 0x0ae1 U25ab # enopensquarebullet
787 0x0ae2 U25ad # openrectbullet
788 0x0ae3 U25b3 # opentribulletup
789 0x0ae4 U25bd # opentribulletdown
790 0x0ae5 U2606 # openstar
791 0x0ae6 U2022 # enfilledcircbullet
792 0x0ae7 U25aa # enfilledsqbullet
793 0x0ae8 U25b2 # filledtribulletup
794 0x0ae9 U25bc # filledtribulletdown
795 0x0aea U261c # leftpointer
796 0x0aeb U261e # rightpointer
797 0x0aec U2663 # club
798 0x0aed U2666 # diamond
799 0x0aee U2665 # heart
800 0x0af0 U2720 # maltesecross
801 0x0af1 U2020 # dagger
802 0x0af2 U2021 # doubledagger
803 0x0af3 U2713 # checkmark
804 0x0af4 U2717 # ballotcross
805 0x0af5 U266f # musicalsharp
806 0x0af6 U266d # musicalflat
807 0x0af7 U2642 # malesymbol
808 0x0af8 U2640 # femalesymbol
809 0x0af9 U260e # telephone
810 0x0afa U2315 # telephonerecorder
811 0x0afb U2117 # phonographcopyright
812 0x0afc U2038 # caret
813 0x0afd U201a # singlelowquotemark
814 0x0afe U201e # doublelowquotemark
815 0x0aff U0000 # cursor
816 0x0ba3 U003c # leftcaret
817 0x0ba6 U003e # rightcaret
818 0x0ba8 U2228 # downcaret
819 0x0ba9 U2227 # upcaret
820 0x0bc0 U00af # overbar
821 0x0bc2 U22a4 # downtack
822 0x0bc3 U2229 # upshoe
823 0x0bc4 U230a # downstile
824 0x0bc6 U005f # underbar
825 0x0bca U2218 # jot
826 0x0bcc U2395 # quad
827 0x0bce U22a5 # uptack
828 0x0bcf U25cb # circle
829 0x0bd3 U2308 # upstile
830 0x0bd6 U222a # downshoe
831 0x0bd8 U2283 # rightshoe
832 0x0bda U2282 # leftshoe
833 0x0bdc U22a3 # lefttack
834 0x0bfc U22a2 # righttack
835 0x0cdf U2017 # hebrew_doublelowline
836 0x0ce0 U05d0 # hebrew_aleph
837 0x0ce1 U05d1 # hebrew_bet
838 0x0ce1 U05d1 # hebrew_beth /* deprecated */
839 0x0ce2 U05d2 # hebrew_gimel
840 0x0ce2 U05d2 # hebrew_gimmel /* deprecated */
841 0x0ce3 U05d3 # hebrew_dalet
842 0x0ce3 U05d3 # hebrew_daleth /* deprecated */
843 0x0ce4 U05d4 # hebrew_he
844 0x0ce5 U05d5 # hebrew_waw
845 0x0ce6 U05d6 # hebrew_zain
846 0x0ce6 U05d6 # hebrew_zayin /* deprecated */
847 0x0ce7 U05d7 # hebrew_chet
848 0x0ce7 U05d7 # hebrew_het /* deprecated */
849 0x0ce8 U05d8 # hebrew_tet
850 0x0ce8 U05d8 # hebrew_teth /* deprecated */
851 0x0ce9 U05d9 # hebrew_yod
852 0x0cea U05da # hebrew_finalkaph
853 0x0ceb U05db # hebrew_kaph
854 0x0cec U05dc # hebrew_lamed
855 0x0ced U05dd # hebrew_finalmem
856 0x0cee U05de # hebrew_mem
857 0x0cef U05df # hebrew_finalnun
858 0x0cf0 U05e0 # hebrew_nun
859 0x0cf1 U05e1 # hebrew_samech
860 0x0cf1 U05e1 # hebrew_samekh /* deprecated */
861 0x0cf2 U05e2 # hebrew_ayin
862 0x0cf3 U05e3 # hebrew_finalpe
863 0x0cf4 U05e4 # hebrew_pe
864 0x0cf5 U05e5 # hebrew_finalzade
865 0x0cf5 U05e5 # hebrew_finalzadi /* deprecated */
866 0x0cf6 U05e6 # hebrew_zade
867 0x0cf6 U05e6 # hebrew_zadi /* deprecated */
868 0x0cf7 U05e7 # hebrew_kuf /* deprecated */
869 0x0cf7 U05e7 # hebrew_qoph
870 0x0cf8 U05e8 # hebrew_resh
871 0x0cf9 U05e9 # hebrew_shin
872 0x0cfa U05ea # hebrew_taf /* deprecated */
873 0x0cfa U05ea # hebrew_taw
874 0x0da1 U0e01 # Thai_kokai
875 0x0da2 U0e02 # Thai_khokhai
876 0x0da3 U0e03 # Thai_khokhuat
877 0x0da4 U0e04 # Thai_khokhwai
878 0x0da5 U0e05 # Thai_khokhon
879 0x0da6 U0e06 # Thai_khorakhang
880 0x0da7 U0e07 # Thai_ngongu
881 0x0da8 U0e08 # Thai_chochan
882 0x0da9 U0e09 # Thai_choching
883 0x0daa U0e0a # Thai_chochang
884 0x0dab U0e0b # Thai_soso
885 0x0dac U0e0c # Thai_chochoe
886 0x0dad U0e0d # Thai_yoying
887 0x0dae U0e0e # Thai_dochada
888 0x0daf U0e0f # Thai_topatak
889 0x0db0 U0e10 # Thai_thothan
890 0x0db1 U0e11 # Thai_thonangmontho
891 0x0db2 U0e12 # Thai_thophuthao
892 0x0db3 U0e13 # Thai_nonen
893 0x0db4 U0e14 # Thai_dodek
894 0x0db5 U0e15 # Thai_totao
895 0x0db6 U0e16 # Thai_thothung
896 0x0db7 U0e17 # Thai_thothahan
897 0x0db8 U0e18 # Thai_thothong
898 0x0db9 U0e19 # Thai_nonu
899 0x0dba U0e1a # Thai_bobaimai
900 0x0dbb U0e1b # Thai_popla
901 0x0dbc U0e1c # Thai_phophung
902 0x0dbd U0e1d # Thai_fofa
903 0x0dbe U0e1e # Thai_phophan
904 0x0dbf U0e1f # Thai_fofan
905 0x0dc0 U0e20 # Thai_phosamphao
906 0x0dc1 U0e21 # Thai_moma
907 0x0dc2 U0e22 # Thai_yoyak
908 0x0dc3 U0e23 # Thai_rorua
909 0x0dc4 U0e24 # Thai_ru
910 0x0dc5 U0e25 # Thai_loling
911 0x0dc6 U0e26 # Thai_lu
912 0x0dc7 U0e27 # Thai_wowaen
913 0x0dc8 U0e28 # Thai_sosala
914 0x0dc9 U0e29 # Thai_sorusi
915 0x0dca U0e2a # Thai_sosua
916 0x0dcb U0e2b # Thai_hohip
917 0x0dcc U0e2c # Thai_lochula
918 0x0dcd U0e2d # Thai_oang
919 0x0dce U0e2e # Thai_honokhuk
920 0x0dcf U0e2f # Thai_paiyannoi
921 0x0dd0 U0e30 # Thai_saraa
922 0x0dd1 U0e31 # Thai_maihanakat
923 0x0dd2 U0e32 # Thai_saraaa
924 0x0dd3 U0e33 # Thai_saraam
925 0x0dd4 U0e34 # Thai_sarai
926 0x0dd5 U0e35 # Thai_saraii
927 0x0dd6 U0e36 # Thai_saraue
928 0x0dd7 U0e37 # Thai_sarauee
929 0x0dd8 U0e38 # Thai_sarau
930 0x0dd9 U0e39 # Thai_sarauu
931 0x0dda U0e3a # Thai_phinthu
932 0x0dde U0e3e # Thai_maihanakat_maitho
933 0x0ddf U0e3f # Thai_baht
934 0x0de0 U0e40 # Thai_sarae
935 0x0de1 U0e41 # Thai_saraae
936 0x0de2 U0e42 # Thai_sarao
937 0x0de3 U0e43 # Thai_saraaimaimuan
938 0x0de4 U0e44 # Thai_saraaimaimalai
939 0x0de5 U0e45 # Thai_lakkhangyao
940 0x0de6 U0e46 # Thai_maiyamok
941 0x0de7 U0e47 # Thai_maitaikhu
942 0x0de8 U0e48 # Thai_maiek
943 0x0de9 U0e49 # Thai_maitho
944 0x0dea U0e4a # Thai_maitri
945 0x0deb U0e4b # Thai_maichattawa
946 0x0dec U0e4c # Thai_thanthakhat
947 0x0ded U0e4d # Thai_nikhahit
948 0x0df0 U0e50 # Thai_leksun
949 0x0df1 U0e51 # Thai_leknung
950 0x0df2 U0e52 # Thai_leksong
951 0x0df3 U0e53 # Thai_leksam
952 0x0df4 U0e54 # Thai_leksi
953 0x0df5 U0e55 # Thai_lekha
954 0x0df6 U0e56 # Thai_lekhok
955 0x0df7 U0e57 # Thai_lekchet
956 0x0df8 U0e58 # Thai_lekpaet
957 0x0df9 U0e59 # Thai_lekkao
958 0x0ea1 U3131 # Hangul_Kiyeog
959 0x0ea2 U3132 # Hangul_SsangKiyeog
960 0x0ea3 U3133 # Hangul_KiyeogSios
961 0x0ea4 U3134 # Hangul_Nieun
962 0x0ea5 U3135 # Hangul_NieunJieuj
963 0x0ea6 U3136 # Hangul_NieunHieuh
964 0x0ea7 U3137 # Hangul_Dikeud
965 0x0ea8 U3138 # Hangul_SsangDikeud
966 0x0ea9 U3139 # Hangul_Rieul
967 0x0eaa U313a # Hangul_RieulKiyeog
968 0x0eab U313b # Hangul_RieulMieum
969 0x0eac U313c # Hangul_RieulPieub
970 0x0ead U313d # Hangul_RieulSios
971 0x0eae U313e # Hangul_RieulTieut
972 0x0eaf U313f # Hangul_RieulPhieuf
973 0x0eb0 U3140 # Hangul_RieulHieuh
974 0x0eb1 U3141 # Hangul_Mieum
975 0x0eb2 U3142 # Hangul_Pieub
976 0x0eb3 U3143 # Hangul_SsangPieub
977 0x0eb4 U3144 # Hangul_PieubSios
978 0x0eb5 U3145 # Hangul_Sios
979 0x0eb6 U3146 # Hangul_SsangSios
980 0x0eb7 U3147 # Hangul_Ieung
981 0x0eb8 U3148 # Hangul_Jieuj
982 0x0eb9 U3149 # Hangul_SsangJieuj
983 0x0eba U314a # Hangul_Cieuc
984 0x0ebb U314b # Hangul_Khieuq
985 0x0ebc U314c # Hangul_Tieut
986 0x0ebd U314d # Hangul_Phieuf
987 0x0ebe U314e # Hangul_Hieuh
988 0x0ebf U314f # Hangul_A
989 0x0ec0 U3150 # Hangul_AE
990 0x0ec1 U3151 # Hangul_YA
991 0x0ec2 U3152 # Hangul_YAE
992 0x0ec3 U3153 # Hangul_EO
993 0x0ec4 U3154 # Hangul_E
994 0x0ec5 U3155 # Hangul_YEO
995 0x0ec6 U3156 # Hangul_YE
996 0x0ec7 U3157 # Hangul_O
997 0x0ec8 U3158 # Hangul_WA
998 0x0ec9 U3159 # Hangul_WAE
999 0x0eca U315a # Hangul_OE
1000 0x0ecb U315b # Hangul_YO
1001 0x0ecc U315c # Hangul_U
1002 0x0ecd U315d # Hangul_WEO
1003 0x0ece U315e # Hangul_WE
1004 0x0ecf U315f # Hangul_WI
1005 0x0ed0 U3160 # Hangul_YU
1006 0x0ed1 U3161 # Hangul_EU
1007 0x0ed2 U3162 # Hangul_YI
1008 0x0ed3 U3163 # Hangul_I
1009 0x0ed4 U11a8 # Hangul_J_Kiyeog
1010 0x0ed5 U11a9 # Hangul_J_SsangKiyeog
1011 0x0ed6 U11aa # Hangul_J_KiyeogSios
1012 0x0ed7 U11ab # Hangul_J_Nieun
1013 0x0ed8 U11ac # Hangul_J_NieunJieuj
1014 0x0ed9 U11ad # Hangul_J_NieunHieuh
1015 0x0eda U11ae # Hangul_J_Dikeud
1016 0x0edb U11af # Hangul_J_Rieul
1017 0x0edc U11b0 # Hangul_J_RieulKiyeog
1018 0x0edd U11b1 # Hangul_J_RieulMieum
1019 0x0ede U11b2 # Hangul_J_RieulPieub
1020 0x0edf U11b3 # Hangul_J_RieulSios
1021 0x0ee0 U11b4 # Hangul_J_RieulTieut
1022 0x0ee1 U11b5 # Hangul_J_RieulPhieuf
1023 0x0ee2 U11b6 # Hangul_J_RieulHieuh
1024 0x0ee3 U11b7 # Hangul_J_Mieum
1025 0x0ee4 U11b8 # Hangul_J_Pieub
1026 0x0ee5 U11b9 # Hangul_J_PieubSios
1027 0x0ee6 U11ba # Hangul_J_Sios
1028 0x0ee7 U11bb # Hangul_J_SsangSios
1029 0x0ee8 U11bc # Hangul_J_Ieung
1030 0x0ee9 U11bd # Hangul_J_Jieuj
1031 0x0eea U11be # Hangul_J_Cieuc
1032 0x0eeb U11bf # Hangul_J_Khieuq
1033 0x0eec U11c0 # Hangul_J_Tieut
1034 0x0eed U11c1 # Hangul_J_Phieuf
1035 0x0eee U11c2 # Hangul_J_Hieuh
1036 0x0eef U316d # Hangul_RieulYeorinHieuh
1037 0x0ef0 U3171 # Hangul_SunkyeongeumMieum
1038 0x0ef1 U3178 # Hangul_SunkyeongeumPieub
1039 0x0ef2 U317f # Hangul_PanSios
1040 0x0ef3 U0000 # Hangul_KkogjiDalrinIeung
1041 0x0ef4 U3184 # Hangul_SunkyeongeumPhieuf
1042 0x0ef5 U3186 # Hangul_YeorinHieuh
1043 0x0ef6 U318d # Hangul_AraeA
1044 0x0ef7 U318e # Hangul_AraeAE
1045 0x0ef8 U11eb # Hangul_J_PanSios
1046 0x0ef9 U0000 # Hangul_J_KkogjiDalrinIeung
1047 0x0efa U11f9 # Hangul_J_YeorinHieuh
1048 0x0eff U20a9 # Korean_Won
1049 0x20a0 U20a0 # EcuSign
1050 0x20a1 U20a1 # ColonSign
1051 0x20a2 U20a2 # CruzeiroSign
1052 0x20a3 U20a3 # FFrancSign
1053 0x20a4 U20a4 # LiraSign
1054 0x20a5 U20a5 # MillSign
1055 0x20a6 U20a6 # NairaSign
1056 0x20a7 U20a7 # PesetaSign
1057 0x20a8 U20a8 # RupeeSign
1058 0x20a9 U20a9 # WonSign
1059 0x20aa U20aa # NewSheqelSign
1060 0x20ab U20ab # DongSign
1061 0x20ac U20ac # EuroSign
0 /* $XFree86$
1 * This module converts keysym values into the corresponding ISO 10646-1
2 * (UCS, Unicode) values.
3 *
4 * The array keysymtab[] contains pairs of X11 keysym values for graphical
5 * characters and the corresponding Unicode value. The function
6 * keysym2ucs() maps a keysym onto a Unicode value using a binary search,
7 * therefore keysymtab[] must remain SORTED by keysym value.
8 *
9 * The keysym -> UTF-8 conversion will hopefully one day be provided
10 * by Xlib via XmbLookupString() and should ideally not have to be
11 * done in X applications. But we are not there yet.
12 *
13 * We allow to represent any UCS character in the range U+00000000 to
14 * U+00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff.
15 * This admittedly does not cover the entire 31-bit space of UCS, but
16 * it does cover all of the characters up to U+10FFFF, which can be
17 * represented by UTF-16, and more, and it is very unlikely that higher
18 * UCS codes will ever be assigned by ISO. So to get Unicode character
19 * U+ABCD you can directly use keysym 0x1000abcd.
20 *
21 * NOTE: The comments in the table below contain the actual character
22 * encoded in UTF-8, so for viewing and editing best use an editor in
23 * UTF-8 mode.
24 *
25 * Author: Markus G. Kuhn <[email protected]>, University of Cambridge, June 1999
26 *
27 * Special thanks to Richard Verhoeven <[email protected]> for preparing
28 * an initial draft of the mapping table.
29 *
30 * This software is in the public domain. Share and enjoy!
31 */
32
33 #include <xcb/xcb.h>
34 #include "keysym2ucs.h"
35
36 struct codepair {
37 unsigned short keysym;
38 unsigned short ucs;
39 } keysymtab[] = {
40 {0x01a1, 0x0104}, /* Aogonek Ą LATIN CAPITAL LETTER A WITH OGONEK */
41 {0x01a2, 0x02d8}, /* breve ˘ BREVE */
42 {0x01a3, 0x0141}, /* Lstroke Ł LATIN CAPITAL LETTER L WITH STROKE */
43 {0x01a5, 0x013d}, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */
44 {0x01a6, 0x015a}, /* Sacute Ś LATIN CAPITAL LETTER S WITH ACUTE */
45 {0x01a9, 0x0160}, /* Scaron Š LATIN CAPITAL LETTER S WITH CARON */
46 {0x01aa, 0x015e}, /* Scedilla Ş LATIN CAPITAL LETTER S WITH CEDILLA */
47 {0x01ab, 0x0164}, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */
48 {0x01ac, 0x0179}, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */
49 {0x01ae, 0x017d}, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */
50 {0x01af, 0x017b}, /* Zabovedot Ż LATIN CAPITAL LETTER Z WITH DOT ABOVE */
51 {0x01b1, 0x0105}, /* aogonek ą LATIN SMALL LETTER A WITH OGONEK */
52 {0x01b2, 0x02db}, /* ogonek ˛ OGONEK */
53 {0x01b3, 0x0142}, /* lstroke ł LATIN SMALL LETTER L WITH STROKE */
54 {0x01b5, 0x013e}, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */
55 {0x01b6, 0x015b}, /* sacute ś LATIN SMALL LETTER S WITH ACUTE */
56 {0x01b7, 0x02c7}, /* caron ˇ CARON */
57 {0x01b9, 0x0161}, /* scaron š LATIN SMALL LETTER S WITH CARON */
58 {0x01ba, 0x015f}, /* scedilla ş LATIN SMALL LETTER S WITH CEDILLA */
59 {0x01bb, 0x0165}, /* tcaron ť LATIN SMALL LETTER T WITH CARON */
60 {0x01bc, 0x017a}, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */
61 {0x01bd, 0x02dd}, /* doubleacute ˝ DOUBLE ACUTE ACCENT */
62 {0x01be, 0x017e}, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */
63 {0x01bf, 0x017c}, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */
64 {0x01c0, 0x0154}, /* Racute Ŕ LATIN CAPITAL LETTER R WITH ACUTE */
65 {0x01c3, 0x0102}, /* Abreve Ă LATIN CAPITAL LETTER A WITH BREVE */
66 {0x01c5, 0x0139}, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */
67 {0x01c6, 0x0106}, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */
68 {0x01c8, 0x010c}, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */
69 {0x01ca, 0x0118}, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */
70 {0x01cc, 0x011a}, /* Ecaron Ě LATIN CAPITAL LETTER E WITH CARON */
71 {0x01cf, 0x010e}, /* Dcaron Ď LATIN CAPITAL LETTER D WITH CARON */
72 {0x01d0, 0x0110}, /* Dstroke Đ LATIN CAPITAL LETTER D WITH STROKE */
73 {0x01d1, 0x0143}, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */
74 {0x01d2, 0x0147}, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */
75 {0x01d5, 0x0150}, /* Odoubleacute Ő LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
76 {0x01d8, 0x0158}, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */
77 {0x01d9, 0x016e}, /* Uring Ů LATIN CAPITAL LETTER U WITH RING ABOVE */
78 {0x01db, 0x0170}, /* Udoubleacute Ű LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
79 {0x01de, 0x0162}, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */
80 {0x01e0, 0x0155}, /* racute ŕ LATIN SMALL LETTER R WITH ACUTE */
81 {0x01e3, 0x0103}, /* abreve ă LATIN SMALL LETTER A WITH BREVE */
82 {0x01e5, 0x013a}, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */
83 {0x01e6, 0x0107}, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */
84 {0x01e8, 0x010d}, /* ccaron č LATIN SMALL LETTER C WITH CARON */
85 {0x01ea, 0x0119}, /* eogonek ę LATIN SMALL LETTER E WITH OGONEK */
86 {0x01ec, 0x011b}, /* ecaron ě LATIN SMALL LETTER E WITH CARON */
87 {0x01ef, 0x010f}, /* dcaron ď LATIN SMALL LETTER D WITH CARON */
88 {0x01f0, 0x0111}, /* dstroke đ LATIN SMALL LETTER D WITH STROKE */
89 {0x01f1, 0x0144}, /* nacute ń LATIN SMALL LETTER N WITH ACUTE */
90 {0x01f2, 0x0148}, /* ncaron ň LATIN SMALL LETTER N WITH CARON */
91 {0x01f5, 0x0151}, /* odoubleacute ő LATIN SMALL LETTER O WITH DOUBLE ACUTE */
92 {0x01f8, 0x0159}, /* rcaron ř LATIN SMALL LETTER R WITH CARON */
93 {0x01f9, 0x016f}, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */
94 {0x01fb, 0x0171}, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */
95 {0x01fe, 0x0163}, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */
96 {0x01ff, 0x02d9}, /* abovedot ˙ DOT ABOVE */
97 {0x02a1, 0x0126}, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */
98 {0x02a6, 0x0124}, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
99 {0x02a9, 0x0130}, /* Iabovedot İ LATIN CAPITAL LETTER I WITH DOT ABOVE */
100 {0x02ab, 0x011e}, /* Gbreve Ğ LATIN CAPITAL LETTER G WITH BREVE */
101 {0x02ac, 0x0134}, /* Jcircumflex Ĵ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
102 {0x02b1, 0x0127}, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */
103 {0x02b6, 0x0125}, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */
104 {0x02b9, 0x0131}, /* idotless ı LATIN SMALL LETTER DOTLESS I */
105 {0x02bb, 0x011f}, /* gbreve ğ LATIN SMALL LETTER G WITH BREVE */
106 {0x02bc, 0x0135}, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */
107 {0x02c5, 0x010a}, /* Cabovedot Ċ LATIN CAPITAL LETTER C WITH DOT ABOVE */
108 {0x02c6, 0x0108}, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
109 {0x02d5, 0x0120}, /* Gabovedot Ġ LATIN CAPITAL LETTER G WITH DOT ABOVE */
110 {0x02d8, 0x011c}, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
111 {0x02dd, 0x016c}, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */
112 {0x02de, 0x015c}, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
113 {0x02e5, 0x010b}, /* cabovedot ċ LATIN SMALL LETTER C WITH DOT ABOVE */
114 {0x02e6, 0x0109}, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */
115 {0x02f5, 0x0121}, /* gabovedot ġ LATIN SMALL LETTER G WITH DOT ABOVE */
116 {0x02f8, 0x011d}, /* gcircumflex ĝ LATIN SMALL LETTER G WITH CIRCUMFLEX */
117 {0x02fd, 0x016d}, /* ubreve ŭ LATIN SMALL LETTER U WITH BREVE */
118 {0x02fe, 0x015d}, /* scircumflex ŝ LATIN SMALL LETTER S WITH CIRCUMFLEX */
119 {0x03a2, 0x0138}, /* kra ĸ LATIN SMALL LETTER KRA */
120 {0x03a3, 0x0156}, /* Rcedilla Ŗ LATIN CAPITAL LETTER R WITH CEDILLA */
121 {0x03a5, 0x0128}, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */
122 {0x03a6, 0x013b}, /* Lcedilla Ļ LATIN CAPITAL LETTER L WITH CEDILLA */
123 {0x03aa, 0x0112}, /* Emacron Ē LATIN CAPITAL LETTER E WITH MACRON */
124 {0x03ab, 0x0122}, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */
125 {0x03ac, 0x0166}, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */
126 {0x03b3, 0x0157}, /* rcedilla ŗ LATIN SMALL LETTER R WITH CEDILLA */
127 {0x03b5, 0x0129}, /* itilde ĩ LATIN SMALL LETTER I WITH TILDE */
128 {0x03b6, 0x013c}, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */
129 {0x03ba, 0x0113}, /* emacron ē LATIN SMALL LETTER E WITH MACRON */
130 {0x03bb, 0x0123}, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */
131 {0x03bc, 0x0167}, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */
132 {0x03bd, 0x014a}, /* ENG Ŋ LATIN CAPITAL LETTER ENG */
133 {0x03bf, 0x014b}, /* eng ŋ LATIN SMALL LETTER ENG */
134 {0x03c0, 0x0100}, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */
135 {0x03c7, 0x012e}, /* Iogonek Į LATIN CAPITAL LETTER I WITH OGONEK */
136 {0x03cc, 0x0116}, /* Eabovedot Ė LATIN CAPITAL LETTER E WITH DOT ABOVE */
137 {0x03cf, 0x012a}, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */
138 {0x03d1, 0x0145}, /* Ncedilla Ņ LATIN CAPITAL LETTER N WITH CEDILLA */
139 {0x03d2, 0x014c}, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */
140 {0x03d3, 0x0136}, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */
141 {0x03d9, 0x0172}, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */
142 {0x03dd, 0x0168}, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */
143 {0x03de, 0x016a}, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */
144 {0x03e0, 0x0101}, /* amacron ā LATIN SMALL LETTER A WITH MACRON */
145 {0x03e7, 0x012f}, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */
146 {0x03ec, 0x0117}, /* eabovedot ė LATIN SMALL LETTER E WITH DOT ABOVE */
147 {0x03ef, 0x012b}, /* imacron ī LATIN SMALL LETTER I WITH MACRON */
148 {0x03f1, 0x0146}, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */
149 {0x03f2, 0x014d}, /* omacron ō LATIN SMALL LETTER O WITH MACRON */
150 {0x03f3, 0x0137}, /* kcedilla ķ LATIN SMALL LETTER K WITH CEDILLA */
151 {0x03f9, 0x0173}, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */
152 {0x03fd, 0x0169}, /* utilde ũ LATIN SMALL LETTER U WITH TILDE */
153 {0x03fe, 0x016b}, /* umacron ū LATIN SMALL LETTER U WITH MACRON */
154 {0x047e, 0x203e}, /* overline ‾ OVERLINE */
155 {0x04a1, 0x3002}, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */
156 {0x04a2, 0x300c}, /* kana_openingbracket 「 LEFT CORNER BRACKET */
157 {0x04a3, 0x300d}, /* kana_closingbracket 」 RIGHT CORNER BRACKET */
158 {0x04a4, 0x3001}, /* kana_comma 、 IDEOGRAPHIC COMMA */
159 {0x04a5, 0x30fb}, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */
160 {0x04a6, 0x30f2}, /* kana_WO ヲ KATAKANA LETTER WO */
161 {0x04a7, 0x30a1}, /* kana_a ァ KATAKANA LETTER SMALL A */
162 {0x04a8, 0x30a3}, /* kana_i ィ KATAKANA LETTER SMALL I */
163 {0x04a9, 0x30a5}, /* kana_u ゥ KATAKANA LETTER SMALL U */
164 {0x04aa, 0x30a7}, /* kana_e ェ KATAKANA LETTER SMALL E */
165 {0x04ab, 0x30a9}, /* kana_o ォ KATAKANA LETTER SMALL O */
166 {0x04ac, 0x30e3}, /* kana_ya ャ KATAKANA LETTER SMALL YA */
167 {0x04ad, 0x30e5}, /* kana_yu ュ KATAKANA LETTER SMALL YU */
168 {0x04ae, 0x30e7}, /* kana_yo ョ KATAKANA LETTER SMALL YO */
169 {0x04af, 0x30c3}, /* kana_tsu ッ KATAKANA LETTER SMALL TU */
170 {0x04b0, 0x30fc}, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */
171 {0x04b1, 0x30a2}, /* kana_A ア KATAKANA LETTER A */
172 {0x04b2, 0x30a4}, /* kana_I イ KATAKANA LETTER I */
173 {0x04b3, 0x30a6}, /* kana_U ウ KATAKANA LETTER U */
174 {0x04b4, 0x30a8}, /* kana_E エ KATAKANA LETTER E */
175 {0x04b5, 0x30aa}, /* kana_O オ KATAKANA LETTER O */
176 {0x04b6, 0x30ab}, /* kana_KA カ KATAKANA LETTER KA */
177 {0x04b7, 0x30ad}, /* kana_KI キ KATAKANA LETTER KI */
178 {0x04b8, 0x30af}, /* kana_KU ク KATAKANA LETTER KU */
179 {0x04b9, 0x30b1}, /* kana_KE ケ KATAKANA LETTER KE */
180 {0x04ba, 0x30b3}, /* kana_KO コ KATAKANA LETTER KO */
181 {0x04bb, 0x30b5}, /* kana_SA サ KATAKANA LETTER SA */
182 {0x04bc, 0x30b7}, /* kana_SHI シ KATAKANA LETTER SI */
183 {0x04bd, 0x30b9}, /* kana_SU ス KATAKANA LETTER SU */
184 {0x04be, 0x30bb}, /* kana_SE セ KATAKANA LETTER SE */
185 {0x04bf, 0x30bd}, /* kana_SO ソ KATAKANA LETTER SO */
186 {0x04c0, 0x30bf}, /* kana_TA タ KATAKANA LETTER TA */
187 {0x04c1, 0x30c1}, /* kana_CHI チ KATAKANA LETTER TI */
188 {0x04c2, 0x30c4}, /* kana_TSU ツ KATAKANA LETTER TU */
189 {0x04c3, 0x30c6}, /* kana_TE テ KATAKANA LETTER TE */
190 {0x04c4, 0x30c8}, /* kana_TO ト KATAKANA LETTER TO */
191 {0x04c5, 0x30ca}, /* kana_NA ナ KATAKANA LETTER NA */
192 {0x04c6, 0x30cb}, /* kana_NI ニ KATAKANA LETTER NI */
193 {0x04c7, 0x30cc}, /* kana_NU ヌ KATAKANA LETTER NU */
194 {0x04c8, 0x30cd}, /* kana_NE ネ KATAKANA LETTER NE */
195 {0x04c9, 0x30ce}, /* kana_NO ノ KATAKANA LETTER NO */
196 {0x04ca, 0x30cf}, /* kana_HA ハ KATAKANA LETTER HA */
197 {0x04cb, 0x30d2}, /* kana_HI ヒ KATAKANA LETTER HI */
198 {0x04cc, 0x30d5}, /* kana_FU フ KATAKANA LETTER HU */
199 {0x04cd, 0x30d8}, /* kana_HE ヘ KATAKANA LETTER HE */
200 {0x04ce, 0x30db}, /* kana_HO ホ KATAKANA LETTER HO */
201 {0x04cf, 0x30de}, /* kana_MA マ KATAKANA LETTER MA */
202 {0x04d0, 0x30df}, /* kana_MI ミ KATAKANA LETTER MI */
203 {0x04d1, 0x30e0}, /* kana_MU ム KATAKANA LETTER MU */
204 {0x04d2, 0x30e1}, /* kana_ME メ KATAKANA LETTER ME */
205 {0x04d3, 0x30e2}, /* kana_MO モ KATAKANA LETTER MO */
206 {0x04d4, 0x30e4}, /* kana_YA ヤ KATAKANA LETTER YA */
207 {0x04d5, 0x30e6}, /* kana_YU ユ KATAKANA LETTER YU */
208 {0x04d6, 0x30e8}, /* kana_YO ヨ KATAKANA LETTER YO */
209 {0x04d7, 0x30e9}, /* kana_RA ラ KATAKANA LETTER RA */
210 {0x04d8, 0x30ea}, /* kana_RI リ KATAKANA LETTER RI */
211 {0x04d9, 0x30eb}, /* kana_RU ル KATAKANA LETTER RU */
212 {0x04da, 0x30ec}, /* kana_RE レ KATAKANA LETTER RE */
213 {0x04db, 0x30ed}, /* kana_RO ロ KATAKANA LETTER RO */
214 {0x04dc, 0x30ef}, /* kana_WA ワ KATAKANA LETTER WA */
215 {0x04dd, 0x30f3}, /* kana_N ン KATAKANA LETTER N */
216 {0x04de, 0x309b}, /* voicedsound ゛ KATAKANA-HIRAGANA VOICED SOUND MARK */
217 {0x04df, 0x309c}, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
218 {0x05ac, 0x060c}, /* Arabic_comma ، ARABIC COMMA */
219 {0x05bb, 0x061b}, /* Arabic_semicolon ؛ ARABIC SEMICOLON */
220 {0x05bf, 0x061f}, /* Arabic_question_mark ؟ ARABIC QUESTION MARK */
221 {0x05c1, 0x0621}, /* Arabic_hamza ء ARABIC LETTER HAMZA */
222 {0x05c2, 0x0622}, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */
223 {0x05c3, 0x0623}, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */
224 {0x05c4, 0x0624}, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */
225 {0x05c5, 0x0625}, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */
226 {0x05c6, 0x0626}, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */
227 {0x05c7, 0x0627}, /* Arabic_alef ا ARABIC LETTER ALEF */
228 {0x05c8, 0x0628}, /* Arabic_beh ب ARABIC LETTER BEH */
229 {0x05c9, 0x0629}, /* Arabic_tehmarbuta ة ARABIC LETTER TEH MARBUTA */
230 {0x05ca, 0x062a}, /* Arabic_teh ت ARABIC LETTER TEH */
231 {0x05cb, 0x062b}, /* Arabic_theh ث ARABIC LETTER THEH */
232 {0x05cc, 0x062c}, /* Arabic_jeem ج ARABIC LETTER JEEM */
233 {0x05cd, 0x062d}, /* Arabic_hah ح ARABIC LETTER HAH */
234 {0x05ce, 0x062e}, /* Arabic_khah خ ARABIC LETTER KHAH */
235 {0x05cf, 0x062f}, /* Arabic_dal د ARABIC LETTER DAL */
236 {0x05d0, 0x0630}, /* Arabic_thal ذ ARABIC LETTER THAL */
237 {0x05d1, 0x0631}, /* Arabic_ra ر ARABIC LETTER REH */
238 {0x05d2, 0x0632}, /* Arabic_zain ز ARABIC LETTER ZAIN */
239 {0x05d3, 0x0633}, /* Arabic_seen س ARABIC LETTER SEEN */
240 {0x05d4, 0x0634}, /* Arabic_sheen ش ARABIC LETTER SHEEN */
241 {0x05d5, 0x0635}, /* Arabic_sad ص ARABIC LETTER SAD */
242 {0x05d6, 0x0636}, /* Arabic_dad ض ARABIC LETTER DAD */
243 {0x05d7, 0x0637}, /* Arabic_tah ط ARABIC LETTER TAH */
244 {0x05d8, 0x0638}, /* Arabic_zah ظ ARABIC LETTER ZAH */
245 {0x05d9, 0x0639}, /* Arabic_ain ع ARABIC LETTER AIN */
246 {0x05da, 0x063a}, /* Arabic_ghain غ ARABIC LETTER GHAIN */
247 {0x05e0, 0x0640}, /* Arabic_tatweel ـ ARABIC TATWEEL */
248 {0x05e1, 0x0641}, /* Arabic_feh ف ARABIC LETTER FEH */
249 {0x05e2, 0x0642}, /* Arabic_qaf ق ARABIC LETTER QAF */
250 {0x05e3, 0x0643}, /* Arabic_kaf ك ARABIC LETTER KAF */
251 {0x05e4, 0x0644}, /* Arabic_lam ل ARABIC LETTER LAM */
252 {0x05e5, 0x0645}, /* Arabic_meem م ARABIC LETTER MEEM */
253 {0x05e6, 0x0646}, /* Arabic_noon ن ARABIC LETTER NOON */
254 {0x05e7, 0x0647}, /* Arabic_ha ه ARABIC LETTER HEH */
255 {0x05e8, 0x0648}, /* Arabic_waw و ARABIC LETTER WAW */
256 {0x05e9, 0x0649}, /* Arabic_alefmaksura ى ARABIC LETTER ALEF MAKSURA */
257 {0x05ea, 0x064a}, /* Arabic_yeh ي ARABIC LETTER YEH */
258 {0x05eb, 0x064b}, /* Arabic_fathatan ً ARABIC FATHATAN */
259 {0x05ec, 0x064c}, /* Arabic_dammatan ٌ ARABIC DAMMATAN */
260 {0x05ed, 0x064d}, /* Arabic_kasratan ٍ ARABIC KASRATAN */
261 {0x05ee, 0x064e}, /* Arabic_fatha َ ARABIC FATHA */
262 {0x05ef, 0x064f}, /* Arabic_damma ُ ARABIC DAMMA */
263 {0x05f0, 0x0650}, /* Arabic_kasra ِ ARABIC KASRA */
264 {0x05f1, 0x0651}, /* Arabic_shadda ّ ARABIC SHADDA */
265 {0x05f2, 0x0652}, /* Arabic_sukun ْ ARABIC SUKUN */
266 {0x06a1, 0x0452}, /* Serbian_dje ђ CYRILLIC SMALL LETTER DJE */
267 {0x06a2, 0x0453}, /* Macedonia_gje ѓ CYRILLIC SMALL LETTER GJE */
268 {0x06a3, 0x0451}, /* Cyrillic_io ё CYRILLIC SMALL LETTER IO */
269 {0x06a4, 0x0454}, /* Ukrainian_ie є CYRILLIC SMALL LETTER UKRAINIAN IE */
270 {0x06a5, 0x0455}, /* Macedonia_dse ѕ CYRILLIC SMALL LETTER DZE */
271 {0x06a6, 0x0456}, /* Ukrainian_i і CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
272 {0x06a7, 0x0457}, /* Ukrainian_yi ї CYRILLIC SMALL LETTER YI */
273 {0x06a8, 0x0458}, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */
274 {0x06a9, 0x0459}, /* Cyrillic_lje љ CYRILLIC SMALL LETTER LJE */
275 {0x06aa, 0x045a}, /* Cyrillic_nje њ CYRILLIC SMALL LETTER NJE */
276 {0x06ab, 0x045b}, /* Serbian_tshe ћ CYRILLIC SMALL LETTER TSHE */
277 {0x06ac, 0x045c}, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */
278 /* 0x06ad Ukrainian_ghe_with_upturn ? ??? */
279 {0x06ae, 0x045e}, /* Byelorussian_shortu ў CYRILLIC SMALL LETTER SHORT U */
280 {0x06af, 0x045f}, /* Cyrillic_dzhe џ CYRILLIC SMALL LETTER DZHE */
281 {0x06b0, 0x2116}, /* numerosign № NUMERO SIGN */
282 {0x06b1, 0x0402}, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */
283 {0x06b2, 0x0403}, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */
284 {0x06b3, 0x0401}, /* Cyrillic_IO Ё CYRILLIC CAPITAL LETTER IO */
285 {0x06b4, 0x0404}, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */
286 {0x06b5, 0x0405}, /* Macedonia_DSE Ѕ CYRILLIC CAPITAL LETTER DZE */
287 {0x06b6, 0x0406}, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
288 {0x06b7, 0x0407}, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */
289 {0x06b8, 0x0408}, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */
290 {0x06b9, 0x0409}, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */
291 {0x06ba, 0x040a}, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */
292 {0x06bb, 0x040b}, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */
293 {0x06bc, 0x040c}, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */
294 /* 0x06bd Ukrainian_GHE_WITH_UPTURN ? ??? */
295 {0x06be, 0x040e}, /* Byelorussian_SHORTU Ў CYRILLIC CAPITAL LETTER SHORT U */
296 {0x06bf, 0x040f}, /* Cyrillic_DZHE Џ CYRILLIC CAPITAL LETTER DZHE */
297 {0x06c0, 0x044e}, /* Cyrillic_yu ю CYRILLIC SMALL LETTER YU */
298 {0x06c1, 0x0430}, /* Cyrillic_a а CYRILLIC SMALL LETTER A */
299 {0x06c2, 0x0431}, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */
300 {0x06c3, 0x0446}, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */
301 {0x06c4, 0x0434}, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */
302 {0x06c5, 0x0435}, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */
303 {0x06c6, 0x0444}, /* Cyrillic_ef ф CYRILLIC SMALL LETTER EF */
304 {0x06c7, 0x0433}, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */
305 {0x06c8, 0x0445}, /* Cyrillic_ha х CYRILLIC SMALL LETTER HA */
306 {0x06c9, 0x0438}, /* Cyrillic_i и CYRILLIC SMALL LETTER I */
307 {0x06ca, 0x0439}, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */
308 {0x06cb, 0x043a}, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */
309 {0x06cc, 0x043b}, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */
310 {0x06cd, 0x043c}, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */
311 {0x06ce, 0x043d}, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */
312 {0x06cf, 0x043e}, /* Cyrillic_o о CYRILLIC SMALL LETTER O */
313 {0x06d0, 0x043f}, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */
314 {0x06d1, 0x044f}, /* Cyrillic_ya я CYRILLIC SMALL LETTER YA */
315 {0x06d2, 0x0440}, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */
316 {0x06d3, 0x0441}, /* Cyrillic_es с CYRILLIC SMALL LETTER ES */
317 {0x06d4, 0x0442}, /* Cyrillic_te т CYRILLIC SMALL LETTER TE */
318 {0x06d5, 0x0443}, /* Cyrillic_u у CYRILLIC SMALL LETTER U */
319 {0x06d6, 0x0436}, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */
320 {0x06d7, 0x0432}, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */
321 {0x06d8, 0x044c}, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */
322 {0x06d9, 0x044b}, /* Cyrillic_yeru ы CYRILLIC SMALL LETTER YERU */
323 {0x06da, 0x0437}, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */
324 {0x06db, 0x0448}, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */
325 {0x06dc, 0x044d}, /* Cyrillic_e э CYRILLIC SMALL LETTER E */
326 {0x06dd, 0x0449}, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */
327 {0x06de, 0x0447}, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */
328 {0x06df, 0x044a}, /* Cyrillic_hardsign ъ CYRILLIC SMALL LETTER HARD SIGN */
329 {0x06e0, 0x042e}, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */
330 {0x06e1, 0x0410}, /* Cyrillic_A А CYRILLIC CAPITAL LETTER A */
331 {0x06e2, 0x0411}, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */
332 {0x06e3, 0x0426}, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */
333 {0x06e4, 0x0414}, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */
334 {0x06e5, 0x0415}, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */
335 {0x06e6, 0x0424}, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */
336 {0x06e7, 0x0413}, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */
337 {0x06e8, 0x0425}, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */
338 {0x06e9, 0x0418}, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */
339 {0x06ea, 0x0419}, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */
340 {0x06eb, 0x041a}, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */
341 {0x06ec, 0x041b}, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */
342 {0x06ed, 0x041c}, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */
343 {0x06ee, 0x041d}, /* Cyrillic_EN Н CYRILLIC CAPITAL LETTER EN */
344 {0x06ef, 0x041e}, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */
345 {0x06f0, 0x041f}, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */
346 {0x06f1, 0x042f}, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */
347 {0x06f2, 0x0420}, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */
348 {0x06f3, 0x0421}, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */
349 {0x06f4, 0x0422}, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */
350 {0x06f5, 0x0423}, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */
351 {0x06f6, 0x0416}, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */
352 {0x06f7, 0x0412}, /* Cyrillic_VE В CYRILLIC CAPITAL LETTER VE */
353 {0x06f8, 0x042c}, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */
354 {0x06f9, 0x042b}, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */
355 {0x06fa, 0x0417}, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */
356 {0x06fb, 0x0428}, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */
357 {0x06fc, 0x042d}, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */
358 {0x06fd, 0x0429}, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */
359 {0x06fe, 0x0427}, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */
360 {0x06ff, 0x042a}, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */
361 {0x07a1, 0x0386}, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */
362 {0x07a2, 0x0388}, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */
363 {0x07a3, 0x0389}, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */
364 {0x07a4, 0x038a}, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */
365 {0x07a5, 0x03aa}, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
366 {0x07a7, 0x038c}, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */
367 {0x07a8, 0x038e}, /* Greek_UPSILONaccent Ύ GREEK CAPITAL LETTER UPSILON WITH TONOS */
368 {0x07a9, 0x03ab}, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
369 {0x07ab, 0x038f}, /* Greek_OMEGAaccent Ώ GREEK CAPITAL LETTER OMEGA WITH TONOS */
370 {0x07ae, 0x0385}, /* Greek_accentdieresis ΅ GREEK DIALYTIKA TONOS */
371 {0x07af, 0x2015}, /* Greek_horizbar ― HORIZONTAL BAR */
372 {0x07b1, 0x03ac}, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */
373 {0x07b2, 0x03ad}, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */
374 {0x07b3, 0x03ae}, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */
375 {0x07b4, 0x03af}, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */
376 {0x07b5, 0x03ca}, /* Greek_iotadieresis ϊ GREEK SMALL LETTER IOTA WITH DIALYTIKA */
377 {0x07b6, 0x0390}, /* Greek_iotaaccentdieresis ΐ GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
378 {0x07b7, 0x03cc}, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */
379 {0x07b8, 0x03cd}, /* Greek_upsilonaccent ύ GREEK SMALL LETTER UPSILON WITH TONOS */
380 {0x07b9, 0x03cb}, /* Greek_upsilondieresis ϋ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
381 {0x07ba, 0x03b0}, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
382 {0x07bb, 0x03ce}, /* Greek_omegaaccent ώ GREEK SMALL LETTER OMEGA WITH TONOS */
383 {0x07c1, 0x0391}, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */
384 {0x07c2, 0x0392}, /* Greek_BETA Β GREEK CAPITAL LETTER BETA */
385 {0x07c3, 0x0393}, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */
386 {0x07c4, 0x0394}, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */
387 {0x07c5, 0x0395}, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */
388 {0x07c6, 0x0396}, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */
389 {0x07c7, 0x0397}, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */
390 {0x07c8, 0x0398}, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */
391 {0x07c9, 0x0399}, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */
392 {0x07ca, 0x039a}, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */
393 {0x07cb, 0x039b}, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */
394 {0x07cc, 0x039c}, /* Greek_MU Μ GREEK CAPITAL LETTER MU */
395 {0x07cd, 0x039d}, /* Greek_NU Ν GREEK CAPITAL LETTER NU */
396 {0x07ce, 0x039e}, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */
397 {0x07cf, 0x039f}, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */
398 {0x07d0, 0x03a0}, /* Greek_PI Π GREEK CAPITAL LETTER PI */
399 {0x07d1, 0x03a1}, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */
400 {0x07d2, 0x03a3}, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */
401 {0x07d4, 0x03a4}, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */
402 {0x07d5, 0x03a5}, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */
403 {0x07d6, 0x03a6}, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */
404 {0x07d7, 0x03a7}, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */
405 {0x07d8, 0x03a8}, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */
406 {0x07d9, 0x03a9}, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */
407 {0x07e1, 0x03b1}, /* Greek_alpha α GREEK SMALL LETTER ALPHA */
408 {0x07e2, 0x03b2}, /* Greek_beta β GREEK SMALL LETTER BETA */
409 {0x07e3, 0x03b3}, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */
410 {0x07e4, 0x03b4}, /* Greek_delta δ GREEK SMALL LETTER DELTA */
411 {0x07e5, 0x03b5}, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */
412 {0x07e6, 0x03b6}, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */
413 {0x07e7, 0x03b7}, /* Greek_eta η GREEK SMALL LETTER ETA */
414 {0x07e8, 0x03b8}, /* Greek_theta θ GREEK SMALL LETTER THETA */
415 {0x07e9, 0x03b9}, /* Greek_iota ι GREEK SMALL LETTER IOTA */
416 {0x07ea, 0x03ba}, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */
417 {0x07eb, 0x03bb}, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */
418 {0x07ec, 0x03bc}, /* Greek_mu μ GREEK SMALL LETTER MU */
419 {0x07ed, 0x03bd}, /* Greek_nu ν GREEK SMALL LETTER NU */
420 {0x07ee, 0x03be}, /* Greek_xi ξ GREEK SMALL LETTER XI */
421 {0x07ef, 0x03bf}, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */
422 {0x07f0, 0x03c0}, /* Greek_pi π GREEK SMALL LETTER PI */
423 {0x07f1, 0x03c1}, /* Greek_rho ρ GREEK SMALL LETTER RHO */
424 {0x07f2, 0x03c3}, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */
425 {0x07f3, 0x03c2}, /* Greek_finalsmallsigma ς GREEK SMALL LETTER FINAL SIGMA */
426 {0x07f4, 0x03c4}, /* Greek_tau τ GREEK SMALL LETTER TAU */
427 {0x07f5, 0x03c5}, /* Greek_upsilon υ GREEK SMALL LETTER UPSILON */
428 {0x07f6, 0x03c6}, /* Greek_phi φ GREEK SMALL LETTER PHI */
429 {0x07f7, 0x03c7}, /* Greek_chi χ GREEK SMALL LETTER CHI */
430 {0x07f8, 0x03c8}, /* Greek_psi ψ GREEK SMALL LETTER PSI */
431 {0x07f9, 0x03c9}, /* Greek_omega ω GREEK SMALL LETTER OMEGA */
432 /* 0x08a1 leftradical ? ??? */
433 /* 0x08a2 topleftradical ? ??? */
434 /* 0x08a3 horizconnector ? ??? */
435 {0x08a4, 0x2320}, /* topintegral ⌠ TOP HALF INTEGRAL */
436 {0x08a5, 0x2321}, /* botintegral ⌡ BOTTOM HALF INTEGRAL */
437 {0x08a6, 0x2502}, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */
438 /* 0x08a7 topleftsqbracket ? ??? */
439 /* 0x08a8 botleftsqbracket ? ??? */
440 /* 0x08a9 toprightsqbracket ? ??? */
441 /* 0x08aa botrightsqbracket ? ??? */
442 /* 0x08ab topleftparens ? ??? */
443 /* 0x08ac botleftparens ? ??? */
444 /* 0x08ad toprightparens ? ??? */
445 /* 0x08ae botrightparens ? ??? */
446 /* 0x08af leftmiddlecurlybrace ? ??? */
447 /* 0x08b0 rightmiddlecurlybrace ? ??? */
448 /* 0x08b1 topleftsummation ? ??? */
449 /* 0x08b2 botleftsummation ? ??? */
450 /* 0x08b3 topvertsummationconnector ? ??? */
451 /* 0x08b4 botvertsummationconnector ? ??? */
452 /* 0x08b5 toprightsummation ? ??? */
453 /* 0x08b6 botrightsummation ? ??? */
454 /* 0x08b7 rightmiddlesummation ? ??? */
455 {0x08bc, 0x2264}, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */
456 {0x08bd, 0x2260}, /* notequal ≠ NOT EQUAL TO */
457 {0x08be, 0x2265}, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */
458 {0x08bf, 0x222b}, /* integral ∫ INTEGRAL */
459 {0x08c0, 0x2234}, /* therefore ∴ THEREFORE */
460 {0x08c1, 0x221d}, /* variation ∝ PROPORTIONAL TO */
461 {0x08c2, 0x221e}, /* infinity ∞ INFINITY */
462 {0x08c5, 0x2207}, /* nabla ∇ NABLA */
463 {0x08c8, 0x2245}, /* approximate ≅ APPROXIMATELY EQUAL TO */
464 /* 0x08c9 similarequal ? ??? */
465 {0x08cd, 0x21d4}, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */
466 {0x08ce, 0x21d2}, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */
467 {0x08cf, 0x2261}, /* identical ≡ IDENTICAL TO */
468 {0x08d6, 0x221a}, /* radical √ SQUARE ROOT */
469 {0x08da, 0x2282}, /* includedin ⊂ SUBSET OF */
470 {0x08db, 0x2283}, /* includes ⊃ SUPERSET OF */
471 {0x08dc, 0x2229}, /* intersection ∩ INTERSECTION */
472 {0x08dd, 0x222a}, /* union ∪ UNION */
473 {0x08de, 0x2227}, /* logicaland ∧ LOGICAL AND */
474 {0x08df, 0x2228}, /* logicalor ∨ LOGICAL OR */
475 {0x08ef, 0x2202}, /* partialderivative ∂ PARTIAL DIFFERENTIAL */
476 {0x08f6, 0x0192}, /* function ƒ LATIN SMALL LETTER F WITH HOOK */
477 {0x08fb, 0x2190}, /* leftarrow ← LEFTWARDS ARROW */
478 {0x08fc, 0x2191}, /* uparrow ↑ UPWARDS ARROW */
479 {0x08fd, 0x2192}, /* rightarrow → RIGHTWARDS ARROW */
480 {0x08fe, 0x2193}, /* downarrow ↓ DOWNWARDS ARROW */
481 {0x09df, 0x2422}, /* blank ␢ BLANK SYMBOL */
482 {0x09e0, 0x25c6}, /* soliddiamond ◆ BLACK DIAMOND */
483 {0x09e1, 0x2592}, /* checkerboard ▒ MEDIUM SHADE */
484 {0x09e2, 0x2409}, /* ht ␉ SYMBOL FOR HORIZONTAL TABULATION */
485 {0x09e3, 0x240c}, /* ff ␌ SYMBOL FOR FORM FEED */
486 {0x09e4, 0x240d}, /* cr ␍ SYMBOL FOR CARRIAGE RETURN */
487 {0x09e5, 0x240a}, /* lf ␊ SYMBOL FOR LINE FEED */
488 {0x09e8, 0x2424}, /* nl ␤ SYMBOL FOR NEWLINE */
489 {0x09e9, 0x240b}, /* vt ␋ SYMBOL FOR VERTICAL TABULATION */
490 {0x09ea, 0x2518}, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */
491 {0x09eb, 0x2510}, /* uprightcorner ┐ BOX DRAWINGS LIGHT DOWN AND LEFT */
492 {0x09ec, 0x250c}, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
493 {0x09ed, 0x2514}, /* lowleftcorner └ BOX DRAWINGS LIGHT UP AND RIGHT */
494 {0x09ee, 0x253c}, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
495 /* 0x09ef horizlinescan1 ? ??? */
496 /* 0x09f0 horizlinescan3 ? ??? */
497 {0x09f1, 0x2500}, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */
498 /* 0x09f2 horizlinescan7 ? ??? */
499 /* 0x09f3 horizlinescan9 ? ??? */
500 {0x09f4, 0x251c}, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
501 {0x09f5, 0x2524}, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */
502 {0x09f6, 0x2534}, /* bott ┴ BOX DRAWINGS LIGHT UP AND HORIZONTAL */
503 {0x09f7, 0x252c}, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
504 {0x09f8, 0x2502}, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */
505 {0x0aa1, 0x2003}, /* emspace   EM SPACE */
506 {0x0aa2, 0x2002}, /* enspace   EN SPACE */
507 {0x0aa3, 0x2004}, /* em3space   THREE-PER-EM SPACE */
508 {0x0aa4, 0x2005}, /* em4space   FOUR-PER-EM SPACE */
509 {0x0aa5, 0x2007}, /* digitspace   FIGURE SPACE */
510 {0x0aa6, 0x2008}, /* punctspace   PUNCTUATION SPACE */
511 {0x0aa7, 0x2009}, /* thinspace   THIN SPACE */
512 {0x0aa8, 0x200a}, /* hairspace   HAIR SPACE */
513 {0x0aa9, 0x2014}, /* emdash — EM DASH */
514 {0x0aaa, 0x2013}, /* endash – EN DASH */
515 /* 0x0aac signifblank ? ??? */
516 {0x0aae, 0x2026}, /* ellipsis … HORIZONTAL ELLIPSIS */
517 /* 0x0aaf doubbaselinedot ? ??? */
518 {0x0ab0, 0x2153}, /* onethird ⅓ VULGAR FRACTION ONE THIRD */
519 {0x0ab1, 0x2154}, /* twothirds ⅔ VULGAR FRACTION TWO THIRDS */
520 {0x0ab2, 0x2155}, /* onefifth ⅕ VULGAR FRACTION ONE FIFTH */
521 {0x0ab3, 0x2156}, /* twofifths ⅖ VULGAR FRACTION TWO FIFTHS */
522 {0x0ab4, 0x2157}, /* threefifths ⅗ VULGAR FRACTION THREE FIFTHS */
523 {0x0ab5, 0x2158}, /* fourfifths ⅘ VULGAR FRACTION FOUR FIFTHS */
524 {0x0ab6, 0x2159}, /* onesixth ⅙ VULGAR FRACTION ONE SIXTH */
525 {0x0ab7, 0x215a}, /* fivesixths ⅚ VULGAR FRACTION FIVE SIXTHS */
526 {0x0ab8, 0x2105}, /* careof ℅ CARE OF */
527 {0x0abb, 0x2012}, /* figdash ‒ FIGURE DASH */
528 {0x0abc, 0x2329}, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */
529 {0x0abd, 0x002e}, /* decimalpoint . FULL STOP */
530 {0x0abe, 0x232a}, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */
531 /* 0x0abf marker ? ??? */
532 {0x0ac3, 0x215b}, /* oneeighth ⅛ VULGAR FRACTION ONE EIGHTH */
533 {0x0ac4, 0x215c}, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */
534 {0x0ac5, 0x215d}, /* fiveeighths ⅝ VULGAR FRACTION FIVE EIGHTHS */
535 {0x0ac6, 0x215e}, /* seveneighths ⅞ VULGAR FRACTION SEVEN EIGHTHS */
536 {0x0ac9, 0x2122}, /* trademark ™ TRADE MARK SIGN */
537 {0x0aca, 0x2613}, /* signaturemark ☓ SALTIRE */
538 /* 0x0acb trademarkincircle ? ??? */
539 {0x0acc, 0x25c1}, /* leftopentriangle ◁ WHITE LEFT-POINTING TRIANGLE */
540 {0x0acd, 0x25b7}, /* rightopentriangle ▷ WHITE RIGHT-POINTING TRIANGLE */
541 {0x0ace, 0x25cb}, /* emopencircle ○ WHITE CIRCLE */
542 {0x0acf, 0x25a1}, /* emopenrectangle □ WHITE SQUARE */
543 {0x0ad0, 0x2018}, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */
544 {0x0ad1, 0x2019}, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */
545 {0x0ad2, 0x201c}, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */
546 {0x0ad3, 0x201d}, /* rightdoublequotemark ” RIGHT DOUBLE QUOTATION MARK */
547 {0x0ad4, 0x211e}, /* prescription ℞ PRESCRIPTION TAKE */
548 {0x0ad6, 0x2032}, /* minutes ′ PRIME */
549 {0x0ad7, 0x2033}, /* seconds ″ DOUBLE PRIME */
550 {0x0ad9, 0x271d}, /* latincross ✝ LATIN CROSS */
551 /* 0x0ada hexagram ? ??? */
552 {0x0adb, 0x25ac}, /* filledrectbullet ▬ BLACK RECTANGLE */
553 {0x0adc, 0x25c0}, /* filledlefttribullet ◀ BLACK LEFT-POINTING TRIANGLE */
554 {0x0add, 0x25b6}, /* filledrighttribullet ▶ BLACK RIGHT-POINTING TRIANGLE */
555 {0x0ade, 0x25cf}, /* emfilledcircle ● BLACK CIRCLE */
556 {0x0adf, 0x25a0}, /* emfilledrect ■ BLACK SQUARE */
557 {0x0ae0, 0x25e6}, /* enopencircbullet ◦ WHITE BULLET */
558 {0x0ae1, 0x25ab}, /* enopensquarebullet ▫ WHITE SMALL SQUARE */
559 {0x0ae2, 0x25ad}, /* openrectbullet ▭ WHITE RECTANGLE */
560 {0x0ae3, 0x25b3}, /* opentribulletup △ WHITE UP-POINTING TRIANGLE */
561 {0x0ae4, 0x25bd}, /* opentribulletdown ▽ WHITE DOWN-POINTING TRIANGLE */
562 {0x0ae5, 0x2606}, /* openstar ☆ WHITE STAR */
563 {0x0ae6, 0x2022}, /* enfilledcircbullet • BULLET */
564 {0x0ae7, 0x25aa}, /* enfilledsqbullet ▪ BLACK SMALL SQUARE */
565 {0x0ae8, 0x25b2}, /* filledtribulletup ▲ BLACK UP-POINTING TRIANGLE */
566 {0x0ae9, 0x25bc}, /* filledtribulletdown ▼ BLACK DOWN-POINTING TRIANGLE */
567 {0x0aea, 0x261c}, /* leftpointer ☜ WHITE LEFT POINTING INDEX */
568 {0x0aeb, 0x261e}, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */
569 {0x0aec, 0x2663}, /* club ♣ BLACK CLUB SUIT */
570 {0x0aed, 0x2666}, /* diamond ♦ BLACK DIAMOND SUIT */
571 {0x0aee, 0x2665}, /* heart ♥ BLACK HEART SUIT */
572 {0x0af0, 0x2720}, /* maltesecross ✠ MALTESE CROSS */
573 {0x0af1, 0x2020}, /* dagger † DAGGER */
574 {0x0af2, 0x2021}, /* doubledagger ‡ DOUBLE DAGGER */
575 {0x0af3, 0x2713}, /* checkmark ✓ CHECK MARK */
576 {0x0af4, 0x2717}, /* ballotcross ✗ BALLOT X */
577 {0x0af5, 0x266f}, /* musicalsharp ♯ MUSIC SHARP SIGN */
578 {0x0af6, 0x266d}, /* musicalflat ♭ MUSIC FLAT SIGN */
579 {0x0af7, 0x2642}, /* malesymbol ♂ MALE SIGN */
580 {0x0af8, 0x2640}, /* femalesymbol ♀ FEMALE SIGN */
581 {0x0af9, 0x260e}, /* telephone ☎ BLACK TELEPHONE */
582 {0x0afa, 0x2315}, /* telephonerecorder ⌕ TELEPHONE RECORDER */
583 {0x0afb, 0x2117}, /* phonographcopyright ℗ SOUND RECORDING COPYRIGHT */
584 {0x0afc, 0x2038}, /* caret ‸ CARET */
585 {0x0afd, 0x201a}, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */
586 {0x0afe, 0x201e}, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */
587 /* 0x0aff cursor ? ??? */
588 {0x0ba3, 0x003c}, /* leftcaret < LESS-THAN SIGN */
589 {0x0ba6, 0x003e}, /* rightcaret > GREATER-THAN SIGN */
590 {0x0ba8, 0x2228}, /* downcaret ∨ LOGICAL OR */
591 {0x0ba9, 0x2227}, /* upcaret ∧ LOGICAL AND */
592 {0x0bc0, 0x00af}, /* overbar ¯ MACRON */
593 {0x0bc2, 0x22a4}, /* downtack ⊤ DOWN TACK */
594 {0x0bc3, 0x2229}, /* upshoe ∩ INTERSECTION */
595 {0x0bc4, 0x230a}, /* downstile ⌊ LEFT FLOOR */
596 {0x0bc6, 0x005f}, /* underbar _ LOW LINE */
597 {0x0bca, 0x2218}, /* jot ∘ RING OPERATOR */
598 {0x0bcc, 0x2395}, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD */
599 {0x0bce, 0x22a5}, /* uptack ⊥ UP TACK */
600 {0x0bcf, 0x25cb}, /* circle ○ WHITE CIRCLE */
601 {0x0bd3, 0x2308}, /* upstile ⌈ LEFT CEILING */
602 {0x0bd6, 0x222a}, /* downshoe ∪ UNION */
603 {0x0bd8, 0x2283}, /* rightshoe ⊃ SUPERSET OF */
604 {0x0bda, 0x2282}, /* leftshoe ⊂ SUBSET OF */
605 {0x0bdc, 0x22a3}, /* lefttack ⊣ LEFT TACK */
606 {0x0bfc, 0x22a2}, /* righttack ⊢ RIGHT TACK */
607 {0x0cdf, 0x2017}, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */
608 {0x0ce0, 0x05d0}, /* hebrew_aleph א HEBREW LETTER ALEF */
609 {0x0ce1, 0x05d1}, /* hebrew_bet ב HEBREW LETTER BET */
610 {0x0ce2, 0x05d2}, /* hebrew_gimel ג HEBREW LETTER GIMEL */
611 {0x0ce3, 0x05d3}, /* hebrew_dalet ד HEBREW LETTER DALET */
612 {0x0ce4, 0x05d4}, /* hebrew_he ה HEBREW LETTER HE */
613 {0x0ce5, 0x05d5}, /* hebrew_waw ו HEBREW LETTER VAV */
614 {0x0ce6, 0x05d6}, /* hebrew_zain ז HEBREW LETTER ZAYIN */
615 {0x0ce7, 0x05d7}, /* hebrew_chet ח HEBREW LETTER HET */
616 {0x0ce8, 0x05d8}, /* hebrew_tet ט HEBREW LETTER TET */
617 {0x0ce9, 0x05d9}, /* hebrew_yod י HEBREW LETTER YOD */
618 {0x0cea, 0x05da}, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */
619 {0x0ceb, 0x05db}, /* hebrew_kaph כ HEBREW LETTER KAF */
620 {0x0cec, 0x05dc}, /* hebrew_lamed ל HEBREW LETTER LAMED */
621 {0x0ced, 0x05dd}, /* hebrew_finalmem ם HEBREW LETTER FINAL MEM */
622 {0x0cee, 0x05de}, /* hebrew_mem מ HEBREW LETTER MEM */
623 {0x0cef, 0x05df}, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */
624 {0x0cf0, 0x05e0}, /* hebrew_nun נ HEBREW LETTER NUN */
625 {0x0cf1, 0x05e1}, /* hebrew_samech ס HEBREW LETTER SAMEKH */
626 {0x0cf2, 0x05e2}, /* hebrew_ayin ע HEBREW LETTER AYIN */
627 {0x0cf3, 0x05e3}, /* hebrew_finalpe ף HEBREW LETTER FINAL PE */
628 {0x0cf4, 0x05e4}, /* hebrew_pe פ HEBREW LETTER PE */
629 {0x0cf5, 0x05e5}, /* hebrew_finalzade ץ HEBREW LETTER FINAL TSADI */
630 {0x0cf6, 0x05e6}, /* hebrew_zade צ HEBREW LETTER TSADI */
631 {0x0cf7, 0x05e7}, /* hebrew_qoph ק HEBREW LETTER QOF */
632 {0x0cf8, 0x05e8}, /* hebrew_resh ר HEBREW LETTER RESH */
633 {0x0cf9, 0x05e9}, /* hebrew_shin ש HEBREW LETTER SHIN */
634 {0x0cfa, 0x05ea}, /* hebrew_taw ת HEBREW LETTER TAV */
635 {0x0da1, 0x0e01}, /* Thai_kokai ก THAI CHARACTER KO KAI */
636 {0x0da2, 0x0e02}, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */
637 {0x0da3, 0x0e03}, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */
638 {0x0da4, 0x0e04}, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */
639 {0x0da5, 0x0e05}, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */
640 {0x0da6, 0x0e06}, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */
641 {0x0da7, 0x0e07}, /* Thai_ngongu ง THAI CHARACTER NGO NGU */
642 {0x0da8, 0x0e08}, /* Thai_chochan จ THAI CHARACTER CHO CHAN */
643 {0x0da9, 0x0e09}, /* Thai_choching ฉ THAI CHARACTER CHO CHING */
644 {0x0daa, 0x0e0a}, /* Thai_chochang ช THAI CHARACTER CHO CHANG */
645 {0x0dab, 0x0e0b}, /* Thai_soso ซ THAI CHARACTER SO SO */
646 {0x0dac, 0x0e0c}, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */
647 {0x0dad, 0x0e0d}, /* Thai_yoying ญ THAI CHARACTER YO YING */
648 {0x0dae, 0x0e0e}, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */
649 {0x0daf, 0x0e0f}, /* Thai_topatak ฏ THAI CHARACTER TO PATAK */
650 {0x0db0, 0x0e10}, /* Thai_thothan ฐ THAI CHARACTER THO THAN */
651 {0x0db1, 0x0e11}, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */
652 {0x0db2, 0x0e12}, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */
653 {0x0db3, 0x0e13}, /* Thai_nonen ณ THAI CHARACTER NO NEN */
654 {0x0db4, 0x0e14}, /* Thai_dodek ด THAI CHARACTER DO DEK */
655 {0x0db5, 0x0e15}, /* Thai_totao ต THAI CHARACTER TO TAO */
656 {0x0db6, 0x0e16}, /* Thai_thothung ถ THAI CHARACTER THO THUNG */
657 {0x0db7, 0x0e17}, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */
658 {0x0db8, 0x0e18}, /* Thai_thothong ธ THAI CHARACTER THO THONG */
659 {0x0db9, 0x0e19}, /* Thai_nonu น THAI CHARACTER NO NU */
660 {0x0dba, 0x0e1a}, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */
661 {0x0dbb, 0x0e1b}, /* Thai_popla ป THAI CHARACTER PO PLA */
662 {0x0dbc, 0x0e1c}, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */
663 {0x0dbd, 0x0e1d}, /* Thai_fofa ฝ THAI CHARACTER FO FA */
664 {0x0dbe, 0x0e1e}, /* Thai_phophan พ THAI CHARACTER PHO PHAN */
665 {0x0dbf, 0x0e1f}, /* Thai_fofan ฟ THAI CHARACTER FO FAN */
666 {0x0dc0, 0x0e20}, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */
667 {0x0dc1, 0x0e21}, /* Thai_moma ม THAI CHARACTER MO MA */
668 {0x0dc2, 0x0e22}, /* Thai_yoyak ย THAI CHARACTER YO YAK */
669 {0x0dc3, 0x0e23}, /* Thai_rorua ร THAI CHARACTER RO RUA */
670 {0x0dc4, 0x0e24}, /* Thai_ru ฤ THAI CHARACTER RU */
671 {0x0dc5, 0x0e25}, /* Thai_loling ล THAI CHARACTER LO LING */
672 {0x0dc6, 0x0e26}, /* Thai_lu ฦ THAI CHARACTER LU */
673 {0x0dc7, 0x0e27}, /* Thai_wowaen ว THAI CHARACTER WO WAEN */
674 {0x0dc8, 0x0e28}, /* Thai_sosala ศ THAI CHARACTER SO SALA */
675 {0x0dc9, 0x0e29}, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */
676 {0x0dca, 0x0e2a}, /* Thai_sosua ส THAI CHARACTER SO SUA */
677 {0x0dcb, 0x0e2b}, /* Thai_hohip ห THAI CHARACTER HO HIP */
678 {0x0dcc, 0x0e2c}, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */
679 {0x0dcd, 0x0e2d}, /* Thai_oang อ THAI CHARACTER O ANG */
680 {0x0dce, 0x0e2e}, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */
681 {0x0dcf, 0x0e2f}, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */
682 {0x0dd0, 0x0e30}, /* Thai_saraa ะ THAI CHARACTER SARA A */
683 {0x0dd1, 0x0e31}, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */
684 {0x0dd2, 0x0e32}, /* Thai_saraaa า THAI CHARACTER SARA AA */
685 {0x0dd3, 0x0e33}, /* Thai_saraam ำ THAI CHARACTER SARA AM */
686 {0x0dd4, 0x0e34}, /* Thai_sarai ิ THAI CHARACTER SARA I */
687 {0x0dd5, 0x0e35}, /* Thai_saraii ี THAI CHARACTER SARA II */
688 {0x0dd6, 0x0e36}, /* Thai_saraue ึ THAI CHARACTER SARA UE */
689 {0x0dd7, 0x0e37}, /* Thai_sarauee ื THAI CHARACTER SARA UEE */
690 {0x0dd8, 0x0e38}, /* Thai_sarau ุ THAI CHARACTER SARA U */
691 {0x0dd9, 0x0e39}, /* Thai_sarauu ู THAI CHARACTER SARA UU */
692 {0x0dda, 0x0e3a}, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */
693 {0x0dde, 0x0e3e}, /* Thai_maihanakat_maitho ฾ ??? */
694 {0x0ddf, 0x0e3f}, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */
695 {0x0de0, 0x0e40}, /* Thai_sarae เ THAI CHARACTER SARA E */
696 {0x0de1, 0x0e41}, /* Thai_saraae แ THAI CHARACTER SARA AE */
697 {0x0de2, 0x0e42}, /* Thai_sarao โ THAI CHARACTER SARA O */
698 {0x0de3, 0x0e43}, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */
699 {0x0de4, 0x0e44}, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */
700 {0x0de5, 0x0e45}, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */
701 {0x0de6, 0x0e46}, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */
702 {0x0de7, 0x0e47}, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */
703 {0x0de8, 0x0e48}, /* Thai_maiek ่ THAI CHARACTER MAI EK */
704 {0x0de9, 0x0e49}, /* Thai_maitho ้ THAI CHARACTER MAI THO */
705 {0x0dea, 0x0e4a}, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */
706 {0x0deb, 0x0e4b}, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */
707 {0x0dec, 0x0e4c}, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */
708 {0x0ded, 0x0e4d}, /* Thai_nikhahit ํ THAI CHARACTER NIKHAHIT */
709 {0x0df0, 0x0e50}, /* Thai_leksun ๐ THAI DIGIT ZERO */
710 {0x0df1, 0x0e51}, /* Thai_leknung ๑ THAI DIGIT ONE */
711 {0x0df2, 0x0e52}, /* Thai_leksong ๒ THAI DIGIT TWO */
712 {0x0df3, 0x0e53}, /* Thai_leksam ๓ THAI DIGIT THREE */
713 {0x0df4, 0x0e54}, /* Thai_leksi ๔ THAI DIGIT FOUR */
714 {0x0df5, 0x0e55}, /* Thai_lekha ๕ THAI DIGIT FIVE */
715 {0x0df6, 0x0e56}, /* Thai_lekhok ๖ THAI DIGIT SIX */
716 {0x0df7, 0x0e57}, /* Thai_lekchet ๗ THAI DIGIT SEVEN */
717 {0x0df8, 0x0e58}, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */
718 {0x0df9, 0x0e59}, /* Thai_lekkao ๙ THAI DIGIT NINE */
719 {0x0ea1, 0x3131}, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */
720 {0x0ea2, 0x3132}, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */
721 {0x0ea3, 0x3133}, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */
722 {0x0ea4, 0x3134}, /* Hangul_Nieun ㄴ HANGUL LETTER NIEUN */
723 {0x0ea5, 0x3135}, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */
724 {0x0ea6, 0x3136}, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */
725 {0x0ea7, 0x3137}, /* Hangul_Dikeud ㄷ HANGUL LETTER TIKEUT */
726 {0x0ea8, 0x3138}, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */
727 {0x0ea9, 0x3139}, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */
728 {0x0eaa, 0x313a}, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */
729 {0x0eab, 0x313b}, /* Hangul_RieulMieum ㄻ HANGUL LETTER RIEUL-MIEUM */
730 {0x0eac, 0x313c}, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */
731 {0x0ead, 0x313d}, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */
732 {0x0eae, 0x313e}, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */
733 {0x0eaf, 0x313f}, /* Hangul_RieulPhieuf ㄿ HANGUL LETTER RIEUL-PHIEUPH */
734 {0x0eb0, 0x3140}, /* Hangul_RieulHieuh ㅀ HANGUL LETTER RIEUL-HIEUH */
735 {0x0eb1, 0x3141}, /* Hangul_Mieum ㅁ HANGUL LETTER MIEUM */
736 {0x0eb2, 0x3142}, /* Hangul_Pieub ㅂ HANGUL LETTER PIEUP */
737 {0x0eb3, 0x3143}, /* Hangul_SsangPieub ㅃ HANGUL LETTER SSANGPIEUP */
738 {0x0eb4, 0x3144}, /* Hangul_PieubSios ㅄ HANGUL LETTER PIEUP-SIOS */
739 {0x0eb5, 0x3145}, /* Hangul_Sios ㅅ HANGUL LETTER SIOS */
740 {0x0eb6, 0x3146}, /* Hangul_SsangSios ㅆ HANGUL LETTER SSANGSIOS */
741 {0x0eb7, 0x3147}, /* Hangul_Ieung ㅇ HANGUL LETTER IEUNG */
742 {0x0eb8, 0x3148}, /* Hangul_Jieuj ㅈ HANGUL LETTER CIEUC */
743 {0x0eb9, 0x3149}, /* Hangul_SsangJieuj ㅉ HANGUL LETTER SSANGCIEUC */
744 {0x0eba, 0x314a}, /* Hangul_Cieuc ㅊ HANGUL LETTER CHIEUCH */
745 {0x0ebb, 0x314b}, /* Hangul_Khieuq ㅋ HANGUL LETTER KHIEUKH */
746 {0x0ebc, 0x314c}, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */
747 {0x0ebd, 0x314d}, /* Hangul_Phieuf ㅍ HANGUL LETTER PHIEUPH */
748 {0x0ebe, 0x314e}, /* Hangul_Hieuh ㅎ HANGUL LETTER HIEUH */
749 {0x0ebf, 0x314f}, /* Hangul_A ㅏ HANGUL LETTER A */
750 {0x0ec0, 0x3150}, /* Hangul_AE ㅐ HANGUL LETTER AE */
751 {0x0ec1, 0x3151}, /* Hangul_YA ㅑ HANGUL LETTER YA */
752 {0x0ec2, 0x3152}, /* Hangul_YAE ㅒ HANGUL LETTER YAE */
753 {0x0ec3, 0x3153}, /* Hangul_EO ㅓ HANGUL LETTER EO */
754 {0x0ec4, 0x3154}, /* Hangul_E ㅔ HANGUL LETTER E */
755 {0x0ec5, 0x3155}, /* Hangul_YEO ㅕ HANGUL LETTER YEO */
756 {0x0ec6, 0x3156}, /* Hangul_YE ㅖ HANGUL LETTER YE */
757 {0x0ec7, 0x3157}, /* Hangul_O ㅗ HANGUL LETTER O */
758 {0x0ec8, 0x3158}, /* Hangul_WA ㅘ HANGUL LETTER WA */
759 {0x0ec9, 0x3159}, /* Hangul_WAE ㅙ HANGUL LETTER WAE */
760 {0x0eca, 0x315a}, /* Hangul_OE ㅚ HANGUL LETTER OE */
761 {0x0ecb, 0x315b}, /* Hangul_YO ㅛ HANGUL LETTER YO */
762 {0x0ecc, 0x315c}, /* Hangul_U ㅜ HANGUL LETTER U */
763 {0x0ecd, 0x315d}, /* Hangul_WEO ㅝ HANGUL LETTER WEO */
764 {0x0ece, 0x315e}, /* Hangul_WE ㅞ HANGUL LETTER WE */
765 {0x0ecf, 0x315f}, /* Hangul_WI ㅟ HANGUL LETTER WI */
766 {0x0ed0, 0x3160}, /* Hangul_YU ㅠ HANGUL LETTER YU */
767 {0x0ed1, 0x3161}, /* Hangul_EU ㅡ HANGUL LETTER EU */
768 {0x0ed2, 0x3162}, /* Hangul_YI ㅢ HANGUL LETTER YI */
769 {0x0ed3, 0x3163}, /* Hangul_I ㅣ HANGUL LETTER I */
770 {0x0ed4, 0x11a8}, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */
771 {0x0ed5, 0x11a9}, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */
772 {0x0ed6, 0x11aa}, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */
773 {0x0ed7, 0x11ab}, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */
774 {0x0ed8, 0x11ac}, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */
775 {0x0ed9, 0x11ad}, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */
776 {0x0eda, 0x11ae}, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */
777 {0x0edb, 0x11af}, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */
778 {0x0edc, 0x11b0}, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */
779 {0x0edd, 0x11b1}, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */
780 {0x0ede, 0x11b2}, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */
781 {0x0edf, 0x11b3}, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */
782 {0x0ee0, 0x11b4}, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */
783 {0x0ee1, 0x11b5}, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */
784 {0x0ee2, 0x11b6}, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */
785 {0x0ee3, 0x11b7}, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */
786 {0x0ee4, 0x11b8}, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */
787 {0x0ee5, 0x11b9}, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */
788 {0x0ee6, 0x11ba}, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */
789 {0x0ee7, 0x11bb}, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */
790 {0x0ee8, 0x11bc}, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */
791 {0x0ee9, 0x11bd}, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */
792 {0x0eea, 0x11be}, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */
793 {0x0eeb, 0x11bf}, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */
794 {0x0eec, 0x11c0}, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */
795 {0x0eed, 0x11c1}, /* Hangul_J_Phieuf ᇁ HANGUL JONGSEONG PHIEUPH */
796 {0x0eee, 0x11c2}, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */
797 {0x0eef, 0x316d}, /* Hangul_RieulYeorinHieuh ㅭ HANGUL LETTER RIEUL-YEORINHIEUH */
798 {0x0ef0, 0x3171}, /* Hangul_SunkyeongeumMieum ㅱ HANGUL LETTER KAPYEOUNMIEUM */
799 {0x0ef1, 0x3178}, /* Hangul_SunkyeongeumPieub ㅸ HANGUL LETTER KAPYEOUNPIEUP */
800 {0x0ef2, 0x317f}, /* Hangul_PanSios ㅿ HANGUL LETTER PANSIOS */
801 /* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */
802 {0x0ef4, 0x3184}, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
803 {0x0ef5, 0x3186}, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
804 {0x0ef6, 0x318d}, /* Hangul_AraeA ㆍ HANGUL LETTER ARAEA */
805 {0x0ef7, 0x318e}, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */
806 {0x0ef8, 0x11eb}, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */
807 /* 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? */
808 {0x0efa, 0x11f9}, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */
809 {0x0eff, 0x20a9}, /* Korean_Won ₩ WON SIGN */
810 {0x13bc, 0x0152}, /* OE ΠLATIN CAPITAL LIGATURE OE */
811 {0x13bd, 0x0153}, /* oe œ LATIN SMALL LIGATURE OE */
812 {0x13be, 0x0178}, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */
813 {0x20ac, 0x20ac}, /* EuroSign € EURO SIGN */
814 };
815
816 long keysym2ucs(xcb_keysym_t keysym) {
817 int min = 0;
818 int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
819 int mid;
820
821 /* first check for Latin-1 characters (1:1 mapping) */
822 if ((keysym >= 0x0020 && keysym <= 0x007e) ||
823 (keysym >= 0x00a0 && keysym <= 0x00ff))
824 return keysym;
825
826 /* also check for directly encoded 24-bit UCS characters */
827 if ((keysym & 0xff000000) == 0x01000000)
828 return keysym & 0x00ffffff;
829
830 /* binary search in table */
831 while (max >= min) {
832 mid = (min + max) / 2;
833 if (keysymtab[mid].keysym < keysym)
834 min = mid + 1;
835 else if (keysymtab[mid].keysym > keysym)
836 max = mid - 1;
837 else {
838 /* found it */
839 return keysymtab[mid].ucs;
840 }
841 }
842
843 /* no matching Unicode value found */
844 return -1;
845 }
0 #include <xcb/xcb.h>
1
2 long keysym2ucs(xcb_keysym_t keysym);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * i3-input/main.c: Utility which lets the user input commands and sends them
7 * to i3.
8 *
9 */
10 #include <stdio.h>
11 #include <sys/types.h>
12 #include <stdlib.h>
13 #include <stdbool.h>
14 #include <unistd.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <err.h>
18 #include <stdint.h>
19 #include <getopt.h>
20 #include <limits.h>
21
22 #include <xcb/xcb.h>
23 #include <xcb/xcb_aux.h>
24 #include <xcb/xcb_event.h>
25 #include <xcb/xcb_keysyms.h>
26
27 xcb_visualtype_t *visual_type = NULL;
28 #include "libi3.h"
29
30 #include <X11/keysym.h>
31
32 #include "keysym2ucs.h"
33
34 #include "i3-input.h"
35
36 #define MAX_WIDTH logical_px(500)
37 #define BORDER logical_px(2)
38 #define PADDING logical_px(2)
39
40 /* IPC format string. %s will be replaced with what the user entered, then
41 * the command will be sent to i3 */
42 static char *format;
43
44 static int sockfd;
45 static xcb_key_symbols_t *symbols;
46 static bool modeswitch_active = false;
47 static xcb_window_t win;
48 static surface_t surface;
49 static xcb_char2b_t glyphs_ucs[512];
50 static char *glyphs_utf8[512];
51 static int input_position;
52 static i3Font font;
53 static i3String *prompt;
54 static int prompt_offset = 0;
55 static int limit;
56 xcb_window_t root;
57 xcb_connection_t *conn;
58 xcb_screen_t *root_screen;
59
60 /*
61 * Having verboselog(), errorlog() and debuglog() is necessary when using libi3.
62 *
63 */
64 void verboselog(char *fmt, ...) {
65 va_list args;
66
67 va_start(args, fmt);
68 vfprintf(stdout, fmt, args);
69 va_end(args);
70 }
71
72 void errorlog(char *fmt, ...) {
73 va_list args;
74
75 va_start(args, fmt);
76 vfprintf(stderr, fmt, args);
77 va_end(args);
78 }
79
80 void debuglog(char *fmt, ...) {
81 }
82
83 /*
84 * Concats the glyphs (either UCS-2 or UTF-8) to a single string, suitable for
85 * rendering it (UCS-2) or sending it to i3 (UTF-8).
86 *
87 */
88 static uint8_t *concat_strings(char **glyphs, int max) {
89 uint8_t *output = scalloc(max + 1, 4);
90 uint8_t *walk = output;
91 for (int c = 0; c < max; c++) {
92 printf("at %c\n", glyphs[c][0]);
93 /* if the first byte is 0, this has to be UCS2 */
94 if (glyphs[c][0] == '\0') {
95 memcpy(walk, glyphs[c], 2);
96 walk += 2;
97 } else {
98 strcpy((char *)walk, glyphs[c]);
99 walk += strlen(glyphs[c]);
100 }
101 }
102 printf("output = %s\n", output);
103 return output;
104 }
105
106 /*
107 * Handles expose events (redraws of the window) and rendering in general. Will
108 * be called from the code with event == NULL or from X with event != NULL.
109 *
110 */
111 static int handle_expose(void *data, xcb_connection_t *conn, xcb_expose_event_t *event) {
112 printf("expose!\n");
113
114 color_t border_color = draw_util_hex_to_color("#FF0000");
115 color_t fg_color = draw_util_hex_to_color("#FFFFFF");
116 color_t bg_color = draw_util_hex_to_color("#000000");
117
118 int text_offset = BORDER + PADDING;
119
120 /* draw border */
121 draw_util_rectangle(&surface, border_color, 0, 0, surface.width, surface.height);
122
123 /* draw background */
124 draw_util_rectangle(&surface, bg_color, BORDER, BORDER, surface.width - 2 * BORDER, surface.height - 2 * BORDER);
125
126 /* draw the prompt … */
127 if (prompt != NULL) {
128 draw_util_text(prompt, &surface, fg_color, bg_color, text_offset, text_offset, MAX_WIDTH - text_offset);
129 }
130
131 /* … and the text */
132 if (input_position > 0) {
133 i3String *input = i3string_from_ucs2(glyphs_ucs, input_position);
134 draw_util_text(input, &surface, fg_color, bg_color, text_offset + prompt_offset, text_offset, MAX_WIDTH - text_offset);
135 i3string_free(input);
136 }
137
138 xcb_flush(conn);
139
140 return 1;
141 }
142
143 /*
144 * Deactivates the Mode_switch bit upon release of the Mode_switch key.
145 *
146 */
147 static int handle_key_release(void *ignored, xcb_connection_t *conn, xcb_key_release_event_t *event) {
148 printf("releasing %d, state raw = %d\n", event->detail, event->state);
149
150 xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, event->state);
151 if (sym == XK_Mode_switch) {
152 printf("Mode switch disabled\n");
153 modeswitch_active = false;
154 }
155
156 return 1;
157 }
158
159 static void finish_input(void) {
160 char *command = (char *)concat_strings(glyphs_utf8, input_position);
161
162 /* count the occurrences of %s in the string */
163 int c;
164 int len = strlen(format);
165 int cnt = 0;
166 for (c = 0; c < (len - 1); c++)
167 if (format[c] == '%' && format[c + 1] == 's')
168 cnt++;
169 printf("occurrences = %d\n", cnt);
170
171 /* allocate space for the output */
172 int inputlen = strlen(command);
173 char *full = scalloc(strlen(format) - (2 * cnt) /* format without all %s */
174 + (inputlen * cnt) /* replaced %s */
175 + 1, /* trailing NUL */
176 1);
177 char *dest = full;
178 for (c = 0; c < len; c++) {
179 /* if this is not % or it is % but without a following 's',
180 * just copy the character */
181 if (format[c] != '%' || (c == (len - 1)) || format[c + 1] != 's')
182 *(dest++) = format[c];
183 else {
184 strncat(dest, command, inputlen);
185 dest += inputlen;
186 /* skip the following 's' of '%s' */
187 c++;
188 }
189 }
190
191 /* prefix the command if a prefix was specified on commandline */
192 printf("command = %s\n", full);
193
194 ipc_send_message(sockfd, strlen(full), 0, (uint8_t *)full);
195
196 free(full);
197
198 exit(0);
199 }
200
201 /*
202 * Handles keypresses by converting the keycodes to keysymbols, then the
203 * keysymbols to UCS-2. If the conversion succeeded, the glyph is saved in the
204 * internal buffers and displayed in the input window.
205 *
206 * Also handles backspace (deleting one character) and return (sending the
207 * command to i3).
208 *
209 */
210 static int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_t *event) {
211 printf("Keypress %d, state raw = %d\n", event->detail, event->state);
212
213 // TODO: port the input handling code from i3lock once libxkbcommon ≥ 0.5.0
214 // is available in distros.
215
216 /* See the documentation of xcb_key_symbols_get_keysym for this one.
217 * Basically: We get either col 0 or col 1, depending on whether shift is
218 * pressed. */
219 int col = (event->state & XCB_MOD_MASK_SHIFT);
220
221 /* If modeswitch is currently active, we need to look in group 2 or 3,
222 * respectively. */
223 if (modeswitch_active)
224 col += 2;
225
226 xcb_keysym_t sym = xcb_key_press_lookup_keysym(symbols, event, col);
227 if (sym == XK_Mode_switch) {
228 printf("Mode switch enabled\n");
229 modeswitch_active = true;
230 return 1;
231 }
232
233 if (sym == XK_Return)
234 finish_input();
235
236 if (sym == XK_BackSpace) {
237 if (input_position == 0)
238 return 1;
239
240 input_position--;
241 free(glyphs_utf8[input_position]);
242
243 handle_expose(NULL, conn, NULL);
244 return 1;
245 }
246 if (sym == XK_Escape) {
247 exit(0);
248 }
249
250 /* TODO: handle all of these? */
251 printf("is_keypad_key = %d\n", xcb_is_keypad_key(sym));
252 printf("is_private_keypad_key = %d\n", xcb_is_private_keypad_key(sym));
253 printf("xcb_is_cursor_key = %d\n", xcb_is_cursor_key(sym));
254 printf("xcb_is_pf_key = %d\n", xcb_is_pf_key(sym));
255 printf("xcb_is_function_key = %d\n", xcb_is_function_key(sym));
256 printf("xcb_is_misc_function_key = %d\n", xcb_is_misc_function_key(sym));
257 printf("xcb_is_modifier_key = %d\n", xcb_is_modifier_key(sym));
258
259 if (xcb_is_modifier_key(sym) || xcb_is_cursor_key(sym))
260 return 1;
261
262 printf("sym = %c (%d)\n", sym, sym);
263
264 /* convert the keysym to UCS */
265 uint16_t ucs = keysym2ucs(sym);
266 if ((int16_t)ucs == -1) {
267 fprintf(stderr, "Keysym could not be converted to UCS, skipping\n");
268 return 1;
269 }
270
271 xcb_char2b_t inp;
272 inp.byte1 = (ucs & 0xff00) >> 2;
273 inp.byte2 = (ucs & 0x00ff) >> 0;
274
275 printf("inp.byte1 = %02x, inp.byte2 = %02x\n", inp.byte1, inp.byte2);
276 /* convert it to UTF-8 */
277 char *out = convert_ucs2_to_utf8(&inp, 1);
278 printf("converted to %s\n", out);
279
280 glyphs_ucs[input_position] = inp;
281 glyphs_utf8[input_position] = out;
282 input_position++;
283
284 if (input_position == limit)
285 finish_input();
286
287 handle_expose(NULL, conn, NULL);
288 return 1;
289 }
290
291 static xcb_rectangle_t get_window_position(void) {
292 xcb_rectangle_t result = (xcb_rectangle_t){logical_px(50), logical_px(50), MAX_WIDTH, font.height + 2 * BORDER + 2 * PADDING};
293
294 xcb_get_property_reply_t *supporting_wm_reply = NULL;
295 xcb_get_input_focus_reply_t *input_focus = NULL;
296 xcb_get_geometry_reply_t *geometry = NULL;
297 xcb_get_property_reply_t *wm_class = NULL;
298 xcb_translate_coordinates_reply_t *coordinates = NULL;
299
300 xcb_atom_t A__NET_SUPPORTING_WM_CHECK;
301 xcb_intern_atom_cookie_t nswc_cookie = xcb_intern_atom(conn, 0, strlen("_NET_SUPPORTING_WM_CHECK"), "_NET_SUPPORTING_WM_CHECK");
302 xcb_intern_atom_reply_t *nswc_reply = xcb_intern_atom_reply(conn, nswc_cookie, NULL);
303 if (nswc_reply == NULL) {
304 ELOG("Could not intern atom _NET_SUPPORTING_WM_CHECK\n");
305 exit(-1);
306 }
307 A__NET_SUPPORTING_WM_CHECK = nswc_reply->atom;
308 free(nswc_reply);
309
310 supporting_wm_reply = xcb_get_property_reply(
311 conn, xcb_get_property(conn, false, root, A__NET_SUPPORTING_WM_CHECK, XCB_ATOM_WINDOW, 0, 32), NULL);
312 xcb_window_t *supporting_wm_win = NULL;
313 if (supporting_wm_reply == NULL || xcb_get_property_value_length(supporting_wm_reply) == 0) {
314 DLOG("Could not determine EWMH support window.\n");
315 } else {
316 supporting_wm_win = xcb_get_property_value(supporting_wm_reply);
317 }
318
319 /* In rare cases, the window holding the input focus might disappear while we are figuring out its
320 * position. To avoid this, we grab the server in the meantime. */
321 xcb_grab_server(conn);
322
323 input_focus = xcb_get_input_focus_reply(conn, xcb_get_input_focus(conn), NULL);
324 if (input_focus == NULL || input_focus->focus == XCB_NONE) {
325 DLOG("Failed to receive the current input focus or no window has the input focus right now.\n");
326 goto free_resources;
327 }
328
329 /* We need to ignore the EWMH support window to which the focus can be set if there's no suitable window to focus. */
330 if (supporting_wm_win != NULL && input_focus->focus == *supporting_wm_win) {
331 DLOG("Input focus is on the EWMH support window, ignoring.\n");
332 goto free_resources;
333 }
334
335 geometry = xcb_get_geometry_reply(conn, xcb_get_geometry(conn, input_focus->focus), NULL);
336 if (geometry == NULL) {
337 DLOG("Failed to received window geometry.\n");
338 goto free_resources;
339 }
340
341 wm_class = xcb_get_property_reply(
342 conn, xcb_get_property(conn, false, input_focus->focus, XCB_ATOM_WM_CLASS, XCB_GET_PROPERTY_TYPE_ANY, 0, 32), NULL);
343
344 /* We need to find out whether the input focus is on an i3 frame window. If it is, we must not translate the coordinates. */
345 if (wm_class == NULL || xcb_get_property_value_length(wm_class) == 0 || strcmp(xcb_get_property_value(wm_class), "i3-frame") != 0) {
346 coordinates = xcb_translate_coordinates_reply(
347 conn, xcb_translate_coordinates(conn, input_focus->focus, root, geometry->x, geometry->y), NULL);
348 if (coordinates == NULL) {
349 DLOG("Failed to translate coordinates.\n");
350 goto free_resources;
351 }
352
353 DLOG("Determined coordinates of window with input focus at x = %i / y = %i.\n", coordinates->dst_x, coordinates->dst_y);
354 result.x += coordinates->dst_x;
355 result.y += coordinates->dst_y;
356 } else {
357 DLOG("Determined coordinates of window with input focus at x = %i / y = %i.\n", geometry->x, geometry->y);
358 result.x += geometry->x;
359 result.y += geometry->y;
360 }
361
362 free_resources:
363 xcb_ungrab_server(conn);
364 xcb_flush(conn);
365
366 FREE(supporting_wm_reply);
367 FREE(input_focus);
368 FREE(geometry);
369 FREE(wm_class);
370 FREE(coordinates);
371 return result;
372 }
373
374 int main(int argc, char *argv[]) {
375 format = sstrdup("%s");
376 char *socket_path = NULL;
377 char *pattern = sstrdup("pango:monospace 8");
378 int o, option_index = 0;
379
380 static struct option long_options[] = {
381 {"socket", required_argument, 0, 's'},
382 {"version", no_argument, 0, 'v'},
383 {"limit", required_argument, 0, 'l'},
384 {"prompt", required_argument, 0, 'P'},
385 {"prefix", required_argument, 0, 'p'},
386 {"format", required_argument, 0, 'F'},
387 {"font", required_argument, 0, 'f'},
388 {"help", no_argument, 0, 'h'},
389 {0, 0, 0, 0}};
390
391 char *options_string = "s:p:P:f:l:F:vh";
392
393 while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
394 switch (o) {
395 case 's':
396 FREE(socket_path);
397 socket_path = sstrdup(optarg);
398 break;
399 case 'v':
400 printf("i3-input " I3_VERSION);
401 return 0;
402 case 'p':
403 /* This option is deprecated, but will still work in i3 v4.1, 4.2 and 4.3 */
404 fprintf(stderr, "i3-input: WARNING: the -p option is DEPRECATED in favor of the -F (format) option\n");
405 FREE(format);
406 sasprintf(&format, "%s%%s", optarg);
407 break;
408 case 'l':
409 limit = atoi(optarg);
410 break;
411 case 'P':
412 i3string_free(prompt);
413 prompt = i3string_from_utf8(optarg);
414 break;
415 case 'f':
416 FREE(pattern);
417 pattern = sstrdup(optarg);
418 break;
419 case 'F':
420 FREE(format);
421 format = sstrdup(optarg);
422 break;
423 case 'h':
424 printf("i3-input " I3_VERSION "\n");
425 printf("i3-input [-s <socket>] [-F <format>] [-l <limit>] [-P <prompt>] [-f <font>] [-v]\n");
426 printf("\n");
427 printf("Example:\n");
428 printf(" i3-input -F 'workspace \"%%s\"' -P 'Switch to workspace: '\n");
429 return 0;
430 }
431 }
432
433 printf("using format \"%s\"\n", format);
434
435 int screen;
436 conn = xcb_connect(NULL, &screen);
437 if (!conn || xcb_connection_has_error(conn))
438 die("Cannot open display");
439
440 sockfd = ipc_connect(socket_path);
441
442 root_screen = xcb_aux_get_screen(conn, screen);
443 root = root_screen->root;
444
445 symbols = xcb_key_symbols_alloc(conn);
446
447 init_dpi();
448 font = load_font(pattern, true);
449 set_font(&font);
450
451 if (prompt != NULL)
452 prompt_offset = predict_text_width(prompt);
453
454 const xcb_rectangle_t win_pos = get_window_position();
455
456 /* Open an input window */
457 win = xcb_generate_id(conn);
458 xcb_create_window(
459 conn,
460 XCB_COPY_FROM_PARENT,
461 win, /* the window id */
462 root, /* parent == root */
463 win_pos.x, win_pos.y, win_pos.width, win_pos.height, /* dimensions */
464 0, /* X11 border = 0, we draw our own */
465 XCB_WINDOW_CLASS_INPUT_OUTPUT,
466 XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from parent */
467 XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK,
468 (uint32_t[]){
469 0, /* back pixel: black */
470 1, /* override redirect: don’t manage this window */
471 XCB_EVENT_MASK_EXPOSURE});
472
473 /* Map the window (make it visible) */
474 xcb_map_window(conn, win);
475
476 /* Initialize the drawable surface */
477 draw_util_surface_init(conn, &surface, win, get_visualtype(root_screen), win_pos.width, win_pos.height);
478
479 /* Grab the keyboard to get all input */
480 xcb_flush(conn);
481
482 /* Try (repeatedly, if necessary) to grab the keyboard. We might not
483 * get the keyboard at the first attempt because of the keybinding
484 * still being active when started via a wm’s keybinding. */
485 xcb_grab_keyboard_cookie_t cookie;
486 xcb_grab_keyboard_reply_t *reply = NULL;
487
488 int count = 0;
489 while ((reply == NULL || reply->status != XCB_GRAB_STATUS_SUCCESS) && (count++ < 500)) {
490 cookie = xcb_grab_keyboard(conn, false, win, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
491 reply = xcb_grab_keyboard_reply(conn, cookie, NULL);
492 usleep(1000);
493 }
494
495 if (reply->status != XCB_GRAB_STATUS_SUCCESS) {
496 fprintf(stderr, "Could not grab keyboard, status = %d\n", reply->status);
497 exit(-1);
498 }
499
500 xcb_flush(conn);
501
502 xcb_generic_event_t *event;
503 while ((event = xcb_wait_for_event(conn)) != NULL) {
504 if (event->response_type == 0) {
505 fprintf(stderr, "X11 Error received! sequence %x\n", event->sequence);
506 continue;
507 }
508
509 /* Strip off the highest bit (set if the event is generated) */
510 int type = (event->response_type & 0x7F);
511
512 switch (type) {
513 case XCB_KEY_PRESS:
514 handle_key_press(NULL, conn, (xcb_key_press_event_t *)event);
515 break;
516
517 case XCB_KEY_RELEASE:
518 handle_key_release(NULL, conn, (xcb_key_release_event_t *)event);
519 break;
520
521 case XCB_EXPOSE:
522 if (((xcb_expose_event_t *)event)->count == 0) {
523 handle_expose(NULL, conn, (xcb_expose_event_t *)event);
524 }
525
526 break;
527 }
528
529 free(event);
530 }
531
532 draw_util_surface_free(conn, &surface);
533 return 0;
534 }
0 #!/usr/bin/env perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # script to migrate an old config file (i3 < 4.0) to the new format (>= 4.0)
4 # this script only uses modules which come with perl 5.10
5 #
6 # reads an i3 v3 config from stdin and spits out a v4 config on stdout
7 # exit codes:
8 # 0 = the input was a v3 config
9 # 1 = the input was already a v4 config
10 # (the config is printed to stdout nevertheless)
11 #
12 # © 2011 Michael Stapelberg and contributors, see LICENSE
13
14 use strict;
15 use warnings;
16 use Getopt::Long;
17 use v5.10;
18
19 # is this a version 3 config file? disables auto-detection
20 my $v3 = 0;
21 my $result = GetOptions('v3' => \$v3);
22
23 # reads stdin
24 sub slurp {
25 local $/;
26 <>;
27 }
28
29 my @unchanged = qw(
30 font
31 set
32 mode
33 exec
34 assign
35 floating_modifier
36 focus_follows_mouse
37 ipc-socket
38 ipc_socket
39 client.focused
40 client.focused_inactive
41 client.unfocused
42 client.urgent
43 client.background
44 );
45
46 my %workspace_names;
47 my $workspace_bar = 1;
48
49 my $input = slurp();
50 my @lines = split /\n/, $input;
51
52 # remove whitespaces in the beginning of lines
53 @lines = map { s/^[ \t]*//g; $_ } @lines;
54
55 # Try to auto-detect if this is a v3 config file.
56 sub need_to_convert {
57 # If the user passed --v3, we need to convert in any case
58 return 1 if $v3;
59
60 for my $line (@lines) {
61 # only v4 configfiles can use bindcode or workspace_layout
62 return 0 if $line =~ /^bindcode/ ||
63 $line =~ /^workspace_layout/ ||
64 $line =~ /^force_focus_wrapping/;
65
66 # have a look at bindings
67 next unless $line =~ /^bind/;
68
69 my ($statement, $key, $command) = ($line =~ /([a-zA-Z_-]+)\s+([^\s]+)\s+(.*)/);
70 return 0 if $command =~ /^layout/ ||
71 $command =~ /^floating/ ||
72 $command =~ /^workspace/ ||
73 $command =~ /^focus (left|right|up|down)/ ||
74 $command =~ /^border (normal|1pixel|none)/;
75 }
76
77 return 1;
78 }
79
80 if (!need_to_convert()) {
81 # If this is already a v4 config file, we will spit out the lines
82 # and exit with return code 1
83 print $input;
84 exit 1;
85 }
86
87 # first pass: get workspace names
88 for my $line (@lines) {
89 next if $line =~ /^#/ || $line =~ /^$/;
90
91 my ($statement, $parameters) = ($line =~ /([a-zA-Z._-]+)(.*)/);
92
93 # skip everything but workspace lines
94 next unless defined($statement) and $statement eq 'workspace';
95
96 my ($number, $params) = ($parameters =~ /\s+([0-9]+)\s+(.+)/);
97
98 # save workspace name (unless the line is actually a workspace assignment)
99 $workspace_names{$number} = $params unless $params =~ /^output/;
100 }
101
102 for my $line (@lines) {
103 # directly use comments and empty lines
104 if ($line =~ /^#/ || $line =~ /^$/) {
105 print "$line\n";
106 next;
107 }
108
109 my ($statement, $parameters) = ($line =~ /([a-zA-Z._-]+)(.*)/);
110
111 # directly use lines which have not changed between 3.x and 4.x
112 if (!defined($statement) || (lc $statement ~~ @unchanged)) {
113 print "$line\n";
114 next;
115 }
116
117 # new_container changed only the statement name to workspace_layout
118 if ($statement eq 'new_container') {
119 print "workspace_layout$parameters\n";
120 next;
121 }
122
123 # workspace_bar is gone, you should use i3bar now
124 if ($statement eq 'workspace_bar') {
125 $workspace_bar = ($parameters =~ /\s+(yes|true|on|enable|active)/);
126 print "# XXX: REMOVED workspace_bar line. There is no internal workspace bar in v4.\n";
127 next;
128 }
129
130 # new_window changed the parameters from bb to none etc.
131 if ($statement eq 'new_window') {
132 if ($parameters =~ /bb/) {
133 print "new_window none\n";
134 } elsif ($parameters =~ /bp/) {
135 print "new_window 1pixel\n";
136 } elsif ($parameters =~ /bn/) {
137 print "new_window normal\n";
138 } else {
139 print "# XXX: Invalid parameter for new_window, not touching line:\n";
140 print "$line\n";
141 }
142 next;
143 }
144
145 # bar colors are obsolete, need to be configured in i3bar
146 if ($statement =~ /^bar\./) {
147 print "# XXX: REMOVED $statement, configure i3bar instead.\n";
148 print "# Old line: $line\n";
149 next;
150 }
151
152 # one form of this is still ok (workspace assignments), the other (named workspaces) isn’t
153 if ($statement eq 'workspace') {
154 my ($number, $params) = ($parameters =~ /\s+([0-9]+)\s+(.+)/);
155 if ($params =~ /^output/) {
156 print "$line\n";
157 next;
158 } else {
159 print "# XXX: workspace name will end up in the corresponding bindings.\n";
160 next;
161 }
162 }
163
164 if ($statement eq 'bind' || $statement eq 'bindsym') {
165 convert_command($line);
166 next;
167 }
168
169 print "# XXX: migration script could not handle line: $line\n";
170 }
171
172 #
173 # Converts a command (after bind/bindsym)
174 #
175 sub convert_command {
176 my ($line) = @_;
177
178 my @unchanged_cmds = qw(
179 exec
180 mark
181 kill
182 restart
183 reload
184 exit
185 );
186
187 my ($statement, $key, $command) = ($line =~ /([a-zA-Z_-]+)\s+([^\s]+)\s+(.*)/);
188
189 # turn 'bind' to 'bindcode'
190 $statement = 'bindcode' if $statement eq 'bind';
191
192 # check if it’s one of the unchanged commands
193 my ($cmd) = ($command =~ /([a-zA-Z_-]+)/);
194 if ($cmd ~~ @unchanged_cmds) {
195 print "$statement $key $command\n";
196 return;
197 }
198
199 # simple replacements
200 my @replace = (
201 qr/^s/ => 'layout stacking',
202 qr/^d/ => 'layout toggle split',
203 qr/^T/ => 'layout tabbed',
204 qr/^f($|[^go])/ => 'fullscreen',
205 qr/^fg/ => 'fullscreen global',
206 qr/^t/ => 'floating toggle',
207 qr/^h/ => 'focus left',
208 qr/^j($|[^u])/ => 'focus down',
209 qr/^k/ => 'focus up',
210 qr/^l/ => 'focus right',
211 qr/^mh/ => 'move left',
212 qr/^mj/ => 'move down',
213 qr/^mk/ => 'move up',
214 qr/^ml/ => 'move right',
215 qr/^bn/ => 'border normal',
216 qr/^bp/ => 'border 1pixel',
217 qr/^bb/ => 'border none',
218 qr/^bt/ => 'border toggle',
219 qr/^pw/ => 'workspace prev',
220 qr/^nw/ => 'workspace next',
221 );
222
223 my $replaced = 0;
224 for (my $c = 0; $c < @replace; $c += 2) {
225 if ($command =~ $replace[$c]) {
226 $command = $replace[$c+1];
227 $replaced = 1;
228 last;
229 }
230 }
231
232 # goto command is now obsolete due to criteria + focus command
233 if ($command =~ /^goto/) {
234 my ($mark) = ($command =~ /^goto\s+(.*)/);
235 print qq|$statement $key [con_mark="$mark"] focus\n|;
236 return;
237 }
238
239 # the jump command is also obsolete due to criteria + focus
240 if ($command =~ /^jump/) {
241 my ($params) = ($command =~ /^jump\s+(.*)/);
242 if ($params =~ /^"/) {
243 # jump ["]window class[/window title]["]
244 ($params) = ($params =~ /^"([^"]+)"/);
245
246 # check if a window title was specified
247 if ($params =~ m,/,) {
248 my ($class, $title) = ($params =~ m,([^/]+)/(.+),);
249 print qq|$statement $key [class="$class" title="$title"] focus\n|;
250 } else {
251 print qq|$statement $key [class="$params"] focus\n|;
252 }
253 return;
254 } else {
255 # jump <workspace> [ column row ]
256 print "# XXX: jump workspace is obsolete in 4.x: $line\n";
257 return;
258 }
259 }
260
261 if (!$replaced && $command =~ /^focus/) {
262 my ($what) = ($command =~ /^focus\s+(.*)/);
263 $what =~ s/\s//g;
264 if ($what eq 'ft') {
265 $what = 'mode_toggle';
266 } elsif ($what eq 'floating' || $what eq 'tiling') {
267 # those are unchanged
268 } else {
269 print "# XXX: focus <number> is obsolete in 4.x: $line\n";
270 return;
271 }
272 print qq|$statement $key focus $what\n|;
273 return;
274 }
275
276 if ($command =~ /^mode/) {
277 my ($parameters) = ($command =~ /^mode\s+(.*)/);
278 print qq|$statement $key mode "$parameters"\n|;
279 return;
280 }
281
282 # the parameters of the resize command have changed
283 if ($command =~ /^resize/) {
284 # OLD: resize <left|right|top|bottom> [+|-]<pixels>\n")
285 # NEW: resize <grow|shrink> <direction> [<px> px] [or <ppt> ppt]
286 my ($direction, $sign, $px) = ($command =~ /^resize\s+(left|right|top|bottom)\s+([+-])([0-9]+)/);
287 my $cmd = 'resize ';
288 $cmd .= ($sign eq '+' ? 'grow' : 'shrink') . ' ';
289 if ($direction eq 'top') {
290 $direction = 'up';
291 } elsif ($direction eq 'bottom') {
292 $direction = 'down';
293 }
294 $cmd .= "$direction ";
295 $cmd .= "$px px";
296 print qq|$statement $key $cmd\n|;
297 return;
298 }
299
300 # switch workspace
301 if ($command =~ /^[0-9]+/) {
302 my ($number) = ($command =~ /^([0-9]+)/);
303 if (exists $workspace_names{$number}) {
304 print qq|$statement $key workspace $workspace_names{$number}\n|;
305 return;
306 } else {
307 print qq|$statement $key workspace $number\n|;
308 return;
309 }
310 }
311
312 # move to workspace
313 if ($command =~ /^m[0-9]+/) {
314 my ($number) = ($command =~ /^m([0-9]+)/);
315 if (exists $workspace_names{$number}) {
316 print qq|$statement $key move container to workspace $workspace_names{$number}\n|;
317 return;
318 } else {
319 print qq|$statement $key move container to workspace $number\n|;
320 return;
321 }
322 }
323
324 # With Container-commands are now obsolete due to different abstraction
325 if ($command =~ /^wc/) {
326 $command =~ s/^wc//g;
327 my $wc_replaced = 0;
328 for (my $c = 0; $c < @replace; $c += 2) {
329 if ($command =~ $replace[$c]) {
330 $command = $replace[$c+1];
331 $wc_replaced = 1;
332 last;
333 }
334 }
335 if (!$wc_replaced) {
336 print "# XXX: migration script could not handle command: $line\n";
337 } else {
338 # NOTE: This is not 100% accurate, as it only works for one level
339 # of nested containers. As this is a common use case, we use 'focus
340 # parent; $command' nevertheless. For advanced use cases, the user
341 # has to modify their config.
342 print "$statement $key focus parent; $command\n";
343 }
344 return;
345 }
346
347 if ($replaced) {
348 print "$statement $key $command\n";
349 } else {
350 print "# XXX: migration script could not handle command: $line\n";
351 }
352 }
353
354
355 # add an i3bar invocation automatically if no 'workspace_bar no' was found
356 if ($workspace_bar) {
357 print "\n";
358 print "# XXX: Automatically added a bar configuration\n";
359 print "bar {\n";
360 print " status_command i3status\n";
361 print "}\n";
362 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * i3-msg/main.c: Utility which sends messages to a running i3-instance using
7 * IPC via UNIX domain sockets.
8 *
9 * This (in combination with libi3/ipc_send_message.c and
10 * libi3/ipc_recv_message.c) serves as an example for how to send your own
11 * messages to i3.
12 *
13 * Additionally, it’s even useful sometimes :-).
14 *
15 */
16 #include "libi3.h"
17
18 #include <stdio.h>
19 #include <stdbool.h>
20 #include <sys/types.h>
21 #include <sys/socket.h>
22 #include <sys/un.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <err.h>
28 #include <stdint.h>
29 #include <getopt.h>
30 #include <limits.h>
31
32 #include <yajl/yajl_parse.h>
33 #include <yajl/yajl_version.h>
34
35 #include <xcb/xcb.h>
36 #include <xcb/xcb_aux.h>
37
38 #include <i3/ipc.h>
39
40 /*
41 * Having verboselog() and errorlog() is necessary when using libi3.
42 *
43 */
44 void verboselog(char *fmt, ...) {
45 va_list args;
46
47 va_start(args, fmt);
48 vfprintf(stdout, fmt, args);
49 va_end(args);
50 }
51
52 void errorlog(char *fmt, ...) {
53 va_list args;
54
55 va_start(args, fmt);
56 vfprintf(stderr, fmt, args);
57 va_end(args);
58 }
59
60 static char *last_key = NULL;
61
62 typedef struct reply_t {
63 bool success;
64 char *error;
65 char *input;
66 char *errorposition;
67 } reply_t;
68
69 static int exit_code = 0;
70 static reply_t last_reply;
71
72 static int reply_boolean_cb(void *params, int val) {
73 if (strcmp(last_key, "success") == 0)
74 last_reply.success = val;
75 return 1;
76 }
77
78 static int reply_string_cb(void *params, const unsigned char *val, size_t len) {
79 char *str = sstrndup((const char *)val, len);
80
81 if (strcmp(last_key, "error") == 0)
82 last_reply.error = str;
83 else if (strcmp(last_key, "input") == 0)
84 last_reply.input = str;
85 else if (strcmp(last_key, "errorposition") == 0)
86 last_reply.errorposition = str;
87 else
88 free(str);
89 return 1;
90 }
91
92 static int reply_start_map_cb(void *params) {
93 return 1;
94 }
95
96 static int reply_end_map_cb(void *params) {
97 if (!last_reply.success) {
98 if (last_reply.input) {
99 fprintf(stderr, "ERROR: Your command: %s\n", last_reply.input);
100 fprintf(stderr, "ERROR: %s\n", last_reply.errorposition);
101 }
102 fprintf(stderr, "ERROR: %s\n", last_reply.error);
103 exit_code = 2;
104 }
105 return 1;
106 }
107
108 static int reply_map_key_cb(void *params, const unsigned char *keyVal, size_t keyLen) {
109 free(last_key);
110 last_key = sstrndup((const char *)keyVal, keyLen);
111 return 1;
112 }
113
114 static yajl_callbacks reply_callbacks = {
115 .yajl_boolean = reply_boolean_cb,
116 .yajl_string = reply_string_cb,
117 .yajl_start_map = reply_start_map_cb,
118 .yajl_map_key = reply_map_key_cb,
119 .yajl_end_map = reply_end_map_cb,
120 };
121
122 /*******************************************************************************
123 * Config reply callbacks
124 *******************************************************************************/
125
126 static char *config_last_key = NULL;
127
128 static int config_string_cb(void *params, const unsigned char *val, size_t len) {
129 char *str = sstrndup((const char *)val, len);
130 if (strcmp(config_last_key, "config") == 0) {
131 fprintf(stdout, "%s", str);
132 }
133 free(str);
134 return 1;
135 }
136
137 static int config_start_map_cb(void *params) {
138 return 1;
139 }
140
141 static int config_end_map_cb(void *params) {
142 return 1;
143 }
144
145 static int config_map_key_cb(void *params, const unsigned char *keyVal, size_t keyLen) {
146 config_last_key = sstrndup((const char *)keyVal, keyLen);
147 return 1;
148 }
149
150 static yajl_callbacks config_callbacks = {
151 .yajl_string = config_string_cb,
152 .yajl_start_map = config_start_map_cb,
153 .yajl_map_key = config_map_key_cb,
154 .yajl_end_map = config_end_map_cb,
155 };
156
157 int main(int argc, char *argv[]) {
158 #if defined(__OpenBSD__)
159 if (pledge("stdio rpath unix", NULL) == -1)
160 err(EXIT_FAILURE, "pledge");
161 #endif
162 char *socket_path = NULL;
163 int o, option_index = 0;
164 uint32_t message_type = I3_IPC_MESSAGE_TYPE_RUN_COMMAND;
165 char *payload = NULL;
166 bool quiet = false;
167 bool monitor = false;
168
169 static struct option long_options[] = {
170 {"socket", required_argument, 0, 's'},
171 {"type", required_argument, 0, 't'},
172 {"version", no_argument, 0, 'v'},
173 {"quiet", no_argument, 0, 'q'},
174 {"monitor", no_argument, 0, 'm'},
175 {"help", no_argument, 0, 'h'},
176 {0, 0, 0, 0}};
177
178 char *options_string = "s:t:vhqm";
179
180 while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
181 if (o == 's') {
182 free(socket_path);
183 socket_path = sstrdup(optarg);
184 } else if (o == 't') {
185 if (strcasecmp(optarg, "command") == 0) {
186 message_type = I3_IPC_MESSAGE_TYPE_RUN_COMMAND;
187 } else if (strcasecmp(optarg, "run_command") == 0) {
188 message_type = I3_IPC_MESSAGE_TYPE_RUN_COMMAND;
189 } else if (strcasecmp(optarg, "get_workspaces") == 0) {
190 message_type = I3_IPC_MESSAGE_TYPE_GET_WORKSPACES;
191 } else if (strcasecmp(optarg, "get_outputs") == 0) {
192 message_type = I3_IPC_MESSAGE_TYPE_GET_OUTPUTS;
193 } else if (strcasecmp(optarg, "get_tree") == 0) {
194 message_type = I3_IPC_MESSAGE_TYPE_GET_TREE;
195 } else if (strcasecmp(optarg, "get_marks") == 0) {
196 message_type = I3_IPC_MESSAGE_TYPE_GET_MARKS;
197 } else if (strcasecmp(optarg, "get_bar_config") == 0) {
198 message_type = I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG;
199 } else if (strcasecmp(optarg, "get_binding_modes") == 0) {
200 message_type = I3_IPC_MESSAGE_TYPE_GET_BINDING_MODES;
201 } else if (strcasecmp(optarg, "get_version") == 0) {
202 message_type = I3_IPC_MESSAGE_TYPE_GET_VERSION;
203 } else if (strcasecmp(optarg, "get_config") == 0) {
204 message_type = I3_IPC_MESSAGE_TYPE_GET_CONFIG;
205 } else if (strcasecmp(optarg, "send_tick") == 0) {
206 message_type = I3_IPC_MESSAGE_TYPE_SEND_TICK;
207 } else if (strcasecmp(optarg, "subscribe") == 0) {
208 message_type = I3_IPC_MESSAGE_TYPE_SUBSCRIBE;
209 } else {
210 printf("Unknown message type\n");
211 printf("Known types: run_command, get_workspaces, get_outputs, get_tree, get_marks, get_bar_config, get_binding_modes, get_version, get_config, send_tick, subscribe\n");
212 exit(EXIT_FAILURE);
213 }
214 } else if (o == 'q') {
215 quiet = true;
216 } else if (o == 'm') {
217 monitor = true;
218 } else if (o == 'v') {
219 printf("i3-msg " I3_VERSION "\n");
220 return 0;
221 } else if (o == 'h') {
222 printf("i3-msg " I3_VERSION "\n");
223 printf("i3-msg [-s <socket>] [-t <type>] [-m] <message>\n");
224 return 0;
225 } else if (o == '?') {
226 exit(EXIT_FAILURE);
227 }
228 }
229
230 if (monitor && message_type != I3_IPC_MESSAGE_TYPE_SUBSCRIBE) {
231 fprintf(stderr, "The monitor option -m is used with -t SUBSCRIBE exclusively.\n");
232 exit(EXIT_FAILURE);
233 }
234
235 /* Use all arguments, separated by whitespace, as payload.
236 * This way, you don’t have to do i3-msg 'mark foo', you can use
237 * i3-msg mark foo */
238 while (optind < argc) {
239 if (!payload) {
240 payload = sstrdup(argv[optind]);
241 } else {
242 char *both;
243 sasprintf(&both, "%s %s", payload, argv[optind]);
244 free(payload);
245 payload = both;
246 }
247 optind++;
248 }
249
250 if (!payload)
251 payload = sstrdup("");
252
253 int sockfd = ipc_connect(socket_path);
254 if (ipc_send_message(sockfd, strlen(payload), message_type, (uint8_t *)payload) == -1)
255 err(EXIT_FAILURE, "IPC: write()");
256 free(payload);
257
258 uint32_t reply_length;
259 uint32_t reply_type;
260 uint8_t *reply;
261 int ret;
262 if ((ret = ipc_recv_message(sockfd, &reply_type, &reply_length, &reply)) != 0) {
263 if (ret == -1)
264 err(EXIT_FAILURE, "IPC: read()");
265 exit(1);
266 }
267 if (reply_type != message_type)
268 errx(EXIT_FAILURE, "IPC: Received reply of type %d but expected %d", reply_type, message_type);
269 /* For the reply of commands, have a look if that command was successful.
270 * If not, nicely format the error message. */
271 if (reply_type == I3_IPC_REPLY_TYPE_COMMAND) {
272 yajl_handle handle = yajl_alloc(&reply_callbacks, NULL, NULL);
273 yajl_status state = yajl_parse(handle, (const unsigned char *)reply, reply_length);
274 yajl_free(handle);
275
276 switch (state) {
277 case yajl_status_ok:
278 break;
279 case yajl_status_client_canceled:
280 case yajl_status_error:
281 errx(EXIT_FAILURE, "IPC: Could not parse JSON reply.");
282 }
283
284 if (!quiet) {
285 printf("%.*s\n", reply_length, reply);
286 }
287 } else if (reply_type == I3_IPC_REPLY_TYPE_CONFIG) {
288 yajl_handle handle = yajl_alloc(&config_callbacks, NULL, NULL);
289 yajl_status state = yajl_parse(handle, (const unsigned char *)reply, reply_length);
290 yajl_free(handle);
291
292 switch (state) {
293 case yajl_status_ok:
294 break;
295 case yajl_status_client_canceled:
296 case yajl_status_error:
297 errx(EXIT_FAILURE, "IPC: Could not parse JSON reply.");
298 }
299 } else if (reply_type == I3_IPC_REPLY_TYPE_SUBSCRIBE) {
300 do {
301 free(reply);
302 if ((ret = ipc_recv_message(sockfd, &reply_type, &reply_length, &reply)) != 0) {
303 if (ret == -1)
304 err(EXIT_FAILURE, "IPC: read()");
305 exit(1);
306 }
307
308 if (!(reply_type & I3_IPC_EVENT_MASK)) {
309 errx(EXIT_FAILURE, "IPC: Received reply of type %d but expected an event", reply_type);
310 }
311
312 if (!quiet) {
313 fprintf(stdout, "%.*s\n", reply_length, reply);
314 fflush(stdout);
315 }
316 } while (monitor);
317 } else {
318 if (!quiet) {
319 printf("%.*s\n", reply_length, reply);
320 }
321 }
322
323 free(reply);
324
325 close(sockfd);
326
327 return exit_code;
328 }
0 xmacro(_NET_WM_WINDOW_TYPE)
1 xmacro(_NET_WM_WINDOW_TYPE_DOCK)
2 xmacro(_NET_WM_STRUT_PARTIAL)
3 xmacro(I3_SOCKET_PATH)
4 xmacro(ATOM)
5 xmacro(CARDINAL)
0 #pragma once
1
2 #include <config.h>
3
4 #include <err.h>
5
6 #define die(...) errx(EXIT_FAILURE, __VA_ARGS__);
7 #define FREE(pointer) \
8 do { \
9 free(pointer); \
10 pointer = NULL; \
11 } while (0)
12
13 #define xmacro(atom) xcb_atom_t A_##atom;
14 #include "atoms.xmacro"
15 #undef xmacro
16
17 extern xcb_window_t root;
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * i3-nagbar is a utility which displays a nag message, for example in the case
7 * when the user has an error in their configuration file.
8 *
9 */
10 #include <stdio.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <sys/wait.h>
14 #include <stdlib.h>
15 #include <stdbool.h>
16 #include <unistd.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <err.h>
20 #include <stdint.h>
21 #include <getopt.h>
22 #include <limits.h>
23 #include <fcntl.h>
24 #include <paths.h>
25
26 #include <xcb/xcb.h>
27 #include <xcb/xcb_aux.h>
28 #include <xcb/xcb_event.h>
29 #include <xcb/randr.h>
30 #include <xcb/xcb_cursor.h>
31
32 xcb_visualtype_t *visual_type = NULL;
33 #include "libi3.h"
34
35 #define SN_API_NOT_YET_FROZEN 1
36 #include <libsn/sn-launchee.h>
37
38 #include "i3-nagbar.h"
39
40 #define MSG_PADDING logical_px(8)
41 #define BTN_PADDING logical_px(3)
42 #define BTN_BORDER logical_px(3)
43 #define BTN_GAP logical_px(20)
44 #define CLOSE_BTN_GAP logical_px(15)
45 #define BAR_BORDER logical_px(2)
46
47 static char *argv0 = NULL;
48
49 typedef struct {
50 i3String *label;
51 char *action;
52 int16_t x;
53 uint16_t width;
54 bool terminal;
55 } button_t;
56
57 static xcb_window_t win;
58 static surface_t bar;
59
60 static i3Font font;
61 static i3String *prompt;
62
63 static button_t btn_close;
64 static button_t *buttons;
65 static int buttoncnt;
66
67 /* Result of get_colorpixel() for the various colors. */
68 static color_t color_background; /* background of the bar */
69 static color_t color_button_background; /* background for buttons */
70 static color_t color_border; /* color of the button border */
71 static color_t color_border_bottom; /* color of the bottom border */
72 static color_t color_text; /* color of the text */
73
74 xcb_window_t root;
75 xcb_connection_t *conn;
76 xcb_screen_t *root_screen;
77
78 /*
79 * Having verboselog(), errorlog() and debuglog() is necessary when using libi3.
80 *
81 */
82 void verboselog(char *fmt, ...) {
83 va_list args;
84
85 va_start(args, fmt);
86 vfprintf(stderr, fmt, args);
87 va_end(args);
88 }
89
90 void errorlog(char *fmt, ...) {
91 va_list args;
92
93 va_start(args, fmt);
94 vfprintf(stderr, fmt, args);
95 va_end(args);
96 }
97
98 void debuglog(char *fmt, ...) {
99 }
100
101 /*
102 * Starts the given application by passing it through a shell. We use double
103 * fork to avoid zombie processes. As the started application’s parent exits
104 * (immediately), the application is reparented to init (process-id 1), which
105 * correctly handles children, so we don’t have to do it :-).
106 */
107 static void start_application(const char *command) {
108 printf("executing: %s\n", command);
109 if (fork() == 0) {
110 /* Child process */
111 setsid();
112 if (fork() == 0) {
113 /* This is the child */
114 execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, NULL);
115 /* not reached */
116 }
117 exit(0);
118 }
119 wait(0);
120 }
121
122 static button_t *get_button_at(int16_t x, int16_t y) {
123 for (int c = 0; c < buttoncnt; c++)
124 if (x >= (buttons[c].x) && x <= (buttons[c].x + buttons[c].width))
125 return &buttons[c];
126
127 return NULL;
128 }
129
130 static void handle_button_press(xcb_connection_t *conn, xcb_button_press_event_t *event) {
131 printf("button pressed on x = %d, y = %d\n",
132 event->event_x, event->event_y);
133 /* TODO: set a flag for the button, re-render */
134 }
135
136 /*
137 * Called when the user releases the mouse button. Checks whether the
138 * coordinates are over a button and executes the appropriate action.
139 *
140 */
141 static void handle_button_release(xcb_connection_t *conn, xcb_button_release_event_t *event) {
142 printf("button released on x = %d, y = %d\n",
143 event->event_x, event->event_y);
144 /* If the user hits the close button, we exit(0) */
145 if (event->event_x >= btn_close.x && event->event_x < btn_close.x + btn_close.width)
146 exit(0);
147 button_t *button = get_button_at(event->event_x, event->event_y);
148 if (!button)
149 return;
150
151 /* We need to create a custom script containing our actual command
152 * since not every terminal emulator which is contained in
153 * i3-sensible-terminal supports -e with multiple arguments (and not
154 * all of them support -e with one quoted argument either).
155 *
156 * NB: The paths need to be unique, that is, don’t assume users close
157 * their nagbars at any point in time (and they still need to work).
158 * */
159 char *script_path = get_process_filename("nagbar-cmd");
160
161 int fd = open(script_path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
162 if (fd == -1) {
163 warn("Could not create temporary script to store the nagbar command");
164 return;
165 }
166 FILE *script = fdopen(fd, "w");
167 if (script == NULL) {
168 warn("Could not fdopen() temporary script to store the nagbar command");
169 return;
170 }
171 fprintf(script, "#!%s\nrm %s\n%s", _PATH_BSHELL, script_path, button->action);
172 /* Also closes fd */
173 fclose(script);
174
175 char *link_path;
176 char *exe_path = get_exe_path(argv0);
177 sasprintf(&link_path, "%s.nagbar_cmd", script_path);
178 if (symlink(exe_path, link_path) == -1) {
179 err(EXIT_FAILURE, "Failed to symlink %s to %s", link_path, exe_path);
180 }
181
182 char *terminal_cmd;
183 if (button->terminal) {
184 sasprintf(&terminal_cmd, "i3-sensible-terminal -e %s", link_path);
185 } else {
186 terminal_cmd = sstrdup(link_path);
187 }
188 printf("argv0 = %s\n", argv0);
189 printf("terminal_cmd = %s\n", terminal_cmd);
190
191 start_application(terminal_cmd);
192
193 free(link_path);
194 free(terminal_cmd);
195 free(script_path);
196 free(exe_path);
197
198 /* TODO: unset flag, re-render */
199 }
200
201 /*
202 * Draws a button and returns its width
203 *
204 */
205 static int button_draw(button_t *button, int position) {
206 int text_width = predict_text_width(button->label);
207 button->width = text_width + 2 * BTN_PADDING + 2 * BTN_BORDER;
208 button->x = position - button->width;
209
210 /* draw border */
211 draw_util_rectangle(&bar, color_border,
212 position - button->width,
213 MSG_PADDING - BTN_PADDING - BTN_BORDER,
214 button->width,
215 font.height + 2 * BTN_PADDING + 2 * BTN_BORDER);
216 /* draw background */
217 draw_util_rectangle(&bar, color_button_background,
218 position - button->width + BTN_BORDER,
219 MSG_PADDING - BTN_PADDING,
220 text_width + 2 * BTN_PADDING,
221 font.height + 2 * BTN_PADDING);
222 /* draw label */
223 draw_util_text(button->label, &bar, color_text, color_button_background,
224 position - button->width + BTN_BORDER + BTN_PADDING,
225 MSG_PADDING,
226 200);
227 return button->width;
228 }
229
230 /*
231 * Handles expose events (redraws of the window) and rendering in general. Will
232 * be called from the code with event == NULL or from X with event != NULL.
233 *
234 */
235 static int handle_expose(xcb_connection_t *conn, xcb_expose_event_t *event) {
236 /* draw background */
237 draw_util_clear_surface(&bar, color_background);
238 /* draw message */
239 draw_util_text(prompt, &bar, color_text, color_background,
240 MSG_PADDING, MSG_PADDING,
241 bar.width - 2 * MSG_PADDING);
242
243 int position = bar.width - (MSG_PADDING - BTN_BORDER - BTN_PADDING);
244
245 /* render close button */
246 position -= button_draw(&btn_close, position);
247 position -= CLOSE_BTN_GAP;
248
249 /* render custom buttons */
250 for (int i = 0; i < buttoncnt; i++) {
251 position -= BTN_GAP;
252 position -= button_draw(&buttons[i], position);
253 }
254
255 /* border line at the bottom */
256 draw_util_rectangle(&bar, color_border_bottom, 0, bar.height - BAR_BORDER, bar.width, BAR_BORDER);
257
258 xcb_flush(conn);
259 return 1;
260 }
261
262 /**
263 * Return the position and size the i3-nagbar window should use.
264 * This will be the primary output or a fallback if it cannot be determined.
265 */
266 static xcb_rectangle_t get_window_position(void) {
267 /* Default values if we cannot determine the primary output or its CRTC info. */
268 xcb_rectangle_t result = (xcb_rectangle_t){50, 50, 500, font.height + 2 * MSG_PADDING + BAR_BORDER};
269
270 xcb_randr_get_screen_resources_current_cookie_t rcookie = xcb_randr_get_screen_resources_current(conn, root);
271 xcb_randr_get_output_primary_cookie_t pcookie = xcb_randr_get_output_primary(conn, root);
272
273 xcb_randr_get_output_primary_reply_t *primary = NULL;
274 xcb_randr_get_screen_resources_current_reply_t *res = NULL;
275
276 if ((primary = xcb_randr_get_output_primary_reply(conn, pcookie, NULL)) == NULL) {
277 LOG("Could not determine the primary output.\n");
278 goto free_resources;
279 }
280
281 if ((res = xcb_randr_get_screen_resources_current_reply(conn, rcookie, NULL)) == NULL) {
282 LOG("Could not query screen resources.\n");
283 goto free_resources;
284 }
285
286 xcb_randr_get_output_info_reply_t *output =
287 xcb_randr_get_output_info_reply(conn,
288 xcb_randr_get_output_info(conn, primary->output, res->config_timestamp),
289 NULL);
290 if (output == NULL || output->crtc == XCB_NONE) {
291 LOG("Could not query primary screen.\n");
292 goto free_resources;
293 }
294
295 xcb_randr_get_crtc_info_reply_t *crtc =
296 xcb_randr_get_crtc_info_reply(conn,
297 xcb_randr_get_crtc_info(conn, output->crtc, res->config_timestamp),
298 NULL);
299 if (crtc == NULL) {
300 LOG("Could not get CRTC.\n");
301 goto free_resources;
302 }
303
304 LOG("Found primary output on position x = %i / y = %i / w = %i / h = %i.\n",
305 crtc->x, crtc->y, crtc->width, crtc->height);
306 if (crtc->width == 0 || crtc->height == 0) {
307 LOG("Primary output is not active, ignoring it.\n");
308 goto free_resources;
309 }
310
311 result.x = crtc->x;
312 result.y = crtc->y;
313 goto free_resources;
314
315 free_resources:
316 FREE(res);
317 FREE(primary);
318 return result;
319 }
320
321 int main(int argc, char *argv[]) {
322 /* The following lines are a terribly horrible kludge. Because terminal
323 * emulators have different ways of interpreting the -e command line
324 * argument (some need -e "less /etc/fstab", others need -e less
325 * /etc/fstab), we need to write commands to a script and then just run
326 * that script. However, since on some machines, $XDG_RUNTIME_DIR and
327 * $TMPDIR are mounted with noexec, we cannot directly execute the script
328 * either.
329 *
330 * Initially, we tried to pass the command via the environment variable
331 * _I3_NAGBAR_CMD. But turns out that some terminal emulators such as
332 * xfce4-terminal run all windows from a single master process and only
333 * pass on the command (not the environment) to that master process.
334 *
335 * Therefore, we symlink i3-nagbar (which MUST reside on an executable
336 * filesystem) with a special name and run that symlink. When i3-nagbar
337 * recognizes it’s started as a binary ending in .nagbar_cmd, it strips off
338 * the .nagbar_cmd suffix and runs /bin/sh on argv[0]. That way, we can run
339 * a shell script on a noexec filesystem.
340 *
341 * From a security point of view, i3-nagbar is just an alias to /bin/sh in
342 * certain circumstances. This should not open any new security issues, I
343 * hope. */
344 char *cmd = NULL;
345 const size_t argv0_len = strlen(argv[0]);
346 if (argv0_len > strlen(".nagbar_cmd") &&
347 strcmp(argv[0] + argv0_len - strlen(".nagbar_cmd"), ".nagbar_cmd") == 0) {
348 unlink(argv[0]);
349 cmd = sstrdup(argv[0]);
350 *(cmd + argv0_len - strlen(".nagbar_cmd")) = '\0';
351 execl(_PATH_BSHELL, _PATH_BSHELL, cmd, NULL);
352 err(EXIT_FAILURE, "execl(%s, %s, %s)", _PATH_BSHELL, _PATH_BSHELL, cmd);
353 }
354
355 argv0 = argv[0];
356
357 char *pattern = sstrdup("pango:monospace 8");
358 int o, option_index = 0;
359 enum { TYPE_ERROR = 0,
360 TYPE_WARNING = 1 } bar_type = TYPE_ERROR;
361
362 static struct option long_options[] = {
363 {"version", no_argument, 0, 'v'},
364 {"font", required_argument, 0, 'f'},
365 {"button", required_argument, 0, 'b'},
366 {"button-no-terminal", required_argument, 0, 'B'},
367 {"help", no_argument, 0, 'h'},
368 {"message", required_argument, 0, 'm'},
369 {"type", required_argument, 0, 't'},
370 {0, 0, 0, 0}};
371
372 char *options_string = "b:B:f:m:t:vh";
373
374 prompt = i3string_from_utf8("Please do not run this program.");
375
376 while ((o = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
377 switch (o) {
378 case 'v':
379 free(pattern);
380 printf("i3-nagbar " I3_VERSION "\n");
381 return 0;
382 case 'f':
383 free(pattern);
384 pattern = sstrdup(optarg);
385 break;
386 case 'm':
387 i3string_free(prompt);
388 prompt = i3string_from_utf8(optarg);
389 break;
390 case 't':
391 bar_type = (strcasecmp(optarg, "warning") == 0 ? TYPE_WARNING : TYPE_ERROR);
392 break;
393 case 'h':
394 free(pattern);
395 printf("i3-nagbar " I3_VERSION "\n");
396 printf("i3-nagbar [-m <message>] [-b <button> <action>] [-B <button> <action>] [-t warning|error] [-f <font>] [-v]\n");
397 return 0;
398 case 'b':
399 case 'B':
400 buttons = srealloc(buttons, sizeof(button_t) * (buttoncnt + 1));
401 buttons[buttoncnt].label = i3string_from_utf8(optarg);
402 buttons[buttoncnt].action = argv[optind];
403 buttons[buttoncnt].terminal = (o == 'b');
404 printf("button with label *%s* and action *%s*\n",
405 i3string_as_utf8(buttons[buttoncnt].label),
406 buttons[buttoncnt].action);
407 buttoncnt++;
408 printf("now %d buttons\n", buttoncnt);
409 if (optind < argc)
410 optind++;
411 break;
412 }
413 }
414
415 btn_close.label = i3string_from_utf8("X");
416
417 int screens;
418 if ((conn = xcb_connect(NULL, &screens)) == NULL ||
419 xcb_connection_has_error(conn))
420 die("Cannot open display");
421
422 /* Place requests for the atoms we need as soon as possible */
423 #define xmacro(atom) \
424 xcb_intern_atom_cookie_t atom##_cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom);
425 #include "atoms.xmacro"
426 #undef xmacro
427
428 /* Init startup notification. */
429 SnDisplay *sndisplay = sn_xcb_display_new(conn, NULL, NULL);
430 SnLauncheeContext *sncontext = sn_launchee_context_new_from_environment(sndisplay, screens);
431 sn_display_unref(sndisplay);
432
433 root_screen = xcb_aux_get_screen(conn, screens);
434 root = root_screen->root;
435
436 if (bar_type == TYPE_ERROR) {
437 /* Red theme for error messages */
438 color_button_background = draw_util_hex_to_color("#680a0a");
439 color_background = draw_util_hex_to_color("#900000");
440 color_text = draw_util_hex_to_color("#ffffff");
441 color_border = draw_util_hex_to_color("#d92424");
442 color_border_bottom = draw_util_hex_to_color("#470909");
443 } else {
444 /* Yellowish theme for warnings */
445 color_button_background = draw_util_hex_to_color("#ffc100");
446 color_background = draw_util_hex_to_color("#ffa8000");
447 color_text = draw_util_hex_to_color("#000000");
448 color_border = draw_util_hex_to_color("#ab7100");
449 color_border_bottom = draw_util_hex_to_color("#ab7100");
450 }
451
452 init_dpi();
453 font = load_font(pattern, true);
454 set_font(&font);
455
456 #if defined(__OpenBSD__)
457 if (pledge("stdio rpath wpath cpath getpw proc exec", NULL) == -1)
458 err(EXIT_FAILURE, "pledge");
459 #endif
460
461 xcb_rectangle_t win_pos = get_window_position();
462
463 xcb_cursor_context_t *cursor_ctx;
464 if (xcb_cursor_context_new(conn, root_screen, &cursor_ctx) < 0) {
465 errx(EXIT_FAILURE, "Cannot allocate xcursor context");
466 }
467 xcb_cursor_t cursor = xcb_cursor_load_cursor(cursor_ctx, "left_ptr");
468 xcb_cursor_context_free(cursor_ctx);
469
470 /* Open an input window */
471 win = xcb_generate_id(conn);
472
473 xcb_create_window(
474 conn,
475 XCB_COPY_FROM_PARENT,
476 win, /* the window id */
477 root, /* parent == root */
478 win_pos.x, win_pos.y, win_pos.width, win_pos.height, /* dimensions */
479 0, /* x11 border = 0, we draw our own */
480 XCB_WINDOW_CLASS_INPUT_OUTPUT,
481 XCB_WINDOW_CLASS_COPY_FROM_PARENT, /* copy visual from parent */
482 XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_CURSOR,
483 (uint32_t[]){
484 0, /* back pixel: black */
485 XCB_EVENT_MASK_EXPOSURE |
486 XCB_EVENT_MASK_STRUCTURE_NOTIFY |
487 XCB_EVENT_MASK_BUTTON_PRESS |
488 XCB_EVENT_MASK_BUTTON_RELEASE,
489 cursor});
490 if (sncontext) {
491 sn_launchee_context_setup_window(sncontext, win);
492 }
493
494 /* Map the window (make it visible) */
495 xcb_map_window(conn, win);
496
497 /* Setup NetWM atoms */
498 #define xmacro(name) \
499 do { \
500 xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, name##_cookie, NULL); \
501 if (!reply) \
502 die("Could not get atom " #name); \
503 \
504 A_##name = reply->atom; \
505 free(reply); \
506 } while (0);
507 #include "atoms.xmacro"
508 #undef xmacro
509
510 /* Set dock mode */
511 xcb_change_property(conn,
512 XCB_PROP_MODE_REPLACE,
513 win,
514 A__NET_WM_WINDOW_TYPE,
515 A_ATOM,
516 32,
517 1,
518 (unsigned char *)&A__NET_WM_WINDOW_TYPE_DOCK);
519
520 /* Reserve some space at the top of the screen */
521 struct {
522 uint32_t left;
523 uint32_t right;
524 uint32_t top;
525 uint32_t bottom;
526 uint32_t left_start_y;
527 uint32_t left_end_y;
528 uint32_t right_start_y;
529 uint32_t right_end_y;
530 uint32_t top_start_x;
531 uint32_t top_end_x;
532 uint32_t bottom_start_x;
533 uint32_t bottom_end_x;
534 } __attribute__((__packed__)) strut_partial;
535 memset(&strut_partial, 0, sizeof(strut_partial));
536
537 strut_partial.top = font.height + logical_px(6);
538 strut_partial.top_start_x = 0;
539 strut_partial.top_end_x = 800;
540
541 xcb_change_property(conn,
542 XCB_PROP_MODE_REPLACE,
543 win,
544 A__NET_WM_STRUT_PARTIAL,
545 A_CARDINAL,
546 32,
547 12,
548 &strut_partial);
549
550 /* Initialize the drawable bar */
551 draw_util_surface_init(conn, &bar, win, get_visualtype(root_screen), win_pos.width, win_pos.height);
552
553 /* Startup complete. */
554 if (sncontext) {
555 sn_launchee_context_complete(sncontext);
556 sn_launchee_context_unref(sncontext);
557 }
558
559 /* Grab the keyboard to get all input */
560 xcb_flush(conn);
561
562 xcb_generic_event_t *event;
563 while ((event = xcb_wait_for_event(conn)) != NULL) {
564 if (event->response_type == 0) {
565 fprintf(stderr, "X11 Error received! sequence %x\n", event->sequence);
566 continue;
567 }
568
569 /* Strip off the highest bit (set if the event is generated) */
570 int type = (event->response_type & 0x7F);
571
572 switch (type) {
573 case XCB_EXPOSE:
574 if (((xcb_expose_event_t *)event)->count == 0) {
575 handle_expose(conn, (xcb_expose_event_t *)event);
576 }
577
578 break;
579
580 case XCB_BUTTON_PRESS:
581 handle_button_press(conn, (xcb_button_press_event_t *)event);
582 break;
583
584 case XCB_BUTTON_RELEASE:
585 handle_button_release(conn, (xcb_button_release_event_t *)event);
586 break;
587
588 case XCB_CONFIGURE_NOTIFY: {
589 xcb_configure_notify_event_t *configure_notify = (xcb_configure_notify_event_t *)event;
590 if (configure_notify->width > 0 && configure_notify->height > 0) {
591 draw_util_surface_set_size(&bar, configure_notify->width, configure_notify->height);
592 }
593 break;
594 }
595 }
596
597 free(event);
598 }
599
600 FREE(pattern);
601 draw_util_surface_free(conn, &bar);
602
603 return 0;
604 }
0 #!/usr/bin/env perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # © 2013 Michael Stapelberg
4 #
5 # Requires perl ≥ v5.10, AnyEvent::I3 and JSON::XS
6
7 use strict;
8 use warnings qw(FATAL utf8);
9 use Data::Dumper;
10 use IPC::Open2;
11 use POSIX qw(locale_h);
12 use File::Find;
13 use File::Basename qw(basename);
14 use File::Temp qw(tempfile);
15 use List::Util qw(first);
16 use Getopt::Long;
17 use Pod::Usage;
18 use AnyEvent::I3;
19 use JSON::XS;
20 use List::Util qw(first);
21 use Encode qw(decode);
22 use v5.10;
23 use utf8;
24 use open ':encoding(UTF-8)';
25
26 binmode STDOUT, ':utf8';
27 binmode STDERR, ':utf8';
28
29 my $workspace;
30 my $output;
31 my $result = GetOptions(
32 'workspace=s' => \$workspace,
33 'output=s' => \$output,
34 'version' => sub {
35 say "i3-save-tree 0.1 © 2013 Michael Stapelberg";
36 exit 0;
37 },
38 'help' => sub {
39 pod2usage(-exitval => 0);
40 });
41
42 die "Could not parse command line options" unless $result;
43
44 if (defined($workspace) && defined($output)) {
45 die "Only one of --workspace or --output can be specified";
46 }
47
48 $workspace = decode('utf-8', $workspace);
49 $output = decode('utf-8', $output);
50
51 my $i3 = i3();
52 if (!$i3->connect->recv) {
53 die "Could not connect to i3";
54 }
55
56 sub get_current_workspace {
57 my $current = first { $_->{focused} } @{$i3->get_workspaces->recv};
58 return $current->{name};
59 }
60
61 if (!defined($workspace) && !defined($output)) {
62 $workspace = get_current_workspace();
63 }
64
65 sub filter_containers {
66 my ($tree, $pred) = @_;
67
68 $_ = $tree;
69 return $tree if $pred->();
70
71 for my $child (@{$tree->{nodes}}, @{$tree->{floating_nodes}}) {
72 my $result = filter_containers($child, $pred);
73 return $result if defined($result);
74 }
75
76 return undef;
77 }
78
79 sub leaf_node {
80 my ($tree) = @_;
81
82 return $tree->{type} eq 'con' &&
83 @{$tree->{nodes}} == 0 &&
84 @{$tree->{floating_nodes}} == 0;
85 }
86
87 my %allowed_keys = map { ($_, 1) } qw(
88 type
89 fullscreen_mode
90 layout
91 border
92 current_border_width
93 floating
94 percent
95 nodes
96 floating_nodes
97 name
98 geometry
99 window_properties
100 marks
101 rect
102 );
103
104 sub strip_containers {
105 my ($tree) = @_;
106
107 # layout is not relevant for a leaf container
108 delete $tree->{layout} if leaf_node($tree);
109
110 # fullscreen_mode conveys no state at all, it can either be 0 or 1 and the
111 # default is _always_ 0, so skip noop entries.
112 delete $tree->{fullscreen_mode} if $tree->{fullscreen_mode} == 0;
113
114 # names for non-leafs are auto-generated and useful only for i3 debugging
115 delete $tree->{name} unless leaf_node($tree);
116
117 delete $tree->{geometry} if zero_rect($tree->{geometry});
118
119 # Retain the rect for floating containers to keep their positions.
120 delete $tree->{rect} unless $tree->{type} eq 'floating_con';
121
122 delete $tree->{current_border_width} if $tree->{current_border_width} == -1;
123
124 for my $key (keys %$tree) {
125 delete $tree->{$key} unless exists($allowed_keys{$key});
126 }
127
128 for my $key (qw(nodes floating_nodes)) {
129 $tree->{$key} = [ map { strip_containers($_) } @{$tree->{$key}} ];
130 }
131
132 return $tree;
133 }
134
135 my $json_xs = JSON::XS->new->pretty(1)->allow_nonref->space_before(0)->canonical(1);
136
137 sub zero_rect {
138 my ($rect) = @_;
139 return $rect->{x} == 0 &&
140 $rect->{y} == 0 &&
141 $rect->{width} == 0 &&
142 $rect->{height} == 0;
143 }
144
145 # Dumps the containers in JSON, but with comments to explain the user what she
146 # needs to fix.
147 sub dump_containers {
148 my ($tree, $ws, $last) = @_;
149
150 $ws //= "";
151
152 say $ws . '{';
153
154 $ws .= (' ' x 4);
155
156 if (!leaf_node($tree)) {
157 my $desc = $tree->{layout} . ' split container';
158 if ($tree->{type} ne 'con') {
159 $desc = $tree->{type};
160 }
161 say "$ws// $desc with " . @{$tree->{nodes}} . " children";
162 }
163
164 # Turn “window_properties” into “swallows” expressions, but only for leaf
165 # nodes. It only makes sense for leaf nodes to swallow anything.
166 if (leaf_node($tree)) {
167 my $swallows = {};
168 for my $property (keys %{$tree->{window_properties}}) {
169 $swallows->{$property} = '^' . quotemeta($tree->{window_properties}->{$property}) . '$'
170 if $property ne 'transient_for';
171 }
172 $tree->{swallows} = [ $swallows ];
173 }
174 delete $tree->{window_properties};
175
176 my @keys = sort keys %$tree;
177 for (0 .. (@keys-1)) {
178 my $key = $keys[$_];
179 # Those are handled recursively, not printed.
180 next if $key eq 'nodes' || $key eq 'floating_nodes';
181
182 # JSON::XS’s encode appends a newline
183 chomp(my $val = $json_xs->encode($tree->{$key}));
184
185 # Fix indentation. Keep in mind we are producing output to be
186 # read/modified by a human.
187 $val =~ s/^/$ws/mg;
188 $val =~ s/^\s+//;
189
190 # Comment out all swallows criteria, they are just suggestions.
191 if ($key eq 'swallows') {
192 $val =~ s,^(\s*)\s{3}",\1// ",gm;
193 }
194
195 # Append a comma unless this is the last value.
196 # Ugly, but necessary so that we can print all values before recursing.
197 my $comma = ($_ == (@keys-1) &&
198 @{$tree->{nodes}} == 0 &&
199 @{$tree->{floating_nodes}} == 0 ? '' : ',');
200 say qq#$ws"$key": $val$comma#;
201 }
202
203 for my $key (qw(nodes floating_nodes)) {
204 my $num = scalar @{$tree->{$key}};
205 next if !$num;
206
207 say qq#$ws"$key": [#;
208 for (0 .. ($num-1)) {
209 dump_containers(
210 $tree->{$key}->[$_],
211 $ws . (' ' x 4),
212 ($_ == ($num-1)));
213 }
214 say qq#$ws]#;
215 }
216
217 $ws =~ s/\s{4}$//;
218
219 say $ws . ($last ? '}' : '},');
220 }
221
222 my $tree = $i3->get_tree->recv;
223
224 my $dump;
225 if (defined($workspace)) {
226 $dump = filter_containers($tree, sub {
227 $_->{type} eq 'workspace' && ($_->{name} eq $workspace || ($workspace =~ /^\d+$/ && $_->{num} eq $workspace))
228 });
229 } else {
230 $dump = filter_containers($tree, sub {
231 $_->{type} eq 'output' && $_->{name} eq $output
232 });
233 # Get the output’s content container (living beneath dockarea containers).
234 $dump = first { $_->{type} eq 'con' } @{$dump->{nodes}};
235 }
236
237 $dump = strip_containers($dump);
238
239 say "// vim:ts=4:sw=4:et";
240 for my $key (qw(nodes floating_nodes)) {
241 for (0 .. (@{$dump->{$key}} - 1)) {
242 dump_containers($dump->{$key}->[$_], undef, 1);
243 # Newlines separate containers so that one can use { and } in vim to
244 # jump out of the current container.
245 say '';
246 }
247 }
248
249 =encoding utf-8
250
251 =head1 NAME
252
253 i3-save-tree - save (parts of) the layout tree for restoring
254
255 =head1 SYNOPSIS
256
257 i3-save-tree [--workspace=name|number] [--output=name]
258
259 =head1 DESCRIPTION
260
261 Dumps a workspace (or an entire output) to stdout. The data is supposed to be
262 edited a bit by a human, then later fed to i3 via the append_layout command.
263
264 The append_layout command will create placeholder windows, arranged in the
265 layout the input file specifies. Each container should have a swallows
266 specification. When a window is mapped (made visible on the screen) that
267 matches the specification, i3 will put it into that place and kill the
268 placeholder.
269
270 If neither argument is specified, the currently focused workspace will be used.
271
272 =head1 OPTIONS
273
274 =over
275
276 =item B<--workspace=name|number>
277
278 Specifies the workspace that should be dumped, e.g. 1. This can either be a
279 name or the number of a workspace.
280
281 =item B<--output=name>
282
283 Specifies the output that should be dumped, e.g. LVDS-1.
284
285 =back
286
287 =head1 VERSION
288
289 Version 0.1
290
291 =head1 AUTHOR
292
293 Michael Stapelberg, C<< <michael at i3wm.org> >>
294
295 =head1 LICENSE AND COPYRIGHT
296
297 Copyright 2013 Michael Stapelberg.
298
299 This program is free software; you can redistribute it and/or modify it
300 under the terms of the BSD license.
301
302 =cut
0 #!/bin/sh
1 #
2 # This code is released in public domain by Han Boetes <[email protected]>
3 #
4 # This script tries to exec an editor by trying some known editors if $EDITOR is
5 # not set.
6 #
7 # Distributions/packagers can enhance this script with a distribution-specific
8 # mechanism to find the preferred editor
9
10 # Hopefully one of these is installed (no flamewars about preference please!):
11 for editor in "$VISUAL" "$EDITOR" nano nvim vim vi emacs pico qe mg jed gedit mcedit gvim; do
12 if command -v "$editor" > /dev/null 2>&1; then
13 exec "$editor" "$@"
14 fi
15 done
0 #!/bin/sh
1 #
2 # This code is released in public domain by Han Boetes <[email protected]>
3
4 # This script tries to exec a pager by trying some known pagers if $PAGER is
5 # not set.
6 #
7 # Distributions/packagers can enhance this script with a
8 # distribution-specific mechanism to find the preferred pager.
9
10 # Hopefully one of these is installed (no flamewars about preference please!):
11 # We don't use 'more' because it will exit if the file is too short.
12 # Worst case scenario we'll open the file in your editor.
13 for pager in "$PAGER" less most w3m pg i3-sensible-editor; do
14 if command -v "$pager" > /dev/null 2>&1; then
15 exec "$pager" "$@"
16 fi
17 done
0 #!/bin/sh
1 #
2 # This code is released in public domain by Han Boetes <[email protected]>
3 #
4 # This script tries to exec a terminal emulator by trying some known terminal
5 # emulators.
6 #
7 # We welcome patches that add distribution-specific mechanisms to find the
8 # preferred terminal emulator. On Debian, there is the x-terminal-emulator
9 # symlink for example.
10 for terminal in "$TERMINAL" x-terminal-emulator urxvt rxvt termit terminator Eterm aterm uxterm xterm gnome-terminal roxterm xfce4-terminal termite lxterminal mate-terminal terminology st qterminal lilyterm tilix terminix konsole kitty guake tilda alacritty hyper; do
11 if command -v "$terminal" > /dev/null 2>&1; then
12 exec "$terminal" "$@"
13 fi
14 done
15
16 i3-nagbar -m 'i3-sensible-terminal could not find a terminal emulator. Please install one.'
0 i3bar
1 *.o
2 core
3 doc/i3bar.1
0 Copyright © 2010 Axel Wagner
1 All rights reserved.
2
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions are met:
5
6 * Redistributions of source code must retain the above copyright
7 notice, this list of conditions and the following disclaimer.
8
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12
13 * Neither the name of Axel Wagner nor the
14 names of contributors may be used to endorse or promote products
15 derived from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY Axel Wagner ''AS IS'' AND ANY
18 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL Axel Wagner BE LIABLE FOR ANY
21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * child.c: Getting input for the statusline
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include <stdbool.h>
14
15 #define STDIN_CHUNK_SIZE 1024
16
17 typedef struct {
18 pid_t pid;
19
20 /**
21 * The version number is an uint32_t to avoid machines with different sizes of
22 * 'int' to allow different values here. It’s highly unlikely we ever exceed
23 * even an int8_t, but still…
24 */
25 uint32_t version;
26
27 bool stopped;
28 /**
29 * The signal requested by the client to inform it of the hidden state of i3bar
30 */
31 int stop_signal;
32 /**
33 * The signal requested by the client to inform it of the unhidden state of i3bar
34 */
35 int cont_signal;
36
37 /**
38 * Enable click events
39 */
40 bool click_events;
41 bool click_events_init;
42 } i3bar_child;
43
44 /*
45 * Start a child process with the specified command and reroute stdin.
46 * We actually start a $SHELL to execute the command so we don't have to care
47 * about arguments and such
48 *
49 */
50 void start_child(char *command);
51
52 /*
53 * kill()s the child process (if any). Called when exit()ing.
54 *
55 */
56 void kill_child_at_exit(void);
57
58 /*
59 * kill()s the child process (if any) and closes and
60 * free()s the stdin- and SIGCHLD-watchers
61 *
62 */
63 void kill_child(void);
64
65 /*
66 * Sends a SIGSTOP to the child process (if existent)
67 *
68 */
69 void stop_child(void);
70
71 /*
72 * Sends a SIGCONT to the child process (if existent)
73 *
74 */
75 void cont_child(void);
76
77 /*
78 * Whether or not the child want click events
79 *
80 */
81 bool child_want_click_events(void);
82
83 /*
84 * Generates a click event, if enabled.
85 *
86 */
87 void send_block_clicked(int button, const char *name, const char *instance, int x, int y, int x_rel, int y_rel, int width, int height, int mods);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 */
7 #pragma once
8
9 #include <config.h>
10
11 #include <stdbool.h>
12 #include <xcb/xcb.h>
13 #include <xcb/xproto.h>
14 #include "libi3.h"
15 #include "queue.h"
16
17 typedef struct rect_t rect;
18
19 extern struct ev_loop *main_loop;
20
21 struct rect_t {
22 int x;
23 int y;
24 int w;
25 int h;
26 };
27
28 typedef enum {
29 /* First value to make it the default. */
30 ALIGN_LEFT,
31 ALIGN_CENTER,
32 ALIGN_RIGHT
33 } blockalign_t;
34
35 /* This data structure describes the way a status block should be rendered. These
36 * variables are updated each time the statusline is re-rendered. */
37 struct status_block_render_desc {
38 uint32_t width;
39 uint32_t x_offset;
40 uint32_t x_append;
41 };
42
43 /* This data structure represents one JSON dictionary, multiple of these make
44 * up one status line. */
45 struct status_block {
46 i3String *full_text;
47 i3String *short_text;
48
49 char *color;
50 char *background;
51 char *border;
52
53 /* min_width can be specified either as a numeric value (in pixels) or as a
54 * string. For strings, we set min_width to the measured text width of
55 * min_width_str. */
56 uint32_t min_width;
57 char *min_width_str;
58
59 blockalign_t align;
60
61 bool urgent;
62 bool no_separator;
63 uint32_t border_top;
64 uint32_t border_right;
65 uint32_t border_bottom;
66 uint32_t border_left;
67 bool pango_markup;
68
69 /* The amount of pixels necessary to render a separater after the block. */
70 uint32_t sep_block_width;
71
72 /* Continuously-updated information on how to render this status block. */
73 struct status_block_render_desc full_render;
74 struct status_block_render_desc short_render;
75
76 /* Optional */
77 char *name;
78 char *instance;
79
80 TAILQ_ENTRY(status_block)
81 blocks;
82 };
83
84 extern TAILQ_HEAD(statusline_head, status_block)
85 statusline_head;
86
87 #include "child.h"
88 #include "ipc.h"
89 #include "outputs.h"
90 #include "util.h"
91 #include "workspaces.h"
92 #include "mode.h"
93 #include "trayclients.h"
94 #include "xcb.h"
95 #include "configuration.h"
96 #include "libi3.h"
97 #include "parse_json_header.h"
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * config.c: Parses the configuration (received from i3).
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include "common.h"
14
15 typedef enum {
16 POS_NONE = 0,
17 POS_TOP,
18 POS_BOT
19 } position_t;
20
21 /* Bar display mode (hide unless modifier is pressed or show in dock mode or always hide in invisible mode) */
22 typedef enum { M_DOCK = 0,
23 M_HIDE = 1,
24 M_INVISIBLE = 2 } bar_display_mode_t;
25
26 typedef struct binding_t {
27 int input_code;
28 char *command;
29 bool release;
30
31 TAILQ_ENTRY(binding_t)
32 bindings;
33 } binding_t;
34
35 typedef struct tray_output_t {
36 char *output;
37
38 TAILQ_ENTRY(tray_output_t)
39 tray_outputs;
40 } tray_output_t;
41
42 typedef struct config_t {
43 uint32_t modifier;
44
45 TAILQ_HEAD(bindings_head, binding_t)
46 bindings;
47
48 position_t position;
49 bool verbose;
50 uint32_t bar_height;
51 bool transparency;
52 struct xcb_color_strings_t colors;
53 bool disable_binding_mode_indicator;
54 bool disable_ws;
55 int ws_min_width;
56 bool strip_ws_numbers;
57 bool strip_ws_name;
58 char *bar_id;
59 char *command;
60 char *fontname;
61 i3String *separator_symbol;
62
63 TAILQ_HEAD(tray_outputs_head, tray_output_t)
64 tray_outputs;
65
66 int tray_padding;
67 int num_outputs;
68 char **outputs;
69
70 bar_display_mode_t hide_on_modifier;
71
72 /* The current hidden_state of the bar, which indicates whether it is hidden or shown */
73 enum { S_HIDE = 0,
74 S_SHOW = 1 } hidden_state;
75 } config_t;
76
77 extern config_t config;
78
79 /**
80 * Start parsing the received bar configuration JSON string
81 *
82 */
83 void parse_config_json(char *json);
84
85 /**
86 * free()s the color strings as soon as they are not needed anymore.
87 *
88 */
89 void free_colors(struct xcb_color_strings_t *colors);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * ipc.c: Communicating with i3
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include <stdint.h>
14
15 /*
16 * Initiate a connection to i3.
17 * socket_path must be a valid path to the ipc_socket of i3
18 *
19 */
20 int init_connection(const char *socket_path);
21
22 /*
23 * Destroy the connection to i3.
24 *
25 */
26 void destroy_connection(void);
27
28 /*
29 * Sends a message to i3.
30 * type must be a valid I3_IPC_MESSAGE_TYPE (see i3/ipc.h for further information)
31 *
32 */
33 int i3_send_msg(uint32_t type, const char *payload);
34
35 /*
36 * Subscribe to all the i3-events, we need
37 *
38 */
39 void subscribe_events(void);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * mode.c: Handle "mode" event and show current binding mode in the bar
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include <xcb/xproto.h>
14
15 #include "common.h"
16
17 /* Name of current binding mode and its render width */
18 struct mode {
19 i3String *name;
20 int name_width;
21 };
22
23 typedef struct mode mode;
24
25 /*
26 * Start parsing the received JSON string
27 *
28 */
29 void parse_mode_json(char *json);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * outputs.c: Maintaining the outputs list
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include <xcb/xcb.h>
14 #include <cairo/cairo-xcb.h>
15
16 #include "common.h"
17
18 typedef struct i3_output i3_output;
19
20 SLIST_HEAD(outputs_head, i3_output);
21 extern struct outputs_head* outputs;
22
23 /*
24 * Start parsing the received JSON string
25 *
26 */
27 void parse_outputs_json(char* json);
28
29 /*
30 * Initiate the outputs list
31 *
32 */
33 void init_outputs(void);
34
35 /*
36 * free() all outputs data structures.
37 *
38 */
39 void free_outputs(void);
40
41 /*
42 * Returns the output with the given name
43 *
44 */
45 i3_output* get_output_by_name(char* name);
46
47 /*
48 * Returns true if the output has the currently focused workspace
49 *
50 */
51 bool output_has_focus(i3_output* output);
52
53 struct i3_output {
54 char* name; /* Name of the output */
55 bool active; /* If the output is active */
56 bool primary; /* If it is the primary output */
57 bool visible; /* If the bar is visible on this output */
58 int ws; /* The number of the currently visible ws */
59 rect rect; /* The rect (relative to the root window) */
60
61 /* Off-screen buffer for preliminary rendering of the bar. */
62 surface_t buffer;
63 /* Off-screen buffer for pre-rendering the statusline, separated to make clipping easier. */
64 surface_t statusline_buffer;
65 /* How much of statusline_buffer's horizontal space was used on last statusline render. */
66 int statusline_width;
67 /* Whether statusline block short texts where used on last statusline render. */
68 bool statusline_short_text;
69 /* The actual window on which we draw. */
70 surface_t bar;
71
72 struct ws_head* workspaces; /* The workspaces on this output */
73 struct tc_head* trayclients; /* The tray clients on this output */
74
75 SLIST_ENTRY(i3_output)
76 slist; /* Pointer for the SLIST-Macro */
77 };
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * parse_json_header.c: Parse the JSON protocol header to determine
7 * protocol version and features.
8 *
9 */
10 #pragma once
11
12 #include <config.h>
13
14 #include <stdint.h>
15
16 /**
17 * Parse the JSON protocol header to determine protocol version and features.
18 * In case the buffer does not contain a valid header (invalid JSON, or no
19 * version field found), the 'correct' field of the returned header is set to
20 * false. The amount of bytes consumed by parsing the header is returned in
21 * *consumed (if non-NULL).
22 *
23 */
24 void parse_json_header(i3bar_child *child, const unsigned char *buffer, int length, unsigned int *consumed);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 */
7 #pragma once
8
9 #include "common.h"
10
11 typedef struct trayclient trayclient;
12
13 TAILQ_HEAD(tc_head, trayclient);
14
15 struct trayclient {
16 xcb_window_t win; /* The window ID of the tray client */
17 bool mapped; /* Whether this window is mapped */
18 int xe_version; /* The XEMBED version supported by the client */
19
20 char *class_class;
21 char *class_instance;
22
23 TAILQ_ENTRY(trayclient)
24 tailq; /* Pointer for the TAILQ-Macro */
25 };
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #pragma once
8
9 #include <config.h>
10
11 #include "queue.h"
12
13 /* Get the maximum/minimum of x and y */
14 #undef MAX
15 #define MAX(x, y) ((x) > (y) ? (x) : (y))
16 #undef MIN
17 #define MIN(x, y) ((x) < (y) ? (x) : (y))
18
19 #define STARTS_WITH(string, len, needle) (((len) >= strlen((needle))) && strncasecmp((string), (needle), strlen((needle))) == 0)
20
21 /* Securely free p */
22 #define FREE(p) \
23 do { \
24 free(p); \
25 p = NULL; \
26 } while (0)
27
28 /* Securely free single-linked list */
29 #define FREE_SLIST(l, type) \
30 do { \
31 type *walk = SLIST_FIRST(l); \
32 while (!SLIST_EMPTY(l)) { \
33 SLIST_REMOVE_HEAD(l, slist); \
34 FREE(walk); \
35 walk = SLIST_FIRST(l); \
36 } \
37 } while (0)
38
39 /* Securely free tail queue */
40 #define FREE_TAILQ(l, type) \
41 do { \
42 type *walk = TAILQ_FIRST(l); \
43 while (!TAILQ_EMPTY(l)) { \
44 TAILQ_REMOVE(l, TAILQ_FIRST(l), tailq); \
45 FREE(walk); \
46 walk = TAILQ_FIRST(l); \
47 } \
48 } while (0)
49
50 #if defined(DLOG)
51 #undef DLOG
52 #endif
53 /* Use cool logging macros */
54 #define DLOG(fmt, ...) \
55 do { \
56 if (config.verbose) { \
57 printf("[%s:%d] " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \
58 } \
59 } while (0)
60
61 /* We will include libi3.h which define its own version of ELOG.
62 * We want *our* version, so we undef the libi3 one. */
63 #if defined(ELOG)
64 #undef ELOG
65 #endif
66 #define ELOG(fmt, ...) \
67 do { \
68 fprintf(stderr, "[%s:%d] ERROR: " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \
69 } while (0)
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * workspaces.c: Maintaining the workspace lists
7 *
8 */
9 #pragma once
10
11 #include "common.h"
12
13 #include <xcb/xproto.h>
14
15 typedef struct i3_ws i3_ws;
16
17 TAILQ_HEAD(ws_head, i3_ws);
18
19 /*
20 * Start parsing the received JSON string
21 *
22 */
23 void parse_workspaces_json(char *json);
24
25 /*
26 * free() all workspace data structures
27 *
28 */
29 void free_workspaces(void);
30
31 struct i3_ws {
32 uintptr_t id; /* Workspace ID - C pointer to a workspace container */
33 int num; /* The internal number of the ws */
34 char *canonical_name; /* The true name of the ws according to the ipc */
35 i3String *name; /* The name of the ws that is displayed on the bar */
36 int name_width; /* The rendered width of the name */
37 bool visible; /* If the ws is currently visible on an output */
38 bool focused; /* If the ws is currently focused */
39 bool urgent; /* If the urgent hint of the ws is set */
40 rect rect; /* The rect of the ws (not used (yet)) */
41 struct i3_output *output; /* The current output of the ws */
42
43 TAILQ_ENTRY(i3_ws)
44 tailq; /* Pointer for the TAILQ-Macro */
45 };
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * xcb.c: Communicating with X
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include <stdint.h>
14 //#include "outputs.h"
15
16 #define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0
17 #define _NET_SYSTEM_TRAY_ORIENTATION_VERT 1
18 #define SYSTEM_TRAY_REQUEST_DOCK 0
19 #define SYSTEM_TRAY_BEGIN_MESSAGE 1
20 #define SYSTEM_TRAY_CANCEL_MESSAGE 2
21 #define XEMBED_MAPPED (1 << 0)
22 #define XEMBED_EMBEDDED_NOTIFY 0
23
24 /* We define xcb_request_failed as a macro to include the relevant line number */
25 #define xcb_request_failed(cookie, err_msg) _xcb_request_failed(cookie, err_msg, __LINE__)
26 int _xcb_request_failed(xcb_void_cookie_t cookie, char *err_msg, int line);
27
28 struct xcb_color_strings_t {
29 char *bar_fg;
30 char *bar_bg;
31 char *sep_fg;
32 char *focus_bar_fg;
33 char *focus_bar_bg;
34 char *focus_sep_fg;
35 char *active_ws_fg;
36 char *active_ws_bg;
37 char *active_ws_border;
38 char *inactive_ws_fg;
39 char *inactive_ws_bg;
40 char *inactive_ws_border;
41 char *focus_ws_bg;
42 char *focus_ws_fg;
43 char *focus_ws_border;
44 char *urgent_ws_bg;
45 char *urgent_ws_fg;
46 char *urgent_ws_border;
47 char *binding_mode_bg;
48 char *binding_mode_fg;
49 char *binding_mode_border;
50 };
51
52 typedef struct xcb_colors_t xcb_colors_t;
53
54 /* Cached width of the custom separator if one was set */
55 extern int separator_symbol_width;
56
57 /*
58 * Early initialization of the connection to X11: Everything which does not
59 * depend on 'config'.
60 *
61 */
62 char *init_xcb_early(void);
63
64 /**
65 * Initialization which depends on 'config' being usable. Called after the
66 * configuration has arrived.
67 *
68 */
69 void init_xcb_late(char *fontname);
70
71 /*
72 * Initialize the colors
73 *
74 */
75 void init_colors(const struct xcb_color_strings_t *colors);
76
77 /*
78 * Cleanup the xcb stuff.
79 * Called once, before the program terminates.
80 *
81 */
82 void clean_xcb(void);
83
84 /*
85 * Get the earlier requested atoms and save them in the prepared data structure
86 *
87 */
88 void get_atoms(void);
89
90 /*
91 * Reparents all tray clients of the specified output to the root window. This
92 * is either used when shutting down, when an output appears (xrandr --output
93 * VGA1 --off) or when the primary output changes.
94 *
95 * Applications using the tray will start the protocol from the beginning again
96 * afterwards.
97 *
98 */
99 void kick_tray_clients(i3_output *output);
100
101 /*
102 * We need to set the _NET_SYSTEM_TRAY_COLORS atom on the tray selection window
103 * to make GTK+ 3 applets with symbolic icons visible. If the colors are unset,
104 * they assume a light background.
105 * See also https://bugzilla.gnome.org/show_bug.cgi?id=679591
106 *
107 */
108 void init_tray_colors(void);
109
110 /*
111 * Destroy the bar of the specified output
112 *
113 */
114 void destroy_window(i3_output *output);
115
116 /*
117 * Reallocate the statusline buffer
118 *
119 */
120 void realloc_sl_buffer(void);
121
122 /*
123 * Reconfigure all bars and create new for newly activated outputs
124 *
125 */
126 void reconfig_windows(bool redraw_bars);
127
128 /*
129 * Render the bars, with buttons and statusline
130 *
131 */
132 void draw_bars(bool force_unhide);
133
134 /*
135 * Redraw the bars, i.e. simply copy the buffer to the barwindow
136 *
137 */
138 void redraw_bars(void);
139
140 /*
141 * Set the current binding mode
142 *
143 */
144 void set_current_mode(struct mode *mode);
0 ATOM_DO(_NET_WM_WINDOW_TYPE)
1 ATOM_DO(_NET_WM_WINDOW_TYPE_DOCK)
2 ATOM_DO(_NET_WM_STRUT_PARTIAL)
3 ATOM_DO(I3_SOCKET_PATH)
4 ATOM_DO(MANAGER)
5 ATOM_DO(_NET_SYSTEM_TRAY_ORIENTATION)
6 ATOM_DO(_NET_SYSTEM_TRAY_VISUAL)
7 ATOM_DO(_NET_SYSTEM_TRAY_OPCODE)
8 ATOM_DO(_NET_SYSTEM_TRAY_COLORS)
9 ATOM_DO(_XEMBED_INFO)
10 ATOM_DO(_XEMBED)
11 ATOM_DO(I3_SYNC)
12 #undef ATOM_DO
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * child.c: Getting input for the statusline
7 *
8 */
9 #include "common.h"
10 #include "yajl_utils.h"
11
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <sys/types.h>
15 #include <sys/wait.h>
16 #include <signal.h>
17 #include <stdio.h>
18 #include <stdarg.h>
19 #include <fcntl.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <err.h>
23 #include <ev.h>
24 #include <yajl/yajl_common.h>
25 #include <yajl/yajl_parse.h>
26 #include <yajl/yajl_version.h>
27 #include <yajl/yajl_gen.h>
28 #include <paths.h>
29
30 #include <xcb/xcb_keysyms.h>
31
32 /* Global variables for child_*() */
33 i3bar_child child;
34 #define DLOG_CHILD DLOG("%s: pid=%ld stopped=%d stop_signal=%d cont_signal=%d click_events=%d click_events_init=%d\n", \
35 __func__, (long)child.pid, child.stopped, child.stop_signal, child.cont_signal, child.click_events, child.click_events_init)
36
37 /* stdin- and SIGCHLD-watchers */
38 ev_io *stdin_io;
39 int stdin_fd;
40 ev_child *child_sig;
41
42 /* JSON parser for stdin */
43 yajl_handle parser;
44
45 /* JSON generator for stdout */
46 yajl_gen gen;
47
48 typedef struct parser_ctx {
49 /* True if one of the parsed blocks was urgent */
50 bool has_urgent;
51
52 /* A copy of the last JSON map key. */
53 char *last_map_key;
54
55 /* The current block. Will be filled, then copied and put into the list of
56 * blocks. */
57 struct status_block block;
58 } parser_ctx;
59
60 parser_ctx parser_context;
61
62 struct statusline_head statusline_head = TAILQ_HEAD_INITIALIZER(statusline_head);
63 /* Used temporarily while reading a statusline */
64 struct statusline_head statusline_buffer = TAILQ_HEAD_INITIALIZER(statusline_buffer);
65
66 int child_stdin;
67
68 /*
69 * Remove all blocks from the given statusline.
70 * If free_resources is set, the fields of each status block will be free'd.
71 */
72 static void clear_statusline(struct statusline_head *head, bool free_resources) {
73 struct status_block *first;
74 while (!TAILQ_EMPTY(head)) {
75 first = TAILQ_FIRST(head);
76 if (free_resources) {
77 I3STRING_FREE(first->full_text);
78 I3STRING_FREE(first->short_text);
79 FREE(first->color);
80 FREE(first->name);
81 FREE(first->instance);
82 FREE(first->min_width_str);
83 FREE(first->background);
84 FREE(first->border);
85 }
86
87 TAILQ_REMOVE(head, first, blocks);
88 free(first);
89 }
90 }
91
92 static void copy_statusline(struct statusline_head *from, struct statusline_head *to) {
93 struct status_block *current;
94 TAILQ_FOREACH (current, from, blocks) {
95 struct status_block *new_block = smalloc(sizeof(struct status_block));
96 memcpy(new_block, current, sizeof(struct status_block));
97 TAILQ_INSERT_TAIL(to, new_block, blocks);
98 }
99 }
100
101 /*
102 * Replaces the statusline in memory with an error message. Pass a format
103 * string and format parameters as you would in `printf'. The next time
104 * `draw_bars' is called, the error message text will be drawn on the bar in
105 * the space allocated for the statusline.
106 */
107 __attribute__((format(printf, 1, 2))) static void set_statusline_error(const char *format, ...) {
108 clear_statusline(&statusline_head, true);
109
110 char *message;
111 va_list args;
112 va_start(args, format);
113 if (vasprintf(&message, format, args) == -1) {
114 goto finish;
115 }
116
117 struct status_block *err_block = scalloc(1, sizeof(struct status_block));
118 err_block->full_text = i3string_from_utf8("Error: ");
119 err_block->name = sstrdup("error");
120 err_block->color = sstrdup("#ff0000");
121 err_block->no_separator = true;
122
123 struct status_block *message_block = scalloc(1, sizeof(struct status_block));
124 message_block->full_text = i3string_from_utf8(message);
125 message_block->name = sstrdup("error_message");
126 message_block->color = sstrdup("#ff0000");
127 message_block->no_separator = true;
128
129 TAILQ_INSERT_HEAD(&statusline_head, err_block, blocks);
130 TAILQ_INSERT_TAIL(&statusline_head, message_block, blocks);
131
132 finish:
133 FREE(message);
134 va_end(args);
135 }
136
137 /*
138 * Stop and free() the stdin- and SIGCHLD-watchers
139 *
140 */
141 static void cleanup(void) {
142 if (stdin_io != NULL) {
143 ev_io_stop(main_loop, stdin_io);
144 FREE(stdin_io);
145 }
146
147 if (child_sig != NULL) {
148 ev_child_stop(main_loop, child_sig);
149 FREE(child_sig);
150 }
151
152 memset(&child, 0, sizeof(i3bar_child));
153 }
154
155 /*
156 * The start of a new array is the start of a new status line, so we clear all
157 * previous entries from the buffer.
158 */
159 static int stdin_start_array(void *context) {
160 // the blocks are still used by statusline_head, so we won't free the
161 // resources here.
162 clear_statusline(&statusline_buffer, false);
163 return 1;
164 }
165
166 /*
167 * The start of a map is the start of a single block of the status line.
168 *
169 */
170 static int stdin_start_map(void *context) {
171 parser_ctx *ctx = context;
172 memset(&(ctx->block), '\0', sizeof(struct status_block));
173
174 /* Default width of the separator block. */
175 if (config.separator_symbol == NULL)
176 ctx->block.sep_block_width = logical_px(9);
177 else
178 ctx->block.sep_block_width = logical_px(8) + separator_symbol_width;
179
180 /* By default we draw all four borders if a border is set. */
181 ctx->block.border_top = 1;
182 ctx->block.border_right = 1;
183 ctx->block.border_bottom = 1;
184 ctx->block.border_left = 1;
185
186 return 1;
187 }
188
189 static int stdin_map_key(void *context, const unsigned char *key, size_t len) {
190 parser_ctx *ctx = context;
191 FREE(ctx->last_map_key);
192 sasprintf(&(ctx->last_map_key), "%.*s", len, key);
193 return 1;
194 }
195
196 static int stdin_boolean(void *context, int val) {
197 parser_ctx *ctx = context;
198
199 if (!ctx->last_map_key) {
200 return 0;
201 }
202
203 if (strcasecmp(ctx->last_map_key, "urgent") == 0) {
204 ctx->block.urgent = val;
205 return 1;
206 }
207 if (strcasecmp(ctx->last_map_key, "separator") == 0) {
208 ctx->block.no_separator = !val;
209 return 1;
210 }
211
212 return 1;
213 }
214
215 static int stdin_string(void *context, const unsigned char *val, size_t len) {
216 parser_ctx *ctx = context;
217
218 if (!ctx->last_map_key) {
219 return 0;
220 }
221
222 if (strcasecmp(ctx->last_map_key, "full_text") == 0) {
223 ctx->block.full_text = i3string_from_markup_with_length((const char *)val, len);
224 return 1;
225 }
226 if (strcasecmp(ctx->last_map_key, "short_text") == 0) {
227 ctx->block.short_text = i3string_from_markup_with_length((const char *)val, len);
228 return 1;
229 }
230 if (strcasecmp(ctx->last_map_key, "color") == 0) {
231 sasprintf(&(ctx->block.color), "%.*s", len, val);
232 return 1;
233 }
234 if (strcasecmp(ctx->last_map_key, "background") == 0) {
235 sasprintf(&(ctx->block.background), "%.*s", len, val);
236 return 1;
237 }
238 if (strcasecmp(ctx->last_map_key, "border") == 0) {
239 sasprintf(&(ctx->block.border), "%.*s", len, val);
240 return 1;
241 }
242 if (strcasecmp(ctx->last_map_key, "markup") == 0) {
243 ctx->block.pango_markup = (len == strlen("pango") && !strncasecmp((const char *)val, "pango", strlen("pango")));
244 return 1;
245 }
246 if (strcasecmp(ctx->last_map_key, "align") == 0) {
247 if (len == strlen("center") && !strncmp((const char *)val, "center", strlen("center"))) {
248 ctx->block.align = ALIGN_CENTER;
249 } else if (len == strlen("right") && !strncmp((const char *)val, "right", strlen("right"))) {
250 ctx->block.align = ALIGN_RIGHT;
251 } else {
252 ctx->block.align = ALIGN_LEFT;
253 }
254 return 1;
255 }
256 if (strcasecmp(ctx->last_map_key, "min_width") == 0) {
257 sasprintf(&(ctx->block.min_width_str), "%.*s", len, val);
258 return 1;
259 }
260 if (strcasecmp(ctx->last_map_key, "name") == 0) {
261 sasprintf(&(ctx->block.name), "%.*s", len, val);
262 return 1;
263 }
264 if (strcasecmp(ctx->last_map_key, "instance") == 0) {
265 sasprintf(&(ctx->block.instance), "%.*s", len, val);
266 return 1;
267 }
268
269 return 1;
270 }
271
272 static int stdin_integer(void *context, long long val) {
273 parser_ctx *ctx = context;
274
275 if (!ctx->last_map_key) {
276 return 0;
277 }
278
279 if (strcasecmp(ctx->last_map_key, "min_width") == 0) {
280 ctx->block.min_width = (uint32_t)val;
281 return 1;
282 }
283 if (strcasecmp(ctx->last_map_key, "separator_block_width") == 0) {
284 ctx->block.sep_block_width = (uint32_t)val;
285 return 1;
286 }
287 if (strcasecmp(ctx->last_map_key, "border_top") == 0) {
288 ctx->block.border_top = (uint32_t)val;
289 return 1;
290 }
291 if (strcasecmp(ctx->last_map_key, "border_right") == 0) {
292 ctx->block.border_right = (uint32_t)val;
293 return 1;
294 }
295 if (strcasecmp(ctx->last_map_key, "border_bottom") == 0) {
296 ctx->block.border_bottom = (uint32_t)val;
297 return 1;
298 }
299 if (strcasecmp(ctx->last_map_key, "border_left") == 0) {
300 ctx->block.border_left = (uint32_t)val;
301 return 1;
302 }
303
304 return 1;
305 }
306
307 /*
308 * When a map is finished, we have an entire status block.
309 * Move it from the parser's context to the statusline buffer.
310 */
311 static int stdin_end_map(void *context) {
312 parser_ctx *ctx = context;
313 struct status_block *new_block = smalloc(sizeof(struct status_block));
314 memcpy(new_block, &(ctx->block), sizeof(struct status_block));
315 /* Ensure we have a full_text set, so that when it is missing (or null),
316 * i3bar doesn’t crash and the user gets an annoying message. */
317 if (!new_block->full_text)
318 new_block->full_text = i3string_from_utf8("SPEC VIOLATION: full_text is NULL!");
319 if (new_block->urgent)
320 ctx->has_urgent = true;
321
322 if (new_block->min_width_str) {
323 i3String *text = i3string_from_utf8(new_block->min_width_str);
324 i3string_set_markup(text, new_block->pango_markup);
325 new_block->min_width = (uint32_t)predict_text_width(text);
326 i3string_free(text);
327 }
328
329 i3string_set_markup(new_block->full_text, new_block->pango_markup);
330
331 if (new_block->short_text != NULL)
332 i3string_set_markup(new_block->short_text, new_block->pango_markup);
333
334 TAILQ_INSERT_TAIL(&statusline_buffer, new_block, blocks);
335 return 1;
336 }
337
338 /*
339 * When an array is finished, we have an entire statusline.
340 * Copy it from the buffer to the actual statusline.
341 */
342 static int stdin_end_array(void *context) {
343 DLOG("copying statusline_buffer to statusline_head\n");
344 clear_statusline(&statusline_head, true);
345 copy_statusline(&statusline_buffer, &statusline_head);
346
347 DLOG("dumping statusline:\n");
348 struct status_block *current;
349 TAILQ_FOREACH (current, &statusline_head, blocks) {
350 DLOG("full_text = %s\n", i3string_as_utf8(current->full_text));
351 DLOG("short_text = %s\n", (current->short_text == NULL ? NULL : i3string_as_utf8(current->short_text)));
352 DLOG("color = %s\n", current->color);
353 }
354 DLOG("end of dump\n");
355 return 1;
356 }
357
358 /*
359 * Helper function to read stdin
360 *
361 * Returns NULL on EOF.
362 *
363 */
364 static unsigned char *get_buffer(ev_io *watcher, int *ret_buffer_len) {
365 int fd = watcher->fd;
366 int n = 0;
367 int rec = 0;
368 int buffer_len = STDIN_CHUNK_SIZE;
369 unsigned char *buffer = smalloc(buffer_len + 1);
370 buffer[0] = '\0';
371 while (1) {
372 n = read(fd, buffer + rec, buffer_len - rec);
373 if (n == -1) {
374 if (errno == EAGAIN) {
375 /* finish up */
376 break;
377 }
378 ELOG("read() failed!: %s\n", strerror(errno));
379 FREE(buffer);
380 exit(EXIT_FAILURE);
381 }
382 if (n == 0) {
383 ELOG("stdin: received EOF\n");
384 FREE(buffer);
385 *ret_buffer_len = -1;
386 return NULL;
387 }
388 rec += n;
389
390 if (rec == buffer_len) {
391 buffer_len += STDIN_CHUNK_SIZE;
392 buffer = srealloc(buffer, buffer_len);
393 }
394 }
395 if (*buffer == '\0') {
396 FREE(buffer);
397 rec = -1;
398 }
399 *ret_buffer_len = rec;
400 return buffer;
401 }
402
403 static void read_flat_input(char *buffer, int length) {
404 struct status_block *first = TAILQ_FIRST(&statusline_head);
405 /* Clear the old buffer if any. */
406 I3STRING_FREE(first->full_text);
407 /* Remove the trailing newline and terminate the string at the same
408 * time. */
409 if (buffer[length - 1] == '\n' || buffer[length - 1] == '\r') {
410 buffer[length - 1] = '\0';
411 } else {
412 buffer[length] = '\0';
413 }
414
415 first->full_text = i3string_from_utf8(buffer);
416 }
417
418 static bool read_json_input(unsigned char *input, int length) {
419 yajl_status status = yajl_parse(parser, input, length);
420 bool has_urgent = false;
421 if (status != yajl_status_ok) {
422 char *message = (char *)yajl_get_error(parser, 0, input, length);
423
424 /* strip the newline yajl adds to the error message */
425 if (message[strlen(message) - 1] == '\n')
426 message[strlen(message) - 1] = '\0';
427
428 fprintf(stderr, "[i3bar] Could not parse JSON input (code = %d, message = %s): %.*s\n",
429 status, message, length, input);
430
431 set_statusline_error("Could not parse JSON (%s)", message);
432 yajl_free_error(parser, (unsigned char *)message);
433 draw_bars(false);
434 } else if (parser_context.has_urgent) {
435 has_urgent = true;
436 }
437 return has_urgent;
438 }
439
440 /*
441 * Callbalk for stdin. We read a line from stdin and store the result
442 * in statusline
443 *
444 */
445 static void stdin_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
446 int rec;
447 unsigned char *buffer = get_buffer(watcher, &rec);
448 if (buffer == NULL)
449 return;
450 bool has_urgent = false;
451 if (child.version > 0) {
452 has_urgent = read_json_input(buffer, rec);
453 } else {
454 read_flat_input((char *)buffer, rec);
455 }
456 free(buffer);
457 draw_bars(has_urgent);
458 }
459
460 /*
461 * Callbalk for stdin first line. We read the first line to detect
462 * whether this is JSON or plain text
463 *
464 */
465 static void stdin_io_first_line_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
466 int rec;
467 unsigned char *buffer = get_buffer(watcher, &rec);
468 if (buffer == NULL)
469 return;
470 DLOG("Detecting input type based on buffer *%.*s*\n", rec, buffer);
471 /* Detect whether this is JSON or plain text. */
472 unsigned int consumed = 0;
473 /* At the moment, we don’t care for the version. This might change
474 * in the future, but for now, we just discard it. */
475 parse_json_header(&child, buffer, rec, &consumed);
476 if (child.version > 0) {
477 /* If hide-on-modifier is set, we start of by sending the
478 * child a SIGSTOP, because the bars aren't mapped at start */
479 if (config.hide_on_modifier) {
480 stop_child();
481 }
482 draw_bars(read_json_input(buffer + consumed, rec - consumed));
483 } else {
484 /* In case of plaintext, we just add a single block and change its
485 * full_text pointer later. */
486 struct status_block *new_block = scalloc(1, sizeof(struct status_block));
487 TAILQ_INSERT_TAIL(&statusline_head, new_block, blocks);
488 read_flat_input((char *)buffer, rec);
489 }
490 free(buffer);
491 ev_io_stop(main_loop, stdin_io);
492 ev_io_init(stdin_io, &stdin_io_cb, stdin_fd, EV_READ);
493 ev_io_start(main_loop, stdin_io);
494 }
495
496 /*
497 * We received a SIGCHLD, meaning, that the child process terminated.
498 * We simply free the respective data structures and don't care for input
499 * anymore
500 *
501 */
502 static void child_sig_cb(struct ev_loop *loop, ev_child *watcher, int revents) {
503 int exit_status = WEXITSTATUS(watcher->rstatus);
504
505 ELOG("Child (pid: %d) unexpectedly exited with status %d\n",
506 child.pid,
507 exit_status);
508
509 /* this error is most likely caused by a user giving a nonexecutable or
510 * nonexistent file, so we will handle those cases separately. */
511 if (exit_status == 126)
512 set_statusline_error("status_command is not executable (exit %d)", exit_status);
513 else if (exit_status == 127)
514 set_statusline_error("status_command not found or is missing a library dependency (exit %d)", exit_status);
515 else
516 set_statusline_error("status_command process exited unexpectedly (exit %d)", exit_status);
517
518 cleanup();
519 draw_bars(false);
520 }
521
522 static void child_write_output(void) {
523 if (child.click_events) {
524 const unsigned char *output;
525 size_t size;
526 ssize_t n;
527
528 yajl_gen_get_buf(gen, &output, &size);
529
530 n = writeall(child_stdin, output, size);
531 if (n != -1)
532 n = writeall(child_stdin, "\n", 1);
533
534 yajl_gen_clear(gen);
535
536 if (n == -1) {
537 child.click_events = false;
538 kill_child();
539 set_statusline_error("child_write_output failed");
540 draw_bars(false);
541 }
542 }
543 }
544
545 /*
546 * Start a child process with the specified command and reroute stdin.
547 * We actually start a shell to execute the command so we don't have to care
548 * about arguments and such.
549 *
550 * If `command' is NULL, such as in the case when no `status_command' is given
551 * in the bar config, no child will be started.
552 *
553 */
554 void start_child(char *command) {
555 if (command == NULL)
556 return;
557
558 /* Allocate a yajl parser which will be used to parse stdin. */
559 static yajl_callbacks callbacks = {
560 .yajl_boolean = stdin_boolean,
561 .yajl_integer = stdin_integer,
562 .yajl_string = stdin_string,
563 .yajl_start_map = stdin_start_map,
564 .yajl_map_key = stdin_map_key,
565 .yajl_end_map = stdin_end_map,
566 .yajl_start_array = stdin_start_array,
567 .yajl_end_array = stdin_end_array,
568 };
569 parser = yajl_alloc(&callbacks, NULL, &parser_context);
570
571 gen = yajl_gen_alloc(NULL);
572
573 int pipe_in[2]; /* pipe we read from */
574 int pipe_out[2]; /* pipe we write to */
575
576 if (pipe(pipe_in) == -1)
577 err(EXIT_FAILURE, "pipe(pipe_in)");
578 if (pipe(pipe_out) == -1)
579 err(EXIT_FAILURE, "pipe(pipe_out)");
580
581 child.pid = fork();
582 switch (child.pid) {
583 case -1:
584 ELOG("Couldn't fork(): %s\n", strerror(errno));
585 exit(EXIT_FAILURE);
586 case 0:
587 /* Child-process. Reroute streams and start shell */
588
589 close(pipe_in[0]);
590 close(pipe_out[1]);
591
592 dup2(pipe_in[1], STDOUT_FILENO);
593 dup2(pipe_out[0], STDIN_FILENO);
594
595 setpgid(child.pid, 0);
596 execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, (char *)NULL);
597 return;
598 default:
599 /* Parent-process. Reroute streams */
600
601 close(pipe_in[1]);
602 close(pipe_out[0]);
603
604 stdin_fd = pipe_in[0];
605 child_stdin = pipe_out[1];
606
607 break;
608 }
609
610 /* We set O_NONBLOCK because blocking is evil in event-driven software */
611 fcntl(stdin_fd, F_SETFL, O_NONBLOCK);
612
613 stdin_io = smalloc(sizeof(ev_io));
614 ev_io_init(stdin_io, &stdin_io_first_line_cb, stdin_fd, EV_READ);
615 ev_io_start(main_loop, stdin_io);
616
617 /* We must cleanup, if the child unexpectedly terminates */
618 child_sig = smalloc(sizeof(ev_child));
619 ev_child_init(child_sig, &child_sig_cb, child.pid, 0);
620 ev_child_start(main_loop, child_sig);
621
622 atexit(kill_child_at_exit);
623 DLOG_CHILD;
624 }
625
626 static void child_click_events_initialize(void) {
627 DLOG_CHILD;
628
629 if (!child.click_events_init) {
630 yajl_gen_array_open(gen);
631 child_write_output();
632 child.click_events_init = true;
633 }
634 }
635
636 /*
637 * Generates a click event, if enabled.
638 *
639 */
640 void send_block_clicked(int button, const char *name, const char *instance, int x, int y, int x_rel, int y_rel, int width, int height, int mods) {
641 if (!child.click_events) {
642 return;
643 }
644
645 child_click_events_initialize();
646
647 yajl_gen_map_open(gen);
648
649 if (name) {
650 ystr("name");
651 ystr(name);
652 }
653
654 if (instance) {
655 ystr("instance");
656 ystr(instance);
657 }
658
659 ystr("button");
660 yajl_gen_integer(gen, button);
661
662 ystr("modifiers");
663 yajl_gen_array_open(gen);
664 if (mods & XCB_MOD_MASK_SHIFT)
665 ystr("Shift");
666 if (mods & XCB_MOD_MASK_CONTROL)
667 ystr("Control");
668 if (mods & XCB_MOD_MASK_1)
669 ystr("Mod1");
670 if (mods & XCB_MOD_MASK_2)
671 ystr("Mod2");
672 if (mods & XCB_MOD_MASK_3)
673 ystr("Mod3");
674 if (mods & XCB_MOD_MASK_4)
675 ystr("Mod4");
676 if (mods & XCB_MOD_MASK_5)
677 ystr("Mod5");
678 yajl_gen_array_close(gen);
679
680 ystr("x");
681 yajl_gen_integer(gen, x);
682
683 ystr("y");
684 yajl_gen_integer(gen, y);
685
686 ystr("relative_x");
687 yajl_gen_integer(gen, x_rel);
688
689 ystr("relative_y");
690 yajl_gen_integer(gen, y_rel);
691
692 ystr("width");
693 yajl_gen_integer(gen, width);
694
695 ystr("height");
696 yajl_gen_integer(gen, height);
697
698 yajl_gen_map_close(gen);
699 child_write_output();
700 }
701
702 /*
703 * kill()s the child process (if any). Called when exit()ing.
704 *
705 */
706 void kill_child_at_exit(void) {
707 DLOG_CHILD;
708
709 if (child.pid > 0) {
710 if (child.cont_signal > 0 && child.stopped)
711 killpg(child.pid, child.cont_signal);
712 killpg(child.pid, SIGTERM);
713 }
714 }
715
716 /*
717 * kill()s the child process (if existent) and closes and
718 * free()s the stdin- and SIGCHLD-watchers
719 *
720 */
721 void kill_child(void) {
722 DLOG_CHILD;
723
724 if (child.pid > 0) {
725 if (child.cont_signal > 0 && child.stopped)
726 killpg(child.pid, child.cont_signal);
727 killpg(child.pid, SIGTERM);
728 int status;
729 waitpid(child.pid, &status, 0);
730 cleanup();
731 }
732 }
733
734 /*
735 * Sends a SIGSTOP to the child process (if existent)
736 *
737 */
738 void stop_child(void) {
739 DLOG_CHILD;
740
741 if (child.stop_signal > 0 && !child.stopped) {
742 child.stopped = true;
743 killpg(child.pid, child.stop_signal);
744 }
745 }
746
747 /*
748 * Sends a SIGCONT to the child process (if existent)
749 *
750 */
751 void cont_child(void) {
752 DLOG_CHILD;
753
754 if (child.cont_signal > 0 && child.stopped) {
755 child.stopped = false;
756 killpg(child.pid, child.cont_signal);
757 }
758 }
759
760 /*
761 * Whether or not the child want click events
762 *
763 */
764 bool child_want_click_events(void) {
765 return child.click_events;
766 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * config.c: Parses the configuration (received from i3).
7 *
8 */
9 #include "common.h"
10
11 #include <string.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <errno.h>
15 #include <i3/ipc.h>
16 #include <yajl/yajl_parse.h>
17 #include <yajl/yajl_version.h>
18
19 #include <X11/Xlib.h>
20
21 config_t config;
22 static char *cur_key;
23 static bool parsing_bindings;
24 static bool parsing_tray_outputs;
25
26 /*
27 * Parse a key.
28 *
29 * Essentially we just save it in cur_key.
30 *
31 */
32 static int config_map_key_cb(void *params_, const unsigned char *keyVal, size_t keyLen) {
33 FREE(cur_key);
34 sasprintf(&(cur_key), "%.*s", keyLen, keyVal);
35
36 if (strcmp(cur_key, "bindings") == 0) {
37 parsing_bindings = true;
38 }
39
40 if (strcmp(cur_key, "tray_outputs") == 0) {
41 parsing_tray_outputs = true;
42 }
43
44 return 1;
45 }
46
47 static int config_end_array_cb(void *params_) {
48 parsing_bindings = false;
49 parsing_tray_outputs = false;
50 return 1;
51 }
52
53 /*
54 * Parse a null value (current_workspace)
55 *
56 */
57 static int config_null_cb(void *params_) {
58 if (!strcmp(cur_key, "id")) {
59 /* If 'id' is NULL, the bar config was not found. Error out. */
60 ELOG("No such bar config. Use 'i3-msg -t get_bar_config' to get the available configs.\n");
61 ELOG("Are you starting i3bar by hand? You should not:\n");
62 ELOG("Configure a 'bar' block in your i3 config and i3 will launch i3bar automatically.\n");
63 exit(EXIT_FAILURE);
64 }
65
66 return 1;
67 }
68
69 /*
70 * Parse a string
71 *
72 */
73 static int config_string_cb(void *params_, const unsigned char *val, size_t _len) {
74 int len = (int)_len;
75 /* The id and socket_path are ignored, we already know them. */
76 if (!strcmp(cur_key, "id") || !strcmp(cur_key, "socket_path"))
77 return 1;
78
79 if (parsing_bindings) {
80 if (strcmp(cur_key, "command") == 0) {
81 binding_t *binding = TAILQ_LAST(&(config.bindings), bindings_head);
82 if (binding == NULL) {
83 ELOG("There is no binding to put the current command onto. This is a bug in i3.\n");
84 return 0;
85 }
86
87 if (binding->command != NULL) {
88 ELOG("The binding for input_code = %d already has a command. This is a bug in i3.\n", binding->input_code);
89 return 0;
90 }
91
92 sasprintf(&(binding->command), "%.*s", len, val);
93 return 1;
94 }
95
96 ELOG("Unknown key \"%s\" while parsing bar bindings.\n", cur_key);
97 return 0;
98 }
99
100 if (parsing_tray_outputs) {
101 DLOG("Adding tray_output = %.*s to the list.\n", len, val);
102 tray_output_t *tray_output = scalloc(1, sizeof(tray_output_t));
103 sasprintf(&(tray_output->output), "%.*s", len, val);
104 TAILQ_INSERT_TAIL(&(config.tray_outputs), tray_output, tray_outputs);
105 return 1;
106 }
107
108 if (!strcmp(cur_key, "mode")) {
109 DLOG("mode = %.*s, len = %d\n", len, val, len);
110 config.hide_on_modifier = (len == strlen("dock") && !strncmp((const char *)val, "dock", strlen("dock")) ? M_DOCK
111 : (len == strlen("hide") && !strncmp((const char *)val, "hide", strlen("hide")) ? M_HIDE
112 : M_INVISIBLE));
113 return 1;
114 }
115
116 if (!strcmp(cur_key, "hidden_state")) {
117 DLOG("hidden_state = %.*s, len = %d\n", len, val, len);
118 config.hidden_state = (len == strlen("hide") && !strncmp((const char *)val, "hide", strlen("hide")) ? S_HIDE : S_SHOW);
119 return 1;
120 }
121
122 /* Kept for backwards compatibility. */
123 if (!strcmp(cur_key, "modifier")) {
124 DLOG("modifier = %.*s\n", len, val);
125 if (len == strlen("none") && !strncmp((const char *)val, "none", strlen("none"))) {
126 config.modifier = XCB_NONE;
127 return 1;
128 }
129
130 if (len == strlen("shift") && !strncmp((const char *)val, "shift", strlen("shift"))) {
131 config.modifier = ShiftMask;
132 return 1;
133 }
134 if (len == strlen("ctrl") && !strncmp((const char *)val, "ctrl", strlen("ctrl"))) {
135 config.modifier = ControlMask;
136 return 1;
137 }
138 if (len == strlen("Mod") + 1 && !strncmp((const char *)val, "Mod", strlen("Mod"))) {
139 switch (val[3]) {
140 case '1':
141 config.modifier = Mod1Mask;
142 return 1;
143 case '2':
144 config.modifier = Mod2Mask;
145 return 1;
146 case '3':
147 config.modifier = Mod3Mask;
148 return 1;
149 case '5':
150 config.modifier = Mod5Mask;
151 return 1;
152 }
153 }
154
155 config.modifier = Mod4Mask;
156 return 1;
157 }
158
159 /* This key was sent in <= 4.10.2. We keep it around to avoid breakage for
160 * users updating from that version and restarting i3bar before i3. */
161 if (!strcmp(cur_key, "wheel_up_cmd")) {
162 DLOG("wheel_up_cmd = %.*s\n", len, val);
163 binding_t *binding = scalloc(1, sizeof(binding_t));
164 binding->input_code = 4;
165 sasprintf(&(binding->command), "%.*s", len, val);
166 TAILQ_INSERT_TAIL(&(config.bindings), binding, bindings);
167 return 1;
168 }
169
170 /* This key was sent in <= 4.10.2. We keep it around to avoid breakage for
171 * users updating from that version and restarting i3bar before i3. */
172 if (!strcmp(cur_key, "wheel_down_cmd")) {
173 DLOG("wheel_down_cmd = %.*s\n", len, val);
174 binding_t *binding = scalloc(1, sizeof(binding_t));
175 binding->input_code = 5;
176 sasprintf(&(binding->command), "%.*s", len, val);
177 TAILQ_INSERT_TAIL(&(config.bindings), binding, bindings);
178 return 1;
179 }
180
181 if (!strcmp(cur_key, "position")) {
182 DLOG("position = %.*s\n", len, val);
183 config.position = (len == strlen("top") && !strncmp((const char *)val, "top", strlen("top")) ? POS_TOP : POS_BOT);
184 return 1;
185 }
186
187 if (!strcmp(cur_key, "status_command")) {
188 DLOG("command = %.*s\n", len, val);
189 FREE(config.command);
190 sasprintf(&config.command, "%.*s", len, val);
191 return 1;
192 }
193
194 if (!strcmp(cur_key, "font")) {
195 DLOG("font = %.*s\n", len, val);
196 FREE(config.fontname);
197 sasprintf(&config.fontname, "%.*s", len, val);
198 return 1;
199 }
200
201 if (!strcmp(cur_key, "separator_symbol")) {
202 DLOG("separator = %.*s\n", len, val);
203 I3STRING_FREE(config.separator_symbol);
204 config.separator_symbol = i3string_from_utf8_with_length((const char *)val, len);
205 return 1;
206 }
207
208 if (!strcmp(cur_key, "outputs")) {
209 DLOG("+output %.*s\n", len, val);
210 int new_num_outputs = config.num_outputs + 1;
211 config.outputs = srealloc(config.outputs, sizeof(char *) * new_num_outputs);
212 sasprintf(&config.outputs[config.num_outputs], "%.*s", len, val);
213 config.num_outputs = new_num_outputs;
214 return 1;
215 }
216
217 /* We keep the old single tray_output working for users who only restart i3bar
218 * after updating. */
219 if (!strcmp(cur_key, "tray_output")) {
220 DLOG("Found deprecated key tray_output %.*s.\n", len, val);
221 tray_output_t *tray_output = scalloc(1, sizeof(tray_output_t));
222 sasprintf(&(tray_output->output), "%.*s", len, val);
223 TAILQ_INSERT_TAIL(&(config.tray_outputs), tray_output, tray_outputs);
224 return 1;
225 }
226
227 #define COLOR(json_name, struct_name) \
228 do { \
229 if (!strcmp(cur_key, #json_name)) { \
230 DLOG(#json_name " = " #struct_name " = %.*s\n", len, val); \
231 sasprintf(&(config.colors.struct_name), "%.*s", len, val); \
232 return 1; \
233 } \
234 } while (0)
235
236 COLOR(statusline, bar_fg);
237 COLOR(background, bar_bg);
238 COLOR(separator, sep_fg);
239 COLOR(focused_statusline, focus_bar_fg);
240 COLOR(focused_background, focus_bar_bg);
241 COLOR(focused_separator, focus_sep_fg);
242 COLOR(focused_workspace_border, focus_ws_border);
243 COLOR(focused_workspace_bg, focus_ws_bg);
244 COLOR(focused_workspace_text, focus_ws_fg);
245 COLOR(active_workspace_border, active_ws_border);
246 COLOR(active_workspace_bg, active_ws_bg);
247 COLOR(active_workspace_text, active_ws_fg);
248 COLOR(inactive_workspace_border, inactive_ws_border);
249 COLOR(inactive_workspace_bg, inactive_ws_bg);
250 COLOR(inactive_workspace_text, inactive_ws_fg);
251 COLOR(urgent_workspace_border, urgent_ws_border);
252 COLOR(urgent_workspace_bg, urgent_ws_bg);
253 COLOR(urgent_workspace_text, urgent_ws_fg);
254 COLOR(binding_mode_border, binding_mode_border);
255 COLOR(binding_mode_bg, binding_mode_bg);
256 COLOR(binding_mode_text, binding_mode_fg);
257
258 printf("got unexpected string %.*s for cur_key = %s\n", len, val, cur_key);
259
260 return 0;
261 }
262
263 /*
264 * Parse a boolean value
265 *
266 */
267 static int config_boolean_cb(void *params_, int val) {
268 if (parsing_bindings) {
269 if (strcmp(cur_key, "release") == 0) {
270 binding_t *binding = TAILQ_LAST(&(config.bindings), bindings_head);
271 if (binding == NULL) {
272 ELOG("There is no binding to put the current command onto. This is a bug in i3.\n");
273 return 0;
274 }
275
276 binding->release = val;
277 return 1;
278 }
279
280 ELOG("Unknown key \"%s\" while parsing bar bindings.\n", cur_key);
281 }
282
283 if (!strcmp(cur_key, "binding_mode_indicator")) {
284 DLOG("binding_mode_indicator = %d\n", val);
285 config.disable_binding_mode_indicator = !val;
286 return 1;
287 }
288
289 if (!strcmp(cur_key, "workspace_buttons")) {
290 DLOG("workspace_buttons = %d\n", val);
291 config.disable_ws = !val;
292 return 1;
293 }
294
295 if (!strcmp(cur_key, "strip_workspace_numbers")) {
296 DLOG("strip_workspace_numbers = %d\n", val);
297 config.strip_ws_numbers = val;
298 return 1;
299 }
300
301 if (!strcmp(cur_key, "strip_workspace_name")) {
302 DLOG("strip_workspace_name = %d\n", val);
303 config.strip_ws_name = val;
304 return 1;
305 }
306
307 if (!strcmp(cur_key, "verbose")) {
308 if (!config.verbose) {
309 DLOG("verbose = %d\n", val);
310 config.verbose = val;
311 }
312 return 1;
313 }
314
315 return 0;
316 }
317
318 /*
319 * Parse an integer value
320 *
321 */
322 static int config_integer_cb(void *params_, long long val) {
323 if (parsing_bindings) {
324 if (strcmp(cur_key, "input_code") == 0) {
325 binding_t *binding = scalloc(1, sizeof(binding_t));
326 binding->input_code = val;
327 TAILQ_INSERT_TAIL(&(config.bindings), binding, bindings);
328
329 return 1;
330 }
331
332 ELOG("Unknown key \"%s\" while parsing bar bindings.\n", cur_key);
333 return 0;
334 }
335
336 if (!strcmp(cur_key, "bar_height")) {
337 DLOG("bar_height = %lld", val);
338 config.bar_height = (uint32_t)val;
339 return 1;
340 }
341
342 if (!strcmp(cur_key, "tray_padding")) {
343 DLOG("tray_padding = %lld\n", val);
344 config.tray_padding = val;
345 return 1;
346 }
347
348 if (!strcmp(cur_key, "modifier")) {
349 DLOG("modifier = %lld\n", val);
350 config.modifier = (uint32_t)val;
351 return 1;
352 }
353
354 if (!strcmp(cur_key, "workspace_min_width")) {
355 DLOG("workspace_min_width = %lld\n", val);
356 config.ws_min_width = val;
357 return 1;
358 }
359
360 return 0;
361 }
362
363 /* A datastructure to pass all these callbacks to yajl */
364 static yajl_callbacks outputs_callbacks = {
365 .yajl_null = config_null_cb,
366 .yajl_integer = config_integer_cb,
367 .yajl_boolean = config_boolean_cb,
368 .yajl_string = config_string_cb,
369 .yajl_end_array = config_end_array_cb,
370 .yajl_map_key = config_map_key_cb,
371 };
372
373 /*
374 * Start parsing the received bar configuration JSON string
375 *
376 */
377 void parse_config_json(char *json) {
378 yajl_handle handle;
379 yajl_status state;
380 handle = yajl_alloc(&outputs_callbacks, NULL, NULL);
381
382 TAILQ_INIT(&(config.bindings));
383 TAILQ_INIT(&(config.tray_outputs));
384
385 state = yajl_parse(handle, (const unsigned char *)json, strlen(json));
386
387 /* FIXME: Proper error handling for JSON parsing */
388 switch (state) {
389 case yajl_status_ok:
390 break;
391 case yajl_status_client_canceled:
392 case yajl_status_error:
393 ELOG("Could not parse config reply!\n");
394 exit(EXIT_FAILURE);
395 break;
396 }
397
398 yajl_free(handle);
399 }
400
401 /*
402 * free()s the color strings as soon as they are not needed anymore.
403 *
404 */
405 void free_colors(struct xcb_color_strings_t *colors) {
406 #define FREE_COLOR(x) \
407 do { \
408 FREE(colors->x); \
409 } while (0)
410 FREE_COLOR(bar_fg);
411 FREE_COLOR(bar_bg);
412 FREE_COLOR(sep_fg);
413 FREE_COLOR(focus_bar_fg);
414 FREE_COLOR(focus_bar_bg);
415 FREE_COLOR(focus_sep_fg);
416 FREE_COLOR(active_ws_fg);
417 FREE_COLOR(active_ws_bg);
418 FREE_COLOR(active_ws_border);
419 FREE_COLOR(inactive_ws_fg);
420 FREE_COLOR(inactive_ws_bg);
421 FREE_COLOR(inactive_ws_border);
422 FREE_COLOR(urgent_ws_fg);
423 FREE_COLOR(urgent_ws_bg);
424 FREE_COLOR(urgent_ws_border);
425 FREE_COLOR(focus_ws_fg);
426 FREE_COLOR(focus_ws_bg);
427 FREE_COLOR(focus_ws_border);
428 FREE_COLOR(binding_mode_fg);
429 FREE_COLOR(binding_mode_bg);
430 FREE_COLOR(binding_mode_border);
431 #undef FREE_COLOR
432 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * ipc.c: Communicating with i3
7 *
8 */
9 #include "common.h"
10
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <unistd.h>
14 #include <stdint.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <sys/socket.h>
18 #include <sys/un.h>
19 #include <i3/ipc.h>
20 #include <ev.h>
21 #ifdef I3_ASAN_ENABLED
22 #include <sanitizer/lsan_interface.h>
23 #endif
24
25 ev_io *i3_connection;
26
27 const char *sock_path;
28
29 typedef void (*handler_t)(char *);
30
31 /*
32 * Called, when we get a reply to a command from i3.
33 * Since i3 does not give us much feedback on commands, we do not much
34 *
35 */
36 static void got_command_reply(char *reply) {
37 /* TODO: Error handling for command replies */
38 }
39
40 /*
41 * Called, when we get a reply with workspaces data
42 *
43 */
44 static void got_workspace_reply(char *reply) {
45 DLOG("Got workspace data!\n");
46 parse_workspaces_json(reply);
47 draw_bars(false);
48 }
49
50 /*
51 * Called, when we get a reply for a subscription.
52 * Since i3 does not give us much feedback on commands, we do not much
53 *
54 */
55 static void got_subscribe_reply(char *reply) {
56 DLOG("Got subscribe reply: %s\n", reply);
57 /* TODO: Error handling for subscribe commands */
58 }
59
60 /*
61 * Called, when we get a reply with outputs data
62 *
63 */
64 static void got_output_reply(char *reply) {
65 DLOG("Clearing old output configuration...\n");
66 free_outputs();
67
68 DLOG("Parsing outputs JSON...\n");
69 parse_outputs_json(reply);
70 DLOG("Reconfiguring windows...\n");
71 reconfig_windows(false);
72
73 i3_output *o_walk;
74 SLIST_FOREACH (o_walk, outputs, slist) {
75 kick_tray_clients(o_walk);
76 }
77
78 if (!config.disable_ws) {
79 i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
80 }
81
82 draw_bars(false);
83 }
84
85 /*
86 * Called when we get the configuration for our bar instance
87 *
88 */
89 static void got_bar_config(char *reply) {
90 DLOG("Received bar config \"%s\"\n", reply);
91 /* We initiate the main function by requesting infos about the outputs and
92 * workspaces. Everything else (creating the bars, showing the right workspace-
93 * buttons and more) is taken care of by the event-drivenness of the code */
94 i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
95
96 free_colors(&(config.colors));
97 parse_config_json(reply);
98
99 /* Now we can actually use 'config', so let's subscribe to the appropriate
100 * events and request the workspaces if necessary. */
101 subscribe_events();
102 if (!config.disable_ws)
103 i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
104
105 /* Initialize the rest of XCB */
106 init_xcb_late(config.fontname);
107
108 /* Resolve color strings to colorpixels and save them, then free the strings. */
109 init_colors(&(config.colors));
110
111 start_child(config.command);
112 }
113
114 /* Data structure to easily call the reply handlers later */
115 handler_t reply_handlers[] = {
116 &got_command_reply, /* I3_IPC_REPLY_TYPE_COMMAND */
117 &got_workspace_reply, /* I3_IPC_REPLY_TYPE_WORKSPACES */
118 &got_subscribe_reply, /* I3_IPC_REPLY_TYPE_SUBSCRIBE */
119 &got_output_reply, /* I3_IPC_REPLY_TYPE_OUTPUTS */
120 NULL, /* I3_IPC_REPLY_TYPE_TREE */
121 NULL, /* I3_IPC_REPLY_TYPE_MARKS */
122 &got_bar_config, /* I3_IPC_REPLY_TYPE_BAR_CONFIG */
123 NULL, /* I3_IPC_REPLY_TYPE_VERSION */
124 NULL, /* I3_IPC_REPLY_TYPE_BINDING_MODES */
125 NULL, /* I3_IPC_REPLY_TYPE_CONFIG */
126 NULL, /* I3_IPC_REPLY_TYPE_TICK */
127 NULL, /* I3_IPC_REPLY_TYPE_SYNC */
128 };
129
130 /*
131 * Called, when a workspace event arrives (i.e. the user changed the workspace)
132 *
133 */
134 static void got_workspace_event(char *event) {
135 DLOG("Got workspace event!\n");
136 i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
137 }
138
139 /*
140 * Called, when an output event arrives (i.e. the screen configuration changed)
141 *
142 */
143 static void got_output_event(char *event) {
144 DLOG("Got output event!\n");
145 i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
146 if (!config.disable_ws) {
147 i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_WORKSPACES, NULL);
148 }
149 }
150
151 /*
152 * Called, when a mode event arrives (i3 changed binding mode).
153 *
154 */
155 static void got_mode_event(char *event) {
156 DLOG("Got mode event!\n");
157 parse_mode_json(event);
158 draw_bars(false);
159 }
160
161 /*
162 * Called, when a barconfig_update event arrives (i.e. i3 changed the bar hidden_state or mode)
163 *
164 */
165 static void got_bar_config_update(char *event) {
166 /* check whether this affect this bar instance by checking the bar_id */
167 char *expected_id;
168 sasprintf(&expected_id, "\"id\":\"%s\"", config.bar_id);
169 char *found_id = strstr(event, expected_id);
170 FREE(expected_id);
171 if (found_id == NULL)
172 return;
173
174 /* reconfigure the bar based on the current outputs */
175 i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
176
177 free_colors(&(config.colors));
178
179 /* update the configuration with the received settings */
180 DLOG("Received bar config update \"%s\"\n", event);
181 char *old_command = config.command ? sstrdup(config.command) : NULL;
182 bar_display_mode_t old_mode = config.hide_on_modifier;
183 parse_config_json(event);
184 if (old_mode != config.hide_on_modifier) {
185 reconfig_windows(true);
186 }
187
188 /* update fonts and colors */
189 init_xcb_late(config.fontname);
190 init_colors(&(config.colors));
191
192 /* restart status command process */
193 if (old_command && strcmp(old_command, config.command) != 0) {
194 kill_child();
195 start_child(config.command);
196 }
197 free(old_command);
198
199 draw_bars(false);
200 }
201
202 /* Data structure to easily call the event handlers later */
203 handler_t event_handlers[] = {
204 &got_workspace_event,
205 &got_output_event,
206 &got_mode_event,
207 NULL,
208 &got_bar_config_update,
209 };
210
211 /*
212 * Called, when we get a message from i3
213 *
214 */
215 static void got_data(struct ev_loop *loop, ev_io *watcher, int events) {
216 DLOG("Got data!\n");
217 int fd = watcher->fd;
218
219 /* First we only read the header, because we know its length */
220 uint32_t header_len = strlen(I3_IPC_MAGIC) + sizeof(uint32_t) * 2;
221 char *header = smalloc(header_len);
222
223 /* We first parse the fixed-length IPC header, to know, how much data
224 * we have to expect */
225 uint32_t rec = 0;
226 while (rec < header_len) {
227 int n = read(fd, header + rec, header_len - rec);
228 if (n == -1) {
229 ELOG("read() failed: %s\n", strerror(errno));
230 exit(EXIT_FAILURE);
231 }
232 if (n == 0) {
233 /* EOF received. Since i3 will restart i3bar instances as appropriate,
234 * we exit here. */
235 DLOG("EOF received, exiting...\n");
236 #ifdef I3_ASAN_ENABLED
237 __lsan_do_leak_check();
238 #endif
239 clean_xcb();
240 exit(EXIT_SUCCESS);
241 }
242 rec += n;
243 }
244
245 if (strncmp(header, I3_IPC_MAGIC, strlen(I3_IPC_MAGIC))) {
246 ELOG("Wrong magic code: %.*s\n Expected: %s\n",
247 (int)strlen(I3_IPC_MAGIC),
248 header,
249 I3_IPC_MAGIC);
250 exit(EXIT_FAILURE);
251 }
252
253 char *walk = header + strlen(I3_IPC_MAGIC);
254 uint32_t size;
255 memcpy(&size, (uint32_t *)walk, sizeof(uint32_t));
256 walk += sizeof(uint32_t);
257 uint32_t type;
258 memcpy(&type, (uint32_t *)walk, sizeof(uint32_t));
259
260 /* Now that we know, what to expect, we can start read()ing the rest
261 * of the message */
262 char *buffer = smalloc(size + 1);
263 rec = 0;
264
265 while (rec < size) {
266 int n = read(fd, buffer + rec, size - rec);
267 if (n == -1) {
268 ELOG("read() failed: %s\n", strerror(errno));
269 exit(EXIT_FAILURE);
270 }
271 if (n == 0) {
272 ELOG("Nothing to read!\n");
273 exit(EXIT_FAILURE);
274 }
275 rec += n;
276 }
277 buffer[size] = '\0';
278
279 /* And call the callback (indexed by the type) */
280 if (type & (1UL << 31)) {
281 type ^= 1UL << 31;
282 event_handlers[type](buffer);
283 } else {
284 if (reply_handlers[type])
285 reply_handlers[type](buffer);
286 }
287
288 FREE(header);
289 FREE(buffer);
290 }
291
292 /*
293 * Sends a message to i3.
294 * type must be a valid I3_IPC_MESSAGE_TYPE (see i3/ipc.h for further information)
295 *
296 */
297 int i3_send_msg(uint32_t type, const char *payload) {
298 uint32_t len = 0;
299 if (payload != NULL) {
300 len = strlen(payload);
301 }
302
303 /* We are a wellbehaved client and send a proper header first */
304 uint32_t to_write = strlen(I3_IPC_MAGIC) + sizeof(uint32_t) * 2 + len;
305 /* TODO: I'm not entirely sure if this buffer really has to contain more
306 * than the pure header (why not just write() the payload from *payload?),
307 * but we leave it for now */
308 char *buffer = smalloc(to_write);
309 char *walk = buffer;
310
311 memcpy(buffer, I3_IPC_MAGIC, strlen(I3_IPC_MAGIC));
312 walk += strlen(I3_IPC_MAGIC);
313 memcpy(walk, &len, sizeof(uint32_t));
314 walk += sizeof(uint32_t);
315 memcpy(walk, &type, sizeof(uint32_t));
316 walk += sizeof(uint32_t);
317
318 if (payload != NULL)
319 strncpy(walk, payload, len);
320
321 swrite(i3_connection->fd, buffer, to_write);
322
323 FREE(buffer);
324
325 return 1;
326 }
327
328 /*
329 * Initiate a connection to i3.
330 * socket_path must be a valid path to the ipc_socket of i3
331 *
332 */
333 int init_connection(const char *socket_path) {
334 sock_path = socket_path;
335 int sockfd = ipc_connect(socket_path);
336 i3_connection = smalloc(sizeof(ev_io));
337 ev_io_init(i3_connection, &got_data, sockfd, EV_READ);
338 ev_io_start(main_loop, i3_connection);
339 return 1;
340 }
341
342 /*
343 * Destroy the connection to i3.
344 */
345 void destroy_connection(void) {
346 close(i3_connection->fd);
347 ev_io_stop(main_loop, i3_connection);
348 }
349
350 /*
351 * Subscribe to all the i3-events, we need
352 *
353 */
354 void subscribe_events(void) {
355 if (config.disable_ws) {
356 i3_send_msg(I3_IPC_MESSAGE_TYPE_SUBSCRIBE, "[ \"output\", \"mode\", \"barconfig_update\" ]");
357 } else {
358 i3_send_msg(I3_IPC_MESSAGE_TYPE_SUBSCRIBE, "[ \"workspace\", \"output\", \"mode\", \"barconfig_update\" ]");
359 }
360 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 */
7 #include "common.h"
8
9 #include <stdio.h>
10 #include <i3/ipc.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <stdlib.h>
14 #include <errno.h>
15 #include <ev.h>
16 #include <getopt.h>
17 #include <glob.h>
18
19 struct ev_loop *main_loop;
20
21 /*
22 * Having verboselog(), errorlog() and debuglog() is necessary when using libi3.
23 *
24 */
25 void verboselog(char *fmt, ...) {
26 va_list args;
27
28 va_start(args, fmt);
29 vfprintf(stdout, fmt, args);
30 va_end(args);
31 }
32
33 void errorlog(char *fmt, ...) {
34 va_list args;
35
36 va_start(args, fmt);
37 vfprintf(stderr, fmt, args);
38 va_end(args);
39 }
40
41 void debuglog(char *fmt, ...) {
42 }
43
44 /*
45 * Glob path, i.e. expand ~
46 *
47 */
48 static char *expand_path(char *path) {
49 static glob_t globbuf;
50 if (glob(path, GLOB_NOCHECK | GLOB_TILDE, NULL, &globbuf) < 0) {
51 ELOG("glob() failed\n");
52 exit(EXIT_FAILURE);
53 }
54 char *result = sstrdup(globbuf.gl_pathc > 0 ? globbuf.gl_pathv[0] : path);
55 globfree(&globbuf);
56 return result;
57 }
58
59 static void print_usage(char *elf_name) {
60 printf("Usage: %s -b bar_id [-s sock_path] [-t] [-h] [-v]\n", elf_name);
61 printf("\n");
62 printf("-b, --bar_id <bar_id>\tBar ID for which to get the configuration\n");
63 printf("-s, --socket <sock_path>\tConnect to i3 via <sock_path>\n");
64 printf("-t, --transparency Enable transparency (RGBA colors)\n");
65 printf("-h, --help Display this help message and exit\n");
66 printf("-v, --version Display version number and exit\n");
67 printf("-V, --verbose Enable verbose mode\n");
68 printf("\n");
69 printf(" PLEASE NOTE that i3bar will be automatically started by i3\n"
70 " as soon as there is a 'bar' configuration block in your\n"
71 " config file. You should never need to start it manually.\n");
72 printf("\n");
73 }
74
75 /*
76 * We watch various signals, that are there to make our application stop.
77 * If we get one of those, we ev_unloop() and invoke the cleanup routines
78 * in main() with that
79 *
80 */
81 static void sig_cb(struct ev_loop *loop, ev_signal *watcher, int revents) {
82 switch (watcher->signum) {
83 case SIGTERM:
84 DLOG("Got a SIGTERM, stopping\n");
85 break;
86 case SIGINT:
87 DLOG("Got a SIGINT, stopping\n");
88 break;
89 case SIGHUP:
90 DLOG("Got a SIGHUP, stopping\n");
91 }
92 ev_unloop(main_loop, EVUNLOOP_ALL);
93 }
94
95 int main(int argc, char **argv) {
96 char *socket_path = NULL;
97
98 /* Initialize the standard config to use 0 as default */
99 memset(&config, '\0', sizeof(config_t));
100
101 static struct option long_opt[] = {
102 {"socket", required_argument, 0, 's'},
103 {"bar_id", required_argument, 0, 'b'},
104 {"transparency", no_argument, 0, 't'},
105 {"help", no_argument, 0, 'h'},
106 {"version", no_argument, 0, 'v'},
107 {"verbose", no_argument, 0, 'V'},
108 {NULL, 0, 0, 0}};
109
110 int opt;
111 int option_index = 0;
112 while ((opt = getopt_long(argc, argv, "b:s:thvV", long_opt, &option_index)) != -1) {
113 switch (opt) {
114 case 's':
115 socket_path = expand_path(optarg);
116 break;
117 case 'v':
118 printf("i3bar version " I3_VERSION " © 2010 Axel Wagner and contributors\n");
119 exit(EXIT_SUCCESS);
120 break;
121 case 'b':
122 config.bar_id = sstrdup(optarg);
123 break;
124 case 't':
125 config.transparency = true;
126 break;
127 case 'V':
128 config.verbose = true;
129 break;
130 default:
131 print_usage(argv[0]);
132 exit(EXIT_SUCCESS);
133 break;
134 }
135 }
136
137 if (!config.bar_id) {
138 /* TODO: maybe we want -f which will automatically ask i3 for the first
139 * configured bar (and error out if there are too many)? */
140 ELOG("No bar_id passed. Please let i3 start i3bar or specify --bar_id\n");
141 exit(EXIT_FAILURE);
142 }
143
144 main_loop = ev_default_loop(0); /* needed in init_xcb_early */
145 char *atom_sock_path = init_xcb_early();
146
147 /* Select a socket_path if the user hasn't specified one */
148 if (socket_path == NULL) {
149 socket_path = getenv("I3SOCK");
150 if (socket_path != NULL) {
151 socket_path = sstrdup(socket_path);
152 }
153 }
154
155 if (socket_path == NULL) {
156 socket_path = atom_sock_path;
157 } else {
158 free(atom_sock_path);
159 }
160
161 if (socket_path == NULL) {
162 char *i3_default_sock_path = "/tmp/i3-ipc.sock";
163 ELOG("No socket path specified, default to %s\n", i3_default_sock_path);
164 socket_path = sstrdup(i3_default_sock_path);
165 }
166
167 init_dpi();
168
169 init_outputs();
170 if (init_connection(socket_path)) {
171 /* Request the bar configuration. When it arrives, we fill the config array. */
172 i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG, config.bar_id);
173 }
174 free(socket_path);
175
176 /* We listen to SIGTERM/QUIT/INT and try to exit cleanly, by stopping the main loop.
177 * We only need those watchers on the stack, so putting them on the stack saves us
178 * some calls to free() */
179 ev_signal *sig_term = smalloc(sizeof(ev_signal));
180 ev_signal *sig_int = smalloc(sizeof(ev_signal));
181 ev_signal *sig_hup = smalloc(sizeof(ev_signal));
182
183 ev_signal_init(sig_term, &sig_cb, SIGTERM);
184 ev_signal_init(sig_int, &sig_cb, SIGINT);
185 ev_signal_init(sig_hup, &sig_cb, SIGHUP);
186
187 ev_signal_start(main_loop, sig_term);
188 ev_signal_start(main_loop, sig_int);
189 ev_signal_start(main_loop, sig_hup);
190
191 /* From here on everything should run smooth for itself, just start listening for
192 * events. We stop simply stop the event loop, when we are finished */
193 ev_loop(main_loop, 0);
194
195 kill_child();
196
197 clean_xcb();
198 ev_default_destroy();
199
200 return 0;
201 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * mode.c: Handle mode event and show current binding mode in the bar
7 *
8 */
9 #include "common.h"
10
11 #include <string.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <errno.h>
15 #include <yajl/yajl_parse.h>
16 #include <yajl/yajl_version.h>
17
18 /* A datatype to pass through the callbacks to save the state */
19 struct mode_json_params {
20 char *json;
21 char *cur_key;
22 char *name;
23 bool pango_markup;
24 mode *mode;
25 };
26
27 /*
28 * Parse a string (change)
29 *
30 */
31 static int mode_string_cb(void *params_, const unsigned char *val, size_t len) {
32 struct mode_json_params *params = (struct mode_json_params *)params_;
33
34 if (!strcmp(params->cur_key, "change")) {
35 sasprintf(&(params->name), "%.*s", len, val);
36 FREE(params->cur_key);
37 return 1;
38 }
39
40 FREE(params->cur_key);
41 return 0;
42 }
43
44 /*
45 * Parse a boolean.
46 *
47 */
48 static int mode_boolean_cb(void *params_, int val) {
49 struct mode_json_params *params = (struct mode_json_params *)params_;
50
51 if (strcmp(params->cur_key, "pango_markup") == 0) {
52 DLOG("Setting pango_markup to %d.\n", val);
53 params->pango_markup = val;
54
55 FREE(params->cur_key);
56 return 1;
57 }
58
59 FREE(params->cur_key);
60 return 0;
61 }
62
63 /*
64 * Parse a key.
65 *
66 * Essentially we just save it in the parsing state
67 *
68 */
69 static int mode_map_key_cb(void *params_, const unsigned char *keyVal, size_t keyLen) {
70 struct mode_json_params *params = (struct mode_json_params *)params_;
71 FREE(params->cur_key);
72 sasprintf(&(params->cur_key), "%.*s", keyLen, keyVal);
73 return 1;
74 }
75
76 static int mode_end_map_cb(void *params_) {
77 struct mode_json_params *params = (struct mode_json_params *)params_;
78
79 /* Save the name */
80 params->mode->name = i3string_from_utf8(params->name);
81 i3string_set_markup(params->mode->name, params->pango_markup);
82 /* Save its rendered width */
83 params->mode->name_width = predict_text_width(params->mode->name);
84
85 DLOG("Got mode change: %s\n", i3string_as_utf8(params->mode->name));
86 FREE(params->cur_key);
87
88 return 1;
89 }
90
91 /* A datastructure to pass all these callbacks to yajl */
92 static yajl_callbacks mode_callbacks = {
93 .yajl_string = mode_string_cb,
94 .yajl_boolean = mode_boolean_cb,
95 .yajl_map_key = mode_map_key_cb,
96 .yajl_end_map = mode_end_map_cb,
97 };
98
99 /*
100 * Start parsing the received JSON string
101 *
102 */
103 void parse_mode_json(char *json) {
104 /* FIXME: Fasciliate stream processing, i.e. allow starting to interpret
105 * JSON in chunks */
106 struct mode_json_params params;
107
108 mode binding;
109
110 params.cur_key = NULL;
111 params.json = json;
112 params.mode = &binding;
113
114 yajl_handle handle;
115 yajl_status state;
116
117 handle = yajl_alloc(&mode_callbacks, NULL, (void *)&params);
118
119 state = yajl_parse(handle, (const unsigned char *)json, strlen(json));
120
121 /* FIXME: Proper error handling for JSON parsing */
122 switch (state) {
123 case yajl_status_ok:
124 break;
125 case yajl_status_client_canceled:
126 case yajl_status_error:
127 ELOG("Could not parse mode event!\n");
128 exit(EXIT_FAILURE);
129 break;
130 }
131
132 /* We don't want to indicate default binding mode */
133 if (strcmp("default", i3string_as_utf8(params.mode->name)) == 0)
134 I3STRING_FREE(params.mode->name);
135
136 /* Set the new binding mode */
137 set_current_mode(&binding);
138
139 yajl_free(handle);
140
141 FREE(params.cur_key);
142 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * outputs.c: Maintaining the outputs list
7 *
8 */
9 #include "common.h"
10
11 #include <string.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <errno.h>
15 #include <i3/ipc.h>
16 #include <yajl/yajl_parse.h>
17 #include <yajl/yajl_version.h>
18
19 /* A datatype to pass through the callbacks to save the state */
20 struct outputs_json_params {
21 struct outputs_head *outputs;
22 i3_output *outputs_walk;
23 char *cur_key;
24 char *json;
25 bool in_rect;
26 };
27
28 /*
29 * Parse a null value (current_workspace)
30 *
31 */
32 static int outputs_null_cb(void *params_) {
33 struct outputs_json_params *params = (struct outputs_json_params *)params_;
34
35 FREE(params->cur_key);
36
37 return 1;
38 }
39
40 /*
41 * Parse a boolean value (active)
42 *
43 */
44 static int outputs_boolean_cb(void *params_, int val) {
45 struct outputs_json_params *params = (struct outputs_json_params *)params_;
46
47 if (!strcmp(params->cur_key, "active")) {
48 params->outputs_walk->active = val;
49 FREE(params->cur_key);
50 return 1;
51 }
52
53 if (!strcmp(params->cur_key, "primary")) {
54 params->outputs_walk->primary = val;
55 FREE(params->cur_key);
56 return 1;
57 }
58
59 return 0;
60 }
61
62 /*
63 * Parse an integer (current_workspace or the rect)
64 *
65 */
66 static int outputs_integer_cb(void *params_, long long val) {
67 struct outputs_json_params *params = (struct outputs_json_params *)params_;
68
69 if (!strcmp(params->cur_key, "current_workspace")) {
70 params->outputs_walk->ws = (int)val;
71 FREE(params->cur_key);
72 return 1;
73 }
74
75 if (!strcmp(params->cur_key, "x")) {
76 params->outputs_walk->rect.x = (int)val;
77 FREE(params->cur_key);
78 return 1;
79 }
80
81 if (!strcmp(params->cur_key, "y")) {
82 params->outputs_walk->rect.y = (int)val;
83 FREE(params->cur_key);
84 return 1;
85 }
86
87 if (!strcmp(params->cur_key, "width")) {
88 params->outputs_walk->rect.w = (int)val;
89 FREE(params->cur_key);
90 return 1;
91 }
92
93 if (!strcmp(params->cur_key, "height")) {
94 params->outputs_walk->rect.h = (int)val;
95 FREE(params->cur_key);
96 return 1;
97 }
98
99 return 0;
100 }
101
102 /*
103 * Parse a string (name)
104 *
105 */
106 static int outputs_string_cb(void *params_, const unsigned char *val, size_t len) {
107 struct outputs_json_params *params = (struct outputs_json_params *)params_;
108
109 if (!strcmp(params->cur_key, "current_workspace")) {
110 char *copy = NULL;
111 sasprintf(&copy, "%.*s", len, val);
112
113 char *end;
114 errno = 0;
115 long parsed_num = strtol(copy, &end, 10);
116 if (errno == 0 &&
117 (end && *end == '\0'))
118 params->outputs_walk->ws = parsed_num;
119
120 FREE(copy);
121 FREE(params->cur_key);
122 return 1;
123 }
124
125 if (strcmp(params->cur_key, "name")) {
126 return 0;
127 }
128
129 sasprintf(&(params->outputs_walk->name), "%.*s", len, val);
130
131 FREE(params->cur_key);
132 return 1;
133 }
134
135 /*
136 * We hit the start of a JSON map (rect or a new output)
137 *
138 */
139 static int outputs_start_map_cb(void *params_) {
140 struct outputs_json_params *params = (struct outputs_json_params *)params_;
141 i3_output *new_output = NULL;
142
143 if (params->cur_key == NULL) {
144 new_output = smalloc(sizeof(i3_output));
145 new_output->name = NULL;
146 new_output->active = false;
147 new_output->primary = false;
148 new_output->visible = false;
149 new_output->ws = 0,
150 new_output->statusline_width = 0;
151 new_output->statusline_short_text = false;
152 memset(&new_output->rect, 0, sizeof(rect));
153 memset(&new_output->bar, 0, sizeof(surface_t));
154 memset(&new_output->buffer, 0, sizeof(surface_t));
155 memset(&new_output->statusline_buffer, 0, sizeof(surface_t));
156
157 new_output->workspaces = smalloc(sizeof(struct ws_head));
158 TAILQ_INIT(new_output->workspaces);
159
160 new_output->trayclients = smalloc(sizeof(struct tc_head));
161 TAILQ_INIT(new_output->trayclients);
162
163 params->outputs_walk = new_output;
164
165 return 1;
166 }
167
168 if (!strcmp(params->cur_key, "rect")) {
169 params->in_rect = true;
170 }
171
172 return 1;
173 }
174
175 static void clear_output(i3_output *output) {
176 FREE(output->name);
177 FREE(output->workspaces);
178 FREE(output->trayclients);
179 }
180
181 /*
182 * We hit the end of a map (rect or a new output)
183 *
184 */
185 static int outputs_end_map_cb(void *params_) {
186 struct outputs_json_params *params = (struct outputs_json_params *)params_;
187 if (params->in_rect) {
188 params->in_rect = false;
189 /* Ignore the end of a rect */
190 return 1;
191 }
192
193 /* See if we actually handle that output */
194 if (config.num_outputs > 0) {
195 bool handle_output = false;
196 for (int c = 0; c < config.num_outputs; c++) {
197 if (strcasecmp(params->outputs_walk->name, config.outputs[c]) == 0 ||
198 (strcasecmp(config.outputs[c], "primary") == 0 &&
199 params->outputs_walk->primary)) {
200 handle_output = true;
201 break;
202 }
203 }
204 if (!handle_output) {
205 DLOG("Ignoring output \"%s\", not configured to handle it.\n",
206 params->outputs_walk->name);
207 clear_output(params->outputs_walk);
208 FREE(params->outputs_walk);
209 FREE(params->cur_key);
210 return 1;
211 }
212 }
213
214 i3_output *target = get_output_by_name(params->outputs_walk->name);
215
216 if (target == NULL) {
217 SLIST_INSERT_HEAD(outputs, params->outputs_walk, slist);
218 } else {
219 target->active = params->outputs_walk->active;
220 target->primary = params->outputs_walk->primary;
221 target->ws = params->outputs_walk->ws;
222 target->rect = params->outputs_walk->rect;
223
224 clear_output(params->outputs_walk);
225 FREE(params->outputs_walk);
226 }
227 return 1;
228 }
229
230 /*
231 * Parse a key.
232 *
233 * Essentially we just save it in the parsing state
234 *
235 */
236 static int outputs_map_key_cb(void *params_, const unsigned char *keyVal, size_t keyLen) {
237 struct outputs_json_params *params = (struct outputs_json_params *)params_;
238 FREE(params->cur_key);
239 sasprintf(&(params->cur_key), "%.*s", keyLen, keyVal);
240 return 1;
241 }
242
243 /* A datastructure to pass all these callbacks to yajl */
244 static yajl_callbacks outputs_callbacks = {
245 .yajl_null = outputs_null_cb,
246 .yajl_boolean = outputs_boolean_cb,
247 .yajl_integer = outputs_integer_cb,
248 .yajl_string = outputs_string_cb,
249 .yajl_start_map = outputs_start_map_cb,
250 .yajl_map_key = outputs_map_key_cb,
251 .yajl_end_map = outputs_end_map_cb,
252 };
253
254 struct outputs_head *outputs;
255 /*
256 * Initiate the outputs list
257 *
258 */
259 void init_outputs(void) {
260 outputs = smalloc(sizeof(struct outputs_head));
261 SLIST_INIT(outputs);
262 }
263
264 /*
265 * Start parsing the received JSON string
266 *
267 */
268 void parse_outputs_json(char *json) {
269 struct outputs_json_params params;
270 params.outputs_walk = NULL;
271 params.cur_key = NULL;
272 params.json = json;
273 params.in_rect = false;
274
275 yajl_handle handle;
276 yajl_status state;
277 handle = yajl_alloc(&outputs_callbacks, NULL, (void *)&params);
278
279 state = yajl_parse(handle, (const unsigned char *)json, strlen(json));
280
281 /* FIXME: Proper errorhandling for JSON-parsing */
282 switch (state) {
283 case yajl_status_ok:
284 break;
285 case yajl_status_client_canceled:
286 case yajl_status_error:
287 ELOG("Could not parse outputs reply!\n");
288 exit(EXIT_FAILURE);
289 break;
290 }
291
292 yajl_free(handle);
293 }
294
295 /*
296 * free() all outputs data structures.
297 *
298 */
299 void free_outputs(void) {
300 free_workspaces();
301
302 i3_output *outputs_walk;
303 if (outputs == NULL) {
304 return;
305 }
306 SLIST_FOREACH (outputs_walk, outputs, slist) {
307 destroy_window(outputs_walk);
308 if (outputs_walk->trayclients != NULL && !TAILQ_EMPTY(outputs_walk->trayclients)) {
309 FREE_TAILQ(outputs_walk->trayclients, trayclient);
310 }
311 clear_output(outputs_walk);
312 }
313 FREE_SLIST(outputs, i3_output);
314 }
315
316 /*
317 * Returns the output with the given name
318 *
319 */
320 i3_output *get_output_by_name(char *name) {
321 i3_output *walk;
322 if (name == NULL) {
323 return NULL;
324 }
325 SLIST_FOREACH (walk, outputs, slist) {
326 if (!strcmp(walk->name, name)) {
327 break;
328 }
329 }
330
331 return walk;
332 }
333
334 /*
335 * Returns true if the output has the currently focused workspace
336 *
337 */
338 bool output_has_focus(i3_output *output) {
339 i3_ws *ws_walk;
340 TAILQ_FOREACH (ws_walk, output->workspaces, tailq) {
341 if (ws_walk->focused) {
342 return true;
343 }
344 }
345 return false;
346 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * parse_json_header.c: Parse the JSON protocol header to determine
7 * protocol version and features.
8 *
9 */
10 #include "common.h"
11
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <sys/types.h>
15 #include <sys/wait.h>
16 #include <signal.h>
17 #include <stdio.h>
18 #include <fcntl.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <err.h>
22 #include <ev.h>
23 #include <stdbool.h>
24 #include <stdint.h>
25 #include <yajl/yajl_common.h>
26 #include <yajl/yajl_parse.h>
27 #include <yajl/yajl_version.h>
28
29 static enum {
30 KEY_VERSION,
31 KEY_STOP_SIGNAL,
32 KEY_CONT_SIGNAL,
33 KEY_CLICK_EVENTS,
34 NO_KEY
35 } current_key;
36
37 static int header_integer(void *ctx, long long val) {
38 i3bar_child *child = ctx;
39
40 switch (current_key) {
41 case KEY_VERSION:
42 child->version = val;
43 break;
44 case KEY_STOP_SIGNAL:
45 child->stop_signal = val;
46 break;
47 case KEY_CONT_SIGNAL:
48 child->cont_signal = val;
49 break;
50 default:
51 break;
52 }
53
54 return 1;
55 }
56
57 static int header_boolean(void *ctx, int val) {
58 i3bar_child *child = ctx;
59
60 switch (current_key) {
61 case KEY_CLICK_EVENTS:
62 child->click_events = val;
63 break;
64 default:
65 break;
66 }
67
68 return 1;
69 }
70
71 #define CHECK_KEY(name) (stringlen == strlen(name) && \
72 STARTS_WITH((const char *)stringval, stringlen, name))
73
74 static int header_map_key(void *ctx, const unsigned char *stringval, size_t stringlen) {
75 if (CHECK_KEY("version")) {
76 current_key = KEY_VERSION;
77 } else if (CHECK_KEY("stop_signal")) {
78 current_key = KEY_STOP_SIGNAL;
79 } else if (CHECK_KEY("cont_signal")) {
80 current_key = KEY_CONT_SIGNAL;
81 } else if (CHECK_KEY("click_events")) {
82 current_key = KEY_CLICK_EVENTS;
83 }
84 return 1;
85 }
86
87 static void child_init(i3bar_child *child) {
88 child->version = 0;
89 child->stop_signal = SIGSTOP;
90 child->cont_signal = SIGCONT;
91 }
92
93 /*
94 * Parse the JSON protocol header to determine protocol version and features.
95 * In case the buffer does not contain a valid header (invalid JSON, or no
96 * version field found), the 'correct' field of the returned header is set to
97 * false. The amount of bytes consumed by parsing the header is returned in
98 * *consumed (if non-NULL).
99 *
100 */
101 void parse_json_header(i3bar_child *child, const unsigned char *buffer, int length, unsigned int *consumed) {
102 static yajl_callbacks version_callbacks = {
103 .yajl_boolean = header_boolean,
104 .yajl_integer = header_integer,
105 .yajl_map_key = &header_map_key,
106 };
107
108 child_init(child);
109
110 current_key = NO_KEY;
111
112 yajl_handle handle = yajl_alloc(&version_callbacks, NULL, child);
113 /* Allow trailing garbage. yajl 1 always behaves that way anyways, but for
114 * yajl 2, we need to be explicit. */
115 yajl_config(handle, yajl_allow_trailing_garbage, 1);
116
117 yajl_status state = yajl_parse(handle, buffer, length);
118 if (state != yajl_status_ok) {
119 child_init(child);
120 if (consumed != NULL)
121 *consumed = 0;
122 } else {
123 if (consumed != NULL)
124 *consumed = yajl_get_bytes_consumed(handle);
125 }
126
127 yajl_free(handle);
128 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * workspaces.c: Maintaining the workspace lists
7 *
8 */
9 #include "common.h"
10
11 #include <string.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <errno.h>
15 #include <yajl/yajl_parse.h>
16 #include <yajl/yajl_version.h>
17
18 /* A datatype to pass through the callbacks to save the state */
19 struct workspaces_json_params {
20 struct ws_head *workspaces;
21 i3_ws *workspaces_walk;
22 char *cur_key;
23 char *json;
24 };
25
26 /*
27 * Parse a boolean value (visible, focused, urgent)
28 *
29 */
30 static int workspaces_boolean_cb(void *params_, int val) {
31 struct workspaces_json_params *params = (struct workspaces_json_params *)params_;
32
33 if (!strcmp(params->cur_key, "visible")) {
34 params->workspaces_walk->visible = val;
35 FREE(params->cur_key);
36 return 1;
37 }
38
39 if (!strcmp(params->cur_key, "focused")) {
40 params->workspaces_walk->focused = val;
41 FREE(params->cur_key);
42 return 1;
43 }
44
45 if (!strcmp(params->cur_key, "urgent")) {
46 params->workspaces_walk->urgent = val;
47 FREE(params->cur_key);
48 return 1;
49 }
50
51 FREE(params->cur_key);
52
53 return 0;
54 }
55
56 /*
57 * Parse an integer (num or the rect)
58 *
59 */
60 static int workspaces_integer_cb(void *params_, long long val) {
61 struct workspaces_json_params *params = (struct workspaces_json_params *)params_;
62
63 if (!strcmp(params->cur_key, "id")) {
64 params->workspaces_walk->id = val;
65 FREE(params->cur_key);
66 return 1;
67 }
68
69 if (!strcmp(params->cur_key, "num")) {
70 params->workspaces_walk->num = (int)val;
71 FREE(params->cur_key);
72 return 1;
73 }
74
75 if (!strcmp(params->cur_key, "x")) {
76 params->workspaces_walk->rect.x = (int)val;
77 FREE(params->cur_key);
78 return 1;
79 }
80
81 if (!strcmp(params->cur_key, "y")) {
82 params->workspaces_walk->rect.y = (int)val;
83 FREE(params->cur_key);
84 return 1;
85 }
86
87 if (!strcmp(params->cur_key, "width")) {
88 params->workspaces_walk->rect.w = (int)val;
89 FREE(params->cur_key);
90 return 1;
91 }
92
93 if (!strcmp(params->cur_key, "height")) {
94 params->workspaces_walk->rect.h = (int)val;
95 FREE(params->cur_key);
96 return 1;
97 }
98
99 FREE(params->cur_key);
100 return 0;
101 }
102
103 /*
104 * Parse a string (name, output)
105 *
106 */
107 static int workspaces_string_cb(void *params_, const unsigned char *val, size_t len) {
108 struct workspaces_json_params *params = (struct workspaces_json_params *)params_;
109
110 if (!strcmp(params->cur_key, "name")) {
111 const char *ws_name = (const char *)val;
112 params->workspaces_walk->canonical_name = sstrndup(ws_name, len);
113
114 if ((config.strip_ws_numbers || config.strip_ws_name) && params->workspaces_walk->num >= 0) {
115 /* Special case: strip off the workspace number/name */
116 static char ws_num[32];
117
118 snprintf(ws_num, sizeof(ws_num), "%d", params->workspaces_walk->num);
119
120 /* Calculate the length of the number str in the name */
121 size_t offset = strspn(ws_name, ws_num);
122
123 /* Also strip off the conventional ws name delimiter */
124 if (offset && ws_name[offset] == ':')
125 offset += 1;
126
127 if (config.strip_ws_numbers) {
128 /* Offset may be equal to length, in which case display the number */
129 params->workspaces_walk->name = (offset < len
130 ? i3string_from_markup_with_length(ws_name + offset, len - offset)
131 : i3string_from_markup(ws_num));
132 } else {
133 params->workspaces_walk->name = i3string_from_markup(ws_num);
134 }
135 } else {
136 /* Default case: just save the name */
137 params->workspaces_walk->name = i3string_from_markup_with_length(ws_name, len);
138 }
139
140 /* Save its rendered width */
141 params->workspaces_walk->name_width =
142 predict_text_width(params->workspaces_walk->name);
143
144 DLOG("Got workspace canonical: %s, name: '%s', name_width: %d, glyphs: %zu\n",
145 params->workspaces_walk->canonical_name,
146 i3string_as_utf8(params->workspaces_walk->name),
147 params->workspaces_walk->name_width,
148 i3string_get_num_glyphs(params->workspaces_walk->name));
149 FREE(params->cur_key);
150
151 return 1;
152 }
153
154 if (!strcmp(params->cur_key, "output")) {
155 /* We add the ws to the TAILQ of the output, it belongs to */
156 char *output_name = NULL;
157 sasprintf(&output_name, "%.*s", len, val);
158
159 i3_output *target = get_output_by_name(output_name);
160 if (target != NULL) {
161 params->workspaces_walk->output = target;
162
163 TAILQ_INSERT_TAIL(params->workspaces_walk->output->workspaces,
164 params->workspaces_walk,
165 tailq);
166 }
167
168 FREE(output_name);
169 return 1;
170 }
171
172 return 0;
173 }
174
175 /*
176 * We hit the start of a JSON map (rect or a new output)
177 *
178 */
179 static int workspaces_start_map_cb(void *params_) {
180 struct workspaces_json_params *params = (struct workspaces_json_params *)params_;
181
182 i3_ws *new_workspace = NULL;
183
184 if (params->cur_key == NULL) {
185 new_workspace = smalloc(sizeof(i3_ws));
186 new_workspace->num = -1;
187 new_workspace->name = NULL;
188 new_workspace->visible = 0;
189 new_workspace->focused = 0;
190 new_workspace->urgent = 0;
191 memset(&new_workspace->rect, 0, sizeof(rect));
192 new_workspace->output = NULL;
193
194 params->workspaces_walk = new_workspace;
195 return 1;
196 }
197
198 return 1;
199 }
200
201 /*
202 * Parse a key.
203 *
204 * Essentially we just save it in the parsing state
205 *
206 */
207 static int workspaces_map_key_cb(void *params_, const unsigned char *keyVal, size_t keyLen) {
208 struct workspaces_json_params *params = (struct workspaces_json_params *)params_;
209 FREE(params->cur_key);
210 sasprintf(&(params->cur_key), "%.*s", keyLen, keyVal);
211 return 1;
212 }
213
214 /* A datastructure to pass all these callbacks to yajl */
215 static yajl_callbacks workspaces_callbacks = {
216 .yajl_boolean = workspaces_boolean_cb,
217 .yajl_integer = workspaces_integer_cb,
218 .yajl_string = workspaces_string_cb,
219 .yajl_start_map = workspaces_start_map_cb,
220 .yajl_map_key = workspaces_map_key_cb,
221 };
222
223 /*
224 * Start parsing the received JSON string
225 *
226 */
227 void parse_workspaces_json(char *json) {
228 /* FIXME: Fasciliate stream processing, i.e. allow starting to interpret
229 * JSON in chunks */
230 struct workspaces_json_params params;
231
232 free_workspaces();
233
234 params.workspaces_walk = NULL;
235 params.cur_key = NULL;
236 params.json = json;
237
238 yajl_handle handle;
239 yajl_status state;
240 handle = yajl_alloc(&workspaces_callbacks, NULL, (void *)&params);
241
242 state = yajl_parse(handle, (const unsigned char *)json, strlen(json));
243
244 /* FIXME: Proper error handling for JSON parsing */
245 switch (state) {
246 case yajl_status_ok:
247 break;
248 case yajl_status_client_canceled:
249 case yajl_status_error:
250 ELOG("Could not parse workspaces reply!\n");
251 exit(EXIT_FAILURE);
252 break;
253 }
254
255 yajl_free(handle);
256
257 FREE(params.cur_key);
258 }
259
260 /*
261 * free() all workspace data structures. Does not free() the heads of the tailqueues.
262 *
263 */
264 void free_workspaces(void) {
265 i3_output *outputs_walk;
266 if (outputs == NULL) {
267 return;
268 }
269 i3_ws *ws_walk;
270
271 SLIST_FOREACH (outputs_walk, outputs, slist) {
272 if (outputs_walk->workspaces != NULL && !TAILQ_EMPTY(outputs_walk->workspaces)) {
273 TAILQ_FOREACH (ws_walk, outputs_walk->workspaces, tailq) {
274 I3STRING_FREE(ws_walk->name);
275 FREE(ws_walk->canonical_name);
276 }
277 FREE_TAILQ(outputs_walk->workspaces, i3_ws);
278 }
279 }
280 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3bar - an xcb-based status- and ws-bar for i3
4 * © 2010 Axel Wagner and contributors (see also: LICENSE)
5 *
6 * xcb.c: Communicating with X
7 *
8 */
9 #include "common.h"
10
11 #include <xcb/xcb.h>
12 #include <xcb/xkb.h>
13 #include <xcb/xproto.h>
14 #include <xcb/xcb_aux.h>
15 #include <xcb/xcb_cursor.h>
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <string.h>
22 #include <i3/ipc.h>
23 #include <ev.h>
24 #include <errno.h>
25 #include <limits.h>
26 #include <err.h>
27
28 #include <X11/Xlib.h>
29 #include <X11/XKBlib.h>
30 #include <X11/extensions/XKB.h>
31
32 #ifdef I3_ASAN_ENABLED
33 #include <sanitizer/lsan_interface.h>
34 #endif
35
36 #include "libi3.h"
37
38 /* We save the atoms in an easy to access array, indexed by an enum */
39 enum {
40 #define ATOM_DO(name) name,
41 #include "xcb_atoms.def"
42 NUM_ATOMS
43 };
44
45 xcb_intern_atom_cookie_t atom_cookies[NUM_ATOMS];
46 xcb_atom_t atoms[NUM_ATOMS];
47
48 /* Variables, that are the same for all functions at all times */
49 xcb_connection_t *xcb_connection;
50 int screen;
51 xcb_screen_t *root_screen;
52 xcb_window_t xcb_root;
53 static xcb_cursor_t cursor;
54
55 /* selection window for tray support */
56 static xcb_window_t selwin = XCB_NONE;
57 static xcb_intern_atom_reply_t *tray_reply = NULL;
58
59 /* This is needed for integration with libi3 */
60 xcb_connection_t *conn;
61
62 /* The font we'll use */
63 static i3Font font;
64
65 /* Icon size (based on font size) */
66 int icon_size;
67
68 xcb_visualtype_t *visual_type;
69 uint8_t depth;
70 xcb_colormap_t colormap;
71
72 /* Overall height of the size */
73 int bar_height;
74
75 /* These are only relevant for XKB, which we only need for grabbing modifiers */
76 int xkb_base;
77 bool mod_pressed = 0;
78
79 /* Event watchers, to interact with the user */
80 ev_prepare *xcb_prep;
81 ev_io *xcb_io;
82 ev_io *xkb_io;
83
84 /* The name of current binding mode */
85 static mode binding;
86
87 /* Indicates whether a new binding mode was recently activated */
88 bool activated_mode = false;
89
90 /* The output in which the tray should be displayed. */
91 static i3_output *output_for_tray;
92
93 /* The parsed colors */
94 struct xcb_colors_t {
95 color_t bar_fg;
96 color_t bar_bg;
97 color_t sep_fg;
98 color_t focus_bar_fg;
99 color_t focus_bar_bg;
100 color_t focus_sep_fg;
101 color_t active_ws_fg;
102 color_t active_ws_bg;
103 color_t active_ws_border;
104 color_t inactive_ws_fg;
105 color_t inactive_ws_bg;
106 color_t inactive_ws_border;
107 color_t urgent_ws_bg;
108 color_t urgent_ws_fg;
109 color_t urgent_ws_border;
110 color_t focus_ws_bg;
111 color_t focus_ws_fg;
112 color_t focus_ws_border;
113 color_t binding_mode_bg;
114 color_t binding_mode_fg;
115 color_t binding_mode_border;
116 };
117 struct xcb_colors_t colors;
118
119 /* Horizontal offset between a workspace label and button borders */
120 static const int ws_hoff_px = 4;
121
122 /* Vertical offset between a workspace label and button borders */
123 static const int ws_voff_px = 3;
124
125 /* Offset between two workspace buttons */
126 static const int ws_spacing_px = 1;
127
128 /* Offset between the statusline and 1) workspace buttons on the left
129 * 2) the tray or screen edge on the right */
130 static const int sb_hoff_px = 4;
131
132 /* Additional offset between the tray and the statusline, if the tray is not empty */
133 static const int tray_loff_px = 2;
134
135 /* Vertical offset between the bar and a separator */
136 static const int sep_voff_px = 4;
137
138 /* Cached width of the custom separator if one was set */
139 int separator_symbol_width;
140
141 int _xcb_request_failed(xcb_void_cookie_t cookie, char *err_msg, int line) {
142 xcb_generic_error_t *err;
143 if ((err = xcb_request_check(xcb_connection, cookie)) != NULL) {
144 fprintf(stderr, "[%s:%d] ERROR: %s. X Error Code: %d\n", __FILE__, line, err_msg, err->error_code);
145 return err->error_code;
146 }
147 return 0;
148 }
149
150 static uint32_t get_sep_offset(struct status_block *block) {
151 if (!block->no_separator && block->sep_block_width > 0)
152 return block->sep_block_width / 2 + block->sep_block_width % 2;
153 return 0;
154 }
155
156 static int get_tray_width(struct tc_head *trayclients) {
157 trayclient *trayclient;
158 int tray_width = 0;
159 TAILQ_FOREACH_REVERSE (trayclient, trayclients, tc_head, tailq) {
160 if (!trayclient->mapped)
161 continue;
162 tray_width += icon_size + logical_px(config.tray_padding);
163 }
164 if (tray_width > 0)
165 tray_width += logical_px(tray_loff_px);
166 return tray_width;
167 }
168
169 /*
170 * Draws a separator for the given block if necessary.
171 *
172 */
173 static void draw_separator(i3_output *output, uint32_t x, struct status_block *block, bool use_focus_colors) {
174 color_t sep_fg = (use_focus_colors ? colors.focus_sep_fg : colors.sep_fg);
175 color_t bar_bg = (use_focus_colors ? colors.focus_bar_bg : colors.bar_bg);
176
177 uint32_t sep_offset = get_sep_offset(block);
178 if (TAILQ_NEXT(block, blocks) == NULL || sep_offset == 0)
179 return;
180
181 uint32_t center_x = x - sep_offset;
182 if (config.separator_symbol == NULL) {
183 /* Draw a classic one pixel, vertical separator. */
184 draw_util_rectangle(&output->statusline_buffer, sep_fg,
185 center_x,
186 logical_px(sep_voff_px),
187 logical_px(1),
188 bar_height - 2 * logical_px(sep_voff_px));
189 } else {
190 /* Draw a custom separator. */
191 uint32_t separator_x = MAX(x - block->sep_block_width, center_x - separator_symbol_width / 2);
192 draw_util_text(config.separator_symbol, &output->statusline_buffer, sep_fg, bar_bg,
193 separator_x, bar_height / 2 - font.height / 2, x - separator_x);
194 }
195 }
196
197 static uint32_t predict_statusline_length(bool use_short_text) {
198 uint32_t width = 0;
199 struct status_block *block;
200
201 TAILQ_FOREACH (block, &statusline_head, blocks) {
202 i3String *text = block->full_text;
203 struct status_block_render_desc *render = &block->full_render;
204 if (use_short_text && block->short_text != NULL) {
205 text = block->short_text;
206 render = &block->short_render;
207 }
208
209 if (i3string_get_num_bytes(text) == 0)
210 continue;
211
212 render->width = predict_text_width(text);
213 if (block->border)
214 render->width += logical_px(block->border_left + block->border_right);
215
216 /* Compute offset and append for text aligment in min_width. */
217 if (block->min_width <= render->width) {
218 render->x_offset = 0;
219 render->x_append = 0;
220 } else {
221 uint32_t padding_width = block->min_width - render->width;
222 switch (block->align) {
223 case ALIGN_LEFT:
224 render->x_append = padding_width;
225 break;
226 case ALIGN_RIGHT:
227 render->x_offset = padding_width;
228 break;
229 case ALIGN_CENTER:
230 render->x_offset = padding_width / 2;
231 render->x_append = padding_width / 2 + padding_width % 2;
232 break;
233 }
234 }
235
236 width += render->width + render->x_offset + render->x_append;
237
238 /* If this is not the last block, add some pixels for a separator. */
239 if (TAILQ_NEXT(block, blocks) != NULL)
240 width += block->sep_block_width;
241 }
242
243 return width;
244 }
245
246 /*
247 * Redraws the statusline to the output's statusline_buffer
248 */
249 static void draw_statusline(i3_output *output, uint32_t clip_left, bool use_focus_colors, bool use_short_text) {
250 struct status_block *block;
251
252 color_t bar_color = (use_focus_colors ? colors.focus_bar_bg : colors.bar_bg);
253 draw_util_clear_surface(&output->statusline_buffer, bar_color);
254
255 /* Use unsigned integer wraparound to clip off the left side.
256 * For example, if clip_left is 75, then x will start at the very large
257 * number INT_MAX-75, which is way outside the surface dimensions. Drawing
258 * to that x position is a no-op which XCB and Cairo safely ignore. Once x moves
259 * up by 75 and goes past INT_MAX, it will wrap around again to 0, and we start
260 * actually rendering content to the surface. */
261 uint32_t x = 0 - clip_left;
262
263 /* Draw the text of each block */
264 TAILQ_FOREACH (block, &statusline_head, blocks) {
265 i3String *text = block->full_text;
266 struct status_block_render_desc *render = &block->full_render;
267 if (use_short_text && block->short_text != NULL) {
268 text = block->short_text;
269 render = &block->short_render;
270 }
271
272 if (i3string_get_num_bytes(text) == 0)
273 continue;
274
275 color_t fg_color;
276 if (block->urgent) {
277 fg_color = colors.urgent_ws_fg;
278 } else if (block->color) {
279 fg_color = draw_util_hex_to_color(block->color);
280 } else if (use_focus_colors) {
281 fg_color = colors.focus_bar_fg;
282 } else {
283 fg_color = colors.bar_fg;
284 }
285
286 color_t bg_color = bar_color;
287
288 int full_render_width = render->width + render->x_offset + render->x_append;
289 int has_border = block->border ? 1 : 0;
290 if (block->border || block->background || block->urgent) {
291 /* Let's determine the colors first. */
292 color_t border_color = bar_color;
293 if (block->urgent) {
294 border_color = colors.urgent_ws_border;
295 bg_color = colors.urgent_ws_bg;
296 } else {
297 if (block->border)
298 border_color = draw_util_hex_to_color(block->border);
299 if (block->background)
300 bg_color = draw_util_hex_to_color(block->background);
301 }
302
303 /* Draw the border. */
304 draw_util_rectangle(&output->statusline_buffer, border_color,
305 x, logical_px(1),
306 full_render_width,
307 bar_height - logical_px(2));
308
309 /* Draw the background. */
310 draw_util_rectangle(&output->statusline_buffer, bg_color,
311 x + has_border * logical_px(block->border_left),
312 logical_px(1) + has_border * logical_px(block->border_top),
313 full_render_width - has_border * logical_px(block->border_right + block->border_left),
314 bar_height - has_border * logical_px(block->border_bottom + block->border_top) - logical_px(2));
315 }
316
317 draw_util_text(text, &output->statusline_buffer, fg_color, bg_color,
318 x + render->x_offset + has_border * logical_px(block->border_left),
319 bar_height / 2 - font.height / 2,
320 render->width - has_border * logical_px(block->border_left + block->border_right));
321 x += full_render_width;
322
323 /* If this is not the last block, draw a separator. */
324 if (TAILQ_NEXT(block, blocks) != NULL) {
325 x += block->sep_block_width;
326 draw_separator(output, x, block, use_focus_colors);
327 }
328 }
329 }
330
331 /*
332 * Hides all bars (unmaps them)
333 *
334 */
335 static void hide_bars(void) {
336 if ((config.hide_on_modifier == M_DOCK) || (config.hidden_state == S_SHOW && config.hide_on_modifier == M_HIDE)) {
337 return;
338 }
339
340 i3_output *walk;
341 SLIST_FOREACH (walk, outputs, slist) {
342 if (!walk->active) {
343 continue;
344 }
345 xcb_unmap_window(xcb_connection, walk->bar.id);
346 }
347 stop_child();
348 }
349
350 /*
351 * Unhides all bars (maps them)
352 *
353 */
354 static void unhide_bars(void) {
355 if (config.hide_on_modifier != M_HIDE) {
356 return;
357 }
358
359 i3_output *walk;
360 xcb_void_cookie_t cookie;
361 uint32_t mask;
362 uint32_t values[5];
363
364 cont_child();
365
366 SLIST_FOREACH (walk, outputs, slist) {
367 if (walk->bar.id == XCB_NONE) {
368 continue;
369 }
370 mask = XCB_CONFIG_WINDOW_X |
371 XCB_CONFIG_WINDOW_Y |
372 XCB_CONFIG_WINDOW_WIDTH |
373 XCB_CONFIG_WINDOW_HEIGHT |
374 XCB_CONFIG_WINDOW_STACK_MODE;
375 values[0] = walk->rect.x;
376 if (config.position == POS_TOP)
377 values[1] = walk->rect.y;
378 else
379 values[1] = walk->rect.y + walk->rect.h - bar_height;
380 values[2] = walk->rect.w;
381 values[3] = bar_height;
382 values[4] = XCB_STACK_MODE_ABOVE;
383 DLOG("Reconfiguring window for output %s to %d,%d\n", walk->name, values[0], values[1]);
384 cookie = xcb_configure_window_checked(xcb_connection,
385 walk->bar.id,
386 mask,
387 values);
388
389 if (xcb_request_failed(cookie, "Could not reconfigure window")) {
390 exit(EXIT_FAILURE);
391 }
392 xcb_map_window(xcb_connection, walk->bar.id);
393 }
394 }
395
396 /*
397 * Parse the colors into a format that we can use
398 *
399 */
400 void init_colors(const struct xcb_color_strings_t *new_colors) {
401 #define PARSE_COLOR(name, def) \
402 do { \
403 colors.name = draw_util_hex_to_color(new_colors->name ? new_colors->name : def); \
404 } while (0)
405 PARSE_COLOR(bar_fg, "#FFFFFF");
406 PARSE_COLOR(bar_bg, "#000000");
407 PARSE_COLOR(sep_fg, "#666666");
408 PARSE_COLOR(active_ws_fg, "#FFFFFF");
409 PARSE_COLOR(active_ws_bg, "#333333");
410 PARSE_COLOR(active_ws_border, "#333333");
411 PARSE_COLOR(inactive_ws_fg, "#888888");
412 PARSE_COLOR(inactive_ws_bg, "#222222");
413 PARSE_COLOR(inactive_ws_border, "#333333");
414 PARSE_COLOR(urgent_ws_fg, "#FFFFFF");
415 PARSE_COLOR(urgent_ws_bg, "#900000");
416 PARSE_COLOR(urgent_ws_border, "#2f343a");
417 PARSE_COLOR(focus_ws_fg, "#FFFFFF");
418 PARSE_COLOR(focus_ws_bg, "#285577");
419 PARSE_COLOR(focus_ws_border, "#4c7899");
420 #undef PARSE_COLOR
421
422 #define PARSE_COLOR_FALLBACK(name, fallback) \
423 do { \
424 colors.name = new_colors->name ? draw_util_hex_to_color(new_colors->name) : colors.fallback; \
425 } while (0)
426
427 /* For the binding mode indicator colors, we don't hardcode a default.
428 * Instead, we fall back to urgent_ws_* colors. */
429 PARSE_COLOR_FALLBACK(binding_mode_fg, urgent_ws_fg);
430 PARSE_COLOR_FALLBACK(binding_mode_bg, urgent_ws_bg);
431 PARSE_COLOR_FALLBACK(binding_mode_border, urgent_ws_border);
432
433 /* Similarly, for unspecified focused bar colors, we fall back to the
434 * regular bar colors. */
435 PARSE_COLOR_FALLBACK(focus_bar_fg, bar_fg);
436 PARSE_COLOR_FALLBACK(focus_bar_bg, bar_bg);
437 PARSE_COLOR_FALLBACK(focus_sep_fg, sep_fg);
438 #undef PARSE_COLOR_FALLBACK
439
440 init_tray_colors();
441 xcb_flush(xcb_connection);
442 }
443
444 static bool execute_custom_command(xcb_keycode_t input_code, bool event_is_release) {
445 binding_t *binding;
446 TAILQ_FOREACH (binding, &(config.bindings), bindings) {
447 if ((binding->input_code != input_code) || (binding->release != event_is_release))
448 continue;
449
450 i3_send_msg(I3_IPC_MESSAGE_TYPE_RUN_COMMAND, binding->command);
451 return true;
452 }
453 return false;
454 }
455
456 static void child_handle_button(xcb_button_press_event_t *event, i3_output *output, uint32_t statusline_x) {
457 if (statusline_x > (uint32_t)output->statusline_width) {
458 return;
459 }
460
461 /* x of the start of the current block relative to the statusline. */
462 uint32_t last_block_x = 0;
463 struct status_block *block;
464 TAILQ_FOREACH (block, &statusline_head, blocks) {
465 i3String *text;
466 struct status_block_render_desc *render;
467 if (output->statusline_short_text && block->short_text != NULL) {
468 text = block->short_text;
469 render = &block->short_render;
470 } else {
471 text = block->full_text;
472 render = &block->full_render;
473 }
474
475 if (i3string_get_num_bytes(text) == 0) {
476 continue;
477 }
478
479 /* Include the whole block in our calculations: when min_width is
480 * specified, we have to take padding width into account. */
481 const uint32_t full_render_width = render->width + render->x_offset + render->x_append;
482 /* x of the click event relative to the current block. */
483 const uint32_t relative_x = statusline_x - last_block_x;
484 if (relative_x <= full_render_width) {
485 send_block_clicked(event->detail, block->name, block->instance,
486 event->root_x, event->root_y, relative_x,
487 event->event_y, full_render_width, bar_height,
488 event->state);
489 return;
490 }
491
492 last_block_x += full_render_width + block->sep_block_width;
493 if (last_block_x > statusline_x) {
494 /* Click was on a separator. */
495 return;
496 }
497 }
498 }
499
500 /*
501 * Predict the width of a workspace button or the current binding mode indicator.
502 *
503 */
504 static int predict_button_width(int name_width) {
505 return MAX(name_width + 2 * logical_px(ws_hoff_px) + 2 * logical_px(1),
506 logical_px(config.ws_min_width));
507 }
508
509 /*
510 * Handle a button press event (i.e. a mouse click on one of our bars).
511 * We determine, whether the click occurred on a workspace button or if the scroll-
512 * wheel was used and change the workspace appropriately
513 *
514 */
515 static void handle_button(xcb_button_press_event_t *event) {
516 /* Determine, which bar was clicked */
517 i3_output *walk;
518 xcb_window_t bar = event->event;
519 SLIST_FOREACH (walk, outputs, slist) {
520 if (walk->bar.id == bar) {
521 break;
522 }
523 }
524
525 if (walk == NULL) {
526 DLOG("Unknown bar clicked!\n");
527 return;
528 }
529
530 DLOG("Got button %d\n", event->detail);
531
532 /* During button release events, only check for custom commands. */
533 const bool event_is_release = (event->response_type & ~0x80) == XCB_BUTTON_RELEASE;
534
535 int32_t x = event->event_x >= 0 ? event->event_x : 0;
536 int workspace_width = 0;
537 i3_ws *cur_ws = NULL, *clicked_ws = NULL, *ws_walk;
538
539 TAILQ_FOREACH (ws_walk, walk->workspaces, tailq) {
540 int w = predict_button_width(ws_walk->name_width);
541 if (x >= workspace_width && x <= workspace_width + w)
542 clicked_ws = ws_walk;
543 if (ws_walk->visible)
544 cur_ws = ws_walk;
545 workspace_width += w;
546 if (TAILQ_NEXT(ws_walk, tailq) != NULL)
547 workspace_width += logical_px(ws_spacing_px);
548 }
549
550 if (child_want_click_events() && x > workspace_width) {
551 const int tray_width = get_tray_width(walk->trayclients);
552 /* Calculate the horizontal coordinate (x) of the start of the
553 * statusline by subtracting its width and the width of the tray from
554 * the bar width. */
555 const int offset = walk->rect.w - walk->statusline_width -
556 tray_width - logical_px((tray_width > 0) * sb_hoff_px);
557 if (x >= offset) {
558 /* Click was after the start of the statusline, return to avoid
559 * executing any other actions even if a click event is not
560 * produced eventually. */
561
562 if (!event_is_release) {
563 /* x of the click event relative to the start of the
564 * statusline. */
565 const uint32_t statusline_x = x - offset;
566 child_handle_button(event, walk, statusline_x);
567 }
568
569 return;
570 }
571 }
572
573 /* If a custom command was specified for this mouse button, it overrides
574 * the default behavior. */
575 if (execute_custom_command(event->detail, event_is_release) || event_is_release) {
576 return;
577 }
578
579 if (cur_ws == NULL) {
580 DLOG("No workspace active?\n");
581 return;
582 }
583 switch (event->detail) {
584 case XCB_BUTTON_SCROLL_UP:
585 case XCB_BUTTON_SCROLL_LEFT:
586 /* Mouse wheel up. We select the previous ws, if any.
587 * If there is no more workspace, don’t even send the workspace
588 * command, otherwise (with workspace auto_back_and_forth) we’d end
589 * up on the wrong workspace. */
590 if (cur_ws == TAILQ_FIRST(walk->workspaces))
591 return;
592
593 cur_ws = TAILQ_PREV(cur_ws, ws_head, tailq);
594 break;
595 case XCB_BUTTON_SCROLL_DOWN:
596 case XCB_BUTTON_SCROLL_RIGHT:
597 /* Mouse wheel down. We select the next ws, if any.
598 * If there is no more workspace, don’t even send the workspace
599 * command, otherwise (with workspace auto_back_and_forth) we’d end
600 * up on the wrong workspace. */
601 if (cur_ws == TAILQ_LAST(walk->workspaces, ws_head))
602 return;
603
604 cur_ws = TAILQ_NEXT(cur_ws, tailq);
605 break;
606 case 1:
607 cur_ws = clicked_ws;
608
609 /* if no workspace was clicked, focus our currently visible
610 * workspace if it is not already focused */
611 if (cur_ws == NULL) {
612 TAILQ_FOREACH (cur_ws, walk->workspaces, tailq) {
613 if (cur_ws->visible && !cur_ws->focused)
614 break;
615 }
616 }
617
618 /* if there is nothing to focus, we are done */
619 if (cur_ws == NULL)
620 return;
621
622 break;
623 default:
624 return;
625 }
626
627 /* To properly handle workspace names with double quotes in them, we need
628 * to escape the double quotes. Unfortunately, that’s rather ugly in C: We
629 * first count the number of double quotes, then we allocate a large enough
630 * buffer, then we copy character by character. */
631 int num_quotes = 0;
632 size_t namelen = 0;
633 const char *utf8_name = cur_ws->canonical_name;
634 for (const char *walk = utf8_name; *walk != '\0'; walk++) {
635 if (*walk == '"' || *walk == '\\')
636 num_quotes++;
637 /* While we’re looping through the name anyway, we can save one
638 * strlen(). */
639 namelen++;
640 }
641
642 const size_t len = namelen + strlen("workspace \"\"") + 1;
643 char *buffer = scalloc(len + num_quotes, 1);
644 memcpy(buffer, "workspace \"", strlen("workspace \""));
645 size_t inpos, outpos;
646 for (inpos = 0, outpos = strlen("workspace \"");
647 inpos < namelen;
648 inpos++, outpos++) {
649 if (utf8_name[inpos] == '"' || utf8_name[inpos] == '\\') {
650 buffer[outpos] = '\\';
651 outpos++;
652 }
653 buffer[outpos] = utf8_name[inpos];
654 }
655 buffer[outpos] = '"';
656 i3_send_msg(I3_IPC_MESSAGE_TYPE_RUN_COMMAND, buffer);
657 free(buffer);
658 }
659
660 /*
661 * Handle visibility notifications: when none of the bars are visible, e.g.
662 * if windows are in fullscreen on each output, suspend the child process.
663 *
664 */
665 static void handle_visibility_notify(xcb_visibility_notify_event_t *event) {
666 bool visible = (event->state != XCB_VISIBILITY_FULLY_OBSCURED);
667 int num_visible = 0;
668 i3_output *output;
669
670 SLIST_FOREACH (output, outputs, slist) {
671 if (!output->active) {
672 continue;
673 }
674 if (output->bar.id == event->window) {
675 output->visible = visible;
676 }
677 num_visible += output->visible;
678 }
679
680 if (num_visible == 0) {
681 stop_child();
682 } else {
683 cont_child();
684 }
685 }
686
687 /*
688 * Comparison function to sort trayclients in ascending alphanumeric order
689 * according to their class.
690 *
691 */
692 static int reorder_trayclients_cmp(const void *_a, const void *_b) {
693 trayclient *a = *((trayclient **)_a);
694 trayclient *b = *((trayclient **)_b);
695
696 int result = strcasecmp_nullable(a->class_class, b->class_class);
697 return result != 0 ? result : strcasecmp_nullable(a->class_instance, b->class_instance);
698 }
699
700 /*
701 * Adjusts the size of the tray window and alignment of the tray clients by
702 * configuring their respective x coordinates. To be called when mapping or
703 * unmapping a tray client window.
704 *
705 */
706 static void configure_trayclients(void) {
707 i3_output *output;
708 SLIST_FOREACH (output, outputs, slist) {
709 if (!output->active) {
710 continue;
711 }
712
713 int count = 0;
714 trayclient *client;
715 TAILQ_FOREACH (client, output->trayclients, tailq) {
716 if (client->mapped) {
717 count++;
718 }
719 }
720
721 int idx = 0;
722 trayclient **trayclients = smalloc(count * sizeof(trayclient *));
723 TAILQ_FOREACH (client, output->trayclients, tailq) {
724 if (client->mapped) {
725 trayclients[idx++] = client;
726 }
727 }
728
729 qsort(trayclients, count, sizeof(trayclient *), reorder_trayclients_cmp);
730
731 uint32_t x = output->rect.w;
732 for (idx = count; idx > 0; idx--) {
733 x -= icon_size + logical_px(config.tray_padding);
734
735 DLOG("Configuring tray window %08x to x=%d\n", trayclients[idx - 1]->win, x);
736 xcb_configure_window(xcb_connection,
737 trayclients[idx - 1]->win,
738 XCB_CONFIG_WINDOW_X,
739 &x);
740 }
741
742 free(trayclients);
743 }
744 }
745
746 static trayclient *trayclient_and_output_from_window(xcb_window_t win, i3_output **output) {
747 i3_output *o_walk;
748 SLIST_FOREACH (o_walk, outputs, slist) {
749 if (!o_walk->active) {
750 continue;
751 }
752
753 trayclient *client;
754 TAILQ_FOREACH (client, o_walk->trayclients, tailq) {
755 if (client->win == win) {
756 if (output) {
757 *output = o_walk;
758 }
759 return client;
760 }
761 }
762 }
763 return NULL;
764 }
765
766 static trayclient *trayclient_from_window(xcb_window_t win) {
767 return trayclient_and_output_from_window(win, NULL);
768 }
769
770 static void trayclient_update_class(trayclient *client) {
771 xcb_get_property_reply_t *prop = xcb_get_property_reply(
772 conn,
773 xcb_get_property_unchecked(
774 xcb_connection,
775 false,
776 client->win,
777 XCB_ATOM_WM_CLASS,
778 XCB_ATOM_STRING,
779 0,
780 32),
781 NULL);
782 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
783 DLOG("WM_CLASS not set.\n");
784 free(prop);
785 return;
786 }
787
788 /* We cannot use asprintf here since this property contains two
789 * null-terminated strings (for compatibility reasons). Instead, we
790 * use strdup() on both strings */
791 const size_t prop_length = xcb_get_property_value_length(prop);
792 char *new_class = xcb_get_property_value(prop);
793 const size_t class_class_index = strnlen(new_class, prop_length) + 1;
794
795 free(client->class_instance);
796 free(client->class_class);
797
798 client->class_instance = sstrndup(new_class, prop_length);
799 if (class_class_index < prop_length) {
800 client->class_class = sstrndup(new_class + class_class_index, prop_length - class_class_index);
801 } else {
802 client->class_class = NULL;
803 }
804 DLOG("WM_CLASS changed to %s (instance), %s (class)\n", client->class_instance, client->class_class);
805
806 free(prop);
807 }
808
809 /*
810 * Handles ClientMessages (messages sent from another client directly to us).
811 *
812 * At the moment, only the tray window will receive client messages. All
813 * supported client messages currently are _NET_SYSTEM_TRAY_OPCODE.
814 *
815 */
816 static void handle_client_message(xcb_client_message_event_t *event) {
817 if (event->type == atoms[I3_SYNC]) {
818 xcb_window_t window = event->data.data32[0];
819 uint32_t rnd = event->data.data32[1];
820 /* Forward the request to i3 via the IPC interface so that all pending
821 * IPC messages are guaranteed to be handled. */
822 char *payload = NULL;
823 sasprintf(&payload, "{\"rnd\":%d, \"window\":%d}", rnd, window);
824 i3_send_msg(I3_IPC_MESSAGE_TYPE_SYNC, payload);
825 free(payload);
826 } else if (event->type == atoms[_NET_SYSTEM_TRAY_OPCODE] &&
827 event->format == 32) {
828 DLOG("_NET_SYSTEM_TRAY_OPCODE received\n");
829 /* event->data.data32[0] is the timestamp */
830 uint32_t op = event->data.data32[1];
831 uint32_t mask;
832 uint32_t values[2];
833 if (op == SYSTEM_TRAY_REQUEST_DOCK) {
834 xcb_window_t client = event->data.data32[2];
835
836 mask = XCB_CW_EVENT_MASK;
837
838 /* Needed to get the most recent value of XEMBED_MAPPED. */
839 values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE;
840 /* Needed for UnmapNotify events. */
841 values[0] |= XCB_EVENT_MASK_STRUCTURE_NOTIFY;
842 /* Needed because some tray applications (e.g., VLC) use
843 * override_redirect which causes no ConfigureRequest to be sent. */
844 values[0] |= XCB_EVENT_MASK_RESIZE_REDIRECT;
845
846 xcb_change_window_attributes(xcb_connection, client, mask, values);
847
848 /* Request the _XEMBED_INFO property. The XEMBED specification
849 * (which is referred by the tray specification) says this *has* to
850 * be set, but VLC does not set it… */
851 bool map_it = true;
852 int xe_version = 1;
853 xcb_get_property_cookie_t xembedc;
854 xcb_generic_error_t *error;
855 xembedc = xcb_get_property(xcb_connection,
856 0,
857 client,
858 atoms[_XEMBED_INFO],
859 XCB_GET_PROPERTY_TYPE_ANY,
860 0,
861 2 * 32);
862
863 xcb_get_property_reply_t *xembedr = xcb_get_property_reply(xcb_connection,
864 xembedc,
865 &error);
866 if (error != NULL) {
867 ELOG("Error getting _XEMBED_INFO property: error_code %d\n",
868 error->error_code);
869 free(error);
870 return;
871 }
872 if (xembedr != NULL && xembedr->length != 0) {
873 DLOG("xembed format = %d, len = %d\n", xembedr->format, xembedr->length);
874 uint32_t *xembed = xcb_get_property_value(xembedr);
875 DLOG("xembed version = %d\n", xembed[0]);
876 DLOG("xembed flags = %d\n", xembed[1]);
877 map_it = ((xembed[1] & XEMBED_MAPPED) == XEMBED_MAPPED);
878 xe_version = xembed[0];
879 if (xe_version > 1)
880 xe_version = 1;
881 free(xembedr);
882 } else {
883 ELOG("Window %08x violates the XEMBED protocol, _XEMBED_INFO not set\n", client);
884 }
885
886 DLOG("X window %08x requested docking\n", client);
887
888 if (output_for_tray == NULL) {
889 ELOG("No output found for tray\n");
890 return;
891 }
892
893 xcb_void_cookie_t rcookie = xcb_reparent_window(xcb_connection,
894 client,
895 output_for_tray->bar.id,
896 output_for_tray->rect.w - icon_size - logical_px(config.tray_padding),
897 logical_px(config.tray_padding));
898 if (xcb_request_failed(rcookie, "Could not reparent window. Maybe it is using an incorrect depth/visual?"))
899 return;
900
901 /* We reconfigure the window to use a reasonable size. The systray
902 * specification explicitly says:
903 * Tray icons may be assigned any size by the system tray, and
904 * should do their best to cope with any size effectively
905 */
906 mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT;
907 values[0] = icon_size;
908 values[1] = icon_size;
909 xcb_configure_window(xcb_connection,
910 client,
911 mask,
912 values);
913
914 /* send the XEMBED_EMBEDDED_NOTIFY message */
915 void *event = scalloc(32, 1);
916 xcb_client_message_event_t *ev = event;
917 ev->response_type = XCB_CLIENT_MESSAGE;
918 ev->window = client;
919 ev->type = atoms[_XEMBED];
920 ev->format = 32;
921 ev->data.data32[0] = XCB_CURRENT_TIME;
922 ev->data.data32[1] = XEMBED_EMBEDDED_NOTIFY;
923 ev->data.data32[2] = output_for_tray->bar.id;
924 ev->data.data32[3] = xe_version;
925 xcb_send_event(xcb_connection,
926 0,
927 client,
928 XCB_EVENT_MASK_NO_EVENT,
929 (char *)ev);
930 free(event);
931
932 /* Put the client inside the save set. Upon termination (whether
933 * killed or normal exit does not matter) of i3bar, these clients
934 * will be correctly reparented to their most closest living
935 * ancestor. Without this, tray icons might die when i3bar
936 * exits/crashes. */
937 xcb_change_save_set(xcb_connection, XCB_SET_MODE_INSERT, client);
938
939 trayclient *tc = scalloc(1, sizeof(trayclient));
940 tc->win = client;
941 tc->xe_version = xe_version;
942 tc->mapped = false;
943 TAILQ_INSERT_TAIL(output_for_tray->trayclients, tc, tailq);
944 trayclient_update_class(tc);
945
946 if (map_it) {
947 DLOG("Mapping dock client\n");
948 xcb_map_window(xcb_connection, client);
949 } else {
950 DLOG("Not mapping dock client yet\n");
951 }
952 /* Trigger an update to copy the statusline text to the appropriate
953 * position */
954 configure_trayclients();
955 draw_bars(false);
956 }
957 }
958 }
959
960 /*
961 * Handles DestroyNotify events by removing the tray client from the data
962 * structure. According to the XEmbed protocol, this is one way for a tray
963 * client to finish the protocol. After this event is received, there is no
964 * further interaction with the tray client.
965 *
966 * See: https://standards.freedesktop.org/xembed-spec/xembed-spec-latest.html
967 *
968 */
969 static void handle_destroy_notify(xcb_destroy_notify_event_t *event) {
970 DLOG("DestroyNotify for window = %08x, event = %08x\n", event->window, event->event);
971
972 i3_output *output;
973 trayclient *client = trayclient_and_output_from_window(event->window, &output);
974 if (!client) {
975 DLOG("WARNING: Could not find corresponding tray window.\n");
976 return;
977 }
978
979 DLOG("Removing tray client with window ID %08x\n", event->window);
980 TAILQ_REMOVE(output->trayclients, client, tailq);
981 free(client->class_class);
982 free(client->class_instance);
983 FREE(client);
984
985 /* Trigger an update, we now have more space for the statusline */
986 configure_trayclients();
987 draw_bars(false);
988 }
989
990 /*
991 * Handles MapNotify events. These events happen when a tray client shows its
992 * window. We respond by realigning the tray clients.
993 *
994 */
995 static void handle_map_notify(xcb_map_notify_event_t *event) {
996 DLOG("MapNotify for window = %08x, event = %08x\n", event->window, event->event);
997
998 trayclient *client = trayclient_from_window(event->window);
999 if (!client) {
1000 DLOG("WARNING: Could not find corresponding tray window.\n");
1001 return;
1002 }
1003
1004 DLOG("Tray client mapped (window ID %08x). Adjusting tray.\n", event->window);
1005 client->mapped = true;
1006
1007 /* Trigger an update, we now have one extra tray client. */
1008 configure_trayclients();
1009 draw_bars(false);
1010 }
1011 /*
1012 * Handles UnmapNotify events. These events happen when a tray client hides its
1013 * window. We respond by realigning the tray clients.
1014 *
1015 */
1016 static void handle_unmap_notify(xcb_unmap_notify_event_t *event) {
1017 DLOG("UnmapNotify for window = %08x, event = %08x\n", event->window, event->event);
1018
1019 trayclient *client = trayclient_from_window(event->window);
1020 if (!client) {
1021 DLOG("WARNING: Could not find corresponding tray window.\n");
1022 return;
1023 }
1024
1025 DLOG("Tray client unmapped (window ID %08x). Adjusting tray.\n", event->window);
1026 client->mapped = false;
1027
1028 /* Trigger an update, we now have more space for the statusline */
1029 configure_trayclients();
1030 draw_bars(false);
1031 }
1032
1033 /*
1034 * Handle PropertyNotify messages.
1035 *
1036 */
1037 static void handle_property_notify(xcb_property_notify_event_t *event) {
1038 DLOG("PropertyNotify\n");
1039 if (event->atom == atoms[_XEMBED_INFO] &&
1040 event->state == XCB_PROPERTY_NEW_VALUE) {
1041 /* _XEMBED_INFO property tells us whether a dock client should be mapped or unmapped. */
1042 DLOG("xembed_info updated\n");
1043
1044 trayclient *client = trayclient_from_window(event->window);
1045 if (!client) {
1046 ELOG("PropertyNotify received for unknown window %08x\n", event->window);
1047 return;
1048 }
1049
1050 xcb_get_property_cookie_t xembedc;
1051 xembedc = xcb_get_property_unchecked(xcb_connection,
1052 0,
1053 client->win,
1054 atoms[_XEMBED_INFO],
1055 XCB_GET_PROPERTY_TYPE_ANY,
1056 0,
1057 2 * 32);
1058
1059 xcb_get_property_reply_t *xembedr = xcb_get_property_reply(xcb_connection,
1060 xembedc,
1061 NULL);
1062 if (xembedr == NULL || xembedr->length == 0) {
1063 DLOG("xembed_info unset\n");
1064 return;
1065 }
1066
1067 DLOG("xembed format = %d, len = %d\n", xembedr->format, xembedr->length);
1068 uint32_t *xembed = xcb_get_property_value(xembedr);
1069 DLOG("xembed version = %d\n", xembed[0]);
1070 DLOG("xembed flags = %d\n", xembed[1]);
1071 bool map_it = ((xembed[1] & XEMBED_MAPPED) == XEMBED_MAPPED);
1072 DLOG("map state now %d\n", map_it);
1073 if (client->mapped && !map_it) {
1074 /* need to unmap the window */
1075 xcb_unmap_window(xcb_connection, client->win);
1076 } else if (!client->mapped && map_it) {
1077 /* need to map the window */
1078 xcb_map_window(xcb_connection, client->win);
1079 }
1080 free(xembedr);
1081 } else if (event->atom == XCB_ATOM_WM_CLASS) {
1082 trayclient *client = trayclient_from_window(event->window);
1083 if (client) {
1084 trayclient_update_class(client);
1085 }
1086 }
1087 }
1088
1089 /*
1090 * If a tray client attempts to change its size we deny the request and respond
1091 * by telling it its actual size.
1092 *
1093 */
1094 static void handle_configuration_change(xcb_window_t window) {
1095 trayclient *trayclient;
1096 i3_output *output;
1097 SLIST_FOREACH (output, outputs, slist) {
1098 if (!output->active)
1099 continue;
1100
1101 int clients = 0;
1102 TAILQ_FOREACH_REVERSE (trayclient, output->trayclients, tc_head, tailq) {
1103 if (!trayclient->mapped)
1104 continue;
1105 clients++;
1106
1107 if (trayclient->win != window)
1108 continue;
1109
1110 xcb_rectangle_t rect;
1111 rect.x = output->rect.w - (clients * (icon_size + logical_px(config.tray_padding)));
1112 rect.y = logical_px(config.tray_padding);
1113 rect.width = icon_size;
1114 rect.height = icon_size;
1115
1116 DLOG("This is a tray window. x = %d\n", rect.x);
1117 fake_configure_notify(xcb_connection, rect, window, 0);
1118 return;
1119 }
1120 }
1121
1122 DLOG("WARNING: Could not find corresponding tray window.\n");
1123 }
1124
1125 static void handle_configure_request(xcb_configure_request_event_t *event) {
1126 DLOG("ConfigureRequest for window = %08x\n", event->window);
1127 handle_configuration_change(event->window);
1128 }
1129
1130 static void handle_resize_request(xcb_resize_request_event_t *event) {
1131 DLOG("ResizeRequest for window = %08x\n", event->window);
1132 handle_configuration_change(event->window);
1133 }
1134
1135 /*
1136 * This function is called immediately before the main loop locks. We check for
1137 * events from X11, handle them, then flush our outgoing queue.
1138 *
1139 */
1140 static void xcb_prep_cb(struct ev_loop *loop, ev_prepare *watcher, int revents) {
1141 xcb_generic_event_t *event;
1142
1143 if (xcb_connection_has_error(xcb_connection)) {
1144 ELOG("X11 connection was closed unexpectedly - maybe your X server terminated / crashed?\n");
1145 #ifdef I3_ASAN_ENABLED
1146 __lsan_do_leak_check();
1147 #endif
1148 exit(1);
1149 }
1150
1151 while ((event = xcb_poll_for_event(xcb_connection)) != NULL) {
1152 if (event->response_type == 0) {
1153 xcb_generic_error_t *error = (xcb_generic_error_t *)event;
1154 DLOG("Received X11 error, sequence 0x%x, error_code = %d\n", error->sequence, error->error_code);
1155 free(event);
1156 continue;
1157 }
1158
1159 int type = (event->response_type & ~0x80);
1160
1161 if (type == xkb_base && xkb_base > -1) {
1162 DLOG("received an xkb event\n");
1163
1164 xcb_xkb_state_notify_event_t *state = (xcb_xkb_state_notify_event_t *)event;
1165 const uint32_t mod = (config.modifier & 0xFFFF);
1166 const bool new_mod_pressed = (mod != 0 && (state->mods & mod) == mod);
1167 if (new_mod_pressed != mod_pressed) {
1168 mod_pressed = new_mod_pressed;
1169 if (state->xkbType == XCB_XKB_STATE_NOTIFY && config.modifier != XCB_NONE) {
1170 if (mod_pressed) {
1171 activated_mode = false;
1172 unhide_bars();
1173 } else if (!activated_mode) {
1174 hide_bars();
1175 }
1176 }
1177 }
1178
1179 free(event);
1180 continue;
1181 }
1182
1183 switch (type) {
1184 case XCB_VISIBILITY_NOTIFY:
1185 /* Visibility change: a bar is [un]obscured by other window */
1186 handle_visibility_notify((xcb_visibility_notify_event_t *)event);
1187 break;
1188 case XCB_EXPOSE:
1189 if (((xcb_expose_event_t *)event)->count == 0) {
1190 /* Expose-events happen, when the window needs to be redrawn */
1191 redraw_bars();
1192 }
1193
1194 break;
1195 case XCB_BUTTON_RELEASE:
1196 case XCB_BUTTON_PRESS:
1197 /* Button press events are mouse buttons clicked on one of our bars */
1198 handle_button((xcb_button_press_event_t *)event);
1199 break;
1200 case XCB_CLIENT_MESSAGE:
1201 /* Client messages are used for client-to-client communication, for
1202 * example system tray widgets talk to us directly via client messages. */
1203 handle_client_message((xcb_client_message_event_t *)event);
1204 break;
1205 case XCB_DESTROY_NOTIFY:
1206 /* DestroyNotify signifies the end of the XEmbed protocol */
1207 handle_destroy_notify((xcb_destroy_notify_event_t *)event);
1208 break;
1209 case XCB_UNMAP_NOTIFY:
1210 /* UnmapNotify is received when a tray client hides its window. */
1211 handle_unmap_notify((xcb_unmap_notify_event_t *)event);
1212 break;
1213 case XCB_MAP_NOTIFY:
1214 handle_map_notify((xcb_map_notify_event_t *)event);
1215 break;
1216 case XCB_PROPERTY_NOTIFY:
1217 /* PropertyNotify */
1218 handle_property_notify((xcb_property_notify_event_t *)event);
1219 break;
1220 case XCB_CONFIGURE_REQUEST:
1221 /* ConfigureRequest, sent by a tray child */
1222 handle_configure_request((xcb_configure_request_event_t *)event);
1223 break;
1224 case XCB_RESIZE_REQUEST:
1225 /* ResizeRequest sent by a tray child using override_redirect. */
1226 handle_resize_request((xcb_resize_request_event_t *)event);
1227 break;
1228 }
1229 free(event);
1230 }
1231
1232 xcb_flush(xcb_connection);
1233 }
1234
1235 /*
1236 * Dummy callback. We only need this, so that the prepare and check watchers
1237 * are triggered
1238 *
1239 */
1240 static void xcb_io_cb(struct ev_loop *loop, ev_io *watcher, int revents) {
1241 }
1242
1243 /*
1244 * Early initialization of the connection to X11: Everything which does not
1245 * depend on 'config'.
1246 *
1247 */
1248 char *init_xcb_early(void) {
1249 /* FIXME: xcb_connect leaks memory */
1250 xcb_connection = xcb_connect(NULL, &screen);
1251 if (xcb_connection_has_error(xcb_connection)) {
1252 ELOG("Cannot open display\n");
1253 exit(EXIT_FAILURE);
1254 }
1255 conn = xcb_connection;
1256 DLOG("Connected to xcb\n");
1257
1258 /* We have to request the atoms we need */
1259 #define ATOM_DO(name) atom_cookies[name] = xcb_intern_atom(xcb_connection, 0, strlen(#name), #name);
1260 #include "xcb_atoms.def"
1261
1262 root_screen = xcb_aux_get_screen(xcb_connection, screen);
1263 xcb_root = root_screen->root;
1264
1265 depth = root_screen->root_depth;
1266 colormap = root_screen->default_colormap;
1267 visual_type = config.transparency ? xcb_aux_find_visual_by_attrs(root_screen, -1, 32) : NULL;
1268 if (visual_type != NULL) {
1269 depth = xcb_aux_get_depth_of_visual(root_screen, visual_type->visual_id);
1270 colormap = xcb_generate_id(xcb_connection);
1271 xcb_void_cookie_t cm_cookie = xcb_create_colormap_checked(xcb_connection,
1272 XCB_COLORMAP_ALLOC_NONE,
1273 colormap,
1274 xcb_root,
1275 visual_type->visual_id);
1276 if (xcb_request_failed(cm_cookie, "Could not allocate colormap")) {
1277 exit(EXIT_FAILURE);
1278 }
1279 } else {
1280 visual_type = get_visualtype(root_screen);
1281 }
1282
1283 xcb_cursor_context_t *cursor_ctx;
1284 if (xcb_cursor_context_new(conn, root_screen, &cursor_ctx) < 0) {
1285 errx(EXIT_FAILURE, "Cannot allocate xcursor context");
1286 }
1287 cursor = xcb_cursor_load_cursor(cursor_ctx, "left_ptr");
1288 xcb_cursor_context_free(cursor_ctx);
1289
1290 /* The various watchers to communicate with xcb */
1291 xcb_io = smalloc(sizeof(ev_io));
1292 xcb_prep = smalloc(sizeof(ev_prepare));
1293
1294 ev_io_init(xcb_io, &xcb_io_cb, xcb_get_file_descriptor(xcb_connection), EV_READ);
1295 ev_prepare_init(xcb_prep, &xcb_prep_cb);
1296
1297 ev_io_start(main_loop, xcb_io);
1298 ev_prepare_start(main_loop, xcb_prep);
1299
1300 /* Now we get the atoms and save them in a nice data structure */
1301 get_atoms();
1302
1303 char *path = root_atom_contents("I3_SOCKET_PATH", xcb_connection, screen);
1304
1305 return path;
1306 }
1307
1308 /*
1309 * Register for xkb keyevents. To grab modifiers without blocking other applications from receiving key events
1310 * involving that modifier, we sadly have to use xkb which is not yet fully supported
1311 * in xcb.
1312 *
1313 */
1314 static void register_xkb_keyevents(void) {
1315 const xcb_query_extension_reply_t *extreply;
1316 extreply = xcb_get_extension_data(conn, &xcb_xkb_id);
1317 if (!extreply->present) {
1318 ELOG("xkb is not present on this server\n");
1319 exit(EXIT_FAILURE);
1320 }
1321 DLOG("initializing xcb-xkb\n");
1322 xcb_xkb_use_extension(conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION);
1323 xcb_xkb_select_events(conn,
1324 XCB_XKB_ID_USE_CORE_KBD,
1325 XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
1326 0,
1327 XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
1328 0xff,
1329 0xff,
1330 NULL);
1331 xkb_base = extreply->first_event;
1332 }
1333
1334 /*
1335 * Deregister from xkb keyevents.
1336 *
1337 */
1338 static void deregister_xkb_keyevents(void) {
1339 xcb_xkb_select_events(conn,
1340 XCB_XKB_ID_USE_CORE_KBD,
1341 0,
1342 0,
1343 0,
1344 0xff,
1345 0xff,
1346 NULL);
1347 }
1348
1349 /*
1350 * Initialization which depends on 'config' being usable. Called after the
1351 * configuration has arrived.
1352 *
1353 */
1354 void init_xcb_late(char *fontname) {
1355 if (fontname == NULL)
1356 fontname = "-misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1";
1357
1358 /* Load the font */
1359 font = load_font(fontname, true);
1360 set_font(&font);
1361 DLOG("Calculated font-height: %d\n", font.height);
1362
1363 /*
1364 * If the bar height was explicitly set, use it. Otherwise, calculate it
1365 * based on the font size.
1366 */
1367 if (config.bar_height <= 0)
1368 bar_height = font.height + 2 * logical_px(ws_voff_px);
1369 else
1370 bar_height = config.bar_height;
1371 icon_size = bar_height - 2 * logical_px(config.tray_padding);
1372
1373 if (config.separator_symbol)
1374 separator_symbol_width = predict_text_width(config.separator_symbol);
1375
1376 xcb_flush(xcb_connection);
1377
1378 if (config.hide_on_modifier == M_HIDE)
1379 register_xkb_keyevents();
1380 }
1381
1382 /*
1383 * Inform clients waiting for a new _NET_SYSTEM_TRAY that we took the
1384 * selection.
1385 *
1386 */
1387 static void send_tray_clientmessage(void) {
1388 uint8_t buffer[32] = {0};
1389 xcb_client_message_event_t *ev = (xcb_client_message_event_t *)buffer;
1390
1391 ev->response_type = XCB_CLIENT_MESSAGE;
1392 ev->window = xcb_root;
1393 ev->type = atoms[MANAGER];
1394 ev->format = 32;
1395 ev->data.data32[0] = XCB_CURRENT_TIME;
1396 ev->data.data32[1] = tray_reply->atom;
1397 ev->data.data32[2] = selwin;
1398
1399 xcb_send_event(xcb_connection,
1400 0,
1401 xcb_root,
1402 0xFFFFFF,
1403 (char *)buffer);
1404 }
1405
1406 /*
1407 * Initializes tray support by requesting the appropriate _NET_SYSTEM_TRAY atom
1408 * for the X11 display we are running on, then acquiring the selection for this
1409 * atom. Afterwards, tray clients will send ClientMessages to our window.
1410 *
1411 */
1412 static void init_tray(void) {
1413 DLOG("Initializing system tray functionality\n");
1414 /* request the tray manager atom for the X11 display we are running on */
1415 char atomname[strlen("_NET_SYSTEM_TRAY_S") + 11];
1416 snprintf(atomname, strlen("_NET_SYSTEM_TRAY_S") + 11, "_NET_SYSTEM_TRAY_S%d", screen);
1417 xcb_intern_atom_cookie_t tray_cookie;
1418 if (tray_reply == NULL)
1419 tray_cookie = xcb_intern_atom(xcb_connection, 0, strlen(atomname), atomname);
1420
1421 /* tray support: we need a window to own the selection */
1422 selwin = xcb_generate_id(xcb_connection);
1423 uint32_t selmask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_COLORMAP;
1424 uint32_t selval[] = {root_screen->black_pixel, root_screen->black_pixel, 1, colormap};
1425 xcb_create_window(xcb_connection,
1426 depth,
1427 selwin,
1428 xcb_root,
1429 -1, -1,
1430 1, 1,
1431 0,
1432 XCB_WINDOW_CLASS_INPUT_OUTPUT,
1433 visual_type->visual_id,
1434 selmask,
1435 selval);
1436
1437 uint32_t orientation = _NET_SYSTEM_TRAY_ORIENTATION_HORZ;
1438 /* set the atoms */
1439 xcb_change_property(xcb_connection,
1440 XCB_PROP_MODE_REPLACE,
1441 selwin,
1442 atoms[_NET_SYSTEM_TRAY_ORIENTATION],
1443 XCB_ATOM_CARDINAL,
1444 32,
1445 1,
1446 &orientation);
1447 xcb_change_property(xcb_connection,
1448 XCB_PROP_MODE_REPLACE,
1449 selwin,
1450 atoms[_NET_SYSTEM_TRAY_VISUAL],
1451 XCB_ATOM_VISUALID,
1452 32,
1453 1,
1454 &visual_type->visual_id);
1455
1456 init_tray_colors();
1457
1458 if (tray_reply == NULL) {
1459 if (!(tray_reply = xcb_intern_atom_reply(xcb_connection, tray_cookie, NULL))) {
1460 ELOG("Could not get atom %s\n", atomname);
1461 exit(EXIT_FAILURE);
1462 }
1463 }
1464
1465 xcb_set_selection_owner(xcb_connection,
1466 selwin,
1467 tray_reply->atom,
1468 XCB_CURRENT_TIME);
1469
1470 /* Verify that we have the selection */
1471 xcb_get_selection_owner_cookie_t selcookie;
1472 xcb_get_selection_owner_reply_t *selreply;
1473
1474 selcookie = xcb_get_selection_owner(xcb_connection, tray_reply->atom);
1475 if (!(selreply = xcb_get_selection_owner_reply(xcb_connection, selcookie, NULL))) {
1476 ELOG("Could not get selection owner for %s\n", atomname);
1477 exit(EXIT_FAILURE);
1478 }
1479
1480 if (selreply->owner != selwin) {
1481 ELOG("Could not set the %s selection. "
1482 "Maybe another tray is already running?\n",
1483 atomname);
1484 /* NOTE that this error is not fatal. We just can’t provide tray
1485 * functionality */
1486 free(selreply);
1487 return;
1488 }
1489
1490 free(selreply);
1491
1492 send_tray_clientmessage();
1493 }
1494
1495 /*
1496 * We need to set the _NET_SYSTEM_TRAY_COLORS atom on the tray selection window
1497 * to make GTK+ 3 applets with symbolic icons visible. If the colors are unset,
1498 * they assume a light background.
1499 * See also https://bugzilla.gnome.org/show_bug.cgi?id=679591
1500 *
1501 */
1502 void init_tray_colors(void) {
1503 /* Convert colors.bar_fg (#rrggbb) to 16-bit RGB */
1504 const char *bar_fg = (config.colors.bar_fg ? config.colors.bar_fg : "#FFFFFF");
1505
1506 DLOG("Setting bar_fg = %s as _NET_SYSTEM_TRAY_COLORS\n", bar_fg);
1507
1508 char strgroups[3][3] = {{bar_fg[1], bar_fg[2], '\0'},
1509 {bar_fg[3], bar_fg[4], '\0'},
1510 {bar_fg[5], bar_fg[6], '\0'}};
1511 const uint8_t r = strtol(strgroups[0], NULL, 16);
1512 const uint8_t g = strtol(strgroups[1], NULL, 16);
1513 const uint8_t b = strtol(strgroups[2], NULL, 16);
1514
1515 const uint16_t r16 = ((uint16_t)r << 8) | r;
1516 const uint16_t g16 = ((uint16_t)g << 8) | g;
1517 const uint16_t b16 = ((uint16_t)b << 8) | b;
1518
1519 const uint32_t tray_colors[12] = {
1520 r16, g16, b16, /* foreground color */
1521 r16, g16, b16, /* error color */
1522 r16, g16, b16, /* warning color */
1523 r16, g16, b16, /* success color */
1524 };
1525
1526 xcb_change_property(xcb_connection,
1527 XCB_PROP_MODE_REPLACE,
1528 selwin,
1529 atoms[_NET_SYSTEM_TRAY_COLORS],
1530 XCB_ATOM_CARDINAL,
1531 32,
1532 12,
1533 tray_colors);
1534 }
1535
1536 /*
1537 * Cleanup the xcb stuff.
1538 * Called once, before the program terminates.
1539 *
1540 */
1541 void clean_xcb(void) {
1542 free_outputs();
1543
1544 free_font();
1545
1546 xcb_free_cursor(xcb_connection, cursor);
1547 xcb_flush(xcb_connection);
1548 xcb_aux_sync(xcb_connection);
1549 xcb_disconnect(xcb_connection);
1550
1551 ev_prepare_stop(main_loop, xcb_prep);
1552 ev_io_stop(main_loop, xcb_io);
1553
1554 FREE(xcb_prep);
1555 FREE(xcb_io);
1556 }
1557
1558 /*
1559 * Get the earlier requested atoms and save them in the prepared data structure
1560 *
1561 */
1562 void get_atoms(void) {
1563 xcb_intern_atom_reply_t *reply;
1564 #define ATOM_DO(name) \
1565 reply = xcb_intern_atom_reply(xcb_connection, atom_cookies[name], NULL); \
1566 if (reply == NULL) { \
1567 ELOG("Could not get atom %s\n", #name); \
1568 exit(EXIT_FAILURE); \
1569 } \
1570 atoms[name] = reply->atom; \
1571 free(reply);
1572
1573 #include "xcb_atoms.def"
1574 DLOG("Got atoms\n");
1575 }
1576
1577 /*
1578 * Reparents all tray clients of the specified output to the root window. This
1579 * is either used when shutting down, when an output appears (xrandr --output
1580 * VGA1 --off) or when the primary output changes.
1581 *
1582 * Applications using the tray will start the protocol from the beginning again
1583 * afterwards.
1584 *
1585 */
1586 void kick_tray_clients(i3_output *output) {
1587 if (TAILQ_EMPTY(output->trayclients))
1588 return;
1589
1590 trayclient *trayclient;
1591 while (!TAILQ_EMPTY(output->trayclients)) {
1592 trayclient = TAILQ_FIRST(output->trayclients);
1593 /* Unmap, then reparent (to root) the tray client windows */
1594 xcb_unmap_window(xcb_connection, trayclient->win);
1595 xcb_reparent_window(xcb_connection,
1596 trayclient->win,
1597 xcb_root,
1598 0,
1599 0);
1600
1601 free(trayclient->class_class);
1602 free(trayclient->class_instance);
1603
1604 /* We remove the trayclient right here. We might receive an UnmapNotify
1605 * event afterwards, but better safe than sorry. */
1606 TAILQ_REMOVE(output->trayclients, trayclient, tailq);
1607 FREE(trayclient);
1608 }
1609
1610 /* Fake a DestroyNotify so that Qt re-adds tray icons.
1611 * We cannot actually destroy the window because then Qt will not restore
1612 * its event mask on the new window. */
1613 uint8_t buffer[32] = {0};
1614 xcb_destroy_notify_event_t *event = (xcb_destroy_notify_event_t *)buffer;
1615
1616 event->response_type = XCB_DESTROY_NOTIFY;
1617 event->event = selwin;
1618 event->window = selwin;
1619
1620 xcb_send_event(conn, false, selwin, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (char *)event);
1621
1622 send_tray_clientmessage();
1623 }
1624
1625 /*
1626 * Destroy the bar of the specified output
1627 *
1628 */
1629 void destroy_window(i3_output *output) {
1630 if (output == NULL) {
1631 return;
1632 }
1633 if (output->bar.id == XCB_NONE) {
1634 return;
1635 }
1636
1637 kick_tray_clients(output);
1638 xcb_destroy_window(xcb_connection, output->bar.id);
1639 output->bar.id = XCB_NONE;
1640 }
1641
1642 /* Strut partial tells i3 where to reserve space for i3bar. This is determined
1643 * by the `position` bar config directive. */
1644 static xcb_void_cookie_t config_strut_partial(i3_output *output) {
1645 /* A local struct to save the strut_partial property */
1646 struct {
1647 uint32_t left;
1648 uint32_t right;
1649 uint32_t top;
1650 uint32_t bottom;
1651 uint32_t left_start_y;
1652 uint32_t left_end_y;
1653 uint32_t right_start_y;
1654 uint32_t right_end_y;
1655 uint32_t top_start_x;
1656 uint32_t top_end_x;
1657 uint32_t bottom_start_x;
1658 uint32_t bottom_end_x;
1659 } __attribute__((__packed__)) strut_partial;
1660 memset(&strut_partial, 0, sizeof(strut_partial));
1661
1662 switch (config.position) {
1663 case POS_NONE:
1664 break;
1665 case POS_TOP:
1666 strut_partial.top = bar_height;
1667 strut_partial.top_start_x = output->rect.x;
1668 strut_partial.top_end_x = output->rect.x + output->rect.w;
1669 break;
1670 case POS_BOT:
1671 strut_partial.bottom = bar_height;
1672 strut_partial.bottom_start_x = output->rect.x;
1673 strut_partial.bottom_end_x = output->rect.x + output->rect.w;
1674 break;
1675 }
1676 return xcb_change_property(xcb_connection,
1677 XCB_PROP_MODE_REPLACE,
1678 output->bar.id,
1679 atoms[_NET_WM_STRUT_PARTIAL],
1680 XCB_ATOM_CARDINAL,
1681 32,
1682 12,
1683 &strut_partial);
1684 }
1685
1686 /*
1687 * Returns the output which should hold the tray, if one exists.
1688 *
1689 * An output is returned in these scenarios:
1690 * 1. A specific output was listed in tray_outputs which is also in the list
1691 * of outputs managed by this bar.
1692 * 2. No tray_output directive was specified. In this case, we use the first
1693 * available output.
1694 * 3. 'tray_output primary' was specified. In this case we use the primary
1695 * output.
1696 *
1697 * Three scenarios in which we specifically don't want to use a tray:
1698 * 1. 'tray_output none' was specified.
1699 * 2. A specific output was listed as a tray_output, but is not one of the
1700 * outputs managed by this bar. For example, consider tray_outputs == [VGA-1],
1701 * but outputs == [HDMI-1].
1702 * 3. 'tray_output primary' was specified and no output in the list is
1703 * primary.
1704 */
1705 static i3_output *get_tray_output(void) {
1706 i3_output *output = NULL;
1707 if (TAILQ_EMPTY(&(config.tray_outputs))) {
1708 /* No tray_output specified, use first active output. */
1709 SLIST_FOREACH (output, outputs, slist) {
1710 if (output->active) {
1711 return output;
1712 }
1713 }
1714 return NULL;
1715 } else if (strcasecmp(TAILQ_FIRST(&(config.tray_outputs))->output, "none") == 0) {
1716 /* Check for "tray_output none" */
1717 return NULL;
1718 }
1719
1720 /* If one or more tray_output assignments were specified, we ensure that at
1721 * least one of them is actually an output managed by this instance. */
1722 tray_output_t *tray_output;
1723 TAILQ_FOREACH (tray_output, &(config.tray_outputs), tray_outputs) {
1724 SLIST_FOREACH (output, outputs, slist) {
1725 if (output->active &&
1726 (strcasecmp(output->name, tray_output->output) == 0 ||
1727 (strcasecmp(tray_output->output, "primary") == 0 && output->primary))) {
1728 return output;
1729 }
1730 }
1731 }
1732
1733 return NULL;
1734 }
1735
1736 /*
1737 * Reconfigure all bars and create new bars for recently activated outputs
1738 *
1739 */
1740 void reconfig_windows(bool redraw_bars) {
1741 uint32_t mask;
1742 uint32_t values[6];
1743
1744 i3_output *walk;
1745 SLIST_FOREACH (walk, outputs, slist) {
1746 if (!walk->active) {
1747 /* If an output is not active, we destroy its bar */
1748 /* FIXME: Maybe we rather want to unmap? */
1749 DLOG("Destroying window for output %s\n", walk->name);
1750 destroy_window(walk);
1751 continue;
1752 }
1753 if (walk->bar.id == XCB_NONE) {
1754 DLOG("Creating window for output %s\n", walk->name);
1755
1756 xcb_window_t bar_id = xcb_generate_id(xcb_connection);
1757 xcb_pixmap_t buffer_id = xcb_generate_id(xcb_connection);
1758 xcb_pixmap_t statusline_buffer_id = xcb_generate_id(xcb_connection);
1759 mask = XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK | XCB_CW_COLORMAP | XCB_CW_CURSOR;
1760
1761 values[0] = colors.bar_bg.colorpixel;
1762 values[1] = root_screen->black_pixel;
1763 /* If hide_on_modifier is set to hide or invisible mode, i3 is not supposed to manage our bar windows */
1764 values[2] = (config.hide_on_modifier == M_DOCK ? 0 : 1);
1765 /* We enable the following EventMask fields:
1766 * EXPOSURE, to get expose events (we have to re-draw then)
1767 * SUBSTRUCTURE_REDIRECT, to get ConfigureRequests when the tray
1768 * child windows use ConfigureWindow
1769 * BUTTON_PRESS, to handle clicks on the workspace buttons
1770 * */
1771 values[3] = XCB_EVENT_MASK_EXPOSURE |
1772 XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
1773 XCB_EVENT_MASK_BUTTON_PRESS |
1774 XCB_EVENT_MASK_BUTTON_RELEASE;
1775 if (config.hide_on_modifier == M_DOCK) {
1776 /* If the bar is normally visible, catch visibility change events to suspend
1777 * the status process when the bar is obscured by full-screened windows. */
1778 values[3] |= XCB_EVENT_MASK_VISIBILITY_CHANGE;
1779 walk->visible = true;
1780 }
1781 values[4] = colormap;
1782 values[5] = cursor;
1783
1784 xcb_void_cookie_t win_cookie = xcb_create_window_checked(xcb_connection,
1785 depth,
1786 bar_id,
1787 xcb_root,
1788 walk->rect.x, walk->rect.y + walk->rect.h - bar_height,
1789 walk->rect.w, bar_height,
1790 0,
1791 XCB_WINDOW_CLASS_INPUT_OUTPUT,
1792 visual_type->visual_id,
1793 mask,
1794 values);
1795
1796 /* The double-buffer we use to render stuff off-screen */
1797 xcb_void_cookie_t pm_cookie = xcb_create_pixmap_checked(xcb_connection,
1798 depth,
1799 buffer_id,
1800 bar_id,
1801 walk->rect.w,
1802 bar_height);
1803
1804 /* The double-buffer we use to render the statusline before copying to buffer */
1805 xcb_void_cookie_t slpm_cookie = xcb_create_pixmap_checked(xcb_connection,
1806 depth,
1807 statusline_buffer_id,
1808 bar_id,
1809 walk->rect.w,
1810 bar_height);
1811
1812 /* Set the WM_CLASS and WM_NAME (we don't need UTF-8) atoms */
1813 char *class;
1814 int len = sasprintf(&class, "%s%ci3bar%c", config.bar_id, 0, 0);
1815 xcb_void_cookie_t class_cookie;
1816 class_cookie = xcb_change_property(xcb_connection,
1817 XCB_PROP_MODE_REPLACE,
1818 bar_id,
1819 XCB_ATOM_WM_CLASS,
1820 XCB_ATOM_STRING,
1821 8,
1822 len,
1823 class);
1824
1825 char *name;
1826 sasprintf(&name, "i3bar for output %s", walk->name);
1827 xcb_void_cookie_t name_cookie;
1828 name_cookie = xcb_change_property(xcb_connection,
1829 XCB_PROP_MODE_REPLACE,
1830 bar_id,
1831 XCB_ATOM_WM_NAME,
1832 XCB_ATOM_STRING,
1833 8,
1834 strlen(name),
1835 name);
1836 free(name);
1837
1838 /* We want dock windows (for now). When override_redirect is set, i3 is ignoring
1839 * this one */
1840 xcb_void_cookie_t dock_cookie = xcb_change_property(xcb_connection,
1841 XCB_PROP_MODE_REPLACE,
1842 bar_id,
1843 atoms[_NET_WM_WINDOW_TYPE],
1844 XCB_ATOM_ATOM,
1845 32,
1846 1,
1847 (unsigned char *)&atoms[_NET_WM_WINDOW_TYPE_DOCK]);
1848
1849 draw_util_surface_init(xcb_connection, &walk->bar, bar_id, NULL, walk->rect.w, bar_height);
1850 draw_util_surface_init(xcb_connection, &walk->buffer, buffer_id, NULL, walk->rect.w, bar_height);
1851 draw_util_surface_init(xcb_connection, &walk->statusline_buffer, statusline_buffer_id, NULL, walk->rect.w, bar_height);
1852
1853 xcb_void_cookie_t strut_cookie = config_strut_partial(walk);
1854
1855 /* We finally map the bar (display it on screen), unless the modifier-switch is on */
1856 xcb_void_cookie_t map_cookie;
1857 if (config.hide_on_modifier == M_DOCK) {
1858 map_cookie = xcb_map_window_checked(xcb_connection, bar_id);
1859 }
1860
1861 if (xcb_request_failed(win_cookie, "Could not create window") ||
1862 xcb_request_failed(pm_cookie, "Could not create pixmap") ||
1863 xcb_request_failed(slpm_cookie, "Could not create statusline pixmap") ||
1864 xcb_request_failed(dock_cookie, "Could not set dock mode") ||
1865 xcb_request_failed(class_cookie, "Could not set WM_CLASS") ||
1866 xcb_request_failed(name_cookie, "Could not set WM_NAME") ||
1867 xcb_request_failed(strut_cookie, "Could not set strut") ||
1868 ((config.hide_on_modifier == M_DOCK) && xcb_request_failed(map_cookie, "Could not map window"))) {
1869 exit(EXIT_FAILURE);
1870 }
1871
1872 } else {
1873 /* We already have a bar, so we just reconfigure it */
1874 mask = XCB_CONFIG_WINDOW_X |
1875 XCB_CONFIG_WINDOW_Y |
1876 XCB_CONFIG_WINDOW_WIDTH |
1877 XCB_CONFIG_WINDOW_HEIGHT |
1878 XCB_CONFIG_WINDOW_STACK_MODE;
1879 values[0] = walk->rect.x;
1880 if (config.position == POS_TOP)
1881 values[1] = walk->rect.y;
1882 else
1883 values[1] = walk->rect.y + walk->rect.h - bar_height;
1884 values[2] = walk->rect.w;
1885 values[3] = bar_height;
1886 values[4] = XCB_STACK_MODE_ABOVE;
1887
1888 DLOG("Reconfiguring strut partial property for output %s\n", walk->name);
1889 xcb_void_cookie_t strut_cookie = config_strut_partial(walk);
1890
1891 DLOG("Destroying buffer for output %s\n", walk->name);
1892 xcb_free_pixmap(xcb_connection, walk->buffer.id);
1893
1894 DLOG("Destroying statusline buffer for output %s\n", walk->name);
1895 xcb_free_pixmap(xcb_connection, walk->statusline_buffer.id);
1896
1897 DLOG("Reconfiguring window for output %s to %d,%d\n", walk->name, values[0], values[1]);
1898 xcb_void_cookie_t cfg_cookie = xcb_configure_window_checked(xcb_connection,
1899 walk->bar.id,
1900 mask,
1901 values);
1902
1903 mask = XCB_CW_OVERRIDE_REDIRECT;
1904 values[0] = (config.hide_on_modifier == M_DOCK ? 0 : 1);
1905 DLOG("Changing window attribute override_redirect for output %s to %d\n", walk->name, values[0]);
1906 xcb_void_cookie_t chg_cookie = xcb_change_window_attributes(xcb_connection,
1907 walk->bar.id,
1908 mask,
1909 values);
1910
1911 DLOG("Recreating buffer for output %s\n", walk->name);
1912 xcb_void_cookie_t pm_cookie = xcb_create_pixmap_checked(xcb_connection,
1913 depth,
1914 walk->buffer.id,
1915 walk->bar.id,
1916 walk->rect.w,
1917 bar_height);
1918
1919 DLOG("Recreating statusline buffer for output %s\n", walk->name);
1920 xcb_void_cookie_t slpm_cookie = xcb_create_pixmap_checked(xcb_connection,
1921 depth,
1922 walk->statusline_buffer.id,
1923 walk->bar.id,
1924 walk->rect.w,
1925 bar_height);
1926
1927 draw_util_surface_free(xcb_connection, &(walk->bar));
1928 draw_util_surface_free(xcb_connection, &(walk->buffer));
1929 draw_util_surface_free(xcb_connection, &(walk->statusline_buffer));
1930 draw_util_surface_init(xcb_connection, &(walk->bar), walk->bar.id, NULL, walk->rect.w, bar_height);
1931 draw_util_surface_init(xcb_connection, &(walk->buffer), walk->buffer.id, NULL, walk->rect.w, bar_height);
1932 draw_util_surface_init(xcb_connection, &(walk->statusline_buffer), walk->statusline_buffer.id, NULL, walk->rect.w, bar_height);
1933
1934 xcb_void_cookie_t map_cookie, umap_cookie;
1935 if (redraw_bars) {
1936 /* Unmap the window, and draw it again when in dock mode */
1937 umap_cookie = xcb_unmap_window_checked(xcb_connection, walk->bar.id);
1938 if (config.hide_on_modifier == M_DOCK) {
1939 cont_child();
1940 map_cookie = xcb_map_window_checked(xcb_connection, walk->bar.id);
1941 } else {
1942 stop_child();
1943 }
1944
1945 if (config.hide_on_modifier == M_HIDE) {
1946 /* Switching to hide mode, register for keyevents */
1947 register_xkb_keyevents();
1948 } else {
1949 /* Switching to dock/invisible mode, deregister from keyevents */
1950 deregister_xkb_keyevents();
1951 }
1952 }
1953
1954 if (xcb_request_failed(cfg_cookie, "Could not reconfigure window") ||
1955 xcb_request_failed(chg_cookie, "Could not change window") ||
1956 xcb_request_failed(pm_cookie, "Could not create pixmap") ||
1957 xcb_request_failed(slpm_cookie, "Could not create statusline pixmap") ||
1958 xcb_request_failed(strut_cookie, "Could not set strut") ||
1959 (redraw_bars && (xcb_request_failed(umap_cookie, "Could not unmap window") ||
1960 (config.hide_on_modifier == M_DOCK && xcb_request_failed(map_cookie, "Could not map window"))))) {
1961 exit(EXIT_FAILURE);
1962 }
1963 }
1964 }
1965
1966 /* Finally, check if we want to initialize the tray or destroy the selection
1967 * window. The result of get_tray_output() is cached. */
1968 output_for_tray = get_tray_output();
1969 if (output_for_tray) {
1970 if (selwin == XCB_NONE) {
1971 init_tray();
1972 }
1973 } else if (selwin != XCB_NONE) {
1974 DLOG("Destroying tray selection window\n");
1975 xcb_destroy_window(xcb_connection, selwin);
1976 selwin = XCB_NONE;
1977 }
1978 }
1979
1980 /*
1981 * Draw the button for a workspace or the current binding mode indicator.
1982 *
1983 */
1984 static void draw_button(surface_t *surface, color_t fg_color, color_t bg_color, color_t border_color,
1985 int x, int width, int text_width, i3String *text) {
1986 int height = bar_height - 2 * logical_px(1);
1987
1988 /* Draw the border of the button. */
1989 draw_util_rectangle(surface, border_color, x, logical_px(1), width, height);
1990
1991 /* Draw the inside of the button. */
1992 draw_util_rectangle(surface, bg_color, x + logical_px(1), 2 * logical_px(1),
1993 width - 2 * logical_px(1), height - 2 * logical_px(1));
1994
1995 draw_util_text(text, surface, fg_color, bg_color, x + (width - text_width) / 2,
1996 bar_height / 2 - font.height / 2, text_width);
1997 }
1998
1999 /*
2000 * Render the bars, with buttons and statusline
2001 *
2002 */
2003 void draw_bars(bool unhide) {
2004 DLOG("Drawing bars...\n");
2005
2006 uint32_t full_statusline_width = predict_statusline_length(false);
2007 uint32_t short_statusline_width = predict_statusline_length(true);
2008
2009 i3_output *outputs_walk;
2010 SLIST_FOREACH (outputs_walk, outputs, slist) {
2011 int workspace_width = 0;
2012
2013 if (!outputs_walk->active) {
2014 DLOG("Output %s inactive, skipping...\n", outputs_walk->name);
2015 continue;
2016 }
2017 if (outputs_walk->bar.id == XCB_NONE) {
2018 /* Oh shit, an active output without an own bar. Create it now! */
2019 reconfig_windows(false);
2020 }
2021
2022 bool use_focus_colors = output_has_focus(outputs_walk);
2023
2024 /* First things first: clear the backbuffer */
2025 draw_util_clear_surface(&(outputs_walk->buffer), (use_focus_colors ? colors.focus_bar_bg : colors.bar_bg));
2026
2027 if (!config.disable_ws) {
2028 i3_ws *ws_walk;
2029 TAILQ_FOREACH (ws_walk, outputs_walk->workspaces, tailq) {
2030 DLOG("Drawing button for WS %s at x = %d, len = %d\n",
2031 i3string_as_utf8(ws_walk->name), workspace_width, ws_walk->name_width);
2032 color_t fg_color = colors.inactive_ws_fg;
2033 color_t bg_color = colors.inactive_ws_bg;
2034 color_t border_color = colors.inactive_ws_border;
2035 if (ws_walk->visible) {
2036 if (!ws_walk->focused) {
2037 fg_color = colors.active_ws_fg;
2038 bg_color = colors.active_ws_bg;
2039 border_color = colors.active_ws_border;
2040 } else {
2041 fg_color = colors.focus_ws_fg;
2042 bg_color = colors.focus_ws_bg;
2043 border_color = colors.focus_ws_border;
2044 }
2045 }
2046 if (ws_walk->urgent) {
2047 DLOG("WS %s is urgent!\n", i3string_as_utf8(ws_walk->name));
2048 fg_color = colors.urgent_ws_fg;
2049 bg_color = colors.urgent_ws_bg;
2050 border_color = colors.urgent_ws_border;
2051 unhide = true;
2052 }
2053
2054 int w = predict_button_width(ws_walk->name_width);
2055 draw_button(&(outputs_walk->buffer), fg_color, bg_color, border_color,
2056 workspace_width, w, ws_walk->name_width, ws_walk->name);
2057
2058 workspace_width += w;
2059 if (TAILQ_NEXT(ws_walk, tailq) != NULL)
2060 workspace_width += logical_px(ws_spacing_px);
2061 }
2062 }
2063
2064 if (binding.name && !config.disable_binding_mode_indicator) {
2065 workspace_width += logical_px(ws_spacing_px);
2066
2067 int w = predict_button_width(binding.name_width);
2068 draw_button(&(outputs_walk->buffer), colors.binding_mode_fg, colors.binding_mode_bg,
2069 colors.binding_mode_border, workspace_width, w, binding.name_width, binding.name);
2070
2071 unhide = true;
2072 workspace_width += w;
2073 }
2074
2075 if (!TAILQ_EMPTY(&statusline_head)) {
2076 DLOG("Printing statusline!\n");
2077
2078 int tray_width = get_tray_width(outputs_walk->trayclients);
2079 uint32_t hoff = logical_px(((workspace_width > 0) + (tray_width > 0)) * sb_hoff_px);
2080 uint32_t max_statusline_width = outputs_walk->rect.w - workspace_width - tray_width - hoff;
2081 uint32_t clip_left = 0;
2082 uint32_t statusline_width = full_statusline_width;
2083 bool use_short_text = false;
2084
2085 if (statusline_width > max_statusline_width) {
2086 statusline_width = short_statusline_width;
2087 use_short_text = true;
2088 if (statusline_width > max_statusline_width) {
2089 clip_left = statusline_width - max_statusline_width;
2090 }
2091 }
2092
2093 int16_t visible_statusline_width = MIN(statusline_width, max_statusline_width);
2094 int x_dest = outputs_walk->rect.w - tray_width - logical_px((tray_width > 0) * sb_hoff_px) - visible_statusline_width;
2095
2096 draw_statusline(outputs_walk, clip_left, use_focus_colors, use_short_text);
2097 draw_util_copy_surface(&outputs_walk->statusline_buffer, &outputs_walk->buffer, 0, 0,
2098 x_dest, 0, visible_statusline_width, (int16_t)bar_height);
2099
2100 outputs_walk->statusline_width = statusline_width;
2101 outputs_walk->statusline_short_text = use_short_text;
2102 }
2103 }
2104
2105 /* Assure the bar is hidden/unhidden according to the specified hidden_state and mode */
2106 if (mod_pressed ||
2107 config.hidden_state == S_SHOW ||
2108 unhide) {
2109 unhide_bars();
2110 } else if (config.hide_on_modifier == M_HIDE) {
2111 hide_bars();
2112 }
2113
2114 redraw_bars();
2115 }
2116
2117 /*
2118 * Redraw the bars, i.e. simply copy the buffer to the barwindow
2119 *
2120 */
2121 void redraw_bars(void) {
2122 i3_output *outputs_walk;
2123 SLIST_FOREACH (outputs_walk, outputs, slist) {
2124 if (!outputs_walk->active) {
2125 continue;
2126 }
2127
2128 draw_util_copy_surface(&(outputs_walk->buffer), &(outputs_walk->bar), 0, 0,
2129 0, 0, outputs_walk->rect.w, outputs_walk->rect.h);
2130 xcb_flush(xcb_connection);
2131 }
2132 }
2133
2134 /*
2135 * Set the current binding mode
2136 *
2137 */
2138 void set_current_mode(struct mode *current) {
2139 I3STRING_FREE(binding.name);
2140 binding = *current;
2141 activated_mode = binding.name != NULL;
2142 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * This header file includes all relevant files of i3 and the most often used
7 * system header files. This reduces boilerplate (the amount of code duplicated
8 * at the beginning of each source file) and is not significantly slower at
9 * compile-time.
10 *
11 */
12 #pragma once
13
14 #include <config.h>
15
16 #include <assert.h>
17 #include <stdbool.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <string.h>
21 #include <locale.h>
22 #include <getopt.h>
23 #include <unistd.h>
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <glob.h>
27 #include <errno.h>
28 #include <err.h>
29 #include <stdint.h>
30 #include <inttypes.h>
31 #include <math.h>
32 #include <limits.h>
33
34 #include <xcb/xcb.h>
35 #include <xcb/xcb_aux.h>
36 #include <xcb/xcb_keysyms.h>
37 #include <xcb/xcb_icccm.h>
38
39 #include <yajl/yajl_gen.h>
40 #include <yajl/yajl_version.h>
41
42 #include "data.h"
43 #include "util.h"
44 #include "ipc.h"
45 #include "tree.h"
46 #include "log.h"
47 #include "xcb.h"
48 #include "manage.h"
49 #include "workspace.h"
50 #include "i3.h"
51 #include "x.h"
52 #include "click.h"
53 #include "key_press.h"
54 #include "floating.h"
55 #include "drag.h"
56 #include "configuration.h"
57 #include "handlers.h"
58 #include "randr.h"
59 #include "xinerama.h"
60 #include "con.h"
61 #include "load_layout.h"
62 #include "render.h"
63 #include "window.h"
64 #include "match.h"
65 #include "cmdparse.h"
66 #include "xcursor.h"
67 #include "resize.h"
68 #include "sighandler.h"
69 #include "move.h"
70 #include "output.h"
71 #include "ewmh.h"
72 #include "assignments.h"
73 #include "regex.h"
74 #include "libi3.h"
75 #include "startup.h"
76 #include "scratchpad.h"
77 #include "commands.h"
78 #include "commands_parser.h"
79 #include "bindings.h"
80 #include "config_directives.h"
81 #include "config_parser.h"
82 #include "fake_outputs.h"
83 #include "display_version.h"
84 #include "restore_layout.h"
85 #include "sync.h"
86 #include "main.h"
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * assignments.c: Assignments for specific windows (for_window).
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 /**
14 * Checks the list of assignments for the given window and runs all matching
15 * ones (unless they have already been run for this specific window).
16 *
17 */
18 void run_assignments(i3Window *window);
19
20 /**
21 * Returns the first matching assignment for the given window.
22 *
23 */
24 Assignment *assignment_for(i3Window *window, int type);
0 #include "atoms_NET_SUPPORTED.xmacro"
1 #include "atoms_rest.xmacro"
0 xmacro(_NET_SUPPORTED)
1 xmacro(_NET_SUPPORTING_WM_CHECK)
2 xmacro(_NET_WM_NAME)
3 xmacro(_NET_WM_VISIBLE_NAME)
4 xmacro(_NET_WM_MOVERESIZE)
5 xmacro(_NET_WM_STATE_STICKY)
6 xmacro(_NET_WM_STATE_FULLSCREEN)
7 xmacro(_NET_WM_STATE_DEMANDS_ATTENTION)
8 xmacro(_NET_WM_STATE_MODAL)
9 xmacro(_NET_WM_STATE_HIDDEN)
10 xmacro(_NET_WM_STATE_FOCUSED)
11 xmacro(_NET_WM_STATE)
12 xmacro(_NET_WM_WINDOW_TYPE)
13 xmacro(_NET_WM_WINDOW_TYPE_NORMAL)
14 xmacro(_NET_WM_WINDOW_TYPE_DOCK)
15 xmacro(_NET_WM_WINDOW_TYPE_DIALOG)
16 xmacro(_NET_WM_WINDOW_TYPE_UTILITY)
17 xmacro(_NET_WM_WINDOW_TYPE_TOOLBAR)
18 xmacro(_NET_WM_WINDOW_TYPE_SPLASH)
19 xmacro(_NET_WM_WINDOW_TYPE_MENU)
20 xmacro(_NET_WM_WINDOW_TYPE_DROPDOWN_MENU)
21 xmacro(_NET_WM_WINDOW_TYPE_POPUP_MENU)
22 xmacro(_NET_WM_WINDOW_TYPE_TOOLTIP)
23 xmacro(_NET_WM_WINDOW_TYPE_NOTIFICATION)
24 xmacro(_NET_WM_DESKTOP)
25 xmacro(_NET_WM_STRUT_PARTIAL)
26 xmacro(_NET_CLIENT_LIST)
27 xmacro(_NET_CLIENT_LIST_STACKING)
28 xmacro(_NET_CURRENT_DESKTOP)
29 xmacro(_NET_NUMBER_OF_DESKTOPS)
30 xmacro(_NET_DESKTOP_NAMES)
31 xmacro(_NET_DESKTOP_VIEWPORT)
32 xmacro(_NET_ACTIVE_WINDOW)
33 xmacro(_NET_CLOSE_WINDOW)
34 xmacro(_NET_MOVERESIZE_WINDOW)
0 xmacro(_NET_WM_USER_TIME)
1 xmacro(_NET_STARTUP_ID)
2 xmacro(_NET_WORKAREA)
3 xmacro(WM_PROTOCOLS)
4 xmacro(WM_DELETE_WINDOW)
5 xmacro(UTF8_STRING)
6 xmacro(WM_STATE)
7 xmacro(WM_CLIENT_LEADER)
8 xmacro(WM_TAKE_FOCUS)
9 xmacro(WM_WINDOW_ROLE)
10 xmacro(I3_SOCKET_PATH)
11 xmacro(I3_CONFIG_PATH)
12 xmacro(I3_SYNC)
13 xmacro(I3_SHMLOG_PATH)
14 xmacro(I3_PID)
15 xmacro(I3_FLOATING_WINDOW)
16 xmacro(_NET_REQUEST_FRAME_EXTENTS)
17 xmacro(_NET_FRAME_EXTENTS)
18 xmacro(_MOTIF_WM_HINTS)
19 xmacro(WM_CHANGE_STATE)
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * bindings.h: Functions for configuring, finding, and running bindings.
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 extern pid_t command_error_nagbar_pid;
14
15 /**
16 * The name of the default mode.
17 *
18 */
19 extern const char *DEFAULT_BINDING_MODE;
20
21 /**
22 * Adds a binding from config parameters given as strings and returns a
23 * pointer to the binding structure. Returns NULL if the input code could not
24 * be parsed.
25 *
26 */
27 Binding *configure_binding(const char *bindtype, const char *modifiers, const char *input_code,
28 const char *release, const char *border, const char *whole_window,
29 const char *exclude_titlebar, const char *command, const char *mode,
30 bool pango_markup);
31
32 /**
33 * Grab the bound keys (tell X to send us keypress events for those keycodes)
34 *
35 */
36 void grab_all_keys(xcb_connection_t *conn);
37
38 /**
39 * Release the button grabs on all managed windows and regrab them,
40 * reevaluating which buttons need to be grabbed.
41 *
42 */
43 void regrab_all_buttons(xcb_connection_t *conn);
44
45 /**
46 * Returns a pointer to the Binding that matches the given xcb event or NULL if
47 * no such binding exists.
48 *
49 */
50 Binding *get_binding_from_xcb_event(xcb_generic_event_t *event);
51
52 /**
53 * Translates keysymbols to keycodes for all bindings which use keysyms.
54 *
55 */
56 void translate_keysyms(void);
57
58 /**
59 * Switches the key bindings to the given mode, if the mode exists
60 *
61 */
62 void switch_mode(const char *new_mode);
63
64 /**
65 * Reorders bindings by event_state_mask descendingly so that get_binding()
66 * correctly matches more specific bindings before more generic bindings. Take
67 * the following binding configuration as an example:
68 *
69 * bindsym n nop lower-case n pressed
70 * bindsym Shift+n nop upper-case n pressed
71 *
72 * Without reordering, the first binding’s event_state_mask of 0x0 would match
73 * the actual event_stat_mask of 0x1 and hence trigger instead of the second
74 * keybinding.
75 *
76 */
77 void reorder_bindings(void);
78
79 /**
80 * Checks for duplicate key bindings (the same keycode or keysym is configured
81 * more than once). If a duplicate binding is found, a message is printed to
82 * stderr and the has_errors variable is set to true, which will start
83 * i3-nagbar.
84 *
85 */
86 void check_for_duplicate_bindings(struct context *context);
87
88 /**
89 * Frees the binding. If bind is null, it simply returns.
90 */
91 void binding_free(Binding *bind);
92
93 /**
94 * Runs the given binding and handles parse errors. If con is passed, it will
95 * execute the command binding with that container selected by criteria.
96 * Returns a CommandResult for running the binding's command. Caller should
97 * render tree if needs_tree_render is true. Free with command_result_free().
98 *
99 */
100 CommandResult *run_binding(Binding *bind, Con *con);
101
102 /**
103 * Loads the XKB keymap from the X11 server and feeds it to xkbcommon.
104 *
105 */
106 bool load_keymap(void);
107
108 /**
109 * Returns a list of buttons that should be grabbed on a window.
110 * This list will always contain 1–3, all higher buttons will only be returned
111 * if there is a whole-window binding for it on some window in the current
112 * config.
113 * The list is terminated by a 0.
114 */
115 int *bindings_get_buttons_to_grab(void);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * click.c: Button press (mouse click) events.
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 /**
14 * The button press X callback. This function determines whether the floating
15 * modifier is pressed and where the user clicked (decoration, border, inside
16 * the window).
17 *
18 * Then, route_click is called on the appropriate con.
19 *
20 */
21 void handle_button_press(xcb_button_press_event_t *event);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * cmdparse.y: the parser for commands you send to i3 (or bind on keys)
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 char *parse_cmd(const char *new);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * commands.c: all command functions (see commands_parser.c)
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include "commands_parser.h"
14
15 /** The beginning of the prototype for every cmd_ function. */
16 #define I3_CMD Match *current_match, struct CommandResultIR *cmd_output
17
18 /**
19 * Initializes the specified 'Match' data structure and the initial state of
20 * commands.c for matching target windows of a command.
21 *
22 */
23 void cmd_criteria_init(I3_CMD);
24
25 /**
26 * A match specification just finished (the closing square bracket was found),
27 * so we filter the list of owindows.
28 *
29 */
30 void cmd_criteria_match_windows(I3_CMD);
31
32 /**
33 * Interprets a ctype=cvalue pair and adds it to the current match
34 * specification.
35 *
36 */
37 void cmd_criteria_add(I3_CMD, const char *ctype, const char *cvalue);
38
39 /**
40 * Implementation of 'move [window|container] [to] workspace
41 * next|prev|next_on_output|prev_on_output'.
42 *
43 */
44 void cmd_move_con_to_workspace(I3_CMD, const char *which);
45
46 /**
47 * Implementation of 'move [window|container] [to] workspace back_and_forth'.
48 *
49 */
50 void cmd_move_con_to_workspace_back_and_forth(I3_CMD);
51
52 /**
53 * Implementation of 'move [--no-auto-back-and-forth] [window|container] [to] workspace <name>'.
54 *
55 */
56 void cmd_move_con_to_workspace_name(I3_CMD, const char *name, const char *no_auto_back_and_forth);
57
58 /**
59 * Implementation of 'move [--no-auto-back-and-forth] [window|container] [to] workspace number <number>'.
60 *
61 */
62 void cmd_move_con_to_workspace_number(I3_CMD, const char *which, const char *no_auto_back_and_forth);
63
64 /**
65 * Implementation of 'resize set <width> [px | ppt] <height> [px | ppt]'.
66 *
67 */
68 void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, const char *mode_height);
69
70 /**
71 * Implementation of 'resize grow|shrink <direction> [<px> px] [or <ppt> ppt]'.
72 *
73 */
74 void cmd_resize(I3_CMD, const char *way, const char *direction, long resize_px, long resize_ppt);
75
76 /**
77 * Implementation of 'border normal|pixel [<n>]', 'border none|1pixel|toggle'.
78 *
79 */
80 void cmd_border(I3_CMD, const char *border_style_str, long border_width);
81
82 /**
83 * Implementation of 'nop <comment>'.
84 *
85 */
86 void cmd_nop(I3_CMD, const char *comment);
87
88 /**
89 * Implementation of 'append_layout <path>'.
90 *
91 */
92 void cmd_append_layout(I3_CMD, const char *path);
93
94 /**
95 * Implementation of 'workspace next|prev|next_on_output|prev_on_output'.
96 *
97 */
98 void cmd_workspace(I3_CMD, const char *which);
99
100 /**
101 * Implementation of 'workspace [--no-auto-back-and-forth] number <number>'
102 *
103 */
104 void cmd_workspace_number(I3_CMD, const char *which, const char *no_auto_back_and_forth);
105
106 /**
107 * Implementation of 'workspace back_and_forth'.
108 *
109 */
110 void cmd_workspace_back_and_forth(I3_CMD);
111
112 /**
113 * Implementation of 'workspace [--no-auto-back-and-forth] <name>'
114 *
115 */
116 void cmd_workspace_name(I3_CMD, const char *name, const char *no_auto_back_and_forth);
117
118 /**
119 * Implementation of 'mark [--add|--replace] [--toggle] <mark>'
120 *
121 */
122 void cmd_mark(I3_CMD, const char *mark, const char *mode, const char *toggle);
123
124 /**
125 * Implementation of 'unmark [mark]'
126 *
127 */
128 void cmd_unmark(I3_CMD, const char *mark);
129
130 /**
131 * Implementation of 'mode <string>'.
132 *
133 */
134 void cmd_mode(I3_CMD, const char *mode);
135
136 /**
137 * Implementation of 'move [window|container] [to] output <str>'.
138 *
139 */
140 void cmd_move_con_to_output(I3_CMD, const char *name);
141
142 /**
143 * Implementation of 'move [window|container] [to] mark <str>'.
144 *
145 */
146 void cmd_move_con_to_mark(I3_CMD, const char *mark);
147
148 /**
149 * Implementation of 'floating enable|disable|toggle'
150 *
151 */
152 void cmd_floating(I3_CMD, const char *floating_mode);
153
154 /**
155 * Implementation of 'move workspace to [output] <str>'.
156 *
157 */
158 void cmd_move_workspace_to_output(I3_CMD, const char *name);
159
160 /**
161 * Implementation of 'split v|h|t|vertical|horizontal|toggle'.
162 *
163 */
164 void cmd_split(I3_CMD, const char *direction);
165
166 /**
167 * Implementation of 'kill [window|client]'.
168 *
169 */
170 void cmd_kill(I3_CMD, const char *kill_mode_str);
171
172 /**
173 * Implementation of 'exec [--no-startup-id] <command>'.
174 *
175 */
176 void cmd_exec(I3_CMD, const char *nosn, const char *command);
177
178 /**
179 * Implementation of 'focus left|right|up|down'.
180 *
181 */
182 void cmd_focus_direction(I3_CMD, const char *direction);
183
184 /**
185 * Implementation of 'focus next|prev sibling'
186 *
187 */
188 void cmd_focus_sibling(I3_CMD, const char *direction);
189
190 /**
191 * Implementation of 'focus tiling|floating|mode_toggle'.
192 *
193 */
194 void cmd_focus_window_mode(I3_CMD, const char *window_mode);
195
196 /**
197 * Implementation of 'focus parent|child'.
198 *
199 */
200 void cmd_focus_level(I3_CMD, const char *level);
201
202 /**
203 * Implementation of 'focus'.
204 *
205 */
206 void cmd_focus(I3_CMD);
207
208 /**
209 * Implementation of 'fullscreen [enable|disable|toggle] [global]'.
210 *
211 */
212 void cmd_fullscreen(I3_CMD, const char *action, const char *fullscreen_mode);
213
214 /**
215 * Implementation of 'sticky enable|disable|toggle'.
216 *
217 */
218 void cmd_sticky(I3_CMD, const char *action);
219
220 /**
221 * Implementation of 'move <direction> [<pixels> [px]]'.
222 *
223 */
224 void cmd_move_direction(I3_CMD, const char *direction_str, long move_px);
225
226 /**
227 * Implementation of 'layout default|stacked|stacking|tabbed|splitv|splith'.
228 *
229 */
230 void cmd_layout(I3_CMD, const char *layout_str);
231
232 /**
233 * Implementation of 'layout toggle [all|split]'.
234 *
235 */
236 void cmd_layout_toggle(I3_CMD, const char *toggle_mode);
237
238 /**
239 * Implementation of 'exit'.
240 *
241 */
242 void cmd_exit(I3_CMD);
243
244 /**
245 * Implementation of 'reload'.
246 *
247 */
248 void cmd_reload(I3_CMD);
249
250 /**
251 * Implementation of 'restart'.
252 *
253 */
254 void cmd_restart(I3_CMD);
255
256 /**
257 * Implementation of 'open'.
258 *
259 */
260 void cmd_open(I3_CMD);
261
262 /**
263 * Implementation of 'focus output <output>'.
264 *
265 */
266 void cmd_focus_output(I3_CMD, const char *name);
267
268 /**
269 * Implementation of 'move [window|container] [to] [absolute] position <px> [px] <px> [px]
270 *
271 */
272 void cmd_move_window_to_position(I3_CMD, long x, long y);
273
274 /**
275 * Implementation of 'move [window|container] [to] [absolute] position center
276 *
277 */
278 void cmd_move_window_to_center(I3_CMD, const char *method);
279
280 /**
281 * Implementation of 'move [window|container] [to] position mouse'
282 *
283 */
284 void cmd_move_window_to_mouse(I3_CMD);
285
286 /**
287 * Implementation of 'move scratchpad'.
288 *
289 */
290 void cmd_move_scratchpad(I3_CMD);
291
292 /**
293 * Implementation of 'scratchpad show'.
294 *
295 */
296 void cmd_scratchpad_show(I3_CMD);
297
298 /**
299 * Implementation of 'swap [container] [with] id|con_id|mark <arg>'.
300 *
301 */
302 void cmd_swap(I3_CMD, const char *mode, const char *arg);
303
304 /**
305 * Implementation of 'title_format <format>'
306 *
307 */
308 void cmd_title_format(I3_CMD, const char *format);
309
310 /**
311 * Implementation of 'rename workspace <name> to <name>'
312 *
313 */
314 void cmd_rename_workspace(I3_CMD, const char *old_name, const char *new_name);
315
316 /**
317 * Implementation of 'bar (hidden_state hide|show|toggle)|(mode dock|hide|invisible|toggle) [<bar_id>]'
318 *
319 */
320 void cmd_bar(I3_CMD, const char *bar_type, const char *bar_value, const char *bar_id);
321
322 /**
323 * Implementation of 'shmlog <size>|toggle|on|off'
324 *
325 */
326 void cmd_shmlog(I3_CMD, const char *argument);
327
328 /**
329 * Implementation of 'debuglog toggle|on|off'
330 *
331 */
332 void cmd_debuglog(I3_CMD, const char *argument);
333
334 /**
335 * Implementation of 'gaps inner|outer|top|right|bottom|left|horizontal|vertical current|all set|plus|minus|toggle <px>'
336 *
337 */
338 void cmd_gaps(I3_CMD, const char *type, const char *scope, const char *mode, const char *value);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * commands.c: all command functions (see commands_parser.c)
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include <yajl/yajl_gen.h>
14
15 /**
16 * Holds an intermediate represenation of the result of a call to any command.
17 * When calling parse_command("floating enable, border none"), the parser will
18 * internally use this struct when calling cmd_floating and cmd_border.
19 */
20 struct CommandResultIR {
21 /* The JSON generator to append a reply to (may be NULL). */
22 yajl_gen json_gen;
23
24 /* The IPC client connection which sent this command (may be NULL, e.g. for
25 key bindings). */
26 ipc_client *client;
27
28 /* The next state to transition to. Passed to the function so that we can
29 * determine the next state as a result of a function call, like
30 * cfg_criteria_pop_state() does. */
31 int next_state;
32
33 /* Whether the command requires calling tree_render. */
34 bool needs_tree_render;
35 };
36
37 typedef struct CommandResult CommandResult;
38
39 /**
40 * A struct that contains useful information about the result of a command as a
41 * whole (e.g. a compound command like "floating enable, border none").
42 * needs_tree_render is true if needs_tree_render of any individual command was
43 * true.
44 */
45 struct CommandResult {
46 bool parse_error;
47 /* the error_message is currently only set for parse errors */
48 char *error_message;
49 bool needs_tree_render;
50 };
51
52 /**
53 * Parses a string (or word, if as_word is true). Extracted out of
54 * parse_command so that it can be used in src/workspace.c for interpreting
55 * workspace commands.
56 *
57 */
58 char *parse_string(const char **walk, bool as_word);
59
60 /**
61 * Parses and executes the given command. If a caller-allocated yajl_gen is
62 * passed, a json reply will be generated in the format specified by the ipc
63 * protocol. Pass NULL if no json reply is required.
64 *
65 * Free the returned CommandResult with command_result_free().
66 */
67 CommandResult *parse_command(const char *input, yajl_gen gen, ipc_client *client);
68
69 /**
70 * Frees a CommandResult
71 */
72 void command_result_free(CommandResult *result);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * con.c: Functions which deal with containers directly (creating containers,
7 * searching containers, getting specific properties from containers,
8 * …).
9 *
10 */
11 #pragma once
12
13 #include <config.h>
14
15 /**
16 * Create a new container (and attach it to the given parent, if not NULL).
17 * This function only initializes the data structures.
18 *
19 */
20 Con *con_new_skeleton(Con *parent, i3Window *window);
21
22 /**
23 * A wrapper for con_new_skeleton, to retain the old con_new behaviour
24 *
25 */
26 Con *con_new(Con *parent, i3Window *window);
27
28 /**
29 * Frees the specified container.
30 *
31 */
32 void con_free(Con *con);
33
34 /**
35 * Sets input focus to the given container. Will be updated in X11 in the next
36 * run of x_push_changes().
37 *
38 */
39 void con_focus(Con *con);
40
41 /**
42 * Sets input focus to the given container and raises it to the top.
43 *
44 */
45 void con_activate(Con *con);
46
47 /**
48 * Activates the container like in con_activate but removes fullscreen
49 * restrictions and properly warps the pointer if needed.
50 *
51 */
52 void con_activate_unblock(Con *con);
53
54 /**
55 * Closes the given container.
56 *
57 */
58 void con_close(Con *con, kill_window_t kill_window);
59
60 /**
61 * Returns true when this node is a leaf node (has no children)
62 *
63 */
64 bool con_is_leaf(Con *con);
65
66 /**
67 * Returns true when this con is a leaf node with a managed X11 window (e.g.,
68 * excluding dock containers)
69 */
70 bool con_has_managed_window(Con *con);
71
72 /**
73 * Returns true if a container should be considered split.
74 *
75 */
76 bool con_is_split(Con *con);
77
78 /**
79 * This will only return true for containers which have some parent with
80 * a tabbed / stacked parent of which they are not the currently focused child.
81 *
82 */
83 bool con_is_hidden(Con *con);
84
85 /**
86 * Returns whether the container or any of its children is sticky.
87 *
88 */
89 bool con_is_sticky(Con *con);
90
91 /**
92 * Returns true if this node has regular or floating children.
93 *
94 */
95 bool con_has_children(Con *con);
96
97 /**
98 * Returns true if this node accepts a window (if the node swallows windows,
99 * it might already have swallowed enough and cannot hold any more).
100 *
101 */
102 bool con_accepts_window(Con *con);
103
104 /**
105 * Gets the output container (first container with CT_OUTPUT in hierarchy) this
106 * node is on.
107 *
108 */
109 Con *con_get_output(Con *con);
110
111 /**
112 * Gets the workspace container this node is on.
113 *
114 */
115 Con *con_get_workspace(Con *con);
116
117 /**
118 * Searches parents of the given 'con' until it reaches one with the specified
119 * 'orientation'. Aborts when it comes across a floating_con.
120 *
121 */
122 Con *con_parent_with_orientation(Con *con, orientation_t orientation);
123
124 /**
125 * Returns the first fullscreen node below this node.
126 *
127 */
128 Con *con_get_fullscreen_con(Con *con, fullscreen_mode_t fullscreen_mode);
129
130 /**
131 * Returns the fullscreen node that covers the given workspace if it exists.
132 * This is either a CF_GLOBAL fullscreen container anywhere or a CF_OUTPUT
133 * fullscreen container in the workspace.
134 *
135 */
136 Con *con_get_fullscreen_covering_ws(Con *ws);
137
138 /**
139 * Returns true if the container is internal, such as __i3_scratch
140 *
141 */
142 bool con_is_internal(Con *con);
143
144 /**
145 * Returns true if the node is floating.
146 *
147 */
148 bool con_is_floating(Con *con);
149
150 /**
151 * Returns true if the container is a docked container.
152 *
153 */
154 bool con_is_docked(Con *con);
155
156 /**
157 * Checks if the given container is either floating or inside some floating
158 * container. It returns the FLOATING_CON container.
159 *
160 */
161 Con *con_inside_floating(Con *con);
162
163 /**
164 * Checks if the given container is inside a focused container.
165 *
166 */
167 bool con_inside_focused(Con *con);
168
169 /**
170 * Checks if the container has the given parent as an actual parent.
171 *
172 */
173 bool con_has_parent(Con *con, Con *parent);
174
175 /**
176 * Returns the container with the given client window ID or NULL if no such
177 * container exists.
178 *
179 */
180 Con *con_by_window_id(xcb_window_t window);
181
182 /**
183 * Returns the container with the given container ID or NULL if no such
184 * container exists.
185 *
186 */
187 Con *con_by_con_id(long target);
188
189 /**
190 * Returns true if the given container (still) exists.
191 * This can be used, e.g., to make sure a container hasn't been closed in the meantime.
192 *
193 */
194 bool con_exists(Con *con);
195
196 /**
197 * Returns the container with the given frame ID or NULL if no such container
198 * exists.
199 *
200 */
201 Con *con_by_frame_id(xcb_window_t frame);
202
203 /**
204 * Returns the container with the given mark or NULL if no such container
205 * exists.
206 *
207 */
208 Con *con_by_mark(const char *mark);
209
210 /**
211 * Returns true if and only if the given containers holds the mark.
212 *
213 */
214 bool con_has_mark(Con *con, const char *mark);
215
216 /**
217 * Toggles the mark on a container.
218 * If the container already has this mark, the mark is removed.
219 * Otherwise, the mark is assigned to the container.
220 *
221 */
222 void con_mark_toggle(Con *con, const char *mark, mark_mode_t mode);
223
224 /**
225 * Assigns a mark to the container.
226 *
227 */
228 void con_mark(Con *con, const char *mark, mark_mode_t mode);
229
230 /**
231 * Removes marks from containers.
232 * If con is NULL, all containers are considered.
233 * If name is NULL, this removes all existing marks.
234 * Otherwise, it will only remove the given mark (if it is present).
235 *
236 */
237 void con_unmark(Con *con, const char *name);
238
239 /**
240 * Returns the first container below 'con' which wants to swallow this window
241 * TODO: priority
242 *
243 */
244 Con *con_for_window(Con *con, i3Window *window, Match **store_match);
245
246 /**
247 * Iterate over the container's focus stack and return an array with the
248 * containers inside it, ordered from higher focus order to lowest.
249 *
250 */
251 Con **get_focus_order(Con *con);
252
253 /**
254 * Clear the container's focus stack and re-add it using the provided container
255 * array. The function doesn't check if the provided array contains the same
256 * containers with the previous focus stack but will not add floating containers
257 * in the new focus stack if container is not a workspace.
258 *
259 */
260 void set_focus_order(Con *con, Con **focus_order);
261
262 /**
263 * Returns the number of children of this container.
264 *
265 */
266 int con_num_children(Con *con);
267
268 /**
269 * Returns the number of visible non-floating children of this container.
270 * For example, if the container contains a hsplit which has two children,
271 * this will return 2 instead of 1.
272 */
273 int con_num_visible_children(Con *con);
274
275 /**
276 * Count the number of windows (i.e., leaf containers).
277 *
278 */
279 int con_num_windows(Con *con);
280
281 /**
282 * Attaches the given container to the given parent. This happens when moving
283 * a container or when inserting a new container at a specific place in the
284 * tree.
285 *
286 * ignore_focus is to just insert the Con at the end (useful when creating a
287 * new split container *around* some containers, that is, detaching and
288 * attaching them in order without wanting to mess with the focus in between).
289 *
290 */
291 void con_attach(Con *con, Con *parent, bool ignore_focus);
292
293 /**
294 * Detaches the given container from its current parent
295 *
296 */
297 void con_detach(Con *con);
298
299 /**
300 * Updates the percent attribute of the children of the given container. This
301 * function needs to be called when a window is added or removed from a
302 * container.
303 *
304 */
305 void con_fix_percent(Con *con);
306
307 /**
308 * Toggles fullscreen mode for the given container. Fullscreen mode will not be
309 * entered when there already is a fullscreen container on this workspace.
310 *
311 */
312 void con_toggle_fullscreen(Con *con, int fullscreen_mode);
313
314 /**
315 * Enables fullscreen mode for the given container, if necessary.
316 *
317 */
318 void con_enable_fullscreen(Con *con, fullscreen_mode_t fullscreen_mode);
319
320 /**
321 * Disables fullscreen mode for the given container, if necessary.
322 *
323 */
324 void con_disable_fullscreen(Con *con);
325
326 /**
327 * Moves the given container to the currently focused container on the given
328 * workspace.
329 *
330 * The fix_coordinates flag will translate the current coordinates (offset from
331 * the monitor position basically) to appropriate coordinates on the
332 * destination workspace.
333 * Not enabling this behaviour comes in handy when this function gets called by
334 * floating_maybe_reassign_ws, which will only "move" a floating window when it
335 * *already* changed its coordinates to a different output.
336 *
337 * The dont_warp flag disables pointer warping and will be set when this
338 * function is called while dragging a floating window.
339 *
340 * If ignore_focus is set, the container will be moved without modifying focus
341 * at all.
342 *
343 * TODO: is there a better place for this function?
344 *
345 */
346 void con_move_to_workspace(Con *con, Con *workspace, bool fix_coordinates,
347 bool dont_warp, bool ignore_focus);
348
349 /**
350 * Moves the given container to the currently focused container on the
351 * visible workspace on the given output.
352 *
353 */
354 void con_move_to_output(Con *con, Output *output, bool fix_coordinates);
355
356 /**
357 * Moves the given container to the currently focused container on the
358 * visible workspace on the output specified by the given name.
359 * The current output for the container is used to resolve relative names
360 * such as left, right, up, down.
361 *
362 */
363 bool con_move_to_output_name(Con *con, const char *name, bool fix_coordinates);
364
365 /**
366 * Moves the given container to the given mark.
367 *
368 */
369 bool con_move_to_mark(Con *con, const char *mark);
370
371 /**
372 * Returns the orientation of the given container (for stacked containers,
373 * vertical orientation is used regardless of the actual orientation of the
374 * container).
375 *
376 */
377 orientation_t con_orientation(Con *con);
378
379 /**
380 * Returns the container which will be focused next when the given container
381 * is not available anymore. Called in tree_close_internal and con_move_to_workspace
382 * to properly restore focus.
383 *
384 */
385 Con *con_next_focused(Con *con);
386
387 /**
388 * Returns the focused con inside this client, descending the tree as far as
389 * possible. This comes in handy when attaching a con to a workspace at the
390 * currently focused position, for example.
391 *
392 */
393 Con *con_descend_focused(Con *con);
394
395 /**
396 * Returns the focused con inside this client, descending the tree as far as
397 * possible. This comes in handy when attaching a con to a workspace at the
398 * currently focused position, for example.
399 *
400 * Works like con_descend_focused but considers only tiling cons.
401 *
402 */
403 Con *con_descend_tiling_focused(Con *con);
404
405 /**
406 * Returns the leftmost, rightmost, etc. container in sub-tree. For example, if
407 * direction is D_LEFT, then we return the rightmost container and if direction
408 * is D_RIGHT, we return the leftmost container. This is because if we are
409 * moving D_LEFT, and thus want the rightmost container.
410 */
411 Con *con_descend_direction(Con *con, direction_t direction);
412
413 /**
414 * Returns a "relative" Rect which contains the amount of pixels that need to
415 * be added to the original Rect to get the final position (obviously the
416 * amount of pixels for normal, 1pixel and borderless are different).
417 *
418 */
419 Rect con_border_style_rect(Con *con);
420
421 /**
422 * Returns adjacent borders of the window. We need this if hide_edge_borders is
423 * enabled.
424 */
425 adjacent_t con_adjacent_borders(Con *con);
426
427 /**
428 * Use this function to get a container’s border style. This is important
429 * because when inside a stack, the border style is always BS_NORMAL.
430 * For tabbed mode, the same applies, with one exception: when the container is
431 * borderless and the only element in the tabbed container, the border is not
432 * rendered.
433 *
434 * For children of a CT_DOCKAREA, the border style is always none.
435 *
436 */
437 int con_border_style(Con *con);
438
439 /**
440 * Sets the given border style on con, correctly keeping the position/size of a
441 * floating window.
442 *
443 */
444 void con_set_border_style(Con *con, int border_style, int border_width);
445
446 /**
447 * This function changes the layout of a given container. Use it to handle
448 * special cases like changing a whole workspace to stacked/tabbed (creates a
449 * new split container before).
450 *
451 */
452 void con_set_layout(Con *con, layout_t layout);
453
454 /**
455 * This function toggles the layout of a given container. toggle_mode can be
456 * either 'default' (toggle only between stacked/tabbed/last_split_layout),
457 * 'split' (toggle only between splitv/splith) or 'all' (toggle between all
458 * layouts).
459 *
460 */
461 void con_toggle_layout(Con *con, const char *toggle_mode);
462
463 /**
464 * Determines the minimum size of the given con by looking at its children (for
465 * split/stacked/tabbed cons). Will be called when resizing floating cons
466 *
467 */
468 Rect con_minimum_size(Con *con);
469
470 /**
471 * Returns true if changing the focus to con would be allowed considering
472 * the fullscreen focus constraints. Specifically, if a fullscreen container or
473 * any of its descendants is focused, this function returns true if and only if
474 * focusing con would mean that focus would still be visible on screen, i.e.,
475 * the newly focused container would not be obscured by a fullscreen container.
476 *
477 * In the simplest case, if a fullscreen container or any of its descendants is
478 * fullscreen, this functions returns true if con is the fullscreen container
479 * itself or any of its descendants, as this means focus wouldn't escape the
480 * boundaries of the fullscreen container.
481 *
482 * In case the fullscreen container is of type CF_OUTPUT, this function returns
483 * true if con is on a different workspace, as focus wouldn't be obscured by
484 * the fullscreen container that is constrained to a different workspace.
485 *
486 * Note that this same logic can be applied to moving containers. If a
487 * container can be focused under the fullscreen focus constraints, it can also
488 * become a parent or sibling to the currently focused container.
489 *
490 */
491 bool con_fullscreen_permits_focusing(Con *con);
492
493 /**
494 * Checks if the given container has an urgent child.
495 *
496 */
497 bool con_has_urgent_child(Con *con);
498
499 /**
500 * Make all parent containers urgent if con is urgent or clear the urgent flag
501 * of all parent containers if there are no more urgent children left.
502 *
503 */
504 void con_update_parents_urgency(Con *con);
505
506 /**
507 * Set urgency flag to the container, all the parent containers and the workspace.
508 *
509 */
510 void con_set_urgency(Con *con, bool urgent);
511
512 /**
513 * Create a string representing the subtree under con.
514 *
515 */
516 char *con_get_tree_representation(Con *con);
517
518 /**
519 * Calculates the effective gap sizes for a container depending
520 * on whether it is adjacent to the edge of the screen or another
521 * container.
522 */
523 gaps_t calculate_effective_gaps(Con *con);
524
525 /**
526 * force parent split containers to be redrawn
527 *
528 */
529 void con_force_split_parents_redraw(Con *con);
530
531 /**
532 * Returns the window title considering the current title format.
533 *
534 */
535 i3String *con_parse_title_format(Con *con);
536
537 /**
538 * Swaps the two containers.
539 *
540 */
541 bool con_swap(Con *first, Con *second);
542
543 /**
544 * Returns given container's rect size depending on its orientation.
545 * i.e. its width when horizontal, its height when vertical.
546 *
547 */
548 uint32_t con_rect_size_in_orientation(Con *con);
549
550 /**
551 * Merges container specific data that should move with the window (e.g. marks,
552 * title format, and the window itself) into another container, and closes the
553 * old container.
554 *
555 */
556 void con_merge_into(Con *old, Con *new);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * config_directives.h: all config storing functions (see config_parser.c)
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include "config_parser.h"
14
15 /**
16 * A utility function to convert a string containing the group and modifiers to
17 * the corresponding bit mask.
18 */
19 i3_event_state_mask_t event_state_from_str(const char *str);
20
21 /** The beginning of the prototype for every cfg_ function. */
22 #define I3_CFG Match *current_match, struct ConfigResultIR *result
23
24 /* Defines a configuration function, that is, anything that can be called by
25 * using 'call cfg_foo()' in parser-specs/.*.spec. Useful so that we don’t need
26 * to repeat the definition all the time. */
27 #define CFGFUN(name, ...) \
28 void cfg_##name(I3_CFG, ##__VA_ARGS__)
29
30 /* The following functions are called by the config parser, see
31 * parser-specs/config.spec. They get the parsed parameters and store them in
32 * our data structures, e.g. cfg_font gets a font name and stores it in
33 * config.font.
34 *
35 * Since they are so similar, individual comments were omitted. */
36
37 CFGFUN(criteria_init, int _state);
38 CFGFUN(criteria_add, const char *ctype, const char *cvalue);
39 CFGFUN(criteria_pop_state);
40
41 CFGFUN(font, const char *font);
42 CFGFUN(exec, const char *exectype, const char *no_startup_id, const char *command);
43 CFGFUN(for_window, const char *command);
44 CFGFUN(gaps, const char *workspace, const char *type, const long value);
45 CFGFUN(smart_borders, const char *enable);
46 CFGFUN(smart_gaps, const char *enable);
47 CFGFUN(floating_minimum_size, const long width, const long height);
48 CFGFUN(floating_maximum_size, const long width, const long height);
49 CFGFUN(default_orientation, const char *orientation);
50 CFGFUN(workspace_layout, const char *layout);
51 CFGFUN(workspace_back_and_forth, const char *value);
52 CFGFUN(focus_follows_mouse, const char *value);
53 CFGFUN(mouse_warping, const char *value);
54 CFGFUN(focus_wrapping, const char *value);
55 CFGFUN(force_focus_wrapping, const char *value);
56 CFGFUN(force_xinerama, const char *value);
57 CFGFUN(disable_randr15, const char *value);
58 CFGFUN(fake_outputs, const char *outputs);
59 CFGFUN(force_display_urgency_hint, const long duration_ms);
60 CFGFUN(focus_on_window_activation, const char *mode);
61 CFGFUN(title_align, const char *alignment);
62 CFGFUN(show_marks, const char *value);
63 CFGFUN(hide_edge_borders, const char *borders);
64 CFGFUN(assign_output, const char *output);
65 CFGFUN(assign, const char *workspace, bool is_number);
66 CFGFUN(no_focus);
67 CFGFUN(ipc_socket, const char *path);
68 CFGFUN(ipc_kill_timeout, const long timeout_ms);
69 CFGFUN(restart_state, const char *path);
70 CFGFUN(popup_during_fullscreen, const char *value);
71 CFGFUN(color, const char *colorclass, const char *border, const char *background, const char *text, const char *indicator, const char *child_border);
72 CFGFUN(color_single, const char *colorclass, const char *color);
73 CFGFUN(floating_modifier, const char *modifiers);
74 CFGFUN(default_border, const char *windowtype, const char *border, const long width);
75 CFGFUN(workspace, const char *workspace, const char *output);
76 CFGFUN(binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *border, const char *whole_window, const char *exclude_titlebar, const char *command);
77
78 CFGFUN(enter_mode, const char *pango_markup, const char *mode);
79 CFGFUN(mode_binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *border, const char *whole_window, const char *exclude_titlebar, const char *command);
80
81 CFGFUN(bar_font, const char *font);
82 CFGFUN(bar_separator_symbol, const char *separator);
83 CFGFUN(bar_mode, const char *mode);
84 CFGFUN(bar_hidden_state, const char *hidden_state);
85 CFGFUN(bar_id, const char *bar_id);
86 CFGFUN(bar_output, const char *output);
87 CFGFUN(bar_verbose, const char *verbose);
88 CFGFUN(bar_height, const long height);
89 CFGFUN(bar_modifier, const char *modifiers);
90 CFGFUN(bar_wheel_up_cmd, const char *command);
91 CFGFUN(bar_wheel_down_cmd, const char *command);
92 CFGFUN(bar_bindsym, const char *button, const char *release, const char *command);
93 CFGFUN(bar_position, const char *position);
94 CFGFUN(bar_i3bar_command, const char *i3bar_command);
95 CFGFUN(bar_color, const char *colorclass, const char *border, const char *background, const char *text);
96 CFGFUN(bar_socket_path, const char *socket_path);
97 CFGFUN(bar_tray_output, const char *output);
98 CFGFUN(bar_tray_padding, const long spacing_px);
99 CFGFUN(bar_color_single, const char *colorclass, const char *color);
100 CFGFUN(bar_status_command, const char *command);
101 CFGFUN(bar_binding_mode_indicator, const char *value);
102 CFGFUN(bar_workspace_buttons, const char *value);
103 CFGFUN(bar_workspace_min_width, const long width);
104 CFGFUN(bar_strip_workspace_numbers, const char *value);
105 CFGFUN(bar_strip_workspace_name, const char *value);
106 CFGFUN(bar_start);
107 CFGFUN(bar_finish);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * config_parser.h: config parser-related definitions
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include <yajl/yajl_gen.h>
14
15 SLIST_HEAD(variables_head, Variable);
16 extern pid_t config_error_nagbar_pid;
17
18 /**
19 * An intermediate reprsentation of the result of a parse_config call.
20 * Currently unused, but the JSON output will be useful in the future when we
21 * implement a config parsing IPC command.
22 *
23 */
24 struct ConfigResultIR {
25 /* The JSON generator to append a reply to. */
26 yajl_gen json_gen;
27
28 /* The next state to transition to. Passed to the function so that we can
29 * determine the next state as a result of a function call, like
30 * cfg_criteria_pop_state() does. */
31 int next_state;
32 };
33
34 struct ConfigResultIR *parse_config(const char *input, struct context *context);
35
36 /**
37 * launch nagbar to indicate errors in the configuration file.
38 */
39 void start_config_error_nagbar(const char *configpath, bool has_errors);
40
41 /**
42 * Parses the given file by first replacing the variables, then calling
43 * parse_config and launching i3-nagbar if use_nagbar is true.
44 *
45 * The return value is a boolean indicating whether there were errors during
46 * parsing.
47 *
48 */
49 bool parse_file(const char *f, bool use_nagbar);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * include/configuration.h: Contains all structs/variables for the configurable
7 * part of i3 as well as functions handling the configuration file (calling
8 * the parser (src/config_parse.c) with the correct path, switching key
9 * bindings mode).
10 *
11 */
12 #pragma once
13
14 #include "libi3.h"
15
16 #include <stdbool.h>
17 #include "queue.h"
18 #include "i3.h"
19
20 typedef struct Config Config;
21 typedef struct Barconfig Barconfig;
22 extern char *current_configpath;
23 extern char *current_config;
24 extern Config config;
25 extern SLIST_HEAD(modes_head, Mode) modes;
26 extern TAILQ_HEAD(barconfig_head, Barconfig) barconfigs;
27
28 /**
29 * Used during the config file lexing/parsing to keep the state of the lexer
30 * in order to provide useful error messages in yyerror().
31 *
32 */
33 struct context {
34 bool has_errors;
35 bool has_warnings;
36
37 int line_number;
38 char *line_copy;
39 const char *filename;
40
41 char *compact_error;
42
43 /* These are the same as in YYLTYPE */
44 int first_column;
45 int last_column;
46 };
47
48 /**
49 * Part of the struct Config. It makes sense to group colors for background,
50 * border and text as every element in i3 has them (window decorations, bar).
51 *
52 */
53 struct Colortriple {
54 color_t border;
55 color_t background;
56 color_t text;
57 color_t indicator;
58 color_t child_border;
59 };
60
61 /**
62 * Holds a user-assigned variable for parsing the configuration file. The key
63 * is replaced by value in every following line of the file.
64 *
65 */
66 struct Variable {
67 char *key;
68 char *value;
69 char *next_match;
70
71 SLIST_ENTRY(Variable)
72 variables;
73 };
74
75 /**
76 * The configuration file can contain multiple sets of bindings. Apart from the
77 * default set (name == "default"), you can specify other sets and change the
78 * currently active set of bindings by using the "mode <name>" command.
79 *
80 */
81 struct Mode {
82 char *name;
83 bool pango_markup;
84 struct bindings_head *bindings;
85
86 SLIST_ENTRY(Mode)
87 modes;
88 };
89
90 /**
91 * Holds part of the configuration (the part which is not already in dedicated
92 * structures in include/data.h).
93 *
94 */
95 struct Config {
96 const char *terminal;
97 i3Font font;
98
99 char *ipc_socket_path;
100 char *restart_state_path;
101
102 layout_t default_layout;
103 int container_stack_limit;
104 int container_stack_limit_value;
105 int default_border_width;
106 int default_floating_border_width;
107
108 /** Default orientation for new containers */
109 int default_orientation;
110
111 /** By default, focus follows mouse. If the user explicitly wants to
112 * turn this off (and instead rely only on the keyboard for changing
113 * focus), we allow them to do this with this relatively special option.
114 * It is not planned to add any different focus models. */
115 bool disable_focus_follows_mouse;
116
117 /** By default, when switching focus to a window on a different output
118 * (e.g. focusing a window on workspace 3 on output VGA-1, coming from
119 * workspace 2 on LVDS-1), the mouse cursor is warped to the center of
120 * that window.
121 *
122 * With the mouse_warping option, you can control when the mouse cursor
123 * should be warped. "none" disables warping entirely, whereas "output"
124 * is the default behavior described above. */
125 warping_t mouse_warping;
126
127 /** Remove borders if they are adjacent to the screen edge.
128 * This is useful if you are reaching scrollbar on the edge of the
129 * screen or do not want to waste a single pixel of displayspace.
130 * By default, this is disabled. */
131 hide_edge_borders_mode_t hide_edge_borders;
132
133 /** By default, a workspace bar is drawn at the bottom of the screen.
134 * If you want to have a more fancy bar, it is recommended to replace
135 * the whole bar by dzen2, for example using the i3-wsbar script which
136 * comes with i3. Thus, you can turn it off entirely. */
137 bool disable_workspace_bar;
138
139 /** When focus wrapping is enabled (the default), attempting to
140 * move focus past the edge of the screen (in other words, in a
141 * direction in which there are no more containers to focus) will
142 * cause the focus to wrap to the opposite edge of the current
143 * container. When it is disabled, nothing happens; the current
144 * focus is preserved.
145 *
146 * Additionally, focus wrapping may be forced. Think of the
147 * following layout: Horizontal workspace with a tabbed con on the
148 * left of the screen and a terminal on the right of the
149 * screen. You are in the second container in the tabbed container
150 * and focus to the right. By default, i3 will set focus to the
151 * terminal on the right. If you are in the first container in the
152 * tabbed container however, focusing to the left will
153 * wrap. Setting focus_wrapping to FOCUS_WRAPPING_FORCE forces i3
154 * to always wrap, which will result in you having to use "focus
155 * parent" more often. */
156 focus_wrapping_t focus_wrapping;
157
158 /** By default, use the RandR API for multi-monitor setups.
159 * Unfortunately, the nVidia binary graphics driver doesn't support
160 * this API. Instead, it only support the less powerful Xinerama API,
161 * which can be enabled by this option.
162 *
163 * Note: this option takes only effect on the initial startup (eg.
164 * reconfiguration is not possible). On startup, the list of screens
165 * is fetched once and never updated. */
166 bool force_xinerama;
167
168 /** Don’t use RandR 1.5 for querying outputs. */
169 bool disable_randr15;
170
171 /** Overwrites output detection (for testing), see src/fake_outputs.c */
172 char *fake_outputs;
173
174 /** Automatic workspace back and forth switching. If this is set, a
175 * switch to the currently active workspace will switch to the
176 * previously focused one instead, making it possible to fast toggle
177 * between two workspaces. */
178 bool workspace_auto_back_and_forth;
179
180 /** By default, urgency is cleared immediately when switching to another
181 * workspace leads to focusing the con with the urgency hint. When having
182 * multiple windows on that workspace, the user needs to guess which
183 * application raised the event. To prevent this, the reset of the urgency
184 * flag can be delayed using an urgency timer. */
185 float workspace_urgency_timer;
186
187 /** Behavior when a window sends a NET_ACTIVE_WINDOW message. */
188 enum {
189 /* Focus if the target workspace is visible, set urgency hint otherwise. */
190 FOWA_SMART,
191 /* Always set the urgency hint. */
192 FOWA_URGENT,
193 /* Always focus the window. */
194 FOWA_FOCUS,
195 /* Ignore the request (no focus, no urgency hint). */
196 FOWA_NONE
197 } focus_on_window_activation;
198
199 /** Specifies whether or not marks should be displayed in the window
200 * decoration. Marks starting with a "_" will be ignored either way. */
201 bool show_marks;
202
203 /** Title alignment options. */
204 enum {
205 ALIGN_LEFT,
206 ALIGN_CENTER,
207 ALIGN_RIGHT
208 } title_align;
209
210 /** The default border style for new windows. */
211 border_style_t default_border;
212
213 /** The default border style for new floating windows. */
214 border_style_t default_floating_border;
215
216 /** The modifier which needs to be pressed in combination with your mouse
217 * buttons to do things with floating windows (move, resize) */
218 uint32_t floating_modifier;
219
220 /** Maximum and minimum dimensions of a floating window */
221 int32_t floating_maximum_width;
222 int32_t floating_maximum_height;
223 int32_t floating_minimum_width;
224 int32_t floating_minimum_height;
225
226 /* Color codes are stored here */
227 struct config_client {
228 color_t background;
229 struct Colortriple focused;
230 struct Colortriple focused_inactive;
231 struct Colortriple unfocused;
232 struct Colortriple urgent;
233 struct Colortriple placeholder;
234 } client;
235 struct config_bar {
236 struct Colortriple focused;
237 struct Colortriple unfocused;
238 struct Colortriple urgent;
239 } bar;
240
241 /** What should happen when a new popup is opened during fullscreen mode */
242 enum {
243 /* display (and focus) the popup when it belongs to the fullscreen
244 * window only. */
245 PDF_SMART = 0,
246
247 /* leave fullscreen mode unconditionally */
248 PDF_LEAVE_FULLSCREEN = 1,
249
250 /* just ignore the popup, that is, don’t map it */
251 PDF_IGNORE = 2,
252 } popup_during_fullscreen;
253
254 /* The number of currently parsed barconfigs */
255 int number_barconfigs;
256
257 /* Gap sizes */
258 gaps_t gaps;
259
260 /* Should single containers on a workspace receive a border? */
261 smart_borders_t smart_borders;
262
263 /* Disable gaps if there is only one container on the workspace */
264 smart_gaps_t smart_gaps;
265 };
266
267 /**
268 * Holds the status bar configuration (i3bar). One of these structures is
269 * created for each 'bar' block in the config.
270 *
271 */
272 struct Barconfig {
273 /** Automatically generated ID for this bar config. Used by the bar process
274 * to request a specific configuration. */
275 char *id;
276
277 /** Number of outputs in the outputs array */
278 int num_outputs;
279 /** Outputs on which this bar should show up on. We use an array for
280 * simplicity (since we store just strings). */
281 char **outputs;
282
283 /* List of outputs on which the tray is allowed to be shown, in order.
284 * The special value "none" disables it (per default, it will be shown) and
285 * the special value "primary" enabled it on the primary output. */
286 TAILQ_HEAD(tray_outputs_head, tray_output_t)
287 tray_outputs;
288
289 /* Padding around the tray icons. */
290 int tray_padding;
291
292 /** Path to the i3 IPC socket. This option is discouraged since programs
293 * can find out the path by looking for the I3_SOCKET_PATH property on the
294 * root window! */
295 char *socket_path;
296
297 /** Bar display mode (hide unless modifier is pressed or show in dock mode or always hide in invisible mode) */
298 enum { M_DOCK = 0,
299 M_HIDE = 1,
300 M_INVISIBLE = 2 } mode;
301
302 /* The current hidden_state of the bar, which indicates whether it is hidden or shown */
303 enum { S_HIDE = 0,
304 S_SHOW = 1 } hidden_state;
305
306 /** Bar modifier (to show bar when in hide mode). */
307 uint32_t modifier;
308
309 TAILQ_HEAD(bar_bindings_head, Barbinding)
310 bar_bindings;
311
312 /** Bar position (bottom by default). */
313 enum { P_BOTTOM = 0,
314 P_TOP = 1 } position;
315
316 /** Command that should be run to execute i3bar, give a full path if i3bar is not
317 * in your $PATH.
318 * By default just 'i3bar' is executed. */
319 char *i3bar_command;
320
321 /** Command that should be run to get a statusline, for example 'i3status'.
322 * Will be passed to the shell. */
323 char *status_command;
324
325 /** Font specification for all text rendered on the bar. */
326 char *font;
327
328 /** A custom separator to use instead of a vertical line. */
329 char *separator_symbol;
330
331 /** Hide workspace buttons? Configuration option is 'workspace_buttons no'
332 * but we invert the bool to get the correct default when initializing with
333 * zero. */
334 bool hide_workspace_buttons;
335
336 /** The minimal width for workspace buttons. */
337 int workspace_min_width;
338
339 /** Strip workspace numbers? Configuration option is
340 * 'strip_workspace_numbers yes'. */
341 bool strip_workspace_numbers;
342
343 /** Strip workspace name? Configuration option is
344 * 'strip_workspace_name yes'. */
345 bool strip_workspace_name;
346
347 /** Hide mode button? Configuration option is 'binding_mode_indicator no'
348 * but we invert the bool for the same reason as hide_workspace_buttons.*/
349 bool hide_binding_mode_indicator;
350
351 /** Enable verbose mode? Useful for debugging purposes. */
352 bool verbose;
353
354 /** Defines the height of the bar in pixels. */
355 uint32_t bar_height;
356
357 struct bar_colors {
358 char *background;
359 char *statusline;
360 char *separator;
361
362 char *focused_background;
363 char *focused_statusline;
364 char *focused_separator;
365
366 char *focused_workspace_border;
367 char *focused_workspace_bg;
368 char *focused_workspace_text;
369
370 char *active_workspace_border;
371 char *active_workspace_bg;
372 char *active_workspace_text;
373
374 char *inactive_workspace_border;
375 char *inactive_workspace_bg;
376 char *inactive_workspace_text;
377
378 char *urgent_workspace_border;
379 char *urgent_workspace_bg;
380 char *urgent_workspace_text;
381
382 char *binding_mode_border;
383 char *binding_mode_bg;
384 char *binding_mode_text;
385 } colors;
386
387 TAILQ_ENTRY(Barconfig)
388 configs;
389 };
390
391 /**
392 * Defines a mouse command to be executed instead of the default behavior when
393 * clicking on the non-statusline part of i3bar.
394 *
395 */
396 struct Barbinding {
397 /** The button to be used (e.g., 1 for "button1"). */
398 int input_code;
399
400 /** The command which is to be executed for this button. */
401 char *command;
402
403 /** If true, the command will be executed after the button is released. */
404 bool release;
405
406 TAILQ_ENTRY(Barbinding)
407 bindings;
408 };
409
410 struct tray_output_t {
411 char *output;
412
413 TAILQ_ENTRY(tray_output_t)
414 tray_outputs;
415 };
416
417 typedef enum {
418 C_VALIDATE,
419 C_LOAD,
420 C_RELOAD,
421 } config_load_t;
422
423 /**
424 * (Re-)loads the configuration file (sets useful defaults before).
425 *
426 * If you specify override_configpath, only this path is used to look for a
427 * configuration file.
428 *
429 * load_type specifies the type of loading: C_VALIDATE is used to only verify
430 * the correctness of the config file (used with the flag -C). C_LOAD will load
431 * the config for normal use and display errors in the nagbar. C_RELOAD will
432 * also clear the previous config.
433 */
434 bool load_configuration(const char *override_configfile, config_load_t load_type);
435
436 /**
437 * Ungrabs all keys, to be called before re-grabbing the keys because of a
438 * mapping_notify event or a configuration file reload
439 *
440 */
441 void ungrab_all_keys(xcb_connection_t *conn);
442
443 /**
444 * Sends the current bar configuration as an event to all barconfig_update listeners.
445 *
446 */
447 void update_barconfig(void);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * include/data.h: This file defines all data structures used by i3
7 *
8 */
9 #pragma once
10
11 #include "libi3.h"
12
13 #define SN_API_NOT_YET_FROZEN 1
14 #include <libsn/sn-launcher.h>
15
16 #include <xcb/randr.h>
17 #include <stdbool.h>
18 #include <pcre.h>
19 #include <sys/time.h>
20
21 #include "queue.h"
22
23 /*
24 * To get the big concept: There are helper structures like struct
25 * Workspace_Assignment. Every struct which is also defined as type (see
26 * forward definitions) is considered to be a major structure, thus important.
27 *
28 * The following things are all stored in a 'Con', from very high level (the
29 * biggest Cons) to very small (a single window):
30 *
31 * 1) X11 root window (as big as all your outputs combined)
32 * 2) output (like LVDS1)
33 * 3) content container, dockarea containers
34 * 4) workspaces
35 * 5) split containers
36 * ... (you can arbitrarily nest split containers)
37 * 6) X11 window containers
38 *
39 */
40
41 /* Forward definitions */
42 typedef struct Binding Binding;
43 typedef struct Rect Rect;
44 typedef struct xoutput Output;
45 typedef struct Con Con;
46 typedef struct Match Match;
47 typedef struct Assignment Assignment;
48 typedef struct Window i3Window;
49 typedef struct gaps_t gaps_t;
50 typedef struct mark_t mark_t;
51
52 /******************************************************************************
53 * Helper types
54 *****************************************************************************/
55 typedef enum { D_LEFT,
56 D_RIGHT,
57 D_UP,
58 D_DOWN } direction_t;
59 typedef enum { NO_ORIENTATION = 0,
60 HORIZ,
61 VERT } orientation_t;
62 typedef enum { BEFORE,
63 AFTER } position_t;
64 typedef enum { BS_NORMAL = 0,
65 BS_NONE = 1,
66 BS_PIXEL = 2 } border_style_t;
67
68 /** parameter to specify whether tree_close_internal() and x_window_kill() should kill
69 * only this specific window or the whole X11 client */
70 typedef enum { DONT_KILL_WINDOW = 0,
71 KILL_WINDOW = 1,
72 KILL_CLIENT = 2 } kill_window_t;
73
74 /** describes if the window is adjacent to the output (physical screen) edges. */
75 typedef enum { ADJ_NONE = 0,
76 ADJ_LEFT_SCREEN_EDGE = (1 << 0),
77 ADJ_RIGHT_SCREEN_EDGE = (1 << 1),
78 ADJ_UPPER_SCREEN_EDGE = (1 << 2),
79 ADJ_LOWER_SCREEN_EDGE = (1 << 4) } adjacent_t;
80
81 typedef enum { SMART_BORDERS_OFF,
82 SMART_BORDERS_ON,
83 SMART_BORDERS_NO_GAPS } smart_borders_t;
84
85 typedef enum { SMART_GAPS_OFF,
86 SMART_GAPS_ON,
87 SMART_GAPS_INVERSE_OUTER } smart_gaps_t;
88
89 typedef enum { HEBM_NONE = ADJ_NONE,
90 HEBM_VERTICAL = ADJ_LEFT_SCREEN_EDGE | ADJ_RIGHT_SCREEN_EDGE,
91 HEBM_HORIZONTAL = ADJ_UPPER_SCREEN_EDGE | ADJ_LOWER_SCREEN_EDGE,
92 HEBM_BOTH = HEBM_VERTICAL | HEBM_HORIZONTAL,
93 HEBM_SMART = (1 << 5),
94 HEBM_SMART_NO_GAPS = (1 << 6) } hide_edge_borders_mode_t;
95
96 typedef enum { MM_REPLACE,
97 MM_ADD } mark_mode_t;
98
99 /**
100 * Container layouts. See Con::layout.
101 */
102 typedef enum {
103 L_DEFAULT = 0,
104 L_STACKED = 1,
105 L_TABBED = 2,
106 L_DOCKAREA = 3,
107 L_OUTPUT = 4,
108 L_SPLITV = 5,
109 L_SPLITH = 6
110 } layout_t;
111
112 /**
113 * Binding input types. See Binding::input_type.
114 */
115 typedef enum {
116 B_KEYBOARD = 0,
117 B_MOUSE = 1
118 } input_type_t;
119
120 /**
121 * Bitmask for matching XCB_XKB_GROUP_1 to XCB_XKB_GROUP_4.
122 */
123 typedef enum {
124 I3_XKB_GROUP_MASK_ANY = 0,
125 I3_XKB_GROUP_MASK_1 = (1 << 0),
126 I3_XKB_GROUP_MASK_2 = (1 << 1),
127 I3_XKB_GROUP_MASK_3 = (1 << 2),
128 I3_XKB_GROUP_MASK_4 = (1 << 3)
129 } i3_xkb_group_mask_t;
130
131 /**
132 * The lower 16 bits contain a xcb_key_but_mask_t, the higher 16 bits contain
133 * an i3_xkb_group_mask_t. This type is necessary for the fallback logic to
134 * work when handling XKB groups (see ticket #1775) and makes the code which
135 * locates keybindings upon KeyPress/KeyRelease events simpler.
136 */
137 typedef uint32_t i3_event_state_mask_t;
138
139 /**
140 * Mouse pointer warping modes.
141 */
142 typedef enum {
143 POINTER_WARPING_OUTPUT = 0,
144 POINTER_WARPING_NONE = 1
145 } warping_t;
146
147 struct gaps_t {
148 int inner;
149 int top;
150 int right;
151 int bottom;
152 int left;
153 };
154
155 /**
156 * Focus wrapping modes.
157 */
158 typedef enum {
159 FOCUS_WRAPPING_OFF = 0,
160 FOCUS_WRAPPING_ON = 1,
161 FOCUS_WRAPPING_FORCE = 2,
162 FOCUS_WRAPPING_WORKSPACE = 3
163 } focus_wrapping_t;
164
165 /**
166 * Stores a rectangle, for example the size of a window, the child window etc.
167 *
168 * Note that x and y can contain signed values in some cases (for example when
169 * used for the coordinates of a window, which can be set outside of the
170 * visible area, but not when specifying the position of a workspace for the
171 * _NET_WM_WORKAREA hint). Not declaring x/y as int32_t saves us a lot of
172 * typecasts.
173 *
174 */
175 struct Rect {
176 uint32_t x;
177 uint32_t y;
178 uint32_t width;
179 uint32_t height;
180 };
181
182 /**
183 * Stores the reserved pixels on each screen edge read from a
184 * _NET_WM_STRUT_PARTIAL.
185 *
186 */
187 struct reservedpx {
188 uint32_t left;
189 uint32_t right;
190 uint32_t top;
191 uint32_t bottom;
192 };
193
194 /**
195 * Stores a width/height pair, used as part of deco_render_params to check
196 * whether the rects width/height have changed.
197 *
198 */
199 struct width_height {
200 uint32_t w;
201 uint32_t h;
202 };
203
204 /**
205 * Stores the parameters for rendering a window decoration. This structure is
206 * cached in every Con and no re-rendering will be done if the parameters have
207 * not changed (only the pixmaps will be copied).
208 *
209 */
210 struct deco_render_params {
211 struct Colortriple *color;
212 int border_style;
213 struct width_height con_rect;
214 struct width_height con_window_rect;
215 Rect con_deco_rect;
216 color_t background;
217 layout_t parent_layout;
218 bool con_is_leaf;
219 };
220
221 /**
222 * Stores which workspace (by name or number) goes to which output and its gaps config.
223 *
224 */
225 struct Workspace_Assignment {
226 char *name;
227 char *output;
228 gaps_t gaps;
229
230 TAILQ_ENTRY(Workspace_Assignment)
231 ws_assignments;
232 };
233
234 struct Ignore_Event {
235 int sequence;
236 int response_type;
237 time_t added;
238
239 SLIST_ENTRY(Ignore_Event)
240 ignore_events;
241 };
242
243 /**
244 * Stores internal information about a startup sequence, like the workspace it
245 * was initiated on.
246 *
247 */
248 struct Startup_Sequence {
249 /** startup ID for this sequence, generated by libstartup-notification */
250 char *id;
251 /** workspace on which this startup was initiated */
252 char *workspace;
253 /** libstartup-notification context for this launch */
254 SnLauncherContext *context;
255 /** time at which this sequence should be deleted (after it was marked as
256 * completed) */
257 time_t delete_at;
258
259 TAILQ_ENTRY(Startup_Sequence)
260 sequences;
261 };
262
263 /**
264 * Regular expression wrapper. It contains the pattern itself as a string (like
265 * ^foo[0-9]$) as well as a pointer to the compiled PCRE expression and the
266 * pcre_extra data returned by pcre_study().
267 *
268 * This makes it easier to have a useful logfile, including the matching or
269 * non-matching pattern.
270 *
271 */
272 struct regex {
273 char *pattern;
274 pcre *regex;
275 pcre_extra *extra;
276 };
277
278 /**
279 * Stores a resolved keycode (from a keysym), including the modifier mask. Will
280 * be passed to xcb_grab_key().
281 *
282 */
283 struct Binding_Keycode {
284 xcb_keycode_t keycode;
285 i3_event_state_mask_t modifiers;
286
287 TAILQ_ENTRY(Binding_Keycode)
288 keycodes;
289 };
290
291 /******************************************************************************
292 * Major types
293 *****************************************************************************/
294
295 /**
296 * Holds a keybinding, consisting of a keycode combined with modifiers and the
297 * command which is executed as soon as the key is pressed (see
298 * src/config_parser.c)
299 *
300 */
301 struct Binding {
302 /* The type of input this binding is for. (Mouse bindings are not yet
303 * implemented. All bindings are currently assumed to be keyboard bindings.) */
304 input_type_t input_type;
305
306 /** If true, the binding should be executed upon a KeyRelease event, not a
307 * KeyPress (the default). */
308 enum {
309 /* This binding will only be executed upon KeyPress events */
310 B_UPON_KEYPRESS = 0,
311 /* This binding will be executed either upon a KeyRelease event, or… */
312 B_UPON_KEYRELEASE = 1,
313 /* …upon a KeyRelease event, even if the modifiers don’t match. This
314 * state is triggered from get_binding() when the corresponding
315 * KeyPress (!) happens, so that users can release the modifier keys
316 * before releasing the actual key. */
317 B_UPON_KEYRELEASE_IGNORE_MODS = 2,
318 } release;
319
320 /** If this is true for a mouse binding, the binding should be executed
321 * when the button is pressed over the window border. */
322 bool border;
323
324 /** If this is true for a mouse binding, the binding should be executed
325 * when the button is pressed over any part of the window, not just the
326 * title bar (default). */
327 bool whole_window;
328
329 /** If this is true for a mouse binding, the binding should only be
330 * executed if the button press was not on the titlebar. */
331 bool exclude_titlebar;
332
333 /** Keycode to bind */
334 uint32_t keycode;
335
336 /** Bitmask which is applied against event->state for KeyPress and
337 * KeyRelease events to determine whether this binding applies to the
338 * current state. */
339 i3_event_state_mask_t event_state_mask;
340
341 /** Symbol the user specified in configfile, if any. This needs to be
342 * stored with the binding to be able to re-convert it into a keycode
343 * if the keyboard mapping changes (using Xmodmap for example) */
344 char *symbol;
345
346 /** Only in use if symbol != NULL. Contains keycodes which generate the
347 * specified symbol. Useful for unbinding and checking which binding was
348 * used when a key press event comes in. */
349 TAILQ_HEAD(keycodes_head, Binding_Keycode)
350 keycodes_head;
351
352 /** Command, like in command mode */
353 char *command;
354
355 TAILQ_ENTRY(Binding)
356 bindings;
357 };
358
359 /**
360 * Holds a command specified by either an:
361 * - exec-line
362 * - exec_always-line
363 * in the config (see src/config.c)
364 *
365 */
366 struct Autostart {
367 /** Command, like in command mode */
368 char *command;
369 /** no_startup_id flag for start_application(). Determines whether a
370 * startup notification context/ID should be created. */
371 bool no_startup_id;
372
373 TAILQ_ENTRY(Autostart)
374 autostarts;
375
376 TAILQ_ENTRY(Autostart)
377 autostarts_always;
378 };
379
380 struct output_name {
381 char *name;
382
383 SLIST_ENTRY(output_name)
384 names;
385 };
386
387 /**
388 * An Output is a physical output on your graphics driver. Outputs which
389 * are currently in use have (output->active == true). Each output has a
390 * position and a mode. An output usually corresponds to one connected
391 * screen (except if you are running multiple screens in clone mode).
392 *
393 */
394 struct xoutput {
395 /** Output id, so that we can requery the output directly later */
396 xcb_randr_output_t id;
397
398 /** Whether the output is currently active (has a CRTC attached with a
399 * valid mode) */
400 bool active;
401
402 /** Internal flags, necessary for querying RandR screens (happens in
403 * two stages) */
404 bool changed;
405 bool to_be_disabled;
406 bool primary;
407
408 /** List of names for the output.
409 * An output always has at least one name; the first name is
410 * considered the primary one. */
411 SLIST_HEAD(names_head, output_name)
412 names_head;
413
414 /** Pointer to the Con which represents this output */
415 Con *con;
416
417 /** x, y, width, height */
418 Rect rect;
419
420 TAILQ_ENTRY(xoutput)
421 outputs;
422 };
423
424 /**
425 * A 'Window' is a type which contains an xcb_window_t and all the related
426 * information (hints like _NET_WM_NAME for that window).
427 *
428 */
429 struct Window {
430 xcb_window_t id;
431
432 /** Holds the xcb_window_t (just an ID) for the leader window (logical
433 * parent for toolwindows and similar floating windows) */
434 xcb_window_t leader;
435 xcb_window_t transient_for;
436
437 /** Pointers to the Assignments which were already ran for this Window
438 * (assignments run only once) */
439 uint32_t nr_assignments;
440 Assignment **ran_assignments;
441
442 char *class_class;
443 char *class_instance;
444
445 /** The name of the window. */
446 i3String *name;
447
448 /** The WM_WINDOW_ROLE of this window (for example, the pidgin buddy window
449 * sets "buddy list"). Useful to match specific windows in assignments or
450 * for_window. */
451 char *role;
452
453 /** Flag to force re-rendering the decoration upon changes */
454 bool name_x_changed;
455
456 /** Whether the application used _NET_WM_NAME */
457 bool uses_net_wm_name;
458
459 /** Whether the application needs to receive WM_TAKE_FOCUS */
460 bool needs_take_focus;
461
462 /** Whether this window accepts focus. We store this inverted so that the
463 * default will be 'accepts focus'. */
464 bool doesnt_accept_focus;
465
466 /** The _NET_WM_WINDOW_TYPE for this window. */
467 xcb_atom_t window_type;
468
469 /** The _NET_WM_DESKTOP for this window. */
470 uint32_t wm_desktop;
471
472 /** Whether the window says it is a dock window */
473 enum { W_NODOCK = 0,
474 W_DOCK_TOP = 1,
475 W_DOCK_BOTTOM = 2 } dock;
476
477 /** When this window was marked urgent. 0 means not urgent */
478 struct timeval urgent;
479
480 /** Pixels the window reserves. left/right/top/bottom */
481 struct reservedpx reserved;
482
483 /** Depth of the window */
484 uint16_t depth;
485
486 /* the wanted size of the window, used in combination with size
487 * increments (see below). */
488 int base_width;
489 int base_height;
490
491 /* minimum increment size specified for the window (in pixels) */
492 int width_increment;
493 int height_increment;
494
495 /* Minimum size specified for the window. */
496 int min_width;
497 int min_height;
498
499 /* Maximum size specified for the window. */
500 int max_width;
501 int max_height;
502
503 /* aspect ratio from WM_NORMAL_HINTS (MPlayer uses this for example) */
504 double min_aspect_ratio;
505 double max_aspect_ratio;
506
507 /** The window has a nonrectangular shape. */
508 bool shaped;
509 /** The window has a nonrectangular input shape. */
510 bool input_shaped;
511
512 /* Time when the window became managed. Used to determine whether a window
513 * should be swallowed after initial management. */
514 time_t managed_since;
515 };
516
517 /**
518 * A "match" is a data structure which acts like a mask or expression to match
519 * certain windows or not. For example, when using commands, you can specify a
520 * command like this: [title="*Firefox*"] kill. The title member of the match
521 * data structure will then be filled and i3 will check each window using
522 * match_matches_window() to find the windows affected by this command.
523 *
524 */
525 struct Match {
526 /* Set if a criterion was specified incorrectly. */
527 char *error;
528
529 struct regex *title;
530 struct regex *application;
531 struct regex *class;
532 struct regex *instance;
533 struct regex *mark;
534 struct regex *window_role;
535 struct regex *workspace;
536 xcb_atom_t window_type;
537 enum {
538 U_DONTCHECK = -1,
539 U_LATEST = 0,
540 U_OLDEST = 1
541 } urgent;
542 enum {
543 M_DONTCHECK = -1,
544 M_NODOCK = 0,
545 M_DOCK_ANY = 1,
546 M_DOCK_TOP = 2,
547 M_DOCK_BOTTOM = 3
548 } dock;
549 xcb_window_t id;
550 enum { WM_ANY = 0,
551 WM_TILING_AUTO,
552 WM_TILING_USER,
553 WM_TILING,
554 WM_FLOATING_AUTO,
555 WM_FLOATING_USER,
556 WM_FLOATING } window_mode;
557 Con *con_id;
558
559 /* Where the window looking for a match should be inserted:
560 *
561 * M_HERE = the matched container will be replaced by the window
562 * (layout saving)
563 * M_ASSIGN_WS = the matched container will be inserted in the target_ws.
564 * M_BELOW = the window will be inserted as a child of the matched container
565 * (dockareas)
566 *
567 */
568 enum { M_HERE = 0,
569 M_ASSIGN_WS,
570 M_BELOW } insert_where;
571
572 TAILQ_ENTRY(Match)
573 matches;
574
575 /* Whether this match was generated when restarting i3 inplace.
576 * Leads to not setting focus when managing a new window, because the old
577 * focus stack should be restored. */
578 bool restart_mode;
579 };
580
581 /**
582 * An Assignment makes specific windows go to a specific workspace/output or
583 * run a command for that window. With this mechanism, the user can -- for
584 * example -- assign their browser to workspace "www". Checking if a window is
585 * assigned works by comparing the Match data structure with the window (see
586 * match_matches_window()).
587 *
588 */
589 struct Assignment {
590 /** type of this assignment:
591 *
592 * A_COMMAND = run the specified command for the matching window
593 * A_TO_WORKSPACE = assign the matching window to the specified workspace
594 * A_NO_FOCUS = don't focus matched window when it is managed
595 *
596 * While the type is a bitmask, only one value can be set at a time. It is
597 * a bitmask to allow filtering for multiple types, for example in the
598 * assignment_for() function.
599 *
600 */
601 enum {
602 A_ANY = 0,
603 A_COMMAND = (1 << 0),
604 A_TO_WORKSPACE = (1 << 1),
605 A_NO_FOCUS = (1 << 2),
606 A_TO_WORKSPACE_NUMBER = (1 << 3),
607 A_TO_OUTPUT = (1 << 4)
608 } type;
609
610 /** the criteria to check if a window matches */
611 Match match;
612
613 /** destination workspace/command/output, depending on the type */
614 union {
615 char *command;
616 char *workspace;
617 char *output;
618 } dest;
619
620 TAILQ_ENTRY(Assignment)
621 assignments;
622 };
623
624 /** Fullscreen modes. Used by Con.fullscreen_mode. */
625 typedef enum { CF_NONE = 0,
626 CF_OUTPUT = 1,
627 CF_GLOBAL = 2 } fullscreen_mode_t;
628
629 struct mark_t {
630 char *name;
631
632 TAILQ_ENTRY(mark_t)
633 marks;
634 };
635
636 /**
637 * A 'Con' represents everything from the X11 root window down to a single X11 window.
638 *
639 */
640 struct Con {
641 bool mapped;
642
643 /* Should this container be marked urgent? This gets set when the window
644 * inside this container (if any) sets the urgency hint, for example. */
645 bool urgent;
646
647 /** This counter contains the number of UnmapNotify events for this
648 * container (or, more precisely, for its ->frame) which should be ignored.
649 * UnmapNotify events need to be ignored when they are caused by i3 itself,
650 * for example when reparenting or when unmapping the window on a workspace
651 * change. */
652 uint8_t ignore_unmap;
653
654 /* The surface used for the frame window. */
655 surface_t frame;
656 surface_t frame_buffer;
657 bool pixmap_recreated;
658
659 enum {
660 CT_ROOT = 0,
661 CT_OUTPUT = 1,
662 CT_CON = 2,
663 CT_FLOATING_CON = 3,
664 CT_WORKSPACE = 4,
665 CT_DOCKAREA = 5
666 } type;
667
668 /** the workspace number, if this Con is of type CT_WORKSPACE and the
669 * workspace is not a named workspace (for named workspaces, num == -1) */
670 int num;
671
672 /** Only applicable for containers of type CT_WORKSPACE. */
673 gaps_t gaps;
674
675 struct Con *parent;
676
677 /* The position and size for this con. These coordinates are absolute. Note
678 * that the rect of a container does not include the decoration. */
679 struct Rect rect;
680 /* The position and size of the actual client window. These coordinates are
681 * relative to the container's rect. */
682 struct Rect window_rect;
683 /* The position and size of the container's decoration. These coordinates
684 * are relative to the container's parent's rect. */
685 struct Rect deco_rect;
686 /** the geometry this window requested when getting mapped */
687 struct Rect geometry;
688
689 char *name;
690
691 /** The format with which the window's name should be displayed. */
692 char *title_format;
693
694 /* a sticky-group is an identifier which bundles several containers to a
695 * group. The contents are shared between all of them, that is they are
696 * displayed on whichever of the containers is currently visible */
697 char *sticky_group;
698
699 /* user-definable marks to jump to this container later */
700 TAILQ_HEAD(marks_head, mark_t)
701 marks_head;
702 /* cached to decide whether a redraw is needed */
703 bool mark_changed;
704
705 double percent;
706
707 /* the x11 border pixel attribute */
708 int border_width;
709 int current_border_width;
710
711 struct Window *window;
712
713 /* timer used for disabling urgency */
714 struct ev_timer *urgency_timer;
715
716 /** Cache for the decoration rendering */
717 struct deco_render_params *deco_render_params;
718
719 /* Only workspace-containers can have floating clients */
720 TAILQ_HEAD(floating_head, Con)
721 floating_head;
722
723 TAILQ_HEAD(nodes_head, Con)
724 nodes_head;
725
726 TAILQ_HEAD(focus_head, Con)
727 focus_head;
728
729 TAILQ_HEAD(swallow_head, Match)
730 swallow_head;
731
732 fullscreen_mode_t fullscreen_mode;
733
734 /* Whether this window should stick to the glass. This corresponds to
735 * the _NET_WM_STATE_STICKY atom and will only be respected if the
736 * window is floating. */
737 bool sticky;
738
739 /* layout is the layout of this container: one of split[v|h], stacked or
740 * tabbed. Special containers in the tree (above workspaces) have special
741 * layouts like dockarea or output.
742 *
743 * last_split_layout is one of splitv or splith to support the old "layout
744 * default" command which by now should be "layout splitv" or "layout
745 * splith" explicitly.
746 *
747 * workspace_layout is only for type == CT_WORKSPACE cons. When you change
748 * the layout of a workspace without any children, i3 cannot just set the
749 * layout (because workspaces need to be splitv/splith to allow focus
750 * parent and opening new containers). Instead, it stores the requested
751 * layout in workspace_layout and creates a new split container with that
752 * layout whenever a new container is attached to the workspace. */
753 layout_t layout, last_split_layout, workspace_layout;
754 border_style_t border_style;
755 /** floating? (= not in tiling layout) This cannot be simply a bool
756 * because we want to keep track of whether the status was set by the
757 * application (by setting _NET_WM_WINDOW_TYPE appropriately) or by the
758 * user. The user’s choice overwrites automatic mode, of course. The
759 * order of the values is important because we check with >=
760 * FLOATING_AUTO_ON if a client is floating. */
761 enum {
762 FLOATING_AUTO_OFF = 0,
763 FLOATING_USER_OFF = 1,
764 FLOATING_AUTO_ON = 2,
765 FLOATING_USER_ON = 3
766 } floating;
767
768 TAILQ_ENTRY(Con)
769 nodes;
770
771 TAILQ_ENTRY(Con)
772 focused;
773
774 TAILQ_ENTRY(Con)
775 all_cons;
776
777 TAILQ_ENTRY(Con)
778 floating_windows;
779
780 /** callbacks */
781 void (*on_remove_child)(Con *);
782
783 enum {
784 /* Not a scratchpad window. */
785 SCRATCHPAD_NONE = 0,
786
787 /* Just moved to scratchpad, not resized by the user yet.
788 * Window will be auto-centered and sized appropriately. */
789 SCRATCHPAD_FRESH = 1,
790
791 /* The user changed position/size of the scratchpad window. */
792 SCRATCHPAD_CHANGED = 2
793 } scratchpad_state;
794
795 /* The ID of this container before restarting. Necessary to correctly
796 * interpret back-references in the JSON (such as the focus stack). */
797 int old_id;
798
799 /* Depth of the container window */
800 uint16_t depth;
801
802 /* The colormap for this con if a custom one is used. */
803 xcb_colormap_t colormap;
804 };
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * display_version.c: displays the running i3 version, runs as part of
7 * i3 --moreversion.
8 */
9 #pragma once
10
11 #include <config.h>
12
13 /**
14 * Connects to i3 to find out the currently running version. Useful since it
15 * might be different from the version compiled into this binary (maybe the
16 * user didn’t correctly install i3 or forgot te restart it).
17 *
18 * The output looks like this:
19 * Running i3 version: 4.2-202-gb8e782c (2012-08-12, branch "next") (pid 14804)
20 *
21 * The i3 binary you just called: /home/michael/i3/i3
22 * The i3 binary you are running: /home/michael/i3/i3
23 *
24 */
25 void display_running_version(void);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * drag.c: click and drag.
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 /** Callback for dragging */
14 typedef void (*callback_t)(Con *, Rect *, uint32_t, uint32_t,
15 const xcb_button_press_event_t *, const void *);
16
17 /** Macro to create a callback function for dragging */
18 #define DRAGGING_CB(name) \
19 static void name(Con *con, Rect *old_rect, uint32_t new_x, uint32_t new_y, \
20 const xcb_button_press_event_t *event, const void *extra)
21
22 /**
23 * This is the return value of a drag operation like drag_pointer.
24 *
25 * DRAGGING will indicate the drag action is still in progress and can be
26 * continued or resolved.
27 *
28 * DRAG_SUCCESS will indicate the intention of the drag action should be
29 * carried out.
30 *
31 * DRAG_REVERT will indicate an attempt should be made to restore the state of
32 * the involved windows to their condition before the drag.
33 *
34 * DRAG_ABORT will indicate that the intention of the drag action cannot be
35 * carried out (e.g. because the window has been unmapped).
36 *
37 */
38 typedef enum {
39 DRAGGING = 0,
40 DRAG_SUCCESS,
41 DRAG_REVERT,
42 DRAG_ABORT
43 } drag_result_t;
44
45 /**
46 * This function grabs your pointer and keyboard and lets you drag stuff around
47 * (borders). Every time you move your mouse, an XCB_MOTION_NOTIFY event will
48 * be received and the given callback will be called with the parameters
49 * specified (client, the original event), the original rect of the client,
50 * and the new coordinates (x, y).
51 *
52 * If use_threshold is set, dragging only starts after the user moves the
53 * pointer past a certain threshold. That is, the cursor will not be set and the
54 * callback will not be called until then.
55 *
56 */
57 drag_result_t drag_pointer(Con *con, const xcb_button_press_event_t *event,
58 xcb_window_t confine_to, int cursor,
59 bool use_threshold, callback_t callback,
60 const void *extra);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * ewmh.c: Get/set certain EWMH properties easily.
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 /**
14 * Updates all the EWMH desktop properties.
15 *
16 */
17 void ewmh_update_desktop_properties(void);
18
19 /**
20 * Updates _NET_CURRENT_DESKTOP with the current desktop number.
21 *
22 * EWMH: The index of the current desktop. This is always an integer between 0
23 * and _NET_NUMBER_OF_DESKTOPS - 1.
24 *
25 */
26 void ewmh_update_current_desktop(void);
27
28 /**
29 * Updates _NET_WM_DESKTOP for all windows.
30 * A request will only be made if the cached value differs from the calculated value.
31 *
32 */
33 void ewmh_update_wm_desktop(void);
34
35 /**
36 * Updates _NET_ACTIVE_WINDOW with the currently focused window.
37 *
38 * EWMH: The window ID of the currently active window or None if no window has
39 * the focus.
40 *
41 */
42 void ewmh_update_active_window(xcb_window_t window);
43
44 /**
45 * Updates _NET_WM_VISIBLE_NAME.
46 *
47 */
48 void ewmh_update_visible_name(xcb_window_t window, const char *name);
49
50 /**
51 * Updates the _NET_CLIENT_LIST hint. Used for window listers.
52 */
53 void ewmh_update_client_list(xcb_window_t *list, int num_windows);
54
55 /**
56 * Updates the _NET_CLIENT_LIST_STACKING hint. Necessary to move tabs in
57 * Chromium correctly.
58 *
59 * EWMH: These arrays contain all X Windows managed by the Window Manager.
60 * _NET_CLIENT_LIST has initial mapping order, starting with the oldest window.
61 * _NET_CLIENT_LIST_STACKING has bottom-to-top stacking order. These properties
62 * SHOULD be set and updated by the Window Manager.
63 *
64 */
65 void ewmh_update_client_list_stacking(xcb_window_t *stack, int num_windows);
66
67 /**
68 * Set or remove _NET_WM_STATE_STICKY on the window.
69 *
70 */
71 void ewmh_update_sticky(xcb_window_t window, bool sticky);
72
73 /**
74 * Set or remove _NEW_WM_STATE_FOCUSED on the window.
75 *
76 */
77 void ewmh_update_focused(xcb_window_t window, bool is_focused);
78
79 /**
80 * Set up the EWMH hints on the root window.
81 *
82 */
83 void ewmh_setup_hints(void);
84
85 /**
86 * i3 currently does not support _NET_WORKAREA, because it does not correspond
87 * to i3’s concept of workspaces. See also:
88 * https://bugs.i3wm.org/539
89 * https://bugs.i3wm.org/301
90 * https://bugs.i3wm.org/1038
91 *
92 * We need to actively delete this property because some display managers (e.g.
93 * LightDM) set it.
94 *
95 * EWMH: Contains a geometry for each desktop. These geometries specify an area
96 * that is completely contained within the viewport. Work area SHOULD be used by
97 * desktop applications to place desktop icons appropriately.
98 *
99 */
100 void ewmh_update_workarea(void);
101
102 /**
103 * Returns the workspace container as enumerated by the EWMH desktop model.
104 * Returns NULL if no workspace could be found for the index.
105 *
106 * This is the reverse of ewmh_get_workspace_index.
107 *
108 */
109 Con *ewmh_get_workspace_by_index(uint32_t idx);
110
111 /**
112 * Returns the EWMH desktop index for the workspace the given container is on.
113 * Returns NET_WM_DESKTOP_NONE if the desktop index cannot be determined.
114 *
115 * This is the reverse of ewmh_get_workspace_by_index.
116 *
117 */
118 uint32_t ewmh_get_workspace_index(Con *con);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * Faking outputs is useful in pathological situations (like network X servers
7 * which don’t support multi-monitor in a useful way) and for our testsuite.
8 *
9 */
10 #pragma once
11
12 #include <config.h>
13
14 /**
15 * Creates outputs according to the given specification.
16 * The specification must be in the format wxh+x+y, for example 1024x768+0+0,
17 * with multiple outputs separated by commas:
18 * 1900x1200+0+0,1280x1024+1900+0
19 *
20 */
21 void fake_outputs_init(const char *output_spec);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * floating.c: Floating windows.
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include "tree.h"
14
15 /** On which border was the dragging initiated? */
16 typedef enum { BORDER_LEFT = (1 << 0),
17 BORDER_RIGHT = (1 << 1),
18 BORDER_TOP = (1 << 2),
19 BORDER_BOTTOM = (1 << 3) } border_t;
20
21 /**
22 * Enables floating mode for the given container by detaching it from its
23 * parent, creating a new container around it and storing this container in the
24 * floating_windows list of the workspace.
25 *
26 */
27 void floating_enable(Con *con, bool automatic);
28
29 /**
30 * Disables floating mode for the given container by re-attaching the container
31 * to its old parent.
32 *
33 */
34 void floating_disable(Con *con);
35
36 /**
37 * Calls floating_enable() for tiling containers and floating_disable() for
38 * floating containers.
39 *
40 * If the automatic flag is set to true, this was an automatic update by a
41 * change of the window class from the application which can be overwritten by
42 * the user.
43 *
44 */
45 void toggle_floating_mode(Con *con, bool automatic);
46
47 /**
48 * Raises the given container in the list of floating containers
49 *
50 */
51 void floating_raise_con(Con *con);
52
53 /**
54 * Checks if con’s coordinates are within its workspace and re-assigns it to
55 * the actual workspace if not.
56 *
57 */
58 bool floating_maybe_reassign_ws(Con *con);
59
60 /**
61 * Centers a floating con above the specified rect.
62 *
63 */
64 void floating_center(Con *con, Rect rect);
65
66 /**
67 * Moves the given floating con to the current pointer position.
68 *
69 */
70 void floating_move_to_pointer(Con *con);
71
72 /**
73 * Called when the user clicked on the titlebar of a floating window.
74 * Calls the drag_pointer function with the drag_window callback
75 *
76 */
77 void floating_drag_window(Con *con, const xcb_button_press_event_t *event, bool use_threshold);
78
79 /**
80 * Called when the user clicked on a floating window while holding the
81 * floating_modifier and the right mouse button.
82 * Calls the drag_pointer function with the resize_window callback
83 *
84 */
85 void floating_resize_window(Con *con, const bool proportional, const xcb_button_press_event_t *event);
86
87 /**
88 * Called when a floating window is created or resized. This function resizes
89 * the window if its size is higher or lower than the configured maximum/minimum
90 * size, respectively or when adjustments are needed to conform to the
91 * configured size increments or aspect ratio limits.
92 *
93 * When prefer_height is true and the window needs to be resized because of the
94 * configured aspect ratio, the width is adjusted first, preserving the previous
95 * height.
96 *
97 */
98 void floating_check_size(Con *floating_con, bool prefer_height);
99
100 /**
101 * Repositions the CT_FLOATING_CON to have the coordinates specified by
102 * newrect, but only if the coordinates are not out-of-bounds. Also reassigns
103 * the floating con to a different workspace if this move was across different
104 * outputs.
105 *
106 */
107 bool floating_reposition(Con *con, Rect newrect);
108
109 /**
110 * Sets size of the CT_FLOATING_CON to specified dimensions. Might limit the
111 * actual size with regard to size constraints taken from user settings.
112 * Additionally, the dimensions may be upscaled until they're divisible by the
113 * window's size hints.
114 *
115 */
116 void floating_resize(Con *floating_con, uint32_t x, uint32_t y);
117
118 /**
119 * Fixes the coordinates of the floating window whenever the window gets
120 * reassigned to a different output (or when the output’s rect changes).
121 *
122 */
123 void floating_fix_coordinates(Con *con, Rect *old_rect, Rect *new_rect);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * handlers.c: Small handlers for various events (keypresses, focus changes,
7 * …).
8 *
9 */
10 #pragma once
11
12 #include <config.h>
13
14 #include <xcb/randr.h>
15
16 extern int randr_base;
17 extern int xkb_base;
18 extern int shape_base;
19
20 /**
21 * Adds the given sequence to the list of events which are ignored.
22 * If this ignore should only affect a specific response_type, pass
23 * response_type, otherwise, pass -1.
24 *
25 * Every ignored sequence number gets garbage collected after 5 seconds.
26 *
27 */
28 void add_ignore_event(const int sequence, const int response_type);
29
30 /**
31 * Checks if the given sequence is ignored and returns true if so.
32 *
33 */
34 bool event_is_ignored(const int sequence, const int response_type);
35
36 /**
37 * Takes an xcb_generic_event_t and calls the appropriate handler, based on the
38 * event type.
39 *
40 */
41 void handle_event(int type, xcb_generic_event_t *event);
42
43 /**
44 * Sets the appropriate atoms for the property handlers after the atoms were
45 * received from X11
46 *
47 */
48 void property_handlers_init(void);
49
50 #if 0
51 /**
52 * Configuration notifies are only handled because we need to set up ignore
53 * for the following enter notify events
54 *
55 */
56 int handle_configure_event(void *prophs, xcb_connection_t *conn, xcb_configure_notify_event_t *event);
57 #endif
58
59 #if 0
60 /**
61 * Handles _NET_WM_WINDOW_TYPE changes
62 *
63 */
64 int handle_window_type(void *data, xcb_connection_t *conn, uint8_t state,
65 xcb_window_t window, xcb_atom_t atom,
66 xcb_get_property_reply_t *property);
67 #endif
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * This public header defines the different constants and message types to use
7 * for the IPC interface to i3 (see docs/ipc for more information).
8 *
9 */
10 #pragma once
11
12 #include <stdint.h>
13
14 typedef struct i3_ipc_header {
15 /* 6 = strlen(I3_IPC_MAGIC) */
16 char magic[6];
17 uint32_t size;
18 uint32_t type;
19 } __attribute__((packed)) i3_ipc_header_t;
20
21 /*
22 * Messages from clients to i3
23 *
24 */
25
26 /** Never change this, only on major IPC breakage (don’t do that) */
27 #define I3_IPC_MAGIC "i3-ipc"
28
29 /** Deprecated: use I3_IPC_MESSAGE_TYPE_RUN_COMMAND */
30 #define I3_IPC_MESSAGE_TYPE_COMMAND 0
31
32 /** The payload of the message will be interpreted as a command */
33 #define I3_IPC_MESSAGE_TYPE_RUN_COMMAND 0
34
35 /** Requests the current workspaces from i3 */
36 #define I3_IPC_MESSAGE_TYPE_GET_WORKSPACES 1
37
38 /** Subscribe to the specified events */
39 #define I3_IPC_MESSAGE_TYPE_SUBSCRIBE 2
40
41 /** Requests the current outputs from i3 */
42 #define I3_IPC_MESSAGE_TYPE_GET_OUTPUTS 3
43
44 /** Requests the tree layout from i3 */
45 #define I3_IPC_MESSAGE_TYPE_GET_TREE 4
46
47 /** Request the current defined marks from i3 */
48 #define I3_IPC_MESSAGE_TYPE_GET_MARKS 5
49
50 /** Request the configuration for a specific 'bar' */
51 #define I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG 6
52
53 /** Request the i3 version */
54 #define I3_IPC_MESSAGE_TYPE_GET_VERSION 7
55
56 /** Request a list of configured binding modes. */
57 #define I3_IPC_MESSAGE_TYPE_GET_BINDING_MODES 8
58
59 /** Request the raw last loaded i3 config. */
60 #define I3_IPC_MESSAGE_TYPE_GET_CONFIG 9
61
62 /** Send a tick event to all subscribers. */
63 #define I3_IPC_MESSAGE_TYPE_SEND_TICK 10
64
65 /** Trigger an i3 sync protocol message via IPC. */
66 #define I3_IPC_MESSAGE_TYPE_SYNC 11
67
68 /*
69 * Messages from i3 to clients
70 *
71 */
72 #define I3_IPC_REPLY_TYPE_COMMAND 0
73 #define I3_IPC_REPLY_TYPE_WORKSPACES 1
74 #define I3_IPC_REPLY_TYPE_SUBSCRIBE 2
75 #define I3_IPC_REPLY_TYPE_OUTPUTS 3
76 #define I3_IPC_REPLY_TYPE_TREE 4
77 #define I3_IPC_REPLY_TYPE_MARKS 5
78 #define I3_IPC_REPLY_TYPE_BAR_CONFIG 6
79 #define I3_IPC_REPLY_TYPE_VERSION 7
80 #define I3_IPC_REPLY_TYPE_BINDING_MODES 8
81 #define I3_IPC_REPLY_TYPE_CONFIG 9
82 #define I3_IPC_REPLY_TYPE_TICK 10
83 #define I3_IPC_REPLY_TYPE_SYNC 11
84
85 /*
86 * Events from i3 to clients. Events have the first bit set high.
87 *
88 */
89 #define I3_IPC_EVENT_MASK (1UL << 31)
90
91 /* The workspace event will be triggered upon changes in the workspace list */
92 #define I3_IPC_EVENT_WORKSPACE (I3_IPC_EVENT_MASK | 0)
93
94 /* The output event will be triggered upon changes in the output list */
95 #define I3_IPC_EVENT_OUTPUT (I3_IPC_EVENT_MASK | 1)
96
97 /* The output event will be triggered upon mode changes */
98 #define I3_IPC_EVENT_MODE (I3_IPC_EVENT_MASK | 2)
99
100 /* The window event will be triggered upon window changes */
101 #define I3_IPC_EVENT_WINDOW (I3_IPC_EVENT_MASK | 3)
102
103 /** Bar config update will be triggered to update the bar config */
104 #define I3_IPC_EVENT_BARCONFIG_UPDATE (I3_IPC_EVENT_MASK | 4)
105
106 /** The binding event will be triggered when bindings run */
107 #define I3_IPC_EVENT_BINDING (I3_IPC_EVENT_MASK | 5)
108
109 /** The shutdown event will be triggered when the ipc shuts down */
110 #define I3_IPC_EVENT_SHUTDOWN (I3_IPC_EVENT_MASK | 6)
111
112 /** The tick event will be sent upon a tick IPC message */
113 #define I3_IPC_EVENT_TICK (I3_IPC_EVENT_MASK | 7)
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * i3.h: global variables that are used all over i3.
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include <sys/time.h>
14 #include <sys/resource.h>
15
16 #include <xcb/shape.h>
17 #include <xcb/xcb_keysyms.h>
18 #include <xcb/xkb.h>
19
20 #include <X11/XKBlib.h>
21
22 #define SN_API_NOT_YET_FROZEN 1
23 #include <libsn/sn-launcher.h>
24
25 #include "queue.h"
26 #include "data.h"
27 #include "xcb.h"
28
29 /** Git commit identifier, from version.c */
30 extern const char *i3_version;
31
32 /** The original value of RLIMIT_CORE when i3 was started. We need to restore
33 * this before starting any other process, since we set RLIMIT_CORE to
34 * RLIM_INFINITY for i3 debugging versions. */
35 extern struct rlimit original_rlimit_core;
36 /** Whether this version of i3 is a debug build or a release build. */
37 extern bool debug_build;
38 /** The number of file descriptors passed via socket activation. */
39 extern int listen_fds;
40 extern int conn_screen;
41 /**
42 * The EWMH support window that is used to indicate that an EWMH-compliant
43 * window manager is present. This window is created when i3 starts and
44 * kept alive until i3 exits.
45 * We also use this window as the focused window if no other window is
46 * available to be focused on the active workspace in order to prevent
47 * keyboard focus issues (see #1378).
48 */
49 extern xcb_window_t ewmh_window;
50 /** The last timestamp we got from X11 (timestamps are included in some events
51 * and are used for some things, like determining a unique ID in startup
52 * notification). */
53 extern xcb_timestamp_t last_timestamp;
54 extern SnDisplay *sndisplay;
55 extern xcb_key_symbols_t *keysyms;
56 extern char **start_argv;
57 extern Display *xlibdpy, *xkbdpy;
58 extern int xkb_current_group;
59 extern TAILQ_HEAD(bindings_head, Binding) * bindings;
60 extern TAILQ_HEAD(autostarts_head, Autostart) autostarts;
61 extern TAILQ_HEAD(autostarts_always_head, Autostart) autostarts_always;
62 extern TAILQ_HEAD(ws_assignments_head, Workspace_Assignment) ws_assignments;
63 extern TAILQ_HEAD(assignments_head, Assignment) assignments;
64 extern SLIST_HEAD(stack_wins_head, Stack_Window) stack_wins;
65
66 /* Color depth, visual id and colormap to use when creating windows and
67 * pixmaps. Will use 32 bit depth and an appropriate visual, if available,
68 * otherwise the root window’s default (usually 24 bit TrueColor). */
69 extern uint8_t root_depth;
70 extern xcb_visualid_t visual_id;
71 extern xcb_colormap_t colormap;
72
73 extern bool xkb_supported, shape_supported;
74 extern xcb_window_t root;
75 extern struct ev_loop *main_loop;
76 extern bool only_check_config;
77 extern bool force_xinerama;
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * ipc.c: UNIX domain socket IPC (initialization, client handling, protocol).
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include <ev.h>
14 #include <stdbool.h>
15 #include <yajl/yajl_gen.h>
16 #include <yajl/yajl_parse.h>
17
18 #include "data.h"
19 #include "tree.h"
20 #include "configuration.h"
21
22 #include "i3/ipc.h"
23
24 extern char *current_socketpath;
25
26 typedef struct ipc_client {
27 int fd;
28
29 /* The events which this client wants to receive */
30 int num_events;
31 char **events;
32
33 /* For clients which subscribe to the tick event: whether the first tick
34 * event has been sent by i3. */
35 bool first_tick_sent;
36
37 struct ev_io *read_callback;
38 struct ev_io *write_callback;
39 struct ev_timer *timeout;
40 uint8_t *buffer;
41 size_t buffer_size;
42
43 TAILQ_ENTRY(ipc_client)
44 clients;
45 } ipc_client;
46
47 /*
48 * Callback type for the different message types.
49 *
50 * message is the raw packet, as received from the UNIX domain socket. size
51 * is the remaining size of bytes for this packet.
52 *
53 * message_size is the size of the message as the sender specified it.
54 * message_type is the type of the message as the sender specified it.
55 *
56 */
57 typedef void (*handler_t)(ipc_client *, uint8_t *, int, uint32_t, uint32_t);
58
59 /* Macro to declare a callback */
60 #define IPC_HANDLER(name) \
61 static void handle_##name(ipc_client *client, uint8_t *message, \
62 int size, uint32_t message_size, \
63 uint32_t message_type)
64
65 /**
66 * Handler for activity on the listening socket, meaning that a new client
67 * has just connected and we should accept() him. Sets up the event handler
68 * for activity on the new connection and inserts the file descriptor into
69 * the list of clients.
70 *
71 */
72 void ipc_new_client(EV_P_ struct ev_io *w, int revents);
73
74 /**
75 * ipc_new_client_on_fd() only sets up the event handler
76 * for activity on the new connection and inserts the file descriptor into
77 * the list of clients.
78 *
79 * This variant is useful for the inherited IPC connection when restarting.
80 *
81 */
82 ipc_client *ipc_new_client_on_fd(EV_P_ int fd);
83
84 /**
85 * Creates the UNIX domain socket at the given path, sets it to non-blocking
86 * mode, bind()s and listen()s on it.
87 *
88 */
89 int ipc_create_socket(const char *filename);
90
91 /**
92 * Sends the specified event to all IPC clients which are currently connected
93 * and subscribed to this kind of event.
94 *
95 */
96 void ipc_send_event(const char *event, uint32_t message_type, const char *payload);
97
98 /**
99 * Calls to ipc_shutdown() should provide a reason for the shutdown.
100 */
101 typedef enum {
102 SHUTDOWN_REASON_RESTART,
103 SHUTDOWN_REASON_EXIT
104 } shutdown_reason_t;
105
106 /**
107 * Calls shutdown() on each socket and closes it. This function is to be called
108 * when exiting or restarting only!
109 *
110 * exempt_fd is never closed. Set to -1 to close all fds.
111 *
112 */
113 void ipc_shutdown(shutdown_reason_t reason, int exempt_fd);
114
115 void dump_node(yajl_gen gen, Con *con, bool inplace_restart);
116
117 /**
118 * Generates a json workspace event. Returns a dynamically allocated yajl
119 * generator. Free with yajl_gen_free().
120 */
121 yajl_gen ipc_marshal_workspace_event(const char *change, Con *current, Con *old);
122
123 /**
124 * For the workspace events we send, along with the usual "change" field, also
125 * the workspace container in "current". For focus events, we send the
126 * previously focused workspace in "old".
127 */
128 void ipc_send_workspace_event(const char *change, Con *current, Con *old);
129
130 /**
131 * For the window events we send, along the usual "change" field,
132 * also the window container, in "container".
133 */
134 void ipc_send_window_event(const char *property, Con *con);
135
136 /**
137 * For the barconfig update events, we send the serialized barconfig.
138 */
139 void ipc_send_barconfig_update_event(Barconfig *barconfig);
140
141 /**
142 * For the binding events, we send the serialized binding struct.
143 */
144 void ipc_send_binding_event(const char *event_type, Binding *bind);
145
146 /**
147 * Set the maximum duration that we allow for a connection with an unwriteable
148 * socket.
149 */
150 void ipc_set_kill_timeout(ev_tstamp new);
151
152 /**
153 * Sends a restart reply to the IPC client on the specified fd.
154 */
155 void ipc_confirm_restart(ipc_client *client);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * key_press.c: key press handler
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 /**
14 * There was a key press. We compare this key code with our bindings table and pass
15 * the bound action to parse_command().
16 *
17 */
18 void handle_key_press(xcb_key_press_event_t *event);
19
20 /**
21 * Kills the commanderror i3-nagbar process, if any.
22 *
23 * Called when reloading/restarting, since the user probably fixed their wrong
24 * keybindings.
25 *
26 * If wait_for_it is set (restarting), this function will waitpid(), otherwise,
27 * ev is assumed to handle it (reloading).
28 *
29 */
30 void kill_commanderror_nagbar(bool wait_for_it);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * libi3: contains functions which are used by i3 *and* accompanying tools such
7 * as i3-msg, i3-config-wizard, …
8 *
9 */
10 #pragma once
11
12 #include <config.h>
13
14 #include <stdbool.h>
15 #include <stdarg.h>
16 #include <stdio.h>
17 #include <xcb/xcb.h>
18 #include <xcb/xproto.h>
19 #include <xcb/xcb_keysyms.h>
20
21 #include <pango/pango.h>
22 #include <cairo/cairo-xcb.h>
23
24 #define DEFAULT_DIR_MODE (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)
25
26 /** Mouse buttons */
27 #define XCB_BUTTON_CLICK_LEFT XCB_BUTTON_INDEX_1
28 #define XCB_BUTTON_CLICK_MIDDLE XCB_BUTTON_INDEX_2
29 #define XCB_BUTTON_CLICK_RIGHT XCB_BUTTON_INDEX_3
30 #define XCB_BUTTON_SCROLL_UP XCB_BUTTON_INDEX_4
31 #define XCB_BUTTON_SCROLL_DOWN XCB_BUTTON_INDEX_5
32 /* xcb doesn't define constants for these. */
33 #define XCB_BUTTON_SCROLL_LEFT 6
34 #define XCB_BUTTON_SCROLL_RIGHT 7
35
36 /**
37 * XCB connection and root screen
38 *
39 */
40 extern xcb_connection_t *conn;
41 extern xcb_screen_t *root_screen;
42
43 /**
44 * Opaque data structure for storing strings.
45 *
46 */
47 typedef struct _i3String i3String;
48
49 typedef struct Font i3Font;
50
51 /**
52 * Data structure for cached font information:
53 * - font id in X11 (load it once)
54 * - font height (multiple calls needed to get it)
55 *
56 */
57 struct Font {
58 /** The type of font */
59 enum {
60 FONT_TYPE_NONE = 0,
61 FONT_TYPE_XCB,
62 FONT_TYPE_PANGO
63 } type;
64
65 /** The height of the font, built from font_ascent + font_descent */
66 int height;
67
68 /** The pattern/name used to load the font. */
69 char *pattern;
70
71 union {
72 struct {
73 /** The xcb-id for the font */
74 xcb_font_t id;
75
76 /** Font information gathered from the server */
77 xcb_query_font_reply_t *info;
78
79 /** Font table for this font (may be NULL) */
80 xcb_charinfo_t *table;
81 } xcb;
82
83 /** The pango font description */
84 PangoFontDescription *pango_desc;
85 } specific;
86 };
87
88 /* Since this file also gets included by utilities which don’t use the i3 log
89 * infrastructure, we define a fallback. */
90 #if !defined(LOG)
91 void verboselog(char *fmt, ...)
92 __attribute__((format(printf, 1, 2)));
93 #define LOG(fmt, ...) verboselog("[libi3] " __FILE__ " " fmt, ##__VA_ARGS__)
94 #endif
95 #if !defined(ELOG)
96 void errorlog(char *fmt, ...)
97 __attribute__((format(printf, 1, 2)));
98 #define ELOG(fmt, ...) errorlog("[libi3] ERROR: " fmt, ##__VA_ARGS__)
99 #endif
100 #if !defined(DLOG)
101 void debuglog(char *fmt, ...)
102 __attribute__((format(printf, 1, 2)));
103 #define DLOG(fmt, ...) debuglog("%s:%s:%d - " fmt, STRIPPED__FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
104 #endif
105
106 /**
107 * Try to get the contents of the given atom (for example I3_SOCKET_PATH) from
108 * the X11 root window and return NULL if it doesn’t work.
109 *
110 * If the provided XCB connection is NULL, a new connection will be
111 * established.
112 *
113 * The memory for the contents is dynamically allocated and has to be
114 * free()d by the caller.
115 *
116 */
117 char *root_atom_contents(const char *atomname, xcb_connection_t *provided_conn, int screen);
118
119 /**
120 * Safe-wrapper around malloc which exits if malloc returns NULL (meaning that
121 * there is no more memory available)
122 *
123 */
124 void *smalloc(size_t size);
125
126 /**
127 * Safe-wrapper around calloc which exits if malloc returns NULL (meaning that
128 * there is no more memory available)
129 *
130 */
131 void *scalloc(size_t num, size_t size);
132
133 /**
134 * Safe-wrapper around realloc which exits if realloc returns NULL (meaning
135 * that there is no more memory available).
136 *
137 */
138 void *srealloc(void *ptr, size_t size);
139
140 /**
141 * Safe-wrapper around strdup which exits if malloc returns NULL (meaning that
142 * there is no more memory available)
143 *
144 */
145 char *sstrdup(const char *str);
146
147 /**
148 * Safe-wrapper around strndup which exits if strndup returns NULL (meaning that
149 * there is no more memory available)
150 *
151 */
152 char *sstrndup(const char *str, size_t size);
153
154 /**
155 * Safe-wrapper around asprintf which exits if it returns -1 (meaning that
156 * there is no more memory available)
157 *
158 */
159 int sasprintf(char **strp, const char *fmt, ...);
160
161 /**
162 * Wrapper around correct write which returns -1 (meaning that
163 * write failed) or count (meaning that all bytes were written)
164 *
165 */
166 ssize_t writeall(int fd, const void *buf, size_t count);
167
168 /**
169 * Like writeall, but instead of retrying upon EAGAIN (returned when a write
170 * would block), the function stops and returns the total number of bytes
171 * written so far.
172 *
173 */
174 ssize_t writeall_nonblock(int fd, const void *buf, size_t count);
175
176 /**
177 * Safe-wrapper around writeall which exits if it returns -1 (meaning that
178 * write failed)
179 *
180 */
181 ssize_t swrite(int fd, const void *buf, size_t count);
182
183 /**
184 * Like strcasecmp but considers the case where either string is NULL.
185 *
186 */
187 int strcasecmp_nullable(const char *a, const char *b);
188
189 /**
190 * Build an i3String from an UTF-8 encoded string.
191 * Returns the newly-allocated i3String.
192 *
193 */
194 i3String *i3string_from_utf8(const char *from_utf8);
195
196 /**
197 * Build an i3String from an UTF-8 encoded string in Pango markup.
198 *
199 */
200 i3String *i3string_from_markup(const char *from_markup);
201
202 /**
203 * Build an i3String from an UTF-8 encoded string with fixed length.
204 * To be used when no proper NULL-termination is available.
205 * Returns the newly-allocated i3String.
206 *
207 */
208 i3String *i3string_from_utf8_with_length(const char *from_utf8, ssize_t num_bytes);
209
210 /**
211 * Build an i3String from an UTF-8 encoded string in Pango markup with fixed
212 * length.
213 *
214 */
215 i3String *i3string_from_markup_with_length(const char *from_markup, size_t num_bytes);
216
217 /**
218 * Build an i3String from an UCS-2 encoded string.
219 * Returns the newly-allocated i3String.
220 *
221 */
222 i3String *i3string_from_ucs2(const xcb_char2b_t *from_ucs2, size_t num_glyphs);
223
224 /**
225 * Copies the given i3string.
226 * Note that this will not free the source string.
227 */
228 i3String *i3string_copy(i3String *str);
229
230 /**
231 * Free an i3String.
232 *
233 */
234 void i3string_free(i3String *str);
235
236 /**
237 * Securely i3string_free by setting the pointer to NULL
238 * to prevent accidentally using freed memory.
239 *
240 */
241 #define I3STRING_FREE(str) \
242 do { \
243 if (str != NULL) { \
244 i3string_free(str); \
245 str = NULL; \
246 } \
247 } while (0)
248
249 /**
250 * Returns the UTF-8 encoded version of the i3String.
251 *
252 */
253 const char *i3string_as_utf8(i3String *str);
254
255 /**
256 * Returns the UCS-2 encoded version of the i3String.
257 *
258 */
259 const xcb_char2b_t *i3string_as_ucs2(i3String *str);
260
261 /**
262 * Returns the number of bytes (UTF-8 encoded) in an i3String.
263 *
264 */
265 size_t i3string_get_num_bytes(i3String *str);
266
267 /**
268 * Whether the given i3String is in Pango markup.
269 */
270 bool i3string_is_markup(i3String *str);
271
272 /**
273 * Set whether the i3String should use Pango markup.
274 */
275 void i3string_set_markup(i3String *str, bool pango_markup);
276
277 /**
278 * Escape pango markup characters in the given string.
279 */
280 i3String *i3string_escape_markup(i3String *str);
281
282 /**
283 * Returns the number of glyphs in an i3String.
284 *
285 */
286 size_t i3string_get_num_glyphs(i3String *str);
287
288 /**
289 * Connects to the i3 IPC socket and returns the file descriptor for the
290 * socket. die()s if anything goes wrong.
291 *
292 */
293 int ipc_connect(const char *socket_path);
294
295 /**
296 * Formats a message (payload) of the given size and type and sends it to i3 via
297 * the given socket file descriptor.
298 *
299 * Returns -1 when write() fails, errno will remain.
300 * Returns 0 on success.
301 *
302 */
303 int ipc_send_message(int sockfd, const uint32_t message_size,
304 const uint32_t message_type, const uint8_t *payload);
305
306 /**
307 * Reads a message from the given socket file descriptor and stores its length
308 * (reply_length) as well as a pointer to its contents (reply).
309 *
310 * Returns -1 when read() fails, errno will remain.
311 * Returns -2 when the IPC protocol is violated (invalid magic, unexpected
312 * message type, EOF instead of a message). Additionally, the error will be
313 * printed to stderr.
314 * Returns 0 on success.
315 *
316 */
317 int ipc_recv_message(int sockfd, uint32_t *message_type,
318 uint32_t *reply_length, uint8_t **reply);
319
320 /**
321 * Generates a configure_notify event and sends it to the given window
322 * Applications need this to think they’ve configured themselves correctly.
323 * The truth is, however, that we will manage them.
324 *
325 */
326 void fake_configure_notify(xcb_connection_t *conn, xcb_rectangle_t r, xcb_window_t window, int border_width);
327
328 #define HAS_G_UTF8_MAKE_VALID GLIB_CHECK_VERSION(2, 52, 0)
329 #if !HAS_G_UTF8_MAKE_VALID
330 gchar *g_utf8_make_valid(const gchar *str, gssize len);
331 #endif
332
333 /**
334 * Returns the colorpixel to use for the given hex color (think of HTML). Only
335 * works for true-color (vast majority of cases) at the moment, avoiding a
336 * roundtrip to X11.
337 *
338 * The hex_color has to start with #, for example #FF00FF.
339 *
340 * NOTE that get_colorpixel() does _NOT_ check the given color code for validity.
341 * This has to be done by the caller.
342 *
343 * NOTE that this function may in the future rely on a global xcb_connection_t
344 * variable called 'conn' to be present.
345 *
346 */
347 uint32_t get_colorpixel(const char *hex) __attribute__((const));
348
349 #ifndef HAVE_strndup
350 /**
351 * Taken from FreeBSD
352 * Returns a pointer to a new string which is a duplicate of the
353 * string, but only copies at most n characters.
354 *
355 */
356 char *strndup(const char *str, size_t n);
357 #endif
358
359 /**
360 * All-in-one function which returns the modifier mask (XCB_MOD_MASK_*) for the
361 * given keysymbol, for example for XCB_NUM_LOCK (usually configured to mod2).
362 *
363 * This function initiates one round-trip. Use get_mod_mask_for() directly if
364 * you already have the modifier mapping and key symbols.
365 *
366 */
367 uint32_t aio_get_mod_mask_for(uint32_t keysym, xcb_key_symbols_t *symbols);
368
369 /**
370 * Returns the modifier mask (XCB_MOD_MASK_*) for the given keysymbol, for
371 * example for XCB_NUM_LOCK (usually configured to mod2).
372 *
373 * This function does not initiate any round-trips.
374 *
375 */
376 uint32_t get_mod_mask_for(uint32_t keysym,
377 xcb_key_symbols_t *symbols,
378 xcb_get_modifier_mapping_reply_t *modmap_reply);
379
380 /**
381 * Loads a font for usage, also getting its height. If fallback is true,
382 * the fonts 'fixed' or '-misc-*' will be loaded instead of exiting. If any
383 * font was previously loaded, it will be freed.
384 *
385 */
386 i3Font load_font(const char *pattern, const bool fallback);
387
388 /**
389 * Defines the font to be used for the forthcoming calls.
390 *
391 */
392 void set_font(i3Font *font);
393
394 /**
395 * Frees the resources taken by the current font. If no font was previously
396 * loaded, it simply returns.
397 *
398 */
399 void free_font(void);
400
401 /**
402 * Converts the given string to UTF-8 from UCS-2 big endian. The return value
403 * must be freed after use.
404 *
405 */
406 char *convert_ucs2_to_utf8(xcb_char2b_t *text, size_t num_glyphs);
407
408 /**
409 * Converts the given string to UCS-2 big endian for use with
410 * xcb_image_text_16(). The amount of real glyphs is stored in real_strlen,
411 * a buffer containing the UCS-2 encoded string (16 bit per glyph) is
412 * returned. It has to be freed when done.
413 *
414 */
415 xcb_char2b_t *convert_utf8_to_ucs2(char *input, size_t *real_strlen);
416
417 /* Represents a color split by color channel. */
418 typedef struct color_t {
419 double red;
420 double green;
421 double blue;
422 double alpha;
423
424 /* The colorpixel we use for direct XCB calls. */
425 uint32_t colorpixel;
426 } color_t;
427
428 #define COLOR_TRANSPARENT ((color_t){.red = 0.0, .green = 0.0, .blue = 0.0, .colorpixel = 0})
429
430 /**
431 * Defines the colors to be used for the forthcoming draw_text calls.
432 *
433 */
434 void set_font_colors(xcb_gcontext_t gc, color_t foreground, color_t background);
435
436 /**
437 * Returns true if and only if the current font is a pango font.
438 *
439 */
440 bool font_is_pango(void);
441
442 /**
443 * Draws text onto the specified X drawable (normally a pixmap) at the
444 * specified coordinates (from the top left corner of the leftmost, uppermost
445 * glyph) and using the provided gc.
446 *
447 * Text must be specified as an i3String.
448 *
449 */
450 void draw_text(i3String *text, xcb_drawable_t drawable, xcb_gcontext_t gc,
451 xcb_visualtype_t *visual, int x, int y, int max_width);
452
453 /**
454 * ASCII version of draw_text to print static strings.
455 *
456 */
457 void draw_text_ascii(const char *text, xcb_drawable_t drawable,
458 xcb_gcontext_t gc, int x, int y, int max_width);
459
460 /**
461 * Predict the text width in pixels for the given text. Text must be
462 * specified as an i3String.
463 *
464 */
465 int predict_text_width(i3String *text);
466
467 /**
468 * Returns the visual type associated with the given screen.
469 *
470 */
471 xcb_visualtype_t *get_visualtype(xcb_screen_t *screen);
472
473 /**
474 * Returns true if this version of i3 is a debug build (anything which is not a
475 * release version), based on the git version number.
476 *
477 */
478 bool is_debug_build(void) __attribute__((const));
479
480 /**
481 * Returns the name of a temporary file with the specified prefix.
482 *
483 */
484 char *get_process_filename(const char *prefix);
485
486 /**
487 * This function returns the absolute path to the executable it is running in.
488 *
489 * The implementation follows https://stackoverflow.com/a/933996/712014
490 *
491 * Returned value must be freed by the caller.
492 */
493 char *get_exe_path(const char *argv0);
494
495 /**
496 * Initialize the DPI setting.
497 * This will use the 'Xft.dpi' X resource if available and fall back to
498 * guessing the correct value otherwise.
499 */
500 void init_dpi(void);
501
502 /**
503 * This function returns the value of the DPI setting.
504 *
505 */
506 long get_dpi_value(void);
507
508 /**
509 * Convert a logical amount of pixels (e.g. 2 pixels on a “standard” 96 DPI
510 * screen) to a corresponding amount of physical pixels on a standard or retina
511 * screen, e.g. 5 pixels on a 227 DPI MacBook Pro 13" Retina screen.
512 *
513 */
514 int logical_px(const int logical);
515
516 /**
517 * This function resolves ~ in pathnames.
518 * It may resolve wildcards in the first part of the path, but if no match
519 * or multiple matches are found, it just returns a copy of path as given.
520 *
521 */
522 char *resolve_tilde(const char *path);
523
524 /**
525 * Get the path of the first configuration file found. If override_configpath is
526 * specified, that path is returned and saved for further calls. Otherwise,
527 * checks the home directory first, then the system directory, always taking
528 * into account the XDG Base Directory Specification ($XDG_CONFIG_HOME,
529 * $XDG_CONFIG_DIRS).
530 *
531 */
532 char *get_config_path(const char *override_configpath, bool use_system_paths);
533
534 #ifndef HAVE_mkdirp
535 /**
536 * Emulates mkdir -p (creates any missing folders)
537 *
538 */
539 int mkdirp(const char *path, mode_t mode);
540 #endif
541
542 /** Helper structure for usage in format_placeholders(). */
543 typedef struct placeholder_t {
544 /* The placeholder to be replaced, e.g., "%title". */
545 char *name;
546 /* The value this placeholder should be replaced with. */
547 char *value;
548 } placeholder_t;
549
550 /**
551 * Replaces occurrences of the defined placeholders in the format string.
552 *
553 */
554 char *format_placeholders(char *format, placeholder_t *placeholders, int num);
555
556 /* We need to flush cairo surfaces twice to avoid an assertion bug. See #1989
557 * and https://bugs.freedesktop.org/show_bug.cgi?id=92455. */
558 #define CAIRO_SURFACE_FLUSH(surface) \
559 do { \
560 cairo_surface_flush(surface); \
561 cairo_surface_flush(surface); \
562 } while (0)
563
564 /* A wrapper grouping an XCB drawable and both a graphics context
565 * and the corresponding cairo objects representing it. */
566 typedef struct surface_t {
567 /* The drawable which is being represented. */
568 xcb_drawable_t id;
569
570 /* A classic XCB graphics context. */
571 xcb_gcontext_t gc;
572
573 xcb_visualtype_t *visual_type;
574
575 int width;
576 int height;
577
578 /* A cairo surface representing the drawable. */
579 cairo_surface_t *surface;
580
581 /* The cairo object representing the drawable. In general,
582 * this is what one should use for any drawing operation. */
583 cairo_t *cr;
584 } surface_t;
585
586 /**
587 * Initialize the surface to represent the given drawable.
588 *
589 */
590 void draw_util_surface_init(xcb_connection_t *conn, surface_t *surface, xcb_drawable_t drawable,
591 xcb_visualtype_t *visual, int width, int height);
592
593 /**
594 * Resize the surface to the given size.
595 *
596 */
597 void draw_util_surface_set_size(surface_t *surface, int width, int height);
598
599 /**
600 * Destroys the surface.
601 *
602 */
603 void draw_util_surface_free(xcb_connection_t *conn, surface_t *surface);
604
605 /**
606 * Parses the given color in hex format to an internal color representation.
607 * Note that the input must begin with a hash sign, e.g., "#3fbc59".
608 *
609 */
610 color_t draw_util_hex_to_color(const char *color);
611
612 /**
613 * Draw the given text using libi3.
614 * This function also marks the surface dirty which is needed if other means of
615 * drawing are used. This will be the case when using XCB to draw text.
616 *
617 */
618 void draw_util_text(i3String *text, surface_t *surface, color_t fg_color, color_t bg_color, int x, int y, int max_width);
619
620 /**
621 * Draws a filled rectangle.
622 * This function is a convenience wrapper and takes care of flushing the
623 * surface as well as restoring the cairo state.
624 *
625 */
626 void draw_util_rectangle(surface_t *surface, color_t color, double x, double y, double w, double h);
627
628 /**
629 * Clears a surface with the given color.
630 *
631 */
632 void draw_util_clear_surface(surface_t *surface, color_t color);
633
634 /**
635 * Copies a surface onto another surface.
636 *
637 */
638 void draw_util_copy_surface(surface_t *src, surface_t *dest, double src_x, double src_y,
639 double dest_x, double dest_y, double width, double height);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * load_layout.c: Restore (parts of) the layout, for example after an inplace
7 * restart.
8 *
9 */
10 #pragma once
11
12 #include <config.h>
13
14 typedef enum {
15 // We could not determine the content of the JSON file. This typically
16 // means it’s unreadable or contains garbage.
17 JSON_CONTENT_UNKNOWN = 0,
18
19 // The JSON file contains a “normal” container, i.e. a container to be
20 // appended to an existing workspace (or split container!).
21 JSON_CONTENT_CON = 1,
22
23 // The JSON file contains a workspace container, which needs to be appended
24 // to the output (next to the other workspaces) with special care to avoid
25 // naming conflicts and ensuring that the workspace _has_ a name.
26 JSON_CONTENT_WORKSPACE = 2,
27 } json_content_t;
28
29 /* Parses the given JSON file until it encounters the first “type” property to
30 * determine whether the file contains workspaces or regular containers, which
31 * is important to know when deciding where (and how) to append the contents.
32 * */
33 json_content_t json_determine_content(const char *buf, const size_t len);
34
35 /**
36 * Returns true if the provided JSON could be parsed by yajl.
37 *
38 */
39 bool json_validate(const char *buf, const size_t len);
40
41 void tree_append_json(Con *con, const char *buf, const size_t len, char **errormsg);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * log.c: Logging functions.
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include <stdarg.h>
14 #include <stdbool.h>
15
16 /* We will include libi3.h which define its own version of LOG, ELOG.
17 * We want *our* version, so we undef the libi3 one. */
18 #if defined(LOG)
19 #undef LOG
20 #endif
21 #if defined(ELOG)
22 #undef ELOG
23 #endif
24 #if defined(DLOG)
25 #undef DLOG
26 #endif
27 /** ##__VA_ARGS__ means: leave out __VA_ARGS__ completely if it is empty, that
28 is, delete the preceding comma */
29 #define LOG(fmt, ...) verboselog(fmt, ##__VA_ARGS__)
30 #define ELOG(fmt, ...) errorlog("ERROR: " fmt, ##__VA_ARGS__)
31 #define DLOG(fmt, ...) debuglog("%s:%s:%d - " fmt, STRIPPED__FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__)
32
33 extern char *errorfilename;
34 extern char *shmlogname;
35 extern int shmlog_size;
36
37 /**
38 * Initializes logging by creating an error logfile in /tmp (or
39 * XDG_RUNTIME_DIR, see get_process_filename()).
40 *
41 */
42 void init_logging(void);
43
44 /**
45 * Opens the logbuffer.
46 *
47 */
48 void open_logbuffer(void);
49
50 /**
51 * Closes the logbuffer.
52 *
53 */
54 void close_logbuffer(void);
55
56 /**
57 * Checks if debug logging is active.
58 *
59 */
60 bool get_debug_logging(void);
61
62 /**
63 * Set debug logging.
64 *
65 */
66 void set_debug_logging(const bool _debug_logging);
67
68 /**
69 * Set verbosity of i3. If verbose is set to true, informative messages will
70 * be printed to stdout. If verbose is set to false, only errors will be
71 * printed.
72 *
73 */
74 void set_verbosity(bool _verbose);
75
76 /**
77 * Logs the given message to stdout while prefixing the current time to it,
78 * but only if debug logging was activated.
79 *
80 */
81 void debuglog(char *fmt, ...)
82 __attribute__((format(printf, 1, 2)));
83
84 /**
85 * Logs the given message to stdout while prefixing the current time to it.
86 *
87 */
88 void errorlog(char *fmt, ...)
89 __attribute__((format(printf, 1, 2)));
90
91 /**
92 * Logs the given message to stdout while prefixing the current time to it,
93 * but only if verbose mode is activated.
94 *
95 */
96 void verboselog(char *fmt, ...)
97 __attribute__((format(printf, 1, 2)));
98
99 /**
100 * Deletes the unused log files. Useful if i3 exits immediately, eg.
101 * because --get-socketpath was called. We don't care for syscall
102 * failures. This function is invoked automatically when exiting.
103 */
104 void purge_zerobyte_logfile(void);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * main.c: Initialization, main loop
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 /**
14 * Enable or disable the main X11 event handling function.
15 * This is used by drag_pointer() which has its own, modal event handler, which
16 * takes precedence over the normal event handler.
17 *
18 */
19 void main_set_x11_cb(bool enable);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * manage.c: Initially managing new windows (or existing ones on restart).
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include "data.h"
14
15 /**
16 * Go through all existing windows (if the window manager is restarted) and
17 * manage them
18 *
19 */
20 void manage_existing_windows(xcb_window_t root);
21
22 /**
23 * Restores the geometry of each window by reparenting it to the root window
24 * at the position of its frame.
25 *
26 * This is to be called *only* before exiting/restarting i3 because of evil
27 * side-effects which are to be expected when continuing to run i3.
28 *
29 */
30 void restore_geometry(void);
31
32 /**
33 * Do some sanity checks and then reparent the window.
34 *
35 */
36 void manage_window(xcb_window_t window,
37 xcb_get_window_attributes_cookie_t cookie,
38 bool needs_to_be_mapped);
39
40 /**
41 * Remanages a window: performs a swallow check and runs assignments.
42 * Returns con for the window regardless if it updated.
43 *
44 */
45 Con *remanage_window(Con *con);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * A "match" is a data structure which acts like a mask or expression to match
7 * certain windows or not. For example, when using commands, you can specify a
8 * command like this: [title="*Firefox*"] kill. The title member of the match
9 * data structure will then be filled and i3 will check each window using
10 * match_matches_window() to find the windows affected by this command.
11 *
12 */
13 #pragma once
14
15 #include <config.h>
16
17 /**
18 * Initializes the Match data structure. This function is necessary because the
19 * members representing boolean values (like dock) need to be initialized with
20 * -1 instead of 0.
21 *
22 */
23 void match_init(Match *match);
24
25 /**
26 * Check if a match is empty. This is necessary while parsing commands to see
27 * whether the user specified a match at all.
28 *
29 */
30 bool match_is_empty(Match *match);
31
32 /**
33 * Copies the data of a match from src to dest.
34 *
35 */
36 void match_copy(Match *dest, Match *src);
37
38 /**
39 * Check if a match data structure matches the given window.
40 *
41 */
42 bool match_matches_window(Match *match, i3Window *window);
43
44 /**
45 * Frees the given match. It must not be used afterwards!
46 *
47 */
48 void match_free(Match *match);
49
50 /**
51 * Interprets a ctype=cvalue pair and adds it to the given match specification.
52 *
53 */
54 void match_parse_property(Match *match, const char *ctype, const char *cvalue);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * move.c: Moving containers into some direction.
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 /**
14 * Moves the given container in the given direction
15 *
16 */
17 void tree_move(Con *con, direction_t direction);
18
19 /**
20 * This function detaches 'con' from its parent and inserts it either before or
21 * after 'target'.
22 *
23 */
24 void insert_con_into(Con *con, Con *target, position_t position);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * output.c: Output (monitor) related functions.
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 /**
14 * Returns the output container below the given output container.
15 *
16 */
17 Con *output_get_content(Con *output);
18
19 /**
20 * Returns an 'output' corresponding to one of left/right/down/up or a specific
21 * output name.
22 *
23 */
24 Output *get_output_from_string(Output *current_output, const char *output_str);
25
26 /**
27 * Retrieves the primary name of an output.
28 *
29 */
30 char *output_primary_name(Output *output);
31
32 /**
33 * Returns the output for the given con.
34 *
35 */
36 Output *get_output_for_con(Con *con);
37
38 /**
39 * Iterates over all outputs and pushes sticky windows to the currently visible
40 * workspace on that output.
41 *
42 * old_focus is used to determine if a sticky window is going to be focused.
43 * old_focus might be different than the currently focused container because the
44 * caller might need to temporarily change the focus and then call
45 * output_push_sticky_windows. For example, workspace_show needs to set focus to
46 * one of its descendants first, then call output_push_sticky_windows that
47 * should focus a sticky window if it was the focused in the previous workspace.
48 *
49 */
50 void output_push_sticky_windows(Con *old_focus);
0 /* $OpenBSD: queue.h,v 1.1 2007/10/26 03:14:08 niallo Exp $ */
1 /* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
2
3 /*
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)queue.h 8.5 (Berkeley) 8/20/94
32 */
33
34 #pragma once
35
36 /*
37 * This file defines five types of data structures: singly-linked lists,
38 * lists, simple queues, tail queues, and circular queues.
39 *
40 *
41 * A singly-linked list is headed by a single forward pointer. The elements
42 * are singly linked for minimum space and pointer manipulation overhead at
43 * the expense of O(n) removal for arbitrary elements. New elements can be
44 * added to the list after an existing element or at the head of the list.
45 * Elements being removed from the head of the list should use the explicit
46 * macro for this purpose for optimum efficiency. A singly-linked list may
47 * only be traversed in the forward direction. Singly-linked lists are ideal
48 * for applications with large datasets and few or no removals or for
49 * implementing a LIFO queue.
50 *
51 * A list is headed by a single forward pointer (or an array of forward
52 * pointers for a hash table header). The elements are doubly linked
53 * so that an arbitrary element can be removed without a need to
54 * traverse the list. New elements can be added to the list before
55 * or after an existing element or at the head of the list. A list
56 * may only be traversed in the forward direction.
57 *
58 * A simple queue is headed by a pair of pointers, one the head of the
59 * list and the other to the tail of the list. The elements are singly
60 * linked to save space, so elements can only be removed from the
61 * head of the list. New elements can be added to the list before or after
62 * an existing element, at the head of the list, or at the end of the
63 * list. A simple queue may only be traversed in the forward direction.
64 *
65 * A tail queue is headed by a pair of pointers, one to the head of the
66 * list and the other to the tail of the list. The elements are doubly
67 * linked so that an arbitrary element can be removed without a need to
68 * traverse the list. New elements can be added to the list before or
69 * after an existing element, at the head of the list, or at the end of
70 * the list. A tail queue may be traversed in either direction.
71 *
72 * A circle queue is headed by a pair of pointers, one to the head of the
73 * list and the other to the tail of the list. The elements are doubly
74 * linked so that an arbitrary element can be removed without a need to
75 * traverse the list. New elements can be added to the list before or after
76 * an existing element, at the head of the list, or at the end of the list.
77 * A circle queue may be traversed in either direction, but has a more
78 * complex end of list detection.
79 *
80 * For details on the use of these macros, see the queue(3) manual page.
81 */
82
83 #if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
84 #define _Q_INVALIDATE(a) (a) = ((void *)-1)
85 #else
86 #define _Q_INVALIDATE(a)
87 #endif
88
89 /*
90 * Singly-linked List definitions.
91 */
92 #define SLIST_HEAD(name, type) \
93 struct name { \
94 struct type *slh_first; /* first element */ \
95 }
96
97 #define SLIST_HEAD_INITIALIZER(head) \
98 { NULL }
99
100 #define SLIST_ENTRY(type) \
101 struct { \
102 struct type *sle_next; /* next element */ \
103 }
104
105 /*
106 * Singly-linked List access methods.
107 */
108 #define SLIST_FIRST(head) ((head)->slh_first)
109 #define SLIST_END(head) NULL
110 #define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
111 #define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
112
113 #define SLIST_FOREACH(var, head, field) \
114 for ((var) = SLIST_FIRST(head); \
115 (var) != SLIST_END(head); \
116 (var) = SLIST_NEXT(var, field))
117
118 #define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
119 for ((varp) = &SLIST_FIRST((head)); \
120 ((var) = *(varp)) != SLIST_END(head); \
121 (varp) = &SLIST_NEXT((var), field))
122
123 /*
124 * Singly-linked List functions.
125 */
126 #define SLIST_INIT(head) \
127 { \
128 SLIST_FIRST(head) = SLIST_END(head); \
129 }
130
131 #define SLIST_INSERT_AFTER(slistelm, elm, field) \
132 do { \
133 (elm)->field.sle_next = (slistelm)->field.sle_next; \
134 (slistelm)->field.sle_next = (elm); \
135 } while (0)
136
137 #define SLIST_INSERT_HEAD(head, elm, field) \
138 do { \
139 (elm)->field.sle_next = (head)->slh_first; \
140 (head)->slh_first = (elm); \
141 } while (0)
142
143 #define SLIST_REMOVE_NEXT(head, elm, field) \
144 do { \
145 (elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
146 } while (0)
147
148 #define SLIST_REMOVE_HEAD(head, field) \
149 do { \
150 (head)->slh_first = (head)->slh_first->field.sle_next; \
151 } while (0)
152
153 #define SLIST_REMOVE(head, elm, type, field) \
154 do { \
155 if ((head)->slh_first == (elm)) { \
156 SLIST_REMOVE_HEAD((head), field); \
157 } else { \
158 struct type *curelm = (head)->slh_first; \
159 \
160 while (curelm->field.sle_next != (elm)) \
161 curelm = curelm->field.sle_next; \
162 curelm->field.sle_next = curelm->field.sle_next->field.sle_next; \
163 _Q_INVALIDATE((elm)->field.sle_next); \
164 } \
165 } while (0)
166
167 /*
168 * List definitions.
169 */
170 #define LIST_HEAD(name, type) \
171 struct name { \
172 struct type *lh_first; /* first element */ \
173 }
174
175 #define LIST_HEAD_INITIALIZER(head) \
176 { NULL }
177
178 #define LIST_ENTRY(type) \
179 struct { \
180 struct type *le_next; /* next element */ \
181 struct type **le_prev; /* address of previous next element */ \
182 }
183
184 /*
185 * List access methods
186 */
187 #define LIST_FIRST(head) ((head)->lh_first)
188 #define LIST_END(head) NULL
189 #define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
190 #define LIST_NEXT(elm, field) ((elm)->field.le_next)
191
192 #define LIST_FOREACH(var, head, field) \
193 for ((var) = LIST_FIRST(head); \
194 (var) != LIST_END(head); \
195 (var) = LIST_NEXT(var, field))
196
197 /*
198 * List functions.
199 */
200 #define LIST_INIT(head) \
201 do { \
202 LIST_FIRST(head) = LIST_END(head); \
203 } while (0)
204
205 #define LIST_INSERT_AFTER(listelm, elm, field) \
206 do { \
207 if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
208 (listelm)->field.le_next->field.le_prev = &(elm)->field.le_next; \
209 (listelm)->field.le_next = (elm); \
210 (elm)->field.le_prev = &(listelm)->field.le_next; \
211 } while (0)
212
213 #define LIST_INSERT_BEFORE(listelm, elm, field) \
214 do { \
215 (elm)->field.le_prev = (listelm)->field.le_prev; \
216 (elm)->field.le_next = (listelm); \
217 *(listelm)->field.le_prev = (elm); \
218 (listelm)->field.le_prev = &(elm)->field.le_next; \
219 } while (0)
220
221 #define LIST_INSERT_HEAD(head, elm, field) \
222 do { \
223 if (((elm)->field.le_next = (head)->lh_first) != NULL) \
224 (head)->lh_first->field.le_prev = &(elm)->field.le_next; \
225 (head)->lh_first = (elm); \
226 (elm)->field.le_prev = &(head)->lh_first; \
227 } while (0)
228
229 #define LIST_REMOVE(elm, field) \
230 do { \
231 if ((elm)->field.le_next != NULL) \
232 (elm)->field.le_next->field.le_prev = (elm)->field.le_prev; \
233 *(elm)->field.le_prev = (elm)->field.le_next; \
234 _Q_INVALIDATE((elm)->field.le_prev); \
235 _Q_INVALIDATE((elm)->field.le_next); \
236 } while (0)
237
238 #define LIST_REPLACE(elm, elm2, field) \
239 do { \
240 if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
241 (elm2)->field.le_next->field.le_prev = &(elm2)->field.le_next; \
242 (elm2)->field.le_prev = (elm)->field.le_prev; \
243 *(elm2)->field.le_prev = (elm2); \
244 _Q_INVALIDATE((elm)->field.le_prev); \
245 _Q_INVALIDATE((elm)->field.le_next); \
246 } while (0)
247
248 /*
249 * Simple queue definitions.
250 */
251 #define SIMPLEQ_HEAD(name, type) \
252 struct name { \
253 struct type *sqh_first; /* first element */ \
254 struct type **sqh_last; /* addr of last next element */ \
255 }
256
257 #define SIMPLEQ_HEAD_INITIALIZER(head) \
258 { NULL, &(head).sqh_first }
259
260 #define SIMPLEQ_ENTRY(type) \
261 struct { \
262 struct type *sqe_next; /* next element */ \
263 }
264
265 /*
266 * Simple queue access methods.
267 */
268 #define SIMPLEQ_FIRST(head) ((head)->sqh_first)
269 #define SIMPLEQ_END(head) NULL
270 #define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
271 #define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
272
273 #define SIMPLEQ_FOREACH(var, head, field) \
274 for ((var) = SIMPLEQ_FIRST(head); \
275 (var) != SIMPLEQ_END(head); \
276 (var) = SIMPLEQ_NEXT(var, field))
277
278 /*
279 * Simple queue functions.
280 */
281 #define SIMPLEQ_INIT(head) \
282 do { \
283 (head)->sqh_first = NULL; \
284 (head)->sqh_last = &(head)->sqh_first; \
285 } while (0)
286
287 #define SIMPLEQ_INSERT_HEAD(head, elm, field) \
288 do { \
289 if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
290 (head)->sqh_last = &(elm)->field.sqe_next; \
291 (head)->sqh_first = (elm); \
292 } while (0)
293
294 #define SIMPLEQ_INSERT_TAIL(head, elm, field) \
295 do { \
296 (elm)->field.sqe_next = NULL; \
297 *(head)->sqh_last = (elm); \
298 (head)->sqh_last = &(elm)->field.sqe_next; \
299 } while (0)
300
301 #define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) \
302 do { \
303 if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL) \
304 (head)->sqh_last = &(elm)->field.sqe_next; \
305 (listelm)->field.sqe_next = (elm); \
306 } while (0)
307
308 #define SIMPLEQ_REMOVE_HEAD(head, field) \
309 do { \
310 if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
311 (head)->sqh_last = &(head)->sqh_first; \
312 } while (0)
313
314 /*
315 * Tail queue definitions.
316 */
317 #define TAILQ_HEAD(name, type) \
318 struct name { \
319 struct type *tqh_first; /* first element */ \
320 struct type **tqh_last; /* addr of last next element */ \
321 }
322
323 #define TAILQ_HEAD_INITIALIZER(head) \
324 { NULL, &(head).tqh_first }
325
326 #define TAILQ_ENTRY(type) \
327 struct { \
328 struct type *tqe_next; /* next element */ \
329 struct type **tqe_prev; /* address of previous next element */ \
330 }
331
332 /*
333 * tail queue access methods
334 */
335 #define TAILQ_FIRST(head) ((head)->tqh_first)
336 #define TAILQ_END(head) NULL
337 #define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
338 #define TAILQ_LAST(head, headname) \
339 (*(((struct headname *)((head)->tqh_last))->tqh_last))
340 /* XXX */
341 #define TAILQ_PREV(elm, headname, field) \
342 (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
343 #define TAILQ_EMPTY(head) \
344 (TAILQ_FIRST(head) == TAILQ_END(head))
345
346 #define TAILQ_FOREACH(var, head, field) \
347 for ((var) = TAILQ_FIRST(head); \
348 (var) != TAILQ_END(head); \
349 (var) = TAILQ_NEXT(var, field))
350
351 #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
352 for ((var) = TAILQ_LAST(head, headname); \
353 (var) != TAILQ_END(head); \
354 (var) = TAILQ_PREV(var, headname, field))
355
356 /*
357 * Tail queue functions.
358 */
359 #define TAILQ_INIT(head) \
360 do { \
361 (head)->tqh_first = NULL; \
362 (head)->tqh_last = &(head)->tqh_first; \
363 } while (0)
364
365 #define TAILQ_INSERT_HEAD(head, elm, field) \
366 do { \
367 if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
368 (head)->tqh_first->field.tqe_prev = &(elm)->field.tqe_next; \
369 else \
370 (head)->tqh_last = &(elm)->field.tqe_next; \
371 (head)->tqh_first = (elm); \
372 (elm)->field.tqe_prev = &(head)->tqh_first; \
373 } while (0)
374
375 #define TAILQ_INSERT_TAIL(head, elm, field) \
376 do { \
377 (elm)->field.tqe_next = NULL; \
378 (elm)->field.tqe_prev = (head)->tqh_last; \
379 *(head)->tqh_last = (elm); \
380 (head)->tqh_last = &(elm)->field.tqe_next; \
381 } while (0)
382
383 #define TAILQ_INSERT_AFTER(head, listelm, elm, field) \
384 do { \
385 if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL) \
386 (elm)->field.tqe_next->field.tqe_prev = &(elm)->field.tqe_next; \
387 else \
388 (head)->tqh_last = &(elm)->field.tqe_next; \
389 (listelm)->field.tqe_next = (elm); \
390 (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
391 } while (0)
392
393 #define TAILQ_INSERT_BEFORE(listelm, elm, field) \
394 do { \
395 (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
396 (elm)->field.tqe_next = (listelm); \
397 *(listelm)->field.tqe_prev = (elm); \
398 (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
399 } while (0)
400
401 #define TAILQ_REMOVE(head, elm, field) \
402 do { \
403 if (((elm)->field.tqe_next) != NULL) \
404 (elm)->field.tqe_next->field.tqe_prev = (elm)->field.tqe_prev; \
405 else \
406 (head)->tqh_last = (elm)->field.tqe_prev; \
407 *(elm)->field.tqe_prev = (elm)->field.tqe_next; \
408 _Q_INVALIDATE((elm)->field.tqe_prev); \
409 _Q_INVALIDATE((elm)->field.tqe_next); \
410 } while (0)
411
412 #define TAILQ_REPLACE(head, elm, elm2, field) \
413 do { \
414 if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
415 (elm2)->field.tqe_next->field.tqe_prev = &(elm2)->field.tqe_next; \
416 else \
417 (head)->tqh_last = &(elm2)->field.tqe_next; \
418 (elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
419 *(elm2)->field.tqe_prev = (elm2); \
420 _Q_INVALIDATE((elm)->field.tqe_prev); \
421 _Q_INVALIDATE((elm)->field.tqe_next); \
422 } while (0)
423
424 /* Swaps two consecutive elements. 'second' *MUST* follow 'first' */
425 #define TAILQ_SWAP(first, second, head, field) \
426 do { \
427 *((first)->field.tqe_prev) = (second); \
428 (second)->field.tqe_prev = (first)->field.tqe_prev; \
429 (first)->field.tqe_prev = &((second)->field.tqe_next); \
430 (first)->field.tqe_next = (second)->field.tqe_next; \
431 if ((second)->field.tqe_next) \
432 (second)->field.tqe_next->field.tqe_prev = &((first)->field.tqe_next); \
433 (second)->field.tqe_next = first; \
434 if ((head)->tqh_last == &((second)->field.tqe_next)) \
435 (head)->tqh_last = &((first)->field.tqe_next); \
436 } while (0)
437
438 /*
439 * Circular queue definitions.
440 */
441 #define CIRCLEQ_HEAD(name, type) \
442 struct name { \
443 struct type *cqh_first; /* first element */ \
444 struct type *cqh_last; /* last element */ \
445 }
446
447 #define CIRCLEQ_HEAD_INITIALIZER(head) \
448 { \
449 CIRCLEQ_END(&head) \
450 , CIRCLEQ_END(&head) \
451 }
452
453 #define CIRCLEQ_ENTRY(type) \
454 struct { \
455 struct type *cqe_next; /* next element */ \
456 struct type *cqe_prev; /* previous element */ \
457 }
458
459 /*
460 * Circular queue access methods
461 */
462 #define CIRCLEQ_FIRST(head) ((head)->cqh_first)
463 #define CIRCLEQ_LAST(head) ((head)->cqh_last)
464 #define CIRCLEQ_END(head) ((void *)(head))
465 #define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
466 #define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
467 #define CIRCLEQ_EMPTY(head) \
468 (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
469
470 #define CIRCLEQ_FOREACH(var, head, field) \
471 for ((var) = CIRCLEQ_FIRST(head); \
472 (var) != CIRCLEQ_END(head); \
473 (var) = CIRCLEQ_NEXT(var, field))
474
475 #define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
476 for ((var) = CIRCLEQ_LAST(head); \
477 (var) != CIRCLEQ_END(head); \
478 (var) = CIRCLEQ_PREV(var, field))
479
480 /*
481 * Circular queue functions.
482 */
483 #define CIRCLEQ_INIT(head) \
484 do { \
485 (head)->cqh_first = CIRCLEQ_END(head); \
486 (head)->cqh_last = CIRCLEQ_END(head); \
487 } while (0)
488
489 #define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) \
490 do { \
491 (elm)->field.cqe_next = (listelm)->field.cqe_next; \
492 (elm)->field.cqe_prev = (listelm); \
493 if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
494 (head)->cqh_last = (elm); \
495 else \
496 (listelm)->field.cqe_next->field.cqe_prev = (elm); \
497 (listelm)->field.cqe_next = (elm); \
498 } while (0)
499
500 #define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) \
501 do { \
502 (elm)->field.cqe_next = (listelm); \
503 (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
504 if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
505 (head)->cqh_first = (elm); \
506 else \
507 (listelm)->field.cqe_prev->field.cqe_next = (elm); \
508 (listelm)->field.cqe_prev = (elm); \
509 } while (0)
510
511 #define CIRCLEQ_INSERT_HEAD(head, elm, field) \
512 do { \
513 (elm)->field.cqe_next = (head)->cqh_first; \
514 (elm)->field.cqe_prev = CIRCLEQ_END(head); \
515 if ((head)->cqh_last == CIRCLEQ_END(head)) \
516 (head)->cqh_last = (elm); \
517 else \
518 (head)->cqh_first->field.cqe_prev = (elm); \
519 (head)->cqh_first = (elm); \
520 } while (0)
521
522 #define CIRCLEQ_INSERT_TAIL(head, elm, field) \
523 do { \
524 (elm)->field.cqe_next = CIRCLEQ_END(head); \
525 (elm)->field.cqe_prev = (head)->cqh_last; \
526 if ((head)->cqh_first == CIRCLEQ_END(head)) \
527 (head)->cqh_first = (elm); \
528 else \
529 (head)->cqh_last->field.cqe_next = (elm); \
530 (head)->cqh_last = (elm); \
531 } while (0)
532
533 #define CIRCLEQ_REMOVE(head, elm, field) \
534 do { \
535 if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
536 (head)->cqh_last = (elm)->field.cqe_prev; \
537 else \
538 (elm)->field.cqe_next->field.cqe_prev = (elm)->field.cqe_prev; \
539 if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
540 (head)->cqh_first = (elm)->field.cqe_next; \
541 else \
542 (elm)->field.cqe_prev->field.cqe_next = (elm)->field.cqe_next; \
543 _Q_INVALIDATE((elm)->field.cqe_prev); \
544 _Q_INVALIDATE((elm)->field.cqe_next); \
545 } while (0)
546
547 #define CIRCLEQ_REPLACE(head, elm, elm2, field) \
548 do { \
549 if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == CIRCLEQ_END(head)) \
550 (head)->cqh_last = (elm2); \
551 else \
552 (elm2)->field.cqe_next->field.cqe_prev = (elm2); \
553 if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == CIRCLEQ_END(head)) \
554 (head)->cqh_first = (elm2); \
555 else \
556 (elm2)->field.cqe_prev->field.cqe_next = (elm2); \
557 _Q_INVALIDATE((elm)->field.cqe_prev); \
558 _Q_INVALIDATE((elm)->field.cqe_next); \
559 } while (0)
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * For more information on RandR, please see the X.org RandR specification at
7 * https://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt
8 * (take your time to read it completely, it answers all questions).
9 *
10 */
11 #pragma once
12
13 #include <config.h>
14
15 #include "data.h"
16 #include <xcb/randr.h>
17
18 TAILQ_HEAD(outputs_head, xoutput);
19 extern struct outputs_head outputs;
20
21 typedef enum {
22 CLOSEST_OUTPUT = 0,
23 FARTHEST_OUTPUT = 1
24 } output_close_far_t;
25
26 /**
27 * We have just established a connection to the X server and need the initial
28 * XRandR information to setup workspaces for each screen.
29 *
30 */
31 void randr_init(int *event_base, const bool disable_randr15);
32
33 /**
34 * Initializes a CT_OUTPUT Con (searches existing ones from inplace restart
35 * before) to use for the given Output.
36 *
37 */
38 void output_init_con(Output *output);
39
40 /**
41 * Initializes at least one workspace for this output, trying the following
42 * steps until there is at least one workspace:
43 *
44 * • Move existing workspaces, which are assigned to be on the given output, to
45 * the output.
46 * • Create the first assigned workspace for this output.
47 * • Create the first unused workspace.
48 *
49 */
50 void init_ws_for_output(Output *output);
51
52 /**
53 * Initializes the specified output, assigning the specified workspace to it.
54 *
55 */
56 //void initialize_output(xcb_connection_t *conn, Output *output, Workspace *workspace);
57
58 /**
59 * (Re-)queries the outputs via RandR and stores them in the list of outputs.
60 *
61 */
62 void randr_query_outputs(void);
63
64 /**
65 * Disables the output and moves its content.
66 *
67 */
68 void randr_disable_output(Output *output);
69
70 /**
71 * Returns the first output which is active.
72 *
73 */
74 Output *get_first_output(void);
75
76 /**
77 * Returns the output with the given name or NULL.
78 * If require_active is true, only active outputs are considered.
79 *
80 */
81 Output *get_output_by_name(const char *name, const bool require_active);
82
83 /**
84 * Returns the active (!) output which contains the coordinates x, y or NULL
85 * if there is no output which contains these coordinates.
86 *
87 */
88 Output *get_output_containing(unsigned int x, unsigned int y);
89
90 /**
91 * Returns the active output which contains the midpoint of the given rect. If
92 * such an output doesn't exist, returns the output which contains most of the
93 * rectangle or NULL if there is no output which intersects with it.
94 *
95 */
96 Output *get_output_from_rect(Rect rect);
97
98 /**
99 * Returns the active output which spans exactly the area specified by
100 * rect or NULL if there is no output like this.
101 *
102 */
103 Output *get_output_with_dimensions(Rect rect);
104
105 /**
106 * In output_containing_rect, we check if any active output contains part of the container.
107 * We do this by checking if the output rect is intersected by the Rect.
108 * This is the 2-dimensional counterpart of get_output_containing.
109 * Returns the output with the maximum intersecting area.
110 *
111 */
112 Output *output_containing_rect(Rect rect);
113
114 /**
115 * Gets the output which is the next one in the given direction.
116 *
117 * If close_far == CLOSEST_OUTPUT, then the output next to the current one will
118 * selected. If close_far == FARTHEST_OUTPUT, the output which is the last one
119 * in the given direction will be selected.
120 *
121 * NULL will be returned when no active outputs are present in the direction
122 * specified (note that ‘current’ counts as such an output).
123 *
124 */
125 Output *get_output_next(direction_t direction, Output *current, output_close_far_t close_far);
126
127 /**
128 * Like get_output_next with close_far == CLOSEST_OUTPUT, but wraps.
129 *
130 * For example if get_output_next(D_DOWN, x, FARTHEST_OUTPUT) = NULL, then
131 * get_output_next_wrap(D_DOWN, x) will return the topmost output.
132 *
133 * This function always returns a output: if no active outputs can be found,
134 * current itself is returned.
135 *
136 */
137 Output *get_output_next_wrap(direction_t direction, Output *current);
138
139 /**
140 * Creates an output covering the root window.
141 *
142 */
143 Output *create_root_output(xcb_connection_t *conn);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * regex.c: Interface to libPCRE (perl compatible regular expressions).
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 /**
14 * Creates a new 'regex' struct containing the given pattern and a PCRE
15 * compiled regular expression. Also, calls pcre_study because this regex will
16 * most likely be used often (like for every new window and on every relevant
17 * property change of existing windows).
18 *
19 * Returns NULL if the pattern could not be compiled into a regular expression
20 * (and ELOGs an appropriate error message).
21 *
22 */
23 struct regex *regex_new(const char *pattern);
24
25 /**
26 * Frees the given regular expression. It must not be used afterwards!
27 *
28 */
29 void regex_free(struct regex *regex);
30
31 /**
32 * Checks if the given regular expression matches the given input and returns
33 * true if it does. In either case, it logs the outcome using LOG(), so it will
34 * be visible without debug logging.
35 *
36 */
37 bool regex_matches(struct regex *regex, const char *input);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * render.c: Renders (determines position/sizes) the layout tree, updating the
7 * various rects. Needs to be pushed to X11 (see x.c) to be visible.
8 *
9 */
10 #pragma once
11
12 #include <config.h>
13
14 /**
15 * This is used to keep a state to pass around when rendering a con in render_con().
16 *
17 */
18 typedef struct render_params {
19 /* A copy of the coordinates of the container which is being rendered. */
20 int x;
21 int y;
22
23 /* The computed height for decorations. */
24 int deco_height;
25 /* Container rect, subtract container border. This is the actually usable space
26 * inside this container for clients. */
27 Rect rect;
28 /* The number of children of the container which is being rendered. */
29 int children;
30 /* A precalculated list of sizes of each child. */
31 int *sizes;
32 } render_params;
33
34 /**
35 * "Renders" the given container (and its children), meaning that all rects are
36 * updated correctly. Note that this function does not call any xcb_*
37 * functions, so the changes are completely done in memory only (and
38 * side-effect free). As soon as you call x_push_changes(), the changes will be
39 * updated in X11.
40 *
41 */
42 void render_con(Con *con, bool already_inset);
43
44 /**
45 * Returns the height for the decorations
46 *
47 */
48 int render_deco_height(void);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * resize.c: Interactive resizing.
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 bool resize_find_tiling_participants(Con **current, Con **other, direction_t direction, bool both_sides);
14
15 void resize_graphical_handler(Con *first, Con *second, orientation_t orientation,
16 const xcb_button_press_event_t *event,
17 bool use_threshold);
18
19 /**
20 * Resize the two given containers using the given amount of pixels or
21 * percentage points. One of the two needs to be 0. A positive amount means
22 * growing the first container while a negative means shrinking it.
23 * Returns false when the resize would result in one of the two containers
24 * having less than 1 pixel of size.
25 *
26 */
27 bool resize_neighboring_cons(Con *first, Con *second, int px, int ppt);
28
29 /**
30 * Calculate the minimum percent needed for the given container to be at least 1
31 * pixel.
32 *
33 */
34 double percent_for_1px(Con *con);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * restore_layout.c: Everything for restored containers that is not pure state
7 * parsing (which can be found in load_layout.c).
8 *
9 */
10 #pragma once
11
12 #include <config.h>
13
14 /**
15 * Opens a separate connection to X11 for placeholder windows when restoring
16 * layouts. This is done as a safety measure (users can xkill a placeholder
17 * window without killing their window manager) and for better isolation, both
18 * on the wire to X11 and thus also in the code.
19 *
20 */
21 void restore_connect(void);
22
23 /**
24 * Open placeholder windows for all children of parent. The placeholder window
25 * will vanish as soon as a real window is swallowed by the container. Until
26 * then, it exposes the criteria that must be fulfilled for a window to be
27 * swallowed by this container.
28 *
29 */
30 void restore_open_placeholder_windows(Con *con);
31
32 /**
33 * Kill the placeholder window, if placeholder refers to a placeholder window.
34 * This function is called when manage.c puts a window into an existing
35 * container. In order not to leak resources, we need to destroy the window and
36 * all associated X11 objects (pixmap/gc).
37 *
38 */
39 bool restore_kill_placeholder(xcb_window_t placeholder);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * scratchpad.c: Scratchpad functions (TODO: more description)
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 /**
14 * Moves the specified window to the __i3_scratch workspace, making it floating
15 * and setting the appropriate scratchpad_state.
16 *
17 * Gets called upon the command 'move scratchpad'.
18 *
19 */
20 void scratchpad_move(Con *con);
21
22 /**
23 * Either shows the top-most scratchpad window (con == NULL) or shows the
24 * specified con (if it is scratchpad window).
25 *
26 * When called with con == NULL and the currently focused window is a
27 * scratchpad window, this serves as a shortcut to hide it again (so the user
28 * can press the same key to quickly look something up).
29 *
30 */
31 bool scratchpad_show(Con *con);
32
33 /**
34 * When starting i3 initially (and after each change to the connected outputs),
35 * this function fixes the resolution of the __i3 pseudo-output. When that
36 * resolution is not set to a function which shares a common divisor with every
37 * active output’s resolution, floating point calculation errors will lead to
38 * the scratchpad window moving when shown repeatedly.
39 *
40 */
41 void scratchpad_fix_resolution(void);
0 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1
2 #pragma once
3
4 /***
5 Copyright 2010 Lennart Poettering
6
7 Permission is hereby granted, free of charge, to any person
8 obtaining a copy of this software and associated documentation files
9 (the "Software"), to deal in the Software without restriction,
10 including without limitation the rights to use, copy, modify, merge,
11 publish, distribute, sublicense, and/or sell copies of the Software,
12 and to permit persons to whom the Software is furnished to do so,
13 subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 SOFTWARE.
26 ***/
27
28 #include <sys/types.h>
29 #include <inttypes.h>
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 /*
36 Reference implementation of a few systemd related interfaces for
37 writing daemons. These interfaces are trivial to implement. To
38 simplify porting we provide this reference implementation.
39 Applications are welcome to reimplement the algorithms described
40 here if they do not want to include these two source files.
41
42 The following functionality is provided:
43
44 - Support for logging with log levels on stderr
45 - File descriptor passing for socket-based activation
46 - Daemon startup and status notification
47 - Detection of systemd boots
48
49 You may compile this with -DDISABLE_SYSTEMD to disable systemd
50 support. This makes all those calls NOPs that are directly related to
51 systemd (i.e. only sd_is_xxx() will stay useful).
52
53 Since this is drop-in code we don't want any of our symbols to be
54 exported in any case. Hence we declare hidden visibility for all of
55 them.
56
57 You may find an up-to-date version of these source files online:
58
59 https://cgit.freedesktop.org/systemd/plain/src/sd-daemon.h
60 https://cgit.freedesktop.org/systemd/plain/src/sd-daemon.c
61
62 This should compile on non-Linux systems, too, but with the
63 exception of the sd_is_xxx() calls all functions will become NOPs.
64
65 See sd-daemon(7) for more information.
66 */
67
68 #ifndef _sd_printf_attr_
69 #if __GNUC__ >= 4
70 #define _sd_printf_attr_(a, b) __attribute__((format(printf, a, b)))
71 #else
72 #define _sd_printf_attr_(a, b)
73 #endif
74 #endif
75
76 #ifndef _sd_hidden_
77 #if (__GNUC__ >= 4) && !defined(SD_EXPORT_SYMBOLS)
78 #define _sd_hidden_ __attribute__((visibility("hidden")))
79 #else
80 #define _sd_hidden_
81 #endif
82 #endif
83
84 /*
85 Log levels for usage on stderr:
86
87 fprintf(stderr, SD_NOTICE "Hello World!\n");
88
89 This is similar to printk() usage in the kernel.
90 */
91 #define SD_EMERG "<0>" /* system is unusable */
92 #define SD_ALERT "<1>" /* action must be taken immediately */
93 #define SD_CRIT "<2>" /* critical conditions */
94 #define SD_ERR "<3>" /* error conditions */
95 #define SD_WARNING "<4>" /* warning conditions */
96 #define SD_NOTICE "<5>" /* normal but significant condition */
97 #define SD_INFO "<6>" /* informational */
98 #define SD_DEBUG "<7>" /* debug-level messages */
99
100 /* The first passed file descriptor is fd 3 */
101 #define SD_LISTEN_FDS_START 3
102
103 /*
104 Returns how many file descriptors have been passed, or a negative
105 errno code on failure. Optionally, removes the $LISTEN_FDS and
106 $LISTEN_PID file descriptors from the environment (recommended, but
107 problematic in threaded environments). If r is the return value of
108 this function you'll find the file descriptors passed as fds
109 SD_LISTEN_FDS_START to SD_LISTEN_FDS_START+r-1. Returns a negative
110 errno style error code on failure. This function call ensures that
111 the FD_CLOEXEC flag is set for the passed file descriptors, to make
112 sure they are not passed on to child processes. If FD_CLOEXEC shall
113 not be set, the caller needs to unset it after this call for all file
114 descriptors that are used.
115
116 See sd_listen_fds(3) for more information.
117 */
118 int sd_listen_fds(int unset_environment) _sd_hidden_;
119
120 /*
121 Helper call for identifying a passed file descriptor. Returns 1 if
122 the file descriptor is a FIFO in the file system stored under the
123 specified path, 0 otherwise. If path is NULL a path name check will
124 not be done and the call only verifies if the file descriptor
125 refers to a FIFO. Returns a negative errno style error code on
126 failure.
127
128 See sd_is_fifo(3) for more information.
129 */
130 int sd_is_fifo(int fd, const char *path) _sd_hidden_;
131
132 /*
133 Helper call for identifying a passed file descriptor. Returns 1 if
134 the file descriptor is a socket of the specified family (AF_INET,
135 ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If
136 family is 0 a socket family check will not be done. If type is 0 a
137 socket type check will not be done and the call only verifies if
138 the file descriptor refers to a socket. If listening is > 0 it is
139 verified that the socket is in listening mode. (i.e. listen() has
140 been called) If listening is == 0 it is verified that the socket is
141 not in listening mode. If listening is < 0 no listening mode check
142 is done. Returns a negative errno style error code on failure.
143
144 See sd_is_socket(3) for more information.
145 */
146 int sd_is_socket(int fd, int family, int type, int listening) _sd_hidden_;
147
148 /*
149 Helper call for identifying a passed file descriptor. Returns 1 if
150 the file descriptor is an Internet socket, of the specified family
151 (either AF_INET or AF_INET6) and the specified type (SOCK_DGRAM,
152 SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version
153 check is not done. If type is 0 a socket type check will not be
154 done. If port is 0 a socket port check will not be done. The
155 listening flag is used the same way as in sd_is_socket(). Returns a
156 negative errno style error code on failure.
157
158 See sd_is_socket_inet(3) for more information.
159 */
160 int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) _sd_hidden_;
161
162 /*
163 Helper call for identifying a passed file descriptor. Returns 1 if
164 the file descriptor is an AF_UNIX socket of the specified type
165 (SOCK_DGRAM, SOCK_STREAM, ...) and path, 0 otherwise. If type is 0
166 a socket type check will not be done. If path is NULL a socket path
167 check will not be done. For normal AF_UNIX sockets set length to
168 0. For abstract namespace sockets set length to the length of the
169 socket name (including the initial 0 byte), and pass the full
170 socket path in path (including the initial 0 byte). The listening
171 flag is used the same way as in sd_is_socket(). Returns a negative
172 errno style error code on failure.
173
174 See sd_is_socket_unix(3) for more information.
175 */
176 int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) _sd_hidden_;
177
178 /*
179 Informs systemd about changed daemon state. This takes a number of
180 newline separated environment-style variable assignments in a
181 string. The following variables are known:
182
183 READY=1 Tells systemd that daemon startup is finished (only
184 relevant for services of Type=notify). The passed
185 argument is a boolean "1" or "0". Since there is
186 little value in signaling non-readiness the only
187 value daemons should send is "READY=1".
188
189 STATUS=... Passes a single-line status string back to systemd
190 that describes the daemon state. This is free-from
191 and can be used for various purposes: general state
192 feedback, fsck-like programs could pass completion
193 percentages and failing programs could pass a human
194 readable error message. Example: "STATUS=Completed
195 66% of file system check..."
196
197 ERRNO=... If a daemon fails, the errno-style error code,
198 formatted as string. Example: "ERRNO=2" for ENOENT.
199
200 BUSERROR=... If a daemon fails, the D-Bus error-style error
201 code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut"
202
203 MAINPID=... The main pid of a daemon, in case systemd did not
204 fork off the process itself. Example: "MAINPID=4711"
205
206 Daemons can choose to send additional variables. However, it is
207 recommended to prefix variable names not listed above with X_.
208
209 Returns a negative errno-style error code on failure. Returns > 0
210 if systemd could be notified, 0 if it couldn't possibly because
211 systemd is not running.
212
213 Example: When a daemon finished starting up, it could issue this
214 call to notify systemd about it:
215
216 sd_notify(0, "READY=1");
217
218 See sd_notifyf() for more complete examples.
219
220 See sd_notify(3) for more information.
221 */
222 int sd_notify(int unset_environment, const char *state) _sd_hidden_;
223
224 /*
225 Similar to sd_notify() but takes a format string.
226
227 Example 1: A daemon could send the following after initialization:
228
229 sd_notifyf(0, "READY=1\n"
230 "STATUS=Processing requests...\n"
231 "MAINPID=%lu",
232 (unsigned long) getpid());
233
234 Example 2: A daemon could send the following shortly before
235 exiting, on failure:
236
237 sd_notifyf(0, "STATUS=Failed to start up: %s\n"
238 "ERRNO=%i",
239 strerror(errno),
240 errno);
241
242 See sd_notifyf(3) for more information.
243 */
244 int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_attr_(2, 3) _sd_hidden_;
245
246 /*
247 Returns > 0 if the system was booted with systemd. Returns < 0 on
248 error. Returns 0 if the system was not booted with systemd. Note
249 that all of the functions above handle non-systemd boots just
250 fine. You should NOT protect them with a call to this function. Also
251 note that this function checks whether the system, not the user
252 session is controlled by systemd. However the functions above work
253 for both user and system services.
254
255 See sd_booted(3) for more information.
256 */
257 int sd_booted(void) _sd_hidden_;
258
259 #ifdef __cplusplus
260 }
261 #endif
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * The format of the shmlog data structure which i3 development versions use by
7 * default (ringbuffer for storing the debug log).
8 *
9 */
10 #pragma once
11
12 #include <config.h>
13
14 #include <stdint.h>
15 #if !defined(__OpenBSD__)
16 #include <pthread.h>
17 #endif
18
19 /* Default shmlog size if not set by user. */
20 extern const int default_shmlog_size;
21
22 /**
23 * Header of the shmlog file. Used by i3/src/log.c and i3/i3-dump-log/main.c.
24 *
25 */
26 typedef struct i3_shmlog_header {
27 /* Byte offset where the next line will be written to. */
28 uint32_t offset_next_write;
29
30 /* Byte offset where the last wrap occurred. */
31 uint32_t offset_last_wrap;
32
33 /* The size of the logfile in bytes. Since the size is limited to 25 MiB
34 * an uint32_t is sufficient. */
35 uint32_t size;
36
37 /* wrap counter. We need it to reliably signal to clients that we just
38 * wrapped (clients cannot use offset_last_wrap because that might
39 * coincidentally be exactly the same as previously). Overflows can happen
40 * and don’t matter — clients use an equality check (==). */
41 uint32_t wrap_count;
42
43 #if !defined(__OpenBSD__)
44 /* pthread condvar which will be broadcasted whenever there is a new
45 * message in the log. i3-dump-log uses this to implement -f (follow, like
46 * tail -f) in an efficient way. */
47 pthread_cond_t condvar;
48 #endif
49 } i3_shmlog_header;
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #pragma once
8
9 #include <config.h>
10
11 /**
12 * Configured a signal handler to gracefully handle crashes and allow the user
13 * to generate a backtrace and rescue their session.
14 *
15 */
16 void setup_signal_handler(void);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * startup.c: Startup notification code. Ensures a startup notification context
7 * is setup when launching applications. We store the current
8 * workspace to open windows in that startup notification context on
9 * the appropriate workspace.
10 *
11 */
12 #pragma once
13
14 #include <config.h>
15
16 #define SN_API_NOT_YET_FROZEN 1
17 #include <libsn/sn-monitor.h>
18
19 /**
20 * Starts the given application by passing it through a shell. We use double
21 * fork to avoid zombie processes. As the started application’s parent exits
22 * (immediately), the application is reparented to init (process-id 1), which
23 * correctly handles children, so we don’t have to do it :-).
24 *
25 * The shell used to start applications is the system's bourne shell (i.e.,
26 * /bin/sh).
27 *
28 * The no_startup_id flag determines whether a startup notification context
29 * (and ID) should be created, which is the default and encouraged behavior.
30 *
31 */
32 void start_application(const char *command, bool no_startup_id);
33
34 /**
35 * Deletes a startup sequence, ignoring whether its timeout has elapsed.
36 * Useful when e.g. a window is moved between workspaces and its children
37 * shouldn't spawn on the original workspace.
38 *
39 */
40 void startup_sequence_delete(struct Startup_Sequence *sequence);
41
42 /**
43 * Called by libstartup-notification when something happens
44 *
45 */
46 void startup_monitor_event(SnMonitorEvent *event, void *userdata);
47
48 /**
49 * Renames workspaces that are mentioned in the startup sequences.
50 *
51 */
52 void startup_sequence_rename_workspace(const char *old_name, const char *new_name);
53
54 /**
55 * Gets the stored startup sequence for the _NET_STARTUP_ID of a given window.
56 *
57 */
58 struct Startup_Sequence *startup_sequence_get(i3Window *cwindow,
59 xcb_get_property_reply_t *startup_id_reply, bool ignore_mapped_leader);
60
61 /**
62 * Checks if the given window belongs to a startup notification by checking if
63 * the _NET_STARTUP_ID property is set on the window (or on its leader, if it’s
64 * unset).
65 *
66 * If so, returns the workspace on which the startup was initiated.
67 * Returns NULL otherwise.
68 *
69 */
70 char *startup_workspace_for_window(i3Window *cwindow, xcb_get_property_reply_t *startup_id_reply);
71
72 /**
73 * Deletes the startup sequence for a window if it exists.
74 *
75 */
76 void startup_sequence_delete_by_window(i3Window *win);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * sync.c: i3 sync protocol: https://i3wm.org/docs/testsuite.html#i3_sync
7 *
8 */
9 #pragma once
10
11 #include <xcb/xcb.h>
12
13 void sync_respond(xcb_window_t window, uint32_t rnd);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * tree.c: Everything that primarily modifies the layout tree data structure.
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 extern Con *croot;
14 /* TODO: i am not sure yet how much access to the focused container should
15 * be permitted to source files */
16 extern Con *focused;
17 TAILQ_HEAD(all_cons_head, Con);
18 extern struct all_cons_head all_cons;
19
20 /**
21 * Initializes the tree by creating the root node, adding all RandR outputs
22 * to the tree (that means randr_init() has to be called before) and
23 * assigning a workspace to each RandR output.
24 *
25 */
26 void tree_init(xcb_get_geometry_reply_t *geometry);
27
28 /**
29 * Opens an empty container in the current container
30 *
31 */
32 Con *tree_open_con(Con *con, i3Window *window);
33
34 /**
35 * Splits (horizontally or vertically) the given container by creating a new
36 * container which contains the old one and the future ones.
37 *
38 */
39 void tree_split(Con *con, orientation_t orientation);
40
41 /**
42 * Moves focus one level up. Returns true if focus changed.
43 *
44 */
45 bool level_up(void);
46
47 /**
48 * Moves focus one level down. Returns true if focus changed.
49 *
50 */
51 bool level_down(void);
52
53 /**
54 * Renders the tree, that is rendering all outputs using render_con() and
55 * pushing the changes to X11 using x_push_changes().
56 *
57 */
58 void tree_render(void);
59
60 /**
61 * Changes focus in the given direction
62 *
63 */
64 void tree_next(Con *con, direction_t direction);
65
66 /**
67 * Get the previous / next sibling
68 *
69 */
70 Con *get_tree_next_sibling(Con *con, position_t direction);
71
72 /**
73 * Closes the given container including all children.
74 * Returns true if the container was killed or false if just WM_DELETE was sent
75 * and the window is expected to kill itself.
76 *
77 * The dont_kill_parent flag is specified when the function calls itself
78 * recursively while deleting a containers children.
79 *
80 */
81 bool tree_close_internal(Con *con, kill_window_t kill_window, bool dont_kill_parent);
82
83 /**
84 * Loads tree from ~/.i3/_restart.json (used for in-place restarts).
85 *
86 */
87 bool tree_restore(const char *path, xcb_get_geometry_reply_t *geometry);
88
89 /**
90 * tree_flatten() removes pairs of redundant split containers, e.g.:
91 * [workspace, horizontal]
92 * [v-split] [child3]
93 * [h-split]
94 * [child1] [child2]
95 * In this example, the v-split and h-split container are redundant.
96 * Such a situation can be created by moving containers in a direction which is
97 * not the orientation of their parent container. i3 needs to create a new
98 * split container then and if you move containers this way multiple times,
99 * redundant chains of split-containers can be the result.
100 *
101 */
102 void tree_flatten(Con *child);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * util.c: Utility functions, which can be useful everywhere within i3 (see
7 * also libi3).
8 *
9 */
10 #pragma once
11
12 #include <config.h>
13
14 #include <err.h>
15
16 #include "data.h"
17
18 #define die(...) errx(EXIT_FAILURE, __VA_ARGS__);
19 #define exit_if_null(pointer, ...) \
20 { \
21 if (pointer == NULL) \
22 die(__VA_ARGS__); \
23 }
24 #define STARTS_WITH(string, needle) (strncasecmp((string), (needle), strlen((needle))) == 0)
25 #define CIRCLEQ_NEXT_OR_NULL(head, elm, field) (CIRCLEQ_NEXT(elm, field) != CIRCLEQ_END(head) ? CIRCLEQ_NEXT(elm, field) : NULL)
26 #define CIRCLEQ_PREV_OR_NULL(head, elm, field) (CIRCLEQ_PREV(elm, field) != CIRCLEQ_END(head) ? CIRCLEQ_PREV(elm, field) : NULL)
27
28 #define NODES_FOREACH(head) \
29 for (Con *child = (Con *)-1; (child == (Con *)-1) && ((child = 0), true);) \
30 TAILQ_FOREACH (child, &((head)->nodes_head), nodes)
31
32 #define NODES_FOREACH_REVERSE(head) \
33 for (Con *child = (Con *)-1; (child == (Con *)-1) && ((child = 0), true);) \
34 TAILQ_FOREACH_REVERSE (child, &((head)->nodes_head), nodes_head, nodes)
35
36 /* greps the ->nodes of the given head and returns the first node that matches the given condition */
37 #define GREP_FIRST(dest, head, condition) \
38 NODES_FOREACH (head) { \
39 if (!(condition)) \
40 continue; \
41 \
42 (dest) = child; \
43 break; \
44 }
45
46 #define FREE(pointer) \
47 do { \
48 free(pointer); \
49 pointer = NULL; \
50 } while (0)
51
52 #define CALL(obj, member, ...) obj->member(obj, ##__VA_ARGS__)
53
54 #define SWAP(first, second, type) \
55 do { \
56 type tmp_SWAP = first; \
57 first = second; \
58 second = tmp_SWAP; \
59 } while (0)
60
61 int min(int a, int b);
62 int max(int a, int b);
63 bool rect_contains(Rect rect, uint32_t x, uint32_t y);
64 Rect rect_add(Rect a, Rect b);
65 Rect rect_sub(Rect a, Rect b);
66 bool rect_equals(Rect a, Rect b);
67 Rect rect_sanitize_dimensions(Rect rect);
68
69 /**
70 * Returns true if the name consists of only digits.
71 *
72 */
73 __attribute__((pure)) bool name_is_digits(const char *name);
74
75 /**
76 * Set 'out' to the layout_t value for the given layout. The function
77 * returns true on success or false if the passed string is not a valid
78 * layout name.
79 *
80 */
81 bool layout_from_name(const char *layout_str, layout_t *out);
82
83 /**
84 * Parses the workspace name as a number. Returns -1 if the workspace should be
85 * interpreted as a "named workspace".
86 *
87 */
88 int ws_name_to_number(const char *name);
89
90 /**
91 * Updates *destination with new_value and returns true if it was changed or false
92 * if it was the same
93 *
94 */
95 bool update_if_necessary(uint32_t *destination, const uint32_t new_value);
96
97 /**
98 * exec()s an i3 utility, for example the config file migration script or
99 * i3-nagbar. This function first searches $PATH for the given utility named,
100 * then falls back to the dirname() of the i3 executable path and then falls
101 * back to the dirname() of the target of /proc/self/exe (on linux).
102 *
103 * This function should be called after fork()ing.
104 *
105 * The first argument of the given argv vector will be overwritten with the
106 * executable name, so pass NULL.
107 *
108 * If the utility cannot be found in any of these locations, it exits with
109 * return code 2.
110 *
111 */
112 void exec_i3_utility(char *name, char *argv[]);
113
114 /**
115 * Checks if the given path exists by calling stat().
116 *
117 */
118 bool path_exists(const char *path);
119
120 /**
121 * Restart i3 in-place
122 * appends -a to argument list to disable autostart
123 *
124 */
125 void i3_restart(bool forget_layout);
126
127 /**
128 * Escapes the given string if a pango font is currently used.
129 * If the string has to be escaped, the input string will be free'd.
130 *
131 */
132 char *pango_escape_markup(char *input);
133
134 /**
135 * Starts an i3-nagbar instance with the given parameters. Takes care of
136 * handling SIGCHLD and killing i3-nagbar when i3 exits.
137 *
138 * The resulting PID will be stored in *nagbar_pid and can be used with
139 * kill_nagbar() to kill the bar later on.
140 *
141 */
142 void start_nagbar(pid_t *nagbar_pid, char *argv[]);
143
144 /**
145 * Kills the i3-nagbar process, if *nagbar_pid != -1.
146 *
147 * If wait_for_it is set (restarting i3), this function will waitpid(),
148 * otherwise, ev is assumed to handle it (reloading).
149 *
150 */
151 void kill_nagbar(pid_t *nagbar_pid, bool wait_for_it);
152
153 /**
154 * Converts a string into a long using strtol().
155 * This is a convenience wrapper checking the parsing result. It returns true
156 * if the number could be parsed.
157 */
158 bool parse_long(const char *str, long *out, int base);
159
160 /**
161 * Slurp reads path in its entirety into buf, returning the length of the file
162 * or -1 if the file could not be read. buf is set to a buffer of appropriate
163 * size, or NULL if -1 is returned.
164 *
165 */
166 ssize_t slurp(const char *path, char **buf);
167
168 /**
169 * Convert a direction to its corresponding orientation.
170 *
171 */
172 orientation_t orientation_from_direction(direction_t direction);
173
174 /**
175 * Convert a direction to its corresponding position.
176 *
177 */
178 position_t position_from_direction(direction_t direction);
179
180 /**
181 * Convert orientation and position to the corresponding direction.
182 *
183 */
184 direction_t direction_from_orientation_position(orientation_t orientation, position_t position);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * window.c: Updates window attributes (X11 hints/properties).
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 /**
14 * Frees an i3Window and all its members.
15 *
16 */
17 void window_free(i3Window *win);
18
19 /**
20 * Updates the WM_CLASS (consisting of the class and instance) for the
21 * given window.
22 *
23 */
24 void window_update_class(i3Window *win, xcb_get_property_reply_t *prop);
25
26 /**
27 * Updates the name by using _NET_WM_NAME (encoded in UTF-8) for the given
28 * window. Further updates using window_update_name_legacy will be ignored.
29 *
30 */
31 void window_update_name(i3Window *win, xcb_get_property_reply_t *prop);
32
33 /**
34 * Updates the name by using WM_NAME (encoded in COMPOUND_TEXT). We do not
35 * touch what the client sends us but pass it to xcb_image_text_8. To get
36 * proper unicode rendering, the application has to use _NET_WM_NAME (see
37 * window_update_name()).
38 *
39 */
40 void window_update_name_legacy(i3Window *win, xcb_get_property_reply_t *prop);
41
42 /**
43 * Updates the CLIENT_LEADER (logical parent window).
44 *
45 */
46 void window_update_leader(i3Window *win, xcb_get_property_reply_t *prop);
47
48 /**
49 * Updates the TRANSIENT_FOR (logical parent window).
50 *
51 */
52 void window_update_transient_for(i3Window *win, xcb_get_property_reply_t *prop);
53
54 /**
55 * Updates the _NET_WM_STRUT_PARTIAL (reserved pixels at the screen edges)
56 *
57 */
58 void window_update_strut_partial(i3Window *win, xcb_get_property_reply_t *prop);
59
60 /**
61 * Updates the WM_WINDOW_ROLE
62 *
63 */
64 void window_update_role(i3Window *win, xcb_get_property_reply_t *prop);
65
66 /**
67 * Updates the _NET_WM_WINDOW_TYPE property.
68 *
69 */
70 void window_update_type(i3Window *window, xcb_get_property_reply_t *reply);
71
72 /**
73 * Updates the WM_NORMAL_HINTS
74 *
75 */
76 bool window_update_normal_hints(i3Window *win, xcb_get_property_reply_t *reply, xcb_get_geometry_reply_t *geom);
77
78 /**
79 * Updates the WM_HINTS (we only care about the input focus handling part).
80 *
81 */
82 void window_update_hints(i3Window *win, xcb_get_property_reply_t *prop, bool *urgency_hint);
83
84 /**
85 * Updates the MOTIF_WM_HINTS. The container's border style should be set to
86 * `motif_border_style' if border style is not BS_NORMAL.
87 *
88 * i3 only uses this hint when it specifies a window should have no
89 * title bar, or no decorations at all, which is how most window managers
90 * handle it.
91 *
92 * The EWMH spec intended to replace Motif hints with _NET_WM_WINDOW_TYPE, but
93 * it is still in use by popular widget toolkits such as GTK+ and Java AWT.
94 *
95 */
96 void window_update_motif_hints(i3Window *win, xcb_get_property_reply_t *prop, border_style_t *motif_border_style);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * workspace.c: Modifying workspaces, accessing them, moving containers to
7 * workspaces.
8 *
9 */
10 #pragma once
11
12 #include <config.h>
13
14 #include "data.h"
15 #include "tree.h"
16 #include "randr.h"
17
18 /* We use NET_WM_DESKTOP_NONE for cases where we cannot determine the EWMH
19 * desktop index for a window. We cannot use a negative value like -1 since we
20 * need to use uint32_t as we actually need the full range of it. This is
21 * technically dangerous, but it's safe to assume that we will never have more
22 * than 4294967279 workspaces open at a time. */
23 #define NET_WM_DESKTOP_NONE 0xFFFFFFF0
24 #define NET_WM_DESKTOP_ALL 0xFFFFFFFF
25
26 /**
27 * Stores a copy of the name of the last used workspace for the workspace
28 * back-and-forth switching.
29 *
30 */
31 extern char *previous_workspace_name;
32
33 /**
34 * Returns the workspace with the given name or NULL if such a workspace does
35 * not exist.
36 *
37 */
38 Con *get_existing_workspace_by_name(const char *name);
39
40 /**
41 * Returns the workspace with the given number or NULL if such a workspace does
42 * not exist.
43 *
44 */
45 Con *get_existing_workspace_by_num(int num);
46
47 /**
48 * Returns true if the first output assigned to a workspace with the given
49 * workspace assignment is the same as the given output.
50 *
51 */
52 bool output_triggers_assignment(Output *output, struct Workspace_Assignment *assignment);
53
54 /**
55 * Returns a pointer to the workspace with the given number (starting at 0),
56 * creating the workspace if necessary (by allocating the necessary amount of
57 * memory and initializing the data structures correctly).
58 *
59 * If created is not NULL, *created will be set to whether or not the
60 * workspace has just been created.
61 *
62 */
63 Con *workspace_get(const char *num, bool *created);
64
65 /**
66 * Extracts workspace names from keybindings (e.g. “web” from “bindsym $mod+1
67 * workspace web”), so that when an output needs a workspace, i3 can start with
68 * the first configured one. Needs to be called before reorder_bindings() so
69 * that the config-file order is used, not the i3-internal order.
70 *
71 */
72 void extract_workspace_names_from_bindings(void);
73
74 /**
75 * Returns a pointer to a new workspace in the given output. The workspace
76 * is created attached to the tree hierarchy through the given content
77 * container.
78 *
79 */
80 Con *create_workspace_on_output(Output *output, Con *content);
81
82 /**
83 * Returns true if the workspace is currently visible. Especially important for
84 * multi-monitor environments, as they can have multiple currenlty active
85 * workspaces.
86 *
87 */
88 bool workspace_is_visible(Con *ws);
89
90 /**
91 * Switches to the given workspace
92 *
93 */
94 void workspace_show(Con *ws);
95
96 /**
97 * Looks up the workspace by name and switches to it.
98 *
99 */
100 void workspace_show_by_name(const char *num);
101
102 /**
103 * Returns the next workspace.
104 *
105 */
106 Con *workspace_next(void);
107
108 /**
109 * Returns the previous workspace.
110 *
111 */
112 Con *workspace_prev(void);
113
114 /**
115 * Returns the next workspace on the same output
116 *
117 */
118 Con *workspace_next_on_output(void);
119
120 /**
121 * Returns the previous workspace on the same output
122 *
123 */
124 Con *workspace_prev_on_output(void);
125
126 /**
127 * Focuses the previously focused workspace.
128 *
129 */
130 void workspace_back_and_forth(void);
131
132 /**
133 * Returns the previously focused workspace con, or NULL if unavailable.
134 *
135 */
136 Con *workspace_back_and_forth_get(void);
137
138 #if 0
139 /**
140 * Assigns the given workspace to the given screen by correctly updating its
141 * state and reconfiguring all the clients on this workspace.
142 *
143 * This is called when initializing a screen and when re-assigning it to a
144 * different screen which just got available (if you configured it to be on
145 * screen 1 and you just plugged in screen 1).
146 *
147 */
148 void workspace_assign_to(Workspace *ws, Output *screen, bool hide_it);
149
150 /**
151 * Initializes the given workspace if it is not already initialized. The given
152 * screen is to be understood as a fallback, if the workspace itself either
153 * was not assigned to a particular screen or cannot be placed there because
154 * the screen is not attached at the moment.
155 *
156 */
157 void workspace_initialize(Workspace *ws, Output *screen, bool recheck);
158
159 /**
160 * Gets the first unused workspace for the given screen, taking into account
161 * the preferred_screen setting of every workspace (workspace assignments).
162 *
163 */
164 Workspace *get_first_workspace_for_output(Output *screen);
165
166 /**
167 * Unmaps all clients (and stack windows) of the given workspace.
168 *
169 * This needs to be called separately when temporarily rendering a workspace
170 * which is not the active workspace to force reconfiguration of all clients,
171 * like in src/xinerama.c when re-assigning a workspace to another screen.
172 *
173 */
174 void workspace_unmap_clients(xcb_connection_t *conn, Workspace *u_ws);
175
176 /**
177 * Maps all clients (and stack windows) of the given workspace.
178 *
179 */
180 void workspace_map_clients(xcb_connection_t *conn, Workspace *ws);
181 #endif
182
183 /**
184 * Goes through all clients on the given workspace and updates the workspace’s
185 * urgent flag accordingly.
186 *
187 */
188 void workspace_update_urgent_flag(Con *ws);
189
190 /**
191 * 'Forces' workspace orientation by moving all cons into a new split-con with
192 * the same orientation as the workspace and then changing the workspace
193 * orientation.
194 *
195 */
196 void ws_force_orientation(Con *ws, orientation_t orientation);
197
198 /**
199 * Called when a new con (with a window, not an empty or split con) should be
200 * attached to the workspace (for example when managing a new window or when
201 * moving an existing window to the workspace level).
202 *
203 * Depending on the workspace_layout setting, this function either returns the
204 * workspace itself (default layout) or creates a new stacked/tabbed con and
205 * returns that.
206 *
207 */
208 Con *workspace_attach_to(Con *ws);
209
210 /**
211 * Creates a new container and re-parents all of children from the given
212 * workspace into it.
213 *
214 * The container inherits the layout from the workspace.
215 */
216 Con *workspace_encapsulate(Con *ws);
217
218 /**
219 * Move the given workspace to the specified output.
220 *
221 */
222 void workspace_move_to_output(Con *ws, Output *output);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * x.c: Interface to X11, transfers our in-memory state to X11 (see also
7 * render.c). Basically a big state machine.
8 *
9 */
10 #pragma once
11
12 #include <config.h>
13
14 /** Stores the X11 window ID of the currently focused window */
15 extern xcb_window_t focused_id;
16
17 /**
18 * Initializes the X11 part for the given container. Called exactly once for
19 * every container from con_new().
20 *
21 */
22 void x_con_init(Con *con);
23
24 /**
25 * Moves a child window from Container src to Container dest.
26 *
27 */
28 void x_move_win(Con *src, Con *dest);
29
30 /**
31 * Reparents the child window of the given container (necessary for sticky
32 * containers). The reparenting happens in the next call of x_push_changes().
33 *
34 */
35 void x_reparent_child(Con *con, Con *old);
36
37 /**
38 * Re-initializes the associated X window state for this container. You have
39 * to call this when you assign a client to an empty container to ensure that
40 * its state gets updated correctly.
41 *
42 */
43 void x_reinit(Con *con);
44
45 /**
46 * Kills the window decoration associated with the given container.
47 *
48 */
49 void x_con_kill(Con *con);
50
51 /*
52 * Completely reinitializes the container's frame, without destroying the old window.
53 *
54 */
55 void x_con_reframe(Con *con);
56
57 /**
58 * Returns true if the client supports the given protocol atom (like WM_DELETE_WINDOW)
59 *
60 */
61 bool window_supports_protocol(xcb_window_t window, xcb_atom_t atom);
62
63 /**
64 * Kills the given X11 window using WM_DELETE_WINDOW (if supported).
65 *
66 */
67 void x_window_kill(xcb_window_t window, kill_window_t kill_window);
68
69 /**
70 * Draws the decoration of the given container onto its parent.
71 *
72 */
73 void x_draw_decoration(Con *con);
74
75 /**
76 * Recursively calls x_draw_decoration. This cannot be done in x_push_node
77 * because x_push_node uses focus order to recurse (see the comment above)
78 * while drawing the decoration needs to happen in the actual order.
79 *
80 */
81 void x_deco_recurse(Con *con);
82
83 /**
84 * This function pushes the properties of each node of the layout tree to
85 * X11 if they have changed (like the map state, position of the window, …).
86 * It recursively traverses all children of the given node.
87 *
88 */
89 void x_push_node(Con *con);
90
91 /**
92 * Pushes all changes (state of each node, see x_push_node() and the window
93 * stack) to X11.
94 *
95 */
96 void x_push_changes(Con *con);
97
98 /**
99 * Raises the specified container in the internal stack of X windows. The
100 * next call to x_push_changes() will make the change visible in X11.
101 *
102 */
103 void x_raise_con(Con *con);
104
105 /**
106 * Sets the WM_NAME property (so, no UTF8, but used only for debugging anyways)
107 * of the given name. Used for properly tagging the windows for easily spotting
108 * i3 windows in xwininfo -root -all.
109 *
110 */
111 void x_set_name(Con *con, const char *name);
112
113 /**
114 * Set up the SHMLOG_PATH atom.
115 *
116 */
117 void update_shmlog_atom(void);
118
119 /**
120 * Sets up i3 specific atoms (I3_SOCKET_PATH and I3_CONFIG_PATH)
121 *
122 */
123 void x_set_i3_atoms(void);
124
125 /**
126 * Set warp_to coordinates. This will trigger on the next call to
127 * x_push_changes().
128 *
129 */
130 void x_set_warp_to(Rect *rect);
131
132 /**
133 * Applies the given mask to the event mask of every i3 window decoration X11
134 * window. This is useful to disable EnterNotify while resizing so that focus
135 * is untouched.
136 *
137 */
138 void x_mask_event_mask(uint32_t mask);
139
140 /**
141 * Enables or disables nonrectangular shape of the container frame.
142 */
143 void x_set_shape(Con *con, xcb_shape_sk_t kind, bool enable);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * xcb.c: Helper functions for easier usage of XCB
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include "data.h"
14 #include "xcursor.h"
15
16 #define _NET_WM_STATE_REMOVE 0
17 #define _NET_WM_STATE_ADD 1
18 #define _NET_WM_STATE_TOGGLE 2
19
20 /* from X11/keysymdef.h */
21 #define XCB_NUM_LOCK 0xff7f
22
23 /* The event masks are defined here because we don’t only set them once but we
24 need to set slight variations of them (without XCB_EVENT_MASK_ENTER_WINDOW
25 while rendering the layout) */
26 /** The XCB_CW_EVENT_MASK for the child (= real window) */
27 #define CHILD_EVENT_MASK (XCB_EVENT_MASK_PROPERTY_CHANGE | \
28 XCB_EVENT_MASK_STRUCTURE_NOTIFY | \
29 XCB_EVENT_MASK_FOCUS_CHANGE)
30
31 /** The XCB_CW_EVENT_MASK for its frame */
32 #define FRAME_EVENT_MASK (XCB_EVENT_MASK_BUTTON_PRESS | /* …mouse is pressed/released */ \
33 XCB_EVENT_MASK_BUTTON_RELEASE | \
34 XCB_EVENT_MASK_POINTER_MOTION | /* …mouse is moved */ \
35 XCB_EVENT_MASK_EXPOSURE | /* …our window needs to be redrawn */ \
36 XCB_EVENT_MASK_STRUCTURE_NOTIFY | /* …the frame gets destroyed */ \
37 XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | /* …the application tries to resize itself */ \
38 XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | /* …subwindows get notifies */ \
39 XCB_EVENT_MASK_ENTER_WINDOW) /* …user moves cursor inside our window */
40
41 #define ROOT_EVENT_MASK (XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | \
42 XCB_EVENT_MASK_BUTTON_PRESS | \
43 XCB_EVENT_MASK_STRUCTURE_NOTIFY | /* when the user adds a screen (e.g. video \
44 * projector), the root window gets a \
45 * ConfigureNotify */ \
46 XCB_EVENT_MASK_POINTER_MOTION | \
47 XCB_EVENT_MASK_PROPERTY_CHANGE | \
48 XCB_EVENT_MASK_FOCUS_CHANGE | \
49 XCB_EVENT_MASK_ENTER_WINDOW)
50
51 #define xmacro(atom) extern xcb_atom_t A_##atom;
52 #include "atoms.xmacro"
53 #undef xmacro
54
55 extern unsigned int xcb_numlock_mask;
56
57 /**
58 * Convenience wrapper around xcb_create_window which takes care of depth,
59 * generating an ID and checking for errors.
60 *
61 */
62 xcb_window_t create_window(xcb_connection_t *conn, Rect r, uint16_t depth, xcb_visualid_t visual,
63 uint16_t window_class, enum xcursor_cursor_t cursor, bool map, uint32_t mask, uint32_t *values);
64
65 /**
66 * Generates a configure_notify_event with absolute coordinates (relative to
67 * the X root window, not to the client’s frame) for the given client.
68 *
69 */
70 void fake_absolute_configure_notify(Con *con);
71
72 /**
73 * Sends the WM_TAKE_FOCUS ClientMessage to the given window
74 *
75 */
76 void send_take_focus(xcb_window_t window, xcb_timestamp_t timestamp);
77
78 /**
79 * Configures the given window to have the size/position specified by given rect
80 *
81 */
82 void xcb_set_window_rect(xcb_connection_t *conn, xcb_window_t window, Rect r);
83
84 /**
85 * Returns the first supported _NET_WM_WINDOW_TYPE atom.
86 *
87 */
88 xcb_atom_t xcb_get_preferred_window_type(xcb_get_property_reply_t *reply);
89
90 /**
91 * Returns true if the given reply contains the given data.
92 *
93 */
94 bool xcb_reply_contains_atom(xcb_get_property_reply_t *prop, xcb_atom_t atom);
95
96 /**
97 * Get depth of visual specified by visualid
98 *
99 */
100 uint16_t get_visual_depth(xcb_visualid_t visual_id);
101
102 /**
103 * Get visual type specified by visualid
104 *
105 */
106 xcb_visualtype_t *get_visualtype_by_id(xcb_visualid_t visual_id);
107
108 /**
109 * Get visualid with specified depth
110 *
111 */
112 xcb_visualid_t get_visualid_by_depth(uint16_t depth);
113
114 /**
115 * Add an atom to a list of atoms the given property defines.
116 * This is useful, for example, for manipulating _NET_WM_STATE.
117 *
118 */
119 void xcb_add_property_atom(xcb_connection_t *conn, xcb_window_t window, xcb_atom_t property, xcb_atom_t atom);
120
121 /**
122 * Remove an atom from a list of atoms the given property defines without
123 * removing any other potentially set atoms. This is useful, for example, for
124 * manipulating _NET_WM_STATE.
125 *
126 */
127 void xcb_remove_property_atom(xcb_connection_t *conn, xcb_window_t window, xcb_atom_t property, xcb_atom_t atom);
128
129 /**
130 * Grab the specified buttons on a window when managing it.
131 *
132 */
133 void xcb_grab_buttons(xcb_connection_t *conn, xcb_window_t window, int *buttons);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * xcursor.c: libXcursor support for themed cursors.
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include <xcb/xcb_cursor.h>
14
15 enum xcursor_cursor_t {
16 XCURSOR_CURSOR_POINTER = 0,
17 XCURSOR_CURSOR_RESIZE_HORIZONTAL,
18 XCURSOR_CURSOR_RESIZE_VERTICAL,
19 XCURSOR_CURSOR_TOP_LEFT_CORNER,
20 XCURSOR_CURSOR_TOP_RIGHT_CORNER,
21 XCURSOR_CURSOR_BOTTOM_LEFT_CORNER,
22 XCURSOR_CURSOR_BOTTOM_RIGHT_CORNER,
23 XCURSOR_CURSOR_WATCH,
24 XCURSOR_CURSOR_MOVE,
25 XCURSOR_CURSOR_MAX
26 };
27
28 void xcursor_load_cursors(void);
29 xcb_cursor_t xcursor_get_cursor(enum xcursor_cursor_t c);
30
31 /**
32 * Sets the cursor of the root window to the 'pointer' cursor.
33 *
34 * This function is called when i3 is initialized, because with some login
35 * managers, the root window will not have a cursor otherwise.
36 *
37 * We have a separate xcursor function to use the same X11 connection as the
38 * xcursor_load_cursors() function. If we mix the Xlib and the XCB connection,
39 * races might occur (even though we flush the Xlib connection).
40 *
41 */
42 void xcursor_set_root_cursor(int cursor_id);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * This is LEGACY code (we support RandR, which can do much more than
7 * Xinerama), but necessary for the poor users of the nVidia binary
8 * driver which does not support RandR in 2011 *sigh*.
9 *
10 */
11 #pragma once
12
13 #include <config.h>
14
15 #include "data.h"
16
17 /**
18 * We have just established a connection to the X server and need the initial
19 * Xinerama information to setup workspaces for each screen.
20 *
21 */
22 void xinerama_init(void);
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * yajl_utils.h
7 *
8 */
9 #pragma once
10
11 #include <config.h>
12
13 #include <yajl/yajl_gen.h>
14 #include <yajl/yajl_parse.h>
15 #include <yajl/yajl_version.h>
16
17 /* Shorter names for all those yajl_gen_* functions */
18 #define y(x, ...) yajl_gen_##x(gen, ##__VA_ARGS__)
19 #define ystr(str) yajl_gen_string(gen, (unsigned char *)str, strlen(str))
20
21 #define ygenalloc() yajl_gen_alloc(NULL)
22 #define yalloc(callbacks, client) yajl_alloc(callbacks, NULL, client)
23 typedef size_t ylength;
0 Introduction
1 ============
2
3 libi3 is an *INTERNAL* library which contains functions that i3 and related
4 tools (i3-msg, i3-input, i3-nagbar, i3-config-wizard, i3bar) use.
5
6 It is NOT to be used by other programs.
7
8 Structure
9 =========
10
11 Every function gets its own .c file, which in turn gets compiled into an .o
12 object file. Afterwards, all .o files are archived into one static library
13 (libi3.a). This library will be linked into all i3 binaries. The linker is able
14 to eliminate unused .o files when linking, so only the functions which you
15 actually use will be included in the corresponding binary.
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <math.h>
10 #include <stdlib.h>
11 #include <xcb/xcb_xrm.h>
12
13 static long dpi;
14
15 static long init_dpi_fallback(void) {
16 return (double)root_screen->height_in_pixels * 25.4 / (double)root_screen->height_in_millimeters;
17 }
18
19 /*
20 * Initialize the DPI setting.
21 * This will use the 'Xft.dpi' X resource if available and fall back to
22 * guessing the correct value otherwise.
23 */
24 void init_dpi(void) {
25 xcb_xrm_database_t *database = NULL;
26 char *resource = NULL;
27
28 if (conn == NULL) {
29 goto init_dpi_end;
30 }
31
32 database = xcb_xrm_database_from_default(conn);
33 if (database == NULL) {
34 ELOG("Failed to open the resource database.\n");
35 goto init_dpi_end;
36 }
37
38 xcb_xrm_resource_get_string(database, "Xft.dpi", NULL, &resource);
39 if (resource == NULL) {
40 DLOG("Resource Xft.dpi not specified, skipping.\n");
41 goto init_dpi_end;
42 }
43
44 char *endptr;
45 double in_dpi = strtod(resource, &endptr);
46 if (in_dpi == HUGE_VAL || dpi < 0 || *endptr != '\0' || endptr == resource) {
47 ELOG("Xft.dpi = %s is an invalid number and couldn't be parsed.\n", resource);
48 dpi = 0;
49 goto init_dpi_end;
50 }
51 dpi = lround(in_dpi);
52
53 DLOG("Found Xft.dpi = %ld.\n", dpi);
54
55 init_dpi_end:
56 free(resource);
57
58 if (database != NULL) {
59 xcb_xrm_database_free(database);
60 }
61
62 if (dpi == 0) {
63 DLOG("Using fallback for calculating DPI.\n");
64 dpi = init_dpi_fallback();
65 DLOG("Using dpi = %ld\n", dpi);
66 }
67 }
68
69 /*
70 * This function returns the value of the DPI setting.
71 *
72 */
73 long get_dpi_value(void) {
74 return dpi;
75 }
76
77 /*
78 * Convert a logical amount of pixels (e.g. 2 pixels on a “standard” 96 DPI
79 * screen) to a corresponding amount of physical pixels on a standard or retina
80 * screen, e.g. 5 pixels on a 227 DPI MacBook Pro 13" Retina screen.
81 *
82 */
83 int logical_px(const int logical) {
84 if (root_screen == NULL) {
85 /* Dpi info may not be available when parsing a config without an X
86 * server, such as for config file validation. */
87 return logical;
88 }
89
90 /* There are many misconfigurations out there, i.e. systems with screens
91 * whose dpi is in fact higher than 96 dpi, but not significantly higher,
92 * so software was never adapted. We could tell people to reconfigure their
93 * systems to 96 dpi in order to get the behavior they expect/are used to,
94 * but since we can easily detect this case in code, let’s do it for them.
95 */
96 if ((dpi / 96.0) < 1.25)
97 return logical;
98 return ceil((dpi / 96.0) * logical);
99 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * © 2015 Ingo Bürk and contributors (see also: LICENSE)
4 *
5 * draw.c: Utility for drawing.
6 *
7 */
8 #include "libi3.h"
9
10 #include <stdlib.h>
11 #include <err.h>
12 #include <string.h>
13 #include <xcb/xcb.h>
14 #include <xcb/xcb_aux.h>
15 #include <cairo/cairo-xcb.h>
16
17 /* The default visual_type to use if none is specified when creating the surface. Must be defined globally. */
18 extern xcb_visualtype_t *visual_type;
19
20 /* Forward declarations */
21 static void draw_util_set_source_color(surface_t *surface, color_t color);
22
23 #define RETURN_UNLESS_SURFACE_INITIALIZED(surface) \
24 do { \
25 if ((surface)->id == XCB_NONE) { \
26 ELOG("Surface %p is not initialized, skipping drawing.\n", surface); \
27 return; \
28 } \
29 } while (0)
30
31 /*
32 * Initialize the surface to represent the given drawable.
33 *
34 */
35 void draw_util_surface_init(xcb_connection_t *conn, surface_t *surface, xcb_drawable_t drawable,
36 xcb_visualtype_t *visual, int width, int height) {
37 surface->id = drawable;
38 surface->visual_type = ((visual == NULL) ? visual_type : visual);
39 surface->width = width;
40 surface->height = height;
41
42 surface->gc = xcb_generate_id(conn);
43 xcb_void_cookie_t gc_cookie = xcb_create_gc_checked(conn, surface->gc, surface->id, 0, NULL);
44
45 xcb_generic_error_t *error = xcb_request_check(conn, gc_cookie);
46 if (error != NULL) {
47 ELOG("Could not create graphical context. Error code: %d. Please report this bug.\n", error->error_code);
48 }
49
50 surface->surface = cairo_xcb_surface_create(conn, surface->id, surface->visual_type, width, height);
51 surface->cr = cairo_create(surface->surface);
52 }
53
54 /*
55 * Destroys the surface.
56 *
57 */
58 void draw_util_surface_free(xcb_connection_t *conn, surface_t *surface) {
59 xcb_free_gc(conn, surface->gc);
60 cairo_surface_destroy(surface->surface);
61 cairo_destroy(surface->cr);
62
63 /* We need to explicitly set these to NULL to avoid assertion errors in
64 * cairo when calling this multiple times. This can happen, for example,
65 * when setting the border of a window to none and then closing it. */
66 surface->surface = NULL;
67 surface->cr = NULL;
68 }
69
70 /*
71 * Resize the surface to the given size.
72 *
73 */
74 void draw_util_surface_set_size(surface_t *surface, int width, int height) {
75 surface->width = width;
76 surface->height = height;
77 cairo_xcb_surface_set_size(surface->surface, width, height);
78 }
79
80 /*
81 * Parses the given color in hex format to an internal color representation.
82 * Note that the input must begin with a hash sign, e.g., "#3fbc59".
83 *
84 */
85 color_t draw_util_hex_to_color(const char *color) {
86 if (strlen(color) < 6 || color[0] != '#') {
87 ELOG("Could not parse color: %s\n", color);
88 return draw_util_hex_to_color("#A9A9A9");
89 }
90
91 char alpha[2];
92 if (strlen(color) == strlen("#rrggbbaa")) {
93 alpha[0] = color[7];
94 alpha[1] = color[8];
95 } else {
96 alpha[0] = alpha[1] = 'F';
97 }
98
99 char groups[4][3] = {
100 {color[1], color[2], '\0'},
101 {color[3], color[4], '\0'},
102 {color[5], color[6], '\0'},
103 {alpha[0], alpha[1], '\0'}};
104
105 return (color_t){
106 .red = strtol(groups[0], NULL, 16) / 255.0,
107 .green = strtol(groups[1], NULL, 16) / 255.0,
108 .blue = strtol(groups[2], NULL, 16) / 255.0,
109 .alpha = strtol(groups[3], NULL, 16) / 255.0,
110 .colorpixel = get_colorpixel(color)};
111 }
112
113 /*
114 * Set the given color as the source color on the surface.
115 *
116 */
117 static void draw_util_set_source_color(surface_t *surface, color_t color) {
118 RETURN_UNLESS_SURFACE_INITIALIZED(surface);
119
120 cairo_set_source_rgba(surface->cr, color.red, color.green, color.blue, color.alpha);
121 }
122
123 /*
124 * Draw the given text using libi3.
125 * This function also marks the surface dirty which is needed if other means of
126 * drawing are used. This will be the case when using XCB to draw text.
127 *
128 */
129 void draw_util_text(i3String *text, surface_t *surface, color_t fg_color, color_t bg_color, int x, int y, int max_width) {
130 RETURN_UNLESS_SURFACE_INITIALIZED(surface);
131
132 /* Flush any changes before we draw the text as this might use XCB directly. */
133 CAIRO_SURFACE_FLUSH(surface->surface);
134
135 set_font_colors(surface->gc, fg_color, bg_color);
136 draw_text(text, surface->id, surface->gc, surface->visual_type, x, y, max_width);
137
138 /* Notify cairo that we (possibly) used another way to draw on the surface. */
139 cairo_surface_mark_dirty(surface->surface);
140 }
141
142 /*
143 * Draws a filled rectangle.
144 * This function is a convenience wrapper and takes care of flushing the
145 * surface as well as restoring the cairo state.
146 *
147 */
148 void draw_util_rectangle(surface_t *surface, color_t color, double x, double y, double w, double h) {
149 RETURN_UNLESS_SURFACE_INITIALIZED(surface);
150
151 cairo_save(surface->cr);
152
153 /* Using the SOURCE operator will copy both color and alpha information directly
154 * onto the surface rather than blending it. This is a bit more efficient and
155 * allows better color control for the user when using opacity. */
156 cairo_set_operator(surface->cr, CAIRO_OPERATOR_SOURCE);
157 draw_util_set_source_color(surface, color);
158
159 cairo_rectangle(surface->cr, x, y, w, h);
160 cairo_fill(surface->cr);
161
162 /* Make sure we flush the surface for any text drawing operations that could follow.
163 * Since we support drawing text via XCB, we need this. */
164 CAIRO_SURFACE_FLUSH(surface->surface);
165
166 cairo_restore(surface->cr);
167 }
168
169 /*
170 * Clears a surface with the given color.
171 *
172 */
173 void draw_util_clear_surface(surface_t *surface, color_t color) {
174 RETURN_UNLESS_SURFACE_INITIALIZED(surface);
175
176 cairo_save(surface->cr);
177
178 /* Using the SOURCE operator will copy both color and alpha information directly
179 * onto the surface rather than blending it. This is a bit more efficient and
180 * allows better color control for the user when using opacity. */
181 cairo_set_operator(surface->cr, CAIRO_OPERATOR_SOURCE);
182 draw_util_set_source_color(surface, color);
183
184 cairo_paint(surface->cr);
185
186 /* Make sure we flush the surface for any text drawing operations that could follow.
187 * Since we support drawing text via XCB, we need this. */
188 CAIRO_SURFACE_FLUSH(surface->surface);
189
190 cairo_restore(surface->cr);
191 }
192
193 /*
194 * Copies a surface onto another surface.
195 *
196 */
197 void draw_util_copy_surface(surface_t *src, surface_t *dest, double src_x, double src_y,
198 double dest_x, double dest_y, double width, double height) {
199 RETURN_UNLESS_SURFACE_INITIALIZED(src);
200 RETURN_UNLESS_SURFACE_INITIALIZED(dest);
201
202 cairo_save(dest->cr);
203
204 /* Using the SOURCE operator will copy both color and alpha information directly
205 * onto the surface rather than blending it. This is a bit more efficient and
206 * allows better color control for the user when using opacity. */
207 cairo_set_operator(dest->cr, CAIRO_OPERATOR_SOURCE);
208 cairo_set_source_surface(dest->cr, src->surface, dest_x - src_x, dest_y - src_y);
209
210 cairo_rectangle(dest->cr, dest_x, dest_y, width, height);
211 cairo_fill(dest->cr);
212
213 /* Make sure we flush the surface for any text drawing operations that could follow.
214 * Since we support drawing text via XCB, we need this. */
215 CAIRO_SURFACE_FLUSH(src->surface);
216 CAIRO_SURFACE_FLUSH(dest->surface);
217
218 cairo_restore(dest->cr);
219 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <stdlib.h>
10 #include <stdbool.h>
11
12 #include <xcb/xcb.h>
13 #include <xcb/xproto.h>
14
15 /*
16 * Generates a configure_notify event and sends it to the given window
17 * Applications need this to think they’ve configured themselves correctly.
18 * The truth is, however, that we will manage them.
19 *
20 */
21 void fake_configure_notify(xcb_connection_t *conn, xcb_rectangle_t r, xcb_window_t window, int border_width) {
22 /* Every X11 event is 32 bytes long. Therefore, XCB will copy 32 bytes.
23 * In order to properly initialize these bytes, we allocate 32 bytes even
24 * though we only need less for an xcb_configure_notify_event_t */
25 void *event = scalloc(32, 1);
26 xcb_configure_notify_event_t *generated_event = event;
27
28 generated_event->event = window;
29 generated_event->window = window;
30 generated_event->response_type = XCB_CONFIGURE_NOTIFY;
31
32 generated_event->x = r.x;
33 generated_event->y = r.y;
34 generated_event->width = r.width;
35 generated_event->height = r.height;
36
37 generated_event->border_width = border_width;
38 generated_event->above_sibling = XCB_NONE;
39 generated_event->override_redirect = false;
40
41 xcb_send_event(conn, false, window, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (char *)generated_event);
42 xcb_flush(conn);
43
44 free(event);
45 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <assert.h>
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <stdbool.h>
14 #include <err.h>
15
16 #include <cairo/cairo-xcb.h>
17 #include <pango/pangocairo.h>
18
19 static const i3Font *savedFont = NULL;
20
21 static xcb_visualtype_t *root_visual_type;
22 static double pango_font_red;
23 static double pango_font_green;
24 static double pango_font_blue;
25 static double pango_font_alpha;
26
27 static PangoLayout *create_layout_with_dpi(cairo_t *cr) {
28 PangoLayout *layout;
29 PangoContext *context;
30
31 context = pango_cairo_create_context(cr);
32 pango_cairo_context_set_resolution(context, get_dpi_value());
33 layout = pango_layout_new(context);
34 g_object_unref(context);
35
36 return layout;
37 }
38
39 /*
40 * Loads a Pango font description into an i3Font structure. Returns true
41 * on success, false otherwise.
42 *
43 */
44 static bool load_pango_font(i3Font *font, const char *desc) {
45 /* Load the font description */
46 font->specific.pango_desc = pango_font_description_from_string(desc);
47 if (!font->specific.pango_desc) {
48 ELOG("Could not open font %s with Pango, fallback to X font.\n", desc);
49 return false;
50 }
51
52 LOG("Using Pango font %s, size %d\n",
53 pango_font_description_get_family(font->specific.pango_desc),
54 pango_font_description_get_size(font->specific.pango_desc) / PANGO_SCALE);
55
56 /* We cache root_visual_type here, since you must call
57 * load_pango_font before any other pango function
58 * that would need root_visual_type */
59 root_visual_type = get_visualtype(root_screen);
60
61 /* Create a dummy Pango layout to compute the font height */
62 cairo_surface_t *surface = cairo_xcb_surface_create(conn, root_screen->root, root_visual_type, 1, 1);
63 cairo_t *cr = cairo_create(surface);
64 PangoLayout *layout = create_layout_with_dpi(cr);
65 pango_layout_set_font_description(layout, font->specific.pango_desc);
66
67 /* Get the font height */
68 gint height;
69 pango_layout_get_pixel_size(layout, NULL, &height);
70 font->height = height;
71
72 /* Free resources */
73 g_object_unref(layout);
74 cairo_destroy(cr);
75 cairo_surface_destroy(surface);
76
77 /* Set the font type and return successfully */
78 font->type = FONT_TYPE_PANGO;
79 return true;
80 }
81
82 /*
83 * Draws text using Pango rendering.
84 *
85 */
86 static void draw_text_pango(const char *text, size_t text_len,
87 xcb_drawable_t drawable, xcb_visualtype_t *visual, int x, int y,
88 int max_width, bool pango_markup) {
89 /* Create the Pango layout */
90 /* root_visual_type is cached in load_pango_font */
91 cairo_surface_t *surface = cairo_xcb_surface_create(conn, drawable,
92 visual, x + max_width, y + savedFont->height);
93 cairo_t *cr = cairo_create(surface);
94 PangoLayout *layout = create_layout_with_dpi(cr);
95 gint height;
96
97 pango_layout_set_font_description(layout, savedFont->specific.pango_desc);
98 pango_layout_set_width(layout, max_width * PANGO_SCALE);
99 pango_layout_set_wrap(layout, PANGO_WRAP_CHAR);
100 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
101
102 if (pango_markup)
103 pango_layout_set_markup(layout, text, text_len);
104 else
105 pango_layout_set_text(layout, text, text_len);
106
107 /* Do the drawing */
108 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
109 cairo_set_source_rgba(cr, pango_font_red, pango_font_green, pango_font_blue, pango_font_alpha);
110 pango_cairo_update_layout(cr, layout);
111 pango_layout_get_pixel_size(layout, NULL, &height);
112 /* Center the piece of text vertically. */
113 int yoffset = (height - savedFont->height) / 2;
114 cairo_move_to(cr, x, y - yoffset);
115 pango_cairo_show_layout(cr, layout);
116
117 /* Free resources */
118 g_object_unref(layout);
119 cairo_destroy(cr);
120 cairo_surface_destroy(surface);
121 }
122
123 /*
124 * Calculate the text width using Pango rendering.
125 *
126 */
127 static int predict_text_width_pango(const char *text, size_t text_len, bool pango_markup) {
128 /* Create a dummy Pango layout */
129 /* root_visual_type is cached in load_pango_font */
130 cairo_surface_t *surface = cairo_xcb_surface_create(conn, root_screen->root, root_visual_type, 1, 1);
131 cairo_t *cr = cairo_create(surface);
132 PangoLayout *layout = create_layout_with_dpi(cr);
133
134 /* Get the font width */
135 gint width;
136 pango_layout_set_font_description(layout, savedFont->specific.pango_desc);
137
138 if (pango_markup)
139 pango_layout_set_markup(layout, text, text_len);
140 else
141 pango_layout_set_text(layout, text, text_len);
142
143 pango_cairo_update_layout(cr, layout);
144 pango_layout_get_pixel_size(layout, &width, NULL);
145
146 /* Free resources */
147 g_object_unref(layout);
148 cairo_destroy(cr);
149 cairo_surface_destroy(surface);
150
151 return width;
152 }
153
154 /*
155 * Loads a font for usage, also getting its metrics. If fallback is true,
156 * the fonts 'fixed' or '-misc-*' will be loaded instead of exiting. If any
157 * font was previously loaded, it will be freed.
158 *
159 */
160 i3Font load_font(const char *pattern, const bool fallback) {
161 /* if any font was previously loaded, free it now */
162 free_font();
163
164 i3Font font;
165 font.type = FONT_TYPE_NONE;
166 font.pattern = NULL;
167
168 /* No XCB connction, return early because we're just validating the
169 * configuration file. */
170 if (conn == NULL) {
171 return font;
172 }
173
174 /* Try to load a pango font if specified */
175 if (strlen(pattern) > strlen("pango:") && !strncmp(pattern, "pango:", strlen("pango:"))) {
176 const char *font_pattern = pattern + strlen("pango:");
177 if (load_pango_font(&font, font_pattern)) {
178 font.pattern = sstrdup(pattern);
179 return font;
180 }
181 } else if (strlen(pattern) > strlen("xft:") && !strncmp(pattern, "xft:", strlen("xft:"))) {
182 const char *font_pattern = pattern + strlen("xft:");
183 if (load_pango_font(&font, font_pattern)) {
184 font.pattern = sstrdup(pattern);
185 return font;
186 }
187 }
188
189 /* Send all our requests first */
190 font.specific.xcb.id = xcb_generate_id(conn);
191 xcb_void_cookie_t font_cookie = xcb_open_font_checked(conn, font.specific.xcb.id,
192 strlen(pattern), pattern);
193 xcb_query_font_cookie_t info_cookie = xcb_query_font(conn, font.specific.xcb.id);
194
195 /* Check for errors. If errors, fall back to default font. */
196 xcb_generic_error_t *error;
197 error = xcb_request_check(conn, font_cookie);
198
199 /* If we fail to open font, fall back to 'fixed' */
200 if (fallback && error != NULL) {
201 ELOG("Could not open font %s (X error %d). Trying fallback to 'fixed'.\n",
202 pattern, error->error_code);
203 pattern = "fixed";
204 font_cookie = xcb_open_font_checked(conn, font.specific.xcb.id,
205 strlen(pattern), pattern);
206 info_cookie = xcb_query_font(conn, font.specific.xcb.id);
207
208 /* Check if we managed to open 'fixed' */
209 free(error);
210 error = xcb_request_check(conn, font_cookie);
211
212 /* Fall back to '-misc-*' if opening 'fixed' fails. */
213 if (error != NULL) {
214 ELOG("Could not open fallback font 'fixed', trying with '-misc-*'.\n");
215 pattern = "-misc-*";
216 font_cookie = xcb_open_font_checked(conn, font.specific.xcb.id,
217 strlen(pattern), pattern);
218 info_cookie = xcb_query_font(conn, font.specific.xcb.id);
219
220 free(error);
221 if ((error = xcb_request_check(conn, font_cookie)) != NULL)
222 errx(EXIT_FAILURE, "Could open neither requested font nor fallbacks "
223 "(fixed or -misc-*): X11 error %d",
224 error->error_code);
225 }
226 }
227 free(error);
228
229 font.pattern = sstrdup(pattern);
230 LOG("Using X font %s\n", pattern);
231
232 /* Get information (height/name) for this font */
233 if (!(font.specific.xcb.info = xcb_query_font_reply(conn, info_cookie, NULL)))
234 errx(EXIT_FAILURE, "Could not load font \"%s\"", pattern);
235
236 /* Get the font table, if possible */
237 if (xcb_query_font_char_infos_length(font.specific.xcb.info) == 0)
238 font.specific.xcb.table = NULL;
239 else
240 font.specific.xcb.table = xcb_query_font_char_infos(font.specific.xcb.info);
241
242 /* Calculate the font height */
243 font.height = font.specific.xcb.info->font_ascent + font.specific.xcb.info->font_descent;
244
245 /* Set the font type and return successfully */
246 font.type = FONT_TYPE_XCB;
247 return font;
248 }
249
250 /*
251 * Defines the font to be used for the forthcoming calls.
252 *
253 */
254 void set_font(i3Font *font) {
255 savedFont = font;
256 }
257
258 /*
259 * Frees the resources taken by the current font. If no font was previously
260 * loaded, it simply returns.
261 *
262 */
263 void free_font(void) {
264 /* if there is no saved font, simply return */
265 if (savedFont == NULL)
266 return;
267
268 free(savedFont->pattern);
269 switch (savedFont->type) {
270 case FONT_TYPE_NONE:
271 /* Nothing to do */
272 break;
273 case FONT_TYPE_XCB: {
274 /* Close the font and free the info */
275 xcb_close_font(conn, savedFont->specific.xcb.id);
276 free(savedFont->specific.xcb.info);
277 break;
278 }
279 case FONT_TYPE_PANGO:
280 /* Free the font description */
281 pango_font_description_free(savedFont->specific.pango_desc);
282 break;
283 }
284
285 savedFont = NULL;
286 }
287
288 /*
289 * Defines the colors to be used for the forthcoming draw_text calls.
290 *
291 */
292 void set_font_colors(xcb_gcontext_t gc, color_t foreground, color_t background) {
293 assert(savedFont != NULL);
294
295 switch (savedFont->type) {
296 case FONT_TYPE_NONE:
297 /* Nothing to do */
298 break;
299 case FONT_TYPE_XCB: {
300 /* Change the font and colors in the GC */
301 uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
302 uint32_t values[] = {foreground.colorpixel, background.colorpixel, savedFont->specific.xcb.id};
303 xcb_change_gc(conn, gc, mask, values);
304 break;
305 }
306 case FONT_TYPE_PANGO:
307 /* Save the foreground font */
308 pango_font_red = foreground.red;
309 pango_font_green = foreground.green;
310 pango_font_blue = foreground.blue;
311 pango_font_alpha = foreground.alpha;
312 break;
313 }
314 }
315
316 /*
317 * Returns true if and only if the current font is a pango font.
318 *
319 */
320 bool font_is_pango(void) {
321 return savedFont->type == FONT_TYPE_PANGO;
322 }
323
324 static int predict_text_width_xcb(const xcb_char2b_t *text, size_t text_len);
325
326 static void draw_text_xcb(const xcb_char2b_t *text, size_t text_len, xcb_drawable_t drawable,
327 xcb_gcontext_t gc, int x, int y) {
328 /* X11 coordinates for fonts start at the baseline */
329 int pos_y = y + savedFont->specific.xcb.info->font_ascent;
330
331 /* The X11 protocol limits text drawing to 255 chars, so we may need
332 * multiple calls */
333 int offset = 0;
334 for (;;) {
335 /* Calculate the size of this chunk */
336 int chunk_size = (text_len > 255 ? 255 : text_len);
337 const xcb_char2b_t *chunk = text + offset;
338
339 /* Draw it */
340 xcb_image_text_16(conn, chunk_size, drawable, gc, x, pos_y, chunk);
341
342 /* Advance the offset and length of the text to draw */
343 offset += chunk_size;
344 text_len -= chunk_size;
345
346 /* Check if we're done */
347 if (text_len == 0)
348 break;
349
350 /* Advance pos_x based on the predicted text width */
351 x += predict_text_width_xcb(chunk, chunk_size);
352 }
353 }
354
355 /*
356 * Draws text onto the specified X drawable (normally a pixmap) at the
357 * specified coordinates (from the top left corner of the leftmost, uppermost
358 * glyph) and using the provided gc.
359 *
360 * Text must be specified as an i3String.
361 *
362 */
363 void draw_text(i3String *text, xcb_drawable_t drawable, xcb_gcontext_t gc,
364 xcb_visualtype_t *visual, int x, int y, int max_width) {
365 assert(savedFont != NULL);
366 if (visual == NULL) {
367 visual = root_visual_type;
368 }
369
370 switch (savedFont->type) {
371 case FONT_TYPE_NONE:
372 /* Nothing to do */
373 return;
374 case FONT_TYPE_XCB:
375 draw_text_xcb(i3string_as_ucs2(text), i3string_get_num_glyphs(text),
376 drawable, gc, x, y);
377 break;
378 case FONT_TYPE_PANGO:
379 /* Render the text using Pango */
380 draw_text_pango(i3string_as_utf8(text), i3string_get_num_bytes(text),
381 drawable, visual, x, y, max_width, i3string_is_markup(text));
382 return;
383 }
384 }
385
386 /*
387 * ASCII version of draw_text to print static strings.
388 *
389 */
390 void draw_text_ascii(const char *text, xcb_drawable_t drawable,
391 xcb_gcontext_t gc, int x, int y, int max_width) {
392 assert(savedFont != NULL);
393
394 switch (savedFont->type) {
395 case FONT_TYPE_NONE:
396 /* Nothing to do */
397 return;
398 case FONT_TYPE_XCB: {
399 size_t text_len = strlen(text);
400 if (text_len > 255) {
401 /* The text is too long to draw it directly to X */
402 i3String *str = i3string_from_utf8(text);
403 draw_text(str, drawable, gc, NULL, x, y, max_width);
404 i3string_free(str);
405 } else {
406 /* X11 coordinates for fonts start at the baseline */
407 int pos_y = y + savedFont->specific.xcb.info->font_ascent;
408
409 xcb_image_text_8(conn, text_len, drawable, gc, x, pos_y, text);
410 }
411 break;
412 }
413 case FONT_TYPE_PANGO:
414 /* Render the text using Pango */
415 draw_text_pango(text, strlen(text),
416 drawable, root_visual_type, x, y, max_width, false);
417 return;
418 }
419 }
420
421 static int xcb_query_text_width(const xcb_char2b_t *text, size_t text_len) {
422 /* Make the user know we’re using the slow path, but only once. */
423 static bool first_invocation = true;
424 if (first_invocation) {
425 fprintf(stderr, "Using slow code path for text extents\n");
426 first_invocation = false;
427 }
428
429 /* Query the text width */
430 xcb_generic_error_t *error;
431 xcb_query_text_extents_cookie_t cookie = xcb_query_text_extents(conn,
432 savedFont->specific.xcb.id, text_len, (xcb_char2b_t *)text);
433 xcb_query_text_extents_reply_t *reply = xcb_query_text_extents_reply(conn,
434 cookie, &error);
435 if (reply == NULL) {
436 /* We return a safe estimate because a rendering error is better than
437 * a crash. Plus, the user will see the error in their log. */
438 fprintf(stderr, "Could not get text extents (X error code %d)\n",
439 error->error_code);
440 free(error);
441 return savedFont->specific.xcb.info->max_bounds.character_width * text_len;
442 }
443
444 int width = reply->overall_width;
445 free(reply);
446 return width;
447 }
448
449 static int predict_text_width_xcb(const xcb_char2b_t *input, size_t text_len) {
450 if (text_len == 0)
451 return 0;
452
453 int width;
454 if (savedFont->specific.xcb.table == NULL) {
455 /* If we don't have a font table, fall back to querying the server */
456 width = xcb_query_text_width(input, text_len);
457 } else {
458 /* Save some pointers for convenience */
459 xcb_query_font_reply_t *font_info = savedFont->specific.xcb.info;
460 xcb_charinfo_t *font_table = savedFont->specific.xcb.table;
461
462 /* Calculate the width using the font table */
463 width = 0;
464 for (size_t i = 0; i < text_len; i++) {
465 xcb_charinfo_t *info;
466 int row = input[i].byte1;
467 int col = input[i].byte2;
468
469 if (row < font_info->min_byte1 ||
470 row > font_info->max_byte1 ||
471 col < font_info->min_char_or_byte2 ||
472 col > font_info->max_char_or_byte2)
473 continue;
474
475 /* Don't you ask me, how this one works… (Merovius) */
476 info = &font_table[((row - font_info->min_byte1) *
477 (font_info->max_char_or_byte2 - font_info->min_char_or_byte2 + 1)) +
478 (col - font_info->min_char_or_byte2)];
479
480 if (info->character_width != 0 ||
481 (info->right_side_bearing |
482 info->left_side_bearing |
483 info->ascent |
484 info->descent) != 0) {
485 width += info->character_width;
486 }
487 }
488 }
489
490 return width;
491 }
492
493 /*
494 * Predict the text width in pixels for the given text. Text must be
495 * specified as an i3String.
496 *
497 */
498 int predict_text_width(i3String *text) {
499 assert(savedFont != NULL);
500
501 switch (savedFont->type) {
502 case FONT_TYPE_NONE:
503 /* Nothing to do */
504 return 0;
505 case FONT_TYPE_XCB:
506 return predict_text_width_xcb(i3string_as_ucs2(text), i3string_get_num_glyphs(text));
507 case FONT_TYPE_PANGO:
508 /* Calculate extents using Pango */
509 return predict_text_width_pango(i3string_as_utf8(text), i3string_get_num_bytes(text),
510 i3string_is_markup(text));
511 }
512 assert(false);
513 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <stdlib.h>
10 #include <stdint.h>
11 #include <string.h>
12
13 #ifndef CS_STARTS_WITH
14 #define CS_STARTS_WITH(string, needle) (strncmp((string), (needle), strlen((needle))) == 0)
15 #endif
16
17 /*
18 * Replaces occurrences of the defined placeholders in the format string.
19 *
20 */
21 char *format_placeholders(char *format, placeholder_t *placeholders, int num) {
22 if (format == NULL)
23 return NULL;
24
25 /* We have to first iterate over the string to see how much buffer space
26 * we need to allocate. */
27 int buffer_len = strlen(format) + 1;
28 for (char *walk = format; *walk != '\0'; walk++) {
29 for (int i = 0; i < num; i++) {
30 if (!CS_STARTS_WITH(walk, placeholders[i].name))
31 continue;
32
33 buffer_len = buffer_len - strlen(placeholders[i].name) + strlen(placeholders[i].value);
34 walk += strlen(placeholders[i].name) - 1;
35 break;
36 }
37 }
38
39 /* Now we can parse the format string. */
40 char buffer[buffer_len];
41 char *outwalk = buffer;
42 for (char *walk = format; *walk != '\0'; walk++) {
43 if (*walk != '%') {
44 *(outwalk++) = *walk;
45 continue;
46 }
47
48 bool matched = false;
49 for (int i = 0; i < num; i++) {
50 if (!CS_STARTS_WITH(walk, placeholders[i].name)) {
51 continue;
52 }
53
54 matched = true;
55 outwalk += sprintf(outwalk, "%s", placeholders[i].value);
56 walk += strlen(placeholders[i].name) - 1;
57 break;
58 }
59
60 if (!matched)
61 *(outwalk++) = *walk;
62 }
63
64 *outwalk = '\0';
65 return sstrdup(buffer);
66 }
0 /* g_utf8_make_valid.c - Coerce string into UTF-8
1 *
2 * Copyright (C) 1999 Tom Tromey
3 * Copyright (C) 2000 Red Hat, Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "libi3.h"
20
21 #include <string.h>
22 #include <glib.h>
23
24 /* Copied from:
25 * https://gitlab.gnome.org/GNOME/glib/blob/f928dfdf57bf92c883b53b16d7a9d49add504f52/glib/gutf8.c#L1752-1815 */
26 /* clang-format off */
27 #if !HAS_G_UTF8_MAKE_VALID
28 /**
29 * g_utf8_make_valid:
30 * @str: string to coerce into UTF-8
31 * @len: the maximum length of @str to use, in bytes. If @len < 0,
32 * then the string is nul-terminated.
33 *
34 * If the provided string is valid UTF-8, return a copy of it. If not,
35 * return a copy in which bytes that could not be interpreted as valid Unicode
36 * are replaced with the Unicode replacement character (U+FFFD).
37 *
38 * For example, this is an appropriate function to use if you have received
39 * a string that was incorrectly declared to be UTF-8, and you need a valid
40 * UTF-8 version of it that can be logged or displayed to the user, with the
41 * assumption that it is close enough to ASCII or UTF-8 to be mostly
42 * readable as-is.
43 *
44 * Returns: (transfer full): a valid UTF-8 string whose content resembles @str
45 *
46 * Since: 2.52
47 */
48 gchar *
49 g_utf8_make_valid (const gchar *str,
50 gssize len)
51 {
52 GString *string;
53 const gchar *remainder, *invalid;
54 gsize remaining_bytes, valid_bytes;
55
56 g_return_val_if_fail (str != NULL, NULL);
57
58 if (len < 0)
59 len = strlen (str);
60
61 string = NULL;
62 remainder = str;
63 remaining_bytes = len;
64
65 while (remaining_bytes != 0)
66 {
67 if (g_utf8_validate (remainder, remaining_bytes, &invalid))
68 break;
69 valid_bytes = invalid - remainder;
70
71 if (string == NULL)
72 string = g_string_sized_new (remaining_bytes);
73
74 g_string_append_len (string, remainder, valid_bytes);
75 /* append U+FFFD REPLACEMENT CHARACTER */
76 g_string_append (string, "\357\277\275");
77
78 remaining_bytes -= valid_bytes + 1;
79 remainder = invalid + 1;
80 }
81
82 if (string == NULL)
83 return g_strndup (str, len);
84
85 g_string_append_len (string, remainder, remaining_bytes);
86 g_string_append_c (string, '\0');
87
88 g_assert (g_utf8_validate (string->str, -1, NULL));
89
90 return g_string_free (string, FALSE);
91 }
92 #endif
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <stdlib.h>
10 #include <stdint.h>
11 #include <string.h>
12
13 #include "queue.h"
14 struct Colorpixel {
15 char hex[8];
16 uint32_t pixel;
17
18 SLIST_ENTRY(Colorpixel)
19 colorpixels;
20 };
21
22 SLIST_HEAD(colorpixel_head, Colorpixel)
23 colorpixels;
24
25 /*
26 * Returns the colorpixel to use for the given hex color (think of HTML).
27 *
28 * The hex_color has to start with #, for example #FF00FF.
29 *
30 * NOTE that get_colorpixel() does _NOT_ check the given color code for validity.
31 * This has to be done by the caller.
32 *
33 */
34 uint32_t get_colorpixel(const char *hex) {
35 char alpha[2];
36 if (strlen(hex) == strlen("#rrggbbaa")) {
37 alpha[0] = hex[7];
38 alpha[1] = hex[8];
39 } else {
40 alpha[0] = alpha[1] = 'F';
41 }
42
43 char strgroups[4][3] = {
44 {hex[1], hex[2], '\0'},
45 {hex[3], hex[4], '\0'},
46 {hex[5], hex[6], '\0'},
47 {alpha[0], alpha[1], '\0'}};
48 uint8_t r = strtol(strgroups[0], NULL, 16);
49 uint8_t g = strtol(strgroups[1], NULL, 16);
50 uint8_t b = strtol(strgroups[2], NULL, 16);
51 uint8_t a = strtol(strgroups[3], NULL, 16);
52
53 /* Shortcut: if our screen is true color, no need to do a roundtrip to X11 */
54 if (root_screen == NULL || root_screen->root_depth == 24 || root_screen->root_depth == 32) {
55 return (a << 24) | (r << 16 | g << 8 | b);
56 }
57
58 /* Lookup this colorpixel in the cache */
59 struct Colorpixel *colorpixel;
60 SLIST_FOREACH (colorpixel, &(colorpixels), colorpixels) {
61 if (strcmp(colorpixel->hex, hex) == 0)
62 return colorpixel->pixel;
63 }
64
65 #define RGB_8_TO_16(i) (65535 * ((i)&0xFF) / 255)
66 int r16 = RGB_8_TO_16(r);
67 int g16 = RGB_8_TO_16(g);
68 int b16 = RGB_8_TO_16(b);
69
70 xcb_alloc_color_reply_t *reply;
71
72 reply = xcb_alloc_color_reply(conn, xcb_alloc_color(conn, root_screen->default_colormap, r16, g16, b16),
73 NULL);
74
75 if (!reply) {
76 LOG("Could not allocate color\n");
77 exit(1);
78 }
79
80 uint32_t pixel = reply->pixel;
81 free(reply);
82
83 /* Store the result in the cache */
84 struct Colorpixel *cache_pixel = scalloc(1, sizeof(struct Colorpixel));
85
86 strncpy(cache_pixel->hex, hex, 7);
87 cache_pixel->hex[7] = '\0';
88
89 cache_pixel->pixel = pixel;
90
91 SLIST_INSERT_HEAD(&(colorpixels), cache_pixel, colorpixels);
92
93 return pixel;
94 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <stdlib.h>
10 #include <string.h>
11 #include <sys/stat.h>
12
13 /*
14 * Checks if the given path exists by calling stat().
15 *
16 */
17 static bool path_exists(const char *path) {
18 struct stat buf;
19 return (stat(path, &buf) == 0);
20 }
21
22 /*
23 * Get the path of the first configuration file found. If override_configpath is
24 * specified, that path is returned and saved for further calls. Otherwise,
25 * checks the home directory first, then the system directory, always taking
26 * into account the XDG Base Directory Specification ($XDG_CONFIG_HOME,
27 * $XDG_CONFIG_DIRS).
28 *
29 */
30 char *get_config_path(const char *override_configpath, bool use_system_paths) {
31 char *xdg_config_home, *xdg_config_dirs, *config_path;
32
33 static const char *saved_configpath = NULL;
34
35 if (override_configpath != NULL) {
36 saved_configpath = override_configpath;
37 return sstrdup(saved_configpath);
38 }
39
40 if (saved_configpath != NULL) {
41 return sstrdup(saved_configpath);
42 }
43
44 /* 1: check for $XDG_CONFIG_HOME/i3/config */
45 if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL) {
46 xdg_config_home = "~/.config";
47 }
48
49 xdg_config_home = resolve_tilde(xdg_config_home);
50 sasprintf(&config_path, "%s/i3/config", xdg_config_home);
51 free(xdg_config_home);
52
53 if (path_exists(config_path)) {
54 return config_path;
55 }
56 free(config_path);
57
58 /* 2: check the traditional path under the home directory */
59 config_path = resolve_tilde("~/.i3/config");
60 if (path_exists(config_path)) {
61 return config_path;
62 }
63 free(config_path);
64
65 /* The below paths are considered system-level, and can be skipped if the
66 * caller only wants user-level configs. */
67 if (!use_system_paths) {
68 return NULL;
69 }
70
71 /* 3: check for $XDG_CONFIG_DIRS/i3/config */
72 if ((xdg_config_dirs = getenv("XDG_CONFIG_DIRS")) == NULL) {
73 xdg_config_dirs = SYSCONFDIR "/xdg";
74 }
75
76 char *buf = sstrdup(xdg_config_dirs);
77 char *tok = strtok(buf, ":");
78 while (tok != NULL) {
79 tok = resolve_tilde(tok);
80 sasprintf(&config_path, "%s/i3/config", tok);
81 free(tok);
82 if (path_exists(config_path)) {
83 free(buf);
84 return config_path;
85 }
86 free(config_path);
87 tok = strtok(NULL, ":");
88 }
89 free(buf);
90
91 /* 4: check the traditional path under /etc */
92 config_path = SYSCONFDIR "/i3/config";
93 if (path_exists(config_path)) {
94 return sstrdup(config_path);
95 }
96
97 return NULL;
98 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <unistd.h>
10 #include <string.h>
11 #include <stdio.h>
12 #include <limits.h>
13 #include <stdlib.h>
14 #include <errno.h>
15
16 /*
17 * This function returns the absolute path to the executable it is running in.
18 *
19 * The implementation follows https://stackoverflow.com/a/933996/712014
20 *
21 * Returned value must be freed by the caller.
22 */
23 char *get_exe_path(const char *argv0) {
24 size_t destpath_size = 1024;
25 size_t tmp_size = 1024;
26 char *destpath = smalloc(destpath_size);
27 char *tmp = smalloc(tmp_size);
28
29 #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
30 /* Linux and Debian/kFreeBSD provide /proc/self/exe */
31 #if defined(__linux__) || defined(__FreeBSD_kernel__)
32 const char *exepath = "/proc/self/exe";
33 #elif defined(__FreeBSD__)
34 const char *exepath = "/proc/curproc/file";
35 #endif
36 ssize_t linksize;
37
38 while ((linksize = readlink(exepath, destpath, destpath_size)) == (ssize_t)destpath_size) {
39 destpath_size = destpath_size * 2;
40 destpath = srealloc(destpath, destpath_size);
41 }
42 if (linksize != -1) {
43 /* readlink() does not NULL-terminate strings, so we have to. */
44 destpath[linksize] = '\0';
45 free(tmp);
46 return destpath;
47 }
48 #endif
49
50 /* argv[0] is most likely a full path if it starts with a slash. */
51 if (argv0[0] == '/') {
52 free(tmp);
53 free(destpath);
54 return sstrdup(argv0);
55 }
56
57 /* if argv[0] contains a /, prepend the working directory */
58 if (strchr(argv0, '/') != NULL) {
59 char *retgcwd;
60 while ((retgcwd = getcwd(tmp, tmp_size)) == NULL && errno == ERANGE) {
61 tmp_size = tmp_size * 2;
62 tmp = srealloc(tmp, tmp_size);
63 }
64 if (retgcwd != NULL) {
65 free(destpath);
66 sasprintf(&destpath, "%s/%s", tmp, argv0);
67 free(tmp);
68 return destpath;
69 }
70 }
71
72 /* Fall back to searching $PATH (or _CS_PATH in absence of $PATH). */
73 char *path = getenv("PATH");
74 if (path == NULL) {
75 /* _CS_PATH is typically something like "/bin:/usr/bin" */
76 while (confstr(_CS_PATH, tmp, tmp_size) > tmp_size) {
77 tmp_size = tmp_size * 2;
78 tmp = srealloc(tmp, tmp_size);
79 }
80 sasprintf(&path, ":%s", tmp);
81 } else {
82 path = sstrdup(path);
83 }
84 const char *component;
85 char *str = path;
86 while (1) {
87 if ((component = strtok(str, ":")) == NULL)
88 break;
89 str = NULL;
90 free(destpath);
91 sasprintf(&destpath, "%s/%s", component, argv0);
92 /* Of course this is not 100% equivalent to actually exec()ing the
93 * binary, but meh. */
94 if (access(destpath, X_OK) == 0) {
95 free(path);
96 free(tmp);
97 return destpath;
98 }
99 }
100 free(destpath);
101 free(path);
102 free(tmp);
103
104 /* Last resort: maybe it’s in /usr/bin? */
105 return sstrdup("/usr/bin/i3-nagbar");
106 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <stdint.h>
10 #include <stdlib.h>
11 #include <xcb/xcb.h>
12 #include <xcb/xcb_keysyms.h>
13
14 /*
15 * All-in-one function which returns the modifier mask (XCB_MOD_MASK_*) for the
16 * given keysymbol, for example for XCB_NUM_LOCK (usually configured to mod2).
17 *
18 * This function initiates one round-trip. Use get_mod_mask_for() directly if
19 * you already have the modifier mapping and key symbols.
20 *
21 */
22 uint32_t aio_get_mod_mask_for(uint32_t keysym, xcb_key_symbols_t *symbols) {
23 xcb_get_modifier_mapping_cookie_t cookie;
24 xcb_get_modifier_mapping_reply_t *modmap_r;
25
26 xcb_flush(conn);
27
28 /* Get the current modifier mapping (this is blocking!) */
29 cookie = xcb_get_modifier_mapping(conn);
30 if (!(modmap_r = xcb_get_modifier_mapping_reply(conn, cookie, NULL)))
31 return 0;
32
33 uint32_t result = get_mod_mask_for(keysym, symbols, modmap_r);
34 free(modmap_r);
35 return result;
36 }
37
38 /*
39 * Returns the modifier mask (XCB_MOD_MASK_*) for the given keysymbol, for
40 * example for XCB_NUM_LOCK (usually configured to mod2).
41 *
42 * This function does not initiate any round-trips.
43 *
44 */
45 uint32_t get_mod_mask_for(uint32_t keysym,
46 xcb_key_symbols_t *symbols,
47 xcb_get_modifier_mapping_reply_t *modmap_reply) {
48 xcb_keycode_t *codes, *modmap;
49 xcb_keycode_t mod_code;
50
51 modmap = xcb_get_modifier_mapping_keycodes(modmap_reply);
52
53 /* Get the list of keycodes for the given symbol */
54 if (!(codes = xcb_key_symbols_get_keycode(symbols, keysym)))
55 return 0;
56
57 /* Loop through all modifiers (Mod1-Mod5, Shift, Control, Lock) */
58 for (int mod = 0; mod < 8; mod++)
59 for (int j = 0; j < modmap_reply->keycodes_per_modifier; j++) {
60 /* Store the current keycode (for modifier 'mod') */
61 mod_code = modmap[(mod * modmap_reply->keycodes_per_modifier) + j];
62 /* Check if that keycode is in the list of previously resolved
63 * keycodes for our symbol. If so, return the modifier mask. */
64 for (xcb_keycode_t *code = codes; *code; code++) {
65 if (*code != mod_code)
66 continue;
67
68 free(codes);
69 /* This corresponds to the XCB_MOD_MASK_* constants */
70 return (1 << mod);
71 }
72 }
73
74 return 0;
75 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <assert.h>
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <stdbool.h>
14 #include <err.h>
15 #include <sys/stat.h>
16 #include <sys/types.h>
17 #include <pwd.h>
18 #include <unistd.h>
19 #include <err.h>
20
21 /*
22 * Returns the name of a temporary file with the specified prefix.
23 *
24 */
25 char *get_process_filename(const char *prefix) {
26 /* dir stores the directory path for this and all subsequent calls so that
27 * we only create a temporary directory once per i3 instance. */
28 static char *dir = NULL;
29 if (dir == NULL) {
30 /* Check if XDG_RUNTIME_DIR is set. If so, we use XDG_RUNTIME_DIR/i3 */
31 if ((dir = getenv("XDG_RUNTIME_DIR"))) {
32 char *tmp;
33 sasprintf(&tmp, "%s/i3", dir);
34 dir = tmp;
35 struct stat buf;
36 if (stat(dir, &buf) != 0) {
37 if (mkdir(dir, 0700) == -1) {
38 warn("Could not mkdir(%s)", dir);
39 errx(EXIT_FAILURE, "Check permissions of $XDG_RUNTIME_DIR = '%s'",
40 getenv("XDG_RUNTIME_DIR"));
41 perror("mkdir()");
42 return NULL;
43 }
44 }
45 } else {
46 /* If not, we create a (secure) temp directory using the template
47 * /tmp/i3-<user>.XXXXXX */
48 struct passwd *pw = getpwuid(getuid());
49 const char *username = pw ? pw->pw_name : "unknown";
50 sasprintf(&dir, "/tmp/i3-%s.XXXXXX", username);
51 /* mkdtemp modifies dir */
52 if (mkdtemp(dir) == NULL) {
53 perror("mkdtemp()");
54 return NULL;
55 }
56 }
57 }
58 char *filename;
59 sasprintf(&filename, "%s/%s.%d", dir, prefix, getpid());
60 return filename;
61 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 /*
10 * Returns the visual type associated with the given screen.
11 *
12 */
13 xcb_visualtype_t *get_visualtype(xcb_screen_t *screen) {
14 xcb_depth_iterator_t depth_iter;
15 for (depth_iter = xcb_screen_allowed_depths_iterator(screen);
16 depth_iter.rem;
17 xcb_depth_next(&depth_iter)) {
18 xcb_visualtype_iterator_t visual_iter;
19 for (visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
20 visual_iter.rem;
21 xcb_visualtype_next(&visual_iter)) {
22 if (screen->root_visual == visual_iter.data->visual_id)
23 return visual_iter.data;
24 }
25 }
26 return NULL;
27 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 #include <sys/un.h>
12 #include <string.h>
13 #include <err.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16 #include <fcntl.h>
17
18 /*
19 * Connects to the i3 IPC socket and returns the file descriptor for the
20 * socket. die()s if anything goes wrong.
21 *
22 */
23 int ipc_connect(const char *socket_path) {
24 char *path = NULL;
25 if (socket_path != NULL) {
26 path = sstrdup(socket_path);
27 }
28
29 if (path == NULL) {
30 if ((path = getenv("I3SOCK")) != NULL) {
31 path = sstrdup(path);
32 }
33 }
34
35 if (path == NULL) {
36 path = root_atom_contents("I3_SOCKET_PATH", NULL, 0);
37 }
38
39 if (path == NULL) {
40 path = sstrdup("/tmp/i3-ipc.sock");
41 }
42
43 int sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
44 if (sockfd == -1)
45 err(EXIT_FAILURE, "Could not create socket");
46
47 (void)fcntl(sockfd, F_SETFD, FD_CLOEXEC);
48
49 struct sockaddr_un addr;
50 memset(&addr, 0, sizeof(struct sockaddr_un));
51 addr.sun_family = AF_LOCAL;
52 strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);
53 if (connect(sockfd, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
54 err(EXIT_FAILURE, "Could not connect to i3 on socket %s", path);
55 free(path);
56 return sockfd;
57 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <string.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <stdint.h>
13 #include <unistd.h>
14 #include <errno.h>
15 #include <inttypes.h>
16
17 #include <i3/ipc.h>
18
19 /*
20 * Reads a message from the given socket file descriptor and stores its length
21 * (reply_length) as well as a pointer to its contents (reply).
22 *
23 * Returns -1 when read() fails, errno will remain.
24 * Returns -2 on EOF.
25 * Returns -3 when the IPC protocol is violated (invalid magic, unexpected
26 * message type, EOF instead of a message). Additionally, the error will be
27 * printed to stderr.
28 * Returns 0 on success.
29 *
30 */
31 int ipc_recv_message(int sockfd, uint32_t *message_type,
32 uint32_t *reply_length, uint8_t **reply) {
33 /* Read the message header first */
34 const uint32_t to_read = strlen(I3_IPC_MAGIC) + sizeof(uint32_t) + sizeof(uint32_t);
35 char msg[to_read];
36 char *walk = msg;
37
38 uint32_t read_bytes = 0;
39 while (read_bytes < to_read) {
40 int n = read(sockfd, msg + read_bytes, to_read - read_bytes);
41 if (n == -1)
42 return -1;
43 if (n == 0) {
44 if (read_bytes == 0) {
45 return -2;
46 } else {
47 ELOG("IPC: unexpected EOF while reading header, got %" PRIu32 " bytes, want %" PRIu32 " bytes\n",
48 read_bytes, to_read);
49 return -3;
50 }
51 }
52
53 read_bytes += n;
54 }
55
56 if (memcmp(walk, I3_IPC_MAGIC, strlen(I3_IPC_MAGIC)) != 0) {
57 ELOG("IPC: invalid magic in header, got \"%.*s\", want \"%s\"\n",
58 (int)strlen(I3_IPC_MAGIC), walk, I3_IPC_MAGIC);
59 return -3;
60 }
61
62 walk += strlen(I3_IPC_MAGIC);
63 memcpy(reply_length, walk, sizeof(uint32_t));
64 walk += sizeof(uint32_t);
65 if (message_type != NULL)
66 memcpy(message_type, walk, sizeof(uint32_t));
67
68 *reply = smalloc(*reply_length);
69
70 read_bytes = 0;
71 while (read_bytes < *reply_length) {
72 const int n = read(sockfd, *reply + read_bytes, *reply_length - read_bytes);
73 if (n == -1) {
74 if (errno == EINTR || errno == EAGAIN)
75 continue;
76 return -1;
77 }
78 if (n == 0) {
79 ELOG("IPC: unexpected EOF while reading payload, got %" PRIu32 " bytes, want %" PRIu32 " bytes\n",
80 read_bytes, *reply_length);
81 return -3;
82 }
83
84 read_bytes += n;
85 }
86
87 return 0;
88 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <string.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <stdint.h>
13 #include <err.h>
14 #include <errno.h>
15
16 #include <i3/ipc.h>
17
18 /*
19 * Formats a message (payload) of the given size and type and sends it to i3 via
20 * the given socket file descriptor.
21 *
22 * Returns -1 when write() fails, errno will remain.
23 * Returns 0 on success.
24 *
25 */
26 int ipc_send_message(int sockfd, const uint32_t message_size,
27 const uint32_t message_type, const uint8_t *payload) {
28 const i3_ipc_header_t header = {
29 /* We don’t use I3_IPC_MAGIC because it’s a 0-terminated C string. */
30 .magic = {'i', '3', '-', 'i', 'p', 'c'},
31 .size = message_size,
32 .type = message_type};
33
34 if (writeall(sockfd, ((void *)&header), sizeof(i3_ipc_header_t)) == -1)
35 return -1;
36
37 if (writeall(sockfd, payload, message_size) == -1)
38 return -1;
39
40 return 0;
41 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <string.h>
10 #include <stdbool.h>
11
12 /*
13 * Returns true if this version of i3 is a debug build (anything which is not a
14 * release version), based on the git version number.
15 *
16 */
17 bool is_debug_build(void) {
18 /* i3_version contains either something like this:
19 * "4.0.2 (2011-11-11, branch "release")".
20 * or: "4.0.2-123-gCOFFEEBABE (2011-11-11, branch "next")".
21 *
22 * So we check for the offset of the first opening round bracket to
23 * determine whether this is a git version or a release version. */
24 return ((strchr(I3_VERSION, '(') - I3_VERSION) > 10);
25 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <errno.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/stat.h>
13
14 #ifndef HAVE_mkdirp
15 /*
16 * Emulates mkdir -p (creates any missing folders)
17 *
18 */
19 int mkdirp(const char *path, mode_t mode) {
20 if (mkdir(path, mode) == 0)
21 return 0;
22 if (errno == EEXIST) {
23 struct stat st;
24 /* Check that the named file actually is a directory. */
25 if (stat(path, &st)) {
26 ELOG("stat(%s) failed: %s\n", path, strerror(errno));
27 return -1;
28 }
29 if (!S_ISDIR(st.st_mode)) {
30 ELOG("mkdir(%s) failed: %s\n", path, strerror(ENOTDIR));
31 return -1;
32 }
33 return 0;
34 } else if (errno != ENOENT) {
35 ELOG("mkdir(%s) failed: %s\n", path, strerror(errno));
36 return -1;
37 }
38 char *copy = sstrdup(path);
39 /* strip trailing slashes, if any */
40 while (copy[strlen(copy) - 1] == '/')
41 copy[strlen(copy) - 1] = '\0';
42
43 char *sep = strrchr(copy, '/');
44 if (sep == NULL) {
45 free(copy);
46 return -1;
47 }
48 *sep = '\0';
49 int result = -1;
50 if (mkdirp(copy, mode) == 0)
51 result = mkdirp(path, mode);
52 free(copy);
53
54 return result;
55 }
56 #endif
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <err.h>
10 #include <glob.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 /*
15 * This function resolves ~ in pathnames.
16 * It may resolve wildcards in the first part of the path, but if no match
17 * or multiple matches are found, it just returns a copy of path as given.
18 *
19 */
20 char *resolve_tilde(const char *path) {
21 static glob_t globbuf;
22 char *head, *tail, *result;
23
24 tail = strchr(path, '/');
25 head = sstrndup(path, tail ? (size_t)(tail - path) : strlen(path));
26
27 int res = glob(head, GLOB_TILDE, NULL, &globbuf);
28 free(head);
29 /* no match, or many wildcard matches are bad */
30 if (res == GLOB_NOMATCH || globbuf.gl_pathc != 1)
31 result = sstrdup(path);
32 else if (res != 0) {
33 err(EXIT_FAILURE, "glob() failed");
34 } else {
35 head = globbuf.gl_pathv[0];
36 result = scalloc(strlen(head) + (tail ? strlen(tail) : 0) + 1, 1);
37 strcpy(result, head);
38 if (tail) {
39 strcat(result, tail);
40 }
41 }
42 globfree(&globbuf);
43
44 return result;
45 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdbool.h>
12 #include <limits.h>
13 #include <stdlib.h>
14 #include <math.h>
15
16 #include <xcb/xcb.h>
17 #include <xcb/xcb_aux.h>
18
19 /*
20 * Try to get the contents of the given atom (for example I3_SOCKET_PATH) from
21 * the X11 root window and return NULL if it doesn’t work.
22 *
23 * If the provided XCB connection is NULL, a new connection will be
24 * established.
25 *
26 * The memory for the contents is dynamically allocated and has to be
27 * free()d by the caller.
28 *
29 */
30 char *root_atom_contents(const char *atomname, xcb_connection_t *provided_conn, int screen) {
31 xcb_intern_atom_cookie_t atom_cookie;
32 xcb_intern_atom_reply_t *atom_reply;
33 char *content = NULL;
34 size_t content_max_words = 256;
35 xcb_connection_t *conn = provided_conn;
36
37 if (provided_conn == NULL &&
38 ((conn = xcb_connect(NULL, &screen)) == NULL ||
39 xcb_connection_has_error(conn))) {
40 return NULL;
41 }
42
43 atom_cookie = xcb_intern_atom(conn, 0, strlen(atomname), atomname);
44
45 xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screen);
46 xcb_window_t root = root_screen->root;
47
48 atom_reply = xcb_intern_atom_reply(conn, atom_cookie, NULL);
49 if (atom_reply == NULL) {
50 goto out_conn;
51 }
52
53 xcb_get_property_cookie_t prop_cookie;
54 xcb_get_property_reply_t *prop_reply;
55 prop_cookie = xcb_get_property_unchecked(conn, false, root, atom_reply->atom,
56 XCB_GET_PROPERTY_TYPE_ANY, 0, content_max_words);
57 prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL);
58 if (prop_reply == NULL) {
59 goto out_atom;
60 }
61 if (xcb_get_property_value_length(prop_reply) > 0 && prop_reply->bytes_after > 0) {
62 /* We received an incomplete value. Ask again but with a properly
63 * adjusted size. */
64 content_max_words += ceil(prop_reply->bytes_after / 4.0);
65 /* Repeat the request, with adjusted size */
66 free(prop_reply);
67 prop_cookie = xcb_get_property_unchecked(conn, false, root, atom_reply->atom,
68 XCB_GET_PROPERTY_TYPE_ANY, 0, content_max_words);
69 prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL);
70 if (prop_reply == NULL) {
71 goto out_atom;
72 }
73 }
74 if (xcb_get_property_value_length(prop_reply) == 0) {
75 goto out;
76 }
77 if (prop_reply->type == XCB_ATOM_CARDINAL) {
78 /* We treat a CARDINAL as a >= 32-bit unsigned int. The only CARDINAL
79 * we query is I3_PID, which is 32-bit. */
80 sasprintf(&content, "%u", *((unsigned int *)xcb_get_property_value(prop_reply)));
81 } else {
82 sasprintf(&content, "%.*s", xcb_get_property_value_length(prop_reply),
83 (char *)xcb_get_property_value(prop_reply));
84 }
85
86 out:
87 free(prop_reply);
88 out_atom:
89 free(atom_reply);
90 out_conn:
91 if (provided_conn == NULL)
92 xcb_disconnect(conn);
93 return content;
94 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <string.h>
10 #include <stdlib.h>
11 #include <stdarg.h>
12 #include <unistd.h>
13 #include <stdio.h>
14 #include <err.h>
15 #include <errno.h>
16
17 /*
18 * The s* functions (safe) are wrappers around malloc, strdup, …, which exits if one of
19 * the called functions returns NULL, meaning that there is no more memory available
20 *
21 */
22 void *smalloc(size_t size) {
23 void *result = malloc(size);
24 if (result == NULL)
25 err(EXIT_FAILURE, "malloc(%zd)", size);
26 return result;
27 }
28
29 void *scalloc(size_t num, size_t size) {
30 void *result = calloc(num, size);
31 if (result == NULL)
32 err(EXIT_FAILURE, "calloc(%zd, %zd)", num, size);
33 return result;
34 }
35
36 void *srealloc(void *ptr, size_t size) {
37 void *result = realloc(ptr, size);
38 if (result == NULL && size > 0)
39 err(EXIT_FAILURE, "realloc(%zd)", size);
40 return result;
41 }
42
43 char *sstrdup(const char *str) {
44 char *result = strdup(str);
45 if (result == NULL)
46 err(EXIT_FAILURE, "strdup()");
47 return result;
48 }
49
50 char *sstrndup(const char *str, size_t size) {
51 char *result = strndup(str, size);
52 if (result == NULL)
53 err(EXIT_FAILURE, "strndup()");
54 return result;
55 }
56
57 int sasprintf(char **strp, const char *fmt, ...) {
58 va_list args;
59 int result;
60
61 va_start(args, fmt);
62 if ((result = vasprintf(strp, fmt, args)) == -1)
63 err(EXIT_FAILURE, "asprintf(%s)", fmt);
64 va_end(args);
65 return result;
66 }
67
68 ssize_t writeall(int fd, const void *buf, size_t count) {
69 size_t written = 0;
70
71 while (written < count) {
72 const ssize_t n = write(fd, ((char *)buf) + written, count - written);
73 if (n == -1) {
74 if (errno == EINTR || errno == EAGAIN)
75 continue;
76 return n;
77 }
78 written += (size_t)n;
79 }
80
81 return written;
82 }
83
84 ssize_t writeall_nonblock(int fd, const void *buf, size_t count) {
85 size_t written = 0;
86
87 while (written < count) {
88 const ssize_t n = write(fd, ((char *)buf) + written, count - written);
89 if (n == -1) {
90 if (errno == EAGAIN) {
91 return written;
92 } else if (errno == EINTR) {
93 continue;
94 } else {
95 return n;
96 }
97 }
98 written += (size_t)n;
99 }
100 return written;
101 }
102
103 ssize_t swrite(int fd, const void *buf, size_t count) {
104 ssize_t n;
105
106 n = writeall(fd, buf, count);
107 if (n == -1)
108 err(EXIT_FAILURE, "Failed to write %d", fd);
109 else
110 return n;
111 }
112
113 /*
114 * Like strcasecmp but considers the case where either string is NULL.
115 *
116 */
117 int strcasecmp_nullable(const char *a, const char *b) {
118 if (a == b) {
119 return 0;
120 }
121 if (a == NULL) {
122 return -1;
123 }
124 if (b == NULL) {
125 return 1;
126 }
127 return strcasecmp(a, b);
128 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * string.c: Define an i3String type to automagically handle UTF-8/UCS-2
7 * conversions. Some font backends need UCS-2 (X core fonts),
8 * others want UTF-8 (Pango).
9 *
10 */
11 #include "libi3.h"
12
13 #include <stdlib.h>
14 #include <string.h>
15
16 #include <glib.h>
17
18 struct _i3String {
19 char *utf8;
20 xcb_char2b_t *ucs2;
21 size_t num_glyphs;
22 size_t num_bytes;
23 bool pango_markup;
24 };
25
26 /*
27 * Build an i3String from an UTF-8 encoded string.
28 * Returns the newly-allocated i3String.
29 *
30 */
31 i3String *i3string_from_utf8(const char *from_utf8) {
32 return i3string_from_utf8_with_length(from_utf8, -1);
33 }
34
35 /*
36 * Build an i3String from an UTF-8 encoded string in Pango markup.
37 *
38 */
39 i3String *i3string_from_markup(const char *from_markup) {
40 i3String *str = i3string_from_utf8(from_markup);
41
42 /* Set the markup flag */
43 str->pango_markup = true;
44
45 return str;
46 }
47
48 /*
49 * Build an i3String from an UTF-8 encoded string with fixed length.
50 * To be used when no proper NULL-termination is available.
51 * Returns the newly-allocated i3String.
52 *
53 */
54 i3String *i3string_from_utf8_with_length(const char *from_utf8, ssize_t num_bytes) {
55 i3String *str = scalloc(1, sizeof(i3String));
56
57 /* g_utf8_make_valid NULL-terminates the string. */
58 str->utf8 = g_utf8_make_valid(from_utf8, num_bytes);
59
60 /* num_bytes < 0 means NULL-terminated string, need to calculate length */
61 str->num_bytes = num_bytes < 0 ? strlen(str->utf8) : (size_t)num_bytes;
62
63 return str;
64 }
65
66 /*
67 * Build an i3String from an UTF-8 encoded string in Pango markup with fixed
68 * length.
69 *
70 */
71 i3String *i3string_from_markup_with_length(const char *from_markup, size_t num_bytes) {
72 i3String *str = i3string_from_utf8_with_length(from_markup, num_bytes);
73
74 /* set the markup flag */
75 str->pango_markup = true;
76
77 return str;
78 }
79
80 /*
81 * Build an i3String from an UCS-2 encoded string.
82 * Returns the newly-allocated i3String.
83 *
84 */
85 i3String *i3string_from_ucs2(const xcb_char2b_t *from_ucs2, size_t num_glyphs) {
86 i3String *str = scalloc(1, sizeof(i3String));
87
88 /* Copy the actual text to our i3String */
89 str->ucs2 = scalloc(num_glyphs, sizeof(xcb_char2b_t));
90 memcpy(str->ucs2, from_ucs2, num_glyphs * sizeof(xcb_char2b_t));
91
92 /* Store the length */
93 str->num_glyphs = num_glyphs;
94
95 str->utf8 = NULL;
96 str->num_bytes = 0;
97
98 return str;
99 }
100
101 /*
102 * Copies the given i3string.
103 * Note that this will not free the source string.
104 */
105 i3String *i3string_copy(i3String *str) {
106 i3String *copy = i3string_from_utf8(i3string_as_utf8(str));
107 copy->pango_markup = str->pango_markup;
108 return copy;
109 }
110
111 /*
112 * Free an i3String.
113 *
114 */
115 void i3string_free(i3String *str) {
116 if (str == NULL)
117 return;
118 free(str->utf8);
119 free(str->ucs2);
120 free(str);
121 }
122
123 static void i3string_ensure_utf8(i3String *str) {
124 if (str->utf8 != NULL)
125 return;
126 if ((str->utf8 = convert_ucs2_to_utf8(str->ucs2, str->num_glyphs)) != NULL)
127 str->num_bytes = strlen(str->utf8);
128 }
129
130 static void i3string_ensure_ucs2(i3String *str) {
131 if (str->ucs2 != NULL)
132 return;
133 str->ucs2 = convert_utf8_to_ucs2(str->utf8, &str->num_glyphs);
134 }
135
136 /*
137 * Returns the UTF-8 encoded version of the i3String.
138 *
139 */
140 const char *i3string_as_utf8(i3String *str) {
141 i3string_ensure_utf8(str);
142 return str->utf8;
143 }
144
145 /*
146 * Returns the UCS-2 encoded version of the i3String.
147 *
148 */
149 const xcb_char2b_t *i3string_as_ucs2(i3String *str) {
150 i3string_ensure_ucs2(str);
151 return str->ucs2;
152 }
153
154 /*
155 * Returns the number of bytes (UTF-8 encoded) in an i3String.
156 *
157 */
158 size_t i3string_get_num_bytes(i3String *str) {
159 i3string_ensure_utf8(str);
160 return str->num_bytes;
161 }
162
163 /*
164 * Whether the given i3String is in Pango markup.
165 */
166 bool i3string_is_markup(i3String *str) {
167 return str->pango_markup;
168 }
169
170 /*
171 * Set whether the i3String should use Pango markup.
172 */
173 void i3string_set_markup(i3String *str, bool pango_markup) {
174 str->pango_markup = pango_markup;
175 }
176
177 /*
178 * Escape pango markup characters in the given string.
179 */
180 i3String *i3string_escape_markup(i3String *str) {
181 const char *text = i3string_as_utf8(str);
182 char *escaped = g_markup_escape_text(text, -1);
183 i3String *result = i3string_from_utf8(escaped);
184 free(escaped);
185 return result;
186 }
187
188 /*
189 * Returns the number of glyphs in an i3String.
190 *
191 */
192 size_t i3string_get_num_glyphs(i3String *str) {
193 i3string_ensure_ucs2(str);
194 return str->num_glyphs;
195 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <sys/types.h>
10 #include <string.h>
11
12 #ifndef HAVE_strndup
13 /*
14 * Taken from FreeBSD
15 * Returns a pointer to a new string which is a duplicate of the
16 * string, but only copies at most n characters.
17 *
18 */
19 char *strndup(const char *str, size_t n) {
20 size_t len;
21 char *copy;
22
23 for (len = 0; len < n && str[len]; len++)
24 continue;
25
26 copy = smalloc(len + 1);
27 memcpy(copy, str, len);
28 copy[len] = '\0';
29 return (copy);
30 }
31 #endif
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "libi3.h"
8
9 #include <err.h>
10 #include <errno.h>
11 #include <iconv.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 static iconv_t utf8_conversion_descriptor = (iconv_t)-1;
16 static iconv_t ucs2_conversion_descriptor = (iconv_t)-1;
17
18 /*
19 * Converts the given string to UTF-8 from UCS-2 big endian. The return value
20 * must be freed after use.
21 *
22 */
23 char *convert_ucs2_to_utf8(xcb_char2b_t *text, size_t num_glyphs) {
24 /* Allocate the output buffer (UTF-8 is at most 4 bytes per glyph) */
25 size_t buffer_size = num_glyphs * 4 + 1;
26 char *buffer = scalloc(buffer_size, 1);
27
28 /* We need to use an additional pointer, because iconv() modifies it */
29 char *output = buffer;
30 size_t output_size = buffer_size - 1;
31
32 if (utf8_conversion_descriptor == (iconv_t)-1) {
33 /* Get a new conversion descriptor */
34 utf8_conversion_descriptor = iconv_open("UTF-8", "UCS-2BE");
35 if (utf8_conversion_descriptor == (iconv_t)-1)
36 err(EXIT_FAILURE, "Error opening the conversion context");
37 } else {
38 /* Reset the existing conversion descriptor */
39 iconv(utf8_conversion_descriptor, NULL, NULL, NULL, NULL);
40 }
41
42 /* Do the conversion */
43 size_t input_len = num_glyphs * sizeof(xcb_char2b_t);
44 size_t rc = iconv(utf8_conversion_descriptor, (char **)&text,
45 &input_len, &output, &output_size);
46 if (rc == (size_t)-1) {
47 perror("Converting to UTF-8 failed");
48 free(buffer);
49 return NULL;
50 }
51
52 return buffer;
53 }
54
55 /*
56 * Converts the given string to UCS-2 big endian for use with
57 * xcb_image_text_16(). The amount of real glyphs is stored in real_strlen,
58 * a buffer containing the UCS-2 encoded string (16 bit per glyph) is
59 * returned. It has to be freed when done.
60 *
61 */
62 xcb_char2b_t *convert_utf8_to_ucs2(char *input, size_t *real_strlen) {
63 /* Calculate the input buffer size (UTF-8 is strlen-safe) */
64 size_t input_size = strlen(input);
65
66 /* Calculate the output buffer size and allocate the buffer */
67 size_t buffer_size = input_size * sizeof(xcb_char2b_t);
68 xcb_char2b_t *buffer = smalloc(buffer_size);
69
70 /* We need to use an additional pointer, because iconv() modifies it */
71 size_t output_bytes_left = buffer_size;
72 xcb_char2b_t *output = buffer;
73
74 if (ucs2_conversion_descriptor == (iconv_t)-1) {
75 /* Get a new conversion descriptor. //IGNORE is a GNU suffix that makes
76 * iconv to silently discard characters that cannot be represented in
77 * the target character set. */
78 ucs2_conversion_descriptor = iconv_open("UCS-2BE//IGNORE", "UTF-8");
79 if (ucs2_conversion_descriptor == (iconv_t)-1) {
80 ucs2_conversion_descriptor = iconv_open("UCS-2BE", "UTF-8");
81 }
82 if (ucs2_conversion_descriptor == (iconv_t)-1) {
83 err(EXIT_FAILURE, "Error opening the conversion context");
84 }
85 } else {
86 /* Reset the existing conversion descriptor */
87 iconv(ucs2_conversion_descriptor, NULL, NULL, NULL, NULL);
88 }
89
90 /* Do the conversion */
91 size_t rc = iconv(ucs2_conversion_descriptor, &input, &input_size,
92 (char **)&output, &output_bytes_left);
93 if (rc == (size_t)-1) {
94 /* Conversion will only be partial. */
95 perror("Converting to UCS-2 failed");
96 }
97
98 /* If no bytes where converted, this is equivalent to freeing buffer. */
99 buffer_size -= output_bytes_left;
100 buffer = srealloc(buffer, buffer_size);
101
102 /* Return the resulting string's length */
103 if (real_strlen != NULL) {
104 *real_strlen = buffer_size / sizeof(xcb_char2b_t);
105 }
106
107 return buffer;
108 }
0 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
1 <!-- Created with Inkscape (http://www.inkscape.org/) -->
2 <svg
3 xmlns:dc="http://purl.org/dc/elements/1.1/"
4 xmlns:cc="http://creativecommons.org/ns#"
5 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
6 xmlns:svg="http://www.w3.org/2000/svg"
7 xmlns="http://www.w3.org/2000/svg"
8 xmlns:xlink="http://www.w3.org/1999/xlink"
9 xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
10 xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
11 width="210mm"
12 height="297mm"
13 id="svg2"
14 sodipodi:version="0.32"
15 inkscape:version="0.46"
16 sodipodi:docname="logo_i3_linuxfr_bapt_v2.svg"
17 inkscape:output_extension="org.inkscape.output.svg.inkscape">
18 <defs
19 id="defs4">
20 <linearGradient
21 id="linearGradient3750">
22 <stop
23 style="stop-color:#17273b;stop-opacity:1;"
24 offset="0"
25 id="stop3752" />
26 <stop
27 id="stop4356"
28 offset="0.41666666"
29 style="stop-color:#008cd4;stop-opacity:0.78039217;" />
30 <stop
31 style="stop-color:#6eb5de;stop-opacity:0.69803923;"
32 offset="0.87847221"
33 id="stop4358" />
34 <stop
35 style="stop-color:#88bfe5;stop-opacity:0.61960787;"
36 offset="1"
37 id="stop3754" />
38 </linearGradient>
39 <inkscape:perspective
40 id="perspective3661"
41 inkscape:persp3d-origin="750.50629 : 505.26732 : 1"
42 inkscape:vp_z="683.5728 : 1230.5721 : 1"
43 inkscape:vp_y="0 : 1946.8917 : 0"
44 inkscape:vp_x="-526.84957 : 2.2065866e-13 : 0"
45 sodipodi:type="inkscape:persp3d" />
46 <linearGradient
47 id="linearGradient3284">
48 <stop
49 style="stop-color:#ffffff;stop-opacity:1;"
50 offset="0"
51 id="stop3286" />
52 <stop
53 style="stop-color:#ffffff;stop-opacity:0.7518248;"
54 offset="1"
55 id="stop3288" />
56 </linearGradient>
57 <linearGradient
58 id="linearGradient3278">
59 <stop
60 id="stop3280"
61 offset="0"
62 style="stop-color:#33bff7;stop-opacity:0.38039216;" />
63 <stop
64 id="stop3282"
65 offset="1"
66 style="stop-color:#2d446b;stop-opacity:1;" />
67 </linearGradient>
68 <linearGradient
69 id="linearGradient3272">
70 <stop
71 id="stop3274"
72 offset="0"
73 style="stop-color:#2596f6;stop-opacity:0.38039216;" />
74 <stop
75 id="stop3276"
76 offset="1"
77 style="stop-color:#2d446b;stop-opacity:1;" />
78 </linearGradient>
79 <linearGradient
80 id="linearGradient3266">
81 <stop
82 id="stop3268"
83 offset="0"
84 style="stop-color:#189fff;stop-opacity:0.38039216;" />
85 <stop
86 id="stop3270"
87 offset="1"
88 style="stop-color:#010b2b;stop-opacity:1;" />
89 </linearGradient>
90 <linearGradient
91 id="linearGradient3244">
92 <stop
93 id="stop3246"
94 offset="0"
95 style="stop-color:#419bff;stop-opacity:1;" />
96 <stop
97 id="stop3248"
98 offset="1"
99 style="stop-color:#002359;stop-opacity:1;" />
100 </linearGradient>
101 <linearGradient
102 id="linearGradient3159">
103 <stop
104 style="stop-color:#33bff7;stop-opacity:0.38039216;"
105 offset="0"
106 id="stop3161" />
107 <stop
108 style="stop-color:#2d446b;stop-opacity:1;"
109 offset="1"
110 id="stop3163" />
111 </linearGradient>
112 <inkscape:perspective
113 sodipodi:type="inkscape:persp3d"
114 inkscape:vp_x="-526.84957 : 2.9848654e-13 : 0"
115 inkscape:vp_y="1.192088e-13 : 1946.8917 : 0"
116 inkscape:vp_z="680.54236 : 1232.3792 : 1"
117 inkscape:persp3d-origin="730.30325 : 937.39936 : 1"
118 id="perspective10" />
119 <radialGradient
120 inkscape:collect="always"
121 xlink:href="#linearGradient3244"
122 id="radialGradient3256"
123 cx="344.73471"
124 cy="77.263504"
125 fx="344.73471"
126 fy="77.263504"
127 r="196.15704"
128 gradientTransform="matrix(-1.39796,-5.3360318e-2,8.3551106e-2,-2.1889079,820.20461,272.08319)"
129 gradientUnits="userSpaceOnUse" />
130 <radialGradient
131 inkscape:collect="always"
132 xlink:href="#linearGradient3159"
133 id="radialGradient3264"
134 cx="140.3363"
135 cy="300.27451"
136 fx="140.3363"
137 fy="300.27451"
138 r="206.15704"
139 gradientTransform="matrix(0.6771172,-0.6830119,1.1802789,1.1700925,-161.83993,77.639162)"
140 gradientUnits="userSpaceOnUse" />
141 <radialGradient
142 inkscape:collect="always"
143 xlink:href="#linearGradient3284"
144 id="radialGradient3290"
145 cx="267.50388"
146 cy="337.12692"
147 fx="267.50388"
148 fy="337.12692"
149 r="77.845424"
150 gradientTransform="matrix(1,0,0,0.7430849,0,86.613009)"
151 gradientUnits="userSpaceOnUse" />
152 <inkscape:perspective
153 id="perspective3373"
154 inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
155 inkscape:vp_z="744.09448 : 526.18109 : 1"
156 inkscape:vp_y="0 : 1000 : 0"
157 inkscape:vp_x="0 : 526.18109 : 1"
158 sodipodi:type="inkscape:persp3d" />
159 <linearGradient
160 id="linearGradient3211">
161 <stop
162 id="stop3213"
163 offset="0"
164 style="stop-color: rgb(0, 160, 255); stop-opacity: 1;" />
165 <stop
166 id="stop3215"
167 offset="1"
168 style="stop-color: rgb(0, 37, 255); stop-opacity: 1;" />
169 </linearGradient>
170 <filter
171 inkscape:collect="always"
172 id="filter3406">
173 <feGaussianBlur
174 inkscape:collect="always"
175 stdDeviation="13.396228"
176 id="feGaussianBlur3408" />
177 </filter>
178 <radialGradient
179 inkscape:collect="always"
180 xlink:href="#linearGradient3284"
181 id="radialGradient3416"
182 cx="119.96373"
183 cy="229.28981"
184 fx="119.96373"
185 fy="229.28981"
186 r="203.19508"
187 gradientTransform="matrix(0.7210805,2.1168143,-1.4722239,0.5015047,347.53034,-320.94088)"
188 gradientUnits="userSpaceOnUse" />
189 <radialGradient
190 inkscape:collect="always"
191 xlink:href="#linearGradient3266"
192 id="radialGradient3423"
193 gradientUnits="userSpaceOnUse"
194 gradientTransform="matrix(1.1454302,-1.1687051,2.0295327,1.9193266,-889.0626,57.219022)"
195 cx="351.15485"
196 cy="372.06332"
197 fx="351.15485"
198 fy="372.06332"
199 r="163.57143" />
200 <radialGradient
201 inkscape:collect="always"
202 xlink:href="#linearGradient3284"
203 id="radialGradient3734"
204 gradientUnits="userSpaceOnUse"
205 gradientTransform="matrix(0.7210805,2.1168143,-1.4722239,0.5015047,347.53034,-320.94088)"
206 cx="119.96373"
207 cy="229.28981"
208 fx="119.96373"
209 fy="229.28981"
210 r="203.19508" />
211 <radialGradient
212 inkscape:collect="always"
213 xlink:href="#linearGradient3284"
214 id="radialGradient3736"
215 gradientUnits="userSpaceOnUse"
216 gradientTransform="matrix(0.7210805,2.1168143,-1.4722239,0.5015047,347.53034,-320.94088)"
217 cx="119.96373"
218 cy="229.28981"
219 fx="119.96373"
220 fy="229.28981"
221 r="203.19508" />
222 <radialGradient
223 inkscape:collect="always"
224 xlink:href="#linearGradient3750"
225 id="radialGradient3758"
226 cx="390.69662"
227 cy="258.92429"
228 fx="390.69662"
229 fy="258.92429"
230 r="32.03125"
231 gradientTransform="matrix(4.0292425,-5.5974184,5.1695404,3.721239,-2510.9809,1613.1551)"
232 gradientUnits="userSpaceOnUse" />
233 <radialGradient
234 inkscape:collect="always"
235 xlink:href="#linearGradient3750"
236 id="radialGradient3760"
237 cx="59.046589"
238 cy="248.2272"
239 fx="59.046589"
240 fy="248.2272"
241 r="197.15625"
242 gradientTransform="matrix(1.7105919,-4.3705195e-2,3.3347151e-2,1.3051856,-58.593126,-250.18318)"
243 gradientUnits="userSpaceOnUse" />
244 <radialGradient
245 inkscape:collect="always"
246 xlink:href="#linearGradient3750"
247 id="radialGradient3762"
248 cx="192.64008"
249 cy="282.40387"
250 fx="192.64008"
251 fy="282.40387"
252 r="133.09375"
253 gradientTransform="matrix(1.0081228,0.4493093,-1.0529321,2.3624813,273.13721,-455.12138)"
254 gradientUnits="userSpaceOnUse" />
255 <radialGradient
256 inkscape:collect="always"
257 xlink:href="#linearGradient3750"
258 id="radialGradient4344"
259 gradientUnits="userSpaceOnUse"
260 gradientTransform="matrix(5.7478532,-0.5889281,0.4834745,4.7186431,-260.98332,-919.446)"
261 cx="24"
262 cy="280.45392"
263 fx="24"
264 fy="280.45392"
265 r="65.0625" />
266 <linearGradient
267 inkscape:collect="always"
268 xlink:href="#linearGradient3750"
269 id="linearGradient4354"
270 x1="-125.59599"
271 y1="-100.47679"
272 x2="-5.2882538"
273 y2="-100.47679"
274 gradientUnits="userSpaceOnUse" />
275 </defs>
276 <sodipodi:namedview
277 id="base"
278 pagecolor="#ffffff"
279 bordercolor="#666666"
280 borderopacity="1.0"
281 inkscape:pageopacity="0.0"
282 inkscape:pageshadow="2"
283 inkscape:zoom="1"
284 inkscape:cx="239.17981"
285 inkscape:cy="807.75327"
286 inkscape:document-units="px"
287 inkscape:current-layer="layer1"
288 showgrid="false"
289 inkscape:window-width="1272"
290 inkscape:window-height="950"
291 inkscape:window-x="24"
292 inkscape:window-y="24" />
293 <metadata
294 id="metadata7">
295 <rdf:RDF>
296 <cc:Work
297 rdf:about="">
298 <dc:format>image/svg+xml</dc:format>
299 <dc:type
300 rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
301 <dc:title>Logo I3</dc:title>
302 <dc:contributor>
303 <cc:Agent>
304 <dc:title>yellowiscool, farvardin</dc:title>
305 </cc:Agent>
306 </dc:contributor>
307 <dc:creator>
308 <cc:Agent>
309 <dc:title>steckdenis</dc:title>
310 </cc:Agent>
311 </dc:creator>
312 <dc:description>Logo for I3, an improved dynamic tiling window manager: http://i3wm.org/</dc:description>
313 <cc:license
314 rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
315 </cc:Work>
316 <cc:License
317 rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
318 <cc:permits
319 rdf:resource="http://creativecommons.org/ns#Reproduction" />
320 <cc:permits
321 rdf:resource="http://creativecommons.org/ns#Distribution" />
322 <cc:requires
323 rdf:resource="http://creativecommons.org/ns#Notice" />
324 <cc:requires
325 rdf:resource="http://creativecommons.org/ns#Attribution" />
326 <cc:permits
327 rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
328 <cc:requires
329 rdf:resource="http://creativecommons.org/ns#ShareAlike" />
330 </cc:License>
331 </rdf:RDF>
332 </metadata>
333 <g
334 inkscape:groupmode="layer"
335 id="layer4"
336 inkscape:label="fond"
337 style="display:none">
338 <rect
339 style="opacity:0.87000002;fill:#5599ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:60;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
340 id="rect3241"
341 width="330"
342 height="313.5"
343 x="39"
344 y="103.86218" />
345 </g>
346 <g
347 inkscape:label="Calque 1"
348 inkscape:groupmode="layer"
349 id="layer1"
350 style="display:inline">
351 <rect
352 style="opacity:1;fill:url(#radialGradient3423);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
353 id="rect2383"
354 width="322.85715"
355 height="308.57144"
356 x="42.85714"
357 y="106.6479" />
358 <path
359 style="opacity:0.09583333;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:60;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
360 d="M 43.707165,106.65625 C 41.782753,110.85167 43.413409,116.56832 42.911106,121.37227 C 43.128238,169.37318 43.345369,217.37409 43.5625,265.375 C 55.407545,275.84522 72.489757,274.25524 87.152921,276.2874 C 140.64585,279.73053 194.4359,279.89819 247.75899,273.83826 C 281.78509,270.40324 315.81178,265.10681 348.64903,255.42536 C 357.00872,252.61832 367.50989,246.20234 365.71875,236.08333 C 365.71875,192.94097 365.71875,149.79861 365.71875,106.65625 C 258.38155,106.65625 151.04436,106.65625 43.707165,106.65625 z"
361 id="path3221" />
362 <g
363 transform="matrix(0.3387513,-0.3401668,0.3401668,0.3387513,59.228831,277.49214)"
364 style="opacity:0.5;fill:#000000;fill-opacity:1;filter:url(#filter3406)"
365 id="g3394">
366 <path
367 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:60;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
368 d="M 412.75,98.59375 C 396.19379,98.835333 382.96319,112.44354 383.1875,129 C 383.1875,129 383.18749,216.25107 383.1875,325.3125 C 383.1875,348.61986 371.07095,364.44442 344.96875,378.78125 C 318.86655,393.11808 279.99599,401.65625 241.09375,401.65625 C 202.19151,401.65625 163.32095,393.11808 137.21875,378.78125 C 111.11655,364.44442 99,348.61986 99,325.3125 C 99,270.93917 99.441249,221.95695 99.65625,186.4375 C 99.76375,168.67777 99.833258,154.32173 99.75,144.09375 C 99.708371,138.97976 99.620501,134.98608 99.46875,131.625 C 99.392874,129.94446 99.331848,128.56919 99.0625,126.375 C 98.927826,125.27791 98.894428,124.1628 98.0625,121.1875 C 97.646536,119.69985 97.275733,117.79087 94.875,113.75 C 92.474267,109.70913 84.912085,98.999943 69,99 C 59.653467,98.879464 50.78473,103.12192 45.013008,110.47443 C 39.241286,117.82694 37.226064,127.44941 39.5625,136.5 C 39.625678,138.53091 39.71934,140.82729 39.75,144.59375 C 39.827653,154.13315 39.763299,168.40852 39.65625,186.09375 C 39.442151,221.46421 39,270.62442 39,325.3125 C 38.999999,372.89506 69.913445,410.26687 108.34375,431.375 C 146.77406,452.48313 193.95265,461.65625 241.09375,461.65625 C 288.23485,461.65625 335.41344,452.48313 373.84375,431.375 C 412.27406,410.26687 443.1875,372.89506 443.1875,325.3125 C 443.18749,216.25108 443.1875,129 443.1875,129 C 443.29728,120.89717 440.12471,113.0945 434.39168,107.36735 C 428.65864,101.6402 420.85272,98.475651 412.75,98.59375 L 412.75,98.59375 z"
369 id="path3396" />
370 <path
371 style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:60;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
372 d="M 239.5625,99.5 C 223.00629,99.741583 209.77569,113.34979 210,129.90625 L 210,350 C 209.84699,360.81908 215.53126,370.88244 224.87619,376.33663 C 234.22111,381.79082 245.77889,381.79082 255.12381,376.33663 C 264.46874,370.88244 270.15301,360.81908 270,350 L 270,129.90625 C 270.10978,121.80342 266.93721,114.00075 261.20418,108.2736 C 255.47114,102.54645 247.66522,99.381901 239.5625,99.5 L 239.5625,99.5 z"
373 id="path3398" />
374 <path
375 sodipodi:type="arc"
376 style="fill:#000000;fill-opacity:1;stroke-width:60;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
377 id="path3400"
378 sodipodi:cx="70"
379 sodipodi:cy="40"
380 sodipodi:rx="30"
381 sodipodi:ry="30"
382 d="M 100,40 A 30,30 0 1 1 40,40 A 30,30 0 1 1 100,40 z"
383 transform="translate(0,-10)" />
384 <path
385 transform="translate(170,-10)"
386 d="M 100,40 A 30,30 0 1 1 40,40 A 30,30 0 1 1 100,40 z"
387 sodipodi:ry="30"
388 sodipodi:rx="30"
389 sodipodi:cy="40"
390 sodipodi:cx="70"
391 id="path3402"
392 style="fill:#000000;fill-opacity:1;stroke-width:60;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
393 sodipodi:type="arc" />
394 <path
395 sodipodi:type="arc"
396 style="fill:#000000;fill-opacity:1;stroke-width:60;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
397 id="path3404"
398 sodipodi:cx="70"
399 sodipodi:cy="40"
400 sodipodi:rx="30"
401 sodipodi:ry="30"
402 d="M 100,40 A 30,30 0 1 1 40,40 A 30,30 0 1 1 100,40 z"
403 transform="translate(345,-10)" />
404 </g>
405 </g>
406 <g
407 inkscape:groupmode="layer"
408 id="layer2"
409 inkscape:label="tiling"
410 style="display:none">
411 <rect
412 y="106.6479"
413 x="42.85714"
414 height="308.57144"
415 width="322.85715"
416 id="rect3247"
417 style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
418 <rect
419 style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
420 id="rect3253"
421 width="212.07706"
422 height="98.216858"
423 x="42.85096"
424 y="218.0385" />
425 <rect
426 style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
427 id="rect3257"
428 width="110.75323"
429 height="70.943619"
430 x="254.94135"
431 y="274.26196" />
432 <rect
433 y="218.02481"
434 x="254.93958"
435 height="56.235466"
436 width="110.76914"
437 id="rect3259"
438 style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
439 <rect
440 y="345.25272"
441 x="254.91608"
442 height="69.955116"
443 width="110.78036"
444 id="rect3255"
445 style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
446 <rect
447 style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
448 id="rect3249"
449 width="106.87583"
450 height="111.69163"
451 x="42.849949"
452 y="106.32091" />
453 <rect
454 y="106.45182"
455 x="149.72185"
456 height="111.57816"
457 width="105.18911"
458 id="rect3261"
459 style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
460 <rect
461 style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
462 id="rect3263"
463 width="110.786"
464 height="111.57211"
465 x="254.91632"
466 y="106.45485" />
467 <rect
468 y="316.22876"
469 x="42.847878"
470 height="98.979958"
471 width="212.0791"
472 id="rect3251"
473 style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" />
474 </g>
475 <g
476 inkscape:groupmode="layer"
477 id="layer5"
478 inkscape:label="tiling2"
479 style="display:inline">
480 <rect
481 y="106.6479"
482 x="42.85714"
483 height="308.57144"
484 width="322.85715"
485 id="rect3244"
486 style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline" />
487 <rect
488 style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;display:inline"
489 id="rect3246"
490 width="322.85715"
491 height="308.57144"
492 x="42.85714"
493 y="106.6479" />
494 <path
495 style="fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;display:inline"
496 d="M 182.85714,106.6479 L 182.85714,415.21935 L 182.85714,106.6479 z"
497 id="rect3246"
498 sodipodi:nodetypes="ccc" />
499 <path
500 sodipodi:nodetypes="ccc"
501 id="path3254"
502 d="M 182.41744,207.43363 L 43.296842,207.43363 L 182.41744,207.43363 z"
503 style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
504 <path
505 style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
506 d="M 182.41744,313.43363 L 43.296842,313.43363 L 182.41744,313.43363 z"
507 id="path3256"
508 sodipodi:nodetypes="ccc" />
509 </g>
510 <g
511 inkscape:groupmode="layer"
512 id="layer3"
513 inkscape:label="I3"
514 style="display:inline">
515 <path
516 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:60;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;opacity:0.87;color:#000000;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-dashoffset:0;visibility:visible;overflow:visible;enable-background:accumulate"
517 d="M 232.58675,170.48705 C 227.06049,176.20076 227.20767,185.31117 232.91561,190.84339 C 232.91561,190.84339 262.59553,220.39981 299.69461,257.34451 C 307.623,265.23991 308.90149,274.72214 304.93625,288.45787 C 300.97101,302.19359 290.70796,318.30838 277.52977,331.54163 C 264.35159,344.77488 248.27973,355.10504 234.56067,359.12752 C 220.8416,363.15 211.35411,361.91106 203.42572,354.01566 C 184.92972,335.59662 168.41707,318.85373 156.40736,306.74834 C 150.40251,300.69564 145.54261,295.80887 142.03518,292.37245 C 140.28147,290.65424 138.89319,289.33126 137.69845,288.24431 C 137.10109,287.70084 136.61259,287.25572 135.77496,286.60406 C 135.35615,286.27823 134.96551,285.91185 133.67159,285.18696 C 133.02464,284.82451 132.24966,284.30398 130.06183,283.75178 C 127.87401,283.19957 121.6694,282.14423 116.27918,287.55701 C 113.07203,290.69556 111.51088,295.14955 112.05678,299.60357 C 112.60268,304.05759 115.19327,308.00272 119.06345,310.27384 C 119.7757,310.94033 120.58858,311.68637 121.88019,312.95183 C 125.15148,316.1569 129.98569,321.01459 135.96535,327.0419 C 147.92468,339.09652 164.49757,355.90001 183.10064,374.42567 C 199.28665,390.54432 222.47127,392.68834 242.66987,386.76604 C 262.86847,380.84373 281.97067,367.90254 297.93978,351.86671 C 313.90889,335.83087 326.77031,316.67487 332.60834,296.45175 C 338.44637,276.22863 336.20569,253.05315 320.01968,236.9345 C 282.92061,199.9898 253.24069,170.43338 253.24069,170.43338 C 250.52156,167.6512 246.79264,166.08723 242.90239,166.09734 C 239.01212,166.10745 235.29138,167.69077 232.58675,170.48705 L 232.58675,170.48705 z"
518 id="path2405" />
519 <path
520 style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:60;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline;opacity:0.87"
521 d="M 174.22754,229.70669 C 168.70128,235.42039 168.84845,244.5308 174.5564,250.06302 L 249.42498,324.62007 C 253.05344,328.33709 258.40222,329.81247 263.42316,328.48125 C 268.4441,327.15003 272.35931,323.21846 273.66958,318.19201 C 274.97985,313.16556 273.48219,307.82299 269.75006,304.21006 L 194.88148,229.65302 C 192.16235,226.87083 188.43343,225.30687 184.54317,225.31697 C 180.65291,225.32708 176.93217,226.9104 174.22754,229.70669 L 174.22754,229.70669 z"
522 id="path3179" />
523 <path
524 sodipodi:type="arc"
525 style="fill:#ffffff;fill-opacity:1;stroke-width:124.98212864999999283;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;display:inline;opacity:0.87;color:#000000;fill-rule:evenodd;stroke:none;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;overflow:visible;enable-background:accumulate"
526 id="path3181"
527 sodipodi:cx="70"
528 sodipodi:cy="40"
529 sodipodi:rx="30"
530 sodipodi:ry="30"
531 d="M 100,40 A 30,30 0 1 1 40,40 A 30,30 0 1 1 100,40 z"
532 transform="matrix(0.3387513,-0.3401668,0.3401668,0.3387513,55.827163,274.10463)" />
533 <path
534 transform="matrix(0.3387513,-0.3401668,0.3401668,0.3387513,113.41488,216.27627)"
535 d="M 100,40 A 30,30 0 1 1 40,40 A 30,30 0 1 1 100,40 z"
536 sodipodi:ry="30"
537 sodipodi:rx="30"
538 sodipodi:cy="40"
539 sodipodi:cx="70"
540 id="path3183"
541 style="fill:#ffffff;fill-opacity:1;stroke-width:124.98212864999999283;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;display:inline;opacity:0.87;color:#000000;fill-rule:evenodd;stroke:none;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;overflow:visible;enable-background:accumulate"
542 sodipodi:type="arc" />
543 <path
544 sodipodi:type="arc"
545 style="fill:#ffffff;fill-opacity:1;stroke-width:124.98212864999999283;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;display:inline;opacity:0.87;color:#000000;fill-rule:evenodd;stroke:none;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;overflow:visible;enable-background:accumulate"
546 id="path3185"
547 sodipodi:cx="70"
548 sodipodi:cy="40"
549 sodipodi:rx="30"
550 sodipodi:ry="30"
551 d="M 100,40 A 30,30 0 1 1 40,40 A 30,30 0 1 1 100,40 z"
552 transform="matrix(0.3387513,-0.3401668,0.3401668,0.3387513,172.69636,156.74708)" />
553 </g>
554 </svg>
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_append_flag.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_APPEND_FLAG(FLAG, [FLAGS-VARIABLE])
7 #
8 # DESCRIPTION
9 #
10 # FLAG is appended to the FLAGS-VARIABLE shell variable, with a space
11 # added in between.
12 #
13 # If FLAGS-VARIABLE is not specified, the current language's flags (e.g.
14 # CFLAGS) is used. FLAGS-VARIABLE is not changed if it already contains
15 # FLAG. If FLAGS-VARIABLE is unset in the shell, it is set to exactly
16 # FLAG.
17 #
18 # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION.
19 #
20 # LICENSE
21 #
22 # Copyright (c) 2008 Guido U. Draheim <[email protected]>
23 # Copyright (c) 2011 Maarten Bosmans <[email protected]>
24 #
25 # This program is free software: you can redistribute it and/or modify it
26 # under the terms of the GNU General Public License as published by the
27 # Free Software Foundation, either version 3 of the License, or (at your
28 # option) any later version.
29 #
30 # This program is distributed in the hope that it will be useful, but
31 # WITHOUT ANY WARRANTY; without even the implied warranty of
32 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
33 # Public License for more details.
34 #
35 # You should have received a copy of the GNU General Public License along
36 # with this program. If not, see <http://www.gnu.org/licenses/>.
37 #
38 # As a special exception, the respective Autoconf Macro's copyright owner
39 # gives unlimited permission to copy, distribute and modify the configure
40 # scripts that are the output of Autoconf when processing the Macro. You
41 # need not follow the terms of the GNU General Public License when using
42 # or distributing such scripts, even though portions of the text of the
43 # Macro appear in them. The GNU General Public License (GPL) does govern
44 # all other use of the material that constitutes the Autoconf Macro.
45 #
46 # This special exception to the GPL applies to versions of the Autoconf
47 # Macro released by the Autoconf Archive. When you make and distribute a
48 # modified version of the Autoconf Macro, you may extend this special
49 # exception to the GPL to apply to your modified version as well.
50
51 #serial 6
52
53 AC_DEFUN([AX_APPEND_FLAG],
54 [dnl
55 AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_SET_IF
56 AS_VAR_PUSHDEF([FLAGS], [m4_default($2,_AC_LANG_PREFIX[FLAGS])])
57 AS_VAR_SET_IF(FLAGS,[
58 AS_CASE([" AS_VAR_GET(FLAGS) "],
59 [*" $1 "*], [AC_RUN_LOG([: FLAGS already contains $1])],
60 [
61 AS_VAR_APPEND(FLAGS,[" $1"])
62 AC_RUN_LOG([: FLAGS="$FLAGS"])
63 ])
64 ],
65 [
66 AS_VAR_SET(FLAGS,[$1])
67 AC_RUN_LOG([: FLAGS="$FLAGS"])
68 ])
69 AS_VAR_POPDEF([FLAGS])dnl
70 ])dnl AX_APPEND_FLAG
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_cflags_warn_all.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_CFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
7 # AX_CXXFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
8 # AX_FCFLAGS_WARN_ALL [(shellvar [,default, [A/NA]])]
9 #
10 # DESCRIPTION
11 #
12 # Try to find a compiler option that enables most reasonable warnings.
13 #
14 # For the GNU compiler it will be -Wall (and -ansi -pedantic) The result
15 # is added to the shellvar being CFLAGS, CXXFLAGS, or FCFLAGS by default.
16 #
17 # Currently this macro knows about the GCC, Solaris, Digital Unix, AIX,
18 # HP-UX, IRIX, NEC SX-5 (Super-UX 10), Cray J90 (Unicos 10.0.0.8), and
19 # Intel compilers. For a given compiler, the Fortran flags are much more
20 # experimental than their C equivalents.
21 #
22 # - $1 shell-variable-to-add-to : CFLAGS, CXXFLAGS, or FCFLAGS
23 # - $2 add-value-if-not-found : nothing
24 # - $3 action-if-found : add value to shellvariable
25 # - $4 action-if-not-found : nothing
26 #
27 # NOTE: These macros depend on AX_APPEND_FLAG.
28 #
29 # LICENSE
30 #
31 # Copyright (c) 2008 Guido U. Draheim <[email protected]>
32 # Copyright (c) 2010 Rhys Ulerich <[email protected]>
33 #
34 # This program is free software; you can redistribute it and/or modify it
35 # under the terms of the GNU General Public License as published by the
36 # Free Software Foundation; either version 3 of the License, or (at your
37 # option) any later version.
38 #
39 # This program is distributed in the hope that it will be useful, but
40 # WITHOUT ANY WARRANTY; without even the implied warranty of
41 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
42 # Public License for more details.
43 #
44 # You should have received a copy of the GNU General Public License along
45 # with this program. If not, see <http://www.gnu.org/licenses/>.
46 #
47 # As a special exception, the respective Autoconf Macro's copyright owner
48 # gives unlimited permission to copy, distribute and modify the configure
49 # scripts that are the output of Autoconf when processing the Macro. You
50 # need not follow the terms of the GNU General Public License when using
51 # or distributing such scripts, even though portions of the text of the
52 # Macro appear in them. The GNU General Public License (GPL) does govern
53 # all other use of the material that constitutes the Autoconf Macro.
54 #
55 # This special exception to the GPL applies to versions of the Autoconf
56 # Macro released by the Autoconf Archive. When you make and distribute a
57 # modified version of the Autoconf Macro, you may extend this special
58 # exception to the GPL to apply to your modified version as well.
59
60 #serial 15
61
62 AC_DEFUN([AX_FLAGS_WARN_ALL],[dnl
63 AS_VAR_PUSHDEF([FLAGS],[_AC_LANG_PREFIX[]FLAGS])dnl
64 AS_VAR_PUSHDEF([VAR],[ac_cv_[]_AC_LANG_ABBREV[]flags_warn_all])dnl
65 AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for maximum warnings],
66 VAR,[VAR="no, unknown"
67 ac_save_[]FLAGS="$[]FLAGS"
68 for ac_arg dnl
69 in "-warn all % -warn all" dnl Intel
70 "-pedantic % -Wall" dnl GCC
71 "-xstrconst % -v" dnl Solaris C
72 "-std1 % -verbose -w0 -warnprotos" dnl Digital Unix
73 "-qlanglvl=ansi % -qsrcmsg -qinfo=all:noppt:noppc:noobs:nocnd" dnl AIX
74 "-ansi -ansiE % -fullwarn" dnl IRIX
75 "+ESlit % +w1" dnl HP-UX C
76 "-Xc % -pvctl[,]fullmsg" dnl NEC SX-5 (Super-UX 10)
77 "-h conform % -h msglevel 2" dnl Cray C (Unicos)
78 #
79 do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'`
80 AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
81 [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break])
82 done
83 FLAGS="$ac_save_[]FLAGS"
84 ])
85 AS_VAR_POPDEF([FLAGS])dnl
86 AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
87 case ".$VAR" in
88 .ok|.ok,*) m4_ifvaln($3,$3) ;;
89 .|.no|.no,*) m4_default($4,[m4_ifval($2,[AX_APPEND_FLAG([$2], [$1])])]) ;;
90 *) m4_default($3,[AX_APPEND_FLAG([$VAR], [$1])]) ;;
91 esac
92 AS_VAR_POPDEF([VAR])dnl
93 ])dnl AX_FLAGS_WARN_ALL
94 dnl implementation tactics:
95 dnl the for-argument contains a list of options. The first part of
96 dnl these does only exist to detect the compiler - usually it is
97 dnl a global option to enable -ansi or -extrawarnings. All other
98 dnl compilers will fail about it. That was needed since a lot of
99 dnl compilers will give false positives for some option-syntax
100 dnl like -Woption or -Xoption as they think of it is a pass-through
101 dnl to later compile stages or something. The "%" is used as a
102 dnl delimiter. A non-option comment can be given after "%%" marks
103 dnl which will be shown but not added to the respective C/CXXFLAGS.
104
105 AC_DEFUN([AX_CFLAGS_WARN_ALL],[dnl
106 AC_LANG_PUSH([C])
107 AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
108 AC_LANG_POP([C])
109 ])
110
111 AC_DEFUN([AX_CXXFLAGS_WARN_ALL],[dnl
112 AC_LANG_PUSH([C++])
113 AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
114 AC_LANG_POP([C++])
115 ])
116
117 AC_DEFUN([AX_FCFLAGS_WARN_ALL],[dnl
118 AC_LANG_PUSH([Fortran])
119 AX_FLAGS_WARN_ALL([$1], [$2], [$3], [$4])
120 AC_LANG_POP([Fortran])
121 ])
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
7 #
8 # DESCRIPTION
9 #
10 # Check whether the given FLAG works with the current language's compiler
11 # or gives an error. (Warnings, however, are ignored)
12 #
13 # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
14 # success/failure.
15 #
16 # If EXTRA-FLAGS is defined, it is added to the current language's default
17 # flags (e.g. CFLAGS) when the check is done. The check is thus made with
18 # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
19 # force the compiler to issue an error when a bad flag is given.
20 #
21 # INPUT gives an alternative input source to AC_COMPILE_IFELSE.
22 #
23 # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
24 # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
25 #
26 # LICENSE
27 #
28 # Copyright (c) 2008 Guido U. Draheim <[email protected]>
29 # Copyright (c) 2011 Maarten Bosmans <[email protected]>
30 #
31 # This program is free software: you can redistribute it and/or modify it
32 # under the terms of the GNU General Public License as published by the
33 # Free Software Foundation, either version 3 of the License, or (at your
34 # option) any later version.
35 #
36 # This program is distributed in the hope that it will be useful, but
37 # WITHOUT ANY WARRANTY; without even the implied warranty of
38 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
39 # Public License for more details.
40 #
41 # You should have received a copy of the GNU General Public License along
42 # with this program. If not, see <http://www.gnu.org/licenses/>.
43 #
44 # As a special exception, the respective Autoconf Macro's copyright owner
45 # gives unlimited permission to copy, distribute and modify the configure
46 # scripts that are the output of Autoconf when processing the Macro. You
47 # need not follow the terms of the GNU General Public License when using
48 # or distributing such scripts, even though portions of the text of the
49 # Macro appear in them. The GNU General Public License (GPL) does govern
50 # all other use of the material that constitutes the Autoconf Macro.
51 #
52 # This special exception to the GPL applies to versions of the Autoconf
53 # Macro released by the Autoconf Archive. When you make and distribute a
54 # modified version of the Autoconf Macro, you may extend this special
55 # exception to the GPL to apply to your modified version as well.
56
57 #serial 4
58
59 AC_DEFUN([AX_CHECK_COMPILE_FLAG],
60 [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
61 AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
62 AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
63 ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
64 _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
65 AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
66 [AS_VAR_SET(CACHEVAR,[yes])],
67 [AS_VAR_SET(CACHEVAR,[no])])
68 _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
69 AS_VAR_IF(CACHEVAR,yes,
70 [m4_default([$2], :)],
71 [m4_default([$3], :)])
72 AS_VAR_POPDEF([CACHEVAR])dnl
73 ])dnl AX_CHECK_COMPILE_FLAGS
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_check_enable_debug.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_CHECK_ENABLE_DEBUG([enable by default=yes/info/profile/no], [ENABLE DEBUG VARIABLES ...], [DISABLE DEBUG VARIABLES NDEBUG ...], [IS-RELEASE])
7 #
8 # DESCRIPTION
9 #
10 # Check for the presence of an --enable-debug option to configure, with
11 # the specified default value used when the option is not present. Return
12 # the value in the variable $ax_enable_debug.
13 #
14 # Specifying 'yes' adds '-g -O0' to the compilation flags for all
15 # languages. Specifying 'info' adds '-g' to the compilation flags.
16 # Specifying 'profile' adds '-g -pg' to the compilation flags and '-pg' to
17 # the linking flags. Otherwise, nothing is added.
18 #
19 # Define the variables listed in the second argument if debug is enabled,
20 # defaulting to no variables. Defines the variables listed in the third
21 # argument if debug is disabled, defaulting to NDEBUG. All lists of
22 # variables should be space-separated.
23 #
24 # If debug is not enabled, ensure AC_PROG_* will not add debugging flags.
25 # Should be invoked prior to any AC_PROG_* compiler checks.
26 #
27 # IS-RELEASE can be used to change the default to 'no' when making a
28 # release. Set IS-RELEASE to 'yes' or 'no' as appropriate. By default, it
29 # uses the value of $ax_is_release, so if you are using the AX_IS_RELEASE
30 # macro, there is no need to pass this parameter.
31 #
32 # AX_IS_RELEASE([git-directory])
33 # AX_CHECK_ENABLE_DEBUG()
34 #
35 # LICENSE
36 #
37 # Copyright (c) 2011 Rhys Ulerich <[email protected]>
38 # Copyright (c) 2014, 2015 Philip Withnall <[email protected]>
39 #
40 # Copying and distribution of this file, with or without modification, are
41 # permitted in any medium without royalty provided the copyright notice
42 # and this notice are preserved.
43
44 #serial 5
45
46 AC_DEFUN([AX_CHECK_ENABLE_DEBUG],[
47 AC_BEFORE([$0],[AC_PROG_CC])dnl
48 AC_BEFORE([$0],[AC_PROG_CXX])dnl
49 AC_BEFORE([$0],[AC_PROG_F77])dnl
50 AC_BEFORE([$0],[AC_PROG_FC])dnl
51
52 AC_MSG_CHECKING(whether to enable debugging)
53
54 ax_enable_debug_default=m4_tolower(m4_normalize(ifelse([$1],,[no],[$1])))
55 ax_enable_debug_is_release=m4_tolower(m4_normalize(ifelse([$4],,
56 [$ax_is_release],
57 [$4])))
58
59 # If this is a release, override the default.
60 AS_IF([test "$ax_enable_debug_is_release" = "yes"],
61 [ax_enable_debug_default="no"])
62
63 m4_define(ax_enable_debug_vars,[m4_normalize(ifelse([$2],,,[$2]))])
64 m4_define(ax_disable_debug_vars,[m4_normalize(ifelse([$3],,[NDEBUG],[$3]))])
65
66 AC_ARG_ENABLE(debug,
67 [AS_HELP_STRING([--enable-debug=]@<:@yes/info/profile/no@:>@,[compile with debugging])],
68 [],enable_debug=$ax_enable_debug_default)
69
70 # empty mean debug yes
71 AS_IF([test "x$enable_debug" = "x"],
72 [enable_debug="yes"])
73
74 # case of debug
75 AS_CASE([$enable_debug],
76 [yes],[
77 AC_MSG_RESULT(yes)
78 CFLAGS="${CFLAGS} -g -O0"
79 CXXFLAGS="${CXXFLAGS} -g -O0"
80 FFLAGS="${FFLAGS} -g -O0"
81 FCFLAGS="${FCFLAGS} -g -O0"
82 OBJCFLAGS="${OBJCFLAGS} -g -O0"
83 ],
84 [info],[
85 AC_MSG_RESULT(info)
86 CFLAGS="${CFLAGS} -g"
87 CXXFLAGS="${CXXFLAGS} -g"
88 FFLAGS="${FFLAGS} -g"
89 FCFLAGS="${FCFLAGS} -g"
90 OBJCFLAGS="${OBJCFLAGS} -g"
91 ],
92 [profile],[
93 AC_MSG_RESULT(profile)
94 CFLAGS="${CFLAGS} -g -pg"
95 CXXFLAGS="${CXXFLAGS} -g -pg"
96 FFLAGS="${FFLAGS} -g -pg"
97 FCFLAGS="${FCFLAGS} -g -pg"
98 OBJCFLAGS="${OBJCFLAGS} -g -pg"
99 LDFLAGS="${LDFLAGS} -pg"
100 ],
101 [
102 AC_MSG_RESULT(no)
103 dnl Ensure AC_PROG_CC/CXX/F77/FC/OBJC will not enable debug flags
104 dnl by setting any unset environment flag variables
105 AS_IF([test "x${CFLAGS+set}" != "xset"],
106 [CFLAGS=""])
107 AS_IF([test "x${CXXFLAGS+set}" != "xset"],
108 [CXXFLAGS=""])
109 AS_IF([test "x${FFLAGS+set}" != "xset"],
110 [FFLAGS=""])
111 AS_IF([test "x${FCFLAGS+set}" != "xset"],
112 [FCFLAGS=""])
113 AS_IF([test "x${OBJCFLAGS+set}" != "xset"],
114 [OBJCFLAGS=""])
115 ])
116
117 dnl Define various variables if debugging is disabled.
118 dnl assert.h is a NOP if NDEBUG is defined, so define it by default.
119 AS_IF([test "x$enable_debug" = "xyes"],
120 [m4_map_args_w(ax_enable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is enabled])])],
121 [m4_map_args_w(ax_disable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is disabled])])])
122 ax_enable_debug=$enable_debug
123 ])
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_check_gnu_make.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_CHECK_GNU_MAKE()
7 #
8 # DESCRIPTION
9 #
10 # This macro searches for a GNU version of make. If a match is found:
11 #
12 # * The makefile variable `ifGNUmake' is set to the empty string, otherwise
13 # it is set to "#". This is useful for including a special features in a
14 # Makefile, which cannot be handled by other versions of make.
15 # * The variable `_cv_gnu_make_command` is set to the command to invoke
16 # GNU make if it exists, the empty string otherwise.
17 # * The variable `ax_cv_gnu_make_command` is set to the command to invoke
18 # GNU make by copying `_cv_gnu_make_command`, otherwise it is unset.
19 # * If GNU Make is found, its version is extracted from the output of
20 # `make --version` as the last field of a record of space-separated
21 # columns and saved into the variable `ax_check_gnu_make_version`.
22 #
23 # Here is an example of its use:
24 #
25 # Makefile.in might contain:
26 #
27 # # A failsafe way of putting a dependency rule into a makefile
28 # $(DEPEND):
29 # $(CC) -MM $(srcdir)/*.c > $(DEPEND)
30 #
31 # @ifGNUmake@ ifeq ($(DEPEND),$(wildcard $(DEPEND)))
32 # @ifGNUmake@ include $(DEPEND)
33 # @ifGNUmake@ endif
34 #
35 # Then configure.in would normally contain:
36 #
37 # AX_CHECK_GNU_MAKE()
38 # AC_OUTPUT(Makefile)
39 #
40 # Then perhaps to cause gnu make to override any other make, we could do
41 # something like this (note that GNU make always looks for GNUmakefile
42 # first):
43 #
44 # if ! test x$_cv_gnu_make_command = x ; then
45 # mv Makefile GNUmakefile
46 # echo .DEFAULT: > Makefile ;
47 # echo \ $_cv_gnu_make_command \$@ >> Makefile;
48 # fi
49 #
50 # Then, if any (well almost any) other make is called, and GNU make also
51 # exists, then the other make wraps the GNU make.
52 #
53 # LICENSE
54 #
55 # Copyright (c) 2008 John Darrington <[email protected]>
56 # Copyright (c) 2015 Enrico M. Crisostomo <[email protected]>
57 #
58 # Copying and distribution of this file, with or without modification, are
59 # permitted in any medium without royalty provided the copyright notice
60 # and this notice are preserved. This file is offered as-is, without any
61 # warranty.
62
63 #serial 8
64
65 AC_DEFUN([AX_CHECK_GNU_MAKE],dnl
66 [AC_PROG_AWK
67 AC_CACHE_CHECK([for GNU make],[_cv_gnu_make_command],[dnl
68 _cv_gnu_make_command="" ;
69 dnl Search all the common names for GNU make
70 for a in "$MAKE" make gmake gnumake ; do
71 if test -z "$a" ; then continue ; fi ;
72 if "$a" --version 2> /dev/null | grep GNU 2>&1 > /dev/null ; then
73 _cv_gnu_make_command=$a ;
74 AX_CHECK_GNU_MAKE_HEADLINE=$("$a" --version 2> /dev/null | grep "GNU Make")
75 ax_check_gnu_make_version=$(echo ${AX_CHECK_GNU_MAKE_HEADLINE} | ${AWK} -F " " '{ print $(NF); }')
76 break ;
77 fi
78 done ;])
79 dnl If there was a GNU version, then set @ifGNUmake@ to the empty string, '#' otherwise
80 AS_VAR_IF([_cv_gnu_make_command], [""], [AS_VAR_SET([ifGNUmake], ["#"])], [AS_VAR_SET([ifGNUmake], [""])])
81 AS_VAR_IF([_cv_gnu_make_command], [""], [AS_UNSET(ax_cv_gnu_make_command)], [AS_VAR_SET([ax_cv_gnu_make_command], [${_cv_gnu_make_command}])])
82 AC_SUBST([ifGNUmake])
83 ])
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
7 #
8 # DESCRIPTION
9 #
10 # Check whether the given FLAG works with the linker or gives an error.
11 # (Warnings, however, are ignored)
12 #
13 # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
14 # success/failure.
15 #
16 # If EXTRA-FLAGS is defined, it is added to the linker's default flags
17 # when the check is done. The check is thus made with the flags: "LDFLAGS
18 # EXTRA-FLAGS FLAG". This can for example be used to force the linker to
19 # issue an error when a bad flag is given.
20 #
21 # INPUT gives an alternative input source to AC_LINK_IFELSE.
22 #
23 # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
24 # macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
25 #
26 # LICENSE
27 #
28 # Copyright (c) 2008 Guido U. Draheim <[email protected]>
29 # Copyright (c) 2011 Maarten Bosmans <[email protected]>
30 #
31 # This program is free software: you can redistribute it and/or modify it
32 # under the terms of the GNU General Public License as published by the
33 # Free Software Foundation, either version 3 of the License, or (at your
34 # option) any later version.
35 #
36 # This program is distributed in the hope that it will be useful, but
37 # WITHOUT ANY WARRANTY; without even the implied warranty of
38 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
39 # Public License for more details.
40 #
41 # You should have received a copy of the GNU General Public License along
42 # with this program. If not, see <http://www.gnu.org/licenses/>.
43 #
44 # As a special exception, the respective Autoconf Macro's copyright owner
45 # gives unlimited permission to copy, distribute and modify the configure
46 # scripts that are the output of Autoconf when processing the Macro. You
47 # need not follow the terms of the GNU General Public License when using
48 # or distributing such scripts, even though portions of the text of the
49 # Macro appear in them. The GNU General Public License (GPL) does govern
50 # all other use of the material that constitutes the Autoconf Macro.
51 #
52 # This special exception to the GPL applies to versions of the Autoconf
53 # Macro released by the Autoconf Archive. When you make and distribute a
54 # modified version of the Autoconf Macro, you may extend this special
55 # exception to the GPL to apply to your modified version as well.
56
57 #serial 4
58
59 AC_DEFUN([AX_CHECK_LINK_FLAG],
60 [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF
61 AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
62 AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
63 ax_check_save_flags=$LDFLAGS
64 LDFLAGS="$LDFLAGS $4 $1"
65 AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
66 [AS_VAR_SET(CACHEVAR,[yes])],
67 [AS_VAR_SET(CACHEVAR,[no])])
68 LDFLAGS=$ax_check_save_flags])
69 AS_VAR_IF(CACHEVAR,yes,
70 [m4_default([$2], :)],
71 [m4_default([$3], :)])
72 AS_VAR_POPDEF([CACHEVAR])dnl
73 ])dnl AX_CHECK_LINK_FLAGS
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_CODE_COVERAGE()
7 #
8 # DESCRIPTION
9 #
10 # Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS,
11 # CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LDFLAGS which should be
12 # included in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LDFLAGS variables of
13 # every build target (program or library) which should be built with code
14 # coverage support. Also defines CODE_COVERAGE_RULES which should be
15 # substituted in your Makefile; and $enable_code_coverage which can be
16 # used in subsequent configure output. CODE_COVERAGE_ENABLED is defined
17 # and substituted, and corresponds to the value of the
18 # --enable-code-coverage option, which defaults to being disabled.
19 #
20 # Test also for gcov program and create GCOV variable that could be
21 # substituted.
22 #
23 # Note that all optimisation flags in CFLAGS must be disabled when code
24 # coverage is enabled.
25 #
26 # Usage example:
27 #
28 # configure.ac:
29 #
30 # AX_CODE_COVERAGE
31 #
32 # Makefile.am:
33 #
34 # @CODE_COVERAGE_RULES@
35 # my_program_LIBS = ... $(CODE_COVERAGE_LDFLAGS) ...
36 # my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ...
37 # my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ...
38 # my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ...
39 #
40 # This results in a "check-code-coverage" rule being added to any
41 # Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module
42 # has been configured with --enable-code-coverage). Running `make
43 # check-code-coverage` in that directory will run the module's test suite
44 # (`make check`) and build a code coverage report detailing the code which
45 # was touched, then print the URI for the report.
46 #
47 # This code was derived from Makefile.decl in GLib, originally licenced
48 # under LGPLv2.1+.
49 #
50 # LICENSE
51 #
52 # Copyright (c) 2012, 2016 Philip Withnall
53 # Copyright (c) 2012 Xan Lopez
54 # Copyright (c) 2012 Christian Persch
55 # Copyright (c) 2012 Paolo Borelli
56 # Copyright (c) 2012 Dan Winship
57 # Copyright (c) 2015 Bastien ROUCARIES
58 #
59 # This library is free software; you can redistribute it and/or modify it
60 # under the terms of the GNU Lesser General Public License as published by
61 # the Free Software Foundation; either version 2.1 of the License, or (at
62 # your option) any later version.
63 #
64 # This library is distributed in the hope that it will be useful, but
65 # WITHOUT ANY WARRANTY; without even the implied warranty of
66 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
67 # General Public License for more details.
68 #
69 # You should have received a copy of the GNU Lesser General Public License
70 # along with this program. If not, see <http://www.gnu.org/licenses/>.
71
72 #serial 15
73
74 AC_DEFUN([AX_CODE_COVERAGE],[
75 dnl Check for --enable-code-coverage
76 AC_REQUIRE([AC_PROG_SED])
77
78 # allow to override gcov location
79 AC_ARG_WITH([gcov],
80 [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])],
81 [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov],
82 [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov])
83
84 AC_MSG_CHECKING([whether to build with code coverage support])
85 AC_ARG_ENABLE([code-coverage],
86 AS_HELP_STRING([--enable-code-coverage],
87 [Whether to enable code coverage support]),,
88 enable_code_coverage=no)
89
90 AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes])
91 AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage])
92 AC_MSG_RESULT($enable_code_coverage)
93
94 AS_IF([ test "$enable_code_coverage" = "yes" ], [
95 # check for gcov
96 AC_CHECK_TOOL([GCOV],
97 [$_AX_CODE_COVERAGE_GCOV_PROG_WITH],
98 [:])
99 AS_IF([test "X$GCOV" = "X:"],
100 [AC_MSG_ERROR([gcov is needed to do coverage])])
101 AC_SUBST([GCOV])
102
103 dnl Check if gcc is being used
104 AS_IF([ test "$GCC" = "no" ], [
105 AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage])
106 ])
107
108 # List of supported lcov versions.
109 lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11 1.12 1.13"
110
111 AC_CHECK_PROG([LCOV], [lcov], [lcov])
112 AC_CHECK_PROG([GENHTML], [genhtml], [genhtml])
113
114 AS_IF([ test "$LCOV" ], [
115 AC_CACHE_CHECK([for lcov version], ax_cv_lcov_version, [
116 ax_cv_lcov_version=invalid
117 lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'`
118 for lcov_check_version in $lcov_version_list; do
119 if test "$lcov_version" = "$lcov_check_version"; then
120 ax_cv_lcov_version="$lcov_check_version (ok)"
121 fi
122 done
123 ])
124 ], [
125 lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list"
126 AC_MSG_ERROR([$lcov_msg])
127 ])
128
129 case $ax_cv_lcov_version in
130 ""|invalid[)]
131 lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)."
132 AC_MSG_ERROR([$lcov_msg])
133 LCOV="exit 0;"
134 ;;
135 esac
136
137 AS_IF([ test -z "$GENHTML" ], [
138 AC_MSG_ERROR([Could not find genhtml from the lcov package])
139 ])
140
141 dnl Build the code coverage flags
142 CODE_COVERAGE_CPPFLAGS="-DNDEBUG"
143 CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
144 CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
145 CODE_COVERAGE_LDFLAGS="-lgcov"
146
147 AC_SUBST([CODE_COVERAGE_CPPFLAGS])
148 AC_SUBST([CODE_COVERAGE_CFLAGS])
149 AC_SUBST([CODE_COVERAGE_CXXFLAGS])
150 AC_SUBST([CODE_COVERAGE_LDFLAGS])
151 ])
152
153 [CODE_COVERAGE_RULES='
154 # Code coverage
155 #
156 # Optional:
157 # - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting.
158 # Multiple directories may be specified, separated by whitespace.
159 # (Default: $(top_builddir))
160 # - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated
161 # by lcov for code coverage. (Default:
162 # $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info)
163 # - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage
164 # reports to be created. (Default:
165 # $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage)
166 # - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage,
167 # set to 0 to disable it and leave empty to stay with the default.
168 # (Default: empty)
169 # - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov
170 # instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
171 # - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov
172 # instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
173 # - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov
174 # - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the
175 # collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
176 # - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov
177 # instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
178 # - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering
179 # lcov instance. (Default: empty)
180 # - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov
181 # instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
182 # - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the
183 # genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
184 # - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml
185 # instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT)
186 # - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore
187 #
188 # The generated report will be titled using the $(PACKAGE_NAME) and
189 # $(PACKAGE_VERSION). In order to add the current git hash to the title,
190 # use the git-version-gen script, available online.
191
192 # Optional variables
193 CODE_COVERAGE_DIRECTORY ?= $(top_builddir)
194 CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info
195 CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage
196 CODE_COVERAGE_BRANCH_COVERAGE ?=
197 CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
198 --rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
199 CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
200 CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)"
201 CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
202 CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
203 CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?=
204 CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
205 CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\
206 $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
207 --rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
208 CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS)
209 CODE_COVERAGE_IGNORE_PATTERN ?=
210
211 code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V))
212 code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY))
213 code_coverage_v_lcov_cap_0 = @echo " LCOV --capture"\
214 $(CODE_COVERAGE_OUTPUT_FILE);
215 code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V))
216 code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY))
217 code_coverage_v_lcov_ign_0 = @echo " LCOV --remove /tmp/*"\
218 $(CODE_COVERAGE_IGNORE_PATTERN);
219 code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V))
220 code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY))
221 code_coverage_v_genhtml_0 = @echo " GEN " $(CODE_COVERAGE_OUTPUT_DIRECTORY);
222 code_coverage_quiet = $(code_coverage_quiet_$(V))
223 code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY))
224 code_coverage_quiet_0 = --quiet
225
226 # sanitizes the test-name: replaces with underscores: dashes and dots
227 code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1)))
228
229 # Use recursive makes in order to ignore errors during check
230 check-code-coverage:
231 ifeq ($(CODE_COVERAGE_ENABLED),yes)
232 -$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check
233 $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture
234 else
235 @echo "Need to reconfigure with --enable-code-coverage"
236 endif
237
238 # Capture code coverage data
239 code-coverage-capture: code-coverage-capture-hook
240 ifeq ($(CODE_COVERAGE_ENABLED),yes)
241 $(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS)
242 $(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS)
243 -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp
244 $(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS)
245 @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html"
246 else
247 @echo "Need to reconfigure with --enable-code-coverage"
248 endif
249
250 # Hook rule executed before code-coverage-capture, overridable by the user
251 code-coverage-capture-hook:
252
253 ifeq ($(CODE_COVERAGE_ENABLED),yes)
254 clean: code-coverage-clean
255 code-coverage-clean:
256 -$(LCOV) --directory $(top_builddir) -z
257 -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY)
258 -find . -name "*.gcda" -o -name "*.gcov" -delete
259 endif
260
261 GITIGNOREFILES ?=
262 GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY)
263
264 A''M_DISTCHECK_CONFIGURE_FLAGS ?=
265 A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage
266
267 .PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean
268 ']
269
270 AC_SUBST([CODE_COVERAGE_RULES])
271 m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])])
272 ])
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_configure_args.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_CONFIGURE_ARGS
7 #
8 # DESCRIPTION
9 #
10 # Helper macro for AX_ENABLE_BUILDDIR.
11 #
12 # The traditional way of starting a subdir-configure is running the script
13 # with ${1+"$@"} but since autoconf 2.60 this is broken. Instead we have
14 # to rely on eval'ing $ac_configure_args however some old autoconf
15 # versions do not provide that. To ensure maximum portability of autoconf
16 # extension macros this helper can be AC_REQUIRE'd so that
17 # $ac_configure_args will alsways be present.
18 #
19 # Sadly, the traditional "exec $SHELL" of the enable_builddir macros is
20 # spoiled now and must be replaced by "eval + exit $?".
21 #
22 # Example:
23 #
24 # AC_DEFUN([AX_ENABLE_SUBDIR],[dnl
25 # AC_REQUIRE([AX_CONFIGURE_ARGS])dnl
26 # eval $SHELL $ac_configure_args || exit $?
27 # ...])
28 #
29 # LICENSE
30 #
31 # Copyright (c) 2008 Guido U. Draheim <[email protected]>
32 #
33 # This program is free software; you can redistribute it and/or modify it
34 # under the terms of the GNU General Public License as published by the
35 # Free Software Foundation; either version 3 of the License, or (at your
36 # option) any later version.
37 #
38 # This program is distributed in the hope that it will be useful, but
39 # WITHOUT ANY WARRANTY; without even the implied warranty of
40 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
41 # Public License for more details.
42 #
43 # You should have received a copy of the GNU General Public License along
44 # with this program. If not, see <http://www.gnu.org/licenses/>.
45 #
46 # As a special exception, the respective Autoconf Macro's copyright owner
47 # gives unlimited permission to copy, distribute and modify the configure
48 # scripts that are the output of Autoconf when processing the Macro. You
49 # need not follow the terms of the GNU General Public License when using
50 # or distributing such scripts, even though portions of the text of the
51 # Macro appear in them. The GNU General Public License (GPL) does govern
52 # all other use of the material that constitutes the Autoconf Macro.
53 #
54 # This special exception to the GPL applies to versions of the Autoconf
55 # Macro released by the Autoconf Archive. When you make and distribute a
56 # modified version of the Autoconf Macro, you may extend this special
57 # exception to the GPL to apply to your modified version as well.
58
59 #serial 9
60
61 AC_DEFUN([AX_CONFIGURE_ARGS],[
62 # [$]@ is unsable in 2.60+ but earlier autoconf had no ac_configure_args
63 if test "${ac_configure_args+set}" != "set" ; then
64 ac_configure_args=
65 for ac_arg in ${1+"[$]@"}; do
66 ac_configure_args="$ac_configure_args '$ac_arg'"
67 done
68 fi
69 ])
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_enable_builddir.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_ENABLE_BUILDDIR [(dirstring-or-command [,Makefile.mk [,-all]])]
7 #
8 # DESCRIPTION
9 #
10 # If the current configure was run within the srcdir then we move all
11 # configure-files into a subdir and let the configure steps continue
12 # there. We provide an option --disable-builddir to suppress the move into
13 # a separate builddir.
14 #
15 # Defaults:
16 #
17 # $1 = $host (overridden with $HOST)
18 # $2 = Makefile.mk
19 # $3 = -all
20 #
21 # This macro must be called before AM_INIT_AUTOMAKE. It creates a default
22 # toplevel srcdir Makefile from the information found in the created
23 # toplevel builddir Makefile. It just copies the variables and
24 # rule-targets, each extended with a default rule-execution that recurses
25 # into the build directory of the current "HOST". You can override the
26 # auto-dection through `config.guess` and build-time of course, as in
27 #
28 # make HOST=i386-mingw-cross
29 #
30 # which can of course set at configure time as well using
31 #
32 # configure --host=i386-mingw-cross
33 #
34 # After the default has been created, additional rules can be appended
35 # that will not just recurse into the subdirectories and only ever exist
36 # in the srcdir toplevel makefile - these parts are read from the $2 =
37 # Makefile.mk file
38 #
39 # The automatic rules are usually scanning the toplevel Makefile for lines
40 # like '#### $host |$builddir' to recognize the place where to recurse
41 # into. Usually, the last one is the only one used. However, almost all
42 # targets have an additional "*-all" rule which makes the script to
43 # recurse into _all_ variants of the current HOST (!!) setting. The "-all"
44 # suffix can be overriden for the macro as well.
45 #
46 # a special rule is only given for things like "dist" that will copy the
47 # tarball from the builddir to the sourcedir (or $(PUB)) for reason of
48 # convenience.
49 #
50 # LICENSE
51 #
52 # Copyright (c) 2009 Guido U. Draheim <[email protected]>
53 # Copyright (c) 2009 Alan Jenkins <[email protected]>
54 #
55 # This program is free software; you can redistribute it and/or modify it
56 # under the terms of the GNU General Public License as published by the
57 # Free Software Foundation; either version 3 of the License, or (at your
58 # option) any later version.
59 #
60 # This program is distributed in the hope that it will be useful, but
61 # WITHOUT ANY WARRANTY; without even the implied warranty of
62 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
63 # Public License for more details.
64 #
65 # You should have received a copy of the GNU General Public License along
66 # with this program. If not, see <http://www.gnu.org/licenses/>.
67 #
68 # As a special exception, the respective Autoconf Macro's copyright owner
69 # gives unlimited permission to copy, distribute and modify the configure
70 # scripts that are the output of Autoconf when processing the Macro. You
71 # need not follow the terms of the GNU General Public License when using
72 # or distributing such scripts, even though portions of the text of the
73 # Macro appear in them. The GNU General Public License (GPL) does govern
74 # all other use of the material that constitutes the Autoconf Macro.
75 #
76 # This special exception to the GPL applies to versions of the Autoconf
77 # Macro released by the Autoconf Archive. When you make and distribute a
78 # modified version of the Autoconf Macro, you may extend this special
79 # exception to the GPL to apply to your modified version as well.
80
81 #serial 25
82
83 AC_DEFUN([AX_ENABLE_BUILDDIR],[
84 AC_REQUIRE([AC_CANONICAL_HOST])[]dnl
85 AC_REQUIRE([AC_CANONICAL_TARGET])[]dnl
86 AC_REQUIRE([AX_CONFIGURE_ARGS])[]dnl
87 AC_REQUIRE([AM_AUX_DIR_EXPAND])[]dnl
88 AC_BEFORE([$0],[AM_INIT_AUTOMAKE])dnl
89 AS_VAR_PUSHDEF([SUB],[ax_enable_builddir])dnl
90 AS_VAR_PUSHDEF([AUX],[ax_enable_builddir_auxdir])dnl
91 AS_VAR_PUSHDEF([SED],[ax_enable_builddir_sed])dnl
92 SUB="."
93 AC_ARG_ENABLE([builddir], AS_HELP_STRING(
94 [--disable-builddir],[disable automatic build in subdir of sources])
95 ,[SUB="$enableval"], [SUB="auto"])
96 if test ".$ac_srcdir_defaulted" != ".no" ; then
97 if test ".$srcdir" = ".." ; then
98 if test -f config.status ; then
99 AC_MSG_NOTICE(toplevel srcdir already configured... skipping subdir build)
100 else
101 test ".$SUB" = "." && SUB="."
102 test ".$SUB" = ".no" && SUB="."
103 test ".$TARGET" = "." && TARGET="$target"
104 test ".$SUB" = ".auto" && SUB="m4_ifval([$1], [$1],[$TARGET])"
105 if test ".$SUB" != ".." ; then # we know where to go and
106 AS_MKDIR_P([$SUB])
107 echo __.$SUB.__ > $SUB/conftest.tmp
108 cd $SUB
109 if grep __.$SUB.__ conftest.tmp >/dev/null 2>/dev/null ; then
110 rm conftest.tmp
111 AC_MSG_RESULT([continue configure in default builddir "./$SUB"])
112 else
113 AC_MSG_ERROR([could not change to default builddir "./$SUB"])
114 fi
115 srcdir=`echo "$SUB" |
116 sed -e 's,^\./,,;s,[[^/]]$,&/,;s,[[^/]]*/,../,g;s,[[/]]$,,;'`
117 # going to restart from subdirectory location
118 test -f $srcdir/config.log && mv $srcdir/config.log .
119 test -f $srcdir/confdefs.h && mv $srcdir/confdefs.h .
120 test -f $srcdir/conftest.log && mv $srcdir/conftest.log .
121 test -f $srcdir/$cache_file && mv $srcdir/$cache_file .
122 AC_MSG_RESULT(....exec $SHELL $srcdir/[$]0 "--srcdir=$srcdir" "--enable-builddir=$SUB" ${1+"[$]@"})
123 case "[$]0" in # restart
124 [[\\/]]* | ?:[[\\/]]*) # Asbolute name
125 eval $SHELL "'[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;;
126 *) eval $SHELL "'$srcdir/[$]0'" "'--srcdir=$srcdir'" "'--enable-builddir=$SUB'" $ac_configure_args ;;
127 esac ; exit $?
128 fi
129 fi
130 fi fi
131 test ".$SUB" = ".auto" && SUB="."
132 dnl ac_path_prog uses "set dummy" to override $@ which would defeat the "exec"
133 AC_PATH_PROG(SED,gsed sed, sed)
134 AUX="$am_aux_dir"
135 AS_VAR_POPDEF([SED])dnl
136 AS_VAR_POPDEF([AUX])dnl
137 AS_VAR_POPDEF([SUB])dnl
138 AC_CONFIG_COMMANDS([buildir],[dnl .............. config.status ..............
139 AS_VAR_PUSHDEF([SUB],[ax_enable_builddir])dnl
140 AS_VAR_PUSHDEF([TOP],[top_srcdir])dnl
141 AS_VAR_PUSHDEF([SRC],[ac_top_srcdir])dnl
142 AS_VAR_PUSHDEF([AUX],[ax_enable_builddir_auxdir])dnl
143 AS_VAR_PUSHDEF([SED],[ax_enable_builddir_sed])dnl
144 pushdef([END],[Makefile.mk])dnl
145 pushdef([_ALL],[ifelse([$3],,[-all],[$3])])dnl
146 SRC="$ax_enable_builddir_srcdir"
147 if test ".$SUB" = ".." ; then
148 if test -f "$TOP/Makefile" ; then
149 AC_MSG_NOTICE([skipping TOP/Makefile - left untouched])
150 else
151 AC_MSG_NOTICE([skipping TOP/Makefile - not created])
152 fi
153 else
154 if test -f "$SRC/Makefile" ; then
155 a=`grep "^VERSION " "$SRC/Makefile"` ; b=`grep "^VERSION " Makefile`
156 test "$a" != "$b" && rm "$SRC/Makefile"
157 fi
158 if test -f "$SRC/Makefile" ; then
159 echo "$SRC/Makefile : $SRC/Makefile.in" > $tmp/conftemp.mk
160 echo " []@ echo 'REMOVED,,,' >\$[]@" >> $tmp/conftemp.mk
161 eval "${MAKE-make} -f $tmp/conftemp.mk 2>/dev/null >/dev/null"
162 if grep '^REMOVED,,,' "$SRC/Makefile" >/dev/null
163 then rm $SRC/Makefile ; fi
164 cp $tmp/conftemp.mk $SRC/makefiles.mk~ ## DEBUGGING
165 fi
166 if test ! -f "$SRC/Makefile" ; then
167 AC_MSG_NOTICE([create TOP/Makefile guessed from local Makefile])
168 x='`' ; cat >$tmp/conftemp.sed <<_EOF
169 /^\$/n
170 x
171 /^\$/bS
172 x
173 /\\\\\$/{H;d;}
174 {H;s/.*//;x;}
175 bM
176 :S
177 x
178 /\\\\\$/{h;d;}
179 {h;s/.*//;x;}
180 :M
181 s/\\(\\n\\) /\\1 /g
182 /^ /d
183 /^[[ ]]*[[\\#]]/d
184 /^VPATH *=/d
185 s/^srcdir *=.*/srcdir = ./
186 s/^top_srcdir *=.*/top_srcdir = ./
187 /[[:=]]/!d
188 /^\\./d
189 dnl Now handle rules (i.e. lines containing ":" but not " = ").
190 / = /b
191 / .= /b
192 /:/!b
193 s/:.*/:/
194 s/ / /g
195 s/ \\([[a-z]][[a-z-]]*[[a-zA-Z0-9]]\\)\\([[ :]]\\)/ \\1 \\1[]_ALL\\2/g
196 s/^\\([[a-z]][[a-z-]]*[[a-zA-Z0-9]]\\)\\([[ :]]\\)/\\1 \\1[]_ALL\\2/
197 s/ / /g
198 /^all all[]_ALL[[ :]]/i\\
199 all-configured : all[]_ALL
200 dnl dist-all exists... and would make for dist-all-all
201 s/ [[a-zA-Z0-9-]]*[]_ALL [[a-zA-Z0-9-]]*[]_ALL[]_ALL//g
202 /[]_ALL[]_ALL/d
203 a\\
204 @ HOST="\$(HOST)\" \\\\\\
205 ; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\
206 ; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
207 ; use=$x basename "\$\@" _ALL $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\
208 ; echo "MAKE \$\$HOST : \$\$n * \$\@"; if test "\$\$n" -eq "0" ; then : \\\\\\
209 ; BUILD=$x grep "^####.*|" Makefile |tail -1| sed -e 's/.*|//' $x ; fi \\\\\\
210 ; test ".\$\$BUILD" = "." && BUILD="." \\\\\\
211 ; test "\$\$use" = "\$\@" && BUILD=$x echo "\$\$BUILD" | tail -1 $x \\\\\\
212 ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
213 ; (cd "\$\$i" && test ! -f configure && \$(MAKE) \$\$use) || exit; done
214 dnl special rule add-on: "dist" copies the tarball to $(PUB). (source tree)
215 /dist[]_ALL *:/a\\
216 @ HOST="\$(HOST)\" \\\\\\
217 ; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\
218 ; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
219 ; found=$x echo \$\$BUILD | wc -w $x \\\\\\
220 ; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).tar.*" \\\\\\
221 ; if test "\$\$found" -eq "0" ; then : \\\\\\
222 ; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\
223 ; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
224 ; for f in \$\$i/\$(PACKAGE)-\$(VERSION).tar.* \\\\\\
225 ; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done
226 dnl special rule add-on: "dist-foo" copies all the archives to $(PUB). (source tree)
227 /dist-[[a-zA-Z0-9]]*[]_ALL *:/a\\
228 @ HOST="\$(HOST)\" \\\\\\
229 ; test ".\$\$HOST" = "." && HOST=$x sh ./config.guess $x \\\\\\
230 ; BUILD=$x grep "^#### \$\$HOST " Makefile | sed -e 's/.*|//' $x \\\\\\
231 ; found=$x echo \$\$BUILD | wc -w $x \\\\\\
232 ; echo "MAKE \$\$HOST : \$\$found \$(PACKAGE)-\$(VERSION).*" \\\\\\
233 ; if test "\$\$found" -eq "0" ; then : \\\\\\
234 ; BUILD=$x grep "^#### .*|" Makefile |tail -1| sed -e 's/.*|//' $x \\\\\\
235 ; fi ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
236 ; for f in \$\$i/\$(PACKAGE)-\$(VERSION).* \\\\\\
237 ; do test -f "\$\$f" && mv "\$\$f" \$(PUB). ; done ; break ; done
238 dnl special rule add-on: "distclean" removes all local builddirs completely
239 /distclean[]_ALL *:/a\\
240 @ HOST="\$(HOST)\" \\\\\\
241 ; test ".\$\$HOST" = "." && HOST=$x sh $AUX/config.guess $x \\\\\\
242 ; BUILD=$x grep "^#### .*|" Makefile | sed -e 's/.*|//' $x \\\\\\
243 ; use=$x basename "\$\@" _ALL $x; n=$x echo \$\$BUILD | wc -w $x \\\\\\
244 ; echo "MAKE \$\$HOST : \$\$n * \$\@ (all local builds)" \\\\\\
245 ; test ".\$\$BUILD" = "." && BUILD="." \\\\\\
246 ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
247 ; echo "# rm -r \$\$i"; done ; echo "# (sleep 3)" ; sleep 3 \\\\\\
248 ; for i in \$\$BUILD ; do test ".\$\$i" = "." && continue \\\\\\
249 ; echo "\$\$i" | grep "^/" > /dev/null && continue \\\\\\
250 ; echo "\$\$i" | grep "^../" > /dev/null && continue \\\\\\
251 ; echo "rm -r \$\$i"; (rm -r "\$\$i") ; done ; rm Makefile
252 _EOF
253 cp "$tmp/conftemp.sed" "$SRC/makefile.sed~" ## DEBUGGING
254 $SED -f $tmp/conftemp.sed Makefile >$SRC/Makefile
255 if test -f "$SRC/m4_ifval([$2],[$2],[END])" ; then
256 AC_MSG_NOTICE([extend TOP/Makefile with TOP/m4_ifval([$2],[$2],[END])])
257 cat $SRC/END >>$SRC/Makefile
258 fi ; xxxx="####"
259 echo "$xxxx CONFIGURATIONS FOR TOPLEVEL MAKEFILE: " >>$SRC/Makefile
260 # sanity check
261 if grep '^; echo "MAKE ' $SRC/Makefile >/dev/null ; then
262 AC_MSG_NOTICE([buggy sed found - it deletes tab in "a" text parts])
263 $SED -e '/^@ HOST=/s/^/ /' -e '/^; /s/^/ /' $SRC/Makefile \
264 >$SRC/Makefile~
265 (test -s $SRC/Makefile~ && mv $SRC/Makefile~ $SRC/Makefile) 2>/dev/null
266 fi
267 else
268 xxxx="\\#\\#\\#\\#"
269 # echo "/^$xxxx *$ax_enable_builddir_host /d" >$tmp/conftemp.sed
270 echo "s!^$xxxx [[^|]]* | *$SUB *\$!$xxxx ...... $SUB!" >$tmp/conftemp.sed
271 $SED -f "$tmp/conftemp.sed" "$SRC/Makefile" >$tmp/mkfile.tmp
272 cp "$tmp/conftemp.sed" "$SRC/makefiles.sed~" ## DEBUGGING
273 cp "$tmp/mkfile.tmp" "$SRC/makefiles.out~" ## DEBUGGING
274 if cmp -s "$SRC/Makefile" "$tmp/mkfile.tmp" 2>/dev/null ; then
275 AC_MSG_NOTICE([keeping TOP/Makefile from earlier configure])
276 rm "$tmp/mkfile.tmp"
277 else
278 AC_MSG_NOTICE([reusing TOP/Makefile from earlier configure])
279 mv "$tmp/mkfile.tmp" "$SRC/Makefile"
280 fi
281 fi
282 AC_MSG_NOTICE([build in $SUB (HOST=$ax_enable_builddir_host)])
283 xxxx="####"
284 echo "$xxxx" "$ax_enable_builddir_host" "|$SUB" >>$SRC/Makefile
285 fi
286 popdef([END])dnl
287 AS_VAR_POPDEF([SED])dnl
288 AS_VAR_POPDEF([AUX])dnl
289 AS_VAR_POPDEF([SRC])dnl
290 AS_VAR_POPDEF([TOP])dnl
291 AS_VAR_POPDEF([SUB])dnl
292 ],[dnl
293 ax_enable_builddir_srcdir="$srcdir" # $srcdir
294 ax_enable_builddir_host="$HOST" # $HOST / $host
295 ax_enable_builddir_version="$VERSION" # $VERSION
296 ax_enable_builddir_package="$PACKAGE" # $PACKAGE
297 ax_enable_builddir_auxdir="$ax_enable_builddir_auxdir" # $AUX
298 ax_enable_builddir_sed="$ax_enable_builddir_sed" # $SED
299 ax_enable_builddir="$ax_enable_builddir" # $SUB
300 ])dnl
301 ])
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_extend_srcdir.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_EXTEND_SRCDIR
7 #
8 # DESCRIPTION
9 #
10 # The AX_EXTEND_SRCDIR macro extends $srcdir by one path component.
11 #
12 # As an example, when working in /home/michael/i3-4.12/build and calling
13 # ../configure, your $srcdir is "..". After calling AX_EXTEND_SRCDIR,
14 # $srcdir will be set to "../../i3-4.12".
15 #
16 # The result of extending $srcdir is that filenames (e.g. in the output of
17 # the "backtrace" gdb command) will include one more path component of the
18 # absolute source path. The additional path component makes it easy for
19 # users to recognize which files belong to the PACKAGE, and -- provided a
20 # dist tarball was unpacked -- which version of PACKAGE was used.
21 #
22 # As an example, in "backtrace", you will see:
23 #
24 # #0 main (argc=1, argv=0x7fffffff1fc8) at ../../i3-4.12/src/main.c:187
25 #
26 # instead of:
27 #
28 # #0 main (argc=1, argv=0x7fffffff1fc8) at ../src/main.c:187
29 #
30 # In case your code uses the __FILE__ preprocessor directive to refer to
31 # the filename of the current source file (e.g. in debug messages), using
32 # the extended path might be undesirable. For this purpose,
33 # AX_EXTEND_SRCDIR defines the output variable AX_EXTEND_SRCDIR_CPPFLAGS,
34 # which can be added to AM_CPPFLAGS in Makefile.am in order to define the
35 # preprocessor directive STRIPPED__FILE__. As an example, when compiling
36 # the file "../../i3-4.12/src/main.c", STRIPPED__FILE__ evaluates to
37 # "main.c".
38 #
39 # There are some caveats: When $srcdir is "." (i.e. when ./configure was
40 # called instead of ../configure in a separate build directory),
41 # AX_EXTEND_SRCDIR will still extend $srcdir, but the intended effect will
42 # not be achieved because of the way automake specifies file paths:
43 # automake defines COMPILE to use "`test -f '$source' || echo
44 # '\$(srcdir)/'`$source" in order to prefer files in the current directory
45 # over specifying $srcdir explicitly.
46 #
47 # The AX_EXTEND_SRCDIR author is not aware of any way to influence this
48 # automake behavior. Patches very welcome.
49 #
50 # To work around this issue, you can use AX_ENABLE_BUILDDIR i.e. by adding
51 # the following code to configure.ac:
52 #
53 # AX_ENABLE_BUILDDIR
54 # dnl ...
55 # AX_EXTEND_SRCDIR
56 #
57 # Then also add this bit to Makefile.am (if you wish to use
58 # STRIPPED__FILE__ in your code):
59 #
60 # AM_CPPFLAGS = @AX_EXTEND_SRCDIR_CPPFLAGS@
61 #
62 # LICENSE
63 #
64 # Copyright (c) 2016 Michael Stapelberg <[email protected]>
65 #
66 # Copying and distribution of this file, with or without modification, are
67 # permitted in any medium without royalty provided the copyright notice
68 # and this notice are preserved. This file is offered as-is, without any
69 # warranty.
70
71 #serial 3
72
73 AC_DEFUN([AX_EXTEND_SRCDIR],
74 [dnl
75 AS_CASE([$srcdir],
76 [.|.*|/*],
77 [
78 # pwd -P is specified in IEEE 1003.1 from 2004
79 as_dir=`cd "$srcdir" && pwd -P`
80 as_base=`AS_BASENAME([$as_dir])`
81 srcdir=${srcdir}/../${as_base}
82
83 AC_SUBST([AX_EXTEND_SRCDIR_CPPFLAGS], ["-DSTRIPPED__FILE__=AS_ESCAPE([\"$$(basename $<)\"])"])
84 ])
85 ])dnl AX_EXTEND_SRCDIR
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_pthread.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
7 #
8 # DESCRIPTION
9 #
10 # This macro figures out how to build C programs using POSIX threads. It
11 # sets the PTHREAD_LIBS output variable to the threads library and linker
12 # flags, and the PTHREAD_CFLAGS output variable to any special C compiler
13 # flags that are needed. (The user can also force certain compiler
14 # flags/libs to be tested by setting these environment variables.)
15 #
16 # Also sets PTHREAD_CC to any special C compiler that is needed for
17 # multi-threaded programs (defaults to the value of CC otherwise). (This
18 # is necessary on AIX to use the special cc_r compiler alias.)
19 #
20 # NOTE: You are assumed to not only compile your program with these flags,
21 # but also to link with them as well. For example, you might link with
22 # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
23 #
24 # If you are only building threaded programs, you may wish to use these
25 # variables in your default LIBS, CFLAGS, and CC:
26 #
27 # LIBS="$PTHREAD_LIBS $LIBS"
28 # CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
29 # CC="$PTHREAD_CC"
30 #
31 # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
32 # has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
33 # that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
34 #
35 # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
36 # PTHREAD_PRIO_INHERIT symbol is defined when compiling with
37 # PTHREAD_CFLAGS.
38 #
39 # ACTION-IF-FOUND is a list of shell commands to run if a threads library
40 # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
41 # is not found. If ACTION-IF-FOUND is not specified, the default action
42 # will define HAVE_PTHREAD.
43 #
44 # Please let the authors know if this macro fails on any platform, or if
45 # you have any other suggestions or comments. This macro was based on work
46 # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
47 # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
48 # Alejandro Forero Cuervo to the autoconf macro repository. We are also
49 # grateful for the helpful feedback of numerous users.
50 #
51 # Updated for Autoconf 2.68 by Daniel Richard G.
52 #
53 # LICENSE
54 #
55 # Copyright (c) 2008 Steven G. Johnson <[email protected]>
56 # Copyright (c) 2011 Daniel Richard G. <[email protected]>
57 #
58 # This program is free software: you can redistribute it and/or modify it
59 # under the terms of the GNU General Public License as published by the
60 # Free Software Foundation, either version 3 of the License, or (at your
61 # option) any later version.
62 #
63 # This program is distributed in the hope that it will be useful, but
64 # WITHOUT ANY WARRANTY; without even the implied warranty of
65 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
66 # Public License for more details.
67 #
68 # You should have received a copy of the GNU General Public License along
69 # with this program. If not, see <http://www.gnu.org/licenses/>.
70 #
71 # As a special exception, the respective Autoconf Macro's copyright owner
72 # gives unlimited permission to copy, distribute and modify the configure
73 # scripts that are the output of Autoconf when processing the Macro. You
74 # need not follow the terms of the GNU General Public License when using
75 # or distributing such scripts, even though portions of the text of the
76 # Macro appear in them. The GNU General Public License (GPL) does govern
77 # all other use of the material that constitutes the Autoconf Macro.
78 #
79 # This special exception to the GPL applies to versions of the Autoconf
80 # Macro released by the Autoconf Archive. When you make and distribute a
81 # modified version of the Autoconf Macro, you may extend this special
82 # exception to the GPL to apply to your modified version as well.
83
84 #serial 23
85
86 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
87 AC_DEFUN([AX_PTHREAD], [
88 AC_REQUIRE([AC_CANONICAL_HOST])
89 AC_REQUIRE([AC_PROG_CC])
90 AC_REQUIRE([AC_PROG_SED])
91 AC_LANG_PUSH([C])
92 ax_pthread_ok=no
93
94 # We used to check for pthread.h first, but this fails if pthread.h
95 # requires special compiler flags (e.g. on Tru64 or Sequent).
96 # It gets checked for in the link test anyway.
97
98 # First of all, check if the user has set any of the PTHREAD_LIBS,
99 # etcetera environment variables, and if threads linking works using
100 # them:
101 if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
102 ax_pthread_save_CC="$CC"
103 ax_pthread_save_CFLAGS="$CFLAGS"
104 ax_pthread_save_LIBS="$LIBS"
105 AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
106 CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
107 LIBS="$PTHREAD_LIBS $LIBS"
108 AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
109 AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
110 AC_MSG_RESULT([$ax_pthread_ok])
111 if test "x$ax_pthread_ok" = "xno"; then
112 PTHREAD_LIBS=""
113 PTHREAD_CFLAGS=""
114 fi
115 CC="$ax_pthread_save_CC"
116 CFLAGS="$ax_pthread_save_CFLAGS"
117 LIBS="$ax_pthread_save_LIBS"
118 fi
119
120 # We must check for the threads library under a number of different
121 # names; the ordering is very important because some systems
122 # (e.g. DEC) have both -lpthread and -lpthreads, where one of the
123 # libraries is broken (non-POSIX).
124
125 # Create a list of thread flags to try. Items starting with a "-" are
126 # C compiler flags, and other items are library names, except for "none"
127 # which indicates that we try without any flags at all, and "pthread-config"
128 # which is a program returning the flags for the Pth emulation library.
129
130 ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
131
132 # The ordering *is* (sometimes) important. Some notes on the
133 # individual items follow:
134
135 # pthreads: AIX (must check this before -lpthread)
136 # none: in case threads are in libc; should be tried before -Kthread and
137 # other compiler flags to prevent continual compiler warnings
138 # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
139 # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
140 # (Note: HP C rejects this with "bad form for `-t' option")
141 # -pthreads: Solaris/gcc (Note: HP C also rejects)
142 # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
143 # doesn't hurt to check since this sometimes defines pthreads and
144 # -D_REENTRANT too), HP C (must be checked before -lpthread, which
145 # is present but should not be used directly; and before -mthreads,
146 # because the compiler interprets this as "-mt" + "-hreads")
147 # -mthreads: Mingw32/gcc, Lynx/gcc
148 # pthread: Linux, etcetera
149 # --thread-safe: KAI C++
150 # pthread-config: use pthread-config program (for GNU Pth library)
151
152 case $host_os in
153
154 freebsd*)
155
156 # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
157 # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
158
159 ax_pthread_flags="-kthread lthread $ax_pthread_flags"
160 ;;
161
162 hpux*)
163
164 # From the cc(1) man page: "[-mt] Sets various -D flags to enable
165 # multi-threading and also sets -lpthread."
166
167 ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
168 ;;
169
170 openedition*)
171
172 # IBM z/OS requires a feature-test macro to be defined in order to
173 # enable POSIX threads at all, so give the user a hint if this is
174 # not set. (We don't define these ourselves, as they can affect
175 # other portions of the system API in unpredictable ways.)
176
177 AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
178 [
179 # if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
180 AX_PTHREAD_ZOS_MISSING
181 # endif
182 ],
183 [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
184 ;;
185
186 solaris*)
187
188 # On Solaris (at least, for some versions), libc contains stubbed
189 # (non-functional) versions of the pthreads routines, so link-based
190 # tests will erroneously succeed. (N.B.: The stubs are missing
191 # pthread_cleanup_push, or rather a function called by this macro,
192 # so we could check for that, but who knows whether they'll stub
193 # that too in a future libc.) So we'll check first for the
194 # standard Solaris way of linking pthreads (-mt -lpthread).
195
196 ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags"
197 ;;
198 esac
199
200 # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
201
202 AS_IF([test "x$GCC" = "xyes"],
203 [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"])
204
205 # The presence of a feature test macro requesting re-entrant function
206 # definitions is, on some systems, a strong hint that pthreads support is
207 # correctly enabled
208
209 case $host_os in
210 darwin* | hpux* | linux* | osf* | solaris*)
211 ax_pthread_check_macro="_REENTRANT"
212 ;;
213
214 aix*)
215 ax_pthread_check_macro="_THREAD_SAFE"
216 ;;
217
218 *)
219 ax_pthread_check_macro="--"
220 ;;
221 esac
222 AS_IF([test "x$ax_pthread_check_macro" = "x--"],
223 [ax_pthread_check_cond=0],
224 [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
225
226 # Are we compiling with Clang?
227
228 AC_CACHE_CHECK([whether $CC is Clang],
229 [ax_cv_PTHREAD_CLANG],
230 [ax_cv_PTHREAD_CLANG=no
231 # Note that Autoconf sets GCC=yes for Clang as well as GCC
232 if test "x$GCC" = "xyes"; then
233 AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
234 [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
235 # if defined(__clang__) && defined(__llvm__)
236 AX_PTHREAD_CC_IS_CLANG
237 # endif
238 ],
239 [ax_cv_PTHREAD_CLANG=yes])
240 fi
241 ])
242 ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
243
244 ax_pthread_clang_warning=no
245
246 # Clang needs special handling, because older versions handle the -pthread
247 # option in a rather... idiosyncratic way
248
249 if test "x$ax_pthread_clang" = "xyes"; then
250
251 # Clang takes -pthread; it has never supported any other flag
252
253 # (Note 1: This will need to be revisited if a system that Clang
254 # supports has POSIX threads in a separate library. This tends not
255 # to be the way of modern systems, but it's conceivable.)
256
257 # (Note 2: On some systems, notably Darwin, -pthread is not needed
258 # to get POSIX threads support; the API is always present and
259 # active. We could reasonably leave PTHREAD_CFLAGS empty. But
260 # -pthread does define _REENTRANT, and while the Darwin headers
261 # ignore this macro, third-party headers might not.)
262
263 PTHREAD_CFLAGS="-pthread"
264 PTHREAD_LIBS=
265
266 ax_pthread_ok=yes
267
268 # However, older versions of Clang make a point of warning the user
269 # that, in an invocation where only linking and no compilation is
270 # taking place, the -pthread option has no effect ("argument unused
271 # during compilation"). They expect -pthread to be passed in only
272 # when source code is being compiled.
273 #
274 # Problem is, this is at odds with the way Automake and most other
275 # C build frameworks function, which is that the same flags used in
276 # compilation (CFLAGS) are also used in linking. Many systems
277 # supported by AX_PTHREAD require exactly this for POSIX threads
278 # support, and in fact it is often not straightforward to specify a
279 # flag that is used only in the compilation phase and not in
280 # linking. Such a scenario is extremely rare in practice.
281 #
282 # Even though use of the -pthread flag in linking would only print
283 # a warning, this can be a nuisance for well-run software projects
284 # that build with -Werror. So if the active version of Clang has
285 # this misfeature, we search for an option to squash it.
286
287 AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
288 [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
289 [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
290 # Create an alternate version of $ac_link that compiles and
291 # links in two steps (.c -> .o, .o -> exe) instead of one
292 # (.c -> exe), because the warning occurs only in the second
293 # step
294 ax_pthread_save_ac_link="$ac_link"
295 ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
296 ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"`
297 ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
298 ax_pthread_save_CFLAGS="$CFLAGS"
299 for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
300 AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
301 CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
302 ac_link="$ax_pthread_save_ac_link"
303 AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
304 [ac_link="$ax_pthread_2step_ac_link"
305 AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
306 [break])
307 ])
308 done
309 ac_link="$ax_pthread_save_ac_link"
310 CFLAGS="$ax_pthread_save_CFLAGS"
311 AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
312 ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
313 ])
314
315 case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
316 no | unknown) ;;
317 *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
318 esac
319
320 fi # $ax_pthread_clang = yes
321
322 if test "x$ax_pthread_ok" = "xno"; then
323 for ax_pthread_try_flag in $ax_pthread_flags; do
324
325 case $ax_pthread_try_flag in
326 none)
327 AC_MSG_CHECKING([whether pthreads work without any flags])
328 ;;
329
330 -mt,pthread)
331 AC_MSG_CHECKING([whether pthreads work with -mt -lpthread])
332 PTHREAD_CFLAGS="-mt"
333 PTHREAD_LIBS="-lpthread"
334 ;;
335
336 -*)
337 AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
338 PTHREAD_CFLAGS="$ax_pthread_try_flag"
339 ;;
340
341 pthread-config)
342 AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
343 AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
344 PTHREAD_CFLAGS="`pthread-config --cflags`"
345 PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
346 ;;
347
348 *)
349 AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
350 PTHREAD_LIBS="-l$ax_pthread_try_flag"
351 ;;
352 esac
353
354 ax_pthread_save_CFLAGS="$CFLAGS"
355 ax_pthread_save_LIBS="$LIBS"
356 CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
357 LIBS="$PTHREAD_LIBS $LIBS"
358
359 # Check for various functions. We must include pthread.h,
360 # since some functions may be macros. (On the Sequent, we
361 # need a special flag -Kthread to make this header compile.)
362 # We check for pthread_join because it is in -lpthread on IRIX
363 # while pthread_create is in libc. We check for pthread_attr_init
364 # due to DEC craziness with -lpthreads. We check for
365 # pthread_cleanup_push because it is one of the few pthread
366 # functions on Solaris that doesn't have a non-functional libc stub.
367 # We try pthread_create on general principles.
368
369 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
370 # if $ax_pthread_check_cond
371 # error "$ax_pthread_check_macro must be defined"
372 # endif
373 static void routine(void *a) { a = 0; }
374 static void *start_routine(void *a) { return a; }],
375 [pthread_t th; pthread_attr_t attr;
376 pthread_create(&th, 0, start_routine, 0);
377 pthread_join(th, 0);
378 pthread_attr_init(&attr);
379 pthread_cleanup_push(routine, 0);
380 pthread_cleanup_pop(0) /* ; */])],
381 [ax_pthread_ok=yes],
382 [])
383
384 CFLAGS="$ax_pthread_save_CFLAGS"
385 LIBS="$ax_pthread_save_LIBS"
386
387 AC_MSG_RESULT([$ax_pthread_ok])
388 AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
389
390 PTHREAD_LIBS=""
391 PTHREAD_CFLAGS=""
392 done
393 fi
394
395 # Various other checks:
396 if test "x$ax_pthread_ok" = "xyes"; then
397 ax_pthread_save_CFLAGS="$CFLAGS"
398 ax_pthread_save_LIBS="$LIBS"
399 CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
400 LIBS="$PTHREAD_LIBS $LIBS"
401
402 # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
403 AC_CACHE_CHECK([for joinable pthread attribute],
404 [ax_cv_PTHREAD_JOINABLE_ATTR],
405 [ax_cv_PTHREAD_JOINABLE_ATTR=unknown
406 for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
407 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
408 [int attr = $ax_pthread_attr; return attr /* ; */])],
409 [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
410 [])
411 done
412 ])
413 AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
414 test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
415 test "x$ax_pthread_joinable_attr_defined" != "xyes"],
416 [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
417 [$ax_cv_PTHREAD_JOINABLE_ATTR],
418 [Define to necessary symbol if this constant
419 uses a non-standard name on your system.])
420 ax_pthread_joinable_attr_defined=yes
421 ])
422
423 AC_CACHE_CHECK([whether more special flags are required for pthreads],
424 [ax_cv_PTHREAD_SPECIAL_FLAGS],
425 [ax_cv_PTHREAD_SPECIAL_FLAGS=no
426 case $host_os in
427 solaris*)
428 ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
429 ;;
430 esac
431 ])
432 AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
433 test "x$ax_pthread_special_flags_added" != "xyes"],
434 [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
435 ax_pthread_special_flags_added=yes])
436
437 AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
438 [ax_cv_PTHREAD_PRIO_INHERIT],
439 [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
440 [[int i = PTHREAD_PRIO_INHERIT;]])],
441 [ax_cv_PTHREAD_PRIO_INHERIT=yes],
442 [ax_cv_PTHREAD_PRIO_INHERIT=no])
443 ])
444 AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
445 test "x$ax_pthread_prio_inherit_defined" != "xyes"],
446 [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
447 ax_pthread_prio_inherit_defined=yes
448 ])
449
450 CFLAGS="$ax_pthread_save_CFLAGS"
451 LIBS="$ax_pthread_save_LIBS"
452
453 # More AIX lossage: compile with *_r variant
454 if test "x$GCC" != "xyes"; then
455 case $host_os in
456 aix*)
457 AS_CASE(["x/$CC"],
458 [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
459 [#handle absolute path differently from PATH based program lookup
460 AS_CASE(["x$CC"],
461 [x/*],
462 [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
463 [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
464 ;;
465 esac
466 fi
467 fi
468
469 test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
470
471 AC_SUBST([PTHREAD_LIBS])
472 AC_SUBST([PTHREAD_CFLAGS])
473 AC_SUBST([PTHREAD_CC])
474
475 # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
476 if test "x$ax_pthread_ok" = "xyes"; then
477 ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
478 :
479 else
480 ax_pthread_ok=no
481 $2
482 fi
483 AC_LANG_POP
484 ])dnl AX_PTHREAD
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_require_defined.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_REQUIRE_DEFINED(MACRO)
7 #
8 # DESCRIPTION
9 #
10 # AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
11 # been defined and thus are available for use. This avoids random issues
12 # where a macro isn't expanded. Instead the configure script emits a
13 # non-fatal:
14 #
15 # ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
16 #
17 # It's like AC_REQUIRE except it doesn't expand the required macro.
18 #
19 # Here's an example:
20 #
21 # AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
22 #
23 # LICENSE
24 #
25 # Copyright (c) 2014 Mike Frysinger <[email protected]>
26 #
27 # Copying and distribution of this file, with or without modification, are
28 # permitted in any medium without royalty provided the copyright notice
29 # and this notice are preserved. This file is offered as-is, without any
30 # warranty.
31
32 #serial 1
33
34 AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
35 m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
36 ])dnl AX_REQUIRE_DEFINED
0 # ===========================================================================
1 # http://www.gnu.org/software/autoconf-archive/ax_sanitizers.html
2 # ===========================================================================
3 #
4 # SYNOPSIS
5 #
6 # AX_SANITIZERS([SANITIZERS], [ENABLED-BY-DEFAULT], [ACTION-SUCCESS])
7 #
8 # DESCRIPTION
9 #
10 # Offers users to enable one or more sanitizers (see
11 # https://github.com/google/sanitizers) with the corresponding
12 # --enable-<sanitizer>-sanitizer option.
13 #
14 # SANITIZERS is a whitespace-separated list of sanitizers to offer via
15 # --enable-<sanitizer>-sanitizer options, e.g. "address memory" for the
16 # address sanitizer and the memory sanitizer. If SANITIZERS is not specified,
17 # all known sanitizers to AX_SANITIZERS will be offered, which at the time of
18 # writing are "address memory undefined".
19 # NOTE that SANITIZERS is expanded at autoconf time, not at configure time,
20 # i.e. you cannot use shell variables in SANITIZERS.
21 #
22 # ENABLED-BY-DEFAULT is a whitespace-separated list of sanitizers which
23 # should be enabled by default, e.g. "memory undefined". Note that not all
24 # sanitizers can be combined, e.g. memory sanitizer cannot be enabled when
25 # address sanitizer is already enabled.
26 # Set ENABLED-BY-DEFAULT to a single whitespace in order to disable all
27 # sanitizers by default.
28 # ENABLED-BY-DEFAULT is expanded at configure time, so you can use shell
29 # variables.
30 #
31 # ACTION-SUCCESS allows to specify shell commands to execute on success, i.e.
32 # when one of the sanitizers was successfully enabled. This is a good place
33 # to call AC_DEFINE for any precompiler constants you might need to make your
34 # code play nice with sanitizers.
35 #
36 # The variable ax_enabled_sanitizers contains a whitespace-separated list of
37 # all enabled sanitizers, so that you can print them at the end of configure,
38 # if you wish.
39 #
40 # The additional --enable-sanitizers option allows users to enable/disable
41 # all sanitizers, effectively overriding ENABLED-BY-DEFAULT.
42 #
43 # EXAMPLES
44 #
45 # AX_SANITIZERS([address])
46 # dnl offer users to enable address sanitizer via --enable-address-sanitizer
47 #
48 # is_debug_build=…
49 # if test "x$is_debug_build" = "xyes"; then
50 # default_sanitizers="address memory"
51 # else
52 # default_sanitizers=
53 # fi
54 # AX_SANITIZERS([address memory], [$default_sanitizers])
55 # dnl enable address sanitizer and memory sanitizer by default for debug
56 # dnl builds, e.g. when building from git instead of a dist tarball.
57 #
58 # AX_SANITIZERS(, , [
59 # AC_DEFINE([SANITIZERS_ENABLED],
60 # [],
61 # [At least one sanitizer was enabled])])
62 # dnl enable all sanitizers known to AX_SANITIZERS by default and set the
63 # dnl SANITIZERS_ENABLED precompiler constant.
64 #
65 # AX_SANITIZERS(, [ ])
66 # dnl provide all sanitizers, but enable none by default.
67 #
68 # LICENSE
69 #
70 # Copyright (c) 2016 Michael Stapelberg <[email protected]>
71 #
72 # Copying and distribution of this file, with or without modification,
73 # are permitted in any medium without royalty provided the copyright
74 # notice and this notice are preserved. This file is offered as-is,
75 # without any warranty.
76
77 AC_DEFUN([AX_SANITIZERS],
78 [AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG])
79 AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
80 AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
81 AC_ARG_ENABLE(sanitizers,
82 AS_HELP_STRING(
83 [--enable-sanitizers],
84 [enable all known sanitizers]),
85 [ax_sanitizers_default=$enableval],
86 [ax_sanitizers_default=])
87 ax_enabled_sanitizers=
88 m4_foreach_w([mysan], m4_default($1, [address memory undefined]), [
89 dnl If ax_sanitizers_default is unset, i.e. the user neither explicitly
90 dnl enabled nor explicitly disabled all sanitizers, we get the default value
91 dnl for this sanitizer based on whether it is listed in ENABLED-BY-DEFAULT.
92 AS_IF([test "x$ax_sanitizers_default" = "x"], [dnl
93 ax_sanitizer_default=
94 for mycheck in m4_default([$2], [address memory undefined]); do
95 AS_IF([test "x$mycheck" = "x[]mysan"], [ax_sanitizer_default=yes])
96 done
97 AS_IF([test "x$ax_sanitizer_default" = "x"], [ax_sanitizer_default=no])
98 ],
99 [ax_sanitizer_default=$ax_sanitizers_default])
100 AC_ARG_ENABLE(mysan[]-sanitizer,
101 AS_HELP_STRING(
102 [--enable-[]mysan[]-sanitizer],
103 [enable -fsanitize=mysan]),
104 [ax_sanitizer_enabled=$enableval],
105 [ax_sanitizer_enabled=$ax_sanitizer_default])
106
107 AS_IF([test "x$ax_sanitizer_enabled" = "xyes"], [
108 dnl Not using AX_APPEND_COMPILE_FLAGS and AX_APPEND_LINK_FLAGS because they
109 dnl lack the ability to specify ACTION-SUCCESS.
110 AX_CHECK_COMPILE_FLAG([-fsanitize=[]mysan], [
111 AX_CHECK_LINK_FLAG([-fsanitize=[]mysan], [
112 AX_APPEND_FLAG([-fsanitize=[]mysan], [])
113 dnl If and only if libtool is being used, LDFLAGS needs to contain -Wc,-fsanitize=….
114 dnl See e.g. https://sources.debian.net/src/systemd/231-7/configure.ac/?hl=128#L135
115 dnl TODO: how can recognize that situation and add -Wc,?
116 AX_APPEND_FLAG([-fsanitize=[]mysan], [LDFLAGS])
117 dnl TODO: add -fPIE -pie for memory
118 # -fno-omit-frame-pointer results in nicer stack traces in error
119 # messages, see http://clang.llvm.org/docs/AddressSanitizer.html#usage
120 AX_CHECK_COMPILE_FLAG([-fno-omit-frame-pointer], [
121 AX_APPEND_FLAG([-fno-omit-frame-pointer], [])])
122 dnl TODO: at least for clang, we should specify exactly -O1, not -O2 or -O0, so that performance is reasonable but stacktraces are not tampered with (due to inlining), see http://clang.llvm.org/docs/AddressSanitizer.html#usage
123 m4_default([$3], :)
124 ax_enabled_sanitizers="[]mysan $ax_enabled_sanitizers"
125 ])
126 ])
127 ])
128 ])dnl
129 ])dnl AX_SANITIZERS
0 ifdef::doctype-manpage[]
1 ifdef::backend-docbook[]
2 [header]
3 template::[header-declarations]
4 <refentry>
5 <refmeta>
6 <refentrytitle>{mantitle}</refentrytitle>
7 <manvolnum>{manvolnum}</manvolnum>
8 <refmiscinfo class="source">i3</refmiscinfo>
9 <refmiscinfo class="version">@PACKAGE_VERSION@</refmiscinfo>
10 <refmiscinfo class="manual">i3 Manual</refmiscinfo>
11 </refmeta>
12 <refnamediv>
13 <refname>{manname}</refname>
14 <refpurpose>{manpurpose}</refpurpose>
15 </refnamediv>
16 endif::backend-docbook[]
17 endif::doctype-manpage[]
0 i3-config-wizard(1)
1 ===================
2 Michael Stapelberg <[email protected]>
3 v4.0, July 2011
4
5 == NAME
6
7 i3-config-wizard - creates a keysym based config based on your layout
8
9 == SYNOPSIS
10
11 i3-config-wizard [*-s* 'socket'] [*-m* 'modifier'] [*-v*] [*-h*]
12
13 == OPTIONS
14
15 *-s, --socket* 'socket'::
16 Overwrites the path to the i3 IPC socket.
17
18 *-m, --modifier* 'modifier'::
19 Generates the configuration file headlessly. Accepts win or alt.
20
21 *-v, --version*::
22 Display version number and exit.
23
24 *-h, --help*::
25 Display a short help message and exit.
26
27 == FILES
28
29 === /etc/i3/config.keycodes
30
31 This file contains the default configuration with keycodes. All the bindcode
32 lines will be transformed to bindsym and the user-specified modifier will be
33 used.
34
35 == DESCRIPTION
36
37 i3-config-wizard is started by i3 in its default config, unless ~/.i3/config
38 exists. i3-config-wizard creates a keysym based i3 config file (based on
39 /etc/i3/config.keycodes) in ~/.i3/config.
40
41 The advantage of using keysyms is that the config file is easy to read,
42 understand and modify. However, if we shipped with a keysym based default
43 config file, the key positions would not be consistent across different
44 keyboard layouts (take for example the homerow for movement). Therefore, we
45 ship with a keycode based default config and let the wizard transform it
46 according to your current keyboard layout.
47
48 == SEE ALSO
49
50 i3(1)
51
52 == AUTHOR
53
54 Michael Stapelberg and contributors
0 i3-dump-log(1)
1 ==============
2 Michael Stapelberg <[email protected]>
3 v4.6, September 2013
4
5 == NAME
6
7 i3-dump-log - dumps the i3 SHM log
8
9 == SYNOPSIS
10
11 i3-dump-log [-s <socketpath>] [-f]
12
13 == DESCRIPTION
14
15 Debug versions of i3 automatically use 1% of your RAM (but 25 MiB max) to store
16 full debug log output. This is extremely helpful for bugreports and
17 figuring out what is going on, without permanently logging to a file.
18
19 With i3-dump-log, you can dump the SHM log to stdout.
20
21 The -f flag works like tail -f, i.e. the process does not terminate after
22 dumping the log, but prints new lines as they appear.
23
24 == EXAMPLE
25
26 i3-dump-log | gzip -9 > /tmp/i3-log.gz
27
28 == SEE ALSO
29
30 i3(1)
31
32 == AUTHOR
33
34 Michael Stapelberg and contributors
0 i3-input(1)
1 ===========
2 Michael Stapelberg <[email protected]>
3 v4.1.2, April 2012
4
5 == NAME
6
7 i3-input - interactively take a command for i3 window manager
8
9 == SYNOPSIS
10
11 i3-input [-s <socket>] [-F <format>] [-l <limit>] [-P <prompt>] [-f <font>] [-v]
12
13 == DESCRIPTION
14
15 i3-input is a tool to take commands (or parts of a command) composed by
16 the user, and send it/them to i3. This is useful, for example, for the
17 mark/goto command.
18
19 You can press Escape to close i3-input without sending any commands.
20
21 == OPTIONS
22
23 -s <socket>::
24 Specify the path to the i3 IPC socket (it should not be necessary to use this
25 option, i3-input will figure out the path on its own).
26
27 -F <format>::
28 Every occurrence of "%s" in the <format> string is replaced by the user input,
29 and the result is sent to i3 as a command. Default value is "%s".
30
31 -l <limit>::
32 Set the maximum allowed length of the user input to <limit> characters.
33 i3-input will automatically issue the command when the user input reaches that
34 length.
35
36 -P <prompt>::
37 Display the <prompt> string in front of user input text field.
38 The prompt string is not included in the user input/command.
39
40 -f <font>::
41 Use the specified X11 core font (use +xfontsel+ to chose a font).
42
43 -v::
44 Show version and exit.
45
46 == EXAMPLES
47
48 Mark a container with a single character:
49 ------------------------------------------------
50 i3-input -F 'mark %s' -l 1 -P 'Mark: '
51 ------------------------------------------------
52
53 Go to the container marked with above example:
54 -----------------------------------------------------
55 i3-input -F '[con_mark="%s"] focus' -l 1 -P 'Go to: '
56 -----------------------------------------------------
57
58 == ENVIRONMENT
59
60 === I3SOCK
61
62 i3-input handles the different sources of socket paths in the following order:
63
64 * I3SOCK environment variable
65 * I3SOCK gets overwritten by the -s parameter, if specified
66 * if neither are available, i3-input reads the socket path from the X11
67 property, which is the recommended way
68 * if everything fails, i3-input tries +/tmp/i3-ipc.sock+
69
70 The socket path is necessary to connect to i3 and actually issue the command.
71
72 == SEE ALSO
73
74 i3(1)
75
76 == AUTHOR
77
78 Michael Stapelberg and contributors
0 i3-migrate-config-to-v4(1)
1 ==========================
2 Michael Stapelberg <[email protected]>
3 v4.0, July 2011
4
5 == NAME
6
7 i3-migrate-config-to-v4 - migrates your i3 config file
8
9 == SYNOPSIS
10
11 -------------------------------------------------------
12 mv ~/.i3/config ~/.i3/old.config
13 i3-migrate-config-to-v4 ~/.i3/old.config > ~/.i3/config
14 -------------------------------------------------------
15
16 == DESCRIPTION
17
18 i3-migrate-config-to-v4 is a Perl script which migrates your old (< version 4)
19 configuration files to a version 4 config file. The most significant changes
20 are the new commands (see the release notes).
21
22 This script will automatically be run by i3 when it detects an old config file.
23 Please migrate your config file as soon as possible. We plan to include this
24 script in all i3 release until 2012-08-01. Afterwards, old config files will no
25 longer be supported.
26
27 == SEE ALSO
28
29 i3(1)
30
31 == AUTHOR
32
33 Michael Stapelberg and contributors
0 i3-msg(1)
1 =========
2 Michael Stapelberg <[email protected]>
3 v4.2, August 2012
4
5 == NAME
6
7 i3-msg - send messages to i3 window manager
8
9 == SYNOPSIS
10
11 i3-msg [-q] [-v] [-h] [-s socket] [-t type] [message]
12
13 == OPTIONS
14
15 *-q, --quiet*::
16 Only send ipc message and suppress the output of the response.
17
18 *-v, --version*::
19 Display version number and exit.
20
21 *-h, --help*::
22 Display a short help-message and exit.
23
24 *-s, --socket* 'sock_path'::
25 i3-msg will use the environment variable I3SOCK or the socket path
26 given here. If both fail, it will try to get the socket information
27 from the root window and then try /tmp/i3-ipc.sock before exiting
28 with an error.
29
30 *-t* 'type'::
31 Send ipc message, see below. This option defaults to "command".
32
33 *-m*, *--monitor*::
34 Instead of exiting right after receiving the first subscribed event,
35 wait indefinitely for all of them. Can only be used with "-t subscribe".
36 See the "subscribe" IPC message type below for details.
37
38 *message*::
39 Send ipc message, see below.
40
41 == IPC MESSAGE TYPES
42
43 command::
44 The payload of the message is a command for i3 (like the commands you can bind
45 to keys in the configuration file) and will be executed directly after
46 receiving it.
47
48 get_workspaces::
49 Gets the current workspaces. The reply will be a JSON-encoded list of
50 workspaces.
51
52 get_outputs::
53 Gets the current outputs. The reply will be a JSON-encoded list of outputs (see
54 the reply section of docs/ipc, e.g. at
55 https://i3wm.org/docs/ipc.html#_receiving_replies_from_i3).
56
57 get_tree::
58 Gets the layout tree. i3 uses a tree as data structure which includes every
59 container. The reply will be the JSON-encoded tree.
60
61 get_marks::
62 Gets a list of marks (identifiers for containers to easily jump to them later).
63 The reply will be a JSON-encoded list of window marks.
64
65 get_bar_config::
66 Gets the configuration (as JSON map) of the workspace bar with the given ID. If
67 no ID is provided, an array with all configured bar IDs is returned instead.
68
69 get_binding_modes::
70 Gets a list of configured binding modes.
71
72 get_version::
73 Gets the version of i3. The reply will be a JSON-encoded dictionary with the
74 major, minor, patch and human-readable version.
75
76 get_config::
77 Gets the currently loaded i3 configuration.
78
79 send_tick::
80 Sends a tick to all IPC connections which subscribe to tick events.
81
82 subscribe::
83 The payload of the message describes the events to subscribe to.
84 Upon reception, each event will be dumped as a JSON-encoded object.
85 See the -m option for continuous monitoring.
86
87 == DESCRIPTION
88
89 i3-msg is a sample implementation for a client using the unix socket IPC
90 interface to i3.
91
92 === Exit status:
93
94 0:
95 if OK,
96 1:
97 if invalid syntax or unable to connect to ipc-socket
98 2:
99 if i3 returned an error processing your command(s)
100
101 == EXAMPLES
102
103 ------------------------------------------------
104 # Use 1-px border for current client
105 i3-msg "border 1pixel"
106
107 # You can leave out the quotes
108 i3-msg border normal
109
110 # Dump the layout tree
111 i3-msg -t get_tree
112
113 # Monitor window changes
114 i3-msg -t subscribe -m '[ "window" ]'
115 ------------------------------------------------
116
117 == ENVIRONMENT
118
119 === I3SOCK
120
121 If no ipc-socket is specified on the commandline, this variable is used
122 to determine the path, at which the unix domain socket is expected, on which
123 to connect to i3.
124
125 == SEE ALSO
126
127 i3(1)
128
129 == AUTHOR
130
131 Michael Stapelberg and contributors
0 i3-nagbar(1)
1 ============
2 Michael Stapelberg <[email protected]>
3 v4.0, July 2011
4
5 == NAME
6
7 i3-nagbar - displays an error bar on top of your screen
8
9 == SYNOPSIS
10
11 i3-nagbar [-m <message>] [-b <button> <action>] [-B <button> <action>] [-t warning|error] [-f <font>] [-v]
12
13 == OPTIONS
14
15 *-v, --version*::
16 Display version number and exit.
17
18 *-h, --help*::
19 Display a short help-message and exit.
20
21 *-t, --type* 'type'::
22 Display either a warning or error message. This only changes the color scheme
23 for the i3-nagbar. Default: error.
24
25 *-m, --message* 'message'::
26 Display 'message' as text on the left of the i3-nagbar.
27
28 *-f, --font* 'font'::
29 Select font that is being used.
30
31 *-b, --button* 'button' 'action'::
32 Create a button with text 'button'. The 'action' are the shell commands that
33 will be executed by this button. Multiple buttons can be defined.
34 Will launch the shell commands inside a terminal emulator, using
35 i3-sensible-terminal.
36
37 *-B, --button-no-terminal* 'button' 'action'::
38 Same as above, but will execute the shell commands directly, without launching a
39 terminal emulator.
40
41 == DESCRIPTION
42
43 i3-nagbar is used by i3 to tell you about errors in your configuration file
44 (for example). While these errors are logged to the logfile (if any), the past
45 has proven that users are either not aware of their logfile or do not check it
46 after modifying the configuration file.
47
48 == EXAMPLE
49
50 ------------------------------------------------
51 i3-nagbar -m 'You have an error in your i3 config file!' \
52 -b 'edit config' 'i3-sensible-editor ~/.config/i3/config'
53 ------------------------------------------------
54
55 == SEE ALSO
56
57 i3(1)
58
59 == AUTHOR
60
61 Michael Stapelberg and contributors
0 i3-sensible-editor(1)
1 =====================
2 Michael Stapelberg <[email protected]>
3 v4.1, November 2011
4
5 == NAME
6
7 i3-sensible-editor - launches $EDITOR with fallbacks
8
9 == SYNOPSIS
10
11 i3-sensible-editor [arguments]
12
13 == DESCRIPTION
14
15 i3-sensible-editor is used by i3-nagbar(1) when you click on the edit button.
16
17 It tries to start one of the following (in that order):
18
19 * $VISUAL
20 * $EDITOR
21 * nano
22 * nvim
23 * vim
24 * vi
25 * emacs
26 * pico
27 * qe
28 * mg
29 * jed
30 * gedit
31 * mcedit
32 * gvim
33
34 Please don’t complain about the order: If the user has any preference, they will
35 have $VISUAL or $EDITOR set.
36
37 == SEE ALSO
38
39 i3(1)
40
41 == AUTHOR
42
43 Michael Stapelberg and contributors
0 i3-sensible-pager(1)
1 ====================
2 Michael Stapelberg <[email protected]>
3 v4.1, November 2011
4
5 == NAME
6
7 i3-sensible-pager - launches $PAGER with fallbacks
8
9 == SYNOPSIS
10
11 i3-sensible-pager [arguments]
12
13 == DESCRIPTION
14
15 i3-sensible-pager is used by i3-nagbar(1) when you click on the view button.
16
17 It tries to start one of the following (in that order):
18
19 * $PAGER
20 * less
21 * most
22 * w3m
23 * i3-sensible-editor(1)
24
25 Please don’t complain about the order: If the user has any preference, they will
26 have $PAGER set.
27
28 == SEE ALSO
29
30 i3(1)
31
32 == AUTHOR
33
34 Michael Stapelberg and contributors
0 i3-sensible-terminal(1)
1 =======================
2 Michael Stapelberg <[email protected]>
3 v4.2, August 2012
4
5 == NAME
6
7 i3-sensible-terminal - launches $TERMINAL with fallbacks
8
9 == SYNOPSIS
10
11 i3-sensible-terminal [arguments]
12
13 == DESCRIPTION
14
15 i3-sensible-terminal is invoked in the i3 default config to start a terminal.
16 This wrapper script is necessary since there is no distribution-independent
17 terminal launcher (but for example Debian has x-terminal-emulator).
18 Distribution packagers are responsible for shipping this script in a way which
19 is appropriate for the distribution.
20
21 It tries to start one of the following (in that order):
22
23 * $TERMINAL (this is a non-standard variable)
24 * x-terminal-emulator (only present on Debian and derivatives)
25 * urxvt
26 * rxvt
27 * termit
28 * terminator
29 * Eterm
30 * aterm
31 * uxterm
32 * xterm
33 * gnome-terminal
34 * roxterm
35 * xfce4-terminal
36 * termite
37 * lxterminal
38 * mate-terminal
39 * terminology
40 * st
41 * qterminal
42 * lilyterm
43 * tilix
44 * terminix
45 * konsole
46 * kitty
47 * guake
48 * tilda
49 * alacritty
50 * hyper
51
52 Please don’t complain about the order: If the user has any preference, they will
53 have $TERMINAL set or modified their i3 configuration file.
54
55 == SEE ALSO
56
57 i3(1)
58
59 == AUTHOR
60
61 Michael Stapelberg and contributors
0 i3(1)
1 =====
2 Michael Stapelberg <[email protected]>
3 v4.3, September 2012
4
5 == NAME
6
7 i3 - an improved dynamic, tiling window manager
8
9 == SYNOPSIS
10
11 i3 [-a] [-c configfile] [-C] [-d all] [-v] [-V]
12
13 == OPTIONS
14
15 -a::
16 Disables autostart.
17
18 -c::
19 Specifies an alternate configuration file path.
20
21 -C::
22 Check the configuration file for validity and exit.
23
24 -d all::
25 Enables debug logging.
26 The 'all' parameter is present for historical reasons.
27
28 -v::
29 Display version number (and date of the last commit).
30
31 -V::
32 Be verbose.
33
34 --force-xinerama::
35 Use Xinerama instead of RandR. This option should only be used if you are stuck
36 with the old nVidia closed source driver (older than 302.17) which does not
37 support RandR.
38
39 --get-socketpath::
40 Retrieve the i3 IPC socket path from X11, print it, then exit.
41
42 --shmlog-size <limit>::
43 Limits the size of the i3 SHM log to <limit> bytes. Setting this to 0 disables
44 SHM logging entirely. The default is 0 bytes.
45
46 == DESCRIPTION
47
48 === INTRODUCTION
49
50 i3 was created because wmii, our favorite window manager at the time, didn’t
51 provide some features we wanted (multi-monitor done right, for example), had
52 some bugs, didn’t progress since quite some time and wasn’t easy to hack at all
53 (source code comments/documentation completely lacking). Still, we think the
54 wmii developers and contributors did a great job. Thank you for inspiring us to
55 create i3.
56
57 Please be aware that i3 is primarily targeted at advanced users and developers.
58
59 === IMPORTANT NOTE TO nVidia BINARY DRIVER USERS
60
61 If you are using the nVidia binary graphics driver (also known as 'blob')
62 before version 302.17, you need to use the +--force-xinerama+ flag (in your
63 ~/.xsession) when starting i3, like so:
64
65 ----------------------------------------------
66 exec i3 --force-xinerama -V >>~/.i3/i3log 2>&1
67 ----------------------------------------------
68
69 See also docs/multi-monitor for the full explanation.
70
71 === TERMINOLOGY
72
73 Tree::
74 i3 keeps your layout in a tree data structure.
75
76 Window::
77 An X11 window, like the Firefox browser window or a terminal emulator.
78
79 Floating Window::
80 A window which "floats" on top of other windows. This style is used by i3 to
81 display X11 windows with type "dialog", such as the "Print" or "Open File"
82 dialog boxes in many GUI applications. Use of floating windows can be
83 fine-tuned with the for_window command (see HTML userguide).
84
85 Split container::
86 A split container contains multiple other split containers or windows.
87 +
88 Containers can be used in various layouts. The default mode is called "default"
89 and just resizes each client equally so that it fits.
90
91 Workspace::
92 A workspace is a set of containers. Other window managers call this "Virtual
93 Desktops".
94 +
95 In i3, each workspace is assigned to a specific virtual screen. By default,
96 screen 1 has workspace 1, screen 2 has workspace 2 and so on… However, when you
97 create a new workspace (by simply switching to it), it’ll be assigned the
98 screen you are currently on.
99
100 Output::
101 Using XRandR, you can have an X11 screen spanning multiple real monitors.
102 Furthermore, you can set them up in cloning mode or with positions (monitor 1
103 is left of monitor 2).
104 +
105 i3 uses the RandR API to query which outputs are available and which screens
106 are connected to these outputs.
107
108 == KEYBINDINGS
109
110 Here is a short overview of the default keybindings:
111
112 Mod1+Enter::
113 Open a new terminal emulator window.
114
115 Mod1+d::
116 Open dmenu for starting any application by typing (part of) its name.
117
118 j/k/l/;::
119 Direction keys (left, down, up, right). They are on your homerow (see the mark
120 on your "j" key). Alternatively, you can use the cursor keys.
121
122 Mod1+<direction>::
123 Focus window in <direction>.
124
125 Mod1+Shift+<direction>::
126 Move window to <direction>.
127
128 Mod1+<number>::
129 Switch to workspace <number>.
130
131 Mod1+Shift+<number>::
132 Move window to workspace <number>.
133
134 Mod1+f::
135 Toggle fullscreen mode.
136
137 Mod1+s::
138 Enable stacking layout for the current container.
139
140 Mod1+e::
141 Enable default layout for the current container.
142
143 Mod1+w::
144 Enable tabbed layout for the current container.
145
146 Mod1+Shift+Space::
147 Toggle tiling/floating for the current container.
148
149 Mod1+Space::
150 Select the first tiling container if the current container is floating and
151 vice-versa.
152
153 Mod1+Shift+q::
154 Kills the current window. This is equivalent to "clicking on the close button",
155 meaning a polite request to the application to close this window. For example,
156 Firefox will save its session upon such a request. If the application does not
157 support that, the window will be killed and it depends on the application what
158 happens.
159
160 Mod1+Shift+r::
161 Restarts i3 in place. Your layout will be preserved.
162
163 Mod1+Shift+e::
164 Exits i3.
165
166 == FILES
167
168 === \~/.config/i3/config (or ~/.i3/config)
169
170 When starting, i3 looks for configuration files in the following order:
171
172 1. ~/.config/i3/config (or $XDG_CONFIG_HOME/i3/config if set)
173 2. ~/.i3/config
174 3. /etc/xdg/i3/config (or $XDG_CONFIG_DIRS/i3/config if set)
175 4. /etc/i3/config
176
177 You can specify a custom path using the -c option.
178
179 .Sample configuration
180 -------------------------------------------------------------
181 # i3 config file (v4)
182
183 # Font for window titles. Will also be used by the bar unless a different font
184 # is used in the bar {} block below.
185 # This font is widely installed, provides lots of unicode glyphs, right-to-left
186 # text rendering and scalability on retina/hidpi displays (thanks to pango).
187 font pango:DejaVu Sans Mono 8
188 # Before i3 v4.8, we used to recommend this one as the default:
189 # font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
190 # The font above is very space-efficient, that is, it looks good, sharp and
191 # clear in small sizes. However, its unicode glyph coverage is limited, the old
192 # X core fonts rendering does not support right-to-left and this being a bitmap
193 # font, it doesn’t scale on retina/hidpi displays.
194
195 # use Mouse+Mod1 to drag floating windows to their wanted position
196 floating_modifier Mod1
197
198 # start a terminal
199 bindsym Mod1+Return exec /usr/bin/urxvt
200
201 # kill focused window
202 bindsym Mod1+Shift+q kill
203
204 # start dmenu (a program launcher)
205 bindsym Mod1+d exec /usr/bin/dmenu_run
206
207 # change focus
208 bindsym Mod1+j focus left
209 bindsym Mod1+k focus down
210 bindsym Mod1+l focus up
211 bindsym Mod1+semicolon focus right
212
213 # alternatively, you can use the cursor keys:
214 bindsym Mod1+Left focus left
215 bindsym Mod1+Down focus down
216 bindsym Mod1+Up focus up
217 bindsym Mod1+Right focus right
218
219 # move focused window
220 bindsym Mod1+Shift+j move left
221 bindsym Mod1+Shift+k move down
222 bindsym Mod1+Shift+l move up
223 bindsym Mod1+Shift+semicolon move right
224
225 # alternatively, you can use the cursor keys:
226 bindsym Mod1+Shift+Left move left
227 bindsym Mod1+Shift+Down move down
228 bindsym Mod1+Shift+Up move up
229 bindsym Mod1+Shift+Right move right
230
231 # split in horizontal orientation
232 bindsym Mod1+h split h
233
234 # split in vertical orientation
235 bindsym Mod1+v split v
236
237 # enter fullscreen mode for the focused container
238 bindsym Mod1+f fullscreen toggle
239
240 # change container layout (stacked, tabbed, default)
241 bindsym Mod1+s layout stacking
242 bindsym Mod1+w layout tabbed
243 bindsym Mod1+e layout default
244
245 # toggle tiling / floating
246 bindsym Mod1+Shift+space floating toggle
247
248 # change focus between tiling / floating windows
249 bindsym Mod1+space focus mode_toggle
250
251 # focus the parent container
252 bindsym Mod1+a focus parent
253
254 # focus the child container
255 #bindsym Mod1+d focus child
256
257 # switch to workspace
258 bindsym Mod1+1 workspace 1
259 bindsym Mod1+2 workspace 2
260 # ..
261
262 # move focused container to workspace
263 bindsym Mod1+Shift+1 move workspace 1
264 bindsym Mod1+Shift+2 move workspace 2
265 # ...
266
267 # reload the configuration file
268 bindsym Mod1+Shift+c reload
269 # restart i3 inplace (preserves your layout/session, can be used to upgrade i3)
270 bindsym Mod1+Shift+r restart
271 # exit i3 (logs you out of your X session)
272 bindsym Mod1+Shift+e exit
273
274 # display workspace buttons plus a statusline generated by i3status
275 bar {
276 status_command i3status
277 }
278 -------------------------------------------------------------
279
280 === ~/.xsession
281
282 This file is where you should configure your locales and start i3. It is run by
283 your login manager (xdm, slim, gdm, …) as soon as you login.
284
285 .Sample xsession
286 -------------------------------------------------------------
287 # Disable DPMS turning off the screen
288 xset -dpms
289 xset s off
290
291 # Disable bell
292 xset -b
293
294 # Enable zapping (C-A-<Bksp> kills X)
295 setxkbmap -option terminate:ctrl_alt_bksp
296
297 # Enforce correct locales from the beginning:
298 # LC_ALL is unset since it overwrites everything
299 # LANG=de_DE.UTF-8 is used, except for:
300 # LC_MESSAGES=C never translates program output
301 # LC_TIME=en_DK leads to yyyy-mm-dd hh:mm date/time output
302 unset LC_ALL
303 export LANG=de_DE.UTF-8
304 export LC_MESSAGES=C
305 export LC_TIME=en_DK.UTF-8
306
307 # Use XToolkit in java applications
308 export AWT_TOOLKIT=XToolkit
309
310 # Set background color
311 xsetroot -solid "#333333"
312
313 # Enable core dumps in case something goes wrong
314 ulimit -c unlimited
315
316 # Start i3 and log to ~/.i3/logfile
317 echo "Starting at $(date)" >> ~/.i3/logfile
318 exec /usr/bin/i3 -V -d all >> ~/.i3/logfile
319 -------------------------------------------------------------
320
321 == ENVIRONMENT
322
323 === I3SOCK
324
325 This variable overwrites the IPC socket path (placed in
326 /tmp/i3-%u.XXXXXX/ipc-socket.%p by default, where %u is replaced with your UNIX
327 username, %p is replaced with i3’s PID and XXXXXX is a string of random
328 characters from the portable filename character set (see mkdtemp(3))). The IPC
329 socket is used by external programs like i3-msg(1) or i3bar(1).
330
331 == TODO
332
333 There is still lot of work to do. Please check our bugtracker for up-to-date
334 information about tasks which are still not finished.
335
336 == SEE ALSO
337
338 You should have a copy of the userguide (featuring nice screenshots/graphics
339 which is why this is not integrated into this manpage), the debugging guide,
340 and the "how to hack" guide. If you are building from source, run:
341 +make -C docs+
342
343 You can also access these documents online at https://i3wm.org/
344
345 i3-input(1), i3-msg(1), i3bar(1), i3-nagbar(1), i3-config-wizard(1),
346 i3-migrate-config-to-v4(1)
347
348 == AUTHOR
349
350 Michael Stapelberg and contributors
0 i3bar(1)
1 ========
2 Axel Wagner <[email protected]>
3 v4.1, October 2011
4
5 == NAME
6
7 i3bar - xcb-based status- and workspace-bar
8
9 == SYNOPSIS
10
11 *i3bar* [*-s* 'sock_path'] [*-b* 'bar_id'] [*-v*] [*-h*]
12
13 == WARNING
14
15 i3bar will automatically be invoked by i3 for every 'bar' configuration block.
16
17 Starting it manually is usually not what you want to do.
18
19 You have been warned!
20
21 == OPTIONS
22
23 *-s, --socket* 'sock_path'::
24 Overwrites the path to the i3 IPC socket.
25
26 *-b, --bar_id* 'bar_id'::
27 Specifies the bar ID for which to get the configuration from i3.
28
29 *-v, --version*::
30 Display version number and exit.
31
32 *-h, --help*::
33 Display a short help-message and exit
34
35 == DESCRIPTION
36
37 *i3bar* displays a bar at the bottom (or top) of your monitor(s) containing
38 workspace switching buttons and a statusline generated by i3status(1) or
39 similar. It is automatically invoked (and configured through) i3.
40
41 i3bar supports colors via a JSON protocol starting from v4.2, see
42 https://i3wm.org/docs/i3bar-protocol.html
43
44 == ENVIRONMENT
45
46 === I3SOCK
47
48 Used as a fallback for the i3 IPC socket path if neither the commandline
49 contains an argument nor the I3_SOCKET_PATH property is set on the X11 root
50 window.
51
52 == EXAMPLES
53
54 Nothing to see here, move along. As stated above, you should not run i3bar manually.
55
56 Instead, see the i3 documentation, especially the User’s Guide.
57
58 == SEE ALSO
59
60 +i3status(1)+, +j4status(1)+ or +conky(1)+ for programs generating a statusline.
61
62 +dzen2(1)+ or +xmobar(1)+ for similar programs to i3bar.
63
64 == AUTHORS
65
66 Axel Wagner and contributors
0 # vim:ts=2:sw=2:expandtab
1 #
2 # i3 - an improved dynamic tiling window manager
3 # © 2009 Michael Stapelberg and contributors (see also: LICENSE)
4 #
5 # parser-specs/commands.spec: Specification file for generate-command-parser.pl
6 # which will generate the appropriate header files for our C parser.
7 #
8 # Use :source highlighting.vim in vim to get syntax highlighting
9 # for this file.
10
11 state INITIAL:
12 # We have an end token here for all the commands which just call some
13 # function without using an explicit 'end' token.
14 end ->
15 '[' -> call cmd_criteria_init(); CRITERIA
16 'move' -> MOVE
17 'exec' -> EXEC
18 'exit' -> call cmd_exit()
19 'restart' -> call cmd_restart()
20 'reload' -> call cmd_reload()
21 'shmlog' -> SHMLOG
22 'debuglog' -> DEBUGLOG
23 'border' -> BORDER
24 'layout' -> LAYOUT
25 'append_layout' -> APPEND_LAYOUT
26 'workspace' -> WORKSPACE
27 'focus' -> FOCUS
28 'kill' -> KILL
29 'open' -> call cmd_open()
30 'fullscreen' -> FULLSCREEN
31 'sticky' -> STICKY
32 'split' -> SPLIT
33 'floating' -> FLOATING
34 'mark' -> MARK
35 'unmark' -> UNMARK
36 'resize' -> RESIZE
37 'rename' -> RENAME
38 'nop' -> NOP
39 'scratchpad' -> SCRATCHPAD
40 'swap' -> SWAP
41 'title_format' -> TITLE_FORMAT
42 'mode' -> MODE
43 'bar' -> BAR
44 'gaps' -> GAPS
45
46 state CRITERIA:
47 ctype = 'class' -> CRITERION
48 ctype = 'instance' -> CRITERION
49 ctype = 'window_role' -> CRITERION
50 ctype = 'con_id' -> CRITERION
51 ctype = 'id' -> CRITERION
52 ctype = 'window_type' -> CRITERION
53 ctype = 'con_mark' -> CRITERION
54 ctype = 'title' -> CRITERION
55 ctype = 'urgent' -> CRITERION
56 ctype = 'workspace' -> CRITERION
57 ctype = 'tiling', 'floating'
58 -> call cmd_criteria_add($ctype, NULL); CRITERIA
59 ']' -> call cmd_criteria_match_windows(); INITIAL
60
61 state CRITERION:
62 '=' -> CRITERION_STR
63
64 state CRITERION_STR:
65 cvalue = word
66 -> call cmd_criteria_add($ctype, $cvalue); CRITERIA
67
68 # exec [--no-startup-id] <command>
69 state EXEC:
70 nosn = '--no-startup-id'
71 ->
72 command = string
73 -> call cmd_exec($nosn, $command)
74
75 # shmlog <size>|toggle|on|off
76 state SHMLOG:
77 # argument may be a number
78 argument = string
79 -> call cmd_shmlog($argument)
80
81 # debuglog toggle|on|off
82 state DEBUGLOG:
83 argument = 'toggle', 'on', 'off'
84 -> call cmd_debuglog($argument)
85
86 # border normal|pixel [<n>]
87 # border none|1pixel|toggle
88 state BORDER:
89 border_style = 'normal', 'pixel', 'toggle'
90 -> BORDER_WIDTH
91 border_style = 'none'
92 -> call cmd_border($border_style, 0)
93 '1pixel'
94 -> call cmd_border("pixel", 1)
95
96 # gaps inner|outer|horizontal|vertical|top|right|bottom|left [current] [set|plus|minus|toggle] <px>
97 state GAPS:
98 type = 'inner', 'outer', 'horizontal', 'vertical', 'top', 'right', 'bottom', 'left'
99 -> GAPS_WITH_TYPE
100
101 state GAPS_WITH_TYPE:
102 scope = 'current', 'all'
103 -> GAPS_WITH_SCOPE
104
105 state GAPS_WITH_SCOPE:
106 mode = 'plus', 'minus', 'set', 'toggle'
107 -> GAPS_WITH_MODE
108
109 state GAPS_WITH_MODE:
110 value = word
111 -> call cmd_gaps($type, $scope, $mode, $value)
112
113 state BORDER_WIDTH:
114 end
115 -> call cmd_border($border_style, -1)
116 border_width = number
117 -> call cmd_border($border_style, &border_width)
118
119 # layout default|stacked|stacking|tabbed|splitv|splith
120 # layout toggle [split|all]
121 state LAYOUT:
122 layout_mode = 'default', 'stacked', 'stacking', 'tabbed', 'splitv', 'splith'
123 -> call cmd_layout($layout_mode)
124 'toggle'
125 -> LAYOUT_TOGGLE
126
127 # layout toggle [split|all]
128 state LAYOUT_TOGGLE:
129 end
130 -> call cmd_layout_toggle($toggle_mode)
131 toggle_mode = string
132 -> call cmd_layout_toggle($toggle_mode)
133
134 # append_layout <path>
135 state APPEND_LAYOUT:
136 path = string -> call cmd_append_layout($path)
137
138 # workspace next|prev|next_on_output|prev_on_output
139 # workspace back_and_forth
140 # workspace [--no-auto-back-and-forth] <name>
141 # workspace [--no-auto-back-and-forth] number <number>
142 state WORKSPACE:
143 no_auto_back_and_forth = '--no-auto-back-and-forth'
144 ->
145 direction = 'next_on_output', 'prev_on_output', 'next', 'prev'
146 -> call cmd_workspace($direction)
147 'back_and_forth'
148 -> call cmd_workspace_back_and_forth()
149 'number'
150 -> WORKSPACE_NUMBER
151 workspace = string
152 -> call cmd_workspace_name($workspace, $no_auto_back_and_forth)
153
154 state WORKSPACE_NUMBER:
155 workspace = string
156 -> call cmd_workspace_number($workspace, $no_auto_back_and_forth)
157
158 # focus left|right|up|down
159 # focus output <output>
160 # focus tiling|floating|mode_toggle
161 # focus parent|child
162 # focus
163 state FOCUS:
164 direction = 'left', 'right', 'up', 'down'
165 -> call cmd_focus_direction($direction)
166 direction = 'prev', 'next'
167 -> FOCUS_AUTO
168 'output'
169 -> FOCUS_OUTPUT
170 window_mode = 'tiling', 'floating', 'mode_toggle'
171 -> call cmd_focus_window_mode($window_mode)
172 level = 'parent', 'child'
173 -> call cmd_focus_level($level)
174 end
175 -> call cmd_focus()
176
177 state FOCUS_AUTO:
178 'sibling'
179 -> call cmd_focus_sibling($direction)
180 end
181 -> call cmd_focus_direction($direction)
182
183 state FOCUS_OUTPUT:
184 output = string
185 -> call cmd_focus_output($output)
186
187 # kill [window|client]
188 state KILL:
189 kill_mode = 'window', 'client'
190 -> call cmd_kill($kill_mode)
191 end
192 -> call cmd_kill($kill_mode)
193
194 # fullscreen enable|toggle [global]
195 # fullscreen disable
196 # fullscreen [global]
197 state FULLSCREEN:
198 action = 'disable'
199 -> call cmd_fullscreen($action, "output")
200 action = 'enable', 'toggle'
201 -> FULLSCREEN_MODE
202 action = ''
203 -> FULLSCREEN_COMPAT
204
205 state FULLSCREEN_MODE:
206 mode = 'global'
207 -> call cmd_fullscreen($action, $mode)
208 end
209 -> call cmd_fullscreen($action, "output")
210
211 state FULLSCREEN_COMPAT:
212 mode = 'global'
213 -> call cmd_fullscreen("toggle", $mode)
214 end
215 -> call cmd_fullscreen("toggle", "output")
216
217 # sticky enable|disable|toggle
218 state STICKY:
219 action = 'enable', 'disable', 'toggle'
220 -> call cmd_sticky($action)
221
222 # split v|h|t|vertical|horizontal|toggle
223 state SPLIT:
224 direction = 'horizontal', 'vertical', 'toggle', 'v', 'h', 't'
225 -> call cmd_split($direction)
226
227 # floating enable|disable|toggle
228 state FLOATING:
229 floating = 'enable', 'disable', 'toggle'
230 -> call cmd_floating($floating)
231
232 # mark [--add|--replace] [--toggle] <mark>
233 state MARK:
234 mode = '--add', '--replace'
235 ->
236 toggle = '--toggle'
237 ->
238 mark = string
239 -> call cmd_mark($mark, $mode, $toggle)
240
241 # unmark [mark]
242 state UNMARK:
243 end
244 -> call cmd_unmark($mark)
245 mark = string
246 -> call cmd_unmark($mark)
247
248 # resize
249 state RESIZE:
250 way = 'grow', 'shrink'
251 -> RESIZE_DIRECTION
252 set = 'set'
253 -> RESIZE_SET
254
255 state RESIZE_DIRECTION:
256 direction = 'up', 'down', 'left', 'right', 'width', 'height'
257 -> RESIZE_PX
258
259 state RESIZE_PX:
260 resize_px = number
261 -> RESIZE_TILING
262 end
263 -> call cmd_resize($way, $direction, 10, 10)
264
265 state RESIZE_TILING:
266 'px'
267 ->
268 'or'
269 -> RESIZE_TILING_OR
270 end
271 -> call cmd_resize($way, $direction, &resize_px, 0)
272
273 state RESIZE_TILING_OR:
274 resize_ppt = number
275 -> RESIZE_TILING_FINAL
276
277 state RESIZE_TILING_FINAL:
278 'ppt', end
279 -> call cmd_resize($way, $direction, &resize_px, &resize_ppt)
280
281 state RESIZE_SET:
282 'height'
283 -> RESIZE_HEIGHT_GET_NUMBER
284 'width'
285 ->
286 width = number
287 -> RESIZE_WIDTH
288
289 state RESIZE_WIDTH:
290 mode_width = 'px', 'ppt'
291 ->
292 end
293 -> call cmd_resize_set(&width, $mode_width, 0, 0)
294 'height'
295 -> RESIZE_HEIGHT_GET_NUMBER
296 height = number
297 -> RESIZE_HEIGHT
298
299 state RESIZE_HEIGHT_GET_NUMBER:
300 height = number
301 -> RESIZE_HEIGHT
302
303 state RESIZE_HEIGHT:
304 mode_height = 'px', 'ppt'
305 ->
306 end
307 -> call cmd_resize_set(&width, $mode_width, &height, $mode_height)
308
309 # rename workspace <name> to <name>
310 # rename workspace to <name>
311 state RENAME:
312 'workspace'
313 -> RENAME_WORKSPACE
314
315 state RENAME_WORKSPACE:
316 'to'
317 -> RENAME_WORKSPACE_LIKELY_TO
318 old_name = word
319 -> RENAME_WORKSPACE_TO
320
321 state RENAME_WORKSPACE_LIKELY_TO:
322 'to '
323 -> RENAME_WORKSPACE_LIKELY_TO_NEW_NAME
324 new_name = word
325 -> call cmd_rename_workspace(NULL, $new_name)
326
327 state RENAME_WORKSPACE_LIKELY_TO_NEW_NAME:
328 new_name = string
329 -> call cmd_rename_workspace("to", $new_name)
330 end
331 -> call cmd_rename_workspace(NULL, "to")
332
333 state RENAME_WORKSPACE_TO:
334 'to'
335 -> RENAME_WORKSPACE_TO_NEW_NAME
336
337 state RENAME_WORKSPACE_TO_NEW_NAME:
338 new_name = string
339 -> call cmd_rename_workspace($old_name, $new_name)
340
341 # move <direction> [<pixels> [px]]
342 # move [window|container] [to] workspace [<str>|next|prev|next_on_output|prev_on_output|current]
343 # move [window|container] [to] output <str>
344 # move [window|container] [to] mark <str>
345 # move [window|container] [to] scratchpad
346 # move workspace to [output] <str>
347 # move scratchpad
348 # move [window|container] [to] [absolute] position [ [<pixels> [px] <pixels> [px]] | center ]
349 # move [window|container] [to] position mouse|cursor|pointer
350 state MOVE:
351 'window'
352 ->
353 'container'
354 ->
355 'to'
356 ->
357 no_auto_back_and_forth = '--no-auto-back-and-forth'
358 ->
359 'workspace'
360 -> MOVE_WORKSPACE
361 'output'
362 -> MOVE_TO_OUTPUT
363 'mark'
364 -> MOVE_TO_MARK
365 'scratchpad'
366 -> call cmd_move_scratchpad()
367 direction = 'left', 'right', 'up', 'down'
368 -> MOVE_DIRECTION
369 method = 'position'
370 -> MOVE_TO_POSITION
371 method = 'absolute'
372 -> MOVE_TO_ABSOLUTE_POSITION
373
374 state MOVE_DIRECTION:
375 pixels = number
376 -> MOVE_DIRECTION_PX
377 end
378 -> call cmd_move_direction($direction, 10)
379
380 state MOVE_DIRECTION_PX:
381 'px'
382 -> call cmd_move_direction($direction, &pixels)
383 end
384 -> call cmd_move_direction($direction, &pixels)
385
386 state MOVE_WORKSPACE:
387 'to '
388 -> MOVE_WORKSPACE_TO_OUTPUT
389 workspace = 'next_on_output', 'prev_on_output', 'next', 'prev', 'current'
390 -> call cmd_move_con_to_workspace($workspace)
391 'back_and_forth'
392 -> call cmd_move_con_to_workspace_back_and_forth()
393 'number'
394 -> MOVE_WORKSPACE_NUMBER
395 workspace = string
396 -> call cmd_move_con_to_workspace_name($workspace, $no_auto_back_and_forth)
397
398 state MOVE_WORKSPACE_NUMBER:
399 number = string
400 -> call cmd_move_con_to_workspace_number($number, $no_auto_back_and_forth)
401
402 state MOVE_TO_OUTPUT:
403 output = string
404 -> call cmd_move_con_to_output($output)
405
406 state MOVE_TO_MARK:
407 mark = string
408 -> call cmd_move_con_to_mark($mark)
409
410 state MOVE_WORKSPACE_TO_OUTPUT:
411 'output'
412 ->
413 output = string
414 -> call cmd_move_workspace_to_output($output)
415
416 state MOVE_TO_ABSOLUTE_POSITION:
417 'position'
418 -> MOVE_TO_POSITION
419
420 state MOVE_TO_POSITION:
421 'center'
422 -> call cmd_move_window_to_center($method)
423 'mouse', 'cursor', 'pointer'
424 -> call cmd_move_window_to_mouse()
425 coord_x = number
426 -> MOVE_TO_POSITION_X
427
428 state MOVE_TO_POSITION_X:
429 'px'
430 ->
431 coord_y = number
432 -> MOVE_TO_POSITION_Y
433
434 state MOVE_TO_POSITION_Y:
435 'px', end
436 -> call cmd_move_window_to_position(&coord_x, &coord_y)
437
438 # mode <string>
439 state MODE:
440 mode = string
441 -> call cmd_mode($mode)
442
443 state NOP:
444 comment = string
445 -> call cmd_nop($comment)
446 end
447 -> call cmd_nop(NULL)
448
449 state SCRATCHPAD:
450 'show'
451 -> call cmd_scratchpad_show()
452
453 # swap [container] [with] id <window>
454 # swap [container] [with] con_id <con_id>
455 # swap [container] [with] mark <mark>
456 state SWAP:
457 'container'
458 ->
459 'with'
460 ->
461 mode = 'id', 'con_id', 'mark'
462 -> SWAP_ARGUMENT
463
464 state SWAP_ARGUMENT:
465 arg = string
466 -> call cmd_swap($mode, $arg)
467
468 state TITLE_FORMAT:
469 format = string
470 -> call cmd_title_format($format)
471
472 # bar (hidden_state hide|show|toggle)|(mode dock|hide|invisible|toggle) [<bar_id>]
473 state BAR:
474 bar_type = 'hidden_state'
475 -> BAR_HIDDEN_STATE
476 bar_type = 'mode'
477 -> BAR_MODE
478
479 state BAR_HIDDEN_STATE:
480 bar_value = 'hide', 'show', 'toggle'
481 -> BAR_W_ID
482
483 state BAR_MODE:
484 bar_value = 'dock', 'hide', 'invisible', 'toggle'
485 -> BAR_W_ID
486
487 state BAR_W_ID:
488 bar_id = word
489 ->
490 end
491 -> call cmd_bar($bar_type, $bar_value, $bar_id)
0 # vim:ts=2:sw=2:expandtab
1 #
2 # i3 - an improved dynamic tiling window manager
3 # © 2009 Michael Stapelberg and contributors (see also: LICENSE)
4 #
5 # parser-specs/config.spec: Specification file for generate-command-parser.pl
6 # which will generate the appropriate header files for our C parser.
7 #
8 # Use :source highlighting.vim in vim to get syntax highlighting
9 # for this file.
10
11 # TODO: should we implement an include statement for the criteria part so we DRY?
12
13 state INITIAL:
14 # We have an end token here for all the commands which just call some
15 # function without using an explicit 'end' token.
16 end ->
17 error ->
18 '#' -> IGNORE_LINE
19 'set ' -> IGNORE_LINE
20 'set ' -> IGNORE_LINE
21 'set_from_resource' -> IGNORE_LINE
22 bindtype = 'bindsym', 'bindcode', 'bind' -> BINDING
23 'bar' -> BARBRACE
24 'font' -> FONT
25 'mode' -> MODENAME
26 'gaps' -> GAPS
27 'smart_borders' -> SMART_BORDERS
28 'smart_gaps' -> SMART_GAPS
29 'floating_minimum_size' -> FLOATING_MINIMUM_SIZE_WIDTH
30 'floating_maximum_size' -> FLOATING_MAXIMUM_SIZE_WIDTH
31 'floating_modifier' -> FLOATING_MODIFIER
32 'default_orientation' -> DEFAULT_ORIENTATION
33 'workspace_layout' -> WORKSPACE_LAYOUT
34 windowtype = 'default_border', 'new_window', 'default_floating_border', 'new_float'
35 -> DEFAULT_BORDER
36 'hide_edge_borders' -> HIDE_EDGE_BORDERS
37 'for_window' -> FOR_WINDOW
38 'assign' -> ASSIGN
39 'no_focus' -> NO_FOCUS
40 'focus_follows_mouse' -> FOCUS_FOLLOWS_MOUSE
41 'mouse_warping' -> MOUSE_WARPING
42 'focus_wrapping' -> FOCUS_WRAPPING
43 'force_focus_wrapping' -> FORCE_FOCUS_WRAPPING
44 'force_xinerama', 'force-xinerama' -> FORCE_XINERAMA
45 'disable_randr15', 'disable-randr15' -> DISABLE_RANDR15
46 'workspace_auto_back_and_forth' -> WORKSPACE_BACK_AND_FORTH
47 'fake_outputs', 'fake-outputs' -> FAKE_OUTPUTS
48 'force_display_urgency_hint' -> FORCE_DISPLAY_URGENCY_HINT
49 'focus_on_window_activation' -> FOCUS_ON_WINDOW_ACTIVATION
50 'title_align' -> TITLE_ALIGN
51 'show_marks' -> SHOW_MARKS
52 'workspace' -> WORKSPACE
53 'ipc_socket', 'ipc-socket' -> IPC_SOCKET
54 'ipc_kill_timeout' -> IPC_KILL_TIMEOUT
55 'restart_state' -> RESTART_STATE
56 'popup_during_fullscreen' -> POPUP_DURING_FULLSCREEN
57 exectype = 'exec_always', 'exec' -> EXEC
58 colorclass = 'client.background'
59 -> COLOR_SINGLE
60 colorclass = 'client.focused_inactive', 'client.focused', 'client.unfocused', 'client.urgent', 'client.placeholder'
61 -> COLOR_BORDER
62
63 # We ignore comments and 'set' lines (variables).
64 state IGNORE_LINE:
65 line
66 -> INITIAL
67
68 # gaps inner|outer|horizontal|vertical|top|right|bottom|left <px>
69 state GAPS:
70 scope = 'inner', 'outer', 'horizontal', 'vertical', 'top', 'right', 'bottom', 'left'
71 -> GAPS_WITH_SCOPE
72
73 state GAPS_WITH_SCOPE:
74 value = number
75 -> call cfg_gaps($workspace, $scope, &value)
76
77 # smart_borders true|false
78 # smart_borders no_gaps
79 state SMART_BORDERS:
80 enabled = '1', 'yes', 'true', 'on', 'enable', 'active'
81 -> call cfg_smart_borders($enabled)
82 enabled = 'no_gaps'
83 -> call cfg_smart_borders($enabled)
84
85 # smart_gaps on|off
86 state SMART_GAPS:
87 enabled = '1', 'yes', 'true', 'on', 'enable', 'active'
88 -> call cfg_smart_gaps($enabled)
89 enabled = 'inverse_outer'
90 -> call cfg_smart_gaps($enabled)
91
92 # floating_minimum_size <width> x <height>
93 state FLOATING_MINIMUM_SIZE_WIDTH:
94 width = number
95 -> FLOATING_MINIMUM_SIZE_X
96
97 state FLOATING_MINIMUM_SIZE_X:
98 'x'
99 -> FLOATING_MINIMUM_SIZE_HEIGHT
100
101 state FLOATING_MINIMUM_SIZE_HEIGHT:
102 height = number
103 -> call cfg_floating_minimum_size(&width, &height)
104
105 # floating_maximum_size <width> x <height>
106 state FLOATING_MAXIMUM_SIZE_WIDTH:
107 width = number
108 -> FLOATING_MAXIMUM_SIZE_X
109
110 state FLOATING_MAXIMUM_SIZE_X:
111 'x'
112 -> FLOATING_MAXIMUM_SIZE_HEIGHT
113
114 state FLOATING_MAXIMUM_SIZE_HEIGHT:
115 height = number
116 -> call cfg_floating_maximum_size(&width, &height)
117
118 # floating_modifier <modifier>
119 state FLOATING_MODIFIER:
120 modifiers = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Shift', 'Control', 'Ctrl'
121 ->
122 '+'
123 ->
124 end
125 -> call cfg_floating_modifier($modifiers)
126
127 # default_orientation <horizontal|vertical|auto>
128 state DEFAULT_ORIENTATION:
129 orientation = 'horizontal', 'vertical', 'auto'
130 -> call cfg_default_orientation($orientation)
131
132 # workspace_layout <default|stacking|tabbed>
133 state WORKSPACE_LAYOUT:
134 layout = 'default', 'stacking', 'stacked', 'tabbed'
135 -> call cfg_workspace_layout($layout)
136
137 # <default_border|new_window> <normal|1pixel|none>
138 # <default_floating_border|new_float> <normal|1pixel|none>
139 state DEFAULT_BORDER:
140 border = 'normal', 'pixel'
141 -> DEFAULT_BORDER_PIXELS
142 border = '1pixel', 'none'
143 -> call cfg_default_border($windowtype, $border, -1)
144
145 state DEFAULT_BORDER_PIXELS:
146 end
147 -> call cfg_default_border($windowtype, $border, 2)
148 width = number
149 -> DEFAULT_BORDER_PIXELS_PX
150
151 state DEFAULT_BORDER_PIXELS_PX:
152 'px'
153 ->
154 end
155 -> call cfg_default_border($windowtype, $border, &width)
156
157 # hide_edge_borders <none|vertical|horizontal|both|smart|no_gaps>
158 # also hide_edge_borders <bool> for compatibility
159 state HIDE_EDGE_BORDERS:
160 hide_borders = 'none', 'vertical', 'horizontal', 'both', 'smart_no_gaps', 'smart'
161 -> call cfg_hide_edge_borders($hide_borders)
162 hide_borders = '1', 'yes', 'true', 'on', 'enable', 'active'
163 -> call cfg_hide_edge_borders($hide_borders)
164
165 # for_window <criteria> command
166 state FOR_WINDOW:
167 '['
168 -> call cfg_criteria_init(FOR_WINDOW_COMMAND); CRITERIA
169
170 state FOR_WINDOW_COMMAND:
171 command = string
172 -> call cfg_for_window($command)
173
174 # assign <criteria> [→] [workspace | output] <name>
175 state ASSIGN:
176 '['
177 -> call cfg_criteria_init(ASSIGN_WORKSPACE); CRITERIA
178
179 state ASSIGN_WORKSPACE:
180 '→'
181 ->
182 'output'
183 -> ASSIGN_OUTPUT
184 'workspace'
185 ->
186 'number'
187 -> ASSIGN_WORKSPACE_NUMBER
188 workspace = string
189 -> call cfg_assign($workspace, 0)
190
191 state ASSIGN_OUTPUT:
192 output = string
193 -> call cfg_assign_output($output)
194
195 state ASSIGN_WORKSPACE_NUMBER:
196 number = string
197 -> call cfg_assign($number, 1)
198
199 # no_focus <criteria>
200 state NO_FOCUS:
201 '['
202 -> call cfg_criteria_init(NO_FOCUS_END); CRITERIA
203
204 state NO_FOCUS_END:
205 end
206 -> call cfg_no_focus()
207
208 # Criteria: Used by for_window and assign.
209 state CRITERIA:
210 ctype = 'class' -> CRITERION
211 ctype = 'instance' -> CRITERION
212 ctype = 'window_role' -> CRITERION
213 ctype = 'con_id' -> CRITERION
214 ctype = 'id' -> CRITERION
215 ctype = 'window_type' -> CRITERION
216 ctype = 'con_mark' -> CRITERION
217 ctype = 'title' -> CRITERION
218 ctype = 'urgent' -> CRITERION
219 ctype = 'workspace' -> CRITERION
220 ctype = 'floating_from' -> CRITERION_FROM
221 ctype = 'tiling_from' -> CRITERION_FROM
222 ctype = 'tiling', 'floating'
223 -> call cfg_criteria_add($ctype, NULL); CRITERIA
224 ']'
225 -> call cfg_criteria_pop_state()
226
227 state CRITERION:
228 '=' -> CRITERION_STR
229
230 state CRITERION_FROM:
231 '=' -> CRITERION_FROM_STR_START
232
233 state CRITERION_FROM_STR_START:
234 '"' -> CRITERION_FROM_STR
235 kind = 'auto', 'user'
236 -> call cfg_criteria_add($ctype, $kind); CRITERIA
237
238 state CRITERION_FROM_STR:
239 kind = 'auto', 'user'
240 -> CRITERION_FROM_STR_END
241
242 state CRITERION_FROM_STR_END:
243 '"'
244 -> call cfg_criteria_add($ctype, $kind); CRITERIA
245
246 state CRITERION_STR:
247 cvalue = word
248 -> call cfg_criteria_add($ctype, $cvalue); CRITERIA
249
250 # focus_follows_mouse bool
251 state FOCUS_FOLLOWS_MOUSE:
252 value = word
253 -> call cfg_focus_follows_mouse($value)
254
255 # mouse_warping warping_t
256 state MOUSE_WARPING:
257 value = 'none', 'output'
258 -> call cfg_mouse_warping($value)
259
260 # focus_wrapping
261 state FOCUS_WRAPPING:
262 value = '1', 'yes', 'true', 'on', 'enable', 'active', '0', 'no', 'false', 'off', 'disable', 'inactive', 'force', 'workspace'
263 -> call cfg_focus_wrapping($value)
264
265 # force_focus_wrapping
266 state FORCE_FOCUS_WRAPPING:
267 value = word
268 -> call cfg_force_focus_wrapping($value)
269
270 # force_xinerama
271 state FORCE_XINERAMA:
272 value = word
273 -> call cfg_force_xinerama($value)
274
275 # disable_randr15
276 state DISABLE_RANDR15:
277 value = word
278 -> call cfg_disable_randr15($value)
279
280 # workspace_back_and_forth
281 state WORKSPACE_BACK_AND_FORTH:
282 value = word
283 -> call cfg_workspace_back_and_forth($value)
284
285
286 # fake_outputs (for testcases)
287 state FAKE_OUTPUTS:
288 outputs = string
289 -> call cfg_fake_outputs($outputs)
290
291 # force_display_urgency_hint <timeout> ms
292 state FORCE_DISPLAY_URGENCY_HINT:
293 duration_ms = number
294 -> FORCE_DISPLAY_URGENCY_HINT_MS
295
296 # title_align [left|center|right]
297 state TITLE_ALIGN:
298 alignment = 'left', 'center', 'right'
299 -> call cfg_title_align($alignment)
300
301 # show_marks
302 state SHOW_MARKS:
303 value = word
304 -> call cfg_show_marks($value)
305
306 state FORCE_DISPLAY_URGENCY_HINT_MS:
307 'ms'
308 ->
309 end
310 -> call cfg_force_display_urgency_hint(&duration_ms)
311
312 # focus_on_window_activation <smart|urgent|focus|none>
313 state FOCUS_ON_WINDOW_ACTIVATION:
314 mode = word
315 -> call cfg_focus_on_window_activation($mode)
316
317 # workspace <workspace> output <output>
318 # workspace <workspace> gaps inner|outer <px>
319 state WORKSPACE:
320 workspace = word
321 -> WORKSPACE_COMMAND
322
323 state WORKSPACE_COMMAND:
324 'output'
325 -> WORKSPACE_OUTPUT_WORD
326 'gaps'
327 -> GAPS
328
329 state WORKSPACE_OUTPUT_WORD:
330 output = word
331 -> call cfg_workspace($workspace, $output); WORKSPACE_OUTPUT_WORD
332 end
333 -> INITIAL
334
335 # ipc-socket <path>
336 state IPC_SOCKET:
337 path = string
338 -> call cfg_ipc_socket($path)
339
340 # ipc_kill_timeout
341 state IPC_KILL_TIMEOUT:
342 timeout = number
343 -> call cfg_ipc_kill_timeout(&timeout)
344
345 # restart_state <path> (for testcases)
346 state RESTART_STATE:
347 path = string
348 -> call cfg_restart_state($path)
349
350 # popup_during_fullscreen
351 state POPUP_DURING_FULLSCREEN:
352 value = 'ignore', 'leave_fullscreen', 'smart'
353 -> call cfg_popup_during_fullscreen($value)
354
355 # client.background <hexcolor>
356 state COLOR_SINGLE:
357 color = word
358 -> call cfg_color_single($colorclass, $color)
359
360 # colorclass border background text indicator
361 state COLOR_BORDER:
362 border = word
363 -> COLOR_BACKGROUND
364
365 state COLOR_BACKGROUND:
366 background = word
367 -> COLOR_TEXT
368
369 state COLOR_TEXT:
370 text = word
371 -> COLOR_INDICATOR
372
373 state COLOR_INDICATOR:
374 indicator = word
375 -> COLOR_CHILD_BORDER
376 end
377 -> call cfg_color($colorclass, $border, $background, $text, NULL, NULL)
378
379 state COLOR_CHILD_BORDER:
380 child_border = word
381 -> call cfg_color($colorclass, $border, $background, $text, $indicator, $child_border)
382 end
383 -> call cfg_color($colorclass, $border, $background, $text, $indicator, NULL)
384
385 # <exec|exec_always> [--no-startup-id] command
386 state EXEC:
387 no_startup_id = '--no-startup-id'
388 ->
389 command = string
390 -> call cfg_exec($exectype, $no_startup_id, $command)
391
392 # font font
393 state FONT:
394 font = string
395 -> call cfg_font($font)
396
397 # bindsym/bindcode
398 state BINDING:
399 release = '--release'
400 ->
401 border = '--border'
402 ->
403 whole_window = '--whole-window'
404 ->
405 exclude_titlebar = '--exclude-titlebar'
406 ->
407 modifiers = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Shift', 'Control', 'Ctrl', 'Mode_switch', 'Group1', 'Group2', 'Group3', 'Group4', '$mod'
408 ->
409 '+'
410 ->
411 key = word
412 -> BINDCOMMAND
413
414 state BINDCOMMAND:
415 release = '--release'
416 ->
417 border = '--border'
418 ->
419 whole_window = '--whole-window'
420 ->
421 exclude_titlebar = '--exclude-titlebar'
422 ->
423 command = string
424 -> call cfg_binding($bindtype, $modifiers, $key, $release, $border, $whole_window, $exclude_titlebar, $command)
425
426 ################################################################################
427 # Mode configuration
428 ################################################################################
429
430 state MODENAME:
431 pango_markup = '--pango_markup'
432 ->
433 modename = word
434 -> call cfg_enter_mode($pango_markup, $modename); MODEBRACE
435
436 state MODEBRACE:
437 end
438 ->
439 '{'
440 -> MODE
441
442 state MODE:
443 end ->
444 error ->
445 '#' -> MODE_IGNORE_LINE
446 'set' -> MODE_IGNORE_LINE
447 bindtype = 'bindsym', 'bindcode', 'bind'
448 -> MODE_BINDING
449 '}'
450 -> INITIAL
451
452 # We ignore comments and 'set' lines (variables).
453 state MODE_IGNORE_LINE:
454 line
455 -> MODE
456
457 state MODE_BINDING:
458 release = '--release'
459 ->
460 border = '--border'
461 ->
462 whole_window = '--whole-window'
463 ->
464 exclude_titlebar = '--exclude-titlebar'
465 ->
466 modifiers = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Shift', 'Control', 'Ctrl', 'Mode_switch', 'Group1', 'Group2', 'Group3', 'Group4', '$mod'
467 ->
468 '+'
469 ->
470 key = word
471 -> MODE_BINDCOMMAND
472
473 state MODE_BINDCOMMAND:
474 release = '--release'
475 ->
476 border = '--border'
477 ->
478 whole_window = '--whole-window'
479 ->
480 exclude_titlebar = '--exclude-titlebar'
481 ->
482 command = string
483 -> call cfg_mode_binding($bindtype, $modifiers, $key, $release, $border, $whole_window, $exclude_titlebar, $command); MODE
484
485 ################################################################################
486 # Bar configuration (i3bar)
487 ################################################################################
488
489 state BARBRACE:
490 end
491 ->
492 '{'
493 -> call cfg_bar_start(); BAR
494
495 state BAR:
496 end ->
497 error ->
498 '#' -> BAR_IGNORE_LINE
499 'set' -> BAR_IGNORE_LINE
500 'i3bar_command' -> BAR_BAR_COMMAND
501 'status_command' -> BAR_STATUS_COMMAND
502 'socket_path' -> BAR_SOCKET_PATH
503 'mode' -> BAR_MODE
504 'hidden_state' -> BAR_HIDDEN_STATE
505 'id' -> BAR_ID
506 'modifier' -> BAR_MODIFIER
507 'wheel_up_cmd' -> BAR_WHEEL_UP_CMD
508 'wheel_down_cmd' -> BAR_WHEEL_DOWN_CMD
509 'bindsym' -> BAR_BINDSYM
510 'position' -> BAR_POSITION
511 'output' -> BAR_OUTPUT
512 'tray_output' -> BAR_TRAY_OUTPUT
513 'tray_padding' -> BAR_TRAY_PADDING
514 'font' -> BAR_FONT
515 'separator_symbol' -> BAR_SEPARATOR_SYMBOL
516 'binding_mode_indicator' -> BAR_BINDING_MODE_INDICATOR
517 'workspace_buttons' -> BAR_WORKSPACE_BUTTONS
518 'workspace_min_width' -> BAR_WORKSPACE_MIN_WIDTH
519 'strip_workspace_numbers' -> BAR_STRIP_WORKSPACE_NUMBERS
520 'strip_workspace_name' -> BAR_STRIP_WORKSPACE_NAME
521 'verbose' -> BAR_VERBOSE
522 'height' -> BAR_HEIGHT
523 'colors' -> BAR_COLORS_BRACE
524 '}'
525 -> call cfg_bar_finish(); INITIAL
526
527 # We ignore comments and 'set' lines (variables).
528 state BAR_IGNORE_LINE:
529 line
530 -> BAR
531
532 state BAR_BAR_COMMAND:
533 command = string
534 -> call cfg_bar_i3bar_command($command); BAR
535
536 state BAR_STATUS_COMMAND:
537 command = string
538 -> call cfg_bar_status_command($command); BAR
539
540 state BAR_SOCKET_PATH:
541 path = string
542 -> call cfg_bar_socket_path($path); BAR
543
544 state BAR_MODE:
545 mode = 'dock', 'hide', 'invisible'
546 -> call cfg_bar_mode($mode); BAR
547
548 state BAR_HIDDEN_STATE:
549 hidden_state = 'hide', 'show'
550 -> call cfg_bar_hidden_state($hidden_state); BAR
551
552 state BAR_ID:
553 bar_id = word
554 -> call cfg_bar_id($bar_id); BAR
555
556 state BAR_MODIFIER:
557 'off', 'none'
558 -> call cfg_bar_modifier(NULL); BAR
559 modifiers = 'Mod1', 'Mod2', 'Mod3', 'Mod4', 'Mod5', 'Shift', 'Control', 'Ctrl'
560 ->
561 '+'
562 ->
563 end
564 -> call cfg_bar_modifier($modifiers); BAR
565
566 state BAR_WHEEL_UP_CMD:
567 command = string
568 -> call cfg_bar_wheel_up_cmd($command); BAR
569
570 state BAR_WHEEL_DOWN_CMD:
571 command = string
572 -> call cfg_bar_wheel_down_cmd($command); BAR
573
574 state BAR_BINDSYM:
575 release = '--release'
576 ->
577 button = word
578 -> BAR_BINDSYM_COMMAND
579
580 state BAR_BINDSYM_COMMAND:
581 release = '--release'
582 ->
583 command = string
584 -> call cfg_bar_bindsym($button, $release, $command); BAR
585
586 state BAR_POSITION:
587 position = 'top', 'bottom'
588 -> call cfg_bar_position($position); BAR
589
590 state BAR_OUTPUT:
591 output = string
592 -> call cfg_bar_output($output); BAR
593
594 state BAR_TRAY_OUTPUT:
595 output = word
596 -> call cfg_bar_tray_output($output); BAR
597
598 state BAR_TRAY_PADDING:
599 padding_px = number
600 -> BAR_TRAY_PADDING_PX
601
602 state BAR_TRAY_PADDING_PX:
603 'px'
604 ->
605 end
606 -> call cfg_bar_tray_padding(&padding_px); BAR
607
608 state BAR_FONT:
609 font = string
610 -> call cfg_bar_font($font); BAR
611
612 state BAR_SEPARATOR_SYMBOL:
613 separator = string
614 -> call cfg_bar_separator_symbol($separator); BAR
615
616 state BAR_BINDING_MODE_INDICATOR:
617 value = word
618 -> call cfg_bar_binding_mode_indicator($value); BAR
619
620 state BAR_WORKSPACE_BUTTONS:
621 value = word
622 -> call cfg_bar_workspace_buttons($value); BAR
623
624 state BAR_WORKSPACE_MIN_WIDTH:
625 width = number
626 -> BAR_WORKSPACE_MIN_WIDTH_PX
627
628 state BAR_WORKSPACE_MIN_WIDTH_PX:
629 'px'
630 ->
631 end
632 -> call cfg_bar_workspace_min_width(&width); BAR
633
634 state BAR_STRIP_WORKSPACE_NUMBERS:
635 value = word
636 -> call cfg_bar_strip_workspace_numbers($value); BAR
637
638 state BAR_STRIP_WORKSPACE_NAME:
639 value = word
640 -> call cfg_bar_strip_workspace_name($value); BAR
641
642 state BAR_VERBOSE:
643 value = word
644 -> call cfg_bar_verbose($value); BAR
645
646 state BAR_HEIGHT:
647 value = number
648 -> call cfg_bar_height(&value); BAR
649
650 state BAR_COLORS_BRACE:
651 end
652 ->
653 '{'
654 -> BAR_COLORS
655
656 state BAR_COLORS:
657 end ->
658 '#' -> BAR_COLORS_IGNORE_LINE
659 'set' -> BAR_COLORS_IGNORE_LINE
660 colorclass = 'background', 'statusline', 'separator', 'focused_background', 'focused_statusline', 'focused_separator'
661 -> BAR_COLORS_SINGLE
662 colorclass = 'focused_workspace', 'active_workspace', 'inactive_workspace', 'urgent_workspace', 'binding_mode'
663 -> BAR_COLORS_BORDER
664 '}'
665 -> BAR
666
667 # We ignore comments and 'set' lines (variables).
668 state BAR_COLORS_IGNORE_LINE:
669 line
670 -> BAR_COLORS
671
672 state BAR_COLORS_SINGLE:
673 color = word
674 -> call cfg_bar_color_single($colorclass, $color); BAR_COLORS
675
676 state BAR_COLORS_BORDER:
677 border = word
678 -> BAR_COLORS_BACKGROUND
679
680 state BAR_COLORS_BACKGROUND:
681 background = word
682 -> BAR_COLORS_TEXT
683
684 state BAR_COLORS_TEXT:
685 end
686 -> call cfg_bar_color($colorclass, $border, $background, NULL); BAR_COLORS
687 text = word
688 -> call cfg_bar_color($colorclass, $border, $background, $text); BAR_COLORS
0 set filetype=i3cmd
1 syntax case match
2 syntax clear
3
4 syntax keyword i3specStatement state call
5 highlight link i3specStatement Statement
6
7 syntax match i3specComment /#.*/
8 highlight link i3specComment Comment
9
10 syntax region i3specLiteral start=/'/ end=/'/
11 syntax keyword i3specToken string word number end
12 highlight link i3specLiteral String
13 highlight link i3specToken String
14
15 syntax match i3specState /[A-Z_]\{3,}/
16 highlight link i3specState PreProc
17
18 syntax match i3specSpecial /[->]/
19 highlight link i3specSpecial Special
0 # Doxyfile 1.5.6
1 #
2 # You can use this file with doxygen to create a pseudo-documentation
3 # automatically from source. doxygen-comments are not used very extensively
4 # in i3, mostly for the reason that it clutters the source code and has no
5 # real use (doxygen’s output looks really ugly).
6 #
7 # So, if you want to use it, here you go. This is however not a supported
8 # document, and I recommend you have a look at the docs/ folder or at
9 # https://i3wm.org/ for more, real documentation.
10 #
11
12 #---------------------------------------------------------------------------
13 # Project related configuration options
14 #---------------------------------------------------------------------------
15
16 DOXYFILE_ENCODING = UTF-8
17 PROJECT_NAME = i3
18 PROJECT_NUMBER =
19 OUTPUT_DIRECTORY = pseudo-doc
20 OUTPUT_LANGUAGE = English
21 BRIEF_MEMBER_DESC = YES
22 REPEAT_BRIEF = YES
23 ALWAYS_DETAILED_SEC = YES
24 FULL_PATH_NAMES = YES
25 SHORT_NAMES = YES
26 JAVADOC_AUTOBRIEF = YES
27 TAB_SIZE = 8
28 OPTIMIZE_OUTPUT_FOR_C = YES
29
30 #---------------------------------------------------------------------------
31 # Build related configuration options
32 #---------------------------------------------------------------------------
33
34 EXTRACT_ALL = YES
35 EXTRACT_PRIVATE = NO
36 EXTRACT_STATIC = YES
37 EXTRACT_LOCAL_CLASSES = YES
38 CASE_SENSE_NAMES = YES
39 SHOW_INCLUDE_FILES = YES
40 SORT_MEMBER_DOCS = YES
41 SORT_BRIEF_DOCS = NO
42 SORT_GROUP_NAMES = NO
43 SORT_BY_SCOPE_NAME = NO
44 SHOW_USED_FILES = YES
45 SHOW_FILES = YES
46
47 #---------------------------------------------------------------------------
48 # configuration options related to warning and progress messages
49 #---------------------------------------------------------------------------
50
51 QUIET = NO
52 WARNINGS = YES
53 WARN_IF_UNDOCUMENTED = YES
54 WARN_IF_DOC_ERROR = YES
55 WARN_NO_PARAMDOC = NO
56 WARN_FORMAT = "$file:$line: $text"
57 WARN_LOGFILE =
58
59 #---------------------------------------------------------------------------
60 # configuration options related to the input files
61 #---------------------------------------------------------------------------
62
63 INPUT = src include
64 INPUT_ENCODING = UTF-8
65 RECURSIVE = NO
66
67 #---------------------------------------------------------------------------
68 # configuration options related to source browsing
69 #---------------------------------------------------------------------------
70
71 SOURCE_BROWSER = YES
72 INLINE_SOURCES = NO
73
74 STRIP_CODE_COMMENTS = YES
75
76 REFERENCED_BY_RELATION = YES
77 REFERENCES_RELATION = YES
78 REFERENCES_LINK_SOURCE = YES
79
80 #---------------------------------------------------------------------------
81 # configuration options related to the alphabetical class index
82 #---------------------------------------------------------------------------
83
84 ALPHABETICAL_INDEX = NO
85 COLS_IN_ALPHA_INDEX = 5
86
87 #---------------------------------------------------------------------------
88 # configuration options related to the HTML output
89 #---------------------------------------------------------------------------
90
91 GENERATE_HTML = YES
92 HTML_OUTPUT = html
93 HTML_FILE_EXTENSION = .html
94 HTML_ALIGN_MEMBERS = YES
95 HTML_DYNAMIC_SECTIONS = NO
96 FORMULA_FONTSIZE = 10
97
98 GENERATE_LATEX = NO
99 GENERATE_RTF = NO
100 GENERATE_MAN = NO
101 GENERATE_XML = NO
102 GENERATE_AUTOGEN_DEF = NO
103 GENERATE_PERLMOD = NO
104
105 ENABLE_PREPROCESSING = YES
106 MACRO_EXPANSION = NO
107 EXPAND_ONLY_PREDEF = NO
108 SEARCH_INCLUDES = YES
109 SKIP_FUNCTION_MACROS = YES
110
111 #---------------------------------------------------------------------------
112 # Configuration::additions related to external references
113 #---------------------------------------------------------------------------
114
115 PERL_PATH = /usr/bin/perl
116
117 #---------------------------------------------------------------------------
118 # Configuration options related to the dot tool
119 #---------------------------------------------------------------------------
120
121 CLASS_DIAGRAMS = YES
122 HAVE_DOT = YES
123 DOT_FONTNAME = FreeSans
124 DOT_FONTPATH =
125 CLASS_GRAPH = YES
126 COLLABORATION_GRAPH = YES
127 GROUP_GRAPHS = YES
128 UML_LOOK = NO
129 INCLUDE_GRAPH = YES
130 INCLUDED_BY_GRAPH = YES
131 CALL_GRAPH = YES
132 CALLER_GRAPH = NO
133 GRAPHICAL_HIERARCHY = YES
134 DIRECTORY_GRAPH = YES
135 DOT_IMAGE_FORMAT = png
136 DOT_GRAPH_MAX_NODES = 50
137 MAX_DOT_GRAPH_DEPTH = 0
138 DOT_TRANSPARENT = YES
139 DOT_MULTI_TARGETS = NO
140 GENERATE_LEGEND = YES
141 DOT_CLEANUP = YES
142
143 #---------------------------------------------------------------------------
144 # Configuration::additions related to the search engine
145 #---------------------------------------------------------------------------
146
147 SEARCHENGINE = NO
0 #!/bin/zsh
1 # This script is used to prepare a new release of i3.
2
3 export RELEASE_VERSION="4.17"
4 export PREVIOUS_VERSION="4.16"
5 export RELEASE_BRANCH="next"
6
7 if [ ! -e "../i3.github.io" ]
8 then
9 echo "../i3.github.io does not exist."
10 echo "Use git clone https://github.com/i3/i3.github.io"
11 exit 1
12 fi
13
14 if ! (cd ../i3.github.io && git pull)
15 then
16 echo "Could not update ../i3.github.io repository"
17 exit 1
18 fi
19
20 if [ ! -e "RELEASE-NOTES-${RELEASE_VERSION}" ]
21 then
22 echo "RELEASE-NOTES-${RELEASE_VERSION} not found."
23 exit 1
24 fi
25
26 if git diff-files --quiet --exit-code debian/changelog
27 then
28 echo "Expected debian/changelog to be changed (containing the changelog for ${RELEASE_VERSION})."
29 exit 1
30 fi
31
32 eval $(gpg-agent --daemon)
33 export GPG_AGENT_INFO
34
35 ################################################################################
36 # Section 1: update git and build the release tarball
37 ################################################################################
38
39 STARTDIR=$PWD
40
41 TMPDIR=$(mktemp -d)
42 cd $TMPDIR
43 if ! wget https://i3wm.org/downloads/i3-${PREVIOUS_VERSION}.tar.bz2; then
44 echo "Could not download i3-${PREVIOUS_VERSION}.tar.bz2 (required for comparing files)."
45 exit 1
46 fi
47 git clone --quiet --branch "${RELEASE_BRANCH}" https://github.com/i3/i3
48 cd i3
49 if [ ! -e "${STARTDIR}/RELEASE-NOTES-${RELEASE_VERSION}" ]; then
50 echo "Required file RELEASE-NOTES-${RELEASE_VERSION} not found."
51 exit 1
52 fi
53 git checkout -b release-${RELEASE_VERSION}
54 cp "${STARTDIR}/RELEASE-NOTES-${RELEASE_VERSION}" "RELEASE-NOTES-${RELEASE_VERSION}"
55 git add RELEASE-NOTES-${RELEASE_VERSION}
56 git rm RELEASE-NOTES-${PREVIOUS_VERSION}
57 sed -i "s,RELEASE-NOTES-${PREVIOUS_VERSION},RELEASE-NOTES-${RELEASE_VERSION},g" Makefile.am
58 sed -i "s/AC_INIT(\[i3\], \[${PREVIOUS_VERSION}\]/AC_INIT([i3], [${RELEASE_VERSION}]/" configure.ac
59 echo "${RELEASE_VERSION} ($(date +%F))" > I3_VERSION
60 git add I3_VERSION
61 git commit -a -m "release i3 ${RELEASE_VERSION}"
62 git tag "${RELEASE_VERSION}" -m "release i3 ${RELEASE_VERSION}" --sign --local-user=0x4AC8EE1D
63
64 autoreconf -fi
65 mkdir build
66 (cd build && ../configure && make dist-bzip2 -j8)
67 cp build/i3-${RELEASE_VERSION}.tar.bz2 .
68
69 echo "Differences in the release tarball file lists:"
70
71 diff -u \
72 <(tar tf ../i3-${PREVIOUS_VERSION}.tar.bz2 | sed "s,i3-${PREVIOUS_VERSION}/,,g" | sort) \
73 <(tar tf i3-${RELEASE_VERSION}.tar.bz2 | sed "s,i3-${RELEASE_VERSION}/,,g" | sort) \
74 | colordiff
75
76
77 gpg --armor -b i3-${RELEASE_VERSION}.tar.bz2
78
79 echo "${RELEASE_VERSION}-non-git" > I3_VERSION
80 git add I3_VERSION
81 git commit -a -m "Set non-git version to ${RELEASE_VERSION}-non-git."
82
83 if [ "${RELEASE_BRANCH}" = "master" ]; then
84 git checkout master
85 git merge --no-ff release-${RELEASE_VERSION} -m "Merge branch 'release-${RELEASE_VERSION}'"
86 git checkout next
87 git merge --no-ff -s recursive -X ours -X no-renames master -m "Merge branch 'master' into next"
88 else
89 git checkout next
90 git merge --no-ff release-${RELEASE_VERSION} -m "Merge branch 'release-${RELEASE_VERSION}'"
91 git checkout master
92 git merge --no-ff -s recursive -X theirs -X no-renames next -m "Merge branch 'next' into master"
93 fi
94
95 git remote remove origin
96 git remote add origin [email protected]:i3/i3.git
97 git config --add remote.origin.push "+refs/tags/*:refs/tags/*"
98 git config --add remote.origin.push "+refs/heads/next:refs/heads/next"
99 git config --add remote.origin.push "+refs/heads/master:refs/heads/master"
100
101 ################################################################################
102 # Section 2: Debian packaging
103 ################################################################################
104
105 cd "${TMPDIR}"
106 mkdir debian
107
108 # Copy over the changelog because we expect it to be locally modified in the
109 # start directory.
110 cp "${STARTDIR}/debian/changelog" i3/debian/changelog
111 (cd i3 && git add debian/changelog && git commit -m 'Update debian/changelog')
112
113 cat > ${TMPDIR}/Dockerfile <<EOT
114 FROM debian:sid
115 RUN sed -i 's,^deb \(.*\),deb \1\ndeb-src \1,g' /etc/apt/sources.list
116 RUN apt-get update && apt-get install -y dpkg-dev devscripts
117 COPY i3/i3-${RELEASE_VERSION}.tar.bz2 /usr/src/i3-wm_${RELEASE_VERSION}.orig.tar.bz2
118 WORKDIR /usr/src/
119 RUN tar xf i3-wm_${RELEASE_VERSION}.orig.tar.bz2
120 WORKDIR /usr/src/i3-${RELEASE_VERSION}
121 COPY i3/debian /usr/src/i3-${RELEASE_VERSION}/debian/
122 RUN mkdir debian/source
123 RUN echo '3.0 (quilt)' > debian/source/format
124 WORKDIR /usr/src
125 RUN mk-build-deps --install --remove --tool 'apt-get --no-install-recommends -y' i3-${RELEASE_VERSION}/debian/control
126 WORKDIR /usr/src/i3-${RELEASE_VERSION}
127 RUN dpkg-buildpackage -sa -j8
128 RUN dpkg-buildpackage -S -sa -j8
129 EOT
130
131 CONTAINER_NAME=$(echo "i3-${TMPDIR}" | sed 's,/,,g')
132 docker build -t i3 .
133 for file in $(docker run --name "${CONTAINER_NAME}" i3 /bin/sh -c "ls /usr/src/i3*_${RELEASE_VERSION}*")
134 do
135 docker cp "${CONTAINER_NAME}:${file}" ${TMPDIR}/debian/
136 done
137
138 echo "Content of resulting package’s .changes file:"
139 cat ${TMPDIR}/debian/*.changes
140
141 # debsign is in devscripts, which is available in fedora and debian
142 debsign --no-re-sign -k4AC8EE1D ${TMPDIR}/debian/*.changes
143
144 # TODO: docker cleanup
145
146 ################################################################################
147 # Section 3: website
148 ################################################################################
149
150 # Ensure we are in the correct branch for copying the docs.
151 cd ${TMPDIR}/i3
152 git checkout ${RELEASE_BRANCH}
153
154 cd ${TMPDIR}
155 git clone --quiet ${STARTDIR}/../i3.github.io
156 cd i3.github.io
157
158 mkdir docs/${PREVIOUS_VERSION}
159 tar cf - '--exclude=[0-9]\.[0-9e]*' docs | tar xf - --strip-components=1 -C docs/${PREVIOUS_VERSION}
160 git add docs/${PREVIOUS_VERSION}
161 git commit -a -m "save docs for ${PREVIOUS_VERSION}"
162
163 cp ${TMPDIR}/i3/i3-${RELEASE_VERSION}.tar.bz2* downloads/
164 git add downloads/i3-${RELEASE_VERSION}.tar.bz2*
165 cp ${TMPDIR}/i3/RELEASE-NOTES-${RELEASE_VERSION} downloads/RELEASE-NOTES-${RELEASE_VERSION}.txt
166 git add downloads/RELEASE-NOTES-${RELEASE_VERSION}.txt
167 sed -i "s,<h2>Documentation for i3 v[^<]*</h2>,<h2>Documentation for i3 v${RELEASE_VERSION}</h2>,g" docs/index.html
168 sed -i "s,<span style=\"margin-left: 2em; color: #c0c0c0\">[^<]*</span>,<span style=\"margin-left: 2em; color: #c0c0c0\">${RELEASE_VERSION}</span>,g" index.html
169 sed -i "s,The current stable version is .*$,The current stable version is ${RELEASE_VERSION}.,g" downloads/index.html
170 sed -i "s,<tbody>,<tbody>\n <tr>\n <td>${RELEASE_VERSION}</td>\n <td><a href=\"/downloads/i3-${RELEASE_VERSION}.tar.bz2\">i3-${RELEASE_VERSION}.tar.bz2</a></td>\n <td>$(LC_ALL=en_US.UTF-8 ls -lh ../i3/i3-${RELEASE_VERSION}.tar.bz2 | awk -F " " {'print $5'} | sed 's/K$/ KiB/g' | sed 's/M$/ MiB/g')</td>\n <td><a href=\"/downloads/i3-${RELEASE_VERSION}.tar.bz2.asc\">signature</a></td>\n <td>$(date +'%Y-%m-%d')</td>\n <td><a href=\"/downloads/RELEASE-NOTES-${RELEASE_VERSION}.txt\">release notes</a></td>\n </tr>\n,g" downloads/index.html
171
172 git commit -a -m "add ${RELEASE_VERSION} release"
173
174 for i in $(find _docs -maxdepth 1 -and -type f -and \! -regex ".*\.\(html\|man\)$" -and \! -name "Makefile")
175 do
176 base="$(basename $i)"
177 [ -e "${TMPDIR}/i3/docs/${base}" ] && cp "${TMPDIR}/i3/docs/${base}" "_docs/${base}"
178 done
179
180 sed -i "s,Verify you are using i3 ≥ .*,Verify you are using i3 ≥ ${RELEASE_VERSION},g" _docs/debugging
181
182 (cd _docs && make)
183
184 for i in $(find _docs -maxdepth 1 -and -type f -and \! -regex ".*\.\(html\|man\)$" -and \! -name "Makefile")
185 do
186 base="$(basename $i)"
187 [ -e "${TMPDIR}/i3/docs/${base}" ] && cp "_docs/${base}.html" docs/
188 done
189
190 git commit -a -m "update docs for ${RELEASE_VERSION}"
191
192 git remote remove origin
193 git remote add origin [email protected]:i3/i3.github.io.git
194 git config --add remote.origin.push "+refs/heads/master:refs/heads/master"
195
196 ################################################################################
197 # Section 4: prepare release announcement email
198 ################################################################################
199
200 cd ${TMPDIR}
201 cat >email.txt <<EOT
202 From: Michael Stapelberg <[email protected]>
203 To: [email protected]
204 Subject: i3 v${RELEASE_VERSION} released
205 Content-Type: text/plain; charset=utf-8
206 Content-Transfer-Encoding: 8bit
207
208 Hi,
209
210 I just released i3 v${RELEASE_VERSION}. Release notes follow:
211 EOT
212 cat ${TMPDIR}/i3/RELEASE-NOTES-${RELEASE_VERSION} >>email.txt
213
214 ################################################################################
215 # Section 5: final push instructions
216 ################################################################################
217
218 echo "As a final sanity check, install the debian package and see whether i3 works."
219
220 echo "When satisfied, run:"
221 echo " cd ${TMPDIR}/i3"
222 echo " git checkout next"
223 echo " vi debian/changelog"
224 echo " git commit -a -m \"debian: update changelog\""
225 echo " git push"
226 echo ""
227 echo " cd ${TMPDIR}/i3.github.io"
228 echo " git push"
229 echo ""
230 echo " cd ${TMPDIR}/debian"
231 echo " dput"
232 echo ""
233 echo " cd ${TMPDIR}"
234 echo " sendmail -t < email.txt"
235 echo ""
236 echo "Update milestones on GitHub (only for new major versions):"
237 echo " Set due date of ${RELEASE_VERSION} to $(date +'%Y-%m-%d') and close the milestone"
238 echo " Create milestone for the next major version with unset due date"
239 echo ""
240 echo "Announce on:"
241 echo " twitter"
242 echo " google+"
243 echo " #i3 topic"
244 echo " reddit /r/i3wm"
0 [Desktop Entry]
1 Type=Application
2 Name=i3
3 NoDisplay=true
4 GenericName=A dynamic tiling window manager
5 Comment=improved dynamic tiling window manager
6 Exec=i3
7 X-GNOME-WMName=i3
8 X-GNOME-Autostart-Phase=WindowManager
9 X-GNOME-Provides=windowmanager
10 X-GNOME-Autostart-Notify=false
0 [Desktop Entry]
1 Name=i3 (with debug log)
2 Comment=improved dynamic tiling window manager
3 Exec=i3-with-shmlog
4 Type=Application
5 Keywords=tiling;wm;windowmanager;window;manager;
0 [Desktop Entry]
1 Name=i3
2 Comment=improved dynamic tiling window manager
3 Exec=i3
4 TryExec=i3
5 Type=Application
6 X-LightDM-DesktopName=i3
7 DesktopNames=i3
8 Keywords=tiling;wm;windowmanager;window;manager;
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * assignments.c: Assignments for specific windows (for_window).
7 *
8 */
9 #include "all.h"
10
11 /*
12 * Checks the list of assignments for the given window and runs all matching
13 * ones (unless they have already been run for this specific window).
14 *
15 */
16 void run_assignments(i3Window *window) {
17 DLOG("Checking if any assignments match this window\n");
18
19 bool needs_tree_render = false;
20
21 /* Check if any assignments match */
22 Assignment *current;
23 TAILQ_FOREACH (current, &assignments, assignments) {
24 if (current->type != A_COMMAND || !match_matches_window(&(current->match), window))
25 continue;
26
27 bool skip = false;
28 for (uint32_t c = 0; c < window->nr_assignments; c++) {
29 if (window->ran_assignments[c] != current)
30 continue;
31
32 DLOG("This assignment already ran for the given window, not executing it again.\n");
33 skip = true;
34 break;
35 }
36
37 if (skip)
38 continue;
39
40 /* Store that we ran this assignment to not execute it again. We have
41 * to do this before running the actual command to prevent infinite
42 * loops. */
43 window->nr_assignments++;
44 window->ran_assignments = srealloc(window->ran_assignments, sizeof(Assignment *) * window->nr_assignments);
45 window->ran_assignments[window->nr_assignments - 1] = current;
46
47 DLOG("matching assignment, execute command %s\n", current->dest.command);
48 char *full_command;
49 sasprintf(&full_command, "[id=\"%d\"] %s", window->id, current->dest.command);
50 CommandResult *result = parse_command(full_command, NULL, NULL);
51 free(full_command);
52
53 if (result->needs_tree_render)
54 needs_tree_render = true;
55
56 command_result_free(result);
57 }
58
59 /* If any of the commands required re-rendering, we will do that now. */
60 if (needs_tree_render)
61 tree_render();
62 }
63
64 /*
65 * Returns the first matching assignment for the given window.
66 *
67 */
68 Assignment *assignment_for(i3Window *window, int type) {
69 Assignment *assignment;
70
71 TAILQ_FOREACH (assignment, &assignments, assignments) {
72 if ((type != A_ANY && (assignment->type & type) == 0) ||
73 !match_matches_window(&(assignment->match), window))
74 continue;
75 DLOG("got a matching assignment\n");
76 return assignment;
77 }
78
79 return NULL;
80 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * bindings.c: Functions for configuring, finding and, running bindings.
7 */
8 #include "all.h"
9
10 #include <xkbcommon/xkbcommon.h>
11 #include <xkbcommon/xkbcommon-x11.h>
12
13 static struct xkb_context *xkb_context;
14 static struct xkb_keymap *xkb_keymap;
15
16 pid_t command_error_nagbar_pid = -1;
17
18 /*
19 * The name of the default mode.
20 *
21 */
22 const char *DEFAULT_BINDING_MODE = "default";
23
24 /*
25 * Returns the mode specified by `name` or creates a new mode and adds it to
26 * the list of modes.
27 *
28 */
29 static struct Mode *mode_from_name(const char *name, bool pango_markup) {
30 struct Mode *mode;
31
32 /* Try to find the mode in the list of modes and return it */
33 SLIST_FOREACH (mode, &modes, modes) {
34 if (strcmp(mode->name, name) == 0) {
35 return mode;
36 }
37 }
38
39 /* If the mode was not found, create a new one */
40 mode = scalloc(1, sizeof(struct Mode));
41 mode->name = sstrdup(name);
42 mode->pango_markup = pango_markup;
43 mode->bindings = scalloc(1, sizeof(struct bindings_head));
44 TAILQ_INIT(mode->bindings);
45 SLIST_INSERT_HEAD(&modes, mode, modes);
46
47 return mode;
48 }
49
50 /*
51 * Adds a binding from config parameters given as strings and returns a
52 * pointer to the binding structure. Returns NULL if the input code could not
53 * be parsed.
54 *
55 */
56 Binding *configure_binding(const char *bindtype, const char *modifiers, const char *input_code,
57 const char *release, const char *border, const char *whole_window,
58 const char *exclude_titlebar, const char *command, const char *modename,
59 bool pango_markup) {
60 Binding *new_binding = scalloc(1, sizeof(Binding));
61 DLOG("Binding %p bindtype %s, modifiers %s, input code %s, release %s\n", new_binding, bindtype, modifiers, input_code, release);
62 new_binding->release = (release != NULL ? B_UPON_KEYRELEASE : B_UPON_KEYPRESS);
63 new_binding->border = (border != NULL);
64 new_binding->whole_window = (whole_window != NULL);
65 new_binding->exclude_titlebar = (exclude_titlebar != NULL);
66 if (strcmp(bindtype, "bindsym") == 0) {
67 new_binding->input_type = (strncasecmp(input_code, "button", (sizeof("button") - 1)) == 0
68 ? B_MOUSE
69 : B_KEYBOARD);
70
71 new_binding->symbol = sstrdup(input_code);
72 } else {
73 long keycode;
74 if (!parse_long(input_code, &keycode, 10)) {
75 ELOG("Could not parse \"%s\" as an input code, ignoring this binding.\n", input_code);
76 FREE(new_binding);
77 return NULL;
78 }
79
80 new_binding->keycode = keycode;
81 new_binding->input_type = B_KEYBOARD;
82 }
83 new_binding->command = sstrdup(command);
84 new_binding->event_state_mask = event_state_from_str(modifiers);
85 int group_bits_set = 0;
86 if ((new_binding->event_state_mask >> 16) & I3_XKB_GROUP_MASK_1)
87 group_bits_set++;
88 if ((new_binding->event_state_mask >> 16) & I3_XKB_GROUP_MASK_2)
89 group_bits_set++;
90 if ((new_binding->event_state_mask >> 16) & I3_XKB_GROUP_MASK_3)
91 group_bits_set++;
92 if ((new_binding->event_state_mask >> 16) & I3_XKB_GROUP_MASK_4)
93 group_bits_set++;
94 if (group_bits_set > 1)
95 ELOG("Keybinding has more than one Group specified, but your X server is always in precisely one group. The keybinding can never trigger.\n");
96
97 struct Mode *mode = mode_from_name(modename, pango_markup);
98 TAILQ_INSERT_TAIL(mode->bindings, new_binding, bindings);
99
100 TAILQ_INIT(&(new_binding->keycodes_head));
101
102 return new_binding;
103 }
104
105 static bool binding_in_current_group(const Binding *bind) {
106 /* If no bits are set, the binding should be installed in every group. */
107 if ((bind->event_state_mask >> 16) == I3_XKB_GROUP_MASK_ANY)
108 return true;
109 switch (xkb_current_group) {
110 case XCB_XKB_GROUP_1:
111 return ((bind->event_state_mask >> 16) & I3_XKB_GROUP_MASK_1);
112 case XCB_XKB_GROUP_2:
113 return ((bind->event_state_mask >> 16) & I3_XKB_GROUP_MASK_2);
114 case XCB_XKB_GROUP_3:
115 return ((bind->event_state_mask >> 16) & I3_XKB_GROUP_MASK_3);
116 case XCB_XKB_GROUP_4:
117 return ((bind->event_state_mask >> 16) & I3_XKB_GROUP_MASK_4);
118 default:
119 ELOG("BUG: xkb_current_group (= %d) outside of [XCB_XKB_GROUP_1..XCB_XKB_GROUP_4]\n", xkb_current_group);
120 return false;
121 }
122 }
123
124 static void grab_keycode_for_binding(xcb_connection_t *conn, Binding *bind, uint32_t keycode) {
125 /* Grab the key in all combinations */
126 #define GRAB_KEY(modifier) \
127 do { \
128 xcb_grab_key(conn, 0, root, modifier, keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC); \
129 } while (0)
130 const int mods = (bind->event_state_mask & 0xFFFF);
131 DLOG("Binding %p Grabbing keycode %d with event state mask 0x%x (mods 0x%x)\n",
132 bind, keycode, bind->event_state_mask, mods);
133 GRAB_KEY(mods);
134 /* Also bind the key with active NumLock */
135 GRAB_KEY(mods | xcb_numlock_mask);
136 /* Also bind the key with active CapsLock */
137 GRAB_KEY(mods | XCB_MOD_MASK_LOCK);
138 /* Also bind the key with active NumLock+CapsLock */
139 GRAB_KEY(mods | xcb_numlock_mask | XCB_MOD_MASK_LOCK);
140 }
141
142 /*
143 * Grab the bound keys (tell X to send us keypress events for those keycodes)
144 *
145 */
146 void grab_all_keys(xcb_connection_t *conn) {
147 Binding *bind;
148 TAILQ_FOREACH (bind, bindings, bindings) {
149 if (bind->input_type != B_KEYBOARD)
150 continue;
151
152 if (!binding_in_current_group(bind))
153 continue;
154
155 /* The easy case: the user specified a keycode directly. */
156 if (bind->keycode > 0) {
157 grab_keycode_for_binding(conn, bind, bind->keycode);
158 continue;
159 }
160
161 struct Binding_Keycode *binding_keycode;
162 TAILQ_FOREACH (binding_keycode, &(bind->keycodes_head), keycodes) {
163 const int keycode = binding_keycode->keycode;
164 const int mods = (binding_keycode->modifiers & 0xFFFF);
165 DLOG("Binding %p Grabbing keycode %d with mods %d\n", bind, keycode, mods);
166 xcb_grab_key(conn, 0, root, mods, keycode, XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC);
167 }
168 }
169 }
170
171 /*
172 * Release the button grabs on all managed windows and regrab them,
173 * reevaluating which buttons need to be grabbed.
174 *
175 */
176 void regrab_all_buttons(xcb_connection_t *conn) {
177 int *buttons = bindings_get_buttons_to_grab();
178 xcb_grab_server(conn);
179
180 Con *con;
181 TAILQ_FOREACH (con, &all_cons, all_cons) {
182 if (con->window == NULL)
183 continue;
184
185 xcb_ungrab_button(conn, XCB_BUTTON_INDEX_ANY, con->window->id, XCB_BUTTON_MASK_ANY);
186 xcb_grab_buttons(conn, con->window->id, buttons);
187 }
188
189 FREE(buttons);
190 xcb_ungrab_server(conn);
191 }
192
193 /*
194 * Returns a pointer to the Binding with the specified modifiers and
195 * keycode or NULL if no such binding exists.
196 *
197 */
198 static Binding *get_binding(i3_event_state_mask_t state_filtered, bool is_release, uint16_t input_code, input_type_t input_type) {
199 Binding *bind;
200 Binding *result = NULL;
201
202 if (!is_release) {
203 /* On a press event, we first reset all B_UPON_KEYRELEASE_IGNORE_MODS
204 * bindings back to B_UPON_KEYRELEASE */
205 TAILQ_FOREACH (bind, bindings, bindings) {
206 if (bind->input_type != input_type)
207 continue;
208 if (bind->release == B_UPON_KEYRELEASE_IGNORE_MODS)
209 bind->release = B_UPON_KEYRELEASE;
210 }
211 }
212
213 const uint32_t xkb_group_state = (state_filtered & 0xFFFF0000);
214 const uint32_t modifiers_state = (state_filtered & 0x0000FFFF);
215 TAILQ_FOREACH (bind, bindings, bindings) {
216 if (bind->input_type != input_type) {
217 continue;
218 }
219
220 const uint32_t xkb_group_mask = (bind->event_state_mask & 0xFFFF0000);
221 const bool groups_match = ((xkb_group_state & xkb_group_mask) == xkb_group_mask);
222 if (!groups_match) {
223 DLOG("skipping binding %p because XKB groups do not match\n", bind);
224 continue;
225 }
226
227 /* For keyboard bindings where a symbol was specified by the user, we
228 * need to look in the array of translated keycodes for the event’s
229 * keycode */
230 bool found_keycode = false;
231 if (input_type == B_KEYBOARD && bind->symbol != NULL) {
232 xcb_keycode_t input_keycode = (xcb_keycode_t)input_code;
233 struct Binding_Keycode *binding_keycode;
234 TAILQ_FOREACH (binding_keycode, &(bind->keycodes_head), keycodes) {
235 const uint32_t modifiers_mask = (binding_keycode->modifiers & 0x0000FFFF);
236 const bool mods_match = (modifiers_mask == modifiers_state);
237 DLOG("binding_keycode->modifiers = %d, modifiers_mask = %d, modifiers_state = %d, mods_match = %s\n",
238 binding_keycode->modifiers, modifiers_mask, modifiers_state, (mods_match ? "yes" : "no"));
239 if (binding_keycode->keycode == input_keycode &&
240 (mods_match || (bind->release == B_UPON_KEYRELEASE_IGNORE_MODS && is_release))) {
241 found_keycode = true;
242 break;
243 }
244 }
245 } else {
246 /* This case is easier: The user specified a keycode */
247 if (bind->keycode != input_code) {
248 continue;
249 }
250
251 struct Binding_Keycode *binding_keycode;
252 TAILQ_FOREACH (binding_keycode, &(bind->keycodes_head), keycodes) {
253 const uint32_t modifiers_mask = (binding_keycode->modifiers & 0x0000FFFF);
254 const bool mods_match = (modifiers_mask == modifiers_state);
255 DLOG("binding_keycode->modifiers = %d, modifiers_mask = %d, modifiers_state = %d, mods_match = %s\n",
256 binding_keycode->modifiers, modifiers_mask, modifiers_state, (mods_match ? "yes" : "no"));
257 if (mods_match || (bind->release == B_UPON_KEYRELEASE_IGNORE_MODS && is_release)) {
258 found_keycode = true;
259 break;
260 }
261 }
262 }
263 if (!found_keycode) {
264 continue;
265 }
266
267 /* If this binding is a release binding, it matches the key which the
268 * user pressed. We therefore mark it as B_UPON_KEYRELEASE_IGNORE_MODS
269 * for later, so that the user can release the modifiers before the
270 * actual key or button and the release event will still be matched. */
271 if (bind->release == B_UPON_KEYRELEASE && !is_release) {
272 bind->release = B_UPON_KEYRELEASE_IGNORE_MODS;
273 DLOG("marked bind %p as B_UPON_KEYRELEASE_IGNORE_MODS\n", bind);
274 if (result) {
275 break;
276 }
277 continue;
278 }
279
280 /* Check if the binding is for a press or a release event */
281 if ((bind->release == B_UPON_KEYPRESS && is_release)) {
282 continue;
283 }
284
285 if (is_release) {
286 return bind;
287 } else if (!result) {
288 /* Continue looping to mark needed B_UPON_KEYRELEASE_IGNORE_MODS. */
289 result = bind;
290 }
291 }
292
293 return result;
294 }
295
296 /*
297 * Returns a pointer to the Binding that matches the given xcb button or key
298 * event or NULL if no such binding exists.
299 *
300 */
301 Binding *get_binding_from_xcb_event(xcb_generic_event_t *event) {
302 const bool is_release = (event->response_type == XCB_KEY_RELEASE ||
303 event->response_type == XCB_BUTTON_RELEASE);
304
305 const input_type_t input_type = ((event->response_type == XCB_BUTTON_RELEASE ||
306 event->response_type == XCB_BUTTON_PRESS)
307 ? B_MOUSE
308 : B_KEYBOARD);
309
310 const uint16_t event_state = ((xcb_key_press_event_t *)event)->state;
311 const uint16_t event_detail = ((xcb_key_press_event_t *)event)->detail;
312
313 /* Remove the CapsLock bit */
314 i3_event_state_mask_t state_filtered = event_state & ~XCB_MOD_MASK_LOCK;
315 DLOG("(removed capslock, state = 0x%x)\n", state_filtered);
316 /* Transform the keyboard_group from bit 13 and bit 14 into an
317 * i3_xkb_group_mask_t, so that get_binding() can just bitwise AND the
318 * configured bindings against |state_filtered|.
319 *
320 * These bits are only set because we set the XKB client flags
321 * XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE and
322 * XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED. See also doc/kbproto
323 * section 2.2.2:
324 * https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html#Computing_A_State_Field_from_an_XKB_State */
325 switch ((event_state & 0x6000) >> 13) {
326 case XCB_XKB_GROUP_1:
327 state_filtered |= (I3_XKB_GROUP_MASK_1 << 16);
328 break;
329 case XCB_XKB_GROUP_2:
330 state_filtered |= (I3_XKB_GROUP_MASK_2 << 16);
331 break;
332 case XCB_XKB_GROUP_3:
333 state_filtered |= (I3_XKB_GROUP_MASK_3 << 16);
334 break;
335 case XCB_XKB_GROUP_4:
336 state_filtered |= (I3_XKB_GROUP_MASK_4 << 16);
337 break;
338 }
339 state_filtered &= ~0x6000;
340 DLOG("(transformed keyboard group, state = 0x%x)\n", state_filtered);
341 return get_binding(state_filtered, is_release, event_detail, input_type);
342 }
343
344 struct resolve {
345 /* The binding which we are resolving. */
346 Binding *bind;
347
348 /* |bind|’s keysym (translated to xkb_keysym_t), e.g. XKB_KEY_R. */
349 xkb_keysym_t keysym;
350
351 /* The xkb state built from the user-provided modifiers and group. */
352 struct xkb_state *xkb_state;
353
354 /* Like |xkb_state|, just without the shift modifier, if shift was specified. */
355 struct xkb_state *xkb_state_no_shift;
356
357 /* Like |xkb_state|, but with NumLock. */
358 struct xkb_state *xkb_state_numlock;
359
360 /* Like |xkb_state|, but with NumLock, just without the shift modifier, if shift was specified. */
361 struct xkb_state *xkb_state_numlock_no_shift;
362 };
363
364 #define ADD_TRANSLATED_KEY(code, mods) \
365 do { \
366 struct Binding_Keycode *binding_keycode = smalloc(sizeof(struct Binding_Keycode)); \
367 binding_keycode->modifiers = (mods); \
368 binding_keycode->keycode = (code); \
369 TAILQ_INSERT_TAIL(&(bind->keycodes_head), binding_keycode, keycodes); \
370 } while (0)
371
372 /*
373 * add_keycode_if_matches is called for each keycode in the keymap and will add
374 * the keycode to |data->bind| if the keycode can result in the keysym
375 * |data->resolving|.
376 *
377 */
378 static void add_keycode_if_matches(struct xkb_keymap *keymap, xkb_keycode_t key, void *data) {
379 const struct resolve *resolving = data;
380 struct xkb_state *numlock_state = resolving->xkb_state_numlock;
381 xkb_keysym_t sym = xkb_state_key_get_one_sym(resolving->xkb_state, key);
382 if (sym != resolving->keysym) {
383 /* Check if Shift was specified, and try resolving the symbol without
384 * shift, so that “bindsym $mod+Shift+a nop” actually works. */
385 const xkb_layout_index_t layout = xkb_state_key_get_layout(resolving->xkb_state, key);
386 if (layout == XKB_LAYOUT_INVALID)
387 return;
388 if (xkb_state_key_get_level(resolving->xkb_state, key, layout) > 1)
389 return;
390 /* Skip the Shift fallback for keypad keys, otherwise one cannot bind
391 * KP_1 independent of KP_End. */
392 if (sym >= XKB_KEY_KP_Space && sym <= XKB_KEY_KP_Equal)
393 return;
394 numlock_state = resolving->xkb_state_numlock_no_shift;
395 sym = xkb_state_key_get_one_sym(resolving->xkb_state_no_shift, key);
396 if (sym != resolving->keysym)
397 return;
398 }
399 Binding *bind = resolving->bind;
400
401 ADD_TRANSLATED_KEY(key, bind->event_state_mask);
402
403 /* Also bind the key with active CapsLock */
404 ADD_TRANSLATED_KEY(key, bind->event_state_mask | XCB_MOD_MASK_LOCK);
405
406 /* If this binding is not explicitly for NumLock, check whether we need to
407 * add a fallback. */
408 if ((bind->event_state_mask & xcb_numlock_mask) != xcb_numlock_mask) {
409 /* Check whether the keycode results in the same keysym when NumLock is
410 * active. If so, grab the key with NumLock as well, so that users don’t
411 * need to duplicate every key binding with an additional Mod2 specified.
412 */
413 xkb_keysym_t sym_numlock = xkb_state_key_get_one_sym(numlock_state, key);
414 if (sym_numlock == resolving->keysym) {
415 /* Also bind the key with active NumLock */
416 ADD_TRANSLATED_KEY(key, bind->event_state_mask | xcb_numlock_mask);
417
418 /* Also bind the key with active NumLock+CapsLock */
419 ADD_TRANSLATED_KEY(key, bind->event_state_mask | xcb_numlock_mask | XCB_MOD_MASK_LOCK);
420 } else {
421 DLOG("Skipping automatic numlock fallback, key %d resolves to 0x%x with numlock\n",
422 key, sym_numlock);
423 }
424 }
425 }
426
427 /*
428 * Translates keysymbols to keycodes for all bindings which use keysyms.
429 *
430 */
431 void translate_keysyms(void) {
432 struct xkb_state *dummy_state = NULL;
433 struct xkb_state *dummy_state_no_shift = NULL;
434 struct xkb_state *dummy_state_numlock = NULL;
435 struct xkb_state *dummy_state_numlock_no_shift = NULL;
436 bool has_errors = false;
437
438 if ((dummy_state = xkb_state_new(xkb_keymap)) == NULL ||
439 (dummy_state_no_shift = xkb_state_new(xkb_keymap)) == NULL ||
440 (dummy_state_numlock = xkb_state_new(xkb_keymap)) == NULL ||
441 (dummy_state_numlock_no_shift = xkb_state_new(xkb_keymap)) == NULL) {
442 ELOG("Could not create XKB state, cannot translate keysyms.\n");
443 goto out;
444 }
445
446 Binding *bind;
447 TAILQ_FOREACH (bind, bindings, bindings) {
448 if (bind->input_type == B_MOUSE) {
449 long button;
450 if (!parse_long(bind->symbol + (sizeof("button") - 1), &button, 10)) {
451 ELOG("Could not translate string to button: \"%s\"\n", bind->symbol);
452 }
453
454 xcb_keycode_t key = button;
455 bind->keycode = key;
456 DLOG("Binding Mouse button, Keycode = %d\n", key);
457 }
458
459 xkb_layout_index_t group = XCB_XKB_GROUP_1;
460 if ((bind->event_state_mask >> 16) & I3_XKB_GROUP_MASK_2)
461 group = XCB_XKB_GROUP_2;
462 else if ((bind->event_state_mask >> 16) & I3_XKB_GROUP_MASK_3)
463 group = XCB_XKB_GROUP_3;
464 else if ((bind->event_state_mask >> 16) & I3_XKB_GROUP_MASK_4)
465 group = XCB_XKB_GROUP_4;
466
467 DLOG("Binding %p group = %d, event_state_mask = %d, &2 = %s, &3 = %s, &4 = %s\n",
468 bind,
469 group,
470 bind->event_state_mask,
471 (bind->event_state_mask & I3_XKB_GROUP_MASK_2) ? "yes" : "no",
472 (bind->event_state_mask & I3_XKB_GROUP_MASK_3) ? "yes" : "no",
473 (bind->event_state_mask & I3_XKB_GROUP_MASK_4) ? "yes" : "no");
474 (void)xkb_state_update_mask(
475 dummy_state,
476 (bind->event_state_mask & 0x1FFF) /* xkb_mod_mask_t base_mods, */,
477 0 /* xkb_mod_mask_t latched_mods, */,
478 0 /* xkb_mod_mask_t locked_mods, */,
479 0 /* xkb_layout_index_t base_group, */,
480 0 /* xkb_layout_index_t latched_group, */,
481 group /* xkb_layout_index_t locked_group, */);
482
483 (void)xkb_state_update_mask(
484 dummy_state_no_shift,
485 (bind->event_state_mask & 0x1FFF) ^ XCB_KEY_BUT_MASK_SHIFT /* xkb_mod_mask_t base_mods, */,
486 0 /* xkb_mod_mask_t latched_mods, */,
487 0 /* xkb_mod_mask_t locked_mods, */,
488 0 /* xkb_layout_index_t base_group, */,
489 0 /* xkb_layout_index_t latched_group, */,
490 group /* xkb_layout_index_t locked_group, */);
491
492 (void)xkb_state_update_mask(
493 dummy_state_numlock,
494 (bind->event_state_mask & 0x1FFF) | xcb_numlock_mask /* xkb_mod_mask_t base_mods, */,
495 0 /* xkb_mod_mask_t latched_mods, */,
496 0 /* xkb_mod_mask_t locked_mods, */,
497 0 /* xkb_layout_index_t base_group, */,
498 0 /* xkb_layout_index_t latched_group, */,
499 group /* xkb_layout_index_t locked_group, */);
500
501 (void)xkb_state_update_mask(
502 dummy_state_numlock_no_shift,
503 ((bind->event_state_mask & 0x1FFF) | xcb_numlock_mask) ^ XCB_KEY_BUT_MASK_SHIFT /* xkb_mod_mask_t base_mods, */,
504 0 /* xkb_mod_mask_t latched_mods, */,
505 0 /* xkb_mod_mask_t locked_mods, */,
506 0 /* xkb_layout_index_t base_group, */,
507 0 /* xkb_layout_index_t latched_group, */,
508 group /* xkb_layout_index_t locked_group, */);
509
510 if (bind->keycode > 0) {
511 /* We need to specify modifiers for the keycode binding (numlock
512 * fallback). */
513 while (!TAILQ_EMPTY(&(bind->keycodes_head))) {
514 struct Binding_Keycode *first = TAILQ_FIRST(&(bind->keycodes_head));
515 TAILQ_REMOVE(&(bind->keycodes_head), first, keycodes);
516 FREE(first);
517 }
518
519 ADD_TRANSLATED_KEY(bind->keycode, bind->event_state_mask);
520
521 /* Also bind the key with active CapsLock */
522 ADD_TRANSLATED_KEY(bind->keycode, bind->event_state_mask | XCB_MOD_MASK_LOCK);
523
524 /* If this binding is not explicitly for NumLock, check whether we need to
525 * add a fallback. */
526 if ((bind->event_state_mask & xcb_numlock_mask) != xcb_numlock_mask) {
527 /* Check whether the keycode results in the same keysym when NumLock is
528 * active. If so, grab the key with NumLock as well, so that users don’t
529 * need to duplicate every key binding with an additional Mod2 specified.
530 */
531 xkb_keysym_t sym = xkb_state_key_get_one_sym(dummy_state, bind->keycode);
532 xkb_keysym_t sym_numlock = xkb_state_key_get_one_sym(dummy_state_numlock, bind->keycode);
533 if (sym == sym_numlock) {
534 /* Also bind the key with active NumLock */
535 ADD_TRANSLATED_KEY(bind->keycode, bind->event_state_mask | xcb_numlock_mask);
536
537 /* Also bind the key with active NumLock+CapsLock */
538 ADD_TRANSLATED_KEY(bind->keycode, bind->event_state_mask | xcb_numlock_mask | XCB_MOD_MASK_LOCK);
539 } else {
540 DLOG("Skipping automatic numlock fallback, key %d resolves to 0x%x with numlock\n",
541 bind->keycode, sym_numlock);
542 }
543 }
544
545 continue;
546 }
547
548 /* We need to translate the symbol to a keycode */
549 const xkb_keysym_t keysym = xkb_keysym_from_name(bind->symbol, XKB_KEYSYM_NO_FLAGS);
550 if (keysym == XKB_KEY_NoSymbol) {
551 ELOG("Could not translate string to key symbol: \"%s\"\n",
552 bind->symbol);
553 continue;
554 }
555
556 struct resolve resolving = {
557 .bind = bind,
558 .keysym = keysym,
559 .xkb_state = dummy_state,
560 .xkb_state_no_shift = dummy_state_no_shift,
561 .xkb_state_numlock = dummy_state_numlock,
562 .xkb_state_numlock_no_shift = dummy_state_numlock_no_shift,
563 };
564 while (!TAILQ_EMPTY(&(bind->keycodes_head))) {
565 struct Binding_Keycode *first = TAILQ_FIRST(&(bind->keycodes_head));
566 TAILQ_REMOVE(&(bind->keycodes_head), first, keycodes);
567 FREE(first);
568 }
569 xkb_keymap_key_for_each(xkb_keymap, add_keycode_if_matches, &resolving);
570 char *keycodes = sstrdup("");
571 int num_keycodes = 0;
572 struct Binding_Keycode *binding_keycode;
573 TAILQ_FOREACH (binding_keycode, &(bind->keycodes_head), keycodes) {
574 char *tmp;
575 sasprintf(&tmp, "%s %d", keycodes, binding_keycode->keycode);
576 free(keycodes);
577 keycodes = tmp;
578 num_keycodes++;
579
580 /* check for duplicate bindings */
581 Binding *check;
582 TAILQ_FOREACH (check, bindings, bindings) {
583 if (check == bind)
584 continue;
585 if (check->symbol != NULL)
586 continue;
587 if (check->keycode != binding_keycode->keycode ||
588 check->event_state_mask != binding_keycode->modifiers ||
589 check->release != bind->release)
590 continue;
591 has_errors = true;
592 ELOG("Duplicate keybinding in config file:\n keysym = %s, keycode = %d, state_mask = 0x%x\n", bind->symbol, check->keycode, bind->event_state_mask);
593 }
594 }
595 DLOG("state=0x%x, cfg=\"%s\", sym=0x%x → keycodes%s (%d)\n",
596 bind->event_state_mask, bind->symbol, keysym, keycodes, num_keycodes);
597 free(keycodes);
598 }
599
600 out:
601 xkb_state_unref(dummy_state);
602 xkb_state_unref(dummy_state_no_shift);
603 xkb_state_unref(dummy_state_numlock);
604 xkb_state_unref(dummy_state_numlock_no_shift);
605
606 if (has_errors) {
607 start_config_error_nagbar(current_configpath, true);
608 }
609 }
610
611 #undef ADD_TRANSLATED_KEY
612
613 /*
614 * Switches the key bindings to the given mode, if the mode exists
615 *
616 */
617 void switch_mode(const char *new_mode) {
618 struct Mode *mode;
619
620 DLOG("Switching to mode %s\n", new_mode);
621
622 SLIST_FOREACH (mode, &modes, modes) {
623 if (strcmp(mode->name, new_mode) != 0)
624 continue;
625
626 ungrab_all_keys(conn);
627 bindings = mode->bindings;
628 translate_keysyms();
629 grab_all_keys(conn);
630
631 /* Reset all B_UPON_KEYRELEASE_IGNORE_MODS bindings to avoid possibly
632 * activating one of them. */
633 Binding *bind;
634 TAILQ_FOREACH (bind, bindings, bindings) {
635 if (bind->release == B_UPON_KEYRELEASE_IGNORE_MODS)
636 bind->release = B_UPON_KEYRELEASE;
637 }
638
639 char *event_msg;
640 sasprintf(&event_msg, "{\"change\":\"%s\", \"pango_markup\":%s}",
641 mode->name, (mode->pango_markup ? "true" : "false"));
642
643 ipc_send_event("mode", I3_IPC_EVENT_MODE, event_msg);
644 FREE(event_msg);
645
646 return;
647 }
648
649 ELOG("Mode not found\n");
650 }
651
652 static int reorder_binding_cmp(const void *a, const void *b) {
653 Binding *first = *((Binding **)a);
654 Binding *second = *((Binding **)b);
655 if (first->event_state_mask < second->event_state_mask) {
656 return 1;
657 } else if (first->event_state_mask == second->event_state_mask) {
658 return 0;
659 } else {
660 return -1;
661 }
662 }
663
664 static void reorder_bindings_of_mode(struct Mode *mode) {
665 /* Copy the bindings into an array, so that we can use qsort(3). */
666 int n = 0;
667 Binding *current;
668 TAILQ_FOREACH (current, mode->bindings, bindings) {
669 n++;
670 }
671 Binding **tmp = scalloc(n, sizeof(Binding *));
672 n = 0;
673 TAILQ_FOREACH (current, mode->bindings, bindings) {
674 tmp[n++] = current;
675 }
676
677 qsort(tmp, n, sizeof(Binding *), reorder_binding_cmp);
678
679 struct bindings_head *reordered = scalloc(1, sizeof(struct bindings_head));
680 TAILQ_INIT(reordered);
681 for (int i = 0; i < n; i++) {
682 current = tmp[i];
683 TAILQ_REMOVE(mode->bindings, current, bindings);
684 TAILQ_INSERT_TAIL(reordered, current, bindings);
685 }
686 free(tmp);
687 assert(TAILQ_EMPTY(mode->bindings));
688 /* Free the old bindings_head, which is now empty. */
689 free(mode->bindings);
690 mode->bindings = reordered;
691 }
692
693 /*
694 * Reorders bindings by event_state_mask descendingly so that get_binding()
695 * correctly matches more specific bindings before more generic bindings. Take
696 * the following binding configuration as an example:
697 *
698 * bindsym n nop lower-case n pressed
699 * bindsym Shift+n nop upper-case n pressed
700 *
701 * Without reordering, the first binding’s event_state_mask of 0x0 would match
702 * the actual event_stat_mask of 0x1 and hence trigger instead of the second
703 * keybinding.
704 *
705 */
706 void reorder_bindings(void) {
707 struct Mode *mode;
708 SLIST_FOREACH (mode, &modes, modes) {
709 const bool current_mode = (mode->bindings == bindings);
710 reorder_bindings_of_mode(mode);
711 if (current_mode)
712 bindings = mode->bindings;
713 }
714 }
715
716 /*
717 * Checks for duplicate key bindings (the same keycode or keysym is configured
718 * more than once). If a duplicate binding is found, a message is printed to
719 * stderr and the has_errors variable is set to true, which will start
720 * i3-nagbar.
721 *
722 */
723 void check_for_duplicate_bindings(struct context *context) {
724 Binding *bind, *current;
725 TAILQ_FOREACH (current, bindings, bindings) {
726 TAILQ_FOREACH (bind, bindings, bindings) {
727 /* Abort when we reach the current keybinding, only check the
728 * bindings before */
729 if (bind == current)
730 break;
731
732 /* Check if the input types are different */
733 if (bind->input_type != current->input_type)
734 continue;
735
736 /* Check if one is using keysym while the other is using bindsym.
737 * If so, skip. */
738 if ((bind->symbol == NULL && current->symbol != NULL) ||
739 (bind->symbol != NULL && current->symbol == NULL))
740 continue;
741
742 /* If bind is NULL, current has to be NULL, too (see above).
743 * If the keycodes differ, it can't be a duplicate. */
744 if (bind->symbol != NULL &&
745 strcasecmp(bind->symbol, current->symbol) != 0)
746 continue;
747
748 /* Check if the keycodes or modifiers are different. If so, they
749 * can't be duplicate */
750 if (bind->keycode != current->keycode ||
751 bind->event_state_mask != current->event_state_mask ||
752 bind->release != current->release)
753 continue;
754
755 context->has_errors = true;
756 if (current->keycode != 0) {
757 ELOG("Duplicate keybinding in config file:\n state mask 0x%x with keycode %d, command \"%s\"\n",
758 current->event_state_mask, current->keycode, current->command);
759 } else {
760 ELOG("Duplicate keybinding in config file:\n state mask 0x%x with keysym %s, command \"%s\"\n",
761 current->event_state_mask, current->symbol, current->command);
762 }
763 }
764 }
765 }
766
767 /*
768 * Creates a dynamically allocated copy of bind.
769 */
770 static Binding *binding_copy(Binding *bind) {
771 Binding *ret = smalloc(sizeof(Binding));
772 *ret = *bind;
773 if (bind->symbol != NULL)
774 ret->symbol = sstrdup(bind->symbol);
775 if (bind->command != NULL)
776 ret->command = sstrdup(bind->command);
777 TAILQ_INIT(&(ret->keycodes_head));
778 struct Binding_Keycode *binding_keycode;
779 TAILQ_FOREACH (binding_keycode, &(bind->keycodes_head), keycodes) {
780 struct Binding_Keycode *ret_binding_keycode = smalloc(sizeof(struct Binding_Keycode));
781 *ret_binding_keycode = *binding_keycode;
782 TAILQ_INSERT_TAIL(&(ret->keycodes_head), ret_binding_keycode, keycodes);
783 }
784
785 return ret;
786 }
787
788 /*
789 * Frees the binding. If bind is null, it simply returns.
790 */
791 void binding_free(Binding *bind) {
792 if (bind == NULL) {
793 return;
794 }
795
796 while (!TAILQ_EMPTY(&(bind->keycodes_head))) {
797 struct Binding_Keycode *first = TAILQ_FIRST(&(bind->keycodes_head));
798 TAILQ_REMOVE(&(bind->keycodes_head), first, keycodes);
799 FREE(first);
800 }
801
802 FREE(bind->symbol);
803 FREE(bind->command);
804 FREE(bind);
805 }
806
807 /*
808 * Runs the given binding and handles parse errors. If con is passed, it will
809 * execute the command binding with that container selected by criteria.
810 * Returns a CommandResult for running the binding's command. Free with
811 * command_result_free().
812 *
813 */
814 CommandResult *run_binding(Binding *bind, Con *con) {
815 char *command;
816
817 /* We need to copy the binding and command since “reload” may be part of
818 * the command, and then the memory that bind points to may not contain the
819 * same data anymore. */
820 if (con == NULL)
821 command = sstrdup(bind->command);
822 else
823 sasprintf(&command, "[con_id=\"%p\"] %s", con, bind->command);
824
825 Binding *bind_cp = binding_copy(bind);
826 CommandResult *result = parse_command(command, NULL, NULL);
827 free(command);
828
829 if (result->needs_tree_render)
830 tree_render();
831
832 if (result->parse_error) {
833 char *pageraction;
834 sasprintf(&pageraction, "i3-sensible-pager \"%s\"\n", errorfilename);
835 char *argv[] = {
836 NULL, /* will be replaced by the executable path */
837 "-f",
838 config.font.pattern,
839 "-t",
840 "error",
841 "-m",
842 "The configured command for this shortcut could not be run successfully.",
843 "-b",
844 "show errors",
845 pageraction,
846 NULL};
847 start_nagbar(&command_error_nagbar_pid, argv);
848 free(pageraction);
849 }
850
851 ipc_send_binding_event("run", bind_cp);
852 binding_free(bind_cp);
853
854 return result;
855 }
856
857 static int fill_rmlvo_from_root(struct xkb_rule_names *xkb_names) {
858 xcb_intern_atom_reply_t *atom_reply;
859 size_t content_max_words = 256;
860
861 atom_reply = xcb_intern_atom_reply(
862 conn, xcb_intern_atom(conn, 0, strlen("_XKB_RULES_NAMES"), "_XKB_RULES_NAMES"), NULL);
863 if (atom_reply == NULL)
864 return -1;
865
866 xcb_get_property_cookie_t prop_cookie;
867 xcb_get_property_reply_t *prop_reply;
868 prop_cookie = xcb_get_property_unchecked(conn, false, root, atom_reply->atom,
869 XCB_GET_PROPERTY_TYPE_ANY, 0, content_max_words);
870 prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL);
871 if (prop_reply == NULL) {
872 free(atom_reply);
873 return -1;
874 }
875 if (xcb_get_property_value_length(prop_reply) > 0 && prop_reply->bytes_after > 0) {
876 /* We received an incomplete value. Ask again but with a properly
877 * adjusted size. */
878 content_max_words += ceil(prop_reply->bytes_after / 4.0);
879 /* Repeat the request, with adjusted size */
880 free(prop_reply);
881 prop_cookie = xcb_get_property_unchecked(conn, false, root, atom_reply->atom,
882 XCB_GET_PROPERTY_TYPE_ANY, 0, content_max_words);
883 prop_reply = xcb_get_property_reply(conn, prop_cookie, NULL);
884 if (prop_reply == NULL) {
885 free(atom_reply);
886 return -1;
887 }
888 }
889 if (xcb_get_property_value_length(prop_reply) == 0) {
890 free(atom_reply);
891 free(prop_reply);
892 return -1;
893 }
894
895 const char *walk = (const char *)xcb_get_property_value(prop_reply);
896 int remaining = xcb_get_property_value_length(prop_reply);
897 for (int i = 0; i < 5 && remaining > 0; i++) {
898 const int len = strnlen(walk, remaining);
899 switch (i) {
900 case 0:
901 sasprintf((char **)&(xkb_names->rules), "%.*s", len, walk);
902 break;
903 case 1:
904 sasprintf((char **)&(xkb_names->model), "%.*s", len, walk);
905 break;
906 case 2:
907 sasprintf((char **)&(xkb_names->layout), "%.*s", len, walk);
908 break;
909 case 3:
910 sasprintf((char **)&(xkb_names->variant), "%.*s", len, walk);
911 break;
912 case 4:
913 sasprintf((char **)&(xkb_names->options), "%.*s", len, walk);
914 break;
915 }
916 DLOG("component %d of _XKB_RULES_NAMES is \"%.*s\"\n", i, len, walk);
917 walk += (len + 1);
918 remaining -= (len + 1);
919 }
920
921 free(atom_reply);
922 free(prop_reply);
923 return 0;
924 }
925
926 /*
927 * Loads the XKB keymap from the X11 server and feeds it to xkbcommon.
928 *
929 */
930 bool load_keymap(void) {
931 if (xkb_context == NULL) {
932 if ((xkb_context = xkb_context_new(0)) == NULL) {
933 ELOG("Could not create xkbcommon context\n");
934 return false;
935 }
936 }
937
938 struct xkb_keymap *new_keymap = NULL;
939 int32_t device_id;
940 if (xkb_supported && (device_id = xkb_x11_get_core_keyboard_device_id(conn)) > -1) {
941 if ((new_keymap = xkb_x11_keymap_new_from_device(xkb_context, conn, device_id, 0)) == NULL) {
942 ELOG("xkb_x11_keymap_new_from_device failed\n");
943 return false;
944 }
945 } else {
946 /* Likely there is no XKB support on this server, possibly because it
947 * is a VNC server. */
948 LOG("No XKB / core keyboard device? Assembling keymap from local RMLVO.\n");
949 struct xkb_rule_names names = {
950 .rules = NULL,
951 .model = NULL,
952 .layout = NULL,
953 .variant = NULL,
954 .options = NULL};
955 if (fill_rmlvo_from_root(&names) == -1) {
956 ELOG("Could not get _XKB_RULES_NAMES atom from root window, falling back to defaults.\n");
957 /* Using NULL for the fields of xkb_rule_names. */
958 }
959 new_keymap = xkb_keymap_new_from_names(xkb_context, &names, 0);
960 free((char *)names.rules);
961 free((char *)names.model);
962 free((char *)names.layout);
963 free((char *)names.variant);
964 free((char *)names.options);
965 if (new_keymap == NULL) {
966 ELOG("xkb_keymap_new_from_names failed\n");
967 return false;
968 }
969 }
970 xkb_keymap_unref(xkb_keymap);
971 xkb_keymap = new_keymap;
972
973 return true;
974 }
975
976 /*
977 * Returns a list of buttons that should be grabbed on a window.
978 * This list will always contain 1–3, all higher buttons will only be returned
979 * if there is a whole-window binding for it on some window in the current
980 * config.
981 * The list is terminated by a 0.
982 */
983 int *bindings_get_buttons_to_grab(void) {
984 /* Let's make the reasonable assumption that there's no more than 25
985 * buttons. */
986 int num_max = 25;
987
988 int buffer[num_max];
989 int num = 0;
990
991 /* We always return buttons 1 through 3. */
992 buffer[num++] = 1;
993 buffer[num++] = 2;
994 buffer[num++] = 3;
995
996 Binding *bind;
997 TAILQ_FOREACH (bind, bindings, bindings) {
998 if (num + 1 == num_max)
999 break;
1000
1001 /* We are only interested in whole window mouse bindings. */
1002 if (bind->input_type != B_MOUSE || !bind->whole_window)
1003 continue;
1004
1005 long button;
1006 if (!parse_long(bind->symbol + (sizeof("button") - 1), &button, 10)) {
1007 ELOG("Could not parse button number, skipping this binding. Please report this bug in i3.\n");
1008 continue;
1009 }
1010
1011 /* Avoid duplicates. */
1012 for (int i = 0; i < num; i++) {
1013 if (buffer[i] == button)
1014 continue;
1015 }
1016
1017 buffer[num++] = button;
1018 }
1019 buffer[num++] = 0;
1020
1021 int *buttons = scalloc(num, sizeof(int));
1022 memcpy(buttons, buffer, num * sizeof(int));
1023
1024 return buttons;
1025 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * click.c: Button press (mouse click) events.
7 *
8 */
9 #include "all.h"
10
11 #include <time.h>
12 #include <math.h>
13
14 #include <xcb/xcb_icccm.h>
15
16 #include <X11/XKBlib.h>
17
18 typedef enum { CLICK_BORDER = 0,
19 CLICK_DECORATION = 1,
20 CLICK_INSIDE = 2 } click_destination_t;
21
22 /*
23 * Finds the correct pair of first/second cons between the resize will take
24 * place according to the passed border position (top, left, right, bottom),
25 * then calls resize_graphical_handler().
26 *
27 */
28 static bool tiling_resize_for_border(Con *con, border_t border, xcb_button_press_event_t *event, bool use_threshold) {
29 DLOG("border = %d, con = %p\n", border, con);
30 Con *second = NULL;
31 Con *first = con;
32 direction_t search_direction;
33 switch (border) {
34 case BORDER_LEFT:
35 search_direction = D_LEFT;
36 break;
37 case BORDER_RIGHT:
38 search_direction = D_RIGHT;
39 break;
40 case BORDER_TOP:
41 search_direction = D_UP;
42 break;
43 case BORDER_BOTTOM:
44 search_direction = D_DOWN;
45 break;
46 }
47
48 bool res = resize_find_tiling_participants(&first, &second, search_direction, false);
49 if (!res) {
50 DLOG("No second container in this direction found.\n");
51 return false;
52 }
53 if (first->fullscreen_mode != second->fullscreen_mode) {
54 DLOG("Avoiding resize between containers with different fullscreen modes, %d != %d\n", first->fullscreen_mode, second->fullscreen_mode);
55 return false;
56 }
57
58 assert(first != second);
59 assert(first->parent == second->parent);
60
61 /* The first container should always be in front of the second container */
62 if (search_direction == D_UP || search_direction == D_LEFT) {
63 Con *tmp = first;
64 first = second;
65 second = tmp;
66 }
67
68 const orientation_t orientation = ((border == BORDER_LEFT || border == BORDER_RIGHT) ? HORIZ : VERT);
69
70 resize_graphical_handler(first, second, orientation, event, use_threshold);
71
72 DLOG("After resize handler, rendering\n");
73 tree_render();
74 return true;
75 }
76
77 /*
78 * Called when the user clicks using the floating_modifier, but the client is in
79 * tiling layout.
80 *
81 * Returns false if it does not do anything (that is, the click should be sent
82 * to the client).
83 *
84 */
85 static bool floating_mod_on_tiled_client(Con *con, xcb_button_press_event_t *event) {
86 /* The client is in tiling layout. We can still initiate a resize with the
87 * right mouse button, by chosing the border which is the most near one to
88 * the position of the mouse pointer */
89 int to_right = con->rect.width - event->event_x,
90 to_left = event->event_x,
91 to_top = event->event_y,
92 to_bottom = con->rect.height - event->event_y;
93
94 DLOG("click was %d px to the right, %d px to the left, %d px to top, %d px to bottom\n",
95 to_right, to_left, to_top, to_bottom);
96
97 if (to_right < to_left &&
98 to_right < to_top &&
99 to_right < to_bottom)
100 return tiling_resize_for_border(con, BORDER_RIGHT, event, false);
101
102 if (to_left < to_right &&
103 to_left < to_top &&
104 to_left < to_bottom)
105 return tiling_resize_for_border(con, BORDER_LEFT, event, false);
106
107 if (to_top < to_right &&
108 to_top < to_left &&
109 to_top < to_bottom)
110 return tiling_resize_for_border(con, BORDER_TOP, event, false);
111
112 if (to_bottom < to_right &&
113 to_bottom < to_left &&
114 to_bottom < to_top)
115 return tiling_resize_for_border(con, BORDER_BOTTOM, event, false);
116
117 return false;
118 }
119
120 /*
121 * Finds out which border was clicked on and calls tiling_resize_for_border().
122 *
123 */
124 static bool tiling_resize(Con *con, xcb_button_press_event_t *event, const click_destination_t dest, bool use_threshold) {
125 /* check if this was a click on the window border (and on which one) */
126 Rect bsr = con_border_style_rect(con);
127 DLOG("BORDER x = %d, y = %d for con %p, window 0x%08x\n",
128 event->event_x, event->event_y, con, event->event);
129 DLOG("checks for right >= %d\n", con->window_rect.x + con->window_rect.width);
130 if (dest == CLICK_DECORATION) {
131 return tiling_resize_for_border(con, BORDER_TOP, event, use_threshold);
132 }
133
134 if (event->event_x >= 0 && event->event_x <= (int32_t)bsr.x &&
135 event->event_y >= (int32_t)bsr.y && event->event_y <= (int32_t)(con->rect.height + bsr.height))
136 return tiling_resize_for_border(con, BORDER_LEFT, event, false);
137
138 if (event->event_x >= (int32_t)(con->window_rect.x + con->window_rect.width) &&
139 event->event_y >= (int32_t)bsr.y && event->event_y <= (int32_t)(con->rect.height + bsr.height))
140 return tiling_resize_for_border(con, BORDER_RIGHT, event, false);
141
142 if (event->event_y >= (int32_t)(con->window_rect.y + con->window_rect.height))
143 return tiling_resize_for_border(con, BORDER_BOTTOM, event, false);
144
145 return false;
146 }
147
148 /*
149 * Being called by handle_button_press, this function calls the appropriate
150 * functions for resizing/dragging.
151 *
152 */
153 static void route_click(Con *con, xcb_button_press_event_t *event, const bool mod_pressed, const click_destination_t dest) {
154 DLOG("--> click properties: mod = %d, destination = %d\n", mod_pressed, dest);
155 DLOG("--> OUTCOME = %p\n", con);
156 DLOG("type = %d, name = %s\n", con->type, con->name);
157
158 /* don’t handle dockarea cons, they must not be focused */
159 if (con->parent->type == CT_DOCKAREA)
160 goto done;
161
162 /* if the user has bound an action to this click, it should override the
163 * default behavior. */
164 Binding *bind = get_binding_from_xcb_event((xcb_generic_event_t *)event);
165 if (bind && ((dest == CLICK_DECORATION && !bind->exclude_titlebar) ||
166 (dest == CLICK_INSIDE && bind->whole_window) ||
167 (dest == CLICK_BORDER && bind->border))) {
168 CommandResult *result = run_binding(bind, con);
169
170 /* ASYNC_POINTER eats the event */
171 xcb_allow_events(conn, XCB_ALLOW_ASYNC_POINTER, event->time);
172 xcb_flush(conn);
173
174 command_result_free(result);
175 return;
176 }
177
178 /* There is no default behavior for button release events so we are done. */
179 if (event->response_type == XCB_BUTTON_RELEASE) {
180 goto done;
181 }
182
183 /* Any click in a workspace should focus that workspace. If the
184 * workspace is on another output we need to do a workspace_show in
185 * order for i3bar (and others) to notice the change in workspace. */
186 Con *ws = con_get_workspace(con);
187 Con *focused_workspace = con_get_workspace(focused);
188
189 if (!ws) {
190 ws = TAILQ_FIRST(&(output_get_content(con_get_output(con))->focus_head));
191 if (!ws)
192 goto done;
193 }
194
195 if (ws != focused_workspace)
196 workspace_show(ws);
197
198 /* get the floating con */
199 Con *floatingcon = con_inside_floating(con);
200 const bool proportional = (event->state & XCB_KEY_BUT_MASK_SHIFT) == XCB_KEY_BUT_MASK_SHIFT;
201 const bool in_stacked = (con->parent->layout == L_STACKED || con->parent->layout == L_TABBED);
202 const bool was_focused = focused == con;
203 const bool is_left_click = (event->detail == XCB_BUTTON_CLICK_LEFT);
204 const bool is_right_click = (event->detail == XCB_BUTTON_CLICK_RIGHT);
205 const bool is_left_or_right_click = (is_left_click || is_right_click);
206 const bool is_scroll = (event->detail == XCB_BUTTON_SCROLL_UP ||
207 event->detail == XCB_BUTTON_SCROLL_DOWN ||
208 event->detail == XCB_BUTTON_SCROLL_LEFT ||
209 event->detail == XCB_BUTTON_SCROLL_RIGHT);
210
211 /* 1: see if the user scrolled on the decoration of a stacked/tabbed con */
212 if (in_stacked && dest == CLICK_DECORATION && is_scroll) {
213 DLOG("Scrolling on a window decoration\n");
214 /* Use the focused child of the tabbed / stacked container, not the
215 * container the user scrolled on. */
216 Con *current = TAILQ_FIRST(&(con->parent->focus_head));
217 const position_t direction =
218 (event->detail == XCB_BUTTON_SCROLL_UP || event->detail == XCB_BUTTON_SCROLL_LEFT) ? BEFORE : AFTER;
219 Con *next = get_tree_next_sibling(current, direction);
220 con_activate(con_descend_focused(next ? next : current));
221
222 goto done;
223 }
224
225 /* 2: focus this con. */
226 con_activate(con);
227
228 /* 3: For floating containers, we also want to raise them on click.
229 * We will skip handling events on floating cons in fullscreen mode */
230 Con *fs = con_get_fullscreen_covering_ws(ws);
231 if (floatingcon != NULL && fs != con) {
232 /* 4: floating_modifier plus left mouse button drags */
233 if (mod_pressed && is_left_click) {
234 floating_drag_window(floatingcon, event, false);
235 return;
236 }
237
238 /* 5: resize (floating) if this was a (left or right) click on the
239 * left/right/bottom border, or a right click on the decoration.
240 * also try resizing (tiling) if possible */
241 if (mod_pressed && is_right_click) {
242 DLOG("floating resize due to floatingmodifier\n");
243 floating_resize_window(floatingcon, proportional, event);
244 return;
245 }
246
247 if ((dest == CLICK_BORDER || dest == CLICK_DECORATION) &&
248 is_left_or_right_click) {
249 /* try tiling resize, but continue if it doesn’t work */
250 DLOG("tiling resize with fallback\n");
251 if (tiling_resize(con, event, dest, dest == CLICK_DECORATION && !was_focused))
252 goto done;
253 }
254
255 if (dest == CLICK_DECORATION && is_right_click) {
256 DLOG("floating resize due to decoration right click\n");
257 floating_resize_window(floatingcon, proportional, event);
258 return;
259 }
260
261 if (dest == CLICK_BORDER && is_left_or_right_click) {
262 DLOG("floating resize due to border click\n");
263 floating_resize_window(floatingcon, proportional, event);
264 return;
265 }
266
267 /* 6: dragging, if this was a click on a decoration (which did not lead
268 * to a resize) */
269 if (dest == CLICK_DECORATION && is_left_click) {
270 floating_drag_window(floatingcon, event, !was_focused);
271 return;
272 }
273
274 goto done;
275 }
276
277 /* 7: floating modifier pressed, initiate a resize */
278 if (dest == CLICK_INSIDE && mod_pressed && is_right_click) {
279 floating_mod_on_tiled_client(con, event);
280 /* Avoid propagating events to clients, since the user expects
281 * $mod + click to be handled by i3. */
282 return;
283 }
284 /* 8: otherwise, check for border/decoration clicks and resize */
285 else if ((dest == CLICK_BORDER || dest == CLICK_DECORATION) &&
286 is_left_or_right_click) {
287 DLOG("Trying to resize (tiling)\n");
288 tiling_resize(con, event, dest, dest == CLICK_DECORATION && !was_focused);
289 }
290
291 done:
292 xcb_allow_events(conn, XCB_ALLOW_REPLAY_POINTER, event->time);
293 xcb_flush(conn);
294 tree_render();
295 }
296
297 /*
298 * The button press X callback. This function determines whether the floating
299 * modifier is pressed and where the user clicked (decoration, border, inside
300 * the window).
301 *
302 * Then, route_click is called on the appropriate con.
303 *
304 */
305 void handle_button_press(xcb_button_press_event_t *event) {
306 Con *con;
307 DLOG("Button %d (state %d) %s on window 0x%08x (child 0x%08x) at (%d, %d) (root %d, %d)\n",
308 event->detail, event->state, (event->response_type == XCB_BUTTON_PRESS ? "press" : "release"),
309 event->event, event->child, event->event_x, event->event_y, event->root_x,
310 event->root_y);
311
312 last_timestamp = event->time;
313
314 const uint32_t mod = (config.floating_modifier & 0xFFFF);
315 const bool mod_pressed = (mod != 0 && (event->state & mod) == mod);
316 DLOG("floating_mod = %d, detail = %d\n", mod_pressed, event->detail);
317 if ((con = con_by_window_id(event->event))) {
318 route_click(con, event, mod_pressed, CLICK_INSIDE);
319 return;
320 }
321
322 if (!(con = con_by_frame_id(event->event))) {
323 /* Run bindings on the root window as well, see #2097. We only run it
324 * if --whole-window was set as that's the equivalent for a normal
325 * window. */
326 if (event->event == root) {
327 Binding *bind = get_binding_from_xcb_event((xcb_generic_event_t *)event);
328 if (bind != NULL && bind->whole_window) {
329 CommandResult *result = run_binding(bind, NULL);
330 command_result_free(result);
331 }
332 }
333
334 /* If the root window is clicked, find the relevant output from the
335 * click coordinates and focus the output's active workspace. */
336 if (event->event == root && event->response_type == XCB_BUTTON_PRESS) {
337 Con *output, *ws;
338 TAILQ_FOREACH (output, &(croot->nodes_head), nodes) {
339 if (con_is_internal(output) ||
340 !rect_contains(output->rect, event->event_x, event->event_y))
341 continue;
342
343 ws = TAILQ_FIRST(&(output_get_content(output)->focus_head));
344 if (ws != con_get_workspace(focused)) {
345 workspace_show(ws);
346 tree_render();
347 }
348 return;
349 }
350 return;
351 }
352
353 ELOG("Clicked into unknown window?!\n");
354 xcb_allow_events(conn, XCB_ALLOW_REPLAY_POINTER, event->time);
355 xcb_flush(conn);
356 return;
357 }
358
359 /* Check if the click was on the decoration of a child */
360 Con *child;
361 TAILQ_FOREACH_REVERSE (child, &(con->nodes_head), nodes_head, nodes) {
362 if (!rect_contains(child->deco_rect, event->event_x, event->event_y))
363 continue;
364
365 route_click(child, event, mod_pressed, CLICK_DECORATION);
366 return;
367 }
368
369 if (event->child != XCB_NONE) {
370 DLOG("event->child not XCB_NONE, so this is an event which originated from a click into the application, but the application did not handle it.\n");
371 route_click(con, event, mod_pressed, CLICK_INSIDE);
372 return;
373 }
374
375 route_click(con, event, mod_pressed, CLICK_BORDER);
376 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * commands.c: all command functions (see commands_parser.c)
7 *
8 */
9 #include "all.h"
10
11 #include <stdint.h>
12 #include <float.h>
13 #include <stdarg.h>
14 #include <unistd.h>
15 #include <fcntl.h>
16
17 #include "shmlog.h"
18
19 // Macros to make the YAJL API a bit easier to use.
20 #define y(x, ...) (cmd_output->json_gen != NULL ? yajl_gen_##x(cmd_output->json_gen, ##__VA_ARGS__) : 0)
21 #define ystr(str) (cmd_output->json_gen != NULL ? yajl_gen_string(cmd_output->json_gen, (unsigned char *)str, strlen(str)) : 0)
22 #define ysuccess(success) \
23 do { \
24 if (cmd_output->json_gen != NULL) { \
25 y(map_open); \
26 ystr("success"); \
27 y(bool, success); \
28 y(map_close); \
29 } \
30 } while (0)
31 #define yerror(format, ...) \
32 do { \
33 if (cmd_output->json_gen != NULL) { \
34 char *message; \
35 sasprintf(&message, format, ##__VA_ARGS__); \
36 y(map_open); \
37 ystr("success"); \
38 y(bool, false); \
39 ystr("error"); \
40 ystr(message); \
41 y(map_close); \
42 free(message); \
43 } \
44 } while (0)
45
46 /** If an error occurred during parsing of the criteria, we want to exit instead
47 * of relying on fallback behavior. See #2091. */
48 #define HANDLE_INVALID_MATCH \
49 do { \
50 if (current_match->error != NULL) { \
51 yerror("Invalid match: %s", current_match->error); \
52 return; \
53 } \
54 } while (0)
55
56 /** When the command did not include match criteria (!), we use the currently
57 * focused container. Do not confuse this case with a command which included
58 * criteria but which did not match any windows. This macro has to be called in
59 * every command.
60 */
61 #define HANDLE_EMPTY_MATCH \
62 do { \
63 HANDLE_INVALID_MATCH; \
64 \
65 if (match_is_empty(current_match)) { \
66 while (!TAILQ_EMPTY(&owindows)) { \
67 owindow *ow = TAILQ_FIRST(&owindows); \
68 TAILQ_REMOVE(&owindows, ow, owindows); \
69 free(ow); \
70 } \
71 owindow *ow = smalloc(sizeof(owindow)); \
72 ow->con = focused; \
73 TAILQ_INIT(&owindows); \
74 TAILQ_INSERT_TAIL(&owindows, ow, owindows); \
75 } \
76 } while (0)
77
78 /*
79 * Checks whether we switched to a new workspace and returns false in that case,
80 * signaling that further workspace switching should be done by the calling function
81 * If not, calls workspace_back_and_forth() if workspace_auto_back_and_forth is set
82 * and return true, signaling that no further workspace switching should occur in the calling function.
83 *
84 */
85 static bool maybe_back_and_forth(struct CommandResultIR *cmd_output, const char *name) {
86 Con *ws = con_get_workspace(focused);
87
88 /* If we switched to a different workspace, do nothing */
89 if (strcmp(ws->name, name) != 0)
90 return false;
91
92 DLOG("This workspace is already focused.\n");
93 if (config.workspace_auto_back_and_forth) {
94 workspace_back_and_forth();
95 cmd_output->needs_tree_render = true;
96 }
97 return true;
98 }
99
100 /*
101 * Return the passed workspace unless it is the current one and auto back and
102 * forth is enabled, in which case the back_and_forth workspace is returned.
103 */
104 static Con *maybe_auto_back_and_forth_workspace(Con *workspace) {
105 Con *current, *baf;
106
107 if (!config.workspace_auto_back_and_forth)
108 return workspace;
109
110 current = con_get_workspace(focused);
111
112 if (current == workspace) {
113 baf = workspace_back_and_forth_get();
114 if (baf != NULL) {
115 DLOG("Substituting workspace with back_and_forth, as it is focused.\n");
116 return baf;
117 }
118 }
119
120 return workspace;
121 }
122
123 /*******************************************************************************
124 * Criteria functions.
125 ******************************************************************************/
126
127 /*
128 * Helper data structure for an operation window (window on which the operation
129 * will be performed). Used to build the TAILQ owindows.
130 *
131 */
132 typedef struct owindow {
133 Con *con;
134
135 TAILQ_ENTRY(owindow)
136 owindows;
137 } owindow;
138
139 typedef TAILQ_HEAD(owindows_head, owindow) owindows_head;
140
141 static owindows_head owindows;
142
143 /*
144 * Initializes the specified 'Match' data structure and the initial state of
145 * commands.c for matching target windows of a command.
146 *
147 */
148 void cmd_criteria_init(I3_CMD) {
149 Con *con;
150 owindow *ow;
151
152 DLOG("Initializing criteria, current_match = %p\n", current_match);
153 match_free(current_match);
154 match_init(current_match);
155 while (!TAILQ_EMPTY(&owindows)) {
156 ow = TAILQ_FIRST(&owindows);
157 TAILQ_REMOVE(&owindows, ow, owindows);
158 free(ow);
159 }
160 TAILQ_INIT(&owindows);
161 /* copy all_cons */
162 TAILQ_FOREACH (con, &all_cons, all_cons) {
163 ow = smalloc(sizeof(owindow));
164 ow->con = con;
165 TAILQ_INSERT_TAIL(&owindows, ow, owindows);
166 }
167 }
168
169 /*
170 * A match specification just finished (the closing square bracket was found),
171 * so we filter the list of owindows.
172 *
173 */
174 void cmd_criteria_match_windows(I3_CMD) {
175 owindow *next, *current;
176
177 DLOG("match specification finished, matching...\n");
178 /* copy the old list head to iterate through it and start with a fresh
179 * list which will contain only matching windows */
180 struct owindows_head old = owindows;
181 TAILQ_INIT(&owindows);
182 for (next = TAILQ_FIRST(&old); next != TAILQ_END(&old);) {
183 /* make a copy of the next pointer and advance the pointer to the
184 * next element as we are going to invalidate the element’s
185 * next/prev pointers by calling TAILQ_INSERT_TAIL later */
186 current = next;
187 next = TAILQ_NEXT(next, owindows);
188
189 DLOG("checking if con %p / %s matches\n", current->con, current->con->name);
190
191 /* We use this flag to prevent matching on window-less containers if
192 * only window-specific criteria were specified. */
193 bool accept_match = false;
194
195 if (current_match->con_id != NULL) {
196 accept_match = true;
197
198 if (current_match->con_id == current->con) {
199 DLOG("con_id matched.\n");
200 } else {
201 DLOG("con_id does not match.\n");
202 FREE(current);
203 continue;
204 }
205 }
206
207 if (current_match->mark != NULL && !TAILQ_EMPTY(&(current->con->marks_head))) {
208 accept_match = true;
209 bool matched_by_mark = false;
210
211 mark_t *mark;
212 TAILQ_FOREACH (mark, &(current->con->marks_head), marks) {
213 if (!regex_matches(current_match->mark, mark->name))
214 continue;
215
216 DLOG("match by mark\n");
217 matched_by_mark = true;
218 break;
219 }
220
221 if (!matched_by_mark) {
222 DLOG("mark does not match.\n");
223 FREE(current);
224 continue;
225 }
226 }
227
228 if (current->con->window != NULL) {
229 if (match_matches_window(current_match, current->con->window)) {
230 DLOG("matches window!\n");
231 accept_match = true;
232 } else {
233 DLOG("doesn't match\n");
234 FREE(current);
235 continue;
236 }
237 }
238
239 if (accept_match) {
240 TAILQ_INSERT_TAIL(&owindows, current, owindows);
241 } else {
242 FREE(current);
243 continue;
244 }
245 }
246
247 TAILQ_FOREACH (current, &owindows, owindows) {
248 DLOG("matching: %p / %s\n", current->con, current->con->name);
249 }
250 }
251
252 /*
253 * Interprets a ctype=cvalue pair and adds it to the current match
254 * specification.
255 *
256 */
257 void cmd_criteria_add(I3_CMD, const char *ctype, const char *cvalue) {
258 match_parse_property(current_match, ctype, cvalue);
259 }
260
261 static void move_matches_to_workspace(Con *ws) {
262 owindow *current;
263 TAILQ_FOREACH (current, &owindows, owindows) {
264 DLOG("matching: %p / %s\n", current->con, current->con->name);
265 con_move_to_workspace(current->con, ws, true, false, false);
266 }
267 }
268
269 #define CHECK_MOVE_CON_TO_WORKSPACE \
270 do { \
271 HANDLE_EMPTY_MATCH; \
272 if (TAILQ_EMPTY(&owindows)) { \
273 yerror("Nothing to move: specified criteria don't match any window"); \
274 return; \
275 } else { \
276 bool found = false; \
277 owindow *current = TAILQ_FIRST(&owindows); \
278 while (current) { \
279 owindow *next = TAILQ_NEXT(current, owindows); \
280 \
281 if (current->con->type == CT_WORKSPACE && !con_has_children(current->con)) { \
282 TAILQ_REMOVE(&owindows, current, owindows); \
283 } else { \
284 found = true; \
285 } \
286 \
287 current = next; \
288 } \
289 if (!found) { \
290 yerror("Nothing to move: workspace empty"); \
291 return; \
292 } \
293 } \
294 } while (0)
295
296 /*
297 * Implementation of 'move [window|container] [to] workspace
298 * next|prev|next_on_output|prev_on_output|current'.
299 *
300 */
301 void cmd_move_con_to_workspace(I3_CMD, const char *which) {
302 DLOG("which=%s\n", which);
303
304 CHECK_MOVE_CON_TO_WORKSPACE;
305
306 /* get the workspace */
307 Con *ws;
308 if (strcmp(which, "next") == 0)
309 ws = workspace_next();
310 else if (strcmp(which, "prev") == 0)
311 ws = workspace_prev();
312 else if (strcmp(which, "next_on_output") == 0)
313 ws = workspace_next_on_output();
314 else if (strcmp(which, "prev_on_output") == 0)
315 ws = workspace_prev_on_output();
316 else if (strcmp(which, "current") == 0)
317 ws = con_get_workspace(focused);
318 else {
319 yerror("BUG: called with which=%s", which);
320 return;
321 }
322
323 move_matches_to_workspace(ws);
324
325 cmd_output->needs_tree_render = true;
326 // XXX: default reply for now, make this a better reply
327 ysuccess(true);
328 }
329
330 /*
331 * Implementation of 'move [window|container] [to] workspace back_and_forth'.
332 *
333 */
334 void cmd_move_con_to_workspace_back_and_forth(I3_CMD) {
335 Con *ws = workspace_back_and_forth_get();
336 if (ws == NULL) {
337 yerror("No workspace was previously active.");
338 return;
339 }
340
341 HANDLE_EMPTY_MATCH;
342
343 move_matches_to_workspace(ws);
344
345 cmd_output->needs_tree_render = true;
346 // XXX: default reply for now, make this a better reply
347 ysuccess(true);
348 }
349
350 /*
351 * Implementation of 'move [--no-auto-back-and-forth] [window|container] [to] workspace <name>'.
352 *
353 */
354 void cmd_move_con_to_workspace_name(I3_CMD, const char *name, const char *no_auto_back_and_forth) {
355 if (strncasecmp(name, "__", strlen("__")) == 0) {
356 yerror("You cannot move containers to i3-internal workspaces (\"%s\").", name);
357 return;
358 }
359
360 CHECK_MOVE_CON_TO_WORKSPACE;
361
362 LOG("should move window to workspace %s\n", name);
363 /* get the workspace */
364 Con *ws = workspace_get(name, NULL);
365
366 if (no_auto_back_and_forth == NULL) {
367 ws = maybe_auto_back_and_forth_workspace(ws);
368 }
369
370 move_matches_to_workspace(ws);
371
372 cmd_output->needs_tree_render = true;
373 // XXX: default reply for now, make this a better reply
374 ysuccess(true);
375 }
376
377 /*
378 * Implementation of 'move [--no-auto-back-and-forth] [window|container] [to] workspace number <name>'.
379 *
380 */
381 void cmd_move_con_to_workspace_number(I3_CMD, const char *which, const char *no_auto_back_and_forth) {
382 CHECK_MOVE_CON_TO_WORKSPACE;
383
384 LOG("should move window to workspace %s\n", which);
385
386 long parsed_num = ws_name_to_number(which);
387 if (parsed_num == -1) {
388 LOG("Could not parse initial part of \"%s\" as a number.\n", which);
389 yerror("Could not parse number \"%s\"", which);
390 return;
391 }
392
393 Con *ws = get_existing_workspace_by_num(parsed_num);
394 if (!ws) {
395 ws = workspace_get(which, NULL);
396 }
397
398 if (no_auto_back_and_forth == NULL) {
399 ws = maybe_auto_back_and_forth_workspace(ws);
400 }
401
402 move_matches_to_workspace(ws);
403
404 cmd_output->needs_tree_render = true;
405 // XXX: default reply for now, make this a better reply
406 ysuccess(true);
407 }
408
409 /*
410 * Convert a string direction ("left", "right", etc.) to a direction_t. Assumes
411 * valid direction string.
412 */
413 static direction_t parse_direction(const char *str) {
414 if (strcmp(str, "left") == 0) {
415 return D_LEFT;
416 } else if (strcmp(str, "right") == 0) {
417 return D_RIGHT;
418 } else if (strcmp(str, "up") == 0) {
419 return D_UP;
420 } else if (strcmp(str, "down") == 0) {
421 return D_DOWN;
422 } else {
423 ELOG("Invalid direction. This is a parser bug.\n");
424 assert(false);
425 }
426 }
427
428 static void cmd_resize_floating(I3_CMD, const char *direction_str, Con *floating_con, int px) {
429 Rect old_rect = floating_con->rect;
430 Con *focused_con = con_descend_focused(floating_con);
431
432 direction_t direction;
433 if (strcmp(direction_str, "height") == 0) {
434 direction = D_DOWN;
435 } else if (strcmp(direction_str, "width") == 0) {
436 direction = D_RIGHT;
437 } else {
438 direction = parse_direction(direction_str);
439 }
440 orientation_t orientation = orientation_from_direction(direction);
441
442 /* ensure that resize will take place even if pixel increment is smaller than
443 * height increment or width increment.
444 * fixes #1011 */
445 const i3Window *window = focused_con->window;
446 if (window != NULL) {
447 if (orientation == VERT) {
448 if (px < 0) {
449 px = (-px < window->height_increment) ? -window->height_increment : px;
450 } else {
451 px = (px < window->height_increment) ? window->height_increment : px;
452 }
453 } else {
454 if (px < 0) {
455 px = (-px < window->width_increment) ? -window->width_increment : px;
456 } else {
457 px = (px < window->width_increment) ? window->width_increment : px;
458 }
459 }
460 }
461
462 if (orientation == VERT) {
463 floating_con->rect.height += px;
464 } else {
465 floating_con->rect.width += px;
466 }
467 floating_check_size(floating_con, orientation == VERT);
468
469 /* Did we actually resize anything or did the size constraints prevent us?
470 * If we could not resize, exit now to not move the window. */
471 if (rect_equals(old_rect, floating_con->rect)) {
472 return;
473 }
474
475 if (direction == D_UP) {
476 floating_con->rect.y -= (floating_con->rect.height - old_rect.height);
477 } else if (direction == D_LEFT) {
478 floating_con->rect.x -= (floating_con->rect.width - old_rect.width);
479 }
480
481 /* If this is a scratchpad window, don't auto center it from now on. */
482 if (floating_con->scratchpad_state == SCRATCHPAD_FRESH) {
483 floating_con->scratchpad_state = SCRATCHPAD_CHANGED;
484 }
485 }
486
487 static bool cmd_resize_tiling_direction(I3_CMD, Con *current, const char *direction, int px, int ppt) {
488 Con *second = NULL;
489 Con *first = current;
490 direction_t search_direction = parse_direction(direction);
491
492 bool res = resize_find_tiling_participants(&first, &second, search_direction, false);
493 if (!res) {
494 yerror("No second container found in this direction.");
495 return false;
496 }
497
498 if (ppt) {
499 /* For backwards compatibility, 'X px or Y ppt' means that ppt is
500 * preferred. */
501 px = 0;
502 }
503 return resize_neighboring_cons(first, second, px, ppt);
504 }
505
506 static bool cmd_resize_tiling_width_height(I3_CMD, Con *current, const char *direction, int px, double ppt) {
507 LOG("width/height resize\n");
508
509 /* get the appropriate current container (skip stacked/tabbed cons) */
510 Con *dummy = NULL;
511 direction_t search_direction = (strcmp(direction, "width") == 0 ? D_LEFT : D_DOWN);
512 bool search_result = resize_find_tiling_participants(&current, &dummy, search_direction, true);
513 if (search_result == false) {
514 yerror("Failed to find appropriate tiling containers for resize operation");
515 return false;
516 }
517
518 /* get the default percentage */
519 int children = con_num_children(current->parent);
520 LOG("ins. %d children\n", children);
521 double percentage = 1.0 / children;
522 LOG("default percentage = %f\n", percentage);
523
524 /* Ensure all the other children have a percentage set. */
525 Con *child;
526 TAILQ_FOREACH (child, &(current->parent->nodes_head), nodes) {
527 LOG("child->percent = %f (child %p)\n", child->percent, child);
528 if (child->percent == 0.0)
529 child->percent = percentage;
530 }
531
532 double new_current_percent;
533 double subtract_percent;
534 if (ppt != 0.0) {
535 new_current_percent = current->percent + ppt;
536 } else {
537 /* Convert px change to change in percentages */
538 ppt = (double)px / (double)con_rect_size_in_orientation(current->parent);
539 new_current_percent = current->percent + ppt;
540 }
541 subtract_percent = ppt / (children - 1);
542 if (ppt < 0.0 && new_current_percent < percent_for_1px(current)) {
543 yerror("Not resizing, container would end with less than 1px");
544 return false;
545 }
546
547 LOG("new_current_percent = %f\n", new_current_percent);
548 LOG("subtract_percent = %f\n", subtract_percent);
549 /* Ensure that the new percentages are positive. */
550 if (subtract_percent >= 0.0) {
551 TAILQ_FOREACH (child, &(current->parent->nodes_head), nodes) {
552 if (child == current) {
553 continue;
554 }
555 if (child->percent - subtract_percent < percent_for_1px(child)) {
556 yerror("Not resizing, already at minimum size (child %p would end up with a size of %.f", child, child->percent - subtract_percent);
557 return false;
558 }
559 }
560 }
561
562 current->percent = new_current_percent;
563 LOG("current->percent after = %f\n", current->percent);
564
565 TAILQ_FOREACH (child, &(current->parent->nodes_head), nodes) {
566 if (child == current)
567 continue;
568 child->percent -= subtract_percent;
569 LOG("child->percent after (%p) = %f\n", child, child->percent);
570 }
571
572 return true;
573 }
574
575 /*
576 * Implementation of 'resize grow|shrink <direction> [<px> px] [or <ppt> ppt]'.
577 *
578 */
579 void cmd_resize(I3_CMD, const char *way, const char *direction, long resize_px, long resize_ppt) {
580 DLOG("resizing in way %s, direction %s, px %ld or ppt %ld\n", way, direction, resize_px, resize_ppt);
581 if (strcmp(way, "shrink") == 0) {
582 resize_px *= -1;
583 resize_ppt *= -1;
584 }
585
586 HANDLE_EMPTY_MATCH;
587
588 owindow *current;
589 TAILQ_FOREACH (current, &owindows, owindows) {
590 /* Don't handle dock windows (issue #1201) */
591 if (current->con->window && current->con->window->dock) {
592 DLOG("This is a dock window. Not resizing (con = %p)\n)", current->con);
593 continue;
594 }
595
596 Con *floating_con;
597 if ((floating_con = con_inside_floating(current->con))) {
598 cmd_resize_floating(current_match, cmd_output, direction, floating_con, resize_px);
599 } else {
600 if (strcmp(direction, "width") == 0 ||
601 strcmp(direction, "height") == 0) {
602 const double ppt = (double)resize_ppt / 100.0;
603 if (!cmd_resize_tiling_width_height(current_match, cmd_output,
604 current->con, direction,
605 resize_px, ppt)) {
606 yerror("Cannot resize.");
607 return;
608 }
609 } else {
610 if (!cmd_resize_tiling_direction(current_match, cmd_output,
611 current->con, direction,
612 resize_px, resize_ppt)) {
613 yerror("Cannot resize.");
614 return;
615 }
616 }
617 }
618 }
619
620 cmd_output->needs_tree_render = true;
621 // XXX: default reply for now, make this a better reply
622 ysuccess(true);
623 }
624
625 static bool resize_set_tiling(I3_CMD, Con *target, orientation_t resize_orientation, bool is_ppt, long target_size) {
626 direction_t search_direction;
627 char *mode;
628 if (resize_orientation == HORIZ) {
629 search_direction = D_LEFT;
630 mode = "width";
631 } else {
632 search_direction = D_DOWN;
633 mode = "height";
634 }
635
636 /* Get the appropriate current container (skip stacked/tabbed cons) */
637 Con *dummy;
638 resize_find_tiling_participants(&target, &dummy, search_direction, true);
639
640 /* Calculate new size for the target container */
641 double ppt = 0.0;
642 int px = 0;
643 if (is_ppt) {
644 ppt = (double)target_size / 100.0 - target->percent;
645 } else {
646 px = target_size - (resize_orientation == HORIZ ? target->rect.width : target->rect.height);
647 }
648
649 /* Perform resizing and report failure if not possible */
650 return cmd_resize_tiling_width_height(current_match, cmd_output,
651 target, mode, px, ppt);
652 }
653
654 /*
655 * Implementation of 'resize set <width> [px | ppt] <height> [px | ppt]'.
656 *
657 */
658 void cmd_resize_set(I3_CMD, long cwidth, const char *mode_width, long cheight, const char *mode_height) {
659 DLOG("resizing to %ld %s x %ld %s\n", cwidth, mode_width, cheight, mode_height);
660 if (cwidth < 0 || cheight < 0) {
661 yerror("Dimensions cannot be negative.");
662 return;
663 }
664
665 HANDLE_EMPTY_MATCH;
666
667 owindow *current;
668 bool success = true;
669 TAILQ_FOREACH (current, &owindows, owindows) {
670 Con *floating_con;
671 if ((floating_con = con_inside_floating(current->con))) {
672 Con *output = con_get_output(floating_con);
673 if (cwidth == 0) {
674 cwidth = floating_con->rect.width;
675 } else if (mode_width && strcmp(mode_width, "ppt") == 0) {
676 cwidth = output->rect.width * ((double)cwidth / 100.0);
677 }
678 if (cheight == 0) {
679 cheight = floating_con->rect.height;
680 } else if (mode_height && strcmp(mode_height, "ppt") == 0) {
681 cheight = output->rect.height * ((double)cheight / 100.0);
682 }
683 floating_resize(floating_con, cwidth, cheight);
684 } else {
685 if (current->con->window && current->con->window->dock) {
686 DLOG("This is a dock window. Not resizing (con = %p)\n)", current->con);
687 continue;
688 }
689
690 if (cwidth > 0) {
691 bool is_ppt = mode_width && strcmp(mode_width, "ppt") == 0;
692 success &= resize_set_tiling(current_match, cmd_output, current->con,
693 HORIZ, is_ppt, cwidth);
694 }
695 if (cheight > 0) {
696 bool is_ppt = mode_height && strcmp(mode_height, "ppt") == 0;
697 success &= resize_set_tiling(current_match, cmd_output, current->con,
698 VERT, is_ppt, cheight);
699 }
700 }
701 }
702
703 cmd_output->needs_tree_render = true;
704 ysuccess(success);
705 }
706
707 static int border_width_from_style(border_style_t border_style, long border_width, Con *con) {
708 if (border_style == BS_NONE) {
709 return 0;
710 }
711 if (border_width >= 0) {
712 return logical_px(border_width);
713 }
714
715 const bool is_floating = con_inside_floating(con) != NULL;
716 /* Load the configured defaults. */
717 if (is_floating && border_style == config.default_floating_border) {
718 return config.default_floating_border_width;
719 } else if (!is_floating && border_style == config.default_border) {
720 return config.default_border_width;
721 } else {
722 /* Use some hardcoded values. */
723 return logical_px(border_style == BS_NORMAL ? 2 : 1);
724 }
725 }
726
727 /*
728 * Implementation of 'border normal|pixel [<n>]', 'border none|1pixel|toggle'.
729 *
730 */
731 void cmd_border(I3_CMD, const char *border_style_str, long border_width) {
732 DLOG("border style should be changed to %s with border width %ld\n", border_style_str, border_width);
733 owindow *current;
734
735 HANDLE_EMPTY_MATCH;
736
737 TAILQ_FOREACH (current, &owindows, owindows) {
738 DLOG("matching: %p / %s\n", current->con, current->con->name);
739
740 border_style_t border_style;
741 if (strcmp(border_style_str, "toggle") == 0) {
742 border_style = (current->con->border_style + 1) % 3;
743 } else if (strcmp(border_style_str, "normal") == 0) {
744 border_style = BS_NORMAL;
745 } else if (strcmp(border_style_str, "pixel") == 0) {
746 border_style = BS_PIXEL;
747 } else if (strcmp(border_style_str, "none") == 0) {
748 border_style = BS_NONE;
749 } else {
750 yerror("BUG: called with border_style=%s", border_style_str);
751 return;
752 }
753
754 const int con_border_width = border_width_from_style(border_style, border_width, current->con);
755 con_set_border_style(current->con, border_style, con_border_width);
756 }
757
758 cmd_output->needs_tree_render = true;
759 ysuccess(true);
760 }
761
762 /*
763 * Implementation of 'nop <comment>'.
764 *
765 */
766 void cmd_nop(I3_CMD, const char *comment) {
767 LOG("-------------------------------------------------\n");
768 LOG(" NOP: %.4000s\n", comment);
769 LOG("-------------------------------------------------\n");
770 ysuccess(true);
771 }
772
773 /*
774 * Implementation of 'append_layout <path>'.
775 *
776 */
777 void cmd_append_layout(I3_CMD, const char *cpath) {
778 LOG("Appending layout \"%s\"\n", cpath);
779
780 /* Make sure we allow paths like '~/.i3/layout.json' */
781 char *path = resolve_tilde(cpath);
782
783 char *buf = NULL;
784 ssize_t len;
785 if ((len = slurp(path, &buf)) < 0) {
786 yerror("Could not slurp \"%s\".", path);
787 /* slurp already logged an error. */
788 goto out;
789 }
790
791 if (!json_validate(buf, len)) {
792 ELOG("Could not parse \"%s\" as JSON, not loading.\n", path);
793 yerror("Could not parse \"%s\" as JSON.", path);
794 goto out;
795 }
796
797 json_content_t content = json_determine_content(buf, len);
798 LOG("JSON content = %d\n", content);
799 if (content == JSON_CONTENT_UNKNOWN) {
800 ELOG("Could not determine the contents of \"%s\", not loading.\n", path);
801 yerror("Could not determine the contents of \"%s\".", path);
802 goto out;
803 }
804
805 Con *parent = focused;
806 if (content == JSON_CONTENT_WORKSPACE) {
807 parent = output_get_content(con_get_output(parent));
808 } else {
809 /* We need to append the layout to a split container, since a leaf
810 * container must not have any children (by definition).
811 * Note that we explicitly check for workspaces, since they are okay for
812 * this purpose, but con_accepts_window() returns false for workspaces. */
813 while (parent->type != CT_WORKSPACE && !con_accepts_window(parent))
814 parent = parent->parent;
815 }
816 DLOG("Appending to parent=%p instead of focused=%p\n", parent, focused);
817 char *errormsg = NULL;
818 tree_append_json(parent, buf, len, &errormsg);
819 if (errormsg != NULL) {
820 yerror(errormsg);
821 free(errormsg);
822 /* Note that we continue executing since tree_append_json() has
823 * side-effects — user-provided layouts can be partly valid, partly
824 * invalid, leading to half of the placeholder containers being
825 * created. */
826 } else {
827 ysuccess(true);
828 }
829
830 // XXX: This is a bit of a kludge. Theoretically, render_con(parent,
831 // false); should be enough, but when sending 'workspace 4; append_layout
832 // /tmp/foo.json', the needs_tree_render == true of the workspace command
833 // is not executed yet and will be batched with append_layout’s
834 // needs_tree_render after the parser finished. We should check if that is
835 // necessary at all.
836 render_con(croot, false);
837
838 restore_open_placeholder_windows(parent);
839
840 if (content == JSON_CONTENT_WORKSPACE)
841 ipc_send_workspace_event("restored", parent, NULL);
842
843 cmd_output->needs_tree_render = true;
844 out:
845 free(path);
846 free(buf);
847 }
848
849 /*
850 * Implementation of 'workspace next|prev|next_on_output|prev_on_output'.
851 *
852 */
853 void cmd_workspace(I3_CMD, const char *which) {
854 Con *ws;
855
856 DLOG("which=%s\n", which);
857
858 if (con_get_fullscreen_con(croot, CF_GLOBAL)) {
859 yerror("Cannot switch workspace while in global fullscreen");
860 return;
861 }
862
863 if (strcmp(which, "next") == 0)
864 ws = workspace_next();
865 else if (strcmp(which, "prev") == 0)
866 ws = workspace_prev();
867 else if (strcmp(which, "next_on_output") == 0)
868 ws = workspace_next_on_output();
869 else if (strcmp(which, "prev_on_output") == 0)
870 ws = workspace_prev_on_output();
871 else {
872 yerror("BUG: called with which=%s", which);
873 return;
874 }
875
876 workspace_show(ws);
877
878 cmd_output->needs_tree_render = true;
879 // XXX: default reply for now, make this a better reply
880 ysuccess(true);
881 }
882
883 /*
884 * Implementation of 'workspace [--no-auto-back-and-forth] number <name>'
885 *
886 */
887 void cmd_workspace_number(I3_CMD, const char *which, const char *_no_auto_back_and_forth) {
888 const bool no_auto_back_and_forth = (_no_auto_back_and_forth != NULL);
889
890 if (con_get_fullscreen_con(croot, CF_GLOBAL)) {
891 yerror("Cannot switch workspace while in global fullscreen");
892 return;
893 }
894
895 long parsed_num = ws_name_to_number(which);
896 if (parsed_num == -1) {
897 yerror("Could not parse initial part of \"%s\" as a number.", which);
898 return;
899 }
900
901 Con *workspace = get_existing_workspace_by_num(parsed_num);
902 if (!workspace) {
903 LOG("There is no workspace with number %ld, creating a new one.\n", parsed_num);
904 ysuccess(true);
905 workspace_show_by_name(which);
906 cmd_output->needs_tree_render = true;
907 return;
908 }
909 if (!no_auto_back_and_forth && maybe_back_and_forth(cmd_output, workspace->name)) {
910 ysuccess(true);
911 return;
912 }
913 workspace_show(workspace);
914
915 cmd_output->needs_tree_render = true;
916 // XXX: default reply for now, make this a better reply
917 ysuccess(true);
918 }
919
920 /*
921 * Implementation of 'workspace back_and_forth'.
922 *
923 */
924 void cmd_workspace_back_and_forth(I3_CMD) {
925 if (con_get_fullscreen_con(croot, CF_GLOBAL)) {
926 yerror("Cannot switch workspace while in global fullscreen");
927 return;
928 }
929
930 workspace_back_and_forth();
931
932 cmd_output->needs_tree_render = true;
933 // XXX: default reply for now, make this a better reply
934 ysuccess(true);
935 }
936
937 /*
938 * Implementation of 'workspace [--no-auto-back-and-forth] <name>'
939 *
940 */
941 void cmd_workspace_name(I3_CMD, const char *name, const char *_no_auto_back_and_forth) {
942 const bool no_auto_back_and_forth = (_no_auto_back_and_forth != NULL);
943
944 if (strncasecmp(name, "__", strlen("__")) == 0) {
945 yerror("You cannot switch to the i3-internal workspaces (\"%s\").", name);
946 return;
947 }
948
949 if (con_get_fullscreen_con(croot, CF_GLOBAL)) {
950 yerror("Cannot switch workspace while in global fullscreen");
951 return;
952 }
953
954 DLOG("should switch to workspace %s\n", name);
955 if (!no_auto_back_and_forth && maybe_back_and_forth(cmd_output, name)) {
956 ysuccess(true);
957 return;
958 }
959 workspace_show_by_name(name);
960
961 cmd_output->needs_tree_render = true;
962 // XXX: default reply for now, make this a better reply
963 ysuccess(true);
964 }
965
966 /*
967 * Implementation of 'mark [--add|--replace] [--toggle] <mark>'
968 *
969 */
970 void cmd_mark(I3_CMD, const char *mark, const char *mode, const char *toggle) {
971 HANDLE_EMPTY_MATCH;
972
973 owindow *current = TAILQ_FIRST(&owindows);
974 if (current == NULL) {
975 yerror("Given criteria don't match a window");
976 return;
977 }
978
979 /* Marks must be unique, i.e., no two windows must have the same mark. */
980 if (current != TAILQ_LAST(&owindows, owindows_head)) {
981 yerror("A mark must not be put onto more than one window");
982 return;
983 }
984
985 DLOG("matching: %p / %s\n", current->con, current->con->name);
986
987 mark_mode_t mark_mode = (mode == NULL || strcmp(mode, "--replace") == 0) ? MM_REPLACE : MM_ADD;
988 if (toggle != NULL) {
989 con_mark_toggle(current->con, mark, mark_mode);
990 } else {
991 con_mark(current->con, mark, mark_mode);
992 }
993
994 cmd_output->needs_tree_render = true;
995 // XXX: default reply for now, make this a better reply
996 ysuccess(true);
997 }
998
999 /*
1000 * Implementation of 'unmark [mark]'
1001 *
1002 */
1003 void cmd_unmark(I3_CMD, const char *mark) {
1004 if (match_is_empty(current_match)) {
1005 con_unmark(NULL, mark);
1006 } else {
1007 owindow *current;
1008 TAILQ_FOREACH (current, &owindows, owindows) {
1009 con_unmark(current->con, mark);
1010 }
1011 }
1012
1013 cmd_output->needs_tree_render = true;
1014 // XXX: default reply for now, make this a better reply
1015 ysuccess(true);
1016 }
1017
1018 /*
1019 * Implementation of 'mode <string>'.
1020 *
1021 */
1022 void cmd_mode(I3_CMD, const char *mode) {
1023 DLOG("mode=%s\n", mode);
1024 switch_mode(mode);
1025
1026 // XXX: default reply for now, make this a better reply
1027 ysuccess(true);
1028 }
1029
1030 /*
1031 * Implementation of 'move [window|container] [to] output <str>'.
1032 *
1033 */
1034 void cmd_move_con_to_output(I3_CMD, const char *name) {
1035 DLOG("Should move window to output \"%s\".\n", name);
1036 HANDLE_EMPTY_MATCH;
1037
1038 owindow *current;
1039 bool had_error = false;
1040 TAILQ_FOREACH (current, &owindows, owindows) {
1041 DLOG("matching: %p / %s\n", current->con, current->con->name);
1042
1043 had_error |= !con_move_to_output_name(current->con, name, true);
1044 }
1045
1046 cmd_output->needs_tree_render = true;
1047 ysuccess(!had_error);
1048 }
1049
1050 /*
1051 * Implementation of 'move [container|window] [to] mark <str>'.
1052 *
1053 */
1054 void cmd_move_con_to_mark(I3_CMD, const char *mark) {
1055 DLOG("moving window to mark \"%s\"\n", mark);
1056
1057 HANDLE_EMPTY_MATCH;
1058
1059 bool result = true;
1060 owindow *current;
1061 TAILQ_FOREACH (current, &owindows, owindows) {
1062 DLOG("moving matched window %p / %s to mark \"%s\"\n", current->con, current->con->name, mark);
1063 result &= con_move_to_mark(current->con, mark);
1064 }
1065
1066 cmd_output->needs_tree_render = true;
1067 ysuccess(result);
1068 }
1069
1070 /*
1071 * Implementation of 'floating enable|disable|toggle'
1072 *
1073 */
1074 void cmd_floating(I3_CMD, const char *floating_mode) {
1075 owindow *current;
1076
1077 DLOG("floating_mode=%s\n", floating_mode);
1078
1079 HANDLE_EMPTY_MATCH;
1080
1081 TAILQ_FOREACH (current, &owindows, owindows) {
1082 DLOG("matching: %p / %s\n", current->con, current->con->name);
1083 if (strcmp(floating_mode, "toggle") == 0) {
1084 DLOG("should toggle mode\n");
1085 toggle_floating_mode(current->con, false);
1086 } else {
1087 DLOG("should switch mode to %s\n", floating_mode);
1088 if (strcmp(floating_mode, "enable") == 0) {
1089 floating_enable(current->con, false);
1090 } else {
1091 floating_disable(current->con);
1092 }
1093 }
1094 }
1095
1096 cmd_output->needs_tree_render = true;
1097 // XXX: default reply for now, make this a better reply
1098 ysuccess(true);
1099 }
1100
1101 /*
1102 * Implementation of 'move workspace to [output] <str>'.
1103 *
1104 */
1105 void cmd_move_workspace_to_output(I3_CMD, const char *name) {
1106 DLOG("should move workspace to output %s\n", name);
1107
1108 HANDLE_EMPTY_MATCH;
1109
1110 owindow *current;
1111 TAILQ_FOREACH (current, &owindows, owindows) {
1112 Con *ws = con_get_workspace(current->con);
1113 if (con_is_internal(ws)) {
1114 continue;
1115 }
1116
1117 Output *current_output = get_output_for_con(ws);
1118 Output *target_output = get_output_from_string(current_output, name);
1119 if (!target_output) {
1120 yerror("Could not get output from string \"%s\"", name);
1121 return;
1122 }
1123
1124 workspace_move_to_output(ws, target_output);
1125 }
1126
1127 cmd_output->needs_tree_render = true;
1128 ysuccess(true);
1129 }
1130
1131 /*
1132 * Implementation of 'split v|h|t|vertical|horizontal|toggle'.
1133 *
1134 */
1135 void cmd_split(I3_CMD, const char *direction) {
1136 HANDLE_EMPTY_MATCH;
1137
1138 owindow *current;
1139 LOG("splitting in direction %c\n", direction[0]);
1140 TAILQ_FOREACH (current, &owindows, owindows) {
1141 if (con_is_docked(current->con)) {
1142 ELOG("Cannot split a docked container, skipping.\n");
1143 continue;
1144 }
1145
1146 DLOG("matching: %p / %s\n", current->con, current->con->name);
1147 if (direction[0] == 't') {
1148 layout_t current_layout;
1149 if (current->con->type == CT_WORKSPACE) {
1150 current_layout = current->con->layout;
1151 } else {
1152 current_layout = current->con->parent->layout;
1153 }
1154 /* toggling split orientation */
1155 if (current_layout == L_SPLITH) {
1156 tree_split(current->con, VERT);
1157 } else {
1158 tree_split(current->con, HORIZ);
1159 }
1160 } else {
1161 tree_split(current->con, (direction[0] == 'v' ? VERT : HORIZ));
1162 }
1163 }
1164
1165 cmd_output->needs_tree_render = true;
1166 // XXX: default reply for now, make this a better reply
1167 ysuccess(true);
1168 }
1169
1170 /*
1171 * Implementation of 'kill [window|client]'.
1172 *
1173 */
1174 void cmd_kill(I3_CMD, const char *kill_mode_str) {
1175 if (kill_mode_str == NULL)
1176 kill_mode_str = "window";
1177
1178 DLOG("kill_mode=%s\n", kill_mode_str);
1179
1180 int kill_mode;
1181 if (strcmp(kill_mode_str, "window") == 0)
1182 kill_mode = KILL_WINDOW;
1183 else if (strcmp(kill_mode_str, "client") == 0)
1184 kill_mode = KILL_CLIENT;
1185 else {
1186 yerror("BUG: called with kill_mode=%s", kill_mode_str);
1187 return;
1188 }
1189
1190 HANDLE_EMPTY_MATCH;
1191
1192 owindow *current;
1193 TAILQ_FOREACH (current, &owindows, owindows) {
1194 con_close(current->con, kill_mode);
1195 }
1196
1197 cmd_output->needs_tree_render = true;
1198 // XXX: default reply for now, make this a better reply
1199 ysuccess(true);
1200 }
1201
1202 /*
1203 * Implementation of 'exec [--no-startup-id] <command>'.
1204 *
1205 */
1206 void cmd_exec(I3_CMD, const char *nosn, const char *command) {
1207 bool no_startup_id = (nosn != NULL);
1208
1209 HANDLE_EMPTY_MATCH;
1210
1211 int count = 0;
1212 owindow *current;
1213 TAILQ_FOREACH (current, &owindows, owindows) {
1214 count++;
1215 }
1216
1217 if (count > 1) {
1218 LOG("WARNING: Your criteria for the exec command match %d containers, "
1219 "so the command will execute this many times.\n",
1220 count);
1221 }
1222
1223 TAILQ_FOREACH (current, &owindows, owindows) {
1224 DLOG("should execute %s, no_startup_id = %d\n", command, no_startup_id);
1225 start_application(command, no_startup_id);
1226 }
1227
1228 ysuccess(true);
1229 }
1230
1231 #define CMD_FOCUS_WARN_CHILDREN \
1232 do { \
1233 int count = 0; \
1234 owindow *current; \
1235 TAILQ_FOREACH (current, &owindows, owindows) { \
1236 count++; \
1237 } \
1238 \
1239 if (count > 1) { \
1240 LOG("WARNING: Your criteria for the focus command matches %d containers, " \
1241 "while only exactly one container can be focused at a time.\n", \
1242 count); \
1243 } \
1244 } while (0)
1245
1246 /*
1247 * Implementation of 'focus left|right|up|down|next|prev'.
1248 *
1249 */
1250 void cmd_focus_direction(I3_CMD, const char *direction_str) {
1251 HANDLE_EMPTY_MATCH;
1252 CMD_FOCUS_WARN_CHILDREN;
1253
1254 direction_t direction;
1255 position_t position;
1256 bool auto_direction = true;
1257 if (strcmp(direction_str, "prev") == 0) {
1258 position = BEFORE;
1259 } else if (strcmp(direction_str, "next") == 0) {
1260 position = AFTER;
1261 } else {
1262 auto_direction = false;
1263 direction = parse_direction(direction_str);
1264 }
1265
1266 owindow *current;
1267 TAILQ_FOREACH (current, &owindows, owindows) {
1268 Con *ws = con_get_workspace(current->con);
1269 if (!ws || con_is_internal(ws)) {
1270 continue;
1271 }
1272 if (auto_direction) {
1273 orientation_t o = con_orientation(current->con->parent);
1274 direction = direction_from_orientation_position(o, position);
1275 }
1276 tree_next(current->con, direction);
1277 }
1278
1279 cmd_output->needs_tree_render = true;
1280 // XXX: default reply for now, make this a better reply
1281 ysuccess(true);
1282 }
1283
1284 /*
1285 * Implementation of 'focus next|prev sibling'
1286 *
1287 */
1288 void cmd_focus_sibling(I3_CMD, const char *direction_str) {
1289 HANDLE_EMPTY_MATCH;
1290 CMD_FOCUS_WARN_CHILDREN;
1291
1292 const position_t direction = (STARTS_WITH(direction_str, "prev")) ? BEFORE : AFTER;
1293 owindow *current;
1294 TAILQ_FOREACH (current, &owindows, owindows) {
1295 Con *ws = con_get_workspace(current->con);
1296 if (!ws || con_is_internal(ws)) {
1297 continue;
1298 }
1299 Con *next = get_tree_next_sibling(current->con, direction);
1300 if (next) {
1301 if (next->type == CT_WORKSPACE) {
1302 /* On the workspace level, we need to make sure that the
1303 * workspace change happens properly. However, workspace_show
1304 * descends focus so we also have to put focus on the workspace
1305 * itself to maintain consistency. See #3997. */
1306 workspace_show(next);
1307 con_focus(next);
1308 } else {
1309 con_activate(next);
1310 }
1311 }
1312 }
1313
1314 cmd_output->needs_tree_render = true;
1315 // XXX: default reply for now, make this a better reply
1316 ysuccess(true);
1317 }
1318
1319 /*
1320 * Implementation of 'focus tiling|floating|mode_toggle'.
1321 *
1322 */
1323 void cmd_focus_window_mode(I3_CMD, const char *window_mode) {
1324 DLOG("window_mode = %s\n", window_mode);
1325
1326 bool to_floating = false;
1327 if (strcmp(window_mode, "mode_toggle") == 0) {
1328 to_floating = !con_inside_floating(focused);
1329 } else if (strcmp(window_mode, "floating") == 0) {
1330 to_floating = true;
1331 } else if (strcmp(window_mode, "tiling") == 0) {
1332 to_floating = false;
1333 }
1334
1335 Con *ws = con_get_workspace(focused);
1336 Con *current;
1337 bool success = false;
1338 TAILQ_FOREACH (current, &(ws->focus_head), focused) {
1339 if ((to_floating && current->type != CT_FLOATING_CON) ||
1340 (!to_floating && current->type == CT_FLOATING_CON))
1341 continue;
1342
1343 con_activate_unblock(con_descend_focused(current));
1344 success = true;
1345 break;
1346 }
1347
1348 if (success) {
1349 cmd_output->needs_tree_render = true;
1350 ysuccess(true);
1351 } else {
1352 yerror("Failed to find a %s container in workspace.", to_floating ? "floating" : "tiling");
1353 }
1354 }
1355
1356 /*
1357 * Implementation of 'focus parent|child'.
1358 *
1359 */
1360 void cmd_focus_level(I3_CMD, const char *level) {
1361 DLOG("level = %s\n", level);
1362 bool success = false;
1363
1364 /* Focusing the parent can only be allowed if the newly
1365 * focused container won't escape the fullscreen container. */
1366 if (strcmp(level, "parent") == 0) {
1367 if (focused && focused->parent) {
1368 if (con_fullscreen_permits_focusing(focused->parent))
1369 success = level_up();
1370 else
1371 ELOG("'focus parent': Currently in fullscreen, not going up\n");
1372 }
1373 }
1374
1375 /* Focusing a child should always be allowed. */
1376 else
1377 success = level_down();
1378
1379 cmd_output->needs_tree_render = success;
1380 // XXX: default reply for now, make this a better reply
1381 ysuccess(success);
1382 }
1383
1384 /*
1385 * Implementation of 'focus'.
1386 *
1387 */
1388 void cmd_focus(I3_CMD) {
1389 DLOG("current_match = %p\n", current_match);
1390
1391 if (match_is_empty(current_match)) {
1392 ELOG("You have to specify which window/container should be focused.\n");
1393 ELOG("Example: [class=\"urxvt\" title=\"irssi\"] focus\n");
1394
1395 yerror("You have to specify which window/container should be focused");
1396 return;
1397 } else if (TAILQ_EMPTY(&owindows)) {
1398 yerror("No window matches given criteria");
1399 return;
1400 }
1401
1402 CMD_FOCUS_WARN_CHILDREN;
1403
1404 Con *__i3_scratch = workspace_get("__i3_scratch", NULL);
1405 owindow *current;
1406 TAILQ_FOREACH (current, &owindows, owindows) {
1407 Con *ws = con_get_workspace(current->con);
1408 /* If no workspace could be found, this was a dock window.
1409 * Just skip it, you cannot focus dock windows. */
1410 if (!ws)
1411 continue;
1412
1413 /* In case this is a scratchpad window, call scratchpad_show(). */
1414 if (ws == __i3_scratch) {
1415 scratchpad_show(current->con);
1416 /* While for the normal focus case we can change focus multiple
1417 * times and only a single window ends up focused, we could show
1418 * multiple scratchpad windows. So, rather break here. */
1419 break;
1420 }
1421
1422 LOG("focusing %p / %s\n", current->con, current->con->name);
1423 con_activate_unblock(current->con);
1424 }
1425
1426 cmd_output->needs_tree_render = true;
1427 ysuccess(true);
1428 }
1429
1430 /*
1431 * Implementation of 'fullscreen enable|toggle [global]' and
1432 * 'fullscreen disable'
1433 *
1434 */
1435 void cmd_fullscreen(I3_CMD, const char *action, const char *fullscreen_mode) {
1436 fullscreen_mode_t mode = strcmp(fullscreen_mode, "global") == 0 ? CF_GLOBAL : CF_OUTPUT;
1437 DLOG("%s fullscreen, mode = %s\n", action, fullscreen_mode);
1438 owindow *current;
1439
1440 HANDLE_EMPTY_MATCH;
1441
1442 TAILQ_FOREACH (current, &owindows, owindows) {
1443 DLOG("matching: %p / %s\n", current->con, current->con->name);
1444 if (strcmp(action, "toggle") == 0) {
1445 con_toggle_fullscreen(current->con, mode);
1446 } else if (strcmp(action, "enable") == 0) {
1447 con_enable_fullscreen(current->con, mode);
1448 } else if (strcmp(action, "disable") == 0) {
1449 con_disable_fullscreen(current->con);
1450 }
1451 }
1452
1453 cmd_output->needs_tree_render = true;
1454 // XXX: default reply for now, make this a better reply
1455 ysuccess(true);
1456 }
1457
1458 /*
1459 * Implementation of 'sticky enable|disable|toggle'.
1460 *
1461 */
1462 void cmd_sticky(I3_CMD, const char *action) {
1463 DLOG("%s sticky on window\n", action);
1464 HANDLE_EMPTY_MATCH;
1465
1466 owindow *current;
1467 TAILQ_FOREACH (current, &owindows, owindows) {
1468 if (current->con->window == NULL) {
1469 ELOG("only containers holding a window can be made sticky, skipping con = %p\n", current->con);
1470 continue;
1471 }
1472 DLOG("setting sticky for container = %p / %s\n", current->con, current->con->name);
1473
1474 bool sticky = false;
1475 if (strcmp(action, "enable") == 0)
1476 sticky = true;
1477 else if (strcmp(action, "disable") == 0)
1478 sticky = false;
1479 else if (strcmp(action, "toggle") == 0)
1480 sticky = !current->con->sticky;
1481
1482 current->con->sticky = sticky;
1483 ewmh_update_sticky(current->con->window->id, sticky);
1484 }
1485
1486 /* A window we made sticky might not be on a visible workspace right now, so we need to make
1487 * sure it gets pushed to the front now. */
1488 output_push_sticky_windows(focused);
1489
1490 ewmh_update_wm_desktop();
1491
1492 cmd_output->needs_tree_render = true;
1493 ysuccess(true);
1494 }
1495
1496 /*
1497 * Implementation of 'move <direction> [<pixels> [px]]'.
1498 *
1499 */
1500 void cmd_move_direction(I3_CMD, const char *direction_str, long move_px) {
1501 owindow *current;
1502 HANDLE_EMPTY_MATCH;
1503
1504 Con *initially_focused = focused;
1505 direction_t direction = parse_direction(direction_str);
1506
1507 TAILQ_FOREACH (current, &owindows, owindows) {
1508 DLOG("moving in direction %s, px %ld\n", direction_str, move_px);
1509 if (con_is_floating(current->con)) {
1510 DLOG("floating move with %ld pixels\n", move_px);
1511 Rect newrect = current->con->parent->rect;
1512
1513 switch (direction) {
1514 case D_LEFT:
1515 newrect.x -= move_px;
1516 break;
1517 case D_RIGHT:
1518 newrect.x += move_px;
1519 break;
1520 case D_UP:
1521 newrect.y -= move_px;
1522 break;
1523 case D_DOWN:
1524 newrect.y += move_px;
1525 break;
1526 }
1527
1528 cmd_output->needs_tree_render = floating_reposition(current->con->parent, newrect);
1529 } else {
1530 tree_move(current->con, direction);
1531 cmd_output->needs_tree_render = true;
1532 }
1533 }
1534
1535 /* The move command should not disturb focus. con_exists is called because
1536 * tree_move calls tree_flatten. */
1537 if (focused != initially_focused && con_exists(initially_focused)) {
1538 con_activate(initially_focused);
1539 }
1540
1541 // XXX: default reply for now, make this a better reply
1542 ysuccess(true);
1543 }
1544
1545 /*
1546 * Implementation of 'layout default|stacked|stacking|tabbed|splitv|splith'.
1547 *
1548 */
1549 void cmd_layout(I3_CMD, const char *layout_str) {
1550 HANDLE_EMPTY_MATCH;
1551
1552 layout_t layout;
1553 if (!layout_from_name(layout_str, &layout)) {
1554 yerror("Unknown layout \"%s\", this is a mismatch between code and parser spec.", layout_str);
1555 return;
1556 }
1557
1558 DLOG("changing layout to %s (%d)\n", layout_str, layout);
1559
1560 owindow *current;
1561 TAILQ_FOREACH (current, &owindows, owindows) {
1562 if (con_is_docked(current->con)) {
1563 ELOG("cannot change layout of a docked container, skipping it.\n");
1564 continue;
1565 }
1566
1567 DLOG("matching: %p / %s\n", current->con, current->con->name);
1568 con_set_layout(current->con, layout);
1569 }
1570
1571 cmd_output->needs_tree_render = true;
1572 // XXX: default reply for now, make this a better reply
1573 ysuccess(true);
1574 }
1575
1576 /*
1577 * Implementation of 'layout toggle [all|split]'.
1578 *
1579 */
1580 void cmd_layout_toggle(I3_CMD, const char *toggle_mode) {
1581 owindow *current;
1582
1583 if (toggle_mode == NULL)
1584 toggle_mode = "default";
1585
1586 DLOG("toggling layout (mode = %s)\n", toggle_mode);
1587
1588 /* check if the match is empty, not if the result is empty */
1589 if (match_is_empty(current_match))
1590 con_toggle_layout(focused, toggle_mode);
1591 else {
1592 TAILQ_FOREACH (current, &owindows, owindows) {
1593 DLOG("matching: %p / %s\n", current->con, current->con->name);
1594 con_toggle_layout(current->con, toggle_mode);
1595 }
1596 }
1597
1598 cmd_output->needs_tree_render = true;
1599 // XXX: default reply for now, make this a better reply
1600 ysuccess(true);
1601 }
1602
1603 /*
1604 * Implementation of 'exit'.
1605 *
1606 */
1607 void cmd_exit(I3_CMD) {
1608 LOG("Exiting due to user command.\n");
1609 exit(EXIT_SUCCESS);
1610
1611 /* unreached */
1612 }
1613
1614 /*
1615 * Implementation of 'reload'.
1616 *
1617 */
1618 void cmd_reload(I3_CMD) {
1619 LOG("reloading\n");
1620 kill_nagbar(&config_error_nagbar_pid, false);
1621 kill_nagbar(&command_error_nagbar_pid, false);
1622 load_configuration(NULL, C_RELOAD);
1623 x_set_i3_atoms();
1624 /* Send an IPC event just in case the ws names have changed */
1625 ipc_send_workspace_event("reload", NULL, NULL);
1626 /* Send an update event for the barconfig just in case it has changed */
1627 update_barconfig();
1628
1629 // XXX: default reply for now, make this a better reply
1630 ysuccess(true);
1631 }
1632
1633 /*
1634 * Implementation of 'restart'.
1635 *
1636 */
1637 void cmd_restart(I3_CMD) {
1638 LOG("restarting i3\n");
1639 int exempt_fd = -1;
1640 if (cmd_output->client != NULL) {
1641 exempt_fd = cmd_output->client->fd;
1642 LOG("Carrying file descriptor %d across restart\n", exempt_fd);
1643 int flags;
1644 if ((flags = fcntl(exempt_fd, F_GETFD)) < 0 ||
1645 fcntl(exempt_fd, F_SETFD, flags & ~FD_CLOEXEC) < 0) {
1646 ELOG("Could not disable FD_CLOEXEC on fd %d\n", exempt_fd);
1647 }
1648 char *fdstr = NULL;
1649 sasprintf(&fdstr, "%d", exempt_fd);
1650 setenv("_I3_RESTART_FD", fdstr, 1);
1651 }
1652 ipc_shutdown(SHUTDOWN_REASON_RESTART, exempt_fd);
1653 unlink(config.ipc_socket_path);
1654 /* We need to call this manually since atexit handlers don’t get called
1655 * when exec()ing */
1656 purge_zerobyte_logfile();
1657 i3_restart(false);
1658 /* unreached */
1659 assert(false);
1660 }
1661
1662 /*
1663 * Implementation of 'open'.
1664 *
1665 */
1666 void cmd_open(I3_CMD) {
1667 LOG("opening new container\n");
1668 Con *con = tree_open_con(NULL, NULL);
1669 con->layout = L_SPLITH;
1670 con_activate(con);
1671
1672 y(map_open);
1673 ystr("success");
1674 y(bool, true);
1675 ystr("id");
1676 y(integer, (uintptr_t)con);
1677 y(map_close);
1678
1679 cmd_output->needs_tree_render = true;
1680 }
1681
1682 /*
1683 * Implementation of 'focus output <output>'.
1684 *
1685 */
1686 void cmd_focus_output(I3_CMD, const char *name) {
1687 HANDLE_EMPTY_MATCH;
1688
1689 if (TAILQ_EMPTY(&owindows)) {
1690 ysuccess(true);
1691 return;
1692 }
1693
1694 Output *current_output = get_output_for_con(TAILQ_FIRST(&owindows)->con);
1695 Output *output = get_output_from_string(current_output, name);
1696
1697 if (!output) {
1698 yerror("Output %s not found.", name);
1699 return;
1700 }
1701
1702 /* get visible workspace on output */
1703 Con *ws = NULL;
1704 GREP_FIRST(ws, output_get_content(output->con), workspace_is_visible(child));
1705 if (!ws) {
1706 yerror("BUG: No workspace found on output.");
1707 return;
1708 }
1709
1710 workspace_show(ws);
1711
1712 cmd_output->needs_tree_render = true;
1713 ysuccess(true);
1714 }
1715
1716 /*
1717 * Implementation of 'move [window|container] [to] [absolute] position <px> [px] <px> [px]
1718 *
1719 */
1720 void cmd_move_window_to_position(I3_CMD, long x, long y) {
1721 bool has_error = false;
1722
1723 owindow *current;
1724 HANDLE_EMPTY_MATCH;
1725
1726 TAILQ_FOREACH (current, &owindows, owindows) {
1727 if (!con_is_floating(current->con)) {
1728 ELOG("Cannot change position. The window/container is not floating\n");
1729
1730 if (!has_error) {
1731 yerror("Cannot change position of a window/container because it is not floating.");
1732 has_error = true;
1733 }
1734
1735 continue;
1736 }
1737
1738 Rect newrect = current->con->parent->rect;
1739
1740 DLOG("moving to position %ld %ld\n", x, y);
1741 newrect.x = x;
1742 newrect.y = y;
1743
1744 if (!floating_reposition(current->con->parent, newrect)) {
1745 yerror("Cannot move window/container out of bounds.");
1746 has_error = true;
1747 }
1748 }
1749
1750 if (!has_error)
1751 ysuccess(true);
1752 }
1753
1754 /*
1755 * Implementation of 'move [window|container] [to] [absolute] position center
1756 *
1757 */
1758 void cmd_move_window_to_center(I3_CMD, const char *method) {
1759 bool has_error = false;
1760 HANDLE_EMPTY_MATCH;
1761
1762 owindow *current;
1763 TAILQ_FOREACH (current, &owindows, owindows) {
1764 Con *floating_con = con_inside_floating(current->con);
1765 if (floating_con == NULL) {
1766 ELOG("con %p / %s is not floating, cannot move it to the center.\n",
1767 current->con, current->con->name);
1768
1769 if (!has_error) {
1770 yerror("Cannot change position of a window/container because it is not floating.");
1771 has_error = true;
1772 }
1773
1774 continue;
1775 }
1776
1777 if (strcmp(method, "absolute") == 0) {
1778 DLOG("moving to absolute center\n");
1779 floating_center(floating_con, croot->rect);
1780
1781 floating_maybe_reassign_ws(floating_con);
1782 cmd_output->needs_tree_render = true;
1783 }
1784
1785 if (strcmp(method, "position") == 0) {
1786 DLOG("moving to center\n");
1787 floating_center(floating_con, con_get_workspace(floating_con)->rect);
1788
1789 cmd_output->needs_tree_render = true;
1790 }
1791 }
1792
1793 // XXX: default reply for now, make this a better reply
1794 if (!has_error)
1795 ysuccess(true);
1796 }
1797
1798 /*
1799 * Implementation of 'move [window|container] [to] position mouse'
1800 *
1801 */
1802 void cmd_move_window_to_mouse(I3_CMD) {
1803 HANDLE_EMPTY_MATCH;
1804
1805 owindow *current;
1806 TAILQ_FOREACH (current, &owindows, owindows) {
1807 Con *floating_con = con_inside_floating(current->con);
1808 if (floating_con == NULL) {
1809 DLOG("con %p / %s is not floating, cannot move it to the mouse position.\n",
1810 current->con, current->con->name);
1811 continue;
1812 }
1813
1814 DLOG("moving floating container %p / %s to cursor position\n", floating_con, floating_con->name);
1815 floating_move_to_pointer(floating_con);
1816 }
1817
1818 cmd_output->needs_tree_render = true;
1819 ysuccess(true);
1820 }
1821
1822 /*
1823 * Implementation of 'move scratchpad'.
1824 *
1825 */
1826 void cmd_move_scratchpad(I3_CMD) {
1827 DLOG("should move window to scratchpad\n");
1828 owindow *current;
1829
1830 HANDLE_EMPTY_MATCH;
1831
1832 TAILQ_FOREACH (current, &owindows, owindows) {
1833 DLOG("matching: %p / %s\n", current->con, current->con->name);
1834 scratchpad_move(current->con);
1835 }
1836
1837 cmd_output->needs_tree_render = true;
1838 // XXX: default reply for now, make this a better reply
1839 ysuccess(true);
1840 }
1841
1842 /*
1843 * Implementation of 'scratchpad show'.
1844 *
1845 */
1846 void cmd_scratchpad_show(I3_CMD) {
1847 DLOG("should show scratchpad window\n");
1848 owindow *current;
1849 bool result = false;
1850
1851 if (match_is_empty(current_match)) {
1852 result = scratchpad_show(NULL);
1853 } else {
1854 TAILQ_FOREACH (current, &owindows, owindows) {
1855 DLOG("matching: %p / %s\n", current->con, current->con->name);
1856 result |= scratchpad_show(current->con);
1857 }
1858 }
1859
1860 cmd_output->needs_tree_render = true;
1861
1862 ysuccess(result);
1863 }
1864
1865 /*
1866 * Implementation of 'swap [container] [with] id|con_id|mark <arg>'.
1867 *
1868 */
1869 void cmd_swap(I3_CMD, const char *mode, const char *arg) {
1870 HANDLE_EMPTY_MATCH;
1871
1872 owindow *match = TAILQ_FIRST(&owindows);
1873 if (match == NULL) {
1874 yerror("No match found for swapping.");
1875 return;
1876 }
1877 if (match->con == NULL) {
1878 yerror("Match %p has no container.", match);
1879 return;
1880 }
1881
1882 Con *con;
1883 if (strcmp(mode, "id") == 0) {
1884 long target;
1885 if (!parse_long(arg, &target, 0)) {
1886 yerror("Failed to parse %s into a window id.", arg);
1887 return;
1888 }
1889
1890 con = con_by_window_id(target);
1891 } else if (strcmp(mode, "con_id") == 0) {
1892 long target;
1893 if (!parse_long(arg, &target, 0)) {
1894 yerror("Failed to parse %s into a container id.", arg);
1895 return;
1896 }
1897
1898 con = con_by_con_id(target);
1899 } else if (strcmp(mode, "mark") == 0) {
1900 con = con_by_mark(arg);
1901 } else {
1902 yerror("Unhandled swap mode \"%s\". This is a bug.", mode);
1903 return;
1904 }
1905
1906 if (con == NULL) {
1907 yerror("Could not find container for %s = %s", mode, arg);
1908 return;
1909 }
1910
1911 if (match != TAILQ_LAST(&owindows, owindows_head)) {
1912 LOG("More than one container matched the swap command, only using the first one.");
1913 }
1914
1915 DLOG("Swapping %p with %p.\n", match->con, con);
1916 bool result = con_swap(match->con, con);
1917
1918 cmd_output->needs_tree_render = true;
1919 // XXX: default reply for now, make this a better reply
1920 ysuccess(result);
1921 }
1922
1923 /*
1924 * Implementation of 'title_format <format>'
1925 *
1926 */
1927 void cmd_title_format(I3_CMD, const char *format) {
1928 DLOG("setting title_format to \"%s\"\n", format);
1929 HANDLE_EMPTY_MATCH;
1930
1931 owindow *current;
1932 TAILQ_FOREACH (current, &owindows, owindows) {
1933 DLOG("setting title_format for %p / %s\n", current->con, current->con->name);
1934 FREE(current->con->title_format);
1935
1936 /* If we only display the title without anything else, we can skip the parsing step,
1937 * so we remove the title format altogether. */
1938 if (strcasecmp(format, "%title") != 0) {
1939 current->con->title_format = sstrdup(format);
1940
1941 if (current->con->window != NULL) {
1942 i3String *formatted_title = con_parse_title_format(current->con);
1943 ewmh_update_visible_name(current->con->window->id, i3string_as_utf8(formatted_title));
1944 I3STRING_FREE(formatted_title);
1945 }
1946 } else {
1947 if (current->con->window != NULL) {
1948 /* We can remove _NET_WM_VISIBLE_NAME since we don't display a custom title. */
1949 ewmh_update_visible_name(current->con->window->id, NULL);
1950 }
1951 }
1952
1953 if (current->con->window != NULL) {
1954 /* Make sure the window title is redrawn immediately. */
1955 current->con->window->name_x_changed = true;
1956 } else {
1957 /* For windowless containers we also need to force the redrawing. */
1958 FREE(current->con->deco_render_params);
1959 }
1960 }
1961
1962 cmd_output->needs_tree_render = true;
1963 ysuccess(true);
1964 }
1965
1966 /*
1967 * Implementation of 'rename workspace [<name>] to <name>'
1968 *
1969 */
1970 void cmd_rename_workspace(I3_CMD, const char *old_name, const char *new_name) {
1971 if (strncasecmp(new_name, "__", strlen("__")) == 0) {
1972 yerror("Cannot rename workspace to \"%s\": names starting with __ are i3-internal.", new_name);
1973 return;
1974 }
1975 if (old_name) {
1976 LOG("Renaming workspace \"%s\" to \"%s\"\n", old_name, new_name);
1977 } else {
1978 LOG("Renaming current workspace to \"%s\"\n", new_name);
1979 }
1980
1981 Con *workspace;
1982 if (old_name) {
1983 workspace = get_existing_workspace_by_name(old_name);
1984 } else {
1985 workspace = con_get_workspace(focused);
1986 old_name = workspace->name;
1987 }
1988
1989 if (!workspace) {
1990 yerror("Old workspace \"%s\" not found", old_name);
1991 return;
1992 }
1993
1994 Con *check_dest = get_existing_workspace_by_name(new_name);
1995
1996 /* If check_dest == workspace, the user might be changing the case of the
1997 * workspace, or it might just be a no-op. */
1998 if (check_dest != NULL && check_dest != workspace) {
1999 yerror("New workspace \"%s\" already exists", new_name);
2000 return;
2001 }
2002
2003 /* Change the name and try to parse it as a number. */
2004 /* old_name might refer to workspace->name, so copy it before free()ing */
2005 char *old_name_copy = sstrdup(old_name);
2006 FREE(workspace->name);
2007 workspace->name = sstrdup(new_name);
2008
2009 workspace->num = ws_name_to_number(new_name);
2010 LOG("num = %d\n", workspace->num);
2011
2012 /* By re-attaching, the sort order will be correct afterwards. */
2013 Con *previously_focused = focused;
2014 Con *previously_focused_content = focused->type == CT_WORKSPACE ? focused->parent : NULL;
2015 Con *parent = workspace->parent;
2016 con_detach(workspace);
2017 con_attach(workspace, parent, false);
2018 ipc_send_workspace_event("rename", workspace, NULL);
2019
2020 /* Move the workspace to the correct output if it has an assignment */
2021 struct Workspace_Assignment *assignment = NULL;
2022 TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) {
2023 if (assignment->output == NULL)
2024 continue;
2025 if (strcmp(assignment->name, workspace->name) != 0 && (!name_is_digits(assignment->name) || ws_name_to_number(assignment->name) != workspace->num)) {
2026 continue;
2027 }
2028
2029 Output *target_output = get_output_by_name(assignment->output, true);
2030 if (!target_output) {
2031 LOG("Could not get output named \"%s\"\n", assignment->output);
2032 continue;
2033 }
2034 if (!output_triggers_assignment(target_output, assignment)) {
2035 continue;
2036 }
2037 workspace_move_to_output(workspace, target_output);
2038
2039 break;
2040 }
2041
2042 bool can_restore_focus = previously_focused != NULL;
2043 /* NB: If previously_focused is a workspace we can't work directly with it
2044 * since it might have been cleaned up by workspace_show() already,
2045 * depending on the focus order/number of other workspaces on the output.
2046 * Instead, we loop through the available workspaces and only focus
2047 * previously_focused if we still find it. */
2048 if (previously_focused_content) {
2049 Con *workspace = NULL;
2050 GREP_FIRST(workspace, previously_focused_content, child == previously_focused);
2051 can_restore_focus &= (workspace != NULL);
2052 }
2053
2054 if (can_restore_focus) {
2055 /* Restore the previous focus since con_attach messes with the focus. */
2056 workspace_show(con_get_workspace(previously_focused));
2057 con_focus(previously_focused);
2058 }
2059
2060 /* Let back-and-forth work after renaming the previous workspace.
2061 * See #3694. */
2062 if (previous_workspace_name && !strcmp(previous_workspace_name, old_name_copy)) {
2063 FREE(previous_workspace_name);
2064 previous_workspace_name = sstrdup(new_name);
2065 }
2066
2067 cmd_output->needs_tree_render = true;
2068 ysuccess(true);
2069
2070 ewmh_update_desktop_properties();
2071
2072 startup_sequence_rename_workspace(old_name_copy, new_name);
2073 free(old_name_copy);
2074 }
2075
2076 /*
2077 * Implementation of 'bar mode dock|hide|invisible|toggle [<bar_id>]'
2078 *
2079 */
2080 static bool cmd_bar_mode(const char *bar_mode, const char *bar_id) {
2081 int mode = M_DOCK;
2082 bool toggle = false;
2083 if (strcmp(bar_mode, "dock") == 0)
2084 mode = M_DOCK;
2085 else if (strcmp(bar_mode, "hide") == 0)
2086 mode = M_HIDE;
2087 else if (strcmp(bar_mode, "invisible") == 0)
2088 mode = M_INVISIBLE;
2089 else if (strcmp(bar_mode, "toggle") == 0)
2090 toggle = true;
2091 else {
2092 ELOG("Unknown bar mode \"%s\", this is a mismatch between code and parser spec.\n", bar_mode);
2093 return false;
2094 }
2095
2096 bool changed_sth = false;
2097 Barconfig *current = NULL;
2098 TAILQ_FOREACH (current, &barconfigs, configs) {
2099 if (bar_id && strcmp(current->id, bar_id) != 0)
2100 continue;
2101
2102 if (toggle)
2103 mode = (current->mode + 1) % 2;
2104
2105 DLOG("Changing bar mode of bar_id '%s' to '%s (%d)'\n", current->id, bar_mode, mode);
2106 current->mode = mode;
2107 changed_sth = true;
2108
2109 if (bar_id)
2110 break;
2111 }
2112
2113 if (bar_id && !changed_sth) {
2114 DLOG("Changing bar mode of bar_id %s failed, bar_id not found.\n", bar_id);
2115 return false;
2116 }
2117
2118 return true;
2119 }
2120
2121 /*
2122 * Implementation of 'bar hidden_state hide|show|toggle [<bar_id>]'
2123 *
2124 */
2125 static bool cmd_bar_hidden_state(const char *bar_hidden_state, const char *bar_id) {
2126 int hidden_state = S_SHOW;
2127 bool toggle = false;
2128 if (strcmp(bar_hidden_state, "hide") == 0)
2129 hidden_state = S_HIDE;
2130 else if (strcmp(bar_hidden_state, "show") == 0)
2131 hidden_state = S_SHOW;
2132 else if (strcmp(bar_hidden_state, "toggle") == 0)
2133 toggle = true;
2134 else {
2135 ELOG("Unknown bar state \"%s\", this is a mismatch between code and parser spec.\n", bar_hidden_state);
2136 return false;
2137 }
2138
2139 bool changed_sth = false;
2140 Barconfig *current = NULL;
2141 TAILQ_FOREACH (current, &barconfigs, configs) {
2142 if (bar_id && strcmp(current->id, bar_id) != 0)
2143 continue;
2144
2145 if (toggle)
2146 hidden_state = (current->hidden_state + 1) % 2;
2147
2148 DLOG("Changing bar hidden_state of bar_id '%s' to '%s (%d)'\n", current->id, bar_hidden_state, hidden_state);
2149 current->hidden_state = hidden_state;
2150 changed_sth = true;
2151
2152 if (bar_id)
2153 break;
2154 }
2155
2156 if (bar_id && !changed_sth) {
2157 DLOG("Changing bar hidden_state of bar_id %s failed, bar_id not found.\n", bar_id);
2158 return false;
2159 }
2160
2161 return true;
2162 }
2163
2164 /*
2165 * Implementation of 'bar (hidden_state hide|show|toggle)|(mode dock|hide|invisible|toggle) [<bar_id>]'
2166 *
2167 */
2168 void cmd_bar(I3_CMD, const char *bar_type, const char *bar_value, const char *bar_id) {
2169 bool ret;
2170 if (strcmp(bar_type, "mode") == 0)
2171 ret = cmd_bar_mode(bar_value, bar_id);
2172 else if (strcmp(bar_type, "hidden_state") == 0)
2173 ret = cmd_bar_hidden_state(bar_value, bar_id);
2174 else {
2175 ELOG("Unknown bar option type \"%s\", this is a mismatch between code and parser spec.\n", bar_type);
2176 ret = false;
2177 }
2178
2179 ysuccess(ret);
2180 if (!ret)
2181 return;
2182
2183 update_barconfig();
2184 }
2185
2186 /*
2187 * Implementation of 'shmlog <size>|toggle|on|off'
2188 *
2189 */
2190 void cmd_shmlog(I3_CMD, const char *argument) {
2191 if (!strcmp(argument, "toggle"))
2192 /* Toggle shm log, if size is not 0. If it is 0, set it to default. */
2193 shmlog_size = shmlog_size ? -shmlog_size : default_shmlog_size;
2194 else if (!strcmp(argument, "on"))
2195 shmlog_size = default_shmlog_size;
2196 else if (!strcmp(argument, "off"))
2197 shmlog_size = 0;
2198 else {
2199 long new_size = 0;
2200 if (!parse_long(argument, &new_size, 0)) {
2201 yerror("Failed to parse %s into a shmlog size.", argument);
2202 return;
2203 }
2204 /* If shm logging now, restart logging with the new size. */
2205 if (shmlog_size > 0) {
2206 shmlog_size = 0;
2207 LOG("Restarting shm logging...\n");
2208 init_logging();
2209 }
2210 shmlog_size = (int)new_size;
2211 }
2212 LOG("%s shm logging\n", shmlog_size > 0 ? "Enabling" : "Disabling");
2213 init_logging();
2214 update_shmlog_atom();
2215 ysuccess(true);
2216 }
2217
2218 /*
2219 * Implementation of 'debuglog toggle|on|off'
2220 *
2221 */
2222 void cmd_debuglog(I3_CMD, const char *argument) {
2223 bool logging = get_debug_logging();
2224 if (!strcmp(argument, "toggle")) {
2225 LOG("%s debug logging\n", logging ? "Disabling" : "Enabling");
2226 set_debug_logging(!logging);
2227 } else if (!strcmp(argument, "on") && !logging) {
2228 LOG("Enabling debug logging\n");
2229 set_debug_logging(true);
2230 } else if (!strcmp(argument, "off") && logging) {
2231 LOG("Disabling debug logging\n");
2232 set_debug_logging(false);
2233 }
2234 // XXX: default reply for now, make this a better reply
2235 ysuccess(true);
2236 }
2237
2238 /**
2239 * Implementation of 'gaps inner|outer|top|right|bottom|left|horizontal|vertical current|all set|plus|minus|toggle <px>'
2240 *
2241 */
2242 void cmd_gaps(I3_CMD, const char *type, const char *scope, const char *mode, const char *value) {
2243 int pixels = logical_px(atoi(value));
2244 Con *workspace = con_get_workspace(focused);
2245
2246 #define CMD_GAPS(type) \
2247 do { \
2248 int current_value = config.gaps.type; \
2249 if (strcmp(scope, "current") == 0) \
2250 current_value += workspace->gaps.type; \
2251 \
2252 bool reset = false; \
2253 if (!strcmp(mode, "plus")) \
2254 current_value += pixels; \
2255 else if (!strcmp(mode, "minus")) \
2256 current_value -= pixels; \
2257 else if (!strcmp(mode, "set")) { \
2258 current_value = pixels; \
2259 reset = true; \
2260 } else if (!strcmp(mode, "toggle")) { \
2261 current_value = !current_value * pixels; \
2262 reset = true; \
2263 } else { \
2264 ELOG("Invalid mode %s when changing gaps", mode); \
2265 ysuccess(false); \
2266 return; \
2267 } \
2268 \
2269 if (current_value < 0) \
2270 current_value = 0; \
2271 \
2272 if (!strcmp(scope, "all")) { \
2273 Con *output, *cur_ws = NULL; \
2274 TAILQ_FOREACH (output, &(croot->nodes_head), nodes) { \
2275 Con *content = output_get_content(output); \
2276 TAILQ_FOREACH (cur_ws, &(content->nodes_head), nodes) { \
2277 if (reset) \
2278 cur_ws->gaps.type = 0; \
2279 else if (current_value + cur_ws->gaps.type < 0) \
2280 cur_ws->gaps.type = -current_value; \
2281 } \
2282 } \
2283 \
2284 config.gaps.type = current_value; \
2285 } else { \
2286 workspace->gaps.type = current_value - config.gaps.type; \
2287 } \
2288 } while (0)
2289
2290 if (!strcmp(type, "inner")) {
2291 CMD_GAPS(inner);
2292 } else if (!strcmp(type, "outer")) {
2293 CMD_GAPS(top);
2294 CMD_GAPS(bottom);
2295 CMD_GAPS(right);
2296 CMD_GAPS(left);
2297 } else if (!strcmp(type, "vertical")) {
2298 CMD_GAPS(top);
2299 CMD_GAPS(bottom);
2300 } else if (!strcmp(type, "horizontal")) {
2301 CMD_GAPS(right);
2302 CMD_GAPS(left);
2303 } else if (!strcmp(type, "top")) {
2304 CMD_GAPS(top);
2305 } else if (!strcmp(type, "bottom")) {
2306 CMD_GAPS(bottom);
2307 } else if (!strcmp(type, "right")) {
2308 CMD_GAPS(right);
2309 } else if (!strcmp(type, "left")) {
2310 CMD_GAPS(left);
2311 } else {
2312 ELOG("Invalid type %s when changing gaps", type);
2313 ysuccess(false);
2314 return;
2315 }
2316
2317 cmd_output->needs_tree_render = true;
2318 // XXX: default reply for now, make this a better reply
2319 ysuccess(true);
2320 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * commands_parser.c: hand-written parser to parse commands (commands are what
7 * you bind on keys and what you can send to i3 using the IPC interface, like
8 * 'move left' or 'workspace 4').
9 *
10 * We use a hand-written parser instead of lex/yacc because our commands are
11 * easy for humans, not for computers. Thus, it’s quite hard to specify a
12 * context-free grammar for the commands. A PEG grammar would be easier, but
13 * there’s downsides to every PEG parser generator I have come across so far.
14 *
15 * This parser is basically a state machine which looks for literals or strings
16 * and can push either on a stack. After identifying a literal or string, it
17 * will either transition to the current state, to a different state, or call a
18 * function (like cmd_move()).
19 *
20 * Special care has been taken that error messages are useful and the code is
21 * well testable (when compiled with -DTEST_PARSER it will output to stdout
22 * instead of actually calling any function).
23 *
24 */
25 #include "all.h"
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <stdbool.h>
32 #include <stdint.h>
33
34 // Macros to make the YAJL API a bit easier to use.
35 #define y(x, ...) (command_output.json_gen != NULL ? yajl_gen_##x(command_output.json_gen, ##__VA_ARGS__) : 0)
36 #define ystr(str) (command_output.json_gen != NULL ? yajl_gen_string(command_output.json_gen, (unsigned char *)str, strlen(str)) : 0)
37
38 /*******************************************************************************
39 * The data structures used for parsing. Essentially the current state and a
40 * list of tokens for that state.
41 *
42 * The GENERATED_* files are generated by generate-commands-parser.pl with the
43 * input parser-specs/commands.spec.
44 ******************************************************************************/
45
46 #include "GENERATED_command_enums.h"
47
48 typedef struct token {
49 char *name;
50 char *identifier;
51 /* This might be __CALL */
52 cmdp_state next_state;
53 union {
54 uint16_t call_identifier;
55 } extra;
56 } cmdp_token;
57
58 typedef struct tokenptr {
59 cmdp_token *array;
60 int n;
61 } cmdp_token_ptr;
62
63 #include "GENERATED_command_tokens.h"
64
65 /*******************************************************************************
66 * The (small) stack where identified literals are stored during the parsing
67 * of a single command (like $workspace).
68 ******************************************************************************/
69
70 struct stack_entry {
71 /* Just a pointer, not dynamically allocated. */
72 const char *identifier;
73 enum {
74 STACK_STR = 0,
75 STACK_LONG = 1,
76 } type;
77 union {
78 char *str;
79 long num;
80 } val;
81 };
82
83 /* 10 entries should be enough for everybody. */
84 static struct stack_entry stack[10];
85
86 /*
87 * Pushes a string (identified by 'identifier') on the stack. We simply use a
88 * single array, since the number of entries we have to store is very small.
89 *
90 */
91 static void push_string(const char *identifier, char *str) {
92 for (int c = 0; c < 10; c++) {
93 if (stack[c].identifier != NULL)
94 continue;
95 /* Found a free slot, let’s store it here. */
96 stack[c].identifier = identifier;
97 stack[c].val.str = str;
98 stack[c].type = STACK_STR;
99 return;
100 }
101
102 /* When we arrive here, the stack is full. This should not happen and
103 * means there’s either a bug in this parser or the specification
104 * contains a command with more than 10 identified tokens. */
105 fprintf(stderr, "BUG: commands_parser stack full. This means either a bug "
106 "in the code, or a new command which contains more than "
107 "10 identified tokens.\n");
108 exit(EXIT_FAILURE);
109 }
110
111 // TODO move to a common util
112 static void push_long(const char *identifier, long num) {
113 for (int c = 0; c < 10; c++) {
114 if (stack[c].identifier != NULL) {
115 continue;
116 }
117
118 stack[c].identifier = identifier;
119 stack[c].val.num = num;
120 stack[c].type = STACK_LONG;
121 return;
122 }
123
124 /* When we arrive here, the stack is full. This should not happen and
125 * means there’s either a bug in this parser or the specification
126 * contains a command with more than 10 identified tokens. */
127 fprintf(stderr, "BUG: commands_parser stack full. This means either a bug "
128 "in the code, or a new command which contains more than "
129 "10 identified tokens.\n");
130 exit(EXIT_FAILURE);
131 }
132
133 // TODO move to a common util
134 static const char *get_string(const char *identifier) {
135 for (int c = 0; c < 10; c++) {
136 if (stack[c].identifier == NULL)
137 break;
138 if (strcmp(identifier, stack[c].identifier) == 0)
139 return stack[c].val.str;
140 }
141 return NULL;
142 }
143
144 // TODO move to a common util
145 static long get_long(const char *identifier) {
146 for (int c = 0; c < 10; c++) {
147 if (stack[c].identifier == NULL)
148 break;
149 if (strcmp(identifier, stack[c].identifier) == 0)
150 return stack[c].val.num;
151 }
152
153 return 0;
154 }
155
156 // TODO move to a common util
157 static void clear_stack(void) {
158 for (int c = 0; c < 10; c++) {
159 if (stack[c].type == STACK_STR)
160 free(stack[c].val.str);
161 stack[c].identifier = NULL;
162 stack[c].val.str = NULL;
163 stack[c].val.num = 0;
164 }
165 }
166
167 /*******************************************************************************
168 * The parser itself.
169 ******************************************************************************/
170
171 static cmdp_state state;
172 #ifndef TEST_PARSER
173 static Match current_match;
174 #endif
175 static struct CommandResultIR subcommand_output;
176 static struct CommandResultIR command_output;
177
178 #include "GENERATED_command_call.h"
179
180 static void next_state(const cmdp_token *token) {
181 if (token->next_state == __CALL) {
182 subcommand_output.json_gen = command_output.json_gen;
183 subcommand_output.client = command_output.client;
184 subcommand_output.needs_tree_render = false;
185 GENERATED_call(token->extra.call_identifier, &subcommand_output);
186 state = subcommand_output.next_state;
187 /* If any subcommand requires a tree_render(), we need to make the
188 * whole parser result request a tree_render(). */
189 if (subcommand_output.needs_tree_render)
190 command_output.needs_tree_render = true;
191 clear_stack();
192 return;
193 }
194
195 state = token->next_state;
196 if (state == INITIAL) {
197 clear_stack();
198 }
199 }
200
201 /*
202 * Parses a string (or word, if as_word is true). Extracted out of
203 * parse_command so that it can be used in src/workspace.c for interpreting
204 * workspace commands.
205 *
206 */
207 char *parse_string(const char **walk, bool as_word) {
208 const char *beginning = *walk;
209 /* Handle quoted strings (or words). */
210 if (**walk == '"') {
211 beginning++;
212 (*walk)++;
213 for (; **walk != '\0' && **walk != '"'; (*walk)++)
214 if (**walk == '\\' && *(*walk + 1) != '\0')
215 (*walk)++;
216 } else {
217 if (!as_word) {
218 /* For a string (starting with 's'), the delimiters are
219 * comma (,) and semicolon (;) which introduce a new
220 * operation or command, respectively. Also, newlines
221 * end a command. */
222 while (**walk != ';' && **walk != ',' &&
223 **walk != '\0' && **walk != '\r' &&
224 **walk != '\n')
225 (*walk)++;
226 } else {
227 /* For a word, the delimiters are white space (' ' or
228 * '\t'), closing square bracket (]), comma (,) and
229 * semicolon (;). */
230 while (**walk != ' ' && **walk != '\t' &&
231 **walk != ']' && **walk != ',' &&
232 **walk != ';' && **walk != '\r' &&
233 **walk != '\n' && **walk != '\0')
234 (*walk)++;
235 }
236 }
237 if (*walk == beginning)
238 return NULL;
239
240 char *str = scalloc(*walk - beginning + 1, 1);
241 /* We copy manually to handle escaping of characters. */
242 int inpos, outpos;
243 for (inpos = 0, outpos = 0;
244 inpos < (*walk - beginning);
245 inpos++, outpos++) {
246 /* We only handle escaped double quotes and backslashes to not break
247 * backwards compatibility with people using \w in regular expressions
248 * etc. */
249 if (beginning[inpos] == '\\' && (beginning[inpos + 1] == '"' || beginning[inpos + 1] == '\\'))
250 inpos++;
251 str[outpos] = beginning[inpos];
252 }
253
254 return str;
255 }
256
257 /*
258 * Parses and executes the given command. If a caller-allocated yajl_gen is
259 * passed, a json reply will be generated in the format specified by the ipc
260 * protocol. Pass NULL if no json reply is required.
261 *
262 * Free the returned CommandResult with command_result_free().
263 */
264 CommandResult *parse_command(const char *input, yajl_gen gen, ipc_client *client) {
265 DLOG("COMMAND: *%.4000s*\n", input);
266 state = INITIAL;
267 CommandResult *result = scalloc(1, sizeof(CommandResult));
268
269 command_output.client = client;
270
271 /* A YAJL JSON generator used for formatting replies. */
272 command_output.json_gen = gen;
273
274 y(array_open);
275 command_output.needs_tree_render = false;
276
277 const char *walk = input;
278 const size_t len = strlen(input);
279 int c;
280 const cmdp_token *token;
281 bool token_handled;
282
283 // TODO: make this testable
284 #ifndef TEST_PARSER
285 cmd_criteria_init(&current_match, &subcommand_output);
286 #endif
287
288 /* The "<=" operator is intentional: We also handle the terminating 0-byte
289 * explicitly by looking for an 'end' token. */
290 while ((size_t)(walk - input) <= len) {
291 /* skip whitespace and newlines before every token */
292 while ((*walk == ' ' || *walk == '\t' ||
293 *walk == '\r' || *walk == '\n') &&
294 *walk != '\0')
295 walk++;
296
297 cmdp_token_ptr *ptr = &(tokens[state]);
298 token_handled = false;
299 for (c = 0; c < ptr->n; c++) {
300 token = &(ptr->array[c]);
301
302 /* A literal. */
303 if (token->name[0] == '\'') {
304 if (strncasecmp(walk, token->name + 1, strlen(token->name) - 1) == 0) {
305 if (token->identifier != NULL)
306 push_string(token->identifier, sstrdup(token->name + 1));
307 walk += strlen(token->name) - 1;
308 next_state(token);
309 token_handled = true;
310 break;
311 }
312 continue;
313 }
314
315 if (strcmp(token->name, "number") == 0) {
316 /* Handle numbers. We only accept decimal numbers for now. */
317 char *end = NULL;
318 errno = 0;
319 long int num = strtol(walk, &end, 10);
320 if ((errno == ERANGE && (num == LONG_MIN || num == LONG_MAX)) ||
321 (errno != 0 && num == 0))
322 continue;
323
324 /* No valid numbers found */
325 if (end == walk)
326 continue;
327
328 if (token->identifier != NULL)
329 push_long(token->identifier, num);
330
331 /* Set walk to the first non-number character */
332 walk = end;
333 next_state(token);
334 token_handled = true;
335 break;
336 }
337
338 if (strcmp(token->name, "string") == 0 ||
339 strcmp(token->name, "word") == 0) {
340 char *str = parse_string(&walk, (token->name[0] != 's'));
341 if (str != NULL) {
342 if (token->identifier)
343 push_string(token->identifier, str);
344 /* If we are at the end of a quoted string, skip the ending
345 * double quote. */
346 if (*walk == '"')
347 walk++;
348 next_state(token);
349 token_handled = true;
350 break;
351 }
352 }
353
354 if (strcmp(token->name, "end") == 0) {
355 if (*walk == '\0' || *walk == ',' || *walk == ';') {
356 next_state(token);
357 token_handled = true;
358 /* To make sure we start with an appropriate matching
359 * datastructure for commands which do *not* specify any
360 * criteria, we re-initialize the criteria system after
361 * every command. */
362 // TODO: make this testable
363 #ifndef TEST_PARSER
364 if (*walk == '\0' || *walk == ';')
365 cmd_criteria_init(&current_match, &subcommand_output);
366 #endif
367 walk++;
368 break;
369 }
370 }
371 }
372
373 if (!token_handled) {
374 /* Figure out how much memory we will need to fill in the names of
375 * all tokens afterwards. */
376 int tokenlen = 0;
377 for (c = 0; c < ptr->n; c++)
378 tokenlen += strlen(ptr->array[c].name) + strlen("'', ");
379
380 /* Build up a decent error message. We include the problem, the
381 * full input, and underline the position where the parser
382 * currently is. */
383 char *errormessage;
384 char *possible_tokens = smalloc(tokenlen + 1);
385 char *tokenwalk = possible_tokens;
386 for (c = 0; c < ptr->n; c++) {
387 token = &(ptr->array[c]);
388 if (token->name[0] == '\'') {
389 /* A literal is copied to the error message enclosed with
390 * single quotes. */
391 *tokenwalk++ = '\'';
392 strcpy(tokenwalk, token->name + 1);
393 tokenwalk += strlen(token->name + 1);
394 *tokenwalk++ = '\'';
395 } else {
396 /* Any other token is copied to the error message enclosed
397 * with angle brackets. */
398 *tokenwalk++ = '<';
399 strcpy(tokenwalk, token->name);
400 tokenwalk += strlen(token->name);
401 *tokenwalk++ = '>';
402 }
403 if (c < (ptr->n - 1)) {
404 *tokenwalk++ = ',';
405 *tokenwalk++ = ' ';
406 }
407 }
408 *tokenwalk = '\0';
409 sasprintf(&errormessage, "Expected one of these tokens: %s",
410 possible_tokens);
411 free(possible_tokens);
412
413 /* Contains the same amount of characters as 'input' has, but with
414 * the unparseable part highlighted using ^ characters. */
415 char *position = smalloc(len + 1);
416 for (const char *copywalk = input; *copywalk != '\0'; copywalk++)
417 position[(copywalk - input)] = (copywalk >= walk ? '^' : ' ');
418 position[len] = '\0';
419
420 ELOG("%s\n", errormessage);
421 ELOG("Your command: %s\n", input);
422 ELOG(" %s\n", position);
423
424 result->parse_error = true;
425 result->error_message = errormessage;
426
427 /* Format this error message as a JSON reply. */
428 y(map_open);
429 ystr("success");
430 y(bool, false);
431 /* We set parse_error to true to distinguish this from other
432 * errors. i3-nagbar is spawned upon keypresses only for parser
433 * errors. */
434 ystr("parse_error");
435 y(bool, true);
436 ystr("error");
437 ystr(errormessage);
438 ystr("input");
439 ystr(input);
440 ystr("errorposition");
441 ystr(position);
442 y(map_close);
443
444 free(position);
445 clear_stack();
446 break;
447 }
448 }
449
450 y(array_close);
451
452 result->needs_tree_render = command_output.needs_tree_render;
453 return result;
454 }
455
456 /*
457 * Frees a CommandResult
458 */
459 void command_result_free(CommandResult *result) {
460 if (result == NULL)
461 return;
462
463 FREE(result->error_message);
464 FREE(result);
465 }
466
467 /*******************************************************************************
468 * Code for building the stand-alone binary test.commands_parser which is used
469 * by t/187-commands-parser.t.
470 ******************************************************************************/
471
472 #ifdef TEST_PARSER
473
474 /*
475 * Logs the given message to stdout while prefixing the current time to it,
476 * but only if debug logging was activated.
477 * This is to be called by DLOG() which includes filename/linenumber
478 *
479 */
480 void debuglog(char *fmt, ...) {
481 va_list args;
482
483 va_start(args, fmt);
484 fprintf(stdout, "# ");
485 vfprintf(stdout, fmt, args);
486 va_end(args);
487 }
488
489 void errorlog(char *fmt, ...) {
490 va_list args;
491
492 va_start(args, fmt);
493 vfprintf(stderr, fmt, args);
494 va_end(args);
495 }
496
497 int main(int argc, char *argv[]) {
498 if (argc < 2) {
499 fprintf(stderr, "Syntax: %s <command>\n", argv[0]);
500 return 1;
501 }
502 yajl_gen gen = yajl_gen_alloc(NULL);
503
504 CommandResult *result = parse_command(argv[1], gen, NULL);
505
506 command_result_free(result);
507
508 yajl_gen_free(gen);
509 }
510 #endif
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * con.c: Functions which deal with containers directly (creating containers,
7 * searching containers, getting specific properties from containers,
8 * …).
9 *
10 */
11 #include "all.h"
12
13 #include "yajl_utils.h"
14
15 static void con_on_remove_child(Con *con);
16
17 /*
18 * force parent split containers to be redrawn
19 *
20 */
21 void con_force_split_parents_redraw(Con *con) {
22 Con *parent = con;
23
24 while (parent != NULL && parent->type != CT_WORKSPACE && parent->type != CT_DOCKAREA) {
25 if (!con_is_leaf(parent)) {
26 FREE(parent->deco_render_params);
27 }
28
29 parent = parent->parent;
30 }
31 }
32
33 /*
34 * Create a new container (and attach it to the given parent, if not NULL).
35 * This function only initializes the data structures.
36 *
37 */
38 Con *con_new_skeleton(Con *parent, i3Window *window) {
39 Con *new = scalloc(1, sizeof(Con));
40 new->on_remove_child = con_on_remove_child;
41 TAILQ_INSERT_TAIL(&all_cons, new, all_cons);
42 new->type = CT_CON;
43 new->window = window;
44 new->border_style = config.default_border;
45 new->current_border_width = -1;
46 if (window) {
47 new->depth = window->depth;
48 } else {
49 new->depth = root_depth;
50 }
51 DLOG("opening window\n");
52
53 TAILQ_INIT(&(new->floating_head));
54 TAILQ_INIT(&(new->nodes_head));
55 TAILQ_INIT(&(new->focus_head));
56 TAILQ_INIT(&(new->swallow_head));
57 TAILQ_INIT(&(new->marks_head));
58
59 if (parent != NULL)
60 con_attach(new, parent, false);
61
62 return new;
63 }
64
65 /* A wrapper for con_new_skeleton, to retain the old con_new behaviour
66 *
67 */
68 Con *con_new(Con *parent, i3Window *window) {
69 Con *new = con_new_skeleton(parent, window);
70 x_con_init(new);
71 return new;
72 }
73
74 /*
75 * Frees the specified container.
76 *
77 */
78 void con_free(Con *con) {
79 free(con->name);
80 FREE(con->deco_render_params);
81 TAILQ_REMOVE(&all_cons, con, all_cons);
82 while (!TAILQ_EMPTY(&(con->swallow_head))) {
83 Match *match = TAILQ_FIRST(&(con->swallow_head));
84 TAILQ_REMOVE(&(con->swallow_head), match, matches);
85 match_free(match);
86 free(match);
87 }
88 while (!TAILQ_EMPTY(&(con->marks_head))) {
89 mark_t *mark = TAILQ_FIRST(&(con->marks_head));
90 TAILQ_REMOVE(&(con->marks_head), mark, marks);
91 FREE(mark->name);
92 FREE(mark);
93 }
94 free(con);
95 DLOG("con %p freed\n", con);
96 }
97
98 static void _con_attach(Con *con, Con *parent, Con *previous, bool ignore_focus) {
99 con->parent = parent;
100 Con *loop;
101 Con *current = previous;
102 struct nodes_head *nodes_head = &(parent->nodes_head);
103 struct focus_head *focus_head = &(parent->focus_head);
104
105 /* Workspaces are handled differently: they need to be inserted at the
106 * right position. */
107 if (con->type == CT_WORKSPACE) {
108 DLOG("it's a workspace. num = %d\n", con->num);
109 if (con->num == -1 || TAILQ_EMPTY(nodes_head)) {
110 TAILQ_INSERT_TAIL(nodes_head, con, nodes);
111 } else {
112 current = TAILQ_FIRST(nodes_head);
113 if (con->num < current->num) {
114 /* we need to insert the container at the beginning */
115 TAILQ_INSERT_HEAD(nodes_head, con, nodes);
116 } else {
117 while (current->num != -1 && con->num > current->num) {
118 current = TAILQ_NEXT(current, nodes);
119 if (current == TAILQ_END(nodes_head)) {
120 current = NULL;
121 break;
122 }
123 }
124 /* we need to insert con after current, if current is not NULL */
125 if (current)
126 TAILQ_INSERT_BEFORE(current, con, nodes);
127 else
128 TAILQ_INSERT_TAIL(nodes_head, con, nodes);
129 }
130 }
131 goto add_to_focus_head;
132 }
133
134 if (parent->type == CT_DOCKAREA) {
135 /* Insert dock client, sorting alphanumerically by class and then
136 * instance name. This makes dock client order deterministic. As a side
137 * effect, bars without a custom bar id will be sorted according to
138 * their declaration order in the config file. See #3491. */
139 current = NULL;
140 TAILQ_FOREACH (loop, nodes_head, nodes) {
141 int result = strcasecmp_nullable(con->window->class_class, loop->window->class_class);
142 if (result == 0) {
143 result = strcasecmp_nullable(con->window->class_instance, loop->window->class_instance);
144 }
145 if (result < 0) {
146 current = loop;
147 break;
148 }
149 }
150 if (current) {
151 TAILQ_INSERT_BEFORE(loop, con, nodes);
152 } else {
153 TAILQ_INSERT_TAIL(nodes_head, con, nodes);
154 }
155 goto add_to_focus_head;
156 }
157
158 if (con->type == CT_FLOATING_CON) {
159 DLOG("Inserting into floating containers\n");
160 TAILQ_INSERT_TAIL(&(parent->floating_head), con, floating_windows);
161 } else {
162 if (!ignore_focus) {
163 /* Get the first tiling container in focus stack */
164 TAILQ_FOREACH (loop, &(parent->focus_head), focused) {
165 if (loop->type == CT_FLOATING_CON)
166 continue;
167 current = loop;
168 break;
169 }
170 }
171
172 /* When the container is not a split container (but contains a window)
173 * and is attached to a workspace, we check if the user configured a
174 * workspace_layout. This is done in workspace_attach_to, which will
175 * provide us with the container to which we should attach (either the
176 * workspace or a new split container with the configured
177 * workspace_layout).
178 */
179 if (con->window != NULL &&
180 parent->type == CT_WORKSPACE &&
181 parent->workspace_layout != L_DEFAULT) {
182 DLOG("Parent is a workspace. Applying default layout...\n");
183 Con *target = workspace_attach_to(parent);
184
185 /* Attach the original con to this new split con instead */
186 nodes_head = &(target->nodes_head);
187 focus_head = &(target->focus_head);
188 con->parent = target;
189 current = NULL;
190
191 DLOG("done\n");
192 }
193
194 /* Insert the container after the tiling container, if found.
195 * When adding to a CT_OUTPUT, just append one after another. */
196 if (current != NULL && parent->type != CT_OUTPUT) {
197 DLOG("Inserting con = %p after con %p\n", con, current);
198 TAILQ_INSERT_AFTER(nodes_head, current, con, nodes);
199 } else
200 TAILQ_INSERT_TAIL(nodes_head, con, nodes);
201 }
202
203 add_to_focus_head:
204 /* We insert to the TAIL because con_focus() will correct this.
205 * This way, we have the option to insert Cons without having
206 * to focus them. */
207 TAILQ_INSERT_TAIL(focus_head, con, focused);
208 con_force_split_parents_redraw(con);
209 }
210
211 /*
212 * Attaches the given container to the given parent. This happens when moving
213 * a container or when inserting a new container at a specific place in the
214 * tree.
215 *
216 * ignore_focus is to just insert the Con at the end (useful when creating a
217 * new split container *around* some containers, that is, detaching and
218 * attaching them in order without wanting to mess with the focus in between).
219 *
220 */
221 void con_attach(Con *con, Con *parent, bool ignore_focus) {
222 _con_attach(con, parent, NULL, ignore_focus);
223 }
224
225 /*
226 * Detaches the given container from its current parent
227 *
228 */
229 void con_detach(Con *con) {
230 con_force_split_parents_redraw(con);
231 if (con->type == CT_FLOATING_CON) {
232 TAILQ_REMOVE(&(con->parent->floating_head), con, floating_windows);
233 TAILQ_REMOVE(&(con->parent->focus_head), con, focused);
234 } else {
235 TAILQ_REMOVE(&(con->parent->nodes_head), con, nodes);
236 TAILQ_REMOVE(&(con->parent->focus_head), con, focused);
237 }
238 }
239
240 /*
241 * Sets input focus to the given container. Will be updated in X11 in the next
242 * run of x_push_changes().
243 *
244 */
245 void con_focus(Con *con) {
246 assert(con != NULL);
247 DLOG("con_focus = %p\n", con);
248
249 /* 1: set focused-pointer to the new con */
250 /* 2: exchange the position of the container in focus stack of the parent all the way up */
251 TAILQ_REMOVE(&(con->parent->focus_head), con, focused);
252 TAILQ_INSERT_HEAD(&(con->parent->focus_head), con, focused);
253 if (con->parent->parent != NULL)
254 con_focus(con->parent);
255
256 focused = con;
257 /* We can't blindly reset non-leaf containers since they might have
258 * other urgent children. Therefore we only reset leafs and propagate
259 * the changes upwards via con_update_parents_urgency() which does proper
260 * checks before resetting the urgency.
261 */
262 if (con->urgent && con_is_leaf(con)) {
263 con_set_urgency(con, false);
264 con_update_parents_urgency(con);
265 workspace_update_urgent_flag(con_get_workspace(con));
266 ipc_send_window_event("urgent", con);
267 }
268 }
269
270 /*
271 * Raise container to the top if it is floating or inside some floating
272 * container.
273 *
274 */
275 static void con_raise(Con *con) {
276 Con *floating = con_inside_floating(con);
277 if (floating) {
278 floating_raise_con(floating);
279 }
280 }
281
282 /*
283 * Sets input focus to the given container and raises it to the top.
284 *
285 */
286 void con_activate(Con *con) {
287 con_focus(con);
288 con_raise(con);
289 }
290
291 /*
292 * Activates the container like in con_activate but removes fullscreen
293 * restrictions and properly warps the pointer if needed.
294 *
295 */
296 void con_activate_unblock(Con *con) {
297 Con *ws = con_get_workspace(con);
298 Con *previous_focus = focused;
299 Con *fullscreen_on_ws = con_get_fullscreen_covering_ws(ws);
300
301 if (fullscreen_on_ws && fullscreen_on_ws != con && !con_has_parent(con, fullscreen_on_ws)) {
302 con_disable_fullscreen(fullscreen_on_ws);
303 }
304
305 con_activate(con);
306
307 /* If the container is not on the current workspace, workspace_show() will
308 * switch to a different workspace and (if enabled) trigger a mouse pointer
309 * warp to the currently focused container (!) on the target workspace.
310 *
311 * Therefore, before calling workspace_show(), we make sure that 'con' will
312 * be focused on the workspace. However, we cannot just con_focus(con)
313 * because then the pointer will not be warped at all (the code thinks we
314 * are already there).
315 *
316 * So we focus 'con' to make it the currently focused window of the target
317 * workspace, then revert focus. */
318 if (ws != con_get_workspace(previous_focus)) {
319 con_activate(previous_focus);
320 /* Now switch to the workspace, then focus */
321 workspace_show(ws);
322 con_activate(con);
323 }
324 }
325
326 /*
327 * Closes the given container.
328 *
329 */
330 void con_close(Con *con, kill_window_t kill_window) {
331 assert(con != NULL);
332 DLOG("Closing con = %p.\n", con);
333
334 /* We never close output or root containers. */
335 if (con->type == CT_OUTPUT || con->type == CT_ROOT) {
336 DLOG("con = %p is of type %d, not closing anything.\n", con, con->type);
337 return;
338 }
339
340 if (con->type == CT_WORKSPACE) {
341 DLOG("con = %p is a workspace, closing all children instead.\n", con);
342 Con *child, *nextchild;
343 for (child = TAILQ_FIRST(&(con->focus_head)); child;) {
344 nextchild = TAILQ_NEXT(child, focused);
345 DLOG("killing child = %p.\n", child);
346 tree_close_internal(child, kill_window, false);
347 child = nextchild;
348 }
349
350 return;
351 }
352
353 tree_close_internal(con, kill_window, false);
354 }
355
356 /*
357 * Returns true when this node is a leaf node (has no children)
358 *
359 */
360 bool con_is_leaf(Con *con) {
361 return TAILQ_EMPTY(&(con->nodes_head));
362 }
363
364 /*
365 * Returns true when this con is a leaf node with a managed X11 window (e.g.,
366 * excluding dock containers)
367 */
368 bool con_has_managed_window(Con *con) {
369 return (con != NULL && con->window != NULL && con->window->id != XCB_WINDOW_NONE && con_get_workspace(con) != NULL);
370 }
371
372 /*
373 * Returns true if this node has regular or floating children.
374 *
375 */
376 bool con_has_children(Con *con) {
377 return (!con_is_leaf(con) || !TAILQ_EMPTY(&(con->floating_head)));
378 }
379
380 /*
381 * Returns true if a container should be considered split.
382 *
383 */
384 bool con_is_split(Con *con) {
385 if (con_is_leaf(con))
386 return false;
387
388 switch (con->layout) {
389 case L_DOCKAREA:
390 case L_OUTPUT:
391 return false;
392
393 default:
394 return true;
395 }
396 }
397
398 /*
399 * This will only return true for containers which have some parent with
400 * a tabbed / stacked parent of which they are not the currently focused child.
401 *
402 */
403 bool con_is_hidden(Con *con) {
404 Con *current = con;
405
406 /* ascend to the workspace level and memorize the highest-up container
407 * which is stacked or tabbed. */
408 while (current != NULL && current->type != CT_WORKSPACE) {
409 Con *parent = current->parent;
410 if (parent != NULL && (parent->layout == L_TABBED || parent->layout == L_STACKED)) {
411 if (TAILQ_FIRST(&(parent->focus_head)) != current)
412 return true;
413 }
414
415 current = parent;
416 }
417
418 return false;
419 }
420
421 /*
422 * Returns whether the container or any of its children is sticky.
423 *
424 */
425 bool con_is_sticky(Con *con) {
426 if (con->sticky)
427 return true;
428
429 Con *child;
430 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
431 if (con_is_sticky(child))
432 return true;
433 }
434
435 return false;
436 }
437
438 /*
439 * Returns true if this node accepts a window (if the node swallows windows,
440 * it might already have swallowed enough and cannot hold any more).
441 *
442 */
443 bool con_accepts_window(Con *con) {
444 /* 1: workspaces never accept direct windows */
445 if (con->type == CT_WORKSPACE)
446 return false;
447
448 if (con_is_split(con)) {
449 DLOG("container %p does not accept windows, it is a split container.\n", con);
450 return false;
451 }
452
453 /* TODO: if this is a swallowing container, we need to check its max_clients */
454 return (con->window == NULL);
455 }
456
457 /*
458 * Gets the output container (first container with CT_OUTPUT in hierarchy) this
459 * node is on.
460 *
461 */
462 Con *con_get_output(Con *con) {
463 Con *result = con;
464 while (result != NULL && result->type != CT_OUTPUT)
465 result = result->parent;
466 /* We must be able to get an output because focus can never be set higher
467 * in the tree (root node cannot be focused). */
468 assert(result != NULL);
469 return result;
470 }
471
472 /*
473 * Gets the workspace container this node is on.
474 *
475 */
476 Con *con_get_workspace(Con *con) {
477 Con *result = con;
478 while (result != NULL && result->type != CT_WORKSPACE)
479 result = result->parent;
480 return result;
481 }
482
483 /*
484 * Searches parents of the given 'con' until it reaches one with the specified
485 * 'orientation'. Aborts when it comes across a floating_con.
486 *
487 */
488 Con *con_parent_with_orientation(Con *con, orientation_t orientation) {
489 DLOG("Searching for parent of Con %p with orientation %d\n", con, orientation);
490 Con *parent = con->parent;
491 if (parent->type == CT_FLOATING_CON)
492 return NULL;
493 while (con_orientation(parent) != orientation) {
494 DLOG("Need to go one level further up\n");
495 parent = parent->parent;
496 /* Abort when we reach a floating con, or an output con */
497 if (parent &&
498 (parent->type == CT_FLOATING_CON ||
499 parent->type == CT_OUTPUT ||
500 (parent->parent && parent->parent->type == CT_OUTPUT)))
501 parent = NULL;
502 if (parent == NULL)
503 break;
504 }
505 DLOG("Result: %p\n", parent);
506 return parent;
507 }
508
509 /*
510 * helper data structure for the breadth-first-search in
511 * con_get_fullscreen_con()
512 *
513 */
514 struct bfs_entry {
515 Con *con;
516
517 TAILQ_ENTRY(bfs_entry)
518 entries;
519 };
520
521 /*
522 * Returns the first fullscreen node below this node.
523 *
524 */
525 Con *con_get_fullscreen_con(Con *con, fullscreen_mode_t fullscreen_mode) {
526 Con *current, *child;
527
528 /* TODO: is breadth-first-search really appropriate? (check as soon as
529 * fullscreen levels and fullscreen for containers is implemented) */
530 TAILQ_HEAD(bfs_head, bfs_entry)
531 bfs_head = TAILQ_HEAD_INITIALIZER(bfs_head);
532
533 struct bfs_entry *entry = smalloc(sizeof(struct bfs_entry));
534 entry->con = con;
535 TAILQ_INSERT_TAIL(&bfs_head, entry, entries);
536
537 while (!TAILQ_EMPTY(&bfs_head)) {
538 entry = TAILQ_FIRST(&bfs_head);
539 current = entry->con;
540 if (current != con && current->fullscreen_mode == fullscreen_mode) {
541 /* empty the queue */
542 while (!TAILQ_EMPTY(&bfs_head)) {
543 entry = TAILQ_FIRST(&bfs_head);
544 TAILQ_REMOVE(&bfs_head, entry, entries);
545 free(entry);
546 }
547 return current;
548 }
549
550 TAILQ_REMOVE(&bfs_head, entry, entries);
551 free(entry);
552
553 TAILQ_FOREACH (child, &(current->nodes_head), nodes) {
554 entry = smalloc(sizeof(struct bfs_entry));
555 entry->con = child;
556 TAILQ_INSERT_TAIL(&bfs_head, entry, entries);
557 }
558
559 TAILQ_FOREACH (child, &(current->floating_head), floating_windows) {
560 entry = smalloc(sizeof(struct bfs_entry));
561 entry->con = child;
562 TAILQ_INSERT_TAIL(&bfs_head, entry, entries);
563 }
564 }
565
566 return NULL;
567 }
568
569 /*
570 * Returns the fullscreen node that covers the given workspace if it exists.
571 * This is either a CF_GLOBAL fullscreen container anywhere or a CF_OUTPUT
572 * fullscreen container in the workspace.
573 *
574 */
575 Con *con_get_fullscreen_covering_ws(Con *ws) {
576 if (!ws) {
577 return NULL;
578 }
579 Con *fs = con_get_fullscreen_con(croot, CF_GLOBAL);
580 if (!fs) {
581 return con_get_fullscreen_con(ws, CF_OUTPUT);
582 }
583 return fs;
584 }
585
586 /*
587 * Returns true if the container is internal, such as __i3_scratch
588 *
589 */
590 bool con_is_internal(Con *con) {
591 return (con->name[0] == '_' && con->name[1] == '_');
592 }
593
594 /*
595 * Returns true if the node is floating.
596 *
597 */
598 bool con_is_floating(Con *con) {
599 assert(con != NULL);
600 return (con->floating >= FLOATING_AUTO_ON);
601 }
602
603 /*
604 * Returns true if the container is a docked container.
605 *
606 */
607 bool con_is_docked(Con *con) {
608 if (con->parent == NULL)
609 return false;
610
611 if (con->parent->type == CT_DOCKAREA)
612 return true;
613
614 return con_is_docked(con->parent);
615 }
616
617 /*
618 * Checks if the given container is either floating or inside some floating
619 * container. It returns the FLOATING_CON container.
620 *
621 */
622 Con *con_inside_floating(Con *con) {
623 assert(con != NULL);
624 if (con->type == CT_FLOATING_CON)
625 return con;
626
627 if (con->floating >= FLOATING_AUTO_ON)
628 return con->parent;
629
630 if (con->type == CT_WORKSPACE || con->type == CT_OUTPUT)
631 return NULL;
632
633 return con_inside_floating(con->parent);
634 }
635
636 /*
637 * Checks if the given container is inside a focused container.
638 *
639 */
640 bool con_inside_focused(Con *con) {
641 if (con == focused)
642 return true;
643 if (!con->parent)
644 return false;
645 return con_inside_focused(con->parent);
646 }
647
648 /*
649 * Checks if the container has the given parent as an actual parent.
650 *
651 */
652 bool con_has_parent(Con *con, Con *parent) {
653 Con *current = con->parent;
654 if (current == NULL) {
655 return false;
656 }
657
658 if (current == parent) {
659 return true;
660 }
661
662 return con_has_parent(current, parent);
663 }
664
665 /*
666 * Returns the container with the given client window ID or NULL if no such
667 * container exists.
668 *
669 */
670 Con *con_by_window_id(xcb_window_t window) {
671 Con *con;
672 TAILQ_FOREACH (con, &all_cons, all_cons) {
673 if (con->window != NULL && con->window->id == window) {
674 return con;
675 }
676 }
677 return NULL;
678 }
679
680 /*
681 * Returns the container with the given container ID or NULL if no such
682 * container exists.
683 *
684 */
685 Con *con_by_con_id(long target) {
686 Con *con;
687 TAILQ_FOREACH (con, &all_cons, all_cons) {
688 if (con == (Con *)target) {
689 return con;
690 }
691 }
692
693 return NULL;
694 }
695
696 /*
697 * Returns true if the given container (still) exists.
698 * This can be used, e.g., to make sure a container hasn't been closed in the meantime.
699 *
700 */
701 bool con_exists(Con *con) {
702 return con_by_con_id((long)con) != NULL;
703 }
704
705 /*
706 * Returns the container with the given frame ID or NULL if no such container
707 * exists.
708 *
709 */
710 Con *con_by_frame_id(xcb_window_t frame) {
711 Con *con;
712 TAILQ_FOREACH (con, &all_cons, all_cons) {
713 if (con->frame.id == frame) {
714 return con;
715 }
716 }
717 return NULL;
718 }
719
720 /*
721 * Returns the container with the given mark or NULL if no such container
722 * exists.
723 *
724 */
725 Con *con_by_mark(const char *mark) {
726 Con *con;
727 TAILQ_FOREACH (con, &all_cons, all_cons) {
728 if (con_has_mark(con, mark))
729 return con;
730 }
731
732 return NULL;
733 }
734
735 /*
736 * Returns true if and only if the given containers holds the mark.
737 *
738 */
739 bool con_has_mark(Con *con, const char *mark) {
740 mark_t *current;
741 TAILQ_FOREACH (current, &(con->marks_head), marks) {
742 if (strcmp(current->name, mark) == 0)
743 return true;
744 }
745
746 return false;
747 }
748
749 /*
750 * Toggles the mark on a container.
751 * If the container already has this mark, the mark is removed.
752 * Otherwise, the mark is assigned to the container.
753 *
754 */
755 void con_mark_toggle(Con *con, const char *mark, mark_mode_t mode) {
756 assert(con != NULL);
757 DLOG("Toggling mark \"%s\" on con = %p.\n", mark, con);
758
759 if (con_has_mark(con, mark)) {
760 con_unmark(con, mark);
761 } else {
762 con_mark(con, mark, mode);
763 }
764 }
765
766 /*
767 * Assigns a mark to the container.
768 *
769 */
770 void con_mark(Con *con, const char *mark, mark_mode_t mode) {
771 assert(con != NULL);
772 DLOG("Setting mark \"%s\" on con = %p.\n", mark, con);
773
774 con_unmark(NULL, mark);
775 if (mode == MM_REPLACE) {
776 DLOG("Removing all existing marks on con = %p.\n", con);
777
778 mark_t *current;
779 while (!TAILQ_EMPTY(&(con->marks_head))) {
780 current = TAILQ_FIRST(&(con->marks_head));
781 con_unmark(con, current->name);
782 }
783 }
784
785 mark_t *new = scalloc(1, sizeof(mark_t));
786 new->name = sstrdup(mark);
787 TAILQ_INSERT_TAIL(&(con->marks_head), new, marks);
788 ipc_send_window_event("mark", con);
789
790 con->mark_changed = true;
791 }
792
793 /*
794 * Removes marks from containers.
795 * If con is NULL, all containers are considered.
796 * If name is NULL, this removes all existing marks.
797 * Otherwise, it will only remove the given mark (if it is present).
798 *
799 */
800 void con_unmark(Con *con, const char *name) {
801 Con *current;
802 if (name == NULL) {
803 DLOG("Unmarking all containers.\n");
804 TAILQ_FOREACH (current, &all_cons, all_cons) {
805 if (con != NULL && current != con)
806 continue;
807
808 if (TAILQ_EMPTY(&(current->marks_head)))
809 continue;
810
811 mark_t *mark;
812 while (!TAILQ_EMPTY(&(current->marks_head))) {
813 mark = TAILQ_FIRST(&(current->marks_head));
814 FREE(mark->name);
815 TAILQ_REMOVE(&(current->marks_head), mark, marks);
816 FREE(mark);
817
818 ipc_send_window_event("mark", current);
819 }
820
821 current->mark_changed = true;
822 }
823 } else {
824 DLOG("Removing mark \"%s\".\n", name);
825 current = (con == NULL) ? con_by_mark(name) : con;
826 if (current == NULL) {
827 DLOG("No container found with this mark, so there is nothing to do.\n");
828 return;
829 }
830
831 DLOG("Found mark on con = %p. Removing it now.\n", current);
832 current->mark_changed = true;
833
834 mark_t *mark;
835 TAILQ_FOREACH (mark, &(current->marks_head), marks) {
836 if (strcmp(mark->name, name) != 0)
837 continue;
838
839 FREE(mark->name);
840 TAILQ_REMOVE(&(current->marks_head), mark, marks);
841 FREE(mark);
842
843 ipc_send_window_event("mark", current);
844 break;
845 }
846 }
847 }
848
849 /*
850 * Returns the first container below 'con' which wants to swallow this window
851 * TODO: priority
852 *
853 */
854 Con *con_for_window(Con *con, i3Window *window, Match **store_match) {
855 Con *child;
856 Match *match;
857 //DLOG("searching con for window %p starting at con %p\n", window, con);
858 //DLOG("class == %s\n", window->class_class);
859
860 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
861 TAILQ_FOREACH (match, &(child->swallow_head), matches) {
862 if (!match_matches_window(match, window))
863 continue;
864 if (store_match != NULL)
865 *store_match = match;
866 return child;
867 }
868 Con *result = con_for_window(child, window, store_match);
869 if (result != NULL)
870 return result;
871 }
872
873 TAILQ_FOREACH (child, &(con->floating_head), floating_windows) {
874 TAILQ_FOREACH (match, &(child->swallow_head), matches) {
875 if (!match_matches_window(match, window))
876 continue;
877 if (store_match != NULL)
878 *store_match = match;
879 return child;
880 }
881 Con *result = con_for_window(child, window, store_match);
882 if (result != NULL)
883 return result;
884 }
885
886 return NULL;
887 }
888
889 static int num_focus_heads(Con *con) {
890 int focus_heads = 0;
891
892 Con *current;
893 TAILQ_FOREACH (current, &(con->focus_head), focused) {
894 focus_heads++;
895 }
896
897 return focus_heads;
898 }
899
900 /*
901 * Iterate over the container's focus stack and return an array with the
902 * containers inside it, ordered from higher focus order to lowest.
903 *
904 */
905 Con **get_focus_order(Con *con) {
906 const int focus_heads = num_focus_heads(con);
907 Con **focus_order = smalloc(focus_heads * sizeof(Con *));
908 Con *current;
909 int idx = 0;
910 TAILQ_FOREACH (current, &(con->focus_head), focused) {
911 assert(idx < focus_heads);
912 focus_order[idx++] = current;
913 }
914
915 return focus_order;
916 }
917
918 /*
919 * Clear the container's focus stack and re-add it using the provided container
920 * array. The function doesn't check if the provided array contains the same
921 * containers with the previous focus stack but will not add floating containers
922 * in the new focus stack if container is not a workspace.
923 *
924 */
925 void set_focus_order(Con *con, Con **focus_order) {
926 int focus_heads = 0;
927 while (!TAILQ_EMPTY(&(con->focus_head))) {
928 Con *current = TAILQ_FIRST(&(con->focus_head));
929
930 TAILQ_REMOVE(&(con->focus_head), current, focused);
931 focus_heads++;
932 }
933
934 for (int idx = 0; idx < focus_heads; idx++) {
935 /* Useful when encapsulating a workspace. */
936 if (con->type != CT_WORKSPACE && con_inside_floating(focus_order[idx])) {
937 focus_heads++;
938 continue;
939 }
940
941 TAILQ_INSERT_TAIL(&(con->focus_head), focus_order[idx], focused);
942 }
943 }
944
945 /*
946 * Returns the number of children of this container.
947 *
948 */
949 int con_num_children(Con *con) {
950 Con *child;
951 int children = 0;
952
953 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
954 children++;
955 }
956
957 return children;
958 }
959
960 /*
961 * Returns the number of visible non-floating children of this container.
962 * For example, if the container contains a hsplit which has two children,
963 * this will return 2 instead of 1.
964 */
965 int con_num_visible_children(Con *con) {
966 if (con == NULL)
967 return 0;
968
969 int children = 0;
970 Con *current = NULL;
971 TAILQ_FOREACH (current, &(con->nodes_head), nodes) {
972 /* Visible leaf nodes are a child. */
973 if (!con_is_hidden(current) && con_is_leaf(current))
974 children++;
975 /* All other containers need to be recursed. */
976 else
977 children += con_num_visible_children(current);
978 }
979
980 return children;
981 }
982
983 /*
984 * Count the number of windows (i.e., leaf containers).
985 *
986 */
987 int con_num_windows(Con *con) {
988 if (con == NULL)
989 return 0;
990
991 if (con_has_managed_window(con))
992 return 1;
993
994 int num = 0;
995 Con *current = NULL;
996 TAILQ_FOREACH (current, &(con->nodes_head), nodes) {
997 num += con_num_windows(current);
998 }
999
1000 TAILQ_FOREACH (current, &(con->floating_head), floating_windows) {
1001 num += con_num_windows(current);
1002 }
1003
1004 return num;
1005 }
1006
1007 /*
1008 * Updates the percent attribute of the children of the given container. This
1009 * function needs to be called when a window is added or removed from a
1010 * container.
1011 *
1012 */
1013 void con_fix_percent(Con *con) {
1014 Con *child;
1015 int children = con_num_children(con);
1016
1017 // calculate how much we have distributed and how many containers
1018 // with a percentage set we have
1019 double total = 0.0;
1020 int children_with_percent = 0;
1021 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
1022 if (child->percent > 0.0) {
1023 total += child->percent;
1024 ++children_with_percent;
1025 }
1026 }
1027
1028 // if there were children without a percentage set, set to a value that
1029 // will make those children proportional to all others
1030 if (children_with_percent != children) {
1031 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
1032 if (child->percent <= 0.0) {
1033 if (children_with_percent == 0) {
1034 total += (child->percent = 1.0);
1035 } else {
1036 total += (child->percent = total / children_with_percent);
1037 }
1038 }
1039 }
1040 }
1041
1042 // if we got a zero, just distribute the space equally, otherwise
1043 // distribute according to the proportions we got
1044 if (total == 0.0) {
1045 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
1046 child->percent = 1.0 / children;
1047 }
1048 } else if (total != 1.0) {
1049 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
1050 child->percent /= total;
1051 }
1052 }
1053 }
1054
1055 /*
1056 * Toggles fullscreen mode for the given container. If there already is a
1057 * fullscreen container on this workspace, fullscreen will be disabled and then
1058 * enabled for the container the user wants to have in fullscreen mode.
1059 *
1060 */
1061 void con_toggle_fullscreen(Con *con, int fullscreen_mode) {
1062 if (con->type == CT_WORKSPACE) {
1063 DLOG("You cannot make a workspace fullscreen.\n");
1064 return;
1065 }
1066
1067 DLOG("toggling fullscreen for %p / %s\n", con, con->name);
1068
1069 if (con->fullscreen_mode == CF_NONE)
1070 con_enable_fullscreen(con, fullscreen_mode);
1071 else
1072 con_disable_fullscreen(con);
1073 }
1074
1075 /*
1076 * Sets the specified fullscreen mode for the given container, sends the
1077 * “fullscreen_mode” event and changes the XCB fullscreen property of the
1078 * container’s window, if any.
1079 *
1080 */
1081 static void con_set_fullscreen_mode(Con *con, fullscreen_mode_t fullscreen_mode) {
1082 con->fullscreen_mode = fullscreen_mode;
1083
1084 DLOG("mode now: %d\n", con->fullscreen_mode);
1085
1086 /* Send an ipc window "fullscreen_mode" event */
1087 ipc_send_window_event("fullscreen_mode", con);
1088
1089 /* update _NET_WM_STATE if this container has a window */
1090 /* TODO: when a window is assigned to a container which is already
1091 * fullscreened, this state needs to be pushed to the client, too */
1092 if (con->window == NULL)
1093 return;
1094
1095 if (con->fullscreen_mode != CF_NONE) {
1096 DLOG("Setting _NET_WM_STATE_FULLSCREEN for con = %p / window = %d.\n", con, con->window->id);
1097 xcb_add_property_atom(conn, con->window->id, A__NET_WM_STATE, A__NET_WM_STATE_FULLSCREEN);
1098 } else {
1099 DLOG("Removing _NET_WM_STATE_FULLSCREEN for con = %p / window = %d.\n", con, con->window->id);
1100 xcb_remove_property_atom(conn, con->window->id, A__NET_WM_STATE, A__NET_WM_STATE_FULLSCREEN);
1101 }
1102 }
1103
1104 /*
1105 * Enables fullscreen mode for the given container, if necessary.
1106 *
1107 * If the container’s mode is already CF_OUTPUT or CF_GLOBAL, the container is
1108 * kept fullscreen but its mode is set to CF_GLOBAL and CF_OUTPUT,
1109 * respectively.
1110 *
1111 * Other fullscreen containers will be disabled first, if they hide the new
1112 * one.
1113 *
1114 */
1115 void con_enable_fullscreen(Con *con, fullscreen_mode_t fullscreen_mode) {
1116 if (con->type == CT_WORKSPACE) {
1117 DLOG("You cannot make a workspace fullscreen.\n");
1118 return;
1119 }
1120
1121 assert(fullscreen_mode == CF_GLOBAL || fullscreen_mode == CF_OUTPUT);
1122
1123 if (fullscreen_mode == CF_GLOBAL)
1124 DLOG("enabling global fullscreen for %p / %s\n", con, con->name);
1125 else
1126 DLOG("enabling fullscreen for %p / %s\n", con, con->name);
1127
1128 if (con->fullscreen_mode == fullscreen_mode) {
1129 DLOG("fullscreen already enabled for %p / %s\n", con, con->name);
1130 return;
1131 }
1132
1133 Con *con_ws = con_get_workspace(con);
1134
1135 /* Disable any fullscreen container that would conflict the new one. */
1136 Con *fullscreen = con_get_fullscreen_con(croot, CF_GLOBAL);
1137 if (fullscreen == NULL)
1138 fullscreen = con_get_fullscreen_con(con_ws, CF_OUTPUT);
1139 if (fullscreen != NULL)
1140 con_disable_fullscreen(fullscreen);
1141
1142 /* Set focus to new fullscreen container. Unless in global fullscreen mode
1143 * and on another workspace restore focus afterwards.
1144 * Switch to the container’s workspace if mode is global. */
1145 Con *cur_ws = con_get_workspace(focused);
1146 Con *old_focused = focused;
1147 if (fullscreen_mode == CF_GLOBAL && cur_ws != con_ws)
1148 workspace_show(con_ws);
1149 con_activate(con);
1150 if (fullscreen_mode != CF_GLOBAL && cur_ws != con_ws)
1151 con_activate(old_focused);
1152
1153 con_set_fullscreen_mode(con, fullscreen_mode);
1154 }
1155
1156 /*
1157 * Disables fullscreen mode for the given container regardless of the mode, if
1158 * necessary.
1159 *
1160 */
1161 void con_disable_fullscreen(Con *con) {
1162 if (con->type == CT_WORKSPACE) {
1163 DLOG("You cannot make a workspace fullscreen.\n");
1164 return;
1165 }
1166
1167 DLOG("disabling fullscreen for %p / %s\n", con, con->name);
1168
1169 if (con->fullscreen_mode == CF_NONE) {
1170 DLOG("fullscreen already disabled for %p / %s\n", con, con->name);
1171 return;
1172 }
1173
1174 con_set_fullscreen_mode(con, CF_NONE);
1175 }
1176
1177 static bool _con_move_to_con(Con *con, Con *target, bool behind_focused, bool fix_coordinates, bool dont_warp, bool ignore_focus, bool fix_percentage) {
1178 Con *orig_target = target;
1179
1180 /* Prevent moving if this would violate the fullscreen focus restrictions. */
1181 Con *target_ws = con_get_workspace(target);
1182 if (!ignore_focus && !con_fullscreen_permits_focusing(target_ws)) {
1183 LOG("Cannot move out of a fullscreen container.\n");
1184 return false;
1185 }
1186
1187 if (con_is_floating(con)) {
1188 DLOG("Container is floating, using parent instead.\n");
1189 con = con->parent;
1190 }
1191
1192 Con *source_ws = con_get_workspace(con);
1193
1194 if (con->type == CT_WORKSPACE) {
1195 /* Re-parent all of the old workspace's floating windows. */
1196 Con *child;
1197 while (!TAILQ_EMPTY(&(source_ws->floating_head))) {
1198 child = TAILQ_FIRST(&(source_ws->floating_head));
1199 con_move_to_workspace(child, target_ws, true, true, false);
1200 }
1201
1202 /* If there are no non-floating children, ignore the workspace. */
1203 if (con_is_leaf(con))
1204 return false;
1205
1206 con = workspace_encapsulate(con);
1207 if (con == NULL) {
1208 ELOG("Workspace failed to move its contents into a container!\n");
1209 return false;
1210 }
1211 }
1212
1213 /* Save the urgency state so that we can restore it. */
1214 bool urgent = con->urgent;
1215
1216 /* Save the current workspace. So we can call workspace_show() by the end
1217 * of this function. */
1218 Con *current_ws = con_get_workspace(focused);
1219
1220 Con *source_output = con_get_output(con),
1221 *dest_output = con_get_output(target_ws);
1222
1223 /* 1: save the container which is going to be focused after the current
1224 * container is moved away */
1225 Con *focus_next = NULL;
1226 if (!ignore_focus && source_ws == current_ws && target_ws != source_ws) {
1227 focus_next = con_descend_focused(source_ws);
1228 if (focus_next == con || con_has_parent(focus_next, con)) {
1229 focus_next = con_next_focused(con);
1230 }
1231 }
1232
1233 /* 2: we go up one level, but only when target is a normal container */
1234 if (target->type != CT_WORKSPACE) {
1235 DLOG("target originally = %p / %s / type %d\n", target, target->name, target->type);
1236 target = target->parent;
1237 }
1238
1239 /* 3: if the original target is the direct child of a floating container, we
1240 * can't move con next to it - floating containers have only one child - so
1241 * we get the workspace instead. */
1242 if (target->type == CT_FLOATING_CON) {
1243 DLOG("floatingcon, going up even further\n");
1244 orig_target = target;
1245 target = target->parent;
1246 }
1247
1248 if (con->type == CT_FLOATING_CON) {
1249 Con *ws = con_get_workspace(target);
1250 DLOG("This is a floating window, using workspace %p / %s\n", ws, ws->name);
1251 target = ws;
1252 }
1253
1254 if (source_output != dest_output) {
1255 /* Take the relative coordinates of the current output, then add them
1256 * to the coordinate space of the correct output */
1257 if (fix_coordinates && con->type == CT_FLOATING_CON) {
1258 floating_fix_coordinates(con, &(source_output->rect), &(dest_output->rect));
1259 } else
1260 DLOG("Not fixing coordinates, fix_coordinates flag = %d\n", fix_coordinates);
1261 }
1262
1263 /* If moving a fullscreen container and the destination already has a
1264 * fullscreen window on it, un-fullscreen the target's fullscreen con. */
1265 Con *fullscreen = con_get_fullscreen_con(target_ws, CF_OUTPUT);
1266 if (con->fullscreen_mode != CF_NONE && fullscreen != NULL) {
1267 con_toggle_fullscreen(fullscreen, CF_OUTPUT);
1268 fullscreen = NULL;
1269 }
1270
1271 DLOG("Re-attaching container to %p / %s\n", target, target->name);
1272 /* 4: re-attach the con to the parent of this focused container */
1273 Con *parent = con->parent;
1274 con_detach(con);
1275 _con_attach(con, target, behind_focused ? NULL : orig_target, !behind_focused);
1276
1277 /* 5: fix the percentages */
1278 if (fix_percentage) {
1279 con_fix_percent(parent);
1280 con->percent = 0.0;
1281 con_fix_percent(target);
1282 }
1283
1284 /* 6: focus the con on the target workspace, but only within that
1285 * workspace, that is, don’t move focus away if the target workspace is
1286 * invisible.
1287 * We don’t focus the con for i3 pseudo workspaces like __i3_scratch and
1288 * we don’t focus when there is a fullscreen con on that workspace. We
1289 * also don't do it if the caller requested to ignore focus. */
1290 if (!ignore_focus && !con_is_internal(target_ws) && !fullscreen) {
1291 /* We need to save the focused workspace on the output in case the
1292 * new workspace is hidden and it's necessary to immediately switch
1293 * back to the originally-focused workspace. */
1294 Con *old_focus_ws = TAILQ_FIRST(&(output_get_content(dest_output)->focus_head));
1295 Con *old_focus = focused;
1296 con_activate(con_descend_focused(con));
1297
1298 if (old_focus_ws == current_ws && old_focus->type != CT_WORKSPACE) {
1299 /* Restore focus to the currently focused container. */
1300 con_activate(old_focus);
1301 } else if (con_get_workspace(focused) != old_focus_ws) {
1302 /* Restore focus if the output's focused workspace has changed. */
1303 con_focus(con_descend_focused(old_focus_ws));
1304 }
1305 }
1306
1307 /* 7: when moving to another workspace, we leave the focus on the current
1308 * workspace. (see also #809) */
1309 if (!ignore_focus) {
1310 workspace_show(current_ws);
1311 if (dont_warp) {
1312 DLOG("x_set_warp_to(NULL) because dont_warp is set\n");
1313 x_set_warp_to(NULL);
1314 }
1315 }
1316
1317 /* Set focus only if con was on current workspace before moving.
1318 * Otherwise we would give focus to some window on different workspace. */
1319 if (focus_next)
1320 con_activate(con_descend_focused(focus_next));
1321
1322 /* 8. If anything within the container is associated with a startup sequence,
1323 * delete it so child windows won't be created on the old workspace. */
1324 if (!con_is_leaf(con)) {
1325 Con *child;
1326 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
1327 if (!child->window)
1328 continue;
1329 startup_sequence_delete_by_window(child->window);
1330 }
1331 }
1332
1333 if (con->window) {
1334 startup_sequence_delete_by_window(con->window);
1335 }
1336
1337 /* 9. If the container was marked urgent, move the urgency hint. */
1338 if (urgent) {
1339 workspace_update_urgent_flag(source_ws);
1340 con_set_urgency(con, true);
1341 }
1342
1343 /* Ensure the container will be redrawn. */
1344 FREE(con->deco_render_params);
1345
1346 CALL(parent, on_remove_child);
1347
1348 ipc_send_window_event("move", con);
1349 ewmh_update_wm_desktop();
1350 return true;
1351 }
1352
1353 /*
1354 * Moves the given container to the given mark.
1355 *
1356 */
1357 bool con_move_to_mark(Con *con, const char *mark) {
1358 Con *target = con_by_mark(mark);
1359 if (target == NULL) {
1360 DLOG("found no container with mark \"%s\"\n", mark);
1361 return false;
1362 }
1363
1364 /* For target containers in the scratchpad, we just send the window to the scratchpad. */
1365 if (con_get_workspace(target) == workspace_get("__i3_scratch", NULL)) {
1366 DLOG("target container is in the scratchpad, moving container to scratchpad.\n");
1367 scratchpad_move(con);
1368 return true;
1369 }
1370
1371 /* For floating target containers, we just send the window to the same workspace. */
1372 if (con_is_floating(target)) {
1373 DLOG("target container is floating, moving container to target's workspace.\n");
1374 con_move_to_workspace(con, con_get_workspace(target), true, false, false);
1375 return true;
1376 }
1377
1378 if (target->type == CT_WORKSPACE && con_is_leaf(target)) {
1379 DLOG("target container is an empty workspace, simply moving the container there.\n");
1380 con_move_to_workspace(con, target, true, false, false);
1381 return true;
1382 }
1383
1384 /* For split containers, we use the currently focused container within it.
1385 * This allows setting marks on, e.g., tabbed containers which will move
1386 * con to a new tab behind the focused tab. */
1387 if (con_is_split(target)) {
1388 DLOG("target is a split container, descending to the currently focused child.\n");
1389 target = TAILQ_FIRST(&(target->focus_head));
1390 }
1391
1392 if (con == target || con_has_parent(target, con)) {
1393 DLOG("cannot move the container to or inside itself, aborting.\n");
1394 return false;
1395 }
1396
1397 return _con_move_to_con(con, target, false, true, false, false, true);
1398 }
1399
1400 /*
1401 * Moves the given container to the currently focused container on the given
1402 * workspace.
1403 *
1404 * The fix_coordinates flag will translate the current coordinates (offset from
1405 * the monitor position basically) to appropriate coordinates on the
1406 * destination workspace.
1407 * Not enabling this behaviour comes in handy when this function gets called by
1408 * floating_maybe_reassign_ws, which will only "move" a floating window when it
1409 * *already* changed its coordinates to a different output.
1410 *
1411 * The dont_warp flag disables pointer warping and will be set when this
1412 * function is called while dragging a floating window.
1413 *
1414 * If ignore_focus is set, the container will be moved without modifying focus
1415 * at all.
1416 *
1417 * TODO: is there a better place for this function?
1418 *
1419 */
1420 void con_move_to_workspace(Con *con, Con *workspace, bool fix_coordinates, bool dont_warp, bool ignore_focus) {
1421 assert(workspace->type == CT_WORKSPACE);
1422
1423 Con *source_ws = con_get_workspace(con);
1424 if (workspace == source_ws) {
1425 DLOG("Not moving, already there\n");
1426 return;
1427 }
1428
1429 Con *target = con_descend_focused(workspace);
1430 _con_move_to_con(con, target, true, fix_coordinates, dont_warp, ignore_focus, true);
1431 }
1432
1433 /*
1434 * Moves the given container to the currently focused container on the
1435 * visible workspace on the given output.
1436 *
1437 */
1438 void con_move_to_output(Con *con, Output *output, bool fix_coordinates) {
1439 Con *ws = NULL;
1440 GREP_FIRST(ws, output_get_content(output->con), workspace_is_visible(child));
1441 assert(ws != NULL);
1442 DLOG("Moving con %p to output %s\n", con, output_primary_name(output));
1443 con_move_to_workspace(con, ws, fix_coordinates, false, false);
1444 }
1445
1446 /*
1447 * Moves the given container to the currently focused container on the
1448 * visible workspace on the output specified by the given name.
1449 * The current output for the container is used to resolve relative names
1450 * such as left, right, up, down.
1451 *
1452 */
1453 bool con_move_to_output_name(Con *con, const char *name, bool fix_coordinates) {
1454 Output *current_output = get_output_for_con(con);
1455 Output *output = get_output_from_string(current_output, name);
1456 if (output == NULL) {
1457 ELOG("Could not find output \"%s\"\n", name);
1458 return false;
1459 }
1460
1461 con_move_to_output(con, output, fix_coordinates);
1462 return true;
1463 }
1464
1465 /*
1466 * Returns the orientation of the given container (for stacked containers,
1467 * vertical orientation is used regardless of the actual orientation of the
1468 * container).
1469 *
1470 */
1471 orientation_t con_orientation(Con *con) {
1472 switch (con->layout) {
1473 case L_SPLITV:
1474 /* stacking containers behave like they are in vertical orientation */
1475 case L_STACKED:
1476 return VERT;
1477
1478 case L_SPLITH:
1479 /* tabbed containers behave like they are in vertical orientation */
1480 case L_TABBED:
1481 return HORIZ;
1482
1483 case L_DEFAULT:
1484 ELOG("Someone called con_orientation() on a con with L_DEFAULT, this is a bug in the code.\n");
1485 assert(false);
1486
1487 case L_DOCKAREA:
1488 case L_OUTPUT:
1489 ELOG("con_orientation() called on dockarea/output (%d) container %p\n", con->layout, con);
1490 assert(false);
1491 }
1492 /* should not be reached */
1493 assert(false);
1494 }
1495
1496 /*
1497 * Returns the container which will be focused next when the given container
1498 * is not available anymore. Called in tree_close_internal and con_move_to_workspace
1499 * to properly restore focus.
1500 *
1501 */
1502 Con *con_next_focused(Con *con) {
1503 /* dock clients cannot be focused, so we focus the workspace instead */
1504 if (con->parent->type == CT_DOCKAREA) {
1505 DLOG("selecting workspace for dock client\n");
1506 return con_descend_focused(output_get_content(con->parent->parent));
1507 }
1508 if (con_is_floating(con)) {
1509 con = con->parent;
1510 }
1511
1512 /* if 'con' is not the first entry in the focus stack, use the first one as
1513 * it’s currently focused already */
1514 Con *next = TAILQ_FIRST(&(con->parent->focus_head));
1515 if (next != con) {
1516 DLOG("Using first entry %p\n", next);
1517 } else {
1518 /* try to focus the next container on the same level as this one or fall
1519 * back to its parent */
1520 if (!(next = TAILQ_NEXT(con, focused))) {
1521 next = con->parent;
1522 }
1523 }
1524
1525 /* now go down the focus stack as far as
1526 * possible, excluding the current container */
1527 while (!TAILQ_EMPTY(&(next->focus_head)) && TAILQ_FIRST(&(next->focus_head)) != con) {
1528 next = TAILQ_FIRST(&(next->focus_head));
1529 }
1530
1531 if (con->type == CT_FLOATING_CON && next != con->parent) {
1532 next = con_descend_focused(next);
1533 }
1534
1535 return next;
1536 }
1537
1538 /*
1539 * Returns the focused con inside this client, descending the tree as far as
1540 * possible. This comes in handy when attaching a con to a workspace at the
1541 * currently focused position, for example.
1542 *
1543 */
1544 Con *con_descend_focused(Con *con) {
1545 Con *next = con;
1546 while (next != focused && !TAILQ_EMPTY(&(next->focus_head)))
1547 next = TAILQ_FIRST(&(next->focus_head));
1548 return next;
1549 }
1550
1551 /*
1552 * Returns the focused con inside this client, descending the tree as far as
1553 * possible. This comes in handy when attaching a con to a workspace at the
1554 * currently focused position, for example.
1555 *
1556 * Works like con_descend_focused but considers only tiling cons.
1557 *
1558 */
1559 Con *con_descend_tiling_focused(Con *con) {
1560 Con *next = con;
1561 Con *before;
1562 Con *child;
1563 if (next == focused)
1564 return next;
1565 do {
1566 before = next;
1567 TAILQ_FOREACH (child, &(next->focus_head), focused) {
1568 if (child->type == CT_FLOATING_CON)
1569 continue;
1570
1571 next = child;
1572 break;
1573 }
1574 } while (before != next && next != focused);
1575 return next;
1576 }
1577
1578 /*
1579 * Returns the leftmost, rightmost, etc. container in sub-tree. For example, if
1580 * direction is D_LEFT, then we return the rightmost container and if direction
1581 * is D_RIGHT, we return the leftmost container. This is because if we are
1582 * moving D_LEFT, and thus want the rightmost container.
1583 *
1584 */
1585 Con *con_descend_direction(Con *con, direction_t direction) {
1586 Con *most = NULL;
1587 Con *current;
1588 int orientation = con_orientation(con);
1589 DLOG("con_descend_direction(%p, orientation %d, direction %d)\n", con, orientation, direction);
1590 if (direction == D_LEFT || direction == D_RIGHT) {
1591 if (orientation == HORIZ) {
1592 /* If the direction is horizontal, we can use either the first
1593 * (D_RIGHT) or the last con (D_LEFT) */
1594 if (direction == D_RIGHT)
1595 most = TAILQ_FIRST(&(con->nodes_head));
1596 else
1597 most = TAILQ_LAST(&(con->nodes_head), nodes_head);
1598 } else if (orientation == VERT) {
1599 /* Wrong orientation. We use the last focused con. Within that con,
1600 * we recurse to chose the left/right con or at least the last
1601 * focused one. */
1602 TAILQ_FOREACH (current, &(con->focus_head), focused) {
1603 if (current->type != CT_FLOATING_CON) {
1604 most = current;
1605 break;
1606 }
1607 }
1608 } else {
1609 /* If the con has no orientation set, it’s not a split container
1610 * but a container with a client window, so stop recursing */
1611 return con;
1612 }
1613 }
1614
1615 if (direction == D_UP || direction == D_DOWN) {
1616 if (orientation == VERT) {
1617 /* If the direction is vertical, we can use either the first
1618 * (D_DOWN) or the last con (D_UP) */
1619 if (direction == D_UP)
1620 most = TAILQ_LAST(&(con->nodes_head), nodes_head);
1621 else
1622 most = TAILQ_FIRST(&(con->nodes_head));
1623 } else if (orientation == HORIZ) {
1624 /* Wrong orientation. We use the last focused con. Within that con,
1625 * we recurse to chose the top/bottom con or at least the last
1626 * focused one. */
1627 TAILQ_FOREACH (current, &(con->focus_head), focused) {
1628 if (current->type != CT_FLOATING_CON) {
1629 most = current;
1630 break;
1631 }
1632 }
1633 } else {
1634 /* If the con has no orientation set, it’s not a split container
1635 * but a container with a client window, so stop recursing */
1636 return con;
1637 }
1638 }
1639
1640 if (!most)
1641 return con;
1642 return con_descend_direction(most, direction);
1643 }
1644
1645 static bool has_outer_gaps(gaps_t gaps) {
1646 return gaps.top > 0 ||
1647 gaps.right > 0 ||
1648 gaps.bottom > 0 ||
1649 gaps.left > 0;
1650 }
1651
1652 /*
1653 * Returns a "relative" Rect which contains the amount of pixels that need to
1654 * be added to the original Rect to get the final position (obviously the
1655 * amount of pixels for normal, 1pixel and borderless are different).
1656 *
1657 */
1658 Rect con_border_style_rect(Con *con) {
1659 if ((config.smart_borders == SMART_BORDERS_ON && con_num_visible_children(con_get_workspace(con)) <= 1) ||
1660 (config.smart_borders == SMART_BORDERS_NO_GAPS && !has_outer_gaps(calculate_effective_gaps(con))) ||
1661 (config.hide_edge_borders == HEBM_SMART && con_num_visible_children(con_get_workspace(con)) <= 1) ||
1662 (config.hide_edge_borders == HEBM_SMART_NO_GAPS && con_num_visible_children(con_get_workspace(con)) <= 1 && !has_outer_gaps(calculate_effective_gaps(con)))) {
1663 if (!con_is_floating(con))
1664 return (Rect){0, 0, 0, 0};
1665 }
1666
1667 adjacent_t borders_to_hide = ADJ_NONE;
1668 int border_width = con->current_border_width;
1669 DLOG("The border width for con is set to: %d\n", con->current_border_width);
1670 Rect result;
1671 if (con->current_border_width < 0) {
1672 if (con_is_floating(con)) {
1673 border_width = config.default_floating_border_width;
1674 } else {
1675 border_width = config.default_border_width;
1676 }
1677 }
1678 DLOG("Effective border width is set to: %d\n", border_width);
1679 /* Shortcut to avoid calling con_adjacent_borders() on dock containers. */
1680 int border_style = con_border_style(con);
1681 if (border_style == BS_NONE)
1682 return (Rect){0, 0, 0, 0};
1683 if (border_style == BS_NORMAL) {
1684 result = (Rect){border_width, 0, -(2 * border_width), -(border_width)};
1685 } else {
1686 result = (Rect){border_width, border_width, -(2 * border_width), -(2 * border_width)};
1687 }
1688
1689 /* If hide_edge_borders is set to no_gaps and it did not pass the no border check, show all borders */
1690 if (config.hide_edge_borders == HEBM_SMART_NO_GAPS) {
1691 borders_to_hide = con_adjacent_borders(con) & HEBM_NONE;
1692 } else {
1693 borders_to_hide = con_adjacent_borders(con) & config.hide_edge_borders;
1694 }
1695
1696 if (borders_to_hide & ADJ_LEFT_SCREEN_EDGE) {
1697 result.x -= border_width;
1698 result.width += border_width;
1699 }
1700 if (borders_to_hide & ADJ_RIGHT_SCREEN_EDGE) {
1701 result.width += border_width;
1702 }
1703 if (borders_to_hide & ADJ_UPPER_SCREEN_EDGE && (border_style != BS_NORMAL)) {
1704 result.y -= border_width;
1705 result.height += border_width;
1706 }
1707 if (borders_to_hide & ADJ_LOWER_SCREEN_EDGE) {
1708 result.height += border_width;
1709 }
1710 return result;
1711 }
1712
1713 /*
1714 * Returns adjacent borders of the window. We need this if hide_edge_borders is
1715 * enabled.
1716 */
1717 adjacent_t con_adjacent_borders(Con *con) {
1718 adjacent_t result = ADJ_NONE;
1719 /* Floating windows are never adjacent to any other window, so
1720 don’t hide their border(s). This prevents bug #998. */
1721 if (con_is_floating(con))
1722 return result;
1723
1724 Con *workspace = con_get_workspace(con);
1725 if (con->rect.x == workspace->rect.x)
1726 result |= ADJ_LEFT_SCREEN_EDGE;
1727 if (con->rect.x + con->rect.width == workspace->rect.x + workspace->rect.width)
1728 result |= ADJ_RIGHT_SCREEN_EDGE;
1729 if (con->rect.y == workspace->rect.y)
1730 result |= ADJ_UPPER_SCREEN_EDGE;
1731 if (con->rect.y + con->rect.height == workspace->rect.y + workspace->rect.height)
1732 result |= ADJ_LOWER_SCREEN_EDGE;
1733 return result;
1734 }
1735
1736 /*
1737 * Use this function to get a container’s border style. This is important
1738 * because when inside a stack, the border style is always BS_NORMAL.
1739 * For tabbed mode, the same applies, with one exception: when the container is
1740 * borderless and the only element in the tabbed container, the border is not
1741 * rendered.
1742 *
1743 * For children of a CT_DOCKAREA, the border style is always none.
1744 *
1745 */
1746 int con_border_style(Con *con) {
1747 if (con->fullscreen_mode == CF_OUTPUT || con->fullscreen_mode == CF_GLOBAL) {
1748 DLOG("this one is fullscreen! overriding BS_NONE\n");
1749 return BS_NONE;
1750 }
1751
1752 if (con->parent->layout == L_STACKED)
1753 return (con_num_children(con->parent) == 1 ? con->border_style : BS_NORMAL);
1754
1755 if (con->parent->layout == L_TABBED && con->border_style != BS_NORMAL)
1756 return (con_num_children(con->parent) == 1 ? con->border_style : BS_NORMAL);
1757
1758 if (con->parent->type == CT_DOCKAREA)
1759 return BS_NONE;
1760
1761 return con->border_style;
1762 }
1763
1764 /*
1765 * Sets the given border style on con, correctly keeping the position/size of a
1766 * floating window.
1767 *
1768 */
1769 void con_set_border_style(Con *con, int border_style, int border_width) {
1770 /* Handle the simple case: non-floating containerns */
1771 if (!con_is_floating(con)) {
1772 con->border_style = border_style;
1773 con->current_border_width = border_width;
1774 return;
1775 }
1776
1777 /* For floating containers, we want to keep the position/size of the
1778 * *window* itself. We first add the border pixels to con->rect to make
1779 * con->rect represent the absolute position of the window (same for
1780 * parent). Then, we change the border style and subtract the new border
1781 * pixels. For the parent, we do the same also for the decoration. */
1782 DLOG("This is a floating container\n");
1783
1784 Con *parent = con->parent;
1785 Rect bsr = con_border_style_rect(con);
1786 int deco_height = (con->border_style == BS_NORMAL ? render_deco_height() : 0);
1787
1788 con->rect = rect_add(con->rect, bsr);
1789 parent->rect = rect_add(parent->rect, bsr);
1790 parent->rect.y += deco_height;
1791 parent->rect.height -= deco_height;
1792
1793 /* Change the border style, get new border/decoration values. */
1794 con->border_style = border_style;
1795 con->current_border_width = border_width;
1796 bsr = con_border_style_rect(con);
1797 deco_height = (con->border_style == BS_NORMAL ? render_deco_height() : 0);
1798
1799 con->rect = rect_sub(con->rect, bsr);
1800 parent->rect = rect_sub(parent->rect, bsr);
1801 parent->rect.y -= deco_height;
1802 parent->rect.height += deco_height;
1803 }
1804
1805 /*
1806 * This function changes the layout of a given container. Use it to handle
1807 * special cases like changing a whole workspace to stacked/tabbed (creates a
1808 * new split container before).
1809 *
1810 */
1811 void con_set_layout(Con *con, layout_t layout) {
1812 DLOG("con_set_layout(%p, %d), con->type = %d\n",
1813 con, layout, con->type);
1814
1815 /* Users can focus workspaces, but not any higher in the hierarchy.
1816 * Focus on the workspace is a special case, since in every other case, the
1817 * user means "change the layout of the parent split container". */
1818 if (con->type != CT_WORKSPACE)
1819 con = con->parent;
1820
1821 /* We fill in last_split_layout when switching to a different layout
1822 * since there are many places in the code that don’t use
1823 * con_set_layout(). */
1824 if (con->layout == L_SPLITH || con->layout == L_SPLITV)
1825 con->last_split_layout = con->layout;
1826
1827 /* When the container type is CT_WORKSPACE, the user wants to change the
1828 * whole workspace into stacked/tabbed mode. To do this and still allow
1829 * intuitive operations (like level-up and then opening a new window), we
1830 * need to create a new split container. */
1831 if (con->type == CT_WORKSPACE) {
1832 if (con_num_children(con) == 0) {
1833 layout_t ws_layout = (layout == L_STACKED || layout == L_TABBED) ? layout : L_DEFAULT;
1834 DLOG("Setting workspace_layout to %d\n", ws_layout);
1835 con->workspace_layout = ws_layout;
1836 DLOG("Setting layout to %d\n", layout);
1837 con->layout = layout;
1838 } else if (layout == L_STACKED || layout == L_TABBED || layout == L_SPLITV || layout == L_SPLITH) {
1839 DLOG("Creating new split container\n");
1840 /* 1: create a new split container */
1841 Con *new = con_new(NULL, NULL);
1842 new->parent = con;
1843
1844 /* 2: Set the requested layout on the split container and mark it as
1845 * split. */
1846 new->layout = layout;
1847 new->last_split_layout = con->last_split_layout;
1848
1849 /* 3: move the existing cons of this workspace below the new con */
1850 Con **focus_order = get_focus_order(con);
1851
1852 DLOG("Moving cons\n");
1853 Con *child;
1854 while (!TAILQ_EMPTY(&(con->nodes_head))) {
1855 child = TAILQ_FIRST(&(con->nodes_head));
1856 con_detach(child);
1857 con_attach(child, new, true);
1858 }
1859
1860 set_focus_order(new, focus_order);
1861 free(focus_order);
1862
1863 /* 4: attach the new split container to the workspace */
1864 DLOG("Attaching new split to ws\n");
1865 con_attach(new, con, false);
1866
1867 tree_flatten(croot);
1868 }
1869 con_force_split_parents_redraw(con);
1870 return;
1871 }
1872
1873 if (layout == L_DEFAULT) {
1874 /* Special case: the layout formerly known as "default" (in combination
1875 * with an orientation). Since we switched to splith/splitv layouts,
1876 * using the "default" layout (which "only" should happen when using
1877 * legacy configs) is using the last split layout (either splith or
1878 * splitv) in order to still do the same thing. */
1879 con->layout = con->last_split_layout;
1880 /* In case last_split_layout was not initialized… */
1881 if (con->layout == L_DEFAULT)
1882 con->layout = L_SPLITH;
1883 } else {
1884 con->layout = layout;
1885 }
1886 con_force_split_parents_redraw(con);
1887 }
1888
1889 /*
1890 * This function toggles the layout of a given container. toggle_mode can be
1891 * either 'default' (toggle only between stacked/tabbed/last_split_layout),
1892 * 'split' (toggle only between splitv/splith) or 'all' (toggle between all
1893 * layouts).
1894 *
1895 */
1896 void con_toggle_layout(Con *con, const char *toggle_mode) {
1897 Con *parent = con;
1898 /* Users can focus workspaces, but not any higher in the hierarchy.
1899 * Focus on the workspace is a special case, since in every other case, the
1900 * user means "change the layout of the parent split container". */
1901 if (con->type != CT_WORKSPACE)
1902 parent = con->parent;
1903 DLOG("con_toggle_layout(%p, %s), parent = %p\n", con, toggle_mode, parent);
1904
1905 const char delim[] = " ";
1906
1907 if (strcasecmp(toggle_mode, "split") == 0 || strstr(toggle_mode, delim)) {
1908 /* L_DEFAULT is used as a placeholder value to distinguish if
1909 * the first layout has already been saved. (it can never be L_DEFAULT) */
1910 layout_t new_layout = L_DEFAULT;
1911 bool current_layout_found = false;
1912 char *tm_dup = sstrdup(toggle_mode);
1913 char *cur_tok = strtok(tm_dup, delim);
1914
1915 for (layout_t layout; cur_tok != NULL; cur_tok = strtok(NULL, delim)) {
1916 if (strcasecmp(cur_tok, "split") == 0) {
1917 /* Toggle between splits. When the current layout is not a split
1918 * layout, we just switch back to last_split_layout. Otherwise, we
1919 * change to the opposite split layout. */
1920 if (parent->layout != L_SPLITH && parent->layout != L_SPLITV) {
1921 layout = parent->last_split_layout;
1922 /* In case last_split_layout was not initialized… */
1923 if (layout == L_DEFAULT) {
1924 layout = L_SPLITH;
1925 }
1926 } else {
1927 layout = (parent->layout == L_SPLITH) ? L_SPLITV : L_SPLITH;
1928 }
1929 } else {
1930 bool success = layout_from_name(cur_tok, &layout);
1931 if (!success || layout == L_DEFAULT) {
1932 ELOG("The token '%s' was not recognized and has been skipped.\n", cur_tok);
1933 continue;
1934 }
1935 }
1936
1937 /* If none of the specified layouts match the current,
1938 * fall back to the first layout in the list */
1939 if (new_layout == L_DEFAULT) {
1940 new_layout = layout;
1941 }
1942
1943 /* We found the active layout in the last iteration, so
1944 * now let's activate the current layout (next in list) */
1945 if (current_layout_found) {
1946 new_layout = layout;
1947 break;
1948 }
1949
1950 if (parent->layout == layout) {
1951 current_layout_found = true;
1952 }
1953 }
1954 free(tm_dup);
1955
1956 if (new_layout != L_DEFAULT) {
1957 con_set_layout(con, new_layout);
1958 }
1959 } else if (strcasecmp(toggle_mode, "all") == 0 || strcasecmp(toggle_mode, "default") == 0) {
1960 if (parent->layout == L_STACKED)
1961 con_set_layout(con, L_TABBED);
1962 else if (parent->layout == L_TABBED) {
1963 if (strcasecmp(toggle_mode, "all") == 0)
1964 con_set_layout(con, L_SPLITH);
1965 else
1966 con_set_layout(con, parent->last_split_layout);
1967 } else if (parent->layout == L_SPLITH || parent->layout == L_SPLITV) {
1968 if (strcasecmp(toggle_mode, "all") == 0) {
1969 /* When toggling through all modes, we toggle between
1970 * splith/splitv, whereas normally we just directly jump to
1971 * stacked. */
1972 if (parent->layout == L_SPLITH)
1973 con_set_layout(con, L_SPLITV);
1974 else
1975 con_set_layout(con, L_STACKED);
1976 } else {
1977 con_set_layout(con, L_STACKED);
1978 }
1979 }
1980 }
1981 }
1982
1983 /*
1984 * Callback which will be called when removing a child from the given con.
1985 * Kills the container if it is empty and replaces it with the child if there
1986 * is exactly one child.
1987 *
1988 */
1989 static void con_on_remove_child(Con *con) {
1990 DLOG("on_remove_child\n");
1991
1992 /* Every container 'above' (in the hierarchy) the workspace content should
1993 * not be closed when the last child was removed */
1994 if (con->type == CT_OUTPUT ||
1995 con->type == CT_ROOT ||
1996 con->type == CT_DOCKAREA ||
1997 (con->parent != NULL && con->parent->type == CT_OUTPUT)) {
1998 DLOG("not handling, type = %d, name = %s\n", con->type, con->name);
1999 return;
2000 }
2001
2002 /* For workspaces, close them only if they're not visible anymore */
2003 if (con->type == CT_WORKSPACE) {
2004 if (TAILQ_EMPTY(&(con->focus_head)) && !workspace_is_visible(con)) {
2005 LOG("Closing old workspace (%p / %s), it is empty\n", con, con->name);
2006 yajl_gen gen = ipc_marshal_workspace_event("empty", con, NULL);
2007 tree_close_internal(con, DONT_KILL_WINDOW, false);
2008
2009 const unsigned char *payload;
2010 ylength length;
2011 y(get_buf, &payload, &length);
2012 ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, (const char *)payload);
2013
2014 y(free);
2015 }
2016 return;
2017 }
2018
2019 con_force_split_parents_redraw(con);
2020 con->urgent = con_has_urgent_child(con);
2021 con_update_parents_urgency(con);
2022
2023 /* TODO: check if this container would swallow any other client and
2024 * don’t close it automatically. */
2025 int children = con_num_children(con);
2026 if (children == 0) {
2027 DLOG("Container empty, closing\n");
2028 tree_close_internal(con, DONT_KILL_WINDOW, false);
2029 return;
2030 }
2031 }
2032
2033 /*
2034 * Determines the minimum size of the given con by looking at its children (for
2035 * split/stacked/tabbed cons). Will be called when resizing floating cons
2036 *
2037 */
2038 Rect con_minimum_size(Con *con) {
2039 DLOG("Determining minimum size for con %p\n", con);
2040
2041 if (con_is_leaf(con)) {
2042 DLOG("leaf node, returning 75x50\n");
2043 return (Rect){0, 0, 75, 50};
2044 }
2045
2046 if (con->type == CT_FLOATING_CON) {
2047 DLOG("floating con\n");
2048 Con *child = TAILQ_FIRST(&(con->nodes_head));
2049 return con_minimum_size(child);
2050 }
2051
2052 if (con->layout == L_STACKED || con->layout == L_TABBED) {
2053 uint32_t max_width = 0, max_height = 0, deco_height = 0;
2054 Con *child;
2055 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
2056 Rect min = con_minimum_size(child);
2057 deco_height += child->deco_rect.height;
2058 max_width = max(max_width, min.width);
2059 max_height = max(max_height, min.height);
2060 }
2061 DLOG("stacked/tabbed now, returning %d x %d + deco_rect = %d\n",
2062 max_width, max_height, deco_height);
2063 return (Rect){0, 0, max_width, max_height + deco_height};
2064 }
2065
2066 /* For horizontal/vertical split containers we sum up the width (h-split)
2067 * or height (v-split) and use the maximum of the height (h-split) or width
2068 * (v-split) as minimum size. */
2069 if (con_is_split(con)) {
2070 uint32_t width = 0, height = 0;
2071 Con *child;
2072 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
2073 Rect min = con_minimum_size(child);
2074 if (con->layout == L_SPLITH) {
2075 width += min.width;
2076 height = max(height, min.height);
2077 } else {
2078 height += min.height;
2079 width = max(width, min.width);
2080 }
2081 }
2082 DLOG("split container, returning width = %d x height = %d\n", width, height);
2083 return (Rect){0, 0, width, height};
2084 }
2085
2086 ELOG("Unhandled case, type = %d, layout = %d, split = %d\n",
2087 con->type, con->layout, con_is_split(con));
2088 assert(false);
2089 }
2090
2091 /*
2092 * Returns true if changing the focus to con would be allowed considering
2093 * the fullscreen focus constraints. Specifically, if a fullscreen container or
2094 * any of its descendants is focused, this function returns true if and only if
2095 * focusing con would mean that focus would still be visible on screen, i.e.,
2096 * the newly focused container would not be obscured by a fullscreen container.
2097 *
2098 * In the simplest case, if a fullscreen container or any of its descendants is
2099 * fullscreen, this functions returns true if con is the fullscreen container
2100 * itself or any of its descendants, as this means focus wouldn't escape the
2101 * boundaries of the fullscreen container.
2102 *
2103 * In case the fullscreen container is of type CF_OUTPUT, this function returns
2104 * true if con is on a different workspace, as focus wouldn't be obscured by
2105 * the fullscreen container that is constrained to a different workspace.
2106 *
2107 * Note that this same logic can be applied to moving containers. If a
2108 * container can be focused under the fullscreen focus constraints, it can also
2109 * become a parent or sibling to the currently focused container.
2110 *
2111 */
2112 bool con_fullscreen_permits_focusing(Con *con) {
2113 /* No focus, no problem. */
2114 if (!focused)
2115 return true;
2116
2117 /* Find the first fullscreen ascendent. */
2118 Con *fs = focused;
2119 while (fs && fs->fullscreen_mode == CF_NONE)
2120 fs = fs->parent;
2121
2122 /* fs must be non-NULL since the workspace con doesn’t have CF_NONE and
2123 * there always has to be a workspace con in the hierarchy. */
2124 assert(fs != NULL);
2125 /* The most common case is we hit the workspace level. In this
2126 * situation, changing focus is also harmless. */
2127 assert(fs->fullscreen_mode != CF_NONE);
2128 if (fs->type == CT_WORKSPACE)
2129 return true;
2130
2131 /* Allow it if the container itself is the fullscreen container. */
2132 if (con == fs)
2133 return true;
2134
2135 /* If fullscreen is per-output, the focus being in a different workspace is
2136 * sufficient to guarantee that change won't leave fullscreen in bad shape. */
2137 if (fs->fullscreen_mode == CF_OUTPUT &&
2138 con_get_workspace(con) != con_get_workspace(fs)) {
2139 return true;
2140 }
2141
2142 /* Allow it only if the container to be focused is contained within the
2143 * current fullscreen container. */
2144 return con_has_parent(con, fs);
2145 }
2146
2147 /*
2148 *
2149 * Checks if the given container has an urgent child.
2150 *
2151 */
2152 bool con_has_urgent_child(Con *con) {
2153 Con *child;
2154
2155 if (con_is_leaf(con))
2156 return con->urgent;
2157
2158 /* We are not interested in floating windows since they can only be
2159 * attached to a workspace → nodes_head instead of focus_head */
2160 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
2161 if (con_has_urgent_child(child))
2162 return true;
2163 }
2164
2165 return false;
2166 }
2167
2168 /*
2169 * Make all parent containers urgent if con is urgent or clear the urgent flag
2170 * of all parent containers if there are no more urgent children left.
2171 *
2172 */
2173 void con_update_parents_urgency(Con *con) {
2174 Con *parent = con->parent;
2175
2176 /* Urgency hints should not be set on any container higher up in the
2177 * hierarchy than the workspace level. Unfortunately, since the content
2178 * container has type == CT_CON, that’s not easy to verify in the loop
2179 * below, so we need another condition to catch that case: */
2180 if (con->type == CT_WORKSPACE)
2181 return;
2182
2183 bool new_urgency_value = con->urgent;
2184 while (parent && parent->type != CT_WORKSPACE && parent->type != CT_DOCKAREA) {
2185 if (new_urgency_value) {
2186 parent->urgent = true;
2187 } else {
2188 /* We can only reset the urgency when the parent
2189 * has no other urgent children */
2190 if (!con_has_urgent_child(parent))
2191 parent->urgent = false;
2192 }
2193 parent = parent->parent;
2194 }
2195 }
2196
2197 /*
2198 * Set urgency flag to the container, all the parent containers and the workspace.
2199 *
2200 */
2201 void con_set_urgency(Con *con, bool urgent) {
2202 if (urgent && focused == con) {
2203 DLOG("Ignoring urgency flag for current client\n");
2204 return;
2205 }
2206
2207 const bool old_urgent = con->urgent;
2208
2209 if (con->urgency_timer == NULL) {
2210 con->urgent = urgent;
2211 } else
2212 DLOG("Discarding urgency WM_HINT because timer is running\n");
2213
2214 //CLIENT_LOG(con);
2215 if (con->window) {
2216 if (con->urgent) {
2217 gettimeofday(&con->window->urgent, NULL);
2218 } else {
2219 con->window->urgent.tv_sec = 0;
2220 con->window->urgent.tv_usec = 0;
2221 }
2222 }
2223
2224 con_update_parents_urgency(con);
2225
2226 Con *ws;
2227 /* Set the urgency flag on the workspace, if a workspace could be found
2228 * (for dock clients, that is not the case). */
2229 if ((ws = con_get_workspace(con)) != NULL)
2230 workspace_update_urgent_flag(ws);
2231
2232 if (con->urgent != old_urgent) {
2233 LOG("Urgency flag changed to %d\n", con->urgent);
2234 ipc_send_window_event("urgent", con);
2235 }
2236 }
2237
2238 /*
2239 * Create a string representing the subtree under con.
2240 *
2241 */
2242 char *con_get_tree_representation(Con *con) {
2243 /* this code works as follows:
2244 * 1) create a string with the layout type (D/V/H/T/S) and an opening bracket
2245 * 2) append the tree representation of the children to the string
2246 * 3) add closing bracket
2247 *
2248 * The recursion ends when we hit a leaf, in which case we return the
2249 * class_instance of the contained window.
2250 */
2251
2252 /* end of recursion */
2253 if (con_is_leaf(con)) {
2254 if (!con->window)
2255 return sstrdup("nowin");
2256
2257 if (!con->window->class_instance)
2258 return sstrdup("noinstance");
2259
2260 return sstrdup(con->window->class_instance);
2261 }
2262
2263 char *buf;
2264 /* 1) add the Layout type to buf */
2265 if (con->layout == L_DEFAULT)
2266 buf = sstrdup("D[");
2267 else if (con->layout == L_SPLITV)
2268 buf = sstrdup("V[");
2269 else if (con->layout == L_SPLITH)
2270 buf = sstrdup("H[");
2271 else if (con->layout == L_TABBED)
2272 buf = sstrdup("T[");
2273 else if (con->layout == L_STACKED)
2274 buf = sstrdup("S[");
2275 else {
2276 ELOG("BUG: Code not updated to account for new layout type\n");
2277 assert(false);
2278 }
2279
2280 /* 2) append representation of children */
2281 Con *child;
2282 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
2283 char *child_txt = con_get_tree_representation(child);
2284
2285 char *tmp_buf;
2286 sasprintf(&tmp_buf, "%s%s%s", buf,
2287 (TAILQ_FIRST(&(con->nodes_head)) == child ? "" : " "), child_txt);
2288 free(buf);
2289 buf = tmp_buf;
2290 free(child_txt);
2291 }
2292
2293 /* 3) close the brackets */
2294 char *complete_buf;
2295 sasprintf(&complete_buf, "%s]", buf);
2296 free(buf);
2297
2298 return complete_buf;
2299 }
2300
2301 /**
2302 * Calculates the effective gap sizes for a container.
2303 */
2304 gaps_t calculate_effective_gaps(Con *con) {
2305 Con *workspace = con_get_workspace(con);
2306 if (workspace == NULL)
2307 return (gaps_t){0, 0, 0, 0, 0};
2308
2309 bool one_child = con_num_visible_children(workspace) <= 1 ||
2310 (con_num_children(workspace) == 1 &&
2311 (TAILQ_FIRST(&(workspace->nodes_head))->layout == L_TABBED ||
2312 TAILQ_FIRST(&(workspace->nodes_head))->layout == L_STACKED));
2313
2314 if (config.smart_gaps == SMART_GAPS_ON && one_child)
2315 return (gaps_t){0, 0, 0, 0, 0};
2316
2317 gaps_t gaps = {
2318 .inner = (workspace->gaps.inner + config.gaps.inner) / 2,
2319 .top = 0,
2320 .right = 0,
2321 .bottom = 0,
2322 .left = 0};
2323
2324 if (config.smart_gaps != SMART_GAPS_INVERSE_OUTER || one_child) {
2325 gaps.top = workspace->gaps.top + config.gaps.top;
2326 gaps.right = workspace->gaps.right + config.gaps.right;
2327 gaps.bottom = workspace->gaps.bottom + config.gaps.bottom;
2328 gaps.left = workspace->gaps.left + config.gaps.left;
2329 }
2330
2331 /* Outer gaps are added on top of inner gaps. */
2332 gaps.top += 2 * gaps.inner;
2333 gaps.right += 2 * gaps.inner;
2334 gaps.bottom += 2 * gaps.inner;
2335 gaps.left += 2 * gaps.inner;
2336
2337 return gaps;
2338 }
2339
2340 /*
2341 * Returns the container's title considering the current title format.
2342 *
2343 */
2344 i3String *con_parse_title_format(Con *con) {
2345 assert(con->title_format != NULL);
2346
2347 i3Window *win = con->window;
2348
2349 /* We need to ensure that we only escape the window title if pango
2350 * is used by the current font. */
2351 const bool pango_markup = font_is_pango();
2352
2353 char *title;
2354 char *class;
2355 char *instance;
2356 if (win == NULL) {
2357 title = pango_escape_markup(con_get_tree_representation(con));
2358 class = sstrdup("i3-frame");
2359 instance = sstrdup("i3-frame");
2360 } else {
2361 title = pango_escape_markup(sstrdup((win->name == NULL) ? "" : i3string_as_utf8(win->name)));
2362 class = pango_escape_markup(sstrdup((win->class_class == NULL) ? "" : win->class_class));
2363 instance = pango_escape_markup(sstrdup((win->class_instance == NULL) ? "" : win->class_instance));
2364 }
2365
2366 placeholder_t placeholders[] = {
2367 {.name = "%title", .value = title},
2368 {.name = "%class", .value = class},
2369 {.name = "%instance", .value = instance}};
2370 const size_t num = sizeof(placeholders) / sizeof(placeholder_t);
2371
2372 char *formatted_str = format_placeholders(con->title_format, &placeholders[0], num);
2373 i3String *formatted = i3string_from_utf8(formatted_str);
2374 i3string_set_markup(formatted, pango_markup);
2375 FREE(formatted_str);
2376
2377 for (size_t i = 0; i < num; i++) {
2378 FREE(placeholders[i].value);
2379 }
2380
2381 return formatted;
2382 }
2383
2384 /*
2385 * Swaps the two containers.
2386 *
2387 */
2388 bool con_swap(Con *first, Con *second) {
2389 assert(first != NULL);
2390 assert(second != NULL);
2391 DLOG("Swapping containers %p / %p\n", first, second);
2392
2393 if (first->type != CT_CON) {
2394 ELOG("Only regular containers can be swapped, but found con = %p with type = %d.\n", first, first->type);
2395 return false;
2396 }
2397
2398 if (second->type != CT_CON) {
2399 ELOG("Only regular containers can be swapped, but found con = %p with type = %d.\n", second, second->type);
2400 return false;
2401 }
2402
2403 if (first == second) {
2404 DLOG("Swapping container %p with itself, nothing to do.\n", first);
2405 return false;
2406 }
2407
2408 if (con_has_parent(first, second) || con_has_parent(second, first)) {
2409 ELOG("Cannot swap containers %p and %p because they are in a parent-child relationship.\n", first, second);
2410 return false;
2411 }
2412
2413 Con *ws1 = con_get_workspace(first);
2414 Con *ws2 = con_get_workspace(second);
2415 Con *restore_focus = NULL;
2416 if (ws1 == ws2 && ws1 == con_get_workspace(focused)) {
2417 /* Preserve focus in the current workspace. */
2418 restore_focus = focused;
2419 } else if (first == focused || con_has_parent(focused, first)) {
2420 restore_focus = second;
2421 } else if (second == focused || con_has_parent(focused, second)) {
2422 restore_focus = first;
2423 }
2424
2425 #define SWAP_CONS_IN_TREE(headname, field) \
2426 do { \
2427 struct headname *head1 = &(first->parent->headname); \
2428 struct headname *head2 = &(second->parent->headname); \
2429 Con *first_prev = TAILQ_PREV(first, headname, field); \
2430 Con *second_prev = TAILQ_PREV(second, headname, field); \
2431 if (second_prev == first) { \
2432 TAILQ_SWAP(first, second, head1, field); \
2433 } else if (first_prev == second) { \
2434 TAILQ_SWAP(second, first, head1, field); \
2435 } else { \
2436 TAILQ_REMOVE(head1, first, field); \
2437 TAILQ_REMOVE(head2, second, field); \
2438 if (second_prev == NULL) { \
2439 TAILQ_INSERT_HEAD(head2, first, field); \
2440 } else { \
2441 TAILQ_INSERT_AFTER(head2, second_prev, first, field); \
2442 } \
2443 if (first_prev == NULL) { \
2444 TAILQ_INSERT_HEAD(head1, second, field); \
2445 } else { \
2446 TAILQ_INSERT_AFTER(head1, first_prev, second, field); \
2447 } \
2448 } \
2449 } while (0)
2450
2451 SWAP_CONS_IN_TREE(nodes_head, nodes);
2452 SWAP_CONS_IN_TREE(focus_head, focused);
2453 SWAP(first->parent, second->parent, Con *);
2454
2455 /* Floating nodes are children of CT_FLOATING_CONs, they are listed in
2456 * nodes_head and focus_head like all other containers. Thus, we don't need
2457 * to do anything special other than swapping the floating status and the
2458 * relevant rects. */
2459 SWAP(first->floating, second->floating, int);
2460 SWAP(first->rect, second->rect, Rect);
2461 SWAP(first->window_rect, second->window_rect, Rect);
2462
2463 /* We need to copy each other's percentages to ensure that the geometry
2464 * doesn't change during the swap. */
2465 SWAP(first->percent, second->percent, double);
2466
2467 if (restore_focus) {
2468 con_focus(restore_focus);
2469 }
2470
2471 /* Update new parents' & workspaces' urgency. */
2472 con_set_urgency(first, first->urgent);
2473 con_set_urgency(second, second->urgent);
2474
2475 /* Exchange fullscreen modes, can't use SWAP because we need to call the
2476 * correct functions. */
2477 fullscreen_mode_t second_fullscreen_mode = second->fullscreen_mode;
2478 if (first->fullscreen_mode == CF_NONE) {
2479 con_disable_fullscreen(second);
2480 } else {
2481 con_enable_fullscreen(second, first->fullscreen_mode);
2482 }
2483 if (second_fullscreen_mode == CF_NONE) {
2484 con_disable_fullscreen(first);
2485 } else {
2486 con_enable_fullscreen(first, second_fullscreen_mode);
2487 }
2488
2489 /* We don't actually need this since percentages-wise we haven't changed
2490 * anything, but we'll better be safe than sorry and just make sure as we'd
2491 * otherwise crash i3. */
2492 con_fix_percent(first->parent);
2493 con_fix_percent(second->parent);
2494
2495 FREE(first->deco_render_params);
2496 FREE(second->deco_render_params);
2497 con_force_split_parents_redraw(first);
2498 con_force_split_parents_redraw(second);
2499
2500 return true;
2501 }
2502
2503 /*
2504 * Returns container's rect size depending on its orientation.
2505 * i.e. its width when horizontal, its height when vertical.
2506 *
2507 */
2508 uint32_t con_rect_size_in_orientation(Con *con) {
2509 return (con_orientation(con) == HORIZ ? con->rect.width : con->rect.height);
2510 }
2511
2512 /*
2513 * Merges container specific data that should move with the window (e.g. marks,
2514 * title format, and the window itself) into another container, and closes the
2515 * old container.
2516 *
2517 */
2518 void con_merge_into(Con *old, Con *new) {
2519 new->window = old->window;
2520 old->window = NULL;
2521
2522 if (old->title_format) {
2523 FREE(new->title_format);
2524 new->title_format = old->title_format;
2525 old->title_format = NULL;
2526 }
2527
2528 if (old->sticky_group) {
2529 FREE(new->sticky_group);
2530 new->sticky_group = old->sticky_group;
2531 old->sticky_group = NULL;
2532 }
2533
2534 new->sticky = old->sticky;
2535
2536 con_set_urgency(new, old->urgent);
2537
2538 mark_t *mark;
2539 TAILQ_FOREACH (mark, &(old->marks_head), marks) {
2540 TAILQ_INSERT_TAIL(&(new->marks_head), mark, marks);
2541 ipc_send_window_event("mark", new);
2542 }
2543 new->mark_changed = (TAILQ_FIRST(&(old->marks_head)) != NULL);
2544 TAILQ_INIT(&(old->marks_head));
2545
2546 tree_close_internal(old, DONT_KILL_WINDOW, false);
2547 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * config.c: Configuration file (calling the parser (src/config_parser.c) with
7 * the correct path, switching key bindings mode).
8 *
9 */
10 #include "all.h"
11
12 #include <xkbcommon/xkbcommon.h>
13
14 char *current_configpath = NULL;
15 char *current_config = NULL;
16 Config config;
17 struct modes_head modes;
18 struct barconfig_head barconfigs = TAILQ_HEAD_INITIALIZER(barconfigs);
19
20 /*
21 * Ungrabs all keys, to be called before re-grabbing the keys because of a
22 * mapping_notify event or a configuration file reload
23 *
24 */
25 void ungrab_all_keys(xcb_connection_t *conn) {
26 DLOG("Ungrabbing all keys\n");
27 xcb_ungrab_key(conn, XCB_GRAB_ANY, root, XCB_BUTTON_MASK_ANY);
28 }
29
30 /*
31 * Sends the current bar configuration as an event to all barconfig_update listeners.
32 *
33 */
34 void update_barconfig(void) {
35 Barconfig *current;
36 TAILQ_FOREACH (current, &barconfigs, configs) {
37 ipc_send_barconfig_update_event(current);
38 }
39 }
40
41 static void free_configuration(void) {
42 assert(conn != NULL);
43
44 /* If we are currently in a binding mode, we first revert to the default
45 * since we have no guarantee that the current mode will even still exist
46 * after parsing the config again. See #2228. */
47 switch_mode("default");
48
49 /* First ungrab the keys */
50 ungrab_all_keys(conn);
51
52 struct Mode *mode;
53 while (!SLIST_EMPTY(&modes)) {
54 mode = SLIST_FIRST(&modes);
55 FREE(mode->name);
56
57 /* Clear the old binding list */
58 while (!TAILQ_EMPTY(mode->bindings)) {
59 Binding *bind = TAILQ_FIRST(mode->bindings);
60 TAILQ_REMOVE(mode->bindings, bind, bindings);
61 binding_free(bind);
62 }
63 FREE(mode->bindings);
64
65 SLIST_REMOVE(&modes, mode, Mode, modes);
66 FREE(mode);
67 }
68
69 while (!TAILQ_EMPTY(&assignments)) {
70 struct Assignment *assign = TAILQ_FIRST(&assignments);
71 if (assign->type == A_TO_WORKSPACE || assign->type == A_TO_WORKSPACE_NUMBER)
72 FREE(assign->dest.workspace);
73 else if (assign->type == A_COMMAND)
74 FREE(assign->dest.command);
75 else if (assign->type == A_TO_OUTPUT)
76 FREE(assign->dest.output);
77 match_free(&(assign->match));
78 TAILQ_REMOVE(&assignments, assign, assignments);
79 FREE(assign);
80 }
81
82 while (!TAILQ_EMPTY(&ws_assignments)) {
83 struct Workspace_Assignment *assign = TAILQ_FIRST(&ws_assignments);
84 FREE(assign->name);
85 FREE(assign->output);
86 TAILQ_REMOVE(&ws_assignments, assign, ws_assignments);
87 FREE(assign);
88 }
89
90 /* Clear bar configs */
91 Barconfig *barconfig;
92 while (!TAILQ_EMPTY(&barconfigs)) {
93 barconfig = TAILQ_FIRST(&barconfigs);
94 FREE(barconfig->id);
95 for (int c = 0; c < barconfig->num_outputs; c++)
96 free(barconfig->outputs[c]);
97
98 while (!TAILQ_EMPTY(&(barconfig->bar_bindings))) {
99 struct Barbinding *binding = TAILQ_FIRST(&(barconfig->bar_bindings));
100 FREE(binding->command);
101 TAILQ_REMOVE(&(barconfig->bar_bindings), binding, bindings);
102 FREE(binding);
103 }
104
105 while (!TAILQ_EMPTY(&(barconfig->tray_outputs))) {
106 struct tray_output_t *tray_output = TAILQ_FIRST(&(barconfig->tray_outputs));
107 FREE(tray_output->output);
108 TAILQ_REMOVE(&(barconfig->tray_outputs), tray_output, tray_outputs);
109 FREE(tray_output);
110 }
111
112 FREE(barconfig->outputs);
113 FREE(barconfig->socket_path);
114 FREE(barconfig->status_command);
115 FREE(barconfig->i3bar_command);
116 FREE(barconfig->font);
117 FREE(barconfig->colors.background);
118 FREE(barconfig->colors.statusline);
119 FREE(barconfig->colors.separator);
120 FREE(barconfig->colors.focused_background);
121 FREE(barconfig->colors.focused_statusline);
122 FREE(barconfig->colors.focused_separator);
123 FREE(barconfig->colors.focused_workspace_border);
124 FREE(barconfig->colors.focused_workspace_bg);
125 FREE(barconfig->colors.focused_workspace_text);
126 FREE(barconfig->colors.active_workspace_border);
127 FREE(barconfig->colors.active_workspace_bg);
128 FREE(barconfig->colors.active_workspace_text);
129 FREE(barconfig->colors.inactive_workspace_border);
130 FREE(barconfig->colors.inactive_workspace_bg);
131 FREE(barconfig->colors.inactive_workspace_text);
132 FREE(barconfig->colors.urgent_workspace_border);
133 FREE(barconfig->colors.urgent_workspace_bg);
134 FREE(barconfig->colors.urgent_workspace_text);
135 FREE(barconfig->colors.binding_mode_border);
136 FREE(barconfig->colors.binding_mode_bg);
137 FREE(barconfig->colors.binding_mode_text);
138 TAILQ_REMOVE(&barconfigs, barconfig, configs);
139 FREE(barconfig);
140 }
141
142 Con *con;
143 TAILQ_FOREACH (con, &all_cons, all_cons) {
144 /* Assignments changed, previously ran assignments are invalid. */
145 if (con->window) {
146 con->window->nr_assignments = 0;
147 FREE(con->window->ran_assignments);
148 }
149 /* Invalidate pixmap caches in case font or colors changed. */
150 FREE(con->deco_render_params);
151 }
152
153 /* Get rid of the current font */
154 free_font();
155
156 free(config.ipc_socket_path);
157 free(config.restart_state_path);
158 free(config.fake_outputs);
159 }
160
161 /*
162 * (Re-)loads the configuration file (sets useful defaults before).
163 *
164 * If you specify override_configpath, only this path is used to look for a
165 * configuration file.
166 *
167 * load_type specifies the type of loading: C_VALIDATE is used to only verify
168 * the correctness of the config file (used with the flag -C). C_LOAD will load
169 * the config for normal use and display errors in the nagbar. C_RELOAD will
170 * also clear the previous config.
171 *
172 */
173 bool load_configuration(const char *override_configpath, config_load_t load_type) {
174 if (load_type == C_RELOAD) {
175 free_configuration();
176 }
177
178 SLIST_INIT(&modes);
179
180 struct Mode *default_mode = scalloc(1, sizeof(struct Mode));
181 default_mode->name = sstrdup("default");
182 default_mode->bindings = scalloc(1, sizeof(struct bindings_head));
183 TAILQ_INIT(default_mode->bindings);
184 SLIST_INSERT_HEAD(&modes, default_mode, modes);
185
186 bindings = default_mode->bindings;
187
188 /* Clear the old config or initialize the data structure */
189 memset(&config, 0, sizeof(config));
190
191 /* Initialize default colors */
192 #define INIT_COLOR(x, cborder, cbackground, ctext, cindicator) \
193 do { \
194 x.border = draw_util_hex_to_color(cborder); \
195 x.background = draw_util_hex_to_color(cbackground); \
196 x.text = draw_util_hex_to_color(ctext); \
197 x.indicator = draw_util_hex_to_color(cindicator); \
198 x.child_border = draw_util_hex_to_color(cbackground); \
199 } while (0)
200
201 config.client.background = draw_util_hex_to_color("#000000");
202 INIT_COLOR(config.client.focused, "#4c7899", "#285577", "#ffffff", "#2e9ef4");
203 INIT_COLOR(config.client.focused_inactive, "#333333", "#5f676a", "#ffffff", "#484e50");
204 INIT_COLOR(config.client.unfocused, "#333333", "#222222", "#888888", "#292d2e");
205 INIT_COLOR(config.client.urgent, "#2f343a", "#900000", "#ffffff", "#900000");
206
207 /* border and indicator color are ignored for placeholder contents */
208 INIT_COLOR(config.client.placeholder, "#000000", "#0c0c0c", "#ffffff", "#000000");
209
210 /* the last argument (indicator color) is ignored for bar colors */
211 INIT_COLOR(config.bar.focused, "#4c7899", "#285577", "#ffffff", "#000000");
212 INIT_COLOR(config.bar.unfocused, "#333333", "#222222", "#888888", "#000000");
213 INIT_COLOR(config.bar.urgent, "#2f343a", "#900000", "#ffffff", "#000000");
214
215 config.show_marks = true;
216
217 config.default_border = BS_NORMAL;
218 config.default_floating_border = BS_NORMAL;
219 config.default_border_width = logical_px(2);
220 config.default_floating_border_width = logical_px(2);
221 /* Set default_orientation to NO_ORIENTATION for auto orientation. */
222 config.default_orientation = NO_ORIENTATION;
223
224 config.gaps.inner = 0;
225 config.gaps.top = 0;
226 config.gaps.right = 0;
227 config.gaps.bottom = 0;
228 config.gaps.left = 0;
229
230 /* Set default urgency reset delay to 500ms */
231 if (config.workspace_urgency_timer == 0)
232 config.workspace_urgency_timer = 0.5;
233
234 config.focus_wrapping = FOCUS_WRAPPING_ON;
235
236 FREE(current_configpath);
237 current_configpath = get_config_path(override_configpath, true);
238 if (current_configpath == NULL) {
239 die("Unable to find the configuration file (looked at "
240 "$XDG_CONFIG_HOME/i3/config, ~/.i3/config, $XDG_CONFIG_DIRS/i3/config "
241 "and " SYSCONFDIR "/i3/config)");
242 }
243 LOG("Parsing configfile %s\n", current_configpath);
244 const bool result = parse_file(current_configpath, load_type != C_VALIDATE);
245
246 if (config.font.type == FONT_TYPE_NONE && load_type != C_VALIDATE) {
247 ELOG("You did not specify required configuration option \"font\"\n");
248 config.font = load_font("fixed", true);
249 set_font(&config.font);
250 }
251
252 if (load_type == C_RELOAD) {
253 translate_keysyms();
254 grab_all_keys(conn);
255 regrab_all_buttons(conn);
256
257 /* Redraw the currently visible decorations on reload, so that the
258 * possibly new drawing parameters changed. */
259 x_deco_recurse(croot);
260 xcb_flush(conn);
261 }
262
263 return result;
264 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * config_directives.c: all config storing functions (see config_parser.c)
7 *
8 */
9 #include "all.h"
10
11 #include <float.h>
12 #include <stdarg.h>
13
14 /*******************************************************************************
15 * Criteria functions.
16 ******************************************************************************/
17
18 static int criteria_next_state;
19
20 /*
21 * Initializes the specified 'Match' data structure and the initial state of
22 * commands.c for matching target windows of a command.
23 *
24 */
25 CFGFUN(criteria_init, int _state) {
26 criteria_next_state = _state;
27
28 DLOG("Initializing criteria, current_match = %p, state = %d\n", current_match, _state);
29 match_free(current_match);
30 match_init(current_match);
31 }
32
33 CFGFUN(criteria_pop_state) {
34 result->next_state = criteria_next_state;
35 }
36
37 /*
38 * Interprets a ctype=cvalue pair and adds it to the current match
39 * specification.
40 *
41 */
42 CFGFUN(criteria_add, const char *ctype, const char *cvalue) {
43 match_parse_property(current_match, ctype, cvalue);
44 }
45
46 /*******************************************************************************
47 * Utility functions
48 ******************************************************************************/
49
50 static bool eval_boolstr(const char *str) {
51 return (strcasecmp(str, "1") == 0 ||
52 strcasecmp(str, "yes") == 0 ||
53 strcasecmp(str, "true") == 0 ||
54 strcasecmp(str, "on") == 0 ||
55 strcasecmp(str, "enable") == 0 ||
56 strcasecmp(str, "active") == 0);
57 }
58
59 /*
60 * A utility function to convert a string containing the group and modifiers to
61 * the corresponding bit mask.
62 */
63 i3_event_state_mask_t event_state_from_str(const char *str) {
64 /* It might be better to use strtok() here, but the simpler strstr() should
65 * do for now. */
66 i3_event_state_mask_t result = 0;
67 if (str == NULL)
68 return result;
69 if (strstr(str, "Mod1") != NULL)
70 result |= XCB_KEY_BUT_MASK_MOD_1;
71 if (strstr(str, "Mod2") != NULL)
72 result |= XCB_KEY_BUT_MASK_MOD_2;
73 if (strstr(str, "Mod3") != NULL)
74 result |= XCB_KEY_BUT_MASK_MOD_3;
75 if (strstr(str, "Mod4") != NULL)
76 result |= XCB_KEY_BUT_MASK_MOD_4;
77 if (strstr(str, "Mod5") != NULL)
78 result |= XCB_KEY_BUT_MASK_MOD_5;
79 if (strstr(str, "Control") != NULL ||
80 strstr(str, "Ctrl") != NULL)
81 result |= XCB_KEY_BUT_MASK_CONTROL;
82 if (strstr(str, "Shift") != NULL)
83 result |= XCB_KEY_BUT_MASK_SHIFT;
84
85 if (strstr(str, "Group1") != NULL)
86 result |= (I3_XKB_GROUP_MASK_1 << 16);
87 if (strstr(str, "Group2") != NULL ||
88 strstr(str, "Mode_switch") != NULL)
89 result |= (I3_XKB_GROUP_MASK_2 << 16);
90 if (strstr(str, "Group3") != NULL)
91 result |= (I3_XKB_GROUP_MASK_3 << 16);
92 if (strstr(str, "Group4") != NULL)
93 result |= (I3_XKB_GROUP_MASK_4 << 16);
94 return result;
95 }
96
97 static char *font_pattern;
98
99 CFGFUN(font, const char *font) {
100 config.font = load_font(font, true);
101 set_font(&config.font);
102
103 /* Save the font pattern for using it as bar font later on */
104 FREE(font_pattern);
105 font_pattern = sstrdup(font);
106 }
107
108 CFGFUN(binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *border, const char *whole_window, const char *exclude_titlebar, const char *command) {
109 configure_binding(bindtype, modifiers, key, release, border, whole_window, exclude_titlebar, command, DEFAULT_BINDING_MODE, false);
110 }
111
112 /*******************************************************************************
113 * Mode handling
114 ******************************************************************************/
115
116 static char *current_mode;
117 static bool current_mode_pango_markup;
118
119 CFGFUN(mode_binding, const char *bindtype, const char *modifiers, const char *key, const char *release, const char *border, const char *whole_window, const char *exclude_titlebar, const char *command) {
120 configure_binding(bindtype, modifiers, key, release, border, whole_window, exclude_titlebar, command, current_mode, current_mode_pango_markup);
121 }
122
123 CFGFUN(enter_mode, const char *pango_markup, const char *modename) {
124 if (strcmp(modename, DEFAULT_BINDING_MODE) == 0) {
125 ELOG("You cannot use the name %s for your mode\n", DEFAULT_BINDING_MODE);
126 return;
127 }
128
129 struct Mode *mode;
130 SLIST_FOREACH (mode, &modes, modes) {
131 if (strcmp(mode->name, modename) == 0) {
132 ELOG("The binding mode with name \"%s\" is defined at least twice.\n", modename);
133 }
134 }
135
136 DLOG("\t now in mode %s\n", modename);
137 FREE(current_mode);
138 current_mode = sstrdup(modename);
139 current_mode_pango_markup = (pango_markup != NULL);
140 }
141
142 CFGFUN(exec, const char *exectype, const char *no_startup_id, const char *command) {
143 struct Autostart *new = smalloc(sizeof(struct Autostart));
144 new->command = sstrdup(command);
145 new->no_startup_id = (no_startup_id != NULL);
146 if (strcmp(exectype, "exec") == 0) {
147 TAILQ_INSERT_TAIL(&autostarts, new, autostarts);
148 } else {
149 TAILQ_INSERT_TAIL(&autostarts_always, new, autostarts_always);
150 }
151 }
152
153 CFGFUN(for_window, const char *command) {
154 if (match_is_empty(current_match)) {
155 ELOG("Match is empty, ignoring this for_window statement\n");
156 return;
157 }
158 DLOG("\t should execute command %s for the criteria mentioned above\n", command);
159 Assignment *assignment = scalloc(1, sizeof(Assignment));
160 assignment->type = A_COMMAND;
161 match_copy(&(assignment->match), current_match);
162 assignment->dest.command = sstrdup(command);
163 TAILQ_INSERT_TAIL(&assignments, assignment, assignments);
164 }
165
166 static void create_gaps_assignment(const char *workspace, const char *scope, gaps_t gaps) {
167 DLOG("Setting gaps for workspace %s", workspace);
168
169 struct Workspace_Assignment *assignment;
170 TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) {
171 if (strcasecmp(assignment->name, workspace) == 0) {
172 if (!strcmp(scope, "inner")) {
173 assignment->gaps.inner = gaps.inner;
174 } else if (!strcmp(scope, "outer")) {
175 assignment->gaps.top = gaps.top;
176 assignment->gaps.right = gaps.right;
177 assignment->gaps.bottom = gaps.bottom;
178 assignment->gaps.left = gaps.left;
179 } else if (!strcmp(scope, "vertical")) {
180 assignment->gaps.top = gaps.top;
181 assignment->gaps.bottom = gaps.bottom;
182 } else if (!strcmp(scope, "horizontal")) {
183 assignment->gaps.right = gaps.right;
184 assignment->gaps.left = gaps.left;
185 } else if (!strcmp(scope, "top")) {
186 assignment->gaps.top = gaps.top;
187 } else if (!strcmp(scope, "right")) {
188 assignment->gaps.right = gaps.right;
189 } else if (!strcmp(scope, "bottom")) {
190 assignment->gaps.bottom = gaps.bottom;
191 } else if (!strcmp(scope, "left")) {
192 assignment->gaps.left = gaps.left;
193 } else {
194 ELOG("Invalid command, cannot process scope %s", scope);
195 }
196
197 return;
198 }
199 }
200
201 // Assignment does not yet exist, let's create it.
202 assignment = scalloc(1, sizeof(struct Workspace_Assignment));
203 assignment->name = sstrdup(workspace);
204 assignment->output = NULL;
205 if (!strcmp(scope, "inner")) {
206 assignment->gaps.inner = gaps.inner;
207 } else if (!strcmp(scope, "outer")) {
208 assignment->gaps.top = gaps.top;
209 assignment->gaps.right = gaps.right;
210 assignment->gaps.bottom = gaps.bottom;
211 assignment->gaps.left = gaps.left;
212 } else if (!strcmp(scope, "vertical")) {
213 assignment->gaps.top = gaps.top;
214 assignment->gaps.bottom = gaps.bottom;
215 } else if (!strcmp(scope, "horizontal")) {
216 assignment->gaps.right = gaps.right;
217 assignment->gaps.left = gaps.left;
218 } else if (!strcmp(scope, "top")) {
219 assignment->gaps.top = gaps.top;
220 } else if (!strcmp(scope, "right")) {
221 assignment->gaps.right = gaps.right;
222 } else if (!strcmp(scope, "bottom")) {
223 assignment->gaps.bottom = gaps.bottom;
224 } else if (!strcmp(scope, "left")) {
225 assignment->gaps.left = gaps.left;
226 } else {
227 ELOG("Invalid command, cannot process scope %s", scope);
228 }
229 TAILQ_INSERT_TAIL(&ws_assignments, assignment, ws_assignments);
230 }
231
232 CFGFUN(gaps, const char *workspace, const char *scope, const long value) {
233 int pixels = logical_px(value);
234 gaps_t gaps = (gaps_t){0, 0, 0, 0, 0};
235 if (!strcmp(scope, "inner")) {
236 if (workspace == NULL)
237 config.gaps.inner = pixels;
238 else {
239 gaps.inner = pixels - config.gaps.inner;
240 create_gaps_assignment(workspace, scope, gaps);
241 }
242 } else if (!strcmp(scope, "outer")) {
243 if (workspace == NULL) {
244 config.gaps.top = pixels;
245 config.gaps.right = pixels;
246 config.gaps.bottom = pixels;
247 config.gaps.left = pixels;
248 } else {
249 gaps.top = pixels - config.gaps.top;
250 gaps.right = pixels - config.gaps.right;
251 gaps.bottom = pixels - config.gaps.bottom;
252 gaps.left = pixels - config.gaps.left;
253 create_gaps_assignment(workspace, scope, gaps);
254 }
255 } else if (!strcmp(scope, "vertical")) {
256 if (workspace == NULL) {
257 config.gaps.top = pixels;
258 config.gaps.bottom = pixels;
259 } else {
260 gaps.top = pixels - config.gaps.top;
261 gaps.bottom = pixels - config.gaps.bottom;
262 create_gaps_assignment(workspace, scope, gaps);
263 }
264 } else if (!strcmp(scope, "horizontal")) {
265 if (workspace == NULL) {
266 config.gaps.right = pixels;
267 config.gaps.left = pixels;
268 } else {
269 gaps.right = pixels - config.gaps.right;
270 gaps.left = pixels - config.gaps.left;
271 create_gaps_assignment(workspace, scope, gaps);
272 }
273 } else if (!strcmp(scope, "top")) {
274 if (workspace == NULL)
275 config.gaps.top = pixels;
276 else {
277 gaps.top = pixels - config.gaps.top;
278 create_gaps_assignment(workspace, scope, gaps);
279 }
280 } else if (!strcmp(scope, "right")) {
281 if (workspace == NULL)
282 config.gaps.right = pixels;
283 else {
284 gaps.right = pixels - config.gaps.right;
285 create_gaps_assignment(workspace, scope, gaps);
286 }
287 } else if (!strcmp(scope, "bottom")) {
288 if (workspace == NULL)
289 config.gaps.bottom = pixels;
290 else {
291 gaps.bottom = pixels - config.gaps.bottom;
292 create_gaps_assignment(workspace, scope, gaps);
293 }
294 } else if (!strcmp(scope, "left")) {
295 if (workspace == NULL)
296 config.gaps.left = pixels;
297 else {
298 gaps.left = pixels - config.gaps.left;
299 create_gaps_assignment(workspace, scope, gaps);
300 }
301 } else {
302 ELOG("Invalid command, cannot process scope %s", scope);
303 }
304 }
305
306 CFGFUN(smart_borders, const char *enable) {
307 if (!strcmp(enable, "no_gaps"))
308 config.smart_borders = SMART_BORDERS_NO_GAPS;
309 else
310 config.smart_borders = eval_boolstr(enable) ? SMART_BORDERS_ON : SMART_BORDERS_OFF;
311 }
312
313 CFGFUN(smart_gaps, const char *enable) {
314 if (!strcmp(enable, "inverse_outer"))
315 config.smart_gaps = SMART_GAPS_INVERSE_OUTER;
316 else
317 config.smart_gaps = eval_boolstr(enable) ? SMART_GAPS_ON : SMART_GAPS_OFF;
318 }
319
320 CFGFUN(floating_minimum_size, const long width, const long height) {
321 config.floating_minimum_width = width;
322 config.floating_minimum_height = height;
323 }
324
325 CFGFUN(floating_maximum_size, const long width, const long height) {
326 config.floating_maximum_width = width;
327 config.floating_maximum_height = height;
328 }
329
330 CFGFUN(floating_modifier, const char *modifiers) {
331 config.floating_modifier = event_state_from_str(modifiers);
332 }
333
334 CFGFUN(default_orientation, const char *orientation) {
335 if (strcmp(orientation, "horizontal") == 0)
336 config.default_orientation = HORIZ;
337 else if (strcmp(orientation, "vertical") == 0)
338 config.default_orientation = VERT;
339 else
340 config.default_orientation = NO_ORIENTATION;
341 }
342
343 CFGFUN(workspace_layout, const char *layout) {
344 if (strcmp(layout, "default") == 0)
345 config.default_layout = L_DEFAULT;
346 else if (strcmp(layout, "stacking") == 0 ||
347 strcmp(layout, "stacked") == 0)
348 config.default_layout = L_STACKED;
349 else
350 config.default_layout = L_TABBED;
351 }
352
353 CFGFUN(default_border, const char *windowtype, const char *border, const long width) {
354 int border_style;
355 int border_width;
356
357 if (strcmp(border, "1pixel") == 0) {
358 border_style = BS_PIXEL;
359 border_width = 1;
360 } else if (strcmp(border, "none") == 0) {
361 border_style = BS_NONE;
362 border_width = 0;
363 } else if (strcmp(border, "pixel") == 0) {
364 border_style = BS_PIXEL;
365 border_width = width;
366 } else {
367 border_style = BS_NORMAL;
368 border_width = width;
369 }
370
371 if ((strcmp(windowtype, "default_border") == 0) ||
372 (strcmp(windowtype, "new_window") == 0)) {
373 DLOG("default tiled border style = %d and border width = %d (%d physical px)\n",
374 border_style, border_width, logical_px(border_width));
375 config.default_border = border_style;
376 config.default_border_width = logical_px(border_width);
377 } else {
378 DLOG("default floating border style = %d and border width = %d (%d physical px)\n",
379 border_style, border_width, logical_px(border_width));
380 config.default_floating_border = border_style;
381 config.default_floating_border_width = logical_px(border_width);
382 }
383 }
384
385 CFGFUN(hide_edge_borders, const char *borders) {
386 if (strcmp(borders, "smart_no_gaps") == 0)
387 config.hide_edge_borders = HEBM_SMART_NO_GAPS;
388 else if (strcmp(borders, "smart") == 0)
389 config.hide_edge_borders = HEBM_SMART;
390 else if (strcmp(borders, "vertical") == 0)
391 config.hide_edge_borders = HEBM_VERTICAL;
392 else if (strcmp(borders, "horizontal") == 0)
393 config.hide_edge_borders = HEBM_HORIZONTAL;
394 else if (strcmp(borders, "both") == 0)
395 config.hide_edge_borders = HEBM_BOTH;
396 else if (strcmp(borders, "none") == 0)
397 config.hide_edge_borders = HEBM_NONE;
398 else if (eval_boolstr(borders))
399 config.hide_edge_borders = HEBM_VERTICAL;
400 else
401 config.hide_edge_borders = HEBM_NONE;
402 }
403
404 CFGFUN(focus_follows_mouse, const char *value) {
405 config.disable_focus_follows_mouse = !eval_boolstr(value);
406 }
407
408 CFGFUN(mouse_warping, const char *value) {
409 if (strcmp(value, "none") == 0)
410 config.mouse_warping = POINTER_WARPING_NONE;
411 else if (strcmp(value, "output") == 0)
412 config.mouse_warping = POINTER_WARPING_OUTPUT;
413 }
414
415 CFGFUN(force_xinerama, const char *value) {
416 config.force_xinerama = eval_boolstr(value);
417 }
418
419 CFGFUN(disable_randr15, const char *value) {
420 config.disable_randr15 = eval_boolstr(value);
421 }
422
423 CFGFUN(focus_wrapping, const char *value) {
424 if (strcmp(value, "force") == 0) {
425 config.focus_wrapping = FOCUS_WRAPPING_FORCE;
426 } else if (strcmp(value, "workspace") == 0) {
427 config.focus_wrapping = FOCUS_WRAPPING_WORKSPACE;
428 } else if (eval_boolstr(value)) {
429 config.focus_wrapping = FOCUS_WRAPPING_ON;
430 } else {
431 config.focus_wrapping = FOCUS_WRAPPING_OFF;
432 }
433 }
434
435 CFGFUN(force_focus_wrapping, const char *value) {
436 /* Legacy syntax. */
437 if (eval_boolstr(value)) {
438 config.focus_wrapping = FOCUS_WRAPPING_FORCE;
439 } else {
440 /* For "force_focus_wrapping off", don't enable or disable
441 * focus wrapping, just ensure it's not forced. */
442 if (config.focus_wrapping == FOCUS_WRAPPING_FORCE) {
443 config.focus_wrapping = FOCUS_WRAPPING_ON;
444 }
445 }
446 }
447
448 CFGFUN(workspace_back_and_forth, const char *value) {
449 config.workspace_auto_back_and_forth = eval_boolstr(value);
450 }
451
452 CFGFUN(fake_outputs, const char *outputs) {
453 free(config.fake_outputs);
454 config.fake_outputs = sstrdup(outputs);
455 }
456
457 CFGFUN(force_display_urgency_hint, const long duration_ms) {
458 config.workspace_urgency_timer = duration_ms / 1000.0;
459 }
460
461 CFGFUN(focus_on_window_activation, const char *mode) {
462 if (strcmp(mode, "smart") == 0)
463 config.focus_on_window_activation = FOWA_SMART;
464 else if (strcmp(mode, "urgent") == 0)
465 config.focus_on_window_activation = FOWA_URGENT;
466 else if (strcmp(mode, "focus") == 0)
467 config.focus_on_window_activation = FOWA_FOCUS;
468 else if (strcmp(mode, "none") == 0)
469 config.focus_on_window_activation = FOWA_NONE;
470 else {
471 ELOG("Unknown focus_on_window_activation mode \"%s\", ignoring it.\n", mode);
472 return;
473 }
474
475 DLOG("Set new focus_on_window_activation mode = %i.\n", config.focus_on_window_activation);
476 }
477
478 CFGFUN(title_align, const char *alignment) {
479 if (strcmp(alignment, "left") == 0) {
480 config.title_align = ALIGN_LEFT;
481 } else if (strcmp(alignment, "center") == 0) {
482 config.title_align = ALIGN_CENTER;
483 } else if (strcmp(alignment, "right") == 0) {
484 config.title_align = ALIGN_RIGHT;
485 } else {
486 assert(false);
487 }
488 }
489
490 CFGFUN(show_marks, const char *value) {
491 config.show_marks = eval_boolstr(value);
492 }
493
494 static char *current_workspace = NULL;
495
496 CFGFUN(workspace, const char *workspace, const char *output) {
497 struct Workspace_Assignment *assignment;
498
499 /* When a new workspace line is encountered, for the first output word,
500 * $workspace from the config.spec is non-NULL. Afterwards, the parser calls
501 * clear_stack() because of the call line. Thus, we have to preserve the
502 * workspace string. */
503 if (workspace) {
504 FREE(current_workspace);
505
506 TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) {
507 if (strcasecmp(assignment->name, workspace) == 0) {
508 if (assignment->output != NULL) {
509 ELOG("You have a duplicate workspace assignment for workspace \"%s\"\n",
510 workspace);
511 return;
512 }
513 }
514 }
515
516 current_workspace = sstrdup(workspace);
517 } else {
518 if (!current_workspace) {
519 DLOG("Both workspace and current_workspace are NULL, assuming we had an error before\n");
520 return;
521 }
522 workspace = current_workspace;
523 }
524
525 DLOG("Assigning workspace \"%s\" to output \"%s\"\n", workspace, output);
526
527 assignment = scalloc(1, sizeof(struct Workspace_Assignment));
528 assignment->name = sstrdup(workspace);
529 assignment->output = sstrdup(output);
530 TAILQ_INSERT_TAIL(&ws_assignments, assignment, ws_assignments);
531 }
532
533 CFGFUN(ipc_socket, const char *path) {
534 free(config.ipc_socket_path);
535 config.ipc_socket_path = sstrdup(path);
536 }
537
538 CFGFUN(restart_state, const char *path) {
539 free(config.restart_state_path);
540 config.restart_state_path = sstrdup(path);
541 }
542
543 CFGFUN(popup_during_fullscreen, const char *value) {
544 if (strcmp(value, "ignore") == 0) {
545 config.popup_during_fullscreen = PDF_IGNORE;
546 } else if (strcmp(value, "leave_fullscreen") == 0) {
547 config.popup_during_fullscreen = PDF_LEAVE_FULLSCREEN;
548 } else {
549 config.popup_during_fullscreen = PDF_SMART;
550 }
551 }
552
553 CFGFUN(color_single, const char *colorclass, const char *color) {
554 /* used for client.background only currently */
555 config.client.background = draw_util_hex_to_color(color);
556 }
557
558 CFGFUN(color, const char *colorclass, const char *border, const char *background, const char *text, const char *indicator, const char *child_border) {
559 #define APPLY_COLORS(classname) \
560 do { \
561 if (strcmp(colorclass, "client." #classname) == 0) { \
562 config.client.classname.border = draw_util_hex_to_color(border); \
563 config.client.classname.background = draw_util_hex_to_color(background); \
564 config.client.classname.text = draw_util_hex_to_color(text); \
565 if (indicator != NULL) { \
566 config.client.classname.indicator = draw_util_hex_to_color(indicator); \
567 } \
568 if (child_border != NULL) { \
569 config.client.classname.child_border = draw_util_hex_to_color(child_border); \
570 } else { \
571 config.client.classname.child_border = config.client.classname.background; \
572 } \
573 } \
574 } while (0)
575
576 APPLY_COLORS(focused_inactive);
577 APPLY_COLORS(focused);
578 APPLY_COLORS(unfocused);
579 APPLY_COLORS(urgent);
580 APPLY_COLORS(placeholder);
581
582 #undef APPLY_COLORS
583 }
584
585 CFGFUN(assign_output, const char *output) {
586 if (match_is_empty(current_match)) {
587 ELOG("Match is empty, ignoring this assignment\n");
588 return;
589 }
590
591 if (current_match->window_mode != WM_ANY) {
592 ELOG("Assignments using window mode (floating/tiling) is not supported\n");
593 return;
594 }
595
596 DLOG("New assignment, using above criteria, to output \"%s\".\n", output);
597 Assignment *assignment = scalloc(1, sizeof(Assignment));
598 match_copy(&(assignment->match), current_match);
599 assignment->type = A_TO_OUTPUT;
600 assignment->dest.output = sstrdup(output);
601 TAILQ_INSERT_TAIL(&assignments, assignment, assignments);
602 }
603
604 CFGFUN(assign, const char *workspace, bool is_number) {
605 if (match_is_empty(current_match)) {
606 ELOG("Match is empty, ignoring this assignment\n");
607 return;
608 }
609
610 if (current_match->window_mode != WM_ANY) {
611 ELOG("Assignments using window mode (floating/tiling) is not supported\n");
612 return;
613 }
614
615 if (is_number && ws_name_to_number(workspace) == -1) {
616 ELOG("Could not parse initial part of \"%s\" as a number.\n", workspace);
617 return;
618 }
619
620 DLOG("New assignment, using above criteria, to workspace \"%s\".\n", workspace);
621 Assignment *assignment = scalloc(1, sizeof(Assignment));
622 match_copy(&(assignment->match), current_match);
623 assignment->type = is_number ? A_TO_WORKSPACE_NUMBER : A_TO_WORKSPACE;
624 assignment->dest.workspace = sstrdup(workspace);
625 TAILQ_INSERT_TAIL(&assignments, assignment, assignments);
626 }
627
628 CFGFUN(no_focus) {
629 if (match_is_empty(current_match)) {
630 ELOG("Match is empty, ignoring this assignment\n");
631 return;
632 }
633
634 DLOG("New assignment, using above criteria, to ignore focus on manage.\n");
635 Assignment *assignment = scalloc(1, sizeof(Assignment));
636 match_copy(&(assignment->match), current_match);
637 assignment->type = A_NO_FOCUS;
638 TAILQ_INSERT_TAIL(&assignments, assignment, assignments);
639 }
640
641 CFGFUN(ipc_kill_timeout, const long timeout_ms) {
642 ipc_set_kill_timeout(timeout_ms / 1000.0);
643 }
644
645 /*******************************************************************************
646 * Bar configuration (i3bar)
647 ******************************************************************************/
648
649 static Barconfig *current_bar;
650
651 CFGFUN(bar_font, const char *font) {
652 FREE(current_bar->font);
653 current_bar->font = sstrdup(font);
654 }
655
656 CFGFUN(bar_separator_symbol, const char *separator) {
657 FREE(current_bar->separator_symbol);
658 current_bar->separator_symbol = sstrdup(separator);
659 }
660
661 CFGFUN(bar_mode, const char *mode) {
662 current_bar->mode = (strcmp(mode, "dock") == 0 ? M_DOCK : (strcmp(mode, "hide") == 0 ? M_HIDE : M_INVISIBLE));
663 }
664
665 CFGFUN(bar_hidden_state, const char *hidden_state) {
666 current_bar->hidden_state = (strcmp(hidden_state, "hide") == 0 ? S_HIDE : S_SHOW);
667 }
668
669 CFGFUN(bar_id, const char *bar_id) {
670 current_bar->id = sstrdup(bar_id);
671 }
672
673 CFGFUN(bar_output, const char *output) {
674 int new_outputs = current_bar->num_outputs + 1;
675 current_bar->outputs = srealloc(current_bar->outputs, sizeof(char *) * new_outputs);
676 current_bar->outputs[current_bar->num_outputs] = sstrdup(output);
677 current_bar->num_outputs = new_outputs;
678 }
679
680 CFGFUN(bar_verbose, const char *verbose) {
681 current_bar->verbose = eval_boolstr(verbose);
682 }
683
684 CFGFUN(bar_height, const long height) {
685 current_bar->bar_height = (uint32_t)height;
686 }
687
688 CFGFUN(bar_modifier, const char *modifiers) {
689 current_bar->modifier = modifiers ? event_state_from_str(modifiers) : XCB_NONE;
690 }
691
692 static void bar_configure_binding(const char *button, const char *release, const char *command) {
693 if (strncasecmp(button, "button", strlen("button")) != 0) {
694 ELOG("Bindings for a bar can only be mouse bindings, not \"%s\", ignoring.\n", button);
695 return;
696 }
697
698 int input_code = atoi(button + strlen("button"));
699 if (input_code < 1) {
700 ELOG("Button \"%s\" does not seem to be in format 'buttonX'.\n", button);
701 return;
702 }
703 const bool release_bool = release != NULL;
704
705 struct Barbinding *current;
706 TAILQ_FOREACH (current, &(current_bar->bar_bindings), bindings) {
707 if (current->input_code == input_code && current->release == release_bool) {
708 ELOG("command for button %s was already specified, ignoring.\n", button);
709 return;
710 }
711 }
712
713 struct Barbinding *new_binding = scalloc(1, sizeof(struct Barbinding));
714 new_binding->release = release_bool;
715 new_binding->input_code = input_code;
716 new_binding->command = sstrdup(command);
717 TAILQ_INSERT_TAIL(&(current_bar->bar_bindings), new_binding, bindings);
718 }
719
720 CFGFUN(bar_wheel_up_cmd, const char *command) {
721 ELOG("'wheel_up_cmd' is deprecated. Please us 'bindsym button4 %s' instead.\n", command);
722 bar_configure_binding("button4", NULL, command);
723 }
724
725 CFGFUN(bar_wheel_down_cmd, const char *command) {
726 ELOG("'wheel_down_cmd' is deprecated. Please us 'bindsym button5 %s' instead.\n", command);
727 bar_configure_binding("button5", NULL, command);
728 }
729
730 CFGFUN(bar_bindsym, const char *button, const char *release, const char *command) {
731 bar_configure_binding(button, release, command);
732 }
733
734 CFGFUN(bar_position, const char *position) {
735 current_bar->position = (strcmp(position, "top") == 0 ? P_TOP : P_BOTTOM);
736 }
737
738 CFGFUN(bar_i3bar_command, const char *i3bar_command) {
739 FREE(current_bar->i3bar_command);
740 current_bar->i3bar_command = sstrdup(i3bar_command);
741 }
742
743 CFGFUN(bar_color, const char *colorclass, const char *border, const char *background, const char *text) {
744 #define APPLY_COLORS(classname) \
745 do { \
746 if (strcmp(colorclass, #classname) == 0) { \
747 if (text != NULL) { \
748 /* New syntax: border, background, text */ \
749 current_bar->colors.classname##_border = sstrdup(border); \
750 current_bar->colors.classname##_bg = sstrdup(background); \
751 current_bar->colors.classname##_text = sstrdup(text); \
752 } else { \
753 /* Old syntax: text, background */ \
754 current_bar->colors.classname##_bg = sstrdup(background); \
755 current_bar->colors.classname##_text = sstrdup(border); \
756 } \
757 } \
758 } while (0)
759
760 APPLY_COLORS(focused_workspace);
761 APPLY_COLORS(active_workspace);
762 APPLY_COLORS(inactive_workspace);
763 APPLY_COLORS(urgent_workspace);
764 APPLY_COLORS(binding_mode);
765
766 #undef APPLY_COLORS
767 }
768
769 CFGFUN(bar_socket_path, const char *socket_path) {
770 FREE(current_bar->socket_path);
771 current_bar->socket_path = sstrdup(socket_path);
772 }
773
774 CFGFUN(bar_tray_output, const char *output) {
775 struct tray_output_t *tray_output = scalloc(1, sizeof(struct tray_output_t));
776 tray_output->output = sstrdup(output);
777 TAILQ_INSERT_TAIL(&(current_bar->tray_outputs), tray_output, tray_outputs);
778 }
779
780 CFGFUN(bar_tray_padding, const long padding_px) {
781 current_bar->tray_padding = padding_px;
782 }
783
784 CFGFUN(bar_color_single, const char *colorclass, const char *color) {
785 if (strcmp(colorclass, "background") == 0)
786 current_bar->colors.background = sstrdup(color);
787 else if (strcmp(colorclass, "separator") == 0)
788 current_bar->colors.separator = sstrdup(color);
789 else if (strcmp(colorclass, "statusline") == 0)
790 current_bar->colors.statusline = sstrdup(color);
791 else if (strcmp(colorclass, "focused_background") == 0)
792 current_bar->colors.focused_background = sstrdup(color);
793 else if (strcmp(colorclass, "focused_separator") == 0)
794 current_bar->colors.focused_separator = sstrdup(color);
795 else
796 current_bar->colors.focused_statusline = sstrdup(color);
797 }
798
799 CFGFUN(bar_status_command, const char *command) {
800 FREE(current_bar->status_command);
801 current_bar->status_command = sstrdup(command);
802 }
803
804 CFGFUN(bar_binding_mode_indicator, const char *value) {
805 current_bar->hide_binding_mode_indicator = !eval_boolstr(value);
806 }
807
808 CFGFUN(bar_workspace_buttons, const char *value) {
809 current_bar->hide_workspace_buttons = !eval_boolstr(value);
810 }
811
812 CFGFUN(bar_workspace_min_width, const long width) {
813 current_bar->workspace_min_width = width;
814 }
815
816 CFGFUN(bar_strip_workspace_numbers, const char *value) {
817 current_bar->strip_workspace_numbers = eval_boolstr(value);
818 }
819
820 CFGFUN(bar_strip_workspace_name, const char *value) {
821 current_bar->strip_workspace_name = eval_boolstr(value);
822 }
823
824 CFGFUN(bar_start) {
825 current_bar = scalloc(1, sizeof(struct Barconfig));
826 TAILQ_INIT(&(current_bar->bar_bindings));
827 TAILQ_INIT(&(current_bar->tray_outputs));
828 current_bar->tray_padding = 2;
829 current_bar->modifier = XCB_KEY_BUT_MASK_MOD_4;
830 }
831
832 CFGFUN(bar_finish) {
833 DLOG("\t new bar configuration finished, saving.\n");
834 /* Generate a unique ID for this bar if not already configured */
835 if (current_bar->id == NULL)
836 sasprintf(&current_bar->id, "bar-%d", config.number_barconfigs);
837
838 config.number_barconfigs++;
839
840 /* If no font was explicitly set, we use the i3 font as default */
841 if (current_bar->font == NULL && font_pattern != NULL)
842 current_bar->font = sstrdup(font_pattern);
843
844 TAILQ_INSERT_TAIL(&barconfigs, current_bar, configs);
845 /* Simply reset the pointer, but don't free the resources. */
846 current_bar = NULL;
847 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * config_parser.c: hand-written parser to parse configuration directives.
7 *
8 * See also src/commands_parser.c for rationale on why we use a custom parser.
9 *
10 * This parser works VERY MUCH like src/commands_parser.c, so read that first.
11 * The differences are:
12 *
13 * 1. config_parser supports the 'number' token type (in addition to 'word' and
14 * 'string'). Numbers are referred to using &num (like $str).
15 *
16 * 2. Criteria are not executed immediately, they are just stored.
17 *
18 * 3. config_parser recognizes \n and \r as 'end' token, while commands_parser
19 * ignores them.
20 *
21 * 4. config_parser skips the current line on invalid inputs and follows the
22 * nearest <error> token.
23 *
24 */
25 #include "all.h"
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <stdbool.h>
32 #include <stdint.h>
33 #include <sys/types.h>
34 #include <sys/wait.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 #include <xcb/xcb_xrm.h>
38
39 // Macros to make the YAJL API a bit easier to use.
40 #define y(x, ...) yajl_gen_##x(command_output.json_gen, ##__VA_ARGS__)
41 #define ystr(str) yajl_gen_string(command_output.json_gen, (unsigned char *)str, strlen(str))
42
43 xcb_xrm_database_t *database = NULL;
44
45 #ifndef TEST_PARSER
46 pid_t config_error_nagbar_pid = -1;
47 static struct context *context;
48 #endif
49
50 /*******************************************************************************
51 * The data structures used for parsing. Essentially the current state and a
52 * list of tokens for that state.
53 *
54 * The GENERATED_* files are generated by generate-commands-parser.pl with the
55 * input parser-specs/configs.spec.
56 ******************************************************************************/
57
58 #include "GENERATED_config_enums.h"
59
60 typedef struct token {
61 char *name;
62 char *identifier;
63 /* This might be __CALL */
64 cmdp_state next_state;
65 union {
66 uint16_t call_identifier;
67 } extra;
68 } cmdp_token;
69
70 typedef struct tokenptr {
71 cmdp_token *array;
72 int n;
73 } cmdp_token_ptr;
74
75 #include "GENERATED_config_tokens.h"
76
77 /*******************************************************************************
78 * The (small) stack where identified literals are stored during the parsing
79 * of a single command (like $workspace).
80 ******************************************************************************/
81
82 struct stack_entry {
83 /* Just a pointer, not dynamically allocated. */
84 const char *identifier;
85 enum {
86 STACK_STR = 0,
87 STACK_LONG = 1,
88 } type;
89 union {
90 char *str;
91 long num;
92 } val;
93 };
94
95 /* 10 entries should be enough for everybody. */
96 static struct stack_entry stack[10];
97
98 /*
99 * Pushes a string (identified by 'identifier') on the stack. We simply use a
100 * single array, since the number of entries we have to store is very small.
101 *
102 */
103 static void push_string(const char *identifier, const char *str) {
104 for (int c = 0; c < 10; c++) {
105 if (stack[c].identifier != NULL &&
106 strcmp(stack[c].identifier, identifier) != 0)
107 continue;
108 if (stack[c].identifier == NULL) {
109 /* Found a free slot, let’s store it here. */
110 stack[c].identifier = identifier;
111 stack[c].val.str = sstrdup(str);
112 stack[c].type = STACK_STR;
113 } else {
114 /* Append the value. */
115 char *prev = stack[c].val.str;
116 sasprintf(&(stack[c].val.str), "%s,%s", prev, str);
117 free(prev);
118 }
119 return;
120 }
121
122 /* When we arrive here, the stack is full. This should not happen and
123 * means there’s either a bug in this parser or the specification
124 * contains a command with more than 10 identified tokens. */
125 fprintf(stderr, "BUG: config_parser stack full. This means either a bug "
126 "in the code, or a new command which contains more than "
127 "10 identified tokens.\n");
128 exit(EXIT_FAILURE);
129 }
130
131 static void push_long(const char *identifier, long num) {
132 for (int c = 0; c < 10; c++) {
133 if (stack[c].identifier != NULL)
134 continue;
135 /* Found a free slot, let’s store it here. */
136 stack[c].identifier = identifier;
137 stack[c].val.num = num;
138 stack[c].type = STACK_LONG;
139 return;
140 }
141
142 /* When we arrive here, the stack is full. This should not happen and
143 * means there’s either a bug in this parser or the specification
144 * contains a command with more than 10 identified tokens. */
145 fprintf(stderr, "BUG: config_parser stack full. This means either a bug "
146 "in the code, or a new command which contains more than "
147 "10 identified tokens.\n");
148 exit(EXIT_FAILURE);
149 }
150
151 static const char *get_string(const char *identifier) {
152 for (int c = 0; c < 10; c++) {
153 if (stack[c].identifier == NULL)
154 break;
155 if (strcmp(identifier, stack[c].identifier) == 0)
156 return stack[c].val.str;
157 }
158 return NULL;
159 }
160
161 static long get_long(const char *identifier) {
162 for (int c = 0; c < 10; c++) {
163 if (stack[c].identifier == NULL)
164 break;
165 if (strcmp(identifier, stack[c].identifier) == 0)
166 return stack[c].val.num;
167 }
168 return 0;
169 }
170
171 static void clear_stack(void) {
172 for (int c = 0; c < 10; c++) {
173 if (stack[c].type == STACK_STR)
174 free(stack[c].val.str);
175 stack[c].identifier = NULL;
176 stack[c].val.str = NULL;
177 stack[c].val.num = 0;
178 }
179 }
180
181 /*******************************************************************************
182 * The parser itself.
183 ******************************************************************************/
184
185 static cmdp_state state;
186 static Match current_match;
187 static struct ConfigResultIR subcommand_output;
188 static struct ConfigResultIR command_output;
189
190 /* A list which contains the states that lead to the current state, e.g.
191 * INITIAL, WORKSPACE_LAYOUT.
192 * When jumping back to INITIAL, statelist_idx will simply be set to 1
193 * (likewise for other states, e.g. MODE or BAR).
194 * This list is used to process the nearest error token. */
195 static cmdp_state statelist[10] = {INITIAL};
196 /* NB: statelist_idx points to where the next entry will be inserted */
197 static int statelist_idx = 1;
198
199 #include "GENERATED_config_call.h"
200
201 static void next_state(const cmdp_token *token) {
202 cmdp_state _next_state = token->next_state;
203
204 //printf("token = name %s identifier %s\n", token->name, token->identifier);
205 //printf("next_state = %d\n", token->next_state);
206 if (token->next_state == __CALL) {
207 subcommand_output.json_gen = command_output.json_gen;
208 GENERATED_call(token->extra.call_identifier, &subcommand_output);
209 _next_state = subcommand_output.next_state;
210 clear_stack();
211 }
212
213 state = _next_state;
214 if (state == INITIAL) {
215 clear_stack();
216 }
217
218 /* See if we are jumping back to a state in which we were in previously
219 * (statelist contains INITIAL) and just move statelist_idx accordingly. */
220 for (int i = 0; i < statelist_idx; i++) {
221 if (statelist[i] != _next_state)
222 continue;
223 statelist_idx = i + 1;
224 return;
225 }
226
227 /* Otherwise, the state is new and we add it to the list */
228 statelist[statelist_idx++] = _next_state;
229 }
230
231 /*
232 * Returns a pointer to the start of the line (one byte after the previous \r,
233 * \n) or the start of the input, if this is the first line.
234 *
235 */
236 static const char *start_of_line(const char *walk, const char *beginning) {
237 while (walk >= beginning && *walk != '\n' && *walk != '\r') {
238 walk--;
239 }
240
241 return walk + 1;
242 }
243
244 /*
245 * Copies the line and terminates it at the next \n, if any.
246 *
247 * The caller has to free() the result.
248 *
249 */
250 static char *single_line(const char *start) {
251 char *result = sstrdup(start);
252 char *end = strchr(result, '\n');
253 if (end != NULL)
254 *end = '\0';
255 return result;
256 }
257
258 struct ConfigResultIR *parse_config(const char *input, struct context *context) {
259 /* Dump the entire config file into the debug log. We cannot just use
260 * DLOG("%s", input); because one log message must not exceed 4 KiB. */
261 const char *dumpwalk = input;
262 int linecnt = 1;
263 while (*dumpwalk != '\0') {
264 char *next_nl = strchr(dumpwalk, '\n');
265 if (next_nl != NULL) {
266 DLOG("CONFIG(line %3d): %.*s\n", linecnt, (int)(next_nl - dumpwalk), dumpwalk);
267 dumpwalk = next_nl + 1;
268 } else {
269 DLOG("CONFIG(line %3d): %s\n", linecnt, dumpwalk);
270 break;
271 }
272 linecnt++;
273 }
274 state = INITIAL;
275 statelist_idx = 1;
276
277 /* A YAJL JSON generator used for formatting replies. */
278 command_output.json_gen = yajl_gen_alloc(NULL);
279
280 y(array_open);
281
282 const char *walk = input;
283 const size_t len = strlen(input);
284 int c;
285 const cmdp_token *token;
286 bool token_handled;
287 linecnt = 1;
288
289 // TODO: make this testable
290 #ifndef TEST_PARSER
291 cfg_criteria_init(&current_match, &subcommand_output, INITIAL);
292 #endif
293
294 /* The "<=" operator is intentional: We also handle the terminating 0-byte
295 * explicitly by looking for an 'end' token. */
296 while ((size_t)(walk - input) <= len) {
297 /* Skip whitespace before every token, newlines are relevant since they
298 * separate configuration directives. */
299 while ((*walk == ' ' || *walk == '\t') && *walk != '\0')
300 walk++;
301
302 //printf("remaining input: %s\n", walk);
303
304 cmdp_token_ptr *ptr = &(tokens[state]);
305 token_handled = false;
306 for (c = 0; c < ptr->n; c++) {
307 token = &(ptr->array[c]);
308
309 /* A literal. */
310 if (token->name[0] == '\'') {
311 if (strncasecmp(walk, token->name + 1, strlen(token->name) - 1) == 0) {
312 if (token->identifier != NULL)
313 push_string(token->identifier, token->name + 1);
314 walk += strlen(token->name) - 1;
315 next_state(token);
316 token_handled = true;
317 break;
318 }
319 continue;
320 }
321
322 if (strcmp(token->name, "number") == 0) {
323 /* Handle numbers. We only accept decimal numbers for now. */
324 char *end = NULL;
325 errno = 0;
326 long int num = strtol(walk, &end, 10);
327 if ((errno == ERANGE && (num == LONG_MIN || num == LONG_MAX)) ||
328 (errno != 0 && num == 0))
329 continue;
330
331 /* No valid numbers found */
332 if (end == walk)
333 continue;
334
335 if (token->identifier != NULL)
336 push_long(token->identifier, num);
337
338 /* Set walk to the first non-number character */
339 walk = end;
340 next_state(token);
341 token_handled = true;
342 break;
343 }
344
345 if (strcmp(token->name, "string") == 0 ||
346 strcmp(token->name, "word") == 0) {
347 const char *beginning = walk;
348 /* Handle quoted strings (or words). */
349 if (*walk == '"') {
350 beginning++;
351 walk++;
352 while (*walk != '\0' && (*walk != '"' || *(walk - 1) == '\\'))
353 walk++;
354 } else {
355 if (token->name[0] == 's') {
356 while (*walk != '\0' && *walk != '\r' && *walk != '\n')
357 walk++;
358 } else {
359 /* For a word, the delimiters are white space (' ' or
360 * '\t'), closing square bracket (]), comma (,) and
361 * semicolon (;). */
362 while (*walk != ' ' && *walk != '\t' &&
363 *walk != ']' && *walk != ',' &&
364 *walk != ';' && *walk != '\r' &&
365 *walk != '\n' && *walk != '\0')
366 walk++;
367 }
368 }
369 if (walk != beginning) {
370 char *str = scalloc(walk - beginning + 1, 1);
371 /* We copy manually to handle escaping of characters. */
372 int inpos, outpos;
373 for (inpos = 0, outpos = 0;
374 inpos < (walk - beginning);
375 inpos++, outpos++) {
376 /* We only handle escaped double quotes to not break
377 * backwards compatibility with people using \w in
378 * regular expressions etc. */
379 if (beginning[inpos] == '\\' && beginning[inpos + 1] == '"')
380 inpos++;
381 str[outpos] = beginning[inpos];
382 }
383 if (token->identifier)
384 push_string(token->identifier, str);
385 free(str);
386 /* If we are at the end of a quoted string, skip the ending
387 * double quote. */
388 if (*walk == '"')
389 walk++;
390 next_state(token);
391 token_handled = true;
392 break;
393 }
394 }
395
396 if (strcmp(token->name, "line") == 0) {
397 while (*walk != '\0' && *walk != '\n' && *walk != '\r')
398 walk++;
399 next_state(token);
400 token_handled = true;
401 linecnt++;
402 walk++;
403 break;
404 }
405
406 if (strcmp(token->name, "end") == 0) {
407 //printf("checking for end: *%s*\n", walk);
408 if (*walk == '\0' || *walk == '\n' || *walk == '\r') {
409 next_state(token);
410 token_handled = true;
411 /* To make sure we start with an appropriate matching
412 * datastructure for commands which do *not* specify any
413 * criteria, we re-initialize the criteria system after
414 * every command. */
415 // TODO: make this testable
416 #ifndef TEST_PARSER
417 cfg_criteria_init(&current_match, &subcommand_output, INITIAL);
418 #endif
419 linecnt++;
420 walk++;
421 break;
422 }
423 }
424 }
425
426 if (!token_handled) {
427 /* Figure out how much memory we will need to fill in the names of
428 * all tokens afterwards. */
429 int tokenlen = 0;
430 for (c = 0; c < ptr->n; c++)
431 tokenlen += strlen(ptr->array[c].name) + strlen("'', ");
432
433 /* Build up a decent error message. We include the problem, the
434 * full input, and underline the position where the parser
435 * currently is. */
436 char *errormessage;
437 char *possible_tokens = smalloc(tokenlen + 1);
438 char *tokenwalk = possible_tokens;
439 for (c = 0; c < ptr->n; c++) {
440 token = &(ptr->array[c]);
441 if (token->name[0] == '\'') {
442 /* A literal is copied to the error message enclosed with
443 * single quotes. */
444 *tokenwalk++ = '\'';
445 strcpy(tokenwalk, token->name + 1);
446 tokenwalk += strlen(token->name + 1);
447 *tokenwalk++ = '\'';
448 } else {
449 /* Skip error tokens in error messages, they are used
450 * internally only and might confuse users. */
451 if (strcmp(token->name, "error") == 0)
452 continue;
453 /* Any other token is copied to the error message enclosed
454 * with angle brackets. */
455 *tokenwalk++ = '<';
456 strcpy(tokenwalk, token->name);
457 tokenwalk += strlen(token->name);
458 *tokenwalk++ = '>';
459 }
460 if (c < (ptr->n - 1)) {
461 *tokenwalk++ = ',';
462 *tokenwalk++ = ' ';
463 }
464 }
465 *tokenwalk = '\0';
466 sasprintf(&errormessage, "Expected one of these tokens: %s",
467 possible_tokens);
468 free(possible_tokens);
469
470 /* Go back to the beginning of the line */
471 const char *error_line = start_of_line(walk, input);
472
473 /* Contains the same amount of characters as 'input' has, but with
474 * the unparseable part highlighted using ^ characters. */
475 char *position = scalloc(strlen(error_line) + 1, 1);
476 const char *copywalk;
477 for (copywalk = error_line;
478 *copywalk != '\n' && *copywalk != '\r' && *copywalk != '\0';
479 copywalk++)
480 position[(copywalk - error_line)] = (copywalk >= walk ? '^' : (*copywalk == '\t' ? '\t' : ' '));
481 position[(copywalk - error_line)] = '\0';
482
483 ELOG("CONFIG: %s\n", errormessage);
484 ELOG("CONFIG: (in file %s)\n", context->filename);
485 char *error_copy = single_line(error_line);
486
487 /* Print context lines *before* the error, if any. */
488 if (linecnt > 1) {
489 const char *context_p1_start = start_of_line(error_line - 2, input);
490 char *context_p1_line = single_line(context_p1_start);
491 if (linecnt > 2) {
492 const char *context_p2_start = start_of_line(context_p1_start - 2, input);
493 char *context_p2_line = single_line(context_p2_start);
494 ELOG("CONFIG: Line %3d: %s\n", linecnt - 2, context_p2_line);
495 free(context_p2_line);
496 }
497 ELOG("CONFIG: Line %3d: %s\n", linecnt - 1, context_p1_line);
498 free(context_p1_line);
499 }
500 ELOG("CONFIG: Line %3d: %s\n", linecnt, error_copy);
501 ELOG("CONFIG: %s\n", position);
502 free(error_copy);
503 /* Print context lines *after* the error, if any. */
504 for (int i = 0; i < 2; i++) {
505 char *error_line_end = strchr(error_line, '\n');
506 if (error_line_end != NULL && *(error_line_end + 1) != '\0') {
507 error_line = error_line_end + 1;
508 error_copy = single_line(error_line);
509 ELOG("CONFIG: Line %3d: %s\n", linecnt + i + 1, error_copy);
510 free(error_copy);
511 }
512 }
513
514 context->has_errors = true;
515
516 /* Format this error message as a JSON reply. */
517 y(map_open);
518 ystr("success");
519 y(bool, false);
520 /* We set parse_error to true to distinguish this from other
521 * errors. i3-nagbar is spawned upon keypresses only for parser
522 * errors. */
523 ystr("parse_error");
524 y(bool, true);
525 ystr("error");
526 ystr(errormessage);
527 ystr("input");
528 ystr(input);
529 ystr("errorposition");
530 ystr(position);
531 y(map_close);
532
533 /* Skip the rest of this line, but continue parsing. */
534 while ((size_t)(walk - input) <= len && *walk != '\n')
535 walk++;
536
537 free(position);
538 free(errormessage);
539 clear_stack();
540
541 /* To figure out in which state to go (e.g. MODE or INITIAL),
542 * we find the nearest state which contains an <error> token
543 * and follow that one. */
544 bool error_token_found = false;
545 for (int i = statelist_idx - 1; (i >= 0) && !error_token_found; i--) {
546 cmdp_token_ptr *errptr = &(tokens[statelist[i]]);
547 for (int j = 0; j < errptr->n; j++) {
548 if (strcmp(errptr->array[j].name, "error") != 0)
549 continue;
550 next_state(&(errptr->array[j]));
551 error_token_found = true;
552 break;
553 }
554 }
555
556 assert(error_token_found);
557 }
558 }
559
560 y(array_close);
561
562 return &command_output;
563 }
564
565 /*******************************************************************************
566 * Code for building the stand-alone binary test.commands_parser which is used
567 * by t/187-commands-parser.t.
568 ******************************************************************************/
569
570 #ifdef TEST_PARSER
571
572 /*
573 * Logs the given message to stdout while prefixing the current time to it,
574 * but only if debug logging was activated.
575 * This is to be called by DLOG() which includes filename/linenumber
576 *
577 */
578 void debuglog(char *fmt, ...) {
579 va_list args;
580
581 va_start(args, fmt);
582 fprintf(stdout, "# ");
583 vfprintf(stdout, fmt, args);
584 va_end(args);
585 }
586
587 void errorlog(char *fmt, ...) {
588 va_list args;
589
590 va_start(args, fmt);
591 vfprintf(stderr, fmt, args);
592 va_end(args);
593 }
594
595 static int criteria_next_state;
596
597 void cfg_criteria_init(I3_CFG, int _state) {
598 criteria_next_state = _state;
599 }
600
601 void cfg_criteria_add(I3_CFG, const char *ctype, const char *cvalue) {
602 }
603
604 void cfg_criteria_pop_state(I3_CFG) {
605 result->next_state = criteria_next_state;
606 }
607
608 int main(int argc, char *argv[]) {
609 if (argc < 2) {
610 fprintf(stderr, "Syntax: %s <command>\n", argv[0]);
611 return 1;
612 }
613 struct context context;
614 context.filename = "<stdin>";
615 parse_config(argv[1], &context);
616 }
617
618 #else
619
620 /*
621 * Goes through each line of buf (separated by \n) and checks for statements /
622 * commands which only occur in i3 v4 configuration files. If it finds any, it
623 * returns version 4, otherwise it returns version 3.
624 *
625 */
626 static int detect_version(char *buf) {
627 char *walk = buf;
628 char *line = buf;
629 while (*walk != '\0') {
630 if (*walk != '\n') {
631 walk++;
632 continue;
633 }
634
635 /* check for some v4-only statements */
636 if (strncasecmp(line, "bindcode", strlen("bindcode")) == 0 ||
637 strncasecmp(line, "force_focus_wrapping", strlen("force_focus_wrapping")) == 0 ||
638 strncasecmp(line, "# i3 config file (v4)", strlen("# i3 config file (v4)")) == 0 ||
639 strncasecmp(line, "workspace_layout", strlen("workspace_layout")) == 0) {
640 LOG("deciding for version 4 due to this line: %.*s\n", (int)(walk - line), line);
641 return 4;
642 }
643
644 /* if this is a bind statement, we can check the command */
645 if (strncasecmp(line, "bind", strlen("bind")) == 0) {
646 char *bind = strchr(line, ' ');
647 if (bind == NULL)
648 goto next;
649 while ((*bind == ' ' || *bind == '\t') && *bind != '\0')
650 bind++;
651 if (*bind == '\0')
652 goto next;
653 if ((bind = strchr(bind, ' ')) == NULL)
654 goto next;
655 while ((*bind == ' ' || *bind == '\t') && *bind != '\0')
656 bind++;
657 if (*bind == '\0')
658 goto next;
659 if (strncasecmp(bind, "layout", strlen("layout")) == 0 ||
660 strncasecmp(bind, "floating", strlen("floating")) == 0 ||
661 strncasecmp(bind, "workspace", strlen("workspace")) == 0 ||
662 strncasecmp(bind, "focus left", strlen("focus left")) == 0 ||
663 strncasecmp(bind, "focus right", strlen("focus right")) == 0 ||
664 strncasecmp(bind, "focus up", strlen("focus up")) == 0 ||
665 strncasecmp(bind, "focus down", strlen("focus down")) == 0 ||
666 strncasecmp(bind, "border normal", strlen("border normal")) == 0 ||
667 strncasecmp(bind, "border 1pixel", strlen("border 1pixel")) == 0 ||
668 strncasecmp(bind, "border pixel", strlen("border pixel")) == 0 ||
669 strncasecmp(bind, "border borderless", strlen("border borderless")) == 0 ||
670 strncasecmp(bind, "--no-startup-id", strlen("--no-startup-id")) == 0 ||
671 strncasecmp(bind, "bar", strlen("bar")) == 0) {
672 LOG("deciding for version 4 due to this line: %.*s\n", (int)(walk - line), line);
673 return 4;
674 }
675 }
676
677 next:
678 /* advance to the next line */
679 walk++;
680 line = walk;
681 }
682
683 return 3;
684 }
685
686 /*
687 * Calls i3-migrate-config-to-v4 to migrate a configuration file (input
688 * buffer).
689 *
690 * Returns the converted config file or NULL if there was an error (for
691 * example the script could not be found in $PATH or the i3 executable’s
692 * directory).
693 *
694 */
695 static char *migrate_config(char *input, off_t size) {
696 int writepipe[2];
697 int readpipe[2];
698
699 if (pipe(writepipe) != 0 ||
700 pipe(readpipe) != 0) {
701 warn("migrate_config: Could not create pipes");
702 return NULL;
703 }
704
705 pid_t pid = fork();
706 if (pid == -1) {
707 warn("Could not fork()");
708 return NULL;
709 }
710
711 /* child */
712 if (pid == 0) {
713 /* close writing end of writepipe, connect reading side to stdin */
714 close(writepipe[1]);
715 dup2(writepipe[0], 0);
716
717 /* close reading end of readpipe, connect writing side to stdout */
718 close(readpipe[0]);
719 dup2(readpipe[1], 1);
720
721 static char *argv[] = {
722 NULL, /* will be replaced by the executable path */
723 NULL};
724 exec_i3_utility("i3-migrate-config-to-v4", argv);
725 }
726
727 /* parent */
728
729 /* close reading end of the writepipe (connected to the script’s stdin) */
730 close(writepipe[0]);
731
732 /* write the whole config file to the pipe, the script will read everything
733 * immediately */
734 if (writeall(writepipe[1], input, size) == -1) {
735 warn("Could not write to pipe");
736 return NULL;
737 }
738 close(writepipe[1]);
739
740 /* close writing end of the readpipe (connected to the script’s stdout) */
741 close(readpipe[1]);
742
743 /* read the script’s output */
744 int conv_size = 65535;
745 char *converted = scalloc(conv_size, 1);
746 int read_bytes = 0, ret;
747 do {
748 if (read_bytes == conv_size) {
749 conv_size += 65535;
750 converted = srealloc(converted, conv_size);
751 }
752 ret = read(readpipe[0], converted + read_bytes, conv_size - read_bytes);
753 if (ret == -1) {
754 warn("Cannot read from pipe");
755 FREE(converted);
756 return NULL;
757 }
758 read_bytes += ret;
759 } while (ret > 0);
760
761 /* get the returncode */
762 int status;
763 wait(&status);
764 if (!WIFEXITED(status)) {
765 fprintf(stderr, "Child did not terminate normally, using old config file (will lead to broken behaviour)\n");
766 FREE(converted);
767 return NULL;
768 }
769
770 int returncode = WEXITSTATUS(status);
771 if (returncode != 0) {
772 fprintf(stderr, "Migration process exit code was != 0\n");
773 if (returncode == 2) {
774 fprintf(stderr, "could not start the migration script\n");
775 /* TODO: script was not found. tell the user to fix their system or create a v4 config */
776 } else if (returncode == 1) {
777 fprintf(stderr, "This already was a v4 config. Please add the following line to your config file:\n");
778 fprintf(stderr, "# i3 config file (v4)\n");
779 /* TODO: nag the user with a message to include a hint for i3 in their config file */
780 }
781 FREE(converted);
782 return NULL;
783 }
784
785 return converted;
786 }
787
788 /**
789 * Launch nagbar to indicate errors in the configuration file.
790 */
791 void start_config_error_nagbar(const char *configpath, bool has_errors) {
792 char *editaction, *pageraction;
793 sasprintf(&editaction, "i3-sensible-editor \"%s\" && i3-msg reload\n", configpath);
794 sasprintf(&pageraction, "i3-sensible-pager \"%s\"\n", errorfilename);
795 char *argv[] = {
796 NULL, /* will be replaced by the executable path */
797 "-f",
798 (config.font.pattern ? config.font.pattern : "fixed"),
799 "-t",
800 (has_errors ? "error" : "warning"),
801 "-m",
802 (has_errors ? "You have an error in your i3 config file!" : "Your config is outdated. Please fix the warnings to make sure everything works."),
803 "-b",
804 "edit config",
805 editaction,
806 (errorfilename ? "-b" : NULL),
807 (has_errors ? "show errors" : "show warnings"),
808 pageraction,
809 NULL};
810
811 start_nagbar(&config_error_nagbar_pid, argv);
812 free(editaction);
813 free(pageraction);
814 }
815
816 /*
817 * Inserts or updates a variable assignment depending on whether it already exists.
818 *
819 */
820 static void upsert_variable(struct variables_head *variables, char *key, char *value) {
821 struct Variable *current;
822 SLIST_FOREACH (current, variables, variables) {
823 if (strcmp(current->key, key) != 0) {
824 continue;
825 }
826
827 DLOG("Updated variable: %s = %s -> %s\n", key, current->value, value);
828 FREE(current->value);
829 current->value = sstrdup(value);
830 return;
831 }
832
833 DLOG("Defined new variable: %s = %s\n", key, value);
834 struct Variable *new = scalloc(1, sizeof(struct Variable));
835 struct Variable *test = NULL, *loc = NULL;
836 new->key = sstrdup(key);
837 new->value = sstrdup(value);
838 /* ensure that the correct variable is matched in case of one being
839 * the prefix of another */
840 SLIST_FOREACH (test, variables, variables) {
841 if (strlen(new->key) >= strlen(test->key))
842 break;
843 loc = test;
844 }
845
846 if (loc == NULL) {
847 SLIST_INSERT_HEAD(variables, new, variables);
848 } else {
849 SLIST_INSERT_AFTER(loc, new, variables);
850 }
851 }
852
853 static char *get_resource(char *name) {
854 if (conn == NULL) {
855 return NULL;
856 }
857
858 /* Load the resource database lazily. */
859 if (database == NULL) {
860 database = xcb_xrm_database_from_default(conn);
861
862 if (database == NULL) {
863 ELOG("Failed to open the resource database.\n");
864
865 /* Load an empty database so we don't keep trying to load the
866 * default database over and over again. */
867 database = xcb_xrm_database_from_string("");
868
869 return NULL;
870 }
871 }
872
873 char *resource;
874 xcb_xrm_resource_get_string(database, name, NULL, &resource);
875 return resource;
876 }
877
878 /*
879 * Parses the given file by first replacing the variables, then calling
880 * parse_config and possibly launching i3-nagbar.
881 *
882 */
883 bool parse_file(const char *f, bool use_nagbar) {
884 struct variables_head variables = SLIST_HEAD_INITIALIZER(&variables);
885 int fd;
886 struct stat stbuf;
887 char *buf;
888 FILE *fstr;
889 char buffer[4096], key[512], value[4096], *continuation = NULL;
890
891 if ((fd = open(f, O_RDONLY)) == -1)
892 die("Could not open configuration file: %s\n", strerror(errno));
893
894 if (fstat(fd, &stbuf) == -1)
895 die("Could not fstat file: %s\n", strerror(errno));
896
897 buf = scalloc(stbuf.st_size + 1, 1);
898
899 if ((fstr = fdopen(fd, "r")) == NULL)
900 die("Could not fdopen: %s\n", strerror(errno));
901
902 FREE(current_config);
903 current_config = scalloc(stbuf.st_size + 1, 1);
904 if ((ssize_t)fread(current_config, 1, stbuf.st_size, fstr) != stbuf.st_size) {
905 die("Could not fread: %s\n", strerror(errno));
906 }
907 rewind(fstr);
908
909 bool invalid_sets = false;
910
911 while (!feof(fstr)) {
912 if (!continuation)
913 continuation = buffer;
914 if (fgets(continuation, sizeof(buffer) - (continuation - buffer), fstr) == NULL) {
915 if (feof(fstr))
916 break;
917 die("Could not read configuration file\n");
918 }
919 if (buffer[strlen(buffer) - 1] != '\n' && !feof(fstr)) {
920 ELOG("Your line continuation is too long, it exceeds %zd bytes\n", sizeof(buffer));
921 }
922
923 /* sscanf implicitly strips whitespace. */
924 value[0] = '\0';
925 const bool skip_line = (sscanf(buffer, "%511s %4095[^\n]", key, value) < 1 || strlen(key) < 3);
926 const bool comment = (key[0] == '#');
927 value[4095] = '\n';
928
929 continuation = strstr(buffer, "\\\n");
930 if (continuation) {
931 if (!comment) {
932 continue;
933 }
934 DLOG("line continuation in comment is ignored: \"%.*s\"\n", (int)strlen(buffer) - 1, buffer);
935 continuation = NULL;
936 }
937
938 strncpy(buf + strlen(buf), buffer, strlen(buffer) + 1);
939
940 /* Skip comments and empty lines. */
941 if (skip_line || comment) {
942 continue;
943 }
944
945 if (strcasecmp(key, "set") == 0 && *value != '\0') {
946 char v_key[512];
947 char v_value[4096] = {'\0'};
948
949 if (sscanf(value, "%511s %4095[^\n]", v_key, v_value) < 1) {
950 ELOG("Failed to parse variable specification '%s', skipping it.\n", value);
951 invalid_sets = true;
952 continue;
953 }
954
955 if (v_key[0] != '$') {
956 ELOG("Malformed variable assignment, name has to start with $\n");
957 invalid_sets = true;
958 continue;
959 }
960
961 upsert_variable(&variables, v_key, v_value);
962 continue;
963 } else if (strcasecmp(key, "set_from_resource") == 0) {
964 char res_name[512] = {'\0'};
965 char v_key[512];
966 char fallback[4096] = {'\0'};
967
968 /* Ensure that this string is terminated. For example, a user might
969 * want a variable to be empty if the resource can't be found and
970 * uses
971 * set_from_resource $foo i3wm.foo
972 * Without explicitly terminating the string first, sscanf() will
973 * leave it uninitialized, causing garbage in the config.*/
974 fallback[0] = '\0';
975
976 if (sscanf(value, "%511s %511s %4095[^\n]", v_key, res_name, fallback) < 1) {
977 ELOG("Failed to parse resource specification '%s', skipping it.\n", value);
978 invalid_sets = true;
979 continue;
980 }
981
982 if (v_key[0] != '$') {
983 ELOG("Malformed variable assignment, name has to start with $\n");
984 invalid_sets = true;
985 continue;
986 }
987
988 char *res_value = get_resource(res_name);
989 if (res_value == NULL) {
990 DLOG("Could not get resource '%s', using fallback '%s'.\n", res_name, fallback);
991 res_value = sstrdup(fallback);
992 }
993
994 upsert_variable(&variables, v_key, res_value);
995 FREE(res_value);
996 continue;
997 }
998 }
999 fclose(fstr);
1000
1001 if (database != NULL) {
1002 xcb_xrm_database_free(database);
1003 /* Explicitly set the database to NULL again in case the config gets reloaded. */
1004 database = NULL;
1005 }
1006
1007 /* For every custom variable, see how often it occurs in the file and
1008 * how much extra bytes it requires when replaced. */
1009 struct Variable *current, *nearest;
1010 int extra_bytes = 0;
1011 /* We need to copy the buffer because we need to invalidate the
1012 * variables (otherwise we will count them twice, which is bad when
1013 * 'extra' is negative) */
1014 char *bufcopy = sstrdup(buf);
1015 SLIST_FOREACH (current, &variables, variables) {
1016 int extra = (strlen(current->value) - strlen(current->key));
1017 char *next;
1018 for (next = bufcopy;
1019 next < (bufcopy + stbuf.st_size) &&
1020 (next = strcasestr(next, current->key)) != NULL;
1021 next += strlen(current->key)) {
1022 *next = '_';
1023 extra_bytes += extra;
1024 }
1025 }
1026 FREE(bufcopy);
1027
1028 /* Then, allocate a new buffer and copy the file over to the new one,
1029 * but replace occurrences of our variables */
1030 char *walk = buf, *destwalk;
1031 char *new = scalloc(stbuf.st_size + extra_bytes + 1, 1);
1032 destwalk = new;
1033 while (walk < (buf + stbuf.st_size)) {
1034 /* Find the next variable */
1035 SLIST_FOREACH (current, &variables, variables) {
1036 current->next_match = strcasestr(walk, current->key);
1037 }
1038 nearest = NULL;
1039 int distance = stbuf.st_size;
1040 SLIST_FOREACH (current, &variables, variables) {
1041 if (current->next_match == NULL)
1042 continue;
1043 if ((current->next_match - walk) < distance) {
1044 distance = (current->next_match - walk);
1045 nearest = current;
1046 }
1047 }
1048 if (nearest == NULL) {
1049 /* If there are no more variables, we just copy the rest */
1050 strncpy(destwalk, walk, (buf + stbuf.st_size) - walk);
1051 destwalk += (buf + stbuf.st_size) - walk;
1052 *destwalk = '\0';
1053 break;
1054 } else {
1055 /* Copy until the next variable, then copy its value */
1056 strncpy(destwalk, walk, distance);
1057 strncpy(destwalk + distance, nearest->value, strlen(nearest->value));
1058 walk += distance + strlen(nearest->key);
1059 destwalk += distance + strlen(nearest->value);
1060 }
1061 }
1062
1063 /* analyze the string to find out whether this is an old config file (3.x)
1064 * or a new config file (4.x). If it’s old, we run the converter script. */
1065 int version = detect_version(buf);
1066 if (version == 3) {
1067 /* We need to convert this v3 configuration */
1068 char *converted = migrate_config(new, strlen(new));
1069 if (converted != NULL) {
1070 ELOG("\n");
1071 ELOG("****************************************************************\n");
1072 ELOG("NOTE: Automatically converted configuration file from v3 to v4.\n");
1073 ELOG("\n");
1074 ELOG("Please convert your config file to v4. You can use this command:\n");
1075 ELOG(" mv %s %s.O\n", f, f);
1076 ELOG(" i3-migrate-config-to-v4 %s.O > %s\n", f, f);
1077 ELOG("****************************************************************\n");
1078 ELOG("\n");
1079 free(new);
1080 new = converted;
1081 } else {
1082 LOG("\n");
1083 LOG("**********************************************************************\n");
1084 LOG("ERROR: Could not convert config file. Maybe i3-migrate-config-to-v4\n");
1085 LOG("was not correctly installed on your system?\n");
1086 LOG("**********************************************************************\n");
1087 LOG("\n");
1088 }
1089 }
1090
1091 context = scalloc(1, sizeof(struct context));
1092 context->filename = f;
1093
1094 struct ConfigResultIR *config_output = parse_config(new, context);
1095 yajl_gen_free(config_output->json_gen);
1096
1097 extract_workspace_names_from_bindings();
1098 check_for_duplicate_bindings(context);
1099 reorder_bindings();
1100
1101 if (use_nagbar && (context->has_errors || context->has_warnings || invalid_sets)) {
1102 ELOG("FYI: You are using i3 version %s\n", i3_version);
1103 if (version == 3)
1104 ELOG("Please convert your configfile first, then fix any remaining errors (see above).\n");
1105
1106 start_config_error_nagbar(f, context->has_errors || invalid_sets);
1107 }
1108
1109 bool has_errors = context->has_errors;
1110
1111 FREE(context->line_copy);
1112 free(context);
1113 free(new);
1114 free(buf);
1115
1116 while (!SLIST_EMPTY(&variables)) {
1117 current = SLIST_FIRST(&variables);
1118 FREE(current->key);
1119 FREE(current->value);
1120 SLIST_REMOVE_HEAD(&variables, variables);
1121 FREE(current);
1122 }
1123
1124 return !has_errors;
1125 }
1126
1127 #endif
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * display_version.c: displays the running i3 version, runs as part of
7 * i3 --moreversion.
8 *
9 */
10 #include "all.h"
11
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <sys/wait.h>
15 #include <sys/socket.h>
16 #include <sys/un.h>
17 #include <fcntl.h>
18 #include <time.h>
19
20 static bool human_readable_key, loaded_config_file_name_key;
21 static char *human_readable_version, *loaded_config_file_name;
22
23 static int version_string(void *ctx, const unsigned char *val, size_t len) {
24 if (human_readable_key)
25 sasprintf(&human_readable_version, "%.*s", (int)len, val);
26 if (loaded_config_file_name_key)
27 sasprintf(&loaded_config_file_name, "%.*s", (int)len, val);
28 return 1;
29 }
30
31 static int version_map_key(void *ctx, const unsigned char *stringval, size_t stringlen) {
32 human_readable_key = (stringlen == strlen("human_readable") &&
33 strncmp((const char *)stringval, "human_readable", strlen("human_readable")) == 0);
34 loaded_config_file_name_key = (stringlen == strlen("loaded_config_file_name") &&
35 strncmp((const char *)stringval, "loaded_config_file_name", strlen("loaded_config_file_name")) == 0);
36 return 1;
37 }
38
39 static yajl_callbacks version_callbacks = {
40 .yajl_string = version_string,
41 .yajl_map_key = version_map_key,
42 };
43
44 /*
45 * Connects to i3 to find out the currently running version. Useful since it
46 * might be different from the version compiled into this binary (maybe the
47 * user didn’t correctly install i3 or forgot te restart it).
48 *
49 * The output looks like this:
50 * Running i3 version: 4.2-202-gb8e782c (2012-08-12, branch "next") (pid 14804)
51 *
52 * The i3 binary you just called: /home/michael/i3/i3
53 * The i3 binary you are running: /home/michael/i3/i3
54 *
55 */
56 void display_running_version(void) {
57 if (getenv("DISPLAY") == NULL) {
58 fprintf(stderr, "\nYour DISPLAY environment variable is not set.\n");
59 fprintf(stderr, "Are you running i3 via SSH or on a virtual console?\n");
60 fprintf(stderr, "Try DISPLAY=:0 i3 --moreversion\n");
61 exit(EXIT_FAILURE);
62 }
63
64 char *pid_from_atom = root_atom_contents("I3_PID", conn, conn_screen);
65 if (pid_from_atom == NULL) {
66 /* If I3_PID is not set, the running version is older than 4.2-200. */
67 printf("\nRunning version: < 4.2-200\n");
68 exit(EXIT_SUCCESS);
69 }
70
71 /* Inform the user of what we are doing. While a single IPC request is
72 * really fast normally, in case i3 hangs, this will not terminate. */
73 printf("(Getting version from running i3, press ctrl-c to abort…)");
74 fflush(stdout);
75
76 int sockfd = ipc_connect(NULL);
77 if (ipc_send_message(sockfd, 0, I3_IPC_MESSAGE_TYPE_GET_VERSION,
78 (uint8_t *)"") == -1)
79 err(EXIT_FAILURE, "IPC: write()");
80
81 uint32_t reply_length;
82 uint32_t reply_type;
83 uint8_t *reply;
84 int ret;
85 if ((ret = ipc_recv_message(sockfd, &reply_type, &reply_length, &reply)) != 0) {
86 if (ret == -1)
87 err(EXIT_FAILURE, "IPC: read()");
88 exit(EXIT_FAILURE);
89 }
90
91 if (reply_type != I3_IPC_MESSAGE_TYPE_GET_VERSION)
92 errx(EXIT_FAILURE, "Got reply type %d, but expected %d (GET_VERSION)", reply_type, I3_IPC_MESSAGE_TYPE_GET_VERSION);
93
94 yajl_handle handle = yajl_alloc(&version_callbacks, NULL, NULL);
95
96 yajl_status state = yajl_parse(handle, (const unsigned char *)reply, (int)reply_length);
97 if (state != yajl_status_ok)
98 errx(EXIT_FAILURE, "Could not parse my own reply. That's weird. reply is %.*s", (int)reply_length, reply);
99
100 printf("\r\x1b[K");
101 printf("Running i3 version: %s (pid %s)\n", human_readable_version, pid_from_atom);
102
103 if (loaded_config_file_name) {
104 struct stat sb;
105 time_t now;
106 char mtime[64];
107 printf("Loaded i3 config: %s", loaded_config_file_name);
108 if (stat(loaded_config_file_name, &sb) == -1) {
109 printf("\n");
110 ELOG("Cannot stat config file \"%s\"\n", loaded_config_file_name);
111 } else {
112 strftime(mtime, sizeof(mtime), "%c", localtime(&(sb.st_mtime)));
113 time(&now);
114 printf(" (Last modified: %s, %.f seconds ago)\n", mtime, difftime(now, sb.st_mtime));
115 }
116 }
117
118 #ifdef __linux__
119 size_t destpath_size = 1024;
120 ssize_t linksize;
121 char *exepath;
122 char *destpath = smalloc(destpath_size);
123
124 sasprintf(&exepath, "/proc/%d/exe", getpid());
125
126 while ((linksize = readlink(exepath, destpath, destpath_size)) == (ssize_t)destpath_size) {
127 destpath_size = destpath_size * 2;
128 destpath = srealloc(destpath, destpath_size);
129 }
130 if (linksize == -1)
131 err(EXIT_FAILURE, "readlink(%s)", exepath);
132
133 /* readlink() does not NULL-terminate strings, so we have to. */
134 destpath[linksize] = '\0';
135
136 printf("\n");
137 printf("The i3 binary you just called: %s\n", destpath);
138
139 free(exepath);
140 sasprintf(&exepath, "/proc/%s/exe", pid_from_atom);
141
142 while ((linksize = readlink(exepath, destpath, destpath_size)) == (ssize_t)destpath_size) {
143 destpath_size = destpath_size * 2;
144 destpath = srealloc(destpath, destpath_size);
145 }
146 if (linksize == -1)
147 err(EXIT_FAILURE, "readlink(%s)", exepath);
148
149 /* readlink() does not NULL-terminate strings, so we have to. */
150 destpath[linksize] = '\0';
151
152 /* Check if "(deleted)" is the readlink result. If so, the running version
153 * does not match the file on disk. */
154 if (strstr(destpath, "(deleted)") != NULL)
155 printf("RUNNING BINARY DIFFERENT FROM BINARY ON DISK!\n");
156
157 /* Since readlink() might put a "(deleted)" somewhere in the buffer and
158 * stripping that out seems hackish and ugly, we read the process’s argv[0]
159 * instead. */
160 free(exepath);
161 sasprintf(&exepath, "/proc/%s/cmdline", pid_from_atom);
162
163 int fd;
164 if ((fd = open(exepath, O_RDONLY)) == -1)
165 err(EXIT_FAILURE, "open(%s)", exepath);
166 if (read(fd, destpath, sizeof(destpath)) == -1)
167 err(EXIT_FAILURE, "read(%s)", exepath);
168 close(fd);
169
170 printf("The i3 binary you are running: %s\n", destpath);
171
172 free(exepath);
173 free(destpath);
174 #endif
175
176 yajl_free(handle);
177 free(reply);
178 free(pid_from_atom);
179 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * drag.c: click and drag.
7 *
8 */
9 #include "all.h"
10
11 /* Custom data structure used to track dragging-related events. */
12 struct drag_x11_cb {
13 ev_prepare prepare;
14
15 /* Whether this modal event loop should be exited and with which result. */
16 drag_result_t result;
17
18 /* The container that is being dragged or resized, or NULL if this is a
19 * drag of the resize handle. */
20 Con *con;
21
22 /* The original event that initiated the drag. */
23 const xcb_button_press_event_t *event;
24
25 /* The dimensions of con when the loop was started. */
26 Rect old_rect;
27
28 /* The callback to invoke after every pointer movement. */
29 callback_t callback;
30
31 /* Drag distance threshold exceeded. If use_threshold is not set, then
32 * threshold_exceeded is always true. */
33 bool threshold_exceeded;
34
35 /* Cursor to set after the threshold is exceeded. */
36 xcb_cursor_t xcursor;
37
38 /* User data pointer for callback. */
39 const void *extra;
40 };
41
42 static bool threshold_exceeded(uint32_t x1, uint32_t y1,
43 uint32_t x2, uint32_t y2) {
44 const uint32_t threshold = 9;
45 return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) > threshold * threshold;
46 }
47
48 static bool drain_drag_events(EV_P, struct drag_x11_cb *dragloop) {
49 xcb_motion_notify_event_t *last_motion_notify = NULL;
50 xcb_generic_event_t *event;
51
52 while ((event = xcb_poll_for_event(conn)) != NULL) {
53 if (event->response_type == 0) {
54 xcb_generic_error_t *error = (xcb_generic_error_t *)event;
55 DLOG("X11 Error received (probably harmless)! sequence 0x%x, error_code = %d\n",
56 error->sequence, error->error_code);
57 free(event);
58 continue;
59 }
60
61 /* Strip off the highest bit (set if the event is generated) */
62 int type = (event->response_type & 0x7F);
63
64 switch (type) {
65 case XCB_BUTTON_RELEASE:
66 dragloop->result = DRAG_SUCCESS;
67 break;
68
69 case XCB_KEY_PRESS:
70 DLOG("A key was pressed during drag, reverting changes.\n");
71 dragloop->result = DRAG_REVERT;
72 handle_event(type, event);
73 break;
74
75 case XCB_UNMAP_NOTIFY: {
76 xcb_unmap_notify_event_t *unmap_event = (xcb_unmap_notify_event_t *)event;
77 Con *con = con_by_window_id(unmap_event->window);
78
79 if (con != NULL) {
80 DLOG("UnmapNotify for window 0x%08x (container %p)\n", unmap_event->window, con);
81
82 if (con_get_workspace(con) == con_get_workspace(focused)) {
83 DLOG("UnmapNotify for a managed window on the current workspace, aborting\n");
84 dragloop->result = DRAG_ABORT;
85 }
86 }
87
88 handle_event(type, event);
89 break;
90 }
91
92 case XCB_MOTION_NOTIFY:
93 /* motion_notify events are saved for later */
94 FREE(last_motion_notify);
95 last_motion_notify = (xcb_motion_notify_event_t *)event;
96 break;
97
98 default:
99 DLOG("Passing to original handler\n");
100 handle_event(type, event);
101 break;
102 }
103
104 if (last_motion_notify != (xcb_motion_notify_event_t *)event)
105 free(event);
106
107 if (dragloop->result != DRAGGING) {
108 ev_break(EV_A_ EVBREAK_ONE);
109 if (dragloop->result == DRAG_SUCCESS) {
110 /* Ensure motion notify events are handled. */
111 break;
112 } else {
113 free(last_motion_notify);
114 return true;
115 }
116 }
117 }
118
119 if (last_motion_notify == NULL) {
120 return true;
121 }
122
123 if (!dragloop->threshold_exceeded &&
124 threshold_exceeded(last_motion_notify->root_x, last_motion_notify->root_y,
125 dragloop->event->root_x, dragloop->event->root_y)) {
126 if (dragloop->xcursor != XCB_NONE) {
127 xcb_change_active_pointer_grab(
128 conn,
129 dragloop->xcursor,
130 XCB_CURRENT_TIME,
131 XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION);
132 }
133 dragloop->threshold_exceeded = true;
134 }
135
136 /* Ensure that we are either dragging the resize handle (con is NULL) or that the
137 * container still exists. The latter might not be true, e.g., if the window closed
138 * for any reason while the user was dragging it. */
139 if (dragloop->threshold_exceeded && (!dragloop->con || con_exists(dragloop->con))) {
140 dragloop->callback(
141 dragloop->con,
142 &(dragloop->old_rect),
143 last_motion_notify->root_x,
144 last_motion_notify->root_y,
145 dragloop->event,
146 dragloop->extra);
147 }
148 FREE(last_motion_notify);
149
150 xcb_flush(conn);
151 return dragloop->result != DRAGGING;
152 }
153
154 static void xcb_drag_prepare_cb(EV_P_ ev_prepare *w, int revents) {
155 struct drag_x11_cb *dragloop = (struct drag_x11_cb *)w->data;
156 while (!drain_drag_events(EV_A, dragloop)) {
157 /* repeatedly drain events: draining might produce additional ones */
158 }
159 }
160
161 /*
162 * This function grabs your pointer and keyboard and lets you drag stuff around
163 * (borders). Every time you move your mouse, an XCB_MOTION_NOTIFY event will
164 * be received and the given callback will be called with the parameters
165 * specified (client, the original event), the original rect of the client,
166 * and the new coordinates (x, y).
167 *
168 * If use_threshold is set, dragging only starts after the user moves the
169 * pointer past a certain threshold. That is, the cursor will not be set and the
170 * callback will not be called until then.
171 *
172 */
173 drag_result_t drag_pointer(Con *con, const xcb_button_press_event_t *event,
174 xcb_window_t confine_to, int cursor,
175 bool use_threshold, callback_t callback,
176 const void *extra) {
177 xcb_cursor_t xcursor = cursor ? xcursor_get_cursor(cursor) : XCB_NONE;
178
179 /* Grab the pointer */
180 xcb_grab_pointer_cookie_t cookie;
181 xcb_grab_pointer_reply_t *reply;
182 xcb_generic_error_t *error;
183
184 cookie = xcb_grab_pointer(conn,
185 false, /* get all pointer events specified by the following mask */
186 root, /* grab the root window */
187 XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION, /* which events to let through */
188 XCB_GRAB_MODE_ASYNC, /* pointer events should continue as normal */
189 XCB_GRAB_MODE_ASYNC, /* keyboard mode */
190 confine_to, /* confine_to = in which window should the cursor stay */
191 use_threshold ? XCB_NONE : xcursor, /* possibly display a special cursor */
192 XCB_CURRENT_TIME);
193
194 if ((reply = xcb_grab_pointer_reply(conn, cookie, &error)) == NULL) {
195 ELOG("Could not grab pointer (error_code = %d)\n", error->error_code);
196 free(error);
197 return DRAG_ABORT;
198 }
199
200 free(reply);
201
202 /* Grab the keyboard */
203 xcb_grab_keyboard_cookie_t keyb_cookie;
204 xcb_grab_keyboard_reply_t *keyb_reply;
205
206 keyb_cookie = xcb_grab_keyboard(conn,
207 false, /* get all keyboard events */
208 root, /* grab the root window */
209 XCB_CURRENT_TIME,
210 XCB_GRAB_MODE_ASYNC, /* continue processing pointer events as normal */
211 XCB_GRAB_MODE_ASYNC /* keyboard mode */
212 );
213
214 if ((keyb_reply = xcb_grab_keyboard_reply(conn, keyb_cookie, &error)) == NULL) {
215 ELOG("Could not grab keyboard (error_code = %d)\n", error->error_code);
216 free(error);
217 xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
218 return DRAG_ABORT;
219 }
220
221 free(keyb_reply);
222
223 /* Go into our own event loop */
224 struct drag_x11_cb loop = {
225 .result = DRAGGING,
226 .con = con,
227 .event = event,
228 .callback = callback,
229 .threshold_exceeded = !use_threshold,
230 .xcursor = xcursor,
231 .extra = extra,
232 };
233 ev_prepare *prepare = &loop.prepare;
234 if (con)
235 loop.old_rect = con->rect;
236 ev_prepare_init(prepare, xcb_drag_prepare_cb);
237 prepare->data = &loop;
238 main_set_x11_cb(false);
239 ev_prepare_start(main_loop, prepare);
240
241 ev_loop(main_loop, 0);
242
243 ev_prepare_stop(main_loop, prepare);
244 main_set_x11_cb(true);
245
246 xcb_ungrab_keyboard(conn, XCB_CURRENT_TIME);
247 xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
248 xcb_flush(conn);
249
250 return loop.result;
251 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * ewmh.c: Get/set certain EWMH properties easily.
7 *
8 */
9 #include "all.h"
10
11 xcb_window_t ewmh_window;
12
13 #define FOREACH_NONINTERNAL \
14 TAILQ_FOREACH (output, &(croot->nodes_head), nodes) \
15 TAILQ_FOREACH (ws, &(output_get_content(output)->nodes_head), nodes) \
16 if (!con_is_internal(ws))
17
18 /*
19 * Updates _NET_CURRENT_DESKTOP with the current desktop number.
20 *
21 * EWMH: The index of the current desktop. This is always an integer between 0
22 * and _NET_NUMBER_OF_DESKTOPS - 1.
23 *
24 */
25 void ewmh_update_current_desktop(void) {
26 static uint32_t old_idx = NET_WM_DESKTOP_NONE;
27 const uint32_t idx = ewmh_get_workspace_index(focused);
28
29 if (idx == old_idx || idx == NET_WM_DESKTOP_NONE) {
30 return;
31 }
32 old_idx = idx;
33
34 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_CURRENT_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, &idx);
35 }
36
37 /*
38 * Updates _NET_NUMBER_OF_DESKTOPS which we interpret as the number of
39 * noninternal workspaces.
40 */
41 static void ewmh_update_number_of_desktops(void) {
42 Con *output, *ws;
43 static uint32_t old_idx = 0;
44 uint32_t idx = 0;
45
46 FOREACH_NONINTERNAL {
47 idx++;
48 };
49
50 if (idx == old_idx) {
51 return;
52 }
53 old_idx = idx;
54
55 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root,
56 A__NET_NUMBER_OF_DESKTOPS, XCB_ATOM_CARDINAL, 32, 1, &idx);
57 }
58
59 /*
60 * Updates _NET_DESKTOP_NAMES: "The names of all virtual desktops. This is a
61 * list of NULL-terminated strings in UTF-8 encoding"
62 */
63 static void ewmh_update_desktop_names(void) {
64 Con *output, *ws;
65 int msg_length = 0;
66
67 /* count the size of the property message to set */
68 FOREACH_NONINTERNAL {
69 msg_length += strlen(ws->name) + 1;
70 };
71
72 char desktop_names[msg_length];
73 int current_position = 0;
74
75 /* fill the buffer with the names of the i3 workspaces */
76 FOREACH_NONINTERNAL {
77 for (size_t i = 0; i < strlen(ws->name) + 1; i++) {
78 desktop_names[current_position++] = ws->name[i];
79 }
80 }
81
82 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root,
83 A__NET_DESKTOP_NAMES, A_UTF8_STRING, 8, msg_length, desktop_names);
84 }
85
86 /*
87 * Updates _NET_DESKTOP_VIEWPORT, which is an array of pairs of cardinals that
88 * define the top left corner of each desktop's viewport.
89 */
90 static void ewmh_update_desktop_viewport(void) {
91 Con *output, *ws;
92 int num_desktops = 0;
93 /* count number of desktops */
94 FOREACH_NONINTERNAL {
95 num_desktops++;
96 }
97
98 uint32_t viewports[num_desktops * 2];
99
100 int current_position = 0;
101 /* fill the viewport buffer */
102 FOREACH_NONINTERNAL {
103 viewports[current_position++] = output->rect.x;
104 viewports[current_position++] = output->rect.y;
105 }
106
107 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root,
108 A__NET_DESKTOP_VIEWPORT, XCB_ATOM_CARDINAL, 32, current_position, &viewports);
109 }
110
111 /*
112 * Updates all the EWMH desktop properties.
113 *
114 */
115 void ewmh_update_desktop_properties(void) {
116 ewmh_update_number_of_desktops();
117 ewmh_update_desktop_viewport();
118 ewmh_update_current_desktop();
119 ewmh_update_desktop_names();
120 ewmh_update_wm_desktop();
121 }
122
123 static void ewmh_update_wm_desktop_recursively(Con *con, const uint32_t desktop) {
124 Con *child;
125
126 /* Recursively call this to descend through the entire subtree. */
127 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
128 ewmh_update_wm_desktop_recursively(child, desktop);
129 }
130
131 /* If con is a workspace, we also need to go through the floating windows on it. */
132 if (con->type == CT_WORKSPACE) {
133 TAILQ_FOREACH (child, &(con->floating_head), floating_windows) {
134 ewmh_update_wm_desktop_recursively(child, desktop);
135 }
136 }
137
138 if (!con_has_managed_window(con))
139 return;
140
141 uint32_t wm_desktop = desktop;
142 /* Sticky windows are only actually sticky when they are floating or inside
143 * a floating container. This is technically still slightly wrong, since
144 * sticky windows will only be on all workspaces on this output, but we
145 * ignore multi-monitor situations for this since the spec isn't too
146 * precise on this anyway. */
147 if (con_is_sticky(con) && con_is_floating(con)) {
148 wm_desktop = NET_WM_DESKTOP_ALL;
149 }
150
151 /* If the window is on the scratchpad we assign the sticky value to it
152 * since showing it works on any workspace. We cannot remove the property
153 * as per specification. */
154 Con *ws = con_get_workspace(con);
155 if (ws != NULL && con_is_internal(ws)) {
156 wm_desktop = NET_WM_DESKTOP_ALL;
157 }
158
159 /* If this is the cached value, we don't need to do anything. */
160 if (con->window->wm_desktop == wm_desktop)
161 return;
162 con->window->wm_desktop = wm_desktop;
163
164 const xcb_window_t window = con->window->id;
165 if (wm_desktop != NET_WM_DESKTOP_NONE) {
166 DLOG("Setting _NET_WM_DESKTOP = %d for window 0x%08x.\n", wm_desktop, window);
167 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, window, A__NET_WM_DESKTOP, XCB_ATOM_CARDINAL, 32, 1, &wm_desktop);
168 } else {
169 /* If we can't determine the workspace index, delete the property. We'd
170 * rather not set it than lie. */
171 ELOG("Failed to determine the proper EWMH desktop index for window 0x%08x, deleting _NET_WM_DESKTOP.\n", window);
172 xcb_delete_property(conn, window, A__NET_WM_DESKTOP);
173 }
174 }
175
176 /*
177 * Updates _NET_WM_DESKTOP for all windows.
178 * A request will only be made if the cached value differs from the calculated value.
179 *
180 */
181 void ewmh_update_wm_desktop(void) {
182 uint32_t desktop = 0;
183
184 Con *output;
185 TAILQ_FOREACH (output, &(croot->nodes_head), nodes) {
186 Con *workspace;
187 TAILQ_FOREACH (workspace, &(output_get_content(output)->nodes_head), nodes) {
188 ewmh_update_wm_desktop_recursively(workspace, desktop);
189
190 if (!con_is_internal(workspace)) {
191 ++desktop;
192 }
193 }
194 }
195 }
196
197 /*
198 * Updates _NET_ACTIVE_WINDOW with the currently focused window.
199 *
200 * EWMH: The window ID of the currently active window or None if no window has
201 * the focus.
202 *
203 */
204 void ewmh_update_active_window(xcb_window_t window) {
205 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root,
206 A__NET_ACTIVE_WINDOW, XCB_ATOM_WINDOW, 32, 1, &window);
207 }
208
209 /*
210 * Updates _NET_WM_VISIBLE_NAME.
211 *
212 */
213 void ewmh_update_visible_name(xcb_window_t window, const char *name) {
214 if (name != NULL) {
215 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, window, A__NET_WM_VISIBLE_NAME, A_UTF8_STRING, 8, strlen(name), name);
216 } else {
217 xcb_delete_property(conn, window, A__NET_WM_VISIBLE_NAME);
218 }
219 }
220
221 /*
222 * i3 currently does not support _NET_WORKAREA, because it does not correspond
223 * to i3’s concept of workspaces. See also:
224 * https://bugs.i3wm.org/539
225 * https://bugs.i3wm.org/301
226 * https://bugs.i3wm.org/1038
227 *
228 * We need to actively delete this property because some display managers (e.g.
229 * LightDM) set it.
230 *
231 * EWMH: Contains a geometry for each desktop. These geometries specify an area
232 * that is completely contained within the viewport. Work area SHOULD be used by
233 * desktop applications to place desktop icons appropriately.
234 *
235 */
236 void ewmh_update_workarea(void) {
237 xcb_delete_property(conn, root, A__NET_WORKAREA);
238 }
239
240 /*
241 * Updates the _NET_CLIENT_LIST hint.
242 *
243 */
244 void ewmh_update_client_list(xcb_window_t *list, int num_windows) {
245 xcb_change_property(
246 conn,
247 XCB_PROP_MODE_REPLACE,
248 root,
249 A__NET_CLIENT_LIST,
250 XCB_ATOM_WINDOW,
251 32,
252 num_windows,
253 list);
254 }
255
256 /*
257 * Updates the _NET_CLIENT_LIST_STACKING hint.
258 *
259 */
260 void ewmh_update_client_list_stacking(xcb_window_t *stack, int num_windows) {
261 xcb_change_property(
262 conn,
263 XCB_PROP_MODE_REPLACE,
264 root,
265 A__NET_CLIENT_LIST_STACKING,
266 XCB_ATOM_WINDOW,
267 32,
268 num_windows,
269 stack);
270 }
271
272 /*
273 * Set or remove _NET_WM_STATE_STICKY on the window.
274 *
275 */
276 void ewmh_update_sticky(xcb_window_t window, bool sticky) {
277 if (sticky) {
278 DLOG("Setting _NET_WM_STATE_STICKY for window = %d.\n", window);
279 xcb_add_property_atom(conn, window, A__NET_WM_STATE, A__NET_WM_STATE_STICKY);
280 } else {
281 DLOG("Removing _NET_WM_STATE_STICKY for window = %d.\n", window);
282 xcb_remove_property_atom(conn, window, A__NET_WM_STATE, A__NET_WM_STATE_STICKY);
283 }
284 }
285
286 /*
287 * Set or remove _NEW_WM_STATE_FOCUSED on the window.
288 *
289 */
290 void ewmh_update_focused(xcb_window_t window, bool is_focused) {
291 if (is_focused) {
292 DLOG("Setting _NET_WM_STATE_FOCUSED for window = %d.\n", window);
293 xcb_add_property_atom(conn, window, A__NET_WM_STATE, A__NET_WM_STATE_FOCUSED);
294 } else {
295 DLOG("Removing _NET_WM_STATE_FOCUSED for window = %d.\n", window);
296 xcb_remove_property_atom(conn, window, A__NET_WM_STATE, A__NET_WM_STATE_FOCUSED);
297 }
298 }
299
300 /*
301 * Set up the EWMH hints on the root window.
302 *
303 */
304 void ewmh_setup_hints(void) {
305 xcb_atom_t supported_atoms[] = {
306 #define xmacro(atom) A_##atom,
307 #include "atoms_NET_SUPPORTED.xmacro"
308 #undef xmacro
309 };
310
311 /* Set up the window manager’s name. According to EWMH, section "Root Window
312 * Properties", to indicate that an EWMH-compliant window manager is
313 * present, a child window has to be created (and kept alive as long as the
314 * window manager is running) which has the _NET_SUPPORTING_WM_CHECK and
315 * _NET_WM_ATOMS. */
316 ewmh_window = xcb_generate_id(conn);
317 /* We create the window and put it at (-1, -1) so that it is off-screen. */
318 xcb_create_window(
319 conn,
320 XCB_COPY_FROM_PARENT, /* depth */
321 ewmh_window, /* window id */
322 root, /* parent */
323 -1, -1, 1, 1, /* dimensions (x, y, w, h) */
324 0, /* border */
325 XCB_WINDOW_CLASS_INPUT_ONLY, /* window class */
326 XCB_COPY_FROM_PARENT, /* visual */
327 XCB_CW_OVERRIDE_REDIRECT,
328 (uint32_t[]){1});
329 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, ewmh_window, A__NET_SUPPORTING_WM_CHECK, XCB_ATOM_WINDOW, 32, 1, &ewmh_window);
330 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, ewmh_window, A__NET_WM_NAME, A_UTF8_STRING, 8, strlen("i3"), "i3");
331 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTING_WM_CHECK, XCB_ATOM_WINDOW, 32, 1, &ewmh_window);
332
333 /* I’m not entirely sure if we need to keep _NET_WM_NAME on root. */
334 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_WM_NAME, A_UTF8_STRING, 8, strlen("i3"), "i3");
335
336 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_SUPPORTED, XCB_ATOM_ATOM, 32, /* number of atoms */ sizeof(supported_atoms) / sizeof(xcb_atom_t), supported_atoms);
337
338 /* We need to map this window to be able to set the input focus to it if no other window is available to be focused. */
339 xcb_map_window(conn, ewmh_window);
340 xcb_configure_window(conn, ewmh_window, XCB_CONFIG_WINDOW_STACK_MODE, (uint32_t[]){XCB_STACK_MODE_BELOW});
341 }
342
343 /*
344 * Returns the workspace container as enumerated by the EWMH desktop model.
345 * Returns NULL if no workspace could be found for the index.
346 *
347 * This is the reverse of ewmh_get_workspace_index.
348 *
349 */
350 Con *ewmh_get_workspace_by_index(uint32_t idx) {
351 if (idx == NET_WM_DESKTOP_NONE)
352 return NULL;
353
354 uint32_t current_index = 0;
355
356 Con *output, *ws;
357 FOREACH_NONINTERNAL {
358 if (current_index == idx) {
359 return ws;
360 }
361 current_index++;
362 }
363
364 return NULL;
365 }
366
367 /*
368 * Returns the EWMH desktop index for the workspace the given container is on.
369 * Returns NET_WM_DESKTOP_NONE if the desktop index cannot be determined.
370 *
371 * This is the reverse of ewmh_get_workspace_by_index.
372 *
373 */
374 uint32_t ewmh_get_workspace_index(Con *con) {
375 uint32_t index = 0;
376
377 Con *target_workspace = con_get_workspace(con);
378 Con *output, *ws;
379 FOREACH_NONINTERNAL {
380 if (ws == target_workspace) {
381 return index;
382 }
383
384 index++;
385 }
386
387 return NET_WM_DESKTOP_NONE;
388 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * Faking outputs is useful in pathological situations (like network X servers
7 * which don’t support multi-monitor in a useful way) and for our testsuite.
8 *
9 */
10 #include "all.h"
11
12 static int num_screens;
13
14 /*
15 * Looks in outputs for the Output whose start coordinates are x, y
16 *
17 */
18 static Output *get_screen_at(unsigned int x, unsigned int y) {
19 Output *output;
20 TAILQ_FOREACH (output, &outputs, outputs) {
21 if (output->rect.x == x && output->rect.y == y) {
22 return output;
23 }
24 }
25
26 return NULL;
27 }
28
29 /*
30 * Creates outputs according to the given specification.
31 * The specification must be in the format wxh+x+y, for example 1024x768+0+0,
32 * optionally followed by 'P' to indicate a primary output,
33 * with multiple outputs separated by commas:
34 * 1900x1200+0+0P,1280x1024+1900+0
35 *
36 */
37 void fake_outputs_init(const char *output_spec) {
38 const char *walk = output_spec;
39 unsigned int x, y, width, height;
40 int chars_consumed;
41 while (sscanf(walk, "%ux%u+%u+%u%n", &width, &height, &x, &y, &chars_consumed) == 4) {
42 walk += chars_consumed;
43 bool primary = false;
44 if (*walk == 'P') {
45 primary = true;
46 walk++;
47 }
48 if (*walk == ',')
49 walk++; /* Skip delimiter */
50 DLOG("Parsed output as width = %u, height = %u at (%u, %u)%s\n",
51 width, height, x, y, primary ? " (primary)" : "");
52
53 Output *new_output = get_screen_at(x, y);
54 if (new_output != NULL) {
55 DLOG("Re-used old output %p\n", new_output);
56 /* This screen already exists. We use the littlest screen so that the user
57 can always see the complete workspace */
58 new_output->rect.width = min(new_output->rect.width, width);
59 new_output->rect.height = min(new_output->rect.height, height);
60 } else {
61 struct output_name *output_name = scalloc(1, sizeof(struct output_name));
62 new_output = scalloc(1, sizeof(Output));
63 sasprintf(&(output_name->name), "fake-%d", num_screens);
64 SLIST_INIT(&(new_output->names_head));
65 SLIST_INSERT_HEAD(&(new_output->names_head), output_name, names);
66 DLOG("Created new fake output %s (%p)\n", output_primary_name(new_output), new_output);
67 new_output->active = true;
68 new_output->rect.x = x;
69 new_output->rect.y = y;
70 new_output->rect.width = width;
71 new_output->rect.height = height;
72 /* We always treat the screen at 0x0 as the primary screen */
73 if (new_output->rect.x == 0 && new_output->rect.y == 0)
74 TAILQ_INSERT_HEAD(&outputs, new_output, outputs);
75 else
76 TAILQ_INSERT_TAIL(&outputs, new_output, outputs);
77 output_init_con(new_output);
78 init_ws_for_output(new_output);
79 num_screens++;
80 }
81 new_output->primary = primary;
82 }
83
84 if (num_screens == 0) {
85 ELOG("No screens found. Please fix your setup. i3 will exit now.\n");
86 exit(EXIT_FAILURE);
87 }
88 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * floating.c: Floating windows.
7 *
8 */
9 #include "all.h"
10
11 #ifndef MAX
12 #define MAX(x, y) ((x) > (y) ? (x) : (y))
13 #endif
14
15 /*
16 * Calculates sum of heights and sum of widths of all currently active outputs
17 *
18 */
19 static Rect total_outputs_dimensions(void) {
20 if (TAILQ_EMPTY(&outputs))
21 return (Rect){0, 0, root_screen->width_in_pixels, root_screen->height_in_pixels};
22
23 Output *output;
24 /* Use Rect to encapsulate dimensions, ignoring x/y */
25 Rect outputs_dimensions = {0, 0, 0, 0};
26 TAILQ_FOREACH (output, &outputs, outputs) {
27 outputs_dimensions.height += output->rect.height;
28 outputs_dimensions.width += output->rect.width;
29 }
30 return outputs_dimensions;
31 }
32
33 /*
34 * Updates I3_FLOATING_WINDOW by either setting or removing it on the con and
35 * all its children.
36 *
37 */
38 static void floating_set_hint_atom(Con *con, bool floating) {
39 if (!con_is_leaf(con)) {
40 Con *child;
41 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
42 floating_set_hint_atom(child, floating);
43 }
44 }
45
46 if (con->window == NULL) {
47 return;
48 }
49
50 if (floating) {
51 uint32_t val = 1;
52 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, con->window->id,
53 A_I3_FLOATING_WINDOW, XCB_ATOM_CARDINAL, 32, 1, &val);
54 } else {
55 xcb_delete_property(conn, con->window->id, A_I3_FLOATING_WINDOW);
56 }
57
58 xcb_flush(conn);
59 }
60
61 /*
62 * Called when a floating window is created or resized. This function resizes
63 * the window if its size is higher or lower than the configured maximum/minimum
64 * size, respectively or when adjustments are needed to conform to the
65 * configured size increments or aspect ratio limits.
66 *
67 * When prefer_height is true and the window needs to be resized because of the
68 * configured aspect ratio, the width is adjusted first, preserving the previous
69 * height.
70 *
71 */
72 void floating_check_size(Con *floating_con, bool prefer_height) {
73 /* Define reasonable minimal and maximal sizes for floating windows */
74 const int floating_sane_min_height = 50;
75 const int floating_sane_min_width = 75;
76 Rect floating_sane_max_dimensions;
77 Con *focused_con = con_descend_focused(floating_con);
78
79 Rect border_rect = con_border_style_rect(focused_con);
80 /* We have to do the opposite calculations that render_con() do
81 * to get the exact size we want. */
82 border_rect.width = -border_rect.width;
83 border_rect.width += 2 * focused_con->border_width;
84 border_rect.height = -border_rect.height;
85 border_rect.height += 2 * focused_con->border_width;
86 if (con_border_style(focused_con) == BS_NORMAL) {
87 border_rect.height += render_deco_height();
88 }
89
90 i3Window *window = focused_con->window;
91 if (window != NULL) {
92 /* ICCCM says: If a base size is not provided, the minimum size is to be used in its place
93 * and vice versa. */
94 int min_width = (window->min_width ? window->min_width : window->base_width);
95 int min_height = (window->min_height ? window->min_height : window->base_height);
96 int base_width = (window->base_width ? window->base_width : window->min_width);
97 int base_height = (window->base_height ? window->base_height : window->min_height);
98
99 if (min_width) {
100 floating_con->rect.width -= border_rect.width;
101 floating_con->rect.width = max(floating_con->rect.width, min_width);
102 floating_con->rect.width += border_rect.width;
103 }
104
105 if (min_height) {
106 floating_con->rect.height -= border_rect.height;
107 floating_con->rect.height = max(floating_con->rect.height, min_height);
108 floating_con->rect.height += border_rect.height;
109 }
110
111 if (window->max_width) {
112 floating_con->rect.width -= border_rect.width;
113 floating_con->rect.width = min(floating_con->rect.width, window->max_width);
114 floating_con->rect.width += border_rect.width;
115 }
116
117 if (window->max_height) {
118 floating_con->rect.height -= border_rect.height;
119 floating_con->rect.height = min(floating_con->rect.height, window->max_height);
120 floating_con->rect.height += border_rect.height;
121 }
122
123 /* Obey the aspect ratio, if any, unless we are in fullscreen mode.
124 *
125 * The spec isn’t explicit on whether the aspect ratio hints should be
126 * respected during fullscreen mode. Other WMs such as Openbox don’t do
127 * that, and this post suggests that this is the correct way to do it:
128 * https://mail.gnome.org/archives/wm-spec-list/2003-May/msg00007.html
129 *
130 * Ignoring aspect ratio during fullscreen was necessary to fix MPlayer
131 * subtitle rendering, see https://bugs.i3wm.org/594 */
132 const double min_ar = window->min_aspect_ratio;
133 const double max_ar = window->max_aspect_ratio;
134 if (floating_con->fullscreen_mode == CF_NONE && (min_ar > 0 || max_ar > 0)) {
135 /* The ICCCM says to subtract the base size from the window size for
136 * aspect ratio calculations. However, unlike determining the base
137 * size itself we must not fall back to using the minimum size in
138 * this case according to the ICCCM. */
139 double width = floating_con->rect.width - window->base_width - border_rect.width;
140 double height = floating_con->rect.height - window->base_height - border_rect.height;
141 const double ar = (double)width / (double)height;
142 double new_ar = -1;
143 if (min_ar > 0 && ar < min_ar) {
144 new_ar = min_ar;
145 } else if (max_ar > 0 && ar > max_ar) {
146 new_ar = max_ar;
147 }
148 if (new_ar > 0) {
149 if (prefer_height) {
150 width = round(height * new_ar);
151 height = round(width / new_ar);
152 } else {
153 height = round(width / new_ar);
154 width = round(height * new_ar);
155 }
156 floating_con->rect.width = width + window->base_width + border_rect.width;
157 floating_con->rect.height = height + window->base_height + border_rect.height;
158 }
159 }
160
161 if (window->height_increment &&
162 floating_con->rect.height >= base_height + border_rect.height) {
163 floating_con->rect.height -= base_height + border_rect.height;
164 floating_con->rect.height -= floating_con->rect.height % window->height_increment;
165 floating_con->rect.height += base_height + border_rect.height;
166 }
167
168 if (window->width_increment &&
169 floating_con->rect.width >= base_width + border_rect.width) {
170 floating_con->rect.width -= base_width + border_rect.width;
171 floating_con->rect.width -= floating_con->rect.width % window->width_increment;
172 floating_con->rect.width += base_width + border_rect.width;
173 }
174 }
175
176 /* Unless user requests otherwise (-1), raise the width/height to
177 * reasonable minimum dimensions */
178 if (config.floating_minimum_height != -1) {
179 floating_con->rect.height -= border_rect.height;
180 if (config.floating_minimum_height == 0) {
181 floating_con->rect.height = max(floating_con->rect.height, floating_sane_min_height);
182 } else {
183 floating_con->rect.height = max(floating_con->rect.height, config.floating_minimum_height);
184 }
185 floating_con->rect.height += border_rect.height;
186 }
187
188 if (config.floating_minimum_width != -1) {
189 floating_con->rect.width -= border_rect.width;
190 if (config.floating_minimum_width == 0) {
191 floating_con->rect.width = max(floating_con->rect.width, floating_sane_min_width);
192 } else {
193 floating_con->rect.width = max(floating_con->rect.width, config.floating_minimum_width);
194 }
195 floating_con->rect.width += border_rect.width;
196 }
197
198 /* Unless user requests otherwise (-1), ensure width/height do not exceed
199 * configured maxima or, if unconfigured, limit to combined width of all
200 * outputs */
201 floating_sane_max_dimensions = total_outputs_dimensions();
202 if (config.floating_maximum_height != -1) {
203 floating_con->rect.height -= border_rect.height;
204 if (config.floating_maximum_height == 0) {
205 floating_con->rect.height = min(floating_con->rect.height, floating_sane_max_dimensions.height);
206 } else {
207 floating_con->rect.height = min(floating_con->rect.height, config.floating_maximum_height);
208 }
209 floating_con->rect.height += border_rect.height;
210 }
211
212 if (config.floating_maximum_width != -1) {
213 floating_con->rect.width -= border_rect.width;
214 if (config.floating_maximum_width == 0) {
215 floating_con->rect.width = min(floating_con->rect.width, floating_sane_max_dimensions.width);
216 } else {
217 floating_con->rect.width = min(floating_con->rect.width, config.floating_maximum_width);
218 }
219 floating_con->rect.width += border_rect.width;
220 }
221 }
222
223 void floating_enable(Con *con, bool automatic) {
224 bool set_focus = (con == focused);
225
226 if (con_is_docked(con)) {
227 LOG("Container is a dock window, not enabling floating mode.\n");
228 return;
229 }
230
231 if (con_is_floating(con)) {
232 LOG("Container is already in floating mode, not doing anything.\n");
233 return;
234 }
235
236 if (con->type == CT_WORKSPACE) {
237 LOG("Container is a workspace, not enabling floating mode.\n");
238 return;
239 }
240
241 Con *focus_head_placeholder = NULL;
242 bool focus_before_parent = true;
243 if (!set_focus) {
244 /* Find recursively the ancestor container which is a child of our workspace.
245 * We need to reuse its focus position later. */
246 Con *ancestor = con;
247 while (ancestor->parent->type != CT_WORKSPACE) {
248 focus_before_parent &= TAILQ_FIRST(&(ancestor->parent->focus_head)) == ancestor;
249 ancestor = ancestor->parent;
250 }
251 /* Consider the part of the focus stack of our current workspace:
252 * [ ... S_{i-1} S_{i} S_{i+1} ... ]
253 * Where S_{x} is a container tree and the container 'con' that is beeing switched to
254 * floating belongs in S_{i}. The new floating container, 'nc', will have the
255 * workspace as its parent so it needs to be placed in this stack. If C was focused
256 * we just need to call con_focus(). Otherwise, nc must be placed before or after S_{i}.
257 * We should avoid using the S_{i} container for our operations since it might get
258 * killed if it has no other children. So, the two possible positions are after S_{i-1}
259 * or before S_{i+1}.
260 */
261 if (focus_before_parent) {
262 focus_head_placeholder = TAILQ_PREV(ancestor, focus_head, focused);
263 } else {
264 focus_head_placeholder = TAILQ_NEXT(ancestor, focused);
265 }
266 }
267
268 /* 1: detach the container from its parent */
269 /* TODO: refactor this with tree_close_internal() */
270 con_detach(con);
271 con_fix_percent(con->parent);
272
273 /* 2: create a new container to render the decoration on, add
274 * it as a floating window to the workspace */
275 Con *nc = con_new(NULL, NULL);
276 /* we need to set the parent afterwards instead of passing it as an
277 * argument to con_new() because nc would be inserted into the tiling layer
278 * otherwise. */
279 Con *ws = con_get_workspace(con);
280 nc->parent = ws;
281 nc->type = CT_FLOATING_CON;
282 nc->layout = L_SPLITH;
283 /* We insert nc already, even though its rect is not yet calculated. This
284 * is necessary because otherwise the workspace might be empty (and get
285 * closed in tree_close_internal()) even though it’s not. */
286 TAILQ_INSERT_HEAD(&(ws->floating_head), nc, floating_windows);
287
288 struct focus_head *fh = &(ws->focus_head);
289 if (focus_before_parent) {
290 if (focus_head_placeholder) {
291 TAILQ_INSERT_AFTER(fh, focus_head_placeholder, nc, focused);
292 } else {
293 TAILQ_INSERT_HEAD(fh, nc, focused);
294 }
295 } else {
296 if (focus_head_placeholder) {
297 TAILQ_INSERT_BEFORE(focus_head_placeholder, nc, focused);
298 } else {
299 /* Also used for the set_focus case */
300 TAILQ_INSERT_TAIL(fh, nc, focused);
301 }
302 }
303
304 /* check if the parent container is empty and close it if so */
305 if ((con->parent->type == CT_CON || con->parent->type == CT_FLOATING_CON) &&
306 con_num_children(con->parent) == 0) {
307 DLOG("Old container empty after setting this child to floating, closing\n");
308 Con *parent = con->parent;
309 /* clear the pointer before calling tree_close_internal in which the memory is freed */
310 con->parent = NULL;
311 tree_close_internal(parent, DONT_KILL_WINDOW, false);
312 }
313
314 char *name;
315 sasprintf(&name, "[i3 con] floatingcon around %p", con);
316 x_set_name(nc, name);
317 free(name);
318
319 /* find the height for the decorations */
320 int deco_height = render_deco_height();
321
322 DLOG("Original rect: (%d, %d) with %d x %d\n", con->rect.x, con->rect.y, con->rect.width, con->rect.height);
323 DLOG("Geometry = (%d, %d) with %d x %d\n", con->geometry.x, con->geometry.y, con->geometry.width, con->geometry.height);
324 nc->rect = con->geometry;
325 /* If the geometry was not set (split containers), we need to determine a
326 * sensible one by combining the geometry of all children */
327 if (rect_equals(nc->rect, (Rect){0, 0, 0, 0})) {
328 DLOG("Geometry not set, combining children\n");
329 Con *child;
330 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
331 DLOG("child geometry: %d x %d\n", child->geometry.width, child->geometry.height);
332 nc->rect.width += child->geometry.width;
333 nc->rect.height = max(nc->rect.height, child->geometry.height);
334 }
335 }
336
337 TAILQ_INSERT_TAIL(&(nc->nodes_head), con, nodes);
338 TAILQ_INSERT_TAIL(&(nc->focus_head), con, focused);
339
340 /* 3: attach the child to the new parent container. We need to do this
341 * because con_border_style_rect() needs to access con->parent. */
342 con->parent = nc;
343 con->percent = 1.0;
344 con->floating = FLOATING_USER_ON;
345
346 /* 4: set the border style as specified with new_float */
347 if (automatic)
348 con->border_style = config.default_floating_border;
349
350 /* Add pixels for the decoration. */
351 Rect border_style_rect = con_border_style_rect(con);
352
353 nc->rect.height -= border_style_rect.height;
354 nc->rect.width -= border_style_rect.width;
355
356 /* Add some more pixels for the title bar */
357 if (con_border_style(con) == BS_NORMAL) {
358 nc->rect.height += deco_height;
359 }
360
361 /* Honor the X11 border */
362 nc->rect.height += con->border_width * 2;
363 nc->rect.width += con->border_width * 2;
364
365 floating_check_size(nc, false);
366
367 /* Some clients (like GIMP’s color picker window) get mapped
368 * to (0, 0), so we push them to a reasonable position
369 * (centered over their leader) */
370 if (nc->rect.x == 0 && nc->rect.y == 0) {
371 Con *leader;
372 if (con->window && con->window->leader != XCB_NONE &&
373 con->window->id != con->window->leader &&
374 (leader = con_by_window_id(con->window->leader)) != NULL) {
375 DLOG("Centering above leader\n");
376 floating_center(nc, leader->rect);
377 } else {
378 /* center the window on workspace as fallback */
379 floating_center(nc, ws->rect);
380 }
381 }
382
383 /* Sanity check: Are the coordinates on the appropriate output? If not, we
384 * need to change them */
385 Output *current_output = get_output_from_rect(nc->rect);
386 Con *correct_output = con_get_output(ws);
387 if (!current_output || current_output->con != correct_output) {
388 DLOG("This floating window is on the wrong output, fixing coordinates (currently (%d, %d))\n",
389 nc->rect.x, nc->rect.y);
390
391 /* If moving from one output to another, keep the relative position
392 * consistent (e.g. a centered dialog will remain centered). */
393 if (current_output) {
394 floating_fix_coordinates(nc, &current_output->con->rect, &correct_output->rect);
395 /* Make sure that the result is in the correct output. */
396 current_output = get_output_from_rect(nc->rect);
397 }
398 if (!current_output || current_output->con != correct_output) {
399 floating_center(nc, ws->rect);
400 }
401 }
402
403 DLOG("Floating rect: (%d, %d) with %d x %d\n", nc->rect.x, nc->rect.y, nc->rect.width, nc->rect.height);
404
405 /* 5: Subtract the deco_height in order to make the floating window appear
406 * at precisely the position it specified in its original geometry (which
407 * is what applications might remember). */
408 deco_height = (con->border_style == BS_NORMAL ? render_deco_height() : 0);
409 nc->rect.y -= deco_height;
410
411 DLOG("Corrected y = %d (deco_height = %d)\n", nc->rect.y, deco_height);
412
413 /* render the cons to get initial window_rect correct */
414 render_con(nc, true);
415
416 if (set_focus)
417 con_activate(con);
418
419 floating_set_hint_atom(nc, true);
420 ipc_send_window_event("floating", con);
421 }
422
423 void floating_disable(Con *con) {
424 if (!con_is_floating(con)) {
425 LOG("Container isn't floating, not doing anything.\n");
426 return;
427 }
428
429 Con *ws = con_get_workspace(con);
430 if (con_is_internal(ws)) {
431 LOG("Can't disable floating for container in internal workspace.\n");
432 return;
433 }
434 Con *tiling_focused = con_descend_tiling_focused(ws);
435
436 if (tiling_focused->type == CT_WORKSPACE) {
437 Con *parent = con->parent;
438 con_detach(con);
439 con->parent = NULL;
440 tree_close_internal(parent, DONT_KILL_WINDOW, true);
441 con_attach(con, tiling_focused, false);
442 con->percent = 0.0;
443 con_fix_percent(con->parent);
444 } else {
445 insert_con_into(con, tiling_focused, AFTER);
446 }
447
448 con->floating = FLOATING_USER_OFF;
449 floating_set_hint_atom(con, false);
450 ipc_send_window_event("floating", con);
451 }
452
453 /*
454 * Toggles floating mode for the given container.
455 *
456 * If the automatic flag is set to true, this was an automatic update by a change of the
457 * window class from the application which can be overwritten by the user.
458 *
459 */
460 void toggle_floating_mode(Con *con, bool automatic) {
461 /* forbid the command to toggle floating on a CT_FLOATING_CON */
462 if (con->type == CT_FLOATING_CON) {
463 ELOG("Cannot toggle floating mode on con = %p because it is of type CT_FLOATING_CON.\n", con);
464 return;
465 }
466
467 /* see if the client is already floating */
468 if (con_is_floating(con)) {
469 LOG("already floating, re-setting to tiling\n");
470
471 floating_disable(con);
472 return;
473 }
474
475 floating_enable(con, automatic);
476 }
477
478 /*
479 * Raises the given container in the list of floating containers
480 *
481 */
482 void floating_raise_con(Con *con) {
483 DLOG("Raising floating con %p / %s\n", con, con->name);
484 TAILQ_REMOVE(&(con->parent->floating_head), con, floating_windows);
485 TAILQ_INSERT_TAIL(&(con->parent->floating_head), con, floating_windows);
486 }
487
488 /*
489 * Checks if con’s coordinates are within its workspace and re-assigns it to
490 * the actual workspace if not.
491 *
492 */
493 bool floating_maybe_reassign_ws(Con *con) {
494 if (con_is_internal(con_get_workspace(con))) {
495 DLOG("Con in an internal workspace\n");
496 return false;
497 }
498
499 Output *output = get_output_from_rect(con->rect);
500
501 if (!output) {
502 ELOG("No output found at destination coordinates?\n");
503 return false;
504 }
505
506 if (con_get_output(con) == output->con) {
507 DLOG("still the same ws\n");
508 return false;
509 }
510
511 DLOG("Need to re-assign!\n");
512
513 Con *content = output_get_content(output->con);
514 Con *ws = TAILQ_FIRST(&(content->focus_head));
515 DLOG("Moving con %p / %s to workspace %p / %s\n", con, con->name, ws, ws->name);
516 Con *needs_focus = con_descend_focused(con);
517 if (!con_inside_focused(needs_focus)) {
518 needs_focus = NULL;
519 }
520 con_move_to_workspace(con, ws, false, true, false);
521 if (needs_focus) {
522 workspace_show(ws);
523 con_activate(needs_focus);
524 }
525 return true;
526 }
527
528 /*
529 * Centers a floating con above the specified rect.
530 *
531 */
532 void floating_center(Con *con, Rect rect) {
533 con->rect.x = rect.x + (rect.width / 2) - (con->rect.width / 2);
534 con->rect.y = rect.y + (rect.height / 2) - (con->rect.height / 2);
535 }
536
537 /*
538 * Moves the given floating con to the current pointer position.
539 *
540 */
541 void floating_move_to_pointer(Con *con) {
542 assert(con->type == CT_FLOATING_CON);
543
544 xcb_query_pointer_reply_t *reply = xcb_query_pointer_reply(conn, xcb_query_pointer(conn, root), NULL);
545 if (reply == NULL) {
546 ELOG("could not query pointer position, not moving this container\n");
547 return;
548 }
549
550 Output *output = get_output_containing(reply->root_x, reply->root_y);
551 if (output == NULL) {
552 ELOG("The pointer is not on any output, cannot move the container here.\n");
553 return;
554 }
555
556 /* Determine where to put the window. */
557 int32_t x = reply->root_x - con->rect.width / 2;
558 int32_t y = reply->root_y - con->rect.height / 2;
559 FREE(reply);
560
561 /* Correct target coordinates to be in-bounds. */
562 x = MAX(x, (int32_t)output->rect.x);
563 y = MAX(y, (int32_t)output->rect.y);
564 if (x + con->rect.width > output->rect.x + output->rect.width)
565 x = output->rect.x + output->rect.width - con->rect.width;
566 if (y + con->rect.height > output->rect.y + output->rect.height)
567 y = output->rect.y + output->rect.height - con->rect.height;
568
569 /* Update container's coordinates to position it correctly. */
570 floating_reposition(con, (Rect){x, y, con->rect.width, con->rect.height});
571 }
572
573 DRAGGING_CB(drag_window_callback) {
574 /* Reposition the client correctly while moving */
575 con->rect.x = old_rect->x + (new_x - event->root_x);
576 con->rect.y = old_rect->y + (new_y - event->root_y);
577
578 render_con(con, true);
579 x_push_node(con);
580 xcb_flush(conn);
581
582 /* Check if we cross workspace boundaries while moving */
583 if (!floating_maybe_reassign_ws(con))
584 return;
585 /* Ensure not to warp the pointer while dragging */
586 x_set_warp_to(NULL);
587 tree_render();
588 }
589
590 /*
591 * Called when the user clicked on the titlebar of a floating window.
592 * Calls the drag_pointer function with the drag_window callback
593 *
594 */
595 void floating_drag_window(Con *con, const xcb_button_press_event_t *event, bool use_threshold) {
596 DLOG("floating_drag_window\n");
597
598 /* Push changes before dragging, so that the window gets raised now and not
599 * after the user releases the mouse button */
600 tree_render();
601
602 /* Store the initial rect in case of user revert/cancel */
603 Rect initial_rect = con->rect;
604
605 /* Drag the window */
606 drag_result_t drag_result = drag_pointer(con, event, XCB_NONE, XCURSOR_CURSOR_MOVE, use_threshold, drag_window_callback, NULL);
607
608 if (!con_exists(con)) {
609 DLOG("The container has been closed in the meantime.\n");
610 return;
611 }
612
613 /* If the user cancelled, undo the changes. */
614 if (drag_result == DRAG_REVERT) {
615 floating_reposition(con, initial_rect);
616 return;
617 }
618
619 /* If this is a scratchpad window, don't auto center it from now on. */
620 if (con->scratchpad_state == SCRATCHPAD_FRESH)
621 con->scratchpad_state = SCRATCHPAD_CHANGED;
622
623 tree_render();
624 }
625
626 /*
627 * This is an ugly data structure which we need because there is no standard
628 * way of having nested functions (only available as a gcc extension at the
629 * moment, clang doesn’t support it) or blocks (only available as a clang
630 * extension and only on Mac OS X systems at the moment).
631 *
632 */
633 struct resize_window_callback_params {
634 const border_t corner;
635 const bool proportional;
636 };
637
638 DRAGGING_CB(resize_window_callback) {
639 const struct resize_window_callback_params *params = extra;
640 border_t corner = params->corner;
641
642 int32_t dest_x = con->rect.x;
643 int32_t dest_y = con->rect.y;
644 uint32_t dest_width;
645 uint32_t dest_height;
646
647 double ratio = (double)old_rect->width / old_rect->height;
648
649 /* First guess: We resize by exactly the amount the mouse moved,
650 * taking into account in which corner the client was grabbed */
651 if (corner & BORDER_LEFT)
652 dest_width = old_rect->width - (new_x - event->root_x);
653 else
654 dest_width = old_rect->width + (new_x - event->root_x);
655
656 if (corner & BORDER_TOP)
657 dest_height = old_rect->height - (new_y - event->root_y);
658 else
659 dest_height = old_rect->height + (new_y - event->root_y);
660
661 /* User wants to keep proportions, so we may have to adjust our values */
662 if (params->proportional) {
663 dest_width = max(dest_width, (int)(dest_height * ratio));
664 dest_height = max(dest_height, (int)(dest_width / ratio));
665 }
666
667 con->rect = (Rect){dest_x, dest_y, dest_width, dest_height};
668
669 /* Obey window size */
670 floating_check_size(con, false);
671
672 /* If not the lower right corner is grabbed, we must also reposition
673 * the client by exactly the amount we resized it */
674 if (corner & BORDER_LEFT)
675 dest_x = old_rect->x + (old_rect->width - con->rect.width);
676
677 if (corner & BORDER_TOP)
678 dest_y = old_rect->y + (old_rect->height - con->rect.height);
679
680 con->rect.x = dest_x;
681 con->rect.y = dest_y;
682
683 render_con(con, true);
684 x_push_changes(croot);
685 }
686
687 /*
688 * Called when the user clicked on a floating window while holding the
689 * floating_modifier and the right mouse button.
690 * Calls the drag_pointer function with the resize_window callback
691 *
692 */
693 void floating_resize_window(Con *con, const bool proportional,
694 const xcb_button_press_event_t *event) {
695 DLOG("floating_resize_window\n");
696
697 /* corner saves the nearest corner to the original click. It contains
698 * a bitmask of the nearest borders (BORDER_LEFT, BORDER_RIGHT, …) */
699 border_t corner = 0;
700
701 if (event->event_x <= (int16_t)(con->rect.width / 2))
702 corner |= BORDER_LEFT;
703 else
704 corner |= BORDER_RIGHT;
705
706 int cursor = 0;
707 if (event->event_y <= (int16_t)(con->rect.height / 2)) {
708 corner |= BORDER_TOP;
709 cursor = (corner & BORDER_LEFT) ? XCURSOR_CURSOR_TOP_LEFT_CORNER : XCURSOR_CURSOR_TOP_RIGHT_CORNER;
710 } else {
711 corner |= BORDER_BOTTOM;
712 cursor = (corner & BORDER_LEFT) ? XCURSOR_CURSOR_BOTTOM_LEFT_CORNER : XCURSOR_CURSOR_BOTTOM_RIGHT_CORNER;
713 }
714
715 struct resize_window_callback_params params = {corner, proportional};
716
717 /* get the initial rect in case of revert/cancel */
718 Rect initial_rect = con->rect;
719
720 drag_result_t drag_result = drag_pointer(con, event, XCB_NONE, cursor, false, resize_window_callback, &params);
721
722 if (!con_exists(con)) {
723 DLOG("The container has been closed in the meantime.\n");
724 return;
725 }
726
727 /* If the user cancels, undo the resize */
728 if (drag_result == DRAG_REVERT)
729 floating_reposition(con, initial_rect);
730
731 /* If this is a scratchpad window, don't auto center it from now on. */
732 if (con->scratchpad_state == SCRATCHPAD_FRESH)
733 con->scratchpad_state = SCRATCHPAD_CHANGED;
734 }
735
736 /*
737 * Repositions the CT_FLOATING_CON to have the coordinates specified by
738 * newrect, but only if the coordinates are not out-of-bounds. Also reassigns
739 * the floating con to a different workspace if this move was across different
740 * outputs.
741 *
742 */
743 bool floating_reposition(Con *con, Rect newrect) {
744 /* Sanity check: Are the new coordinates on any output? If not, we
745 * ignore that request. */
746 if (!output_containing_rect(newrect)) {
747 ELOG("No output found at destination coordinates. Not repositioning.\n");
748 return false;
749 }
750
751 con->rect = newrect;
752
753 floating_maybe_reassign_ws(con);
754
755 /* If this is a scratchpad window, don't auto center it from now on. */
756 if (con->scratchpad_state == SCRATCHPAD_FRESH)
757 con->scratchpad_state = SCRATCHPAD_CHANGED;
758
759 tree_render();
760 return true;
761 }
762
763 /*
764 * Sets size of the CT_FLOATING_CON to specified dimensions. Might limit the
765 * actual size with regard to size constraints taken from user settings.
766 * Additionally, the dimensions may be upscaled until they're divisible by the
767 * window's size hints.
768 *
769 */
770 void floating_resize(Con *floating_con, uint32_t x, uint32_t y) {
771 DLOG("floating resize to %dx%d px\n", x, y);
772 Rect *rect = &floating_con->rect;
773 Con *focused_con = con_descend_focused(floating_con);
774 if (focused_con->window == NULL) {
775 DLOG("No window is focused. Not resizing.\n");
776 return;
777 }
778 int wi = focused_con->window->width_increment;
779 int hi = focused_con->window->height_increment;
780 bool prefer_height = (rect->width == x);
781 rect->width = x;
782 rect->height = y;
783 if (wi)
784 rect->width += (wi - 1 - rect->width) % wi;
785 if (hi)
786 rect->height += (hi - 1 - rect->height) % hi;
787
788 floating_check_size(floating_con, prefer_height);
789
790 /* If this is a scratchpad window, don't auto center it from now on. */
791 if (floating_con->scratchpad_state == SCRATCHPAD_FRESH)
792 floating_con->scratchpad_state = SCRATCHPAD_CHANGED;
793 }
794
795 /*
796 * Fixes the coordinates of the floating window whenever the window gets
797 * reassigned to a different output (or when the output’s rect changes).
798 *
799 */
800 void floating_fix_coordinates(Con *con, Rect *old_rect, Rect *new_rect) {
801 DLOG("Fixing coordinates of floating window %p (rect (%d, %d), %d x %d)\n",
802 con, con->rect.x, con->rect.y, con->rect.width, con->rect.height);
803 DLOG("old_rect = (%d, %d), %d x %d\n",
804 old_rect->x, old_rect->y, old_rect->width, old_rect->height);
805 DLOG("new_rect = (%d, %d), %d x %d\n",
806 new_rect->x, new_rect->y, new_rect->width, new_rect->height);
807 /* First we get the x/y coordinates relative to the x/y coordinates
808 * of the output on which the window is on */
809 int32_t rel_x = con->rect.x - old_rect->x + (int32_t)(con->rect.width / 2);
810 int32_t rel_y = con->rect.y - old_rect->y + (int32_t)(con->rect.height / 2);
811 /* Then we calculate a fraction, for example 0.63 for a window
812 * which is at y = 1212 of a 1920 px high output */
813 DLOG("rel_x = %d, rel_y = %d, fraction_x = %f, fraction_y = %f, output->w = %d, output->h = %d\n",
814 rel_x, rel_y, (double)rel_x / old_rect->width, (double)rel_y / old_rect->height,
815 old_rect->width, old_rect->height);
816 /* Here we have to multiply at first. Or we will lose precision when not compiled with -msse2 */
817 con->rect.x = (int32_t)new_rect->x + (double)(rel_x * (int32_t)new_rect->width) / (int32_t)old_rect->width - (int32_t)(con->rect.width / 2);
818 con->rect.y = (int32_t)new_rect->y + (double)(rel_y * (int32_t)new_rect->height) / (int32_t)old_rect->height - (int32_t)(con->rect.height / 2);
819 DLOG("Resulting coordinates: x = %d, y = %d\n", con->rect.x, con->rect.y);
820 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * handlers.c: Small handlers for various events (keypresses, focus changes,
7 * …).
8 *
9 */
10 #include "all.h"
11
12 #include <time.h>
13 #include <float.h>
14 #include <sys/time.h>
15 #include <xcb/randr.h>
16 #define SN_API_NOT_YET_FROZEN 1
17 #include <libsn/sn-monitor.h>
18
19 int randr_base = -1;
20 int xkb_base = -1;
21 int xkb_current_group;
22 int shape_base = -1;
23
24 /* After mapping/unmapping windows, a notify event is generated. However, we don’t want it,
25 since it’d trigger an infinite loop of switching between the different windows when
26 changing workspaces */
27 static SLIST_HEAD(ignore_head, Ignore_Event) ignore_events;
28
29 /*
30 * Adds the given sequence to the list of events which are ignored.
31 * If this ignore should only affect a specific response_type, pass
32 * response_type, otherwise, pass -1.
33 *
34 * Every ignored sequence number gets garbage collected after 5 seconds.
35 *
36 */
37 void add_ignore_event(const int sequence, const int response_type) {
38 struct Ignore_Event *event = smalloc(sizeof(struct Ignore_Event));
39
40 event->sequence = sequence;
41 event->response_type = response_type;
42 event->added = time(NULL);
43
44 SLIST_INSERT_HEAD(&ignore_events, event, ignore_events);
45 }
46
47 /*
48 * Checks if the given sequence is ignored and returns true if so.
49 *
50 */
51 bool event_is_ignored(const int sequence, const int response_type) {
52 struct Ignore_Event *event;
53 time_t now = time(NULL);
54 for (event = SLIST_FIRST(&ignore_events); event != SLIST_END(&ignore_events);) {
55 if ((now - event->added) > 5) {
56 struct Ignore_Event *save = event;
57 event = SLIST_NEXT(event, ignore_events);
58 SLIST_REMOVE(&ignore_events, save, Ignore_Event, ignore_events);
59 free(save);
60 } else
61 event = SLIST_NEXT(event, ignore_events);
62 }
63
64 SLIST_FOREACH (event, &ignore_events, ignore_events) {
65 if (event->sequence != sequence)
66 continue;
67
68 if (event->response_type != -1 &&
69 event->response_type != response_type)
70 continue;
71
72 /* instead of removing a sequence number we better wait until it gets
73 * garbage collected. it may generate multiple events (there are multiple
74 * enter_notifies for one configure_request, for example). */
75 //SLIST_REMOVE(&ignore_events, event, Ignore_Event, ignore_events);
76 //free(event);
77 return true;
78 }
79
80 return false;
81 }
82
83 /*
84 * Called with coordinates of an enter_notify event or motion_notify event
85 * to check if the user crossed virtual screen boundaries and adjust the
86 * current workspace, if so.
87 *
88 */
89 static void check_crossing_screen_boundary(uint32_t x, uint32_t y) {
90 Output *output;
91
92 /* If the user disable focus follows mouse, we have nothing to do here */
93 if (config.disable_focus_follows_mouse)
94 return;
95
96 if ((output = get_output_containing(x, y)) == NULL) {
97 ELOG("ERROR: No such screen\n");
98 return;
99 }
100
101 if (output->con == NULL) {
102 ELOG("ERROR: The screen is not recognized by i3 (no container associated)\n");
103 return;
104 }
105
106 /* Focus the output on which the user moved their cursor */
107 Con *old_focused = focused;
108 Con *next = con_descend_focused(output_get_content(output->con));
109 /* Since we are switching outputs, this *must* be a different workspace, so
110 * call workspace_show() */
111 workspace_show(con_get_workspace(next));
112 con_focus(next);
113
114 /* If the focus changed, we re-render to get updated decorations */
115 if (old_focused != focused)
116 tree_render();
117 }
118
119 /*
120 * When the user moves the mouse pointer onto a window, this callback gets called.
121 *
122 */
123 static void handle_enter_notify(xcb_enter_notify_event_t *event) {
124 Con *con;
125
126 last_timestamp = event->time;
127
128 DLOG("enter_notify for %08x, mode = %d, detail %d, serial %d\n",
129 event->event, event->mode, event->detail, event->sequence);
130 DLOG("coordinates %d, %d\n", event->event_x, event->event_y);
131 if (event->mode != XCB_NOTIFY_MODE_NORMAL) {
132 DLOG("This was not a normal notify, ignoring\n");
133 return;
134 }
135 /* Some events are not interesting, because they were not generated
136 * actively by the user, but by reconfiguration of windows */
137 if (event_is_ignored(event->sequence, XCB_ENTER_NOTIFY)) {
138 DLOG("Event ignored\n");
139 return;
140 }
141
142 bool enter_child = false;
143 /* Get container by frame or by child window */
144 if ((con = con_by_frame_id(event->event)) == NULL) {
145 con = con_by_window_id(event->event);
146 enter_child = true;
147 }
148
149 /* If we cannot find the container, the user moved their cursor to the root
150 * window. In this case and if they used it to a dock, we need to focus the
151 * workspace on the correct output. */
152 if (con == NULL || con->parent->type == CT_DOCKAREA) {
153 DLOG("Getting screen at %d x %d\n", event->root_x, event->root_y);
154 check_crossing_screen_boundary(event->root_x, event->root_y);
155 return;
156 }
157
158 /* see if the user entered the window on a certain window decoration */
159 layout_t layout = (enter_child ? con->parent->layout : con->layout);
160 if (layout == L_DEFAULT) {
161 Con *child;
162 TAILQ_FOREACH_REVERSE (child, &(con->nodes_head), nodes_head, nodes) {
163 if (rect_contains(child->deco_rect, event->event_x, event->event_y)) {
164 LOG("using child %p / %s instead!\n", child, child->name);
165 con = child;
166 break;
167 }
168 }
169 }
170
171 if (config.disable_focus_follows_mouse)
172 return;
173
174 /* if this container is already focused, there is nothing to do. */
175 if (con == focused)
176 return;
177
178 /* Get the currently focused workspace to check if the focus change also
179 * involves changing workspaces. If so, we need to call workspace_show() to
180 * correctly update state and send the IPC event. */
181 Con *ws = con_get_workspace(con);
182 if (ws != con_get_workspace(focused))
183 workspace_show(ws);
184
185 focused_id = XCB_NONE;
186 con_focus(con_descend_focused(con));
187 tree_render();
188 }
189
190 /*
191 * When the user moves the mouse but does not change the active window
192 * (e.g. when having no windows opened but moving mouse on the root screen
193 * and crossing virtual screen boundaries), this callback gets called.
194 *
195 */
196 static void handle_motion_notify(xcb_motion_notify_event_t *event) {
197 last_timestamp = event->time;
198
199 /* Skip events where the pointer was over a child window, we are only
200 * interested in events on the root window. */
201 if (event->child != XCB_NONE)
202 return;
203
204 Con *con;
205 if ((con = con_by_frame_id(event->event)) == NULL) {
206 DLOG("MotionNotify for an unknown container, checking if it crosses screen boundaries.\n");
207 check_crossing_screen_boundary(event->root_x, event->root_y);
208 return;
209 }
210
211 if (config.disable_focus_follows_mouse)
212 return;
213
214 if (con->layout != L_DEFAULT && con->layout != L_SPLITV && con->layout != L_SPLITH)
215 return;
216
217 /* see over which rect the user is */
218 Con *current;
219 TAILQ_FOREACH_REVERSE (current, &(con->nodes_head), nodes_head, nodes) {
220 if (!rect_contains(current->deco_rect, event->event_x, event->event_y))
221 continue;
222
223 /* We found the rect, let’s see if this window is focused */
224 if (TAILQ_FIRST(&(con->focus_head)) == current)
225 return;
226
227 con_focus(current);
228 x_push_changes(croot);
229 return;
230 }
231 }
232
233 /*
234 * Called when the keyboard mapping changes (for example by using Xmodmap),
235 * we need to update our key bindings then (re-translate symbols).
236 *
237 */
238 static void handle_mapping_notify(xcb_mapping_notify_event_t *event) {
239 if (event->request != XCB_MAPPING_KEYBOARD &&
240 event->request != XCB_MAPPING_MODIFIER)
241 return;
242
243 DLOG("Received mapping_notify for keyboard or modifier mapping, re-grabbing keys\n");
244 xcb_refresh_keyboard_mapping(keysyms, event);
245
246 xcb_numlock_mask = aio_get_mod_mask_for(XCB_NUM_LOCK, keysyms);
247
248 ungrab_all_keys(conn);
249 translate_keysyms();
250 grab_all_keys(conn);
251 }
252
253 /*
254 * A new window appeared on the screen (=was mapped), so let’s manage it.
255 *
256 */
257 static void handle_map_request(xcb_map_request_event_t *event) {
258 xcb_get_window_attributes_cookie_t cookie;
259
260 cookie = xcb_get_window_attributes_unchecked(conn, event->window);
261
262 DLOG("window = 0x%08x, serial is %d.\n", event->window, event->sequence);
263 add_ignore_event(event->sequence, -1);
264
265 manage_window(event->window, cookie, false);
266 }
267
268 /*
269 * Configure requests are received when the application wants to resize windows
270 * on their own.
271 *
272 * We generate a synthethic configure notify event to signalize the client its
273 * "new" position.
274 *
275 */
276 static void handle_configure_request(xcb_configure_request_event_t *event) {
277 Con *con;
278
279 DLOG("window 0x%08x wants to be at %dx%d with %dx%d\n",
280 event->window, event->x, event->y, event->width, event->height);
281
282 /* For unmanaged windows, we just execute the configure request. As soon as
283 * it gets mapped, we will take over anyways. */
284 if ((con = con_by_window_id(event->window)) == NULL) {
285 DLOG("Configure request for unmanaged window, can do that.\n");
286
287 uint32_t mask = 0;
288 uint32_t values[7];
289 int c = 0;
290 #define COPY_MASK_MEMBER(mask_member, event_member) \
291 do { \
292 if (event->value_mask & mask_member) { \
293 mask |= mask_member; \
294 values[c++] = event->event_member; \
295 } \
296 } while (0)
297
298 COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_X, x);
299 COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_Y, y);
300 COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_WIDTH, width);
301 COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_HEIGHT, height);
302 COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_BORDER_WIDTH, border_width);
303 COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_SIBLING, sibling);
304 COPY_MASK_MEMBER(XCB_CONFIG_WINDOW_STACK_MODE, stack_mode);
305
306 xcb_configure_window(conn, event->window, mask, values);
307 xcb_flush(conn);
308
309 return;
310 }
311
312 DLOG("Configure request!\n");
313
314 Con *workspace = con_get_workspace(con);
315 if (workspace && (strcmp(workspace->name, "__i3_scratch") == 0)) {
316 DLOG("This is a scratchpad container, ignoring ConfigureRequest\n");
317 goto out;
318 }
319 Con *fullscreen = con_get_fullscreen_covering_ws(workspace);
320
321 if (fullscreen != con && con_is_floating(con) && con_is_leaf(con)) {
322 /* find the height for the decorations */
323 int deco_height = con->deco_rect.height;
324 /* we actually need to apply the size/position changes to the *parent*
325 * container */
326 Rect bsr = con_border_style_rect(con);
327 if (con->border_style == BS_NORMAL) {
328 bsr.y += deco_height;
329 bsr.height -= deco_height;
330 }
331 Con *floatingcon = con->parent;
332 Rect newrect = floatingcon->rect;
333
334 if (event->value_mask & XCB_CONFIG_WINDOW_X) {
335 newrect.x = event->x + (-1) * bsr.x;
336 DLOG("proposed x = %d, new x is %d\n", event->x, newrect.x);
337 }
338 if (event->value_mask & XCB_CONFIG_WINDOW_Y) {
339 newrect.y = event->y + (-1) * bsr.y;
340 DLOG("proposed y = %d, new y is %d\n", event->y, newrect.y);
341 }
342 if (event->value_mask & XCB_CONFIG_WINDOW_WIDTH) {
343 newrect.width = event->width + (-1) * bsr.width;
344 newrect.width += con->border_width * 2;
345 DLOG("proposed width = %d, new width is %d (x11 border %d)\n",
346 event->width, newrect.width, con->border_width);
347 }
348 if (event->value_mask & XCB_CONFIG_WINDOW_HEIGHT) {
349 newrect.height = event->height + (-1) * bsr.height;
350 newrect.height += con->border_width * 2;
351 DLOG("proposed height = %d, new height is %d (x11 border %d)\n",
352 event->height, newrect.height, con->border_width);
353 }
354
355 DLOG("Container is a floating leaf node, will do that.\n");
356 floating_reposition(floatingcon, newrect);
357 return;
358 }
359
360 /* Dock windows can be reconfigured in their height and moved to another output. */
361 if (con->parent && con->parent->type == CT_DOCKAREA) {
362 DLOG("Reconfiguring dock window (con = %p).\n", con);
363 if (event->value_mask & XCB_CONFIG_WINDOW_HEIGHT) {
364 DLOG("Dock client wants to change height to %d, we can do that.\n", event->height);
365
366 con->geometry.height = event->height;
367 tree_render();
368 }
369
370 if (event->value_mask & XCB_CONFIG_WINDOW_X || event->value_mask & XCB_CONFIG_WINDOW_Y) {
371 int16_t x = event->value_mask & XCB_CONFIG_WINDOW_X ? event->x : (int16_t)con->geometry.x;
372 int16_t y = event->value_mask & XCB_CONFIG_WINDOW_Y ? event->y : (int16_t)con->geometry.y;
373
374 Con *current_output = con_get_output(con);
375 Output *target = get_output_containing(x, y);
376 if (target != NULL && current_output != target->con) {
377 DLOG("Dock client is requested to be moved to output %s, moving it there.\n", output_primary_name(target));
378 Match *match;
379 Con *nc = con_for_window(target->con, con->window, &match);
380 DLOG("Dock client will be moved to container %p.\n", nc);
381 con_detach(con);
382 con_attach(con, nc, false);
383
384 tree_render();
385 } else {
386 DLOG("Dock client will not be moved, we only support moving it to another output.\n");
387 }
388 }
389 goto out;
390 }
391
392 if (event->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) {
393 DLOG("window 0x%08x wants to be stacked %d\n", event->window, event->stack_mode);
394
395 /* Emacs and IntelliJ Idea “request focus” by stacking their window
396 * above all others. */
397 if (event->stack_mode != XCB_STACK_MODE_ABOVE) {
398 DLOG("stack_mode != XCB_STACK_MODE_ABOVE, ignoring ConfigureRequest\n");
399 goto out;
400 }
401
402 if (fullscreen || !con_is_leaf(con)) {
403 DLOG("fullscreen or not a leaf, ignoring ConfigureRequest\n");
404 goto out;
405 }
406
407 if (workspace == NULL) {
408 DLOG("Window is not being managed, ignoring ConfigureRequest\n");
409 goto out;
410 }
411
412 if (config.focus_on_window_activation == FOWA_FOCUS || (config.focus_on_window_activation == FOWA_SMART && workspace_is_visible(workspace))) {
413 DLOG("Focusing con = %p\n", con);
414 workspace_show(workspace);
415 con_activate_unblock(con);
416 tree_render();
417 } else if (config.focus_on_window_activation == FOWA_URGENT || (config.focus_on_window_activation == FOWA_SMART && !workspace_is_visible(workspace))) {
418 DLOG("Marking con = %p urgent\n", con);
419 con_set_urgency(con, true);
420 tree_render();
421 } else {
422 DLOG("Ignoring request for con = %p.\n", con);
423 }
424 }
425
426 out:
427 fake_absolute_configure_notify(con);
428 }
429
430 /*
431 * Gets triggered upon a RandR screen change event, that is when the user
432 * changes the screen configuration in any way (mode, position, …)
433 *
434 */
435 static void handle_screen_change(xcb_generic_event_t *e) {
436 DLOG("RandR screen change\n");
437
438 /* The geometry of the root window is used for “fullscreen global” and
439 * changes when new outputs are added. */
440 xcb_get_geometry_cookie_t cookie = xcb_get_geometry(conn, root);
441 xcb_get_geometry_reply_t *reply = xcb_get_geometry_reply(conn, cookie, NULL);
442 if (reply == NULL) {
443 ELOG("Could not get geometry of the root window, exiting\n");
444 exit(EXIT_FAILURE);
445 }
446 DLOG("root geometry reply: (%d, %d) %d x %d\n", reply->x, reply->y, reply->width, reply->height);
447
448 croot->rect.width = reply->width;
449 croot->rect.height = reply->height;
450
451 randr_query_outputs();
452
453 scratchpad_fix_resolution();
454
455 ipc_send_event("output", I3_IPC_EVENT_OUTPUT, "{\"change\":\"unspecified\"}");
456 }
457
458 /*
459 * Our window decorations were unmapped. That means, the window will be killed
460 * now, so we better clean up before.
461 *
462 */
463 static void handle_unmap_notify_event(xcb_unmap_notify_event_t *event) {
464 DLOG("UnmapNotify for 0x%08x (received from 0x%08x), serial %d\n", event->window, event->event, event->sequence);
465 xcb_get_input_focus_cookie_t cookie;
466 Con *con = con_by_window_id(event->window);
467 if (con == NULL) {
468 /* This could also be an UnmapNotify for the frame. We need to
469 * decrement the ignore_unmap counter. */
470 con = con_by_frame_id(event->window);
471 if (con == NULL) {
472 LOG("Not a managed window, ignoring UnmapNotify event\n");
473 return;
474 }
475
476 if (con->ignore_unmap > 0)
477 con->ignore_unmap--;
478 /* See the end of this function. */
479 cookie = xcb_get_input_focus(conn);
480 DLOG("ignore_unmap = %d for frame of container %p\n", con->ignore_unmap, con);
481 goto ignore_end;
482 }
483
484 /* See the end of this function. */
485 cookie = xcb_get_input_focus(conn);
486
487 if (con->ignore_unmap > 0) {
488 DLOG("ignore_unmap = %d, dec\n", con->ignore_unmap);
489 con->ignore_unmap--;
490 goto ignore_end;
491 }
492
493 /* Since we close the container, we need to unset _NET_WM_DESKTOP and
494 * _NET_WM_STATE according to the spec. */
495 xcb_delete_property(conn, event->window, A__NET_WM_DESKTOP);
496 xcb_delete_property(conn, event->window, A__NET_WM_STATE);
497
498 tree_close_internal(con, DONT_KILL_WINDOW, false);
499 tree_render();
500
501 ignore_end:
502 /* If the client (as opposed to i3) destroyed or unmapped a window, an
503 * EnterNotify event will follow (indistinguishable from an EnterNotify
504 * event caused by moving your mouse), causing i3 to set focus to whichever
505 * window is now visible.
506 *
507 * In a complex stacked or tabbed layout (take two v-split containers in a
508 * tabbed container), when the bottom window in tab2 is closed, the bottom
509 * window of tab1 is visible instead. X11 will thus send an EnterNotify
510 * event for the bottom window of tab1, while the focus should be set to
511 * the remaining window of tab2.
512 *
513 * Therefore, we ignore all EnterNotify events which have the same sequence
514 * as an UnmapNotify event. */
515 add_ignore_event(event->sequence, XCB_ENTER_NOTIFY);
516
517 /* Since we just ignored the sequence of this UnmapNotify, we want to make
518 * sure that following events use a different sequence. When putting xterm
519 * into fullscreen and moving the pointer to a different window, without
520 * using GetInputFocus, subsequent (legitimate) EnterNotify events arrived
521 * with the same sequence and thus were ignored (see ticket #609). */
522 free(xcb_get_input_focus_reply(conn, cookie, NULL));
523 }
524
525 /*
526 * A destroy notify event is sent when the window is not unmapped, but
527 * immediately destroyed (for example when starting a window and immediately
528 * killing the program which started it).
529 *
530 * We just pass on the event to the unmap notify handler (by copying the
531 * important fields in the event data structure).
532 *
533 */
534 static void handle_destroy_notify_event(xcb_destroy_notify_event_t *event) {
535 DLOG("destroy notify for 0x%08x, 0x%08x\n", event->event, event->window);
536
537 xcb_unmap_notify_event_t unmap;
538 unmap.sequence = event->sequence;
539 unmap.event = event->event;
540 unmap.window = event->window;
541
542 handle_unmap_notify_event(&unmap);
543 }
544
545 static bool window_name_changed(i3Window *window, char *old_name) {
546 if ((old_name == NULL) && (window->name == NULL))
547 return false;
548
549 /* Either the old or the new one is NULL, but not both. */
550 if ((old_name == NULL) ^ (window->name == NULL))
551 return true;
552
553 return (strcmp(old_name, i3string_as_utf8(window->name)) != 0);
554 }
555
556 /*
557 * Called when a window changes its title
558 *
559 */
560 static bool handle_windowname_change(Con *con, xcb_get_property_reply_t *prop) {
561 char *old_name = (con->window->name != NULL ? sstrdup(i3string_as_utf8(con->window->name)) : NULL);
562
563 window_update_name(con->window, prop);
564
565 con = remanage_window(con);
566
567 x_push_changes(croot);
568
569 if (window_name_changed(con->window, old_name))
570 ipc_send_window_event("title", con);
571
572 FREE(old_name);
573
574 return true;
575 }
576
577 /*
578 * Handles legacy window name updates (WM_NAME), see also src/window.c,
579 * window_update_name_legacy().
580 *
581 */
582 static bool handle_windowname_change_legacy(Con *con, xcb_get_property_reply_t *prop) {
583 char *old_name = (con->window->name != NULL ? sstrdup(i3string_as_utf8(con->window->name)) : NULL);
584
585 window_update_name_legacy(con->window, prop);
586
587 con = remanage_window(con);
588
589 x_push_changes(croot);
590
591 if (window_name_changed(con->window, old_name))
592 ipc_send_window_event("title", con);
593
594 FREE(old_name);
595
596 return true;
597 }
598
599 /*
600 * Called when a window changes its WM_WINDOW_ROLE.
601 *
602 */
603 static bool handle_windowrole_change(Con *con, xcb_get_property_reply_t *prop) {
604 window_update_role(con->window, prop);
605
606 con = remanage_window(con);
607
608 return true;
609 }
610
611 /*
612 * Expose event means we should redraw our windows (= title bar)
613 *
614 */
615 static void handle_expose_event(xcb_expose_event_t *event) {
616 Con *parent;
617
618 DLOG("window = %08x\n", event->window);
619
620 if ((parent = con_by_frame_id(event->window)) == NULL) {
621 LOG("expose event for unknown window, ignoring\n");
622 return;
623 }
624
625 /* Since we render to our surface on every change anyways, expose events
626 * only tell us that the X server lost (parts of) the window contents. */
627 draw_util_copy_surface(&(parent->frame_buffer), &(parent->frame),
628 0, 0, 0, 0, parent->rect.width, parent->rect.height);
629 xcb_flush(conn);
630 }
631
632 #define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
633 #define _NET_WM_MOVERESIZE_SIZE_TOP 1
634 #define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
635 #define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
636 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
637 #define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
638 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
639 #define _NET_WM_MOVERESIZE_SIZE_LEFT 7
640 #define _NET_WM_MOVERESIZE_MOVE 8 /* movement only */
641 #define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9 /* size via keyboard */
642 #define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 /* move via keyboard */
643 #define _NET_WM_MOVERESIZE_CANCEL 11 /* cancel operation */
644
645 #define _NET_MOVERESIZE_WINDOW_X (1 << 8)
646 #define _NET_MOVERESIZE_WINDOW_Y (1 << 9)
647 #define _NET_MOVERESIZE_WINDOW_WIDTH (1 << 10)
648 #define _NET_MOVERESIZE_WINDOW_HEIGHT (1 << 11)
649
650 /*
651 * Handle client messages (EWMH)
652 *
653 */
654 static void handle_client_message(xcb_client_message_event_t *event) {
655 /* If this is a startup notification ClientMessage, the library will handle
656 * it and call our monitor_event() callback. */
657 if (sn_xcb_display_process_event(sndisplay, (xcb_generic_event_t *)event))
658 return;
659
660 LOG("ClientMessage for window 0x%08x\n", event->window);
661 if (event->type == A__NET_WM_STATE) {
662 if (event->format != 32 ||
663 (event->data.data32[1] != A__NET_WM_STATE_FULLSCREEN &&
664 event->data.data32[1] != A__NET_WM_STATE_DEMANDS_ATTENTION &&
665 event->data.data32[1] != A__NET_WM_STATE_STICKY)) {
666 DLOG("Unknown atom in clientmessage of type %d\n", event->data.data32[1]);
667 return;
668 }
669
670 Con *con = con_by_window_id(event->window);
671 if (con == NULL) {
672 DLOG("Could not get window for client message\n");
673 return;
674 }
675
676 if (event->data.data32[1] == A__NET_WM_STATE_FULLSCREEN) {
677 /* Check if the fullscreen state should be toggled */
678 if ((con->fullscreen_mode != CF_NONE &&
679 (event->data.data32[0] == _NET_WM_STATE_REMOVE ||
680 event->data.data32[0] == _NET_WM_STATE_TOGGLE)) ||
681 (con->fullscreen_mode == CF_NONE &&
682 (event->data.data32[0] == _NET_WM_STATE_ADD ||
683 event->data.data32[0] == _NET_WM_STATE_TOGGLE))) {
684 DLOG("toggling fullscreen\n");
685 con_toggle_fullscreen(con, CF_OUTPUT);
686 }
687 } else if (event->data.data32[1] == A__NET_WM_STATE_DEMANDS_ATTENTION) {
688 /* Check if the urgent flag must be set or not */
689 if (event->data.data32[0] == _NET_WM_STATE_ADD)
690 con_set_urgency(con, true);
691 else if (event->data.data32[0] == _NET_WM_STATE_REMOVE)
692 con_set_urgency(con, false);
693 else if (event->data.data32[0] == _NET_WM_STATE_TOGGLE)
694 con_set_urgency(con, !con->urgent);
695 } else if (event->data.data32[1] == A__NET_WM_STATE_STICKY) {
696 DLOG("Received a client message to modify _NET_WM_STATE_STICKY.\n");
697 if (event->data.data32[0] == _NET_WM_STATE_ADD)
698 con->sticky = true;
699 else if (event->data.data32[0] == _NET_WM_STATE_REMOVE)
700 con->sticky = false;
701 else if (event->data.data32[0] == _NET_WM_STATE_TOGGLE)
702 con->sticky = !con->sticky;
703
704 DLOG("New sticky status for con = %p is %i.\n", con, con->sticky);
705 ewmh_update_sticky(con->window->id, con->sticky);
706 output_push_sticky_windows(focused);
707 ewmh_update_wm_desktop();
708 }
709
710 tree_render();
711 } else if (event->type == A__NET_ACTIVE_WINDOW) {
712 if (event->format != 32)
713 return;
714
715 DLOG("_NET_ACTIVE_WINDOW: Window 0x%08x should be activated\n", event->window);
716
717 Con *con = con_by_window_id(event->window);
718 if (con == NULL) {
719 DLOG("Could not get window for client message\n");
720 return;
721 }
722
723 Con *ws = con_get_workspace(con);
724 if (ws == NULL) {
725 DLOG("Window is not being managed, ignoring _NET_ACTIVE_WINDOW\n");
726 return;
727 }
728
729 if (con_is_internal(ws) && ws != workspace_get("__i3_scratch", NULL)) {
730 DLOG("Workspace is internal but not scratchpad, ignoring _NET_ACTIVE_WINDOW\n");
731 return;
732 }
733
734 /* data32[0] indicates the source of the request (application or pager) */
735 if (event->data.data32[0] == 2) {
736 /* Always focus the con if it is from a pager, because this is most
737 * likely from some user action */
738 DLOG("This request came from a pager. Focusing con = %p\n", con);
739
740 if (con_is_internal(ws)) {
741 scratchpad_show(con);
742 } else {
743 workspace_show(ws);
744 /* Re-set focus, even if unchanged from i3’s perspective. */
745 focused_id = XCB_NONE;
746 con_activate_unblock(con);
747 }
748 } else {
749 /* Request is from an application. */
750 if (con_is_internal(ws)) {
751 DLOG("Ignoring request to make con = %p active because it's on an internal workspace.\n", con);
752 return;
753 }
754
755 if (config.focus_on_window_activation == FOWA_FOCUS || (config.focus_on_window_activation == FOWA_SMART && workspace_is_visible(ws))) {
756 DLOG("Focusing con = %p\n", con);
757 con_activate_unblock(con);
758 } else if (config.focus_on_window_activation == FOWA_URGENT || (config.focus_on_window_activation == FOWA_SMART && !workspace_is_visible(ws))) {
759 DLOG("Marking con = %p urgent\n", con);
760 con_set_urgency(con, true);
761 } else
762 DLOG("Ignoring request for con = %p.\n", con);
763 }
764
765 tree_render();
766 } else if (event->type == A_I3_SYNC) {
767 xcb_window_t window = event->data.data32[0];
768 uint32_t rnd = event->data.data32[1];
769 sync_respond(window, rnd);
770 } else if (event->type == A__NET_REQUEST_FRAME_EXTENTS) {
771 /*
772 * A client can request an estimate for the frame size which the window
773 * manager will put around it before actually mapping its window. Java
774 * does this (as of openjdk-7).
775 *
776 * Note that the calculation below is not entirely accurate — once you
777 * set a different border type, it’s off. We _could_ request all the
778 * window properties (which have to be set up at this point according
779 * to EWMH), but that seems rather elaborate. The standard explicitly
780 * says the application must cope with an estimate that is not entirely
781 * accurate.
782 */
783 DLOG("_NET_REQUEST_FRAME_EXTENTS for window 0x%08x\n", event->window);
784
785 /* The reply data: approximate frame size */
786 Rect r = {
787 config.default_border_width, /* left */
788 config.default_border_width, /* right */
789 render_deco_height(), /* top */
790 config.default_border_width /* bottom */
791 };
792 xcb_change_property(
793 conn,
794 XCB_PROP_MODE_REPLACE,
795 event->window,
796 A__NET_FRAME_EXTENTS,
797 XCB_ATOM_CARDINAL, 32, 4,
798 &r);
799 xcb_flush(conn);
800 } else if (event->type == A_WM_CHANGE_STATE) {
801 /* http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.4 */
802 if (event->data.data32[0] == XCB_ICCCM_WM_STATE_ICONIC) {
803 /* For compatiblity reasons, Wine will request iconic state and cannot ensure that the WM has agreed on it;
804 * immediately revert to normal to avoid being stuck in a paused state. */
805 DLOG("Client has requested iconic state, rejecting. (window = %d)\n", event->window);
806 long data[] = {XCB_ICCCM_WM_STATE_NORMAL, XCB_NONE};
807 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, event->window,
808 A_WM_STATE, A_WM_STATE, 32, 2, data);
809 } else {
810 DLOG("Not handling WM_CHANGE_STATE request. (window = %d, state = %d)\n", event->window, event->data.data32[0]);
811 }
812 } else if (event->type == A__NET_CURRENT_DESKTOP) {
813 /* This request is used by pagers and bars to change the current
814 * desktop likely as a result of some user action. We interpret this as
815 * a request to focus the given workspace. See
816 * https://standards.freedesktop.org/wm-spec/latest/ar01s03.html#idm140251368135008
817 * */
818 DLOG("Request to change current desktop to index %d\n", event->data.data32[0]);
819 Con *ws = ewmh_get_workspace_by_index(event->data.data32[0]);
820 if (ws == NULL) {
821 ELOG("Could not determine workspace for this index, ignoring request.\n");
822 return;
823 }
824
825 DLOG("Handling request to focus workspace %s\n", ws->name);
826 workspace_show(ws);
827 tree_render();
828 } else if (event->type == A__NET_WM_DESKTOP) {
829 uint32_t index = event->data.data32[0];
830 DLOG("Request to move window %d to EWMH desktop index %d\n", event->window, index);
831
832 Con *con = con_by_window_id(event->window);
833 if (con == NULL) {
834 DLOG("Couldn't find con for window %d, ignoring the request.\n", event->window);
835 return;
836 }
837
838 if (index == NET_WM_DESKTOP_ALL) {
839 /* The window is requesting to be visible on all workspaces, so
840 * let's float it and make it sticky. */
841 DLOG("The window was requested to be visible on all workspaces, making it sticky and floating.\n");
842
843 floating_enable(con, false);
844 con->floating = FLOATING_AUTO_ON;
845
846 con->sticky = true;
847 ewmh_update_sticky(con->window->id, true);
848 output_push_sticky_windows(focused);
849 } else {
850 Con *ws = ewmh_get_workspace_by_index(index);
851 if (ws == NULL) {
852 ELOG("Could not determine workspace for this index, ignoring request.\n");
853 return;
854 }
855
856 con_move_to_workspace(con, ws, true, false, false);
857 }
858
859 tree_render();
860 ewmh_update_wm_desktop();
861 } else if (event->type == A__NET_CLOSE_WINDOW) {
862 /*
863 * Pagers wanting to close a window MUST send a _NET_CLOSE_WINDOW
864 * client message request to the root window.
865 * https://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472668896
866 */
867 Con *con = con_by_window_id(event->window);
868 if (con) {
869 DLOG("Handling _NET_CLOSE_WINDOW request (con = %p)\n", con);
870
871 if (event->data.data32[0])
872 last_timestamp = event->data.data32[0];
873
874 tree_close_internal(con, KILL_WINDOW, false);
875 tree_render();
876 } else {
877 DLOG("Couldn't find con for _NET_CLOSE_WINDOW request. (window = %d)\n", event->window);
878 }
879 } else if (event->type == A__NET_WM_MOVERESIZE) {
880 /*
881 * Client-side decorated Gtk3 windows emit this signal when being
882 * dragged by their GtkHeaderBar
883 */
884 Con *con = con_by_window_id(event->window);
885 if (!con || !con_is_floating(con)) {
886 DLOG("Couldn't find con for _NET_WM_MOVERESIZE request, or con not floating (window = %d)\n", event->window);
887 return;
888 }
889 DLOG("Handling _NET_WM_MOVERESIZE request (con = %p)\n", con);
890 uint32_t direction = event->data.data32[2];
891 uint32_t x_root = event->data.data32[0];
892 uint32_t y_root = event->data.data32[1];
893 /* construct fake xcb_button_press_event_t */
894 xcb_button_press_event_t fake = {
895 .root_x = x_root,
896 .root_y = y_root,
897 .event_x = x_root - (con->rect.x),
898 .event_y = y_root - (con->rect.y)};
899 switch (direction) {
900 case _NET_WM_MOVERESIZE_MOVE:
901 floating_drag_window(con->parent, &fake, false);
902 break;
903 case _NET_WM_MOVERESIZE_SIZE_TOPLEFT ... _NET_WM_MOVERESIZE_SIZE_LEFT:
904 floating_resize_window(con->parent, false, &fake);
905 break;
906 default:
907 DLOG("_NET_WM_MOVERESIZE direction %d not implemented\n", direction);
908 break;
909 }
910 } else if (event->type == A__NET_MOVERESIZE_WINDOW) {
911 DLOG("Received _NET_MOVE_RESIZE_WINDOW. Handling by faking a configure request.\n");
912
913 void *_generated_event = scalloc(32, 1);
914 xcb_configure_request_event_t *generated_event = _generated_event;
915
916 generated_event->window = event->window;
917 generated_event->response_type = XCB_CONFIGURE_REQUEST;
918
919 generated_event->value_mask = 0;
920 if (event->data.data32[0] & _NET_MOVERESIZE_WINDOW_X) {
921 generated_event->value_mask |= XCB_CONFIG_WINDOW_X;
922 generated_event->x = event->data.data32[1];
923 }
924 if (event->data.data32[0] & _NET_MOVERESIZE_WINDOW_Y) {
925 generated_event->value_mask |= XCB_CONFIG_WINDOW_Y;
926 generated_event->y = event->data.data32[2];
927 }
928 if (event->data.data32[0] & _NET_MOVERESIZE_WINDOW_WIDTH) {
929 generated_event->value_mask |= XCB_CONFIG_WINDOW_WIDTH;
930 generated_event->width = event->data.data32[3];
931 }
932 if (event->data.data32[0] & _NET_MOVERESIZE_WINDOW_HEIGHT) {
933 generated_event->value_mask |= XCB_CONFIG_WINDOW_HEIGHT;
934 generated_event->height = event->data.data32[4];
935 }
936
937 handle_configure_request(generated_event);
938 FREE(generated_event);
939 } else {
940 DLOG("Skipping client message for unhandled type %d\n", event->type);
941 }
942 }
943
944 static bool handle_window_type(Con *con, xcb_get_property_reply_t *reply) {
945 window_update_type(con->window, reply);
946 return true;
947 }
948
949 /*
950 * Handles the size hints set by a window, but currently only the part necessary for displaying
951 * clients proportionally inside their frames (mplayer for example)
952 *
953 * See ICCCM 4.1.2.3 for more details
954 *
955 */
956 static bool handle_normal_hints(Con *con, xcb_get_property_reply_t *reply) {
957 bool changed = window_update_normal_hints(con->window, reply, NULL);
958
959 if (changed) {
960 Con *floating = con_inside_floating(con);
961 if (floating) {
962 floating_check_size(con, false);
963 tree_render();
964 }
965 }
966
967 FREE(reply);
968 return true;
969 }
970
971 /*
972 * Handles the WM_HINTS property for extracting the urgency state of the window.
973 *
974 */
975 static bool handle_hints(Con *con, xcb_get_property_reply_t *reply) {
976 bool urgency_hint;
977 window_update_hints(con->window, reply, &urgency_hint);
978 con_set_urgency(con, urgency_hint);
979 tree_render();
980 return true;
981 }
982
983 /*
984 * Handles the transient for hints set by a window, signalizing that this window is a popup window
985 * for some other window.
986 *
987 * See ICCCM 4.1.2.6 for more details
988 *
989 */
990 static bool handle_transient_for(Con *con, xcb_get_property_reply_t *prop) {
991 window_update_transient_for(con->window, prop);
992 return true;
993 }
994
995 /*
996 * Handles changes of the WM_CLIENT_LEADER atom which specifies if this is a
997 * toolwindow (or similar) and to which window it belongs (logical parent).
998 *
999 */
1000 static bool handle_clientleader_change(Con *con, xcb_get_property_reply_t *prop) {
1001 window_update_leader(con->window, prop);
1002 return true;
1003 }
1004
1005 /*
1006 * Handles FocusIn events which are generated by clients (i3’s focus changes
1007 * don’t generate FocusIn events due to a different EventMask) and updates the
1008 * decorations accordingly.
1009 *
1010 */
1011 static void handle_focus_in(xcb_focus_in_event_t *event) {
1012 DLOG("focus change in, for window 0x%08x\n", event->event);
1013
1014 if (event->event == root) {
1015 DLOG("Received focus in for root window, refocusing the focused window.\n");
1016 con_focus(focused);
1017 focused_id = XCB_NONE;
1018 x_push_changes(croot);
1019 }
1020
1021 Con *con;
1022 if ((con = con_by_window_id(event->event)) == NULL || con->window == NULL)
1023 return;
1024 DLOG("That is con %p / %s\n", con, con->name);
1025
1026 if (event->mode == XCB_NOTIFY_MODE_GRAB ||
1027 event->mode == XCB_NOTIFY_MODE_UNGRAB) {
1028 DLOG("FocusIn event for grab/ungrab, ignoring\n");
1029 return;
1030 }
1031
1032 if (event->detail == XCB_NOTIFY_DETAIL_POINTER) {
1033 DLOG("notify detail is pointer, ignoring this event\n");
1034 return;
1035 }
1036
1037 /* Floating windows should be refocused to ensure that they are on top of
1038 * other windows. */
1039 if (focused_id == event->event && !con_inside_floating(con)) {
1040 DLOG("focus matches the currently focused window, not doing anything\n");
1041 return;
1042 }
1043
1044 /* Skip dock clients, they cannot get the i3 focus. */
1045 if (con->parent->type == CT_DOCKAREA) {
1046 DLOG("This is a dock client, not focusing.\n");
1047 return;
1048 }
1049
1050 DLOG("focus is different / refocusing floating window: updating decorations\n");
1051
1052 con_activate_unblock(con);
1053
1054 /* We update focused_id because we don’t need to set focus again */
1055 focused_id = event->event;
1056 tree_render();
1057 }
1058
1059 /*
1060 * Handles ConfigureNotify events for the root window, which are generated when
1061 * the monitor configuration changed.
1062 *
1063 */
1064 static void handle_configure_notify(xcb_configure_notify_event_t *event) {
1065 if (event->event != root) {
1066 DLOG("ConfigureNotify for non-root window 0x%08x, ignoring\n", event->event);
1067 return;
1068 }
1069 DLOG("ConfigureNotify for root window 0x%08x\n", event->event);
1070
1071 if (force_xinerama) {
1072 return;
1073 }
1074 randr_query_outputs();
1075 }
1076
1077 /*
1078 * Handles the WM_CLASS property for assignments and criteria selection.
1079 *
1080 */
1081 static bool handle_class_change(Con *con, xcb_get_property_reply_t *prop) {
1082 window_update_class(con->window, prop);
1083 con = remanage_window(con);
1084 return true;
1085 }
1086
1087 /*
1088 * Handles the _MOTIF_WM_HINTS property of specifing window deocration settings.
1089 *
1090 */
1091 static bool handle_motif_hints_change(Con *con, xcb_get_property_reply_t *prop) {
1092 border_style_t motif_border_style;
1093 window_update_motif_hints(con->window, prop, &motif_border_style);
1094
1095 if (motif_border_style != con->border_style && motif_border_style != BS_NORMAL) {
1096 DLOG("Update border style of con %p to %d\n", con, motif_border_style);
1097 con_set_border_style(con, motif_border_style, con->current_border_width);
1098
1099 x_push_changes(croot);
1100 }
1101
1102 return true;
1103 }
1104
1105 /*
1106 * Handles the _NET_WM_STRUT_PARTIAL property for allocating space for dock clients.
1107 *
1108 */
1109 static bool handle_strut_partial_change(Con *con, xcb_get_property_reply_t *prop) {
1110 window_update_strut_partial(con->window, prop);
1111
1112 /* we only handle this change for dock clients */
1113 if (con->parent == NULL || con->parent->type != CT_DOCKAREA) {
1114 return true;
1115 }
1116
1117 Con *search_at = croot;
1118 Con *output = con_get_output(con);
1119 if (output != NULL) {
1120 DLOG("Starting search at output %s\n", output->name);
1121 search_at = output;
1122 }
1123
1124 /* find out the desired position of this dock window */
1125 if (con->window->reserved.top > 0 && con->window->reserved.bottom == 0) {
1126 DLOG("Top dock client\n");
1127 con->window->dock = W_DOCK_TOP;
1128 } else if (con->window->reserved.top == 0 && con->window->reserved.bottom > 0) {
1129 DLOG("Bottom dock client\n");
1130 con->window->dock = W_DOCK_BOTTOM;
1131 } else {
1132 DLOG("Ignoring invalid reserved edges (_NET_WM_STRUT_PARTIAL), using position as fallback:\n");
1133 if (con->geometry.y < (search_at->rect.height / 2)) {
1134 DLOG("geom->y = %d < rect.height / 2 = %d, it is a top dock client\n",
1135 con->geometry.y, (search_at->rect.height / 2));
1136 con->window->dock = W_DOCK_TOP;
1137 } else {
1138 DLOG("geom->y = %d >= rect.height / 2 = %d, it is a bottom dock client\n",
1139 con->geometry.y, (search_at->rect.height / 2));
1140 con->window->dock = W_DOCK_BOTTOM;
1141 }
1142 }
1143
1144 /* find the dockarea */
1145 Con *dockarea = con_for_window(search_at, con->window, NULL);
1146 assert(dockarea != NULL);
1147
1148 /* attach the dock to the dock area */
1149 con_detach(con);
1150 con_attach(con, dockarea, true);
1151
1152 tree_render();
1153
1154 return true;
1155 }
1156
1157 /*
1158 * Handles the _I3_FLOATING_WINDOW property to properly run assignments for
1159 * floating window changes.
1160 *
1161 * This is needed to correctly run the assignments after changes in floating
1162 * windows which are triggered by user commands (floating enable | disable). In
1163 * that case, we can't call run_assignments because it will modify the parser
1164 * state when it needs to parse the user-specified action, breaking the parser
1165 * state for the original command.
1166 *
1167 */
1168 static bool handle_i3_floating(Con *con, xcb_get_property_reply_t *prop) {
1169 DLOG("floating change for con %p\n", con);
1170
1171 remanage_window(con);
1172
1173 return true;
1174 }
1175
1176 /* Returns false if the event could not be processed (e.g. the window could not
1177 * be found), true otherwise */
1178 typedef bool (*cb_property_handler_t)(Con *con, xcb_get_property_reply_t *property);
1179
1180 struct property_handler_t {
1181 xcb_atom_t atom;
1182 uint32_t long_len;
1183 cb_property_handler_t cb;
1184 };
1185
1186 static struct property_handler_t property_handlers[] = {
1187 {0, 128, handle_windowname_change},
1188 {0, UINT_MAX, handle_hints},
1189 {0, 128, handle_windowname_change_legacy},
1190 {0, UINT_MAX, handle_normal_hints},
1191 {0, UINT_MAX, handle_clientleader_change},
1192 {0, UINT_MAX, handle_transient_for},
1193 {0, 128, handle_windowrole_change},
1194 {0, 128, handle_class_change},
1195 {0, UINT_MAX, handle_strut_partial_change},
1196 {0, UINT_MAX, handle_window_type},
1197 {0, UINT_MAX, handle_i3_floating},
1198 {0, 5 * sizeof(uint64_t), handle_motif_hints_change}};
1199 #define NUM_HANDLERS (sizeof(property_handlers) / sizeof(struct property_handler_t))
1200
1201 /*
1202 * Sets the appropriate atoms for the property handlers after the atoms were
1203 * received from X11
1204 *
1205 */
1206 void property_handlers_init(void) {
1207 sn_monitor_context_new(sndisplay, conn_screen, startup_monitor_event, NULL, NULL);
1208
1209 property_handlers[0].atom = A__NET_WM_NAME;
1210 property_handlers[1].atom = XCB_ATOM_WM_HINTS;
1211 property_handlers[2].atom = XCB_ATOM_WM_NAME;
1212 property_handlers[3].atom = XCB_ATOM_WM_NORMAL_HINTS;
1213 property_handlers[4].atom = A_WM_CLIENT_LEADER;
1214 property_handlers[5].atom = XCB_ATOM_WM_TRANSIENT_FOR;
1215 property_handlers[6].atom = A_WM_WINDOW_ROLE;
1216 property_handlers[7].atom = XCB_ATOM_WM_CLASS;
1217 property_handlers[8].atom = A__NET_WM_STRUT_PARTIAL;
1218 property_handlers[9].atom = A__NET_WM_WINDOW_TYPE;
1219 property_handlers[10].atom = A_I3_FLOATING_WINDOW;
1220 property_handlers[11].atom = A__MOTIF_WM_HINTS;
1221 }
1222
1223 static void property_notify(uint8_t state, xcb_window_t window, xcb_atom_t atom) {
1224 struct property_handler_t *handler = NULL;
1225 xcb_get_property_reply_t *propr = NULL;
1226 xcb_generic_error_t *err = NULL;
1227 Con *con;
1228
1229 for (size_t c = 0; c < NUM_HANDLERS; c++) {
1230 if (property_handlers[c].atom != atom)
1231 continue;
1232
1233 handler = &property_handlers[c];
1234 break;
1235 }
1236
1237 if (handler == NULL) {
1238 //DLOG("Unhandled property notify for atom %d (0x%08x)\n", atom, atom);
1239 return;
1240 }
1241
1242 if ((con = con_by_window_id(window)) == NULL || con->window == NULL) {
1243 DLOG("Received property for atom %d for unknown client\n", atom);
1244 return;
1245 }
1246
1247 if (state != XCB_PROPERTY_DELETE) {
1248 xcb_get_property_cookie_t cookie = xcb_get_property(conn, 0, window, atom, XCB_GET_PROPERTY_TYPE_ANY, 0, handler->long_len);
1249 propr = xcb_get_property_reply(conn, cookie, &err);
1250 if (err != NULL) {
1251 DLOG("got error %d when getting property of atom %d\n", err->error_code, atom);
1252 FREE(err);
1253 return;
1254 }
1255 }
1256
1257 /* the handler will free() the reply unless it returns false */
1258 if (!handler->cb(con, propr))
1259 FREE(propr);
1260 }
1261
1262 /*
1263 * Takes an xcb_generic_event_t and calls the appropriate handler, based on the
1264 * event type.
1265 *
1266 */
1267 void handle_event(int type, xcb_generic_event_t *event) {
1268 if (type != XCB_MOTION_NOTIFY)
1269 DLOG("event type %d, xkb_base %d\n", type, xkb_base);
1270
1271 if (randr_base > -1 &&
1272 type == randr_base + XCB_RANDR_SCREEN_CHANGE_NOTIFY) {
1273 handle_screen_change(event);
1274 return;
1275 }
1276
1277 if (xkb_base > -1 && type == xkb_base) {
1278 DLOG("xkb event, need to handle it.\n");
1279
1280 xcb_xkb_state_notify_event_t *state = (xcb_xkb_state_notify_event_t *)event;
1281 if (state->xkbType == XCB_XKB_NEW_KEYBOARD_NOTIFY) {
1282 DLOG("xkb new keyboard notify, sequence %d, time %d\n", state->sequence, state->time);
1283 xcb_key_symbols_free(keysyms);
1284 keysyms = xcb_key_symbols_alloc(conn);
1285 if (((xcb_xkb_new_keyboard_notify_event_t *)event)->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
1286 (void)load_keymap();
1287 ungrab_all_keys(conn);
1288 translate_keysyms();
1289 grab_all_keys(conn);
1290 } else if (state->xkbType == XCB_XKB_MAP_NOTIFY) {
1291 if (event_is_ignored(event->sequence, type)) {
1292 DLOG("Ignoring map notify event for sequence %d.\n", state->sequence);
1293 } else {
1294 DLOG("xkb map notify, sequence %d, time %d\n", state->sequence, state->time);
1295 add_ignore_event(event->sequence, type);
1296 xcb_key_symbols_free(keysyms);
1297 keysyms = xcb_key_symbols_alloc(conn);
1298 ungrab_all_keys(conn);
1299 translate_keysyms();
1300 grab_all_keys(conn);
1301 (void)load_keymap();
1302 }
1303 } else if (state->xkbType == XCB_XKB_STATE_NOTIFY) {
1304 DLOG("xkb state group = %d\n", state->group);
1305 if (xkb_current_group == state->group)
1306 return;
1307 xkb_current_group = state->group;
1308 ungrab_all_keys(conn);
1309 grab_all_keys(conn);
1310 }
1311
1312 return;
1313 }
1314
1315 if (shape_supported && type == shape_base + XCB_SHAPE_NOTIFY) {
1316 xcb_shape_notify_event_t *shape = (xcb_shape_notify_event_t *)event;
1317
1318 DLOG("shape_notify_event for window 0x%08x, shape_kind = %d, shaped = %d\n",
1319 shape->affected_window, shape->shape_kind, shape->shaped);
1320
1321 Con *con = con_by_window_id(shape->affected_window);
1322 if (con == NULL) {
1323 LOG("Not a managed window 0x%08x, ignoring shape_notify_event\n",
1324 shape->affected_window);
1325 return;
1326 }
1327
1328 if (shape->shape_kind == XCB_SHAPE_SK_BOUNDING ||
1329 shape->shape_kind == XCB_SHAPE_SK_INPUT) {
1330 x_set_shape(con, shape->shape_kind, shape->shaped);
1331 }
1332
1333 return;
1334 }
1335
1336 switch (type) {
1337 case XCB_KEY_PRESS:
1338 case XCB_KEY_RELEASE:
1339 handle_key_press((xcb_key_press_event_t *)event);
1340 break;
1341
1342 case XCB_BUTTON_PRESS:
1343 case XCB_BUTTON_RELEASE:
1344 handle_button_press((xcb_button_press_event_t *)event);
1345 break;
1346
1347 case XCB_MAP_REQUEST:
1348 handle_map_request((xcb_map_request_event_t *)event);
1349 break;
1350
1351 case XCB_UNMAP_NOTIFY:
1352 handle_unmap_notify_event((xcb_unmap_notify_event_t *)event);
1353 break;
1354
1355 case XCB_DESTROY_NOTIFY:
1356 handle_destroy_notify_event((xcb_destroy_notify_event_t *)event);
1357 break;
1358
1359 case XCB_EXPOSE:
1360 if (((xcb_expose_event_t *)event)->count == 0) {
1361 handle_expose_event((xcb_expose_event_t *)event);
1362 }
1363
1364 break;
1365
1366 case XCB_MOTION_NOTIFY:
1367 handle_motion_notify((xcb_motion_notify_event_t *)event);
1368 break;
1369
1370 /* Enter window = user moved their mouse over the window */
1371 case XCB_ENTER_NOTIFY:
1372 handle_enter_notify((xcb_enter_notify_event_t *)event);
1373 break;
1374
1375 /* Client message are sent to the root window. The only interesting
1376 * client message for us is _NET_WM_STATE, we honour
1377 * _NET_WM_STATE_FULLSCREEN and _NET_WM_STATE_DEMANDS_ATTENTION */
1378 case XCB_CLIENT_MESSAGE:
1379 handle_client_message((xcb_client_message_event_t *)event);
1380 break;
1381
1382 /* Configure request = window tried to change size on its own */
1383 case XCB_CONFIGURE_REQUEST:
1384 handle_configure_request((xcb_configure_request_event_t *)event);
1385 break;
1386
1387 /* Mapping notify = keyboard mapping changed (Xmodmap), re-grab bindings */
1388 case XCB_MAPPING_NOTIFY:
1389 handle_mapping_notify((xcb_mapping_notify_event_t *)event);
1390 break;
1391
1392 case XCB_FOCUS_IN:
1393 handle_focus_in((xcb_focus_in_event_t *)event);
1394 break;
1395
1396 case XCB_PROPERTY_NOTIFY: {
1397 xcb_property_notify_event_t *e = (xcb_property_notify_event_t *)event;
1398 last_timestamp = e->time;
1399 property_notify(e->state, e->window, e->atom);
1400 break;
1401 }
1402
1403 case XCB_CONFIGURE_NOTIFY:
1404 handle_configure_notify((xcb_configure_notify_event_t *)event);
1405 break;
1406
1407 default:
1408 //DLOG("Unhandled event of type %d\n", type);
1409 break;
1410 }
1411 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * ipc.c: UNIX domain socket IPC (initialization, client handling, protocol).
7 *
8 */
9 #include "all.h"
10
11 #include "yajl_utils.h"
12
13 #include <stdint.h>
14 #include <sys/socket.h>
15 #include <sys/un.h>
16 #include <fcntl.h>
17 #include <libgen.h>
18 #include <ev.h>
19 #include <yajl/yajl_gen.h>
20 #include <yajl/yajl_parse.h>
21
22 char *current_socketpath = NULL;
23
24 TAILQ_HEAD(ipc_client_head, ipc_client)
25 all_clients = TAILQ_HEAD_INITIALIZER(all_clients);
26
27 /*
28 * Puts the given socket file descriptor into non-blocking mode or dies if
29 * setting O_NONBLOCK failed. Non-blocking sockets are a good idea for our
30 * IPC model because we should by no means block the window manager.
31 *
32 */
33 static void set_nonblock(int sockfd) {
34 int flags = fcntl(sockfd, F_GETFL, 0);
35 if (flags & O_NONBLOCK) {
36 return;
37 }
38 flags |= O_NONBLOCK;
39 if (fcntl(sockfd, F_SETFL, flags) < 0)
40 err(-1, "Could not set O_NONBLOCK");
41 }
42
43 static void ipc_client_timeout(EV_P_ ev_timer *w, int revents);
44 static void ipc_socket_writeable_cb(EV_P_ struct ev_io *w, int revents);
45
46 static ev_tstamp kill_timeout = 10.0;
47
48 void ipc_set_kill_timeout(ev_tstamp new) {
49 kill_timeout = new;
50 }
51
52 /*
53 * Try to write the contents of the pending buffer to the client's subscription
54 * socket. Will set, reset or clear the timeout and io write callbacks depending
55 * on the result of the write operation.
56 *
57 */
58 static void ipc_push_pending(ipc_client *client) {
59 const ssize_t result = writeall_nonblock(client->fd, client->buffer, client->buffer_size);
60 if (result < 0) {
61 return;
62 }
63
64 if ((size_t)result == client->buffer_size) {
65 /* Everything was written successfully: clear the timer and stop the io
66 * callback. */
67 FREE(client->buffer);
68 client->buffer_size = 0;
69 if (client->timeout) {
70 ev_timer_stop(main_loop, client->timeout);
71 FREE(client->timeout);
72 }
73 ev_io_stop(main_loop, client->write_callback);
74 return;
75 }
76
77 /* Otherwise, make sure that the io callback is enabled and create a new
78 * timer if needed. */
79 ev_io_start(main_loop, client->write_callback);
80
81 if (!client->timeout) {
82 struct ev_timer *timeout = scalloc(1, sizeof(struct ev_timer));
83 ev_timer_init(timeout, ipc_client_timeout, kill_timeout, 0.);
84 timeout->data = client;
85 client->timeout = timeout;
86 ev_set_priority(timeout, EV_MINPRI);
87 ev_timer_start(main_loop, client->timeout);
88 } else if (result > 0) {
89 /* Keep the old timeout when nothing is written. Otherwise, we would
90 * keep a dead connection by continuously renewing its timeouts. */
91 ev_timer_stop(main_loop, client->timeout);
92 ev_timer_set(client->timeout, kill_timeout, 0.0);
93 ev_timer_start(main_loop, client->timeout);
94 }
95 if (result == 0) {
96 return;
97 }
98
99 /* Shift the buffer to the left and reduce the allocated space. */
100 client->buffer_size -= (size_t)result;
101 memmove(client->buffer, client->buffer + result, client->buffer_size);
102 client->buffer = srealloc(client->buffer, client->buffer_size);
103 }
104
105 /*
106 * Given a message and a message type, create the corresponding header, merge it
107 * with the message and append it to the given client's output buffer. Also,
108 * send the message if the client's buffer was empty.
109 *
110 */
111 static void ipc_send_client_message(ipc_client *client, size_t size, const uint32_t message_type, const uint8_t *payload) {
112 const i3_ipc_header_t header = {
113 .magic = {'i', '3', '-', 'i', 'p', 'c'},
114 .size = size,
115 .type = message_type};
116 const size_t header_size = sizeof(i3_ipc_header_t);
117 const size_t message_size = header_size + size;
118
119 const bool push_now = (client->buffer_size == 0);
120 client->buffer = srealloc(client->buffer, client->buffer_size + message_size);
121 memcpy(client->buffer + client->buffer_size, ((void *)&header), header_size);
122 memcpy(client->buffer + client->buffer_size + header_size, payload, size);
123 client->buffer_size += message_size;
124
125 if (push_now) {
126 ipc_push_pending(client);
127 }
128 }
129
130 static void free_ipc_client(ipc_client *client, int exempt_fd) {
131 if (client->fd != exempt_fd) {
132 DLOG("Disconnecting client on fd %d\n", client->fd);
133 close(client->fd);
134 }
135
136 ev_io_stop(main_loop, client->read_callback);
137 FREE(client->read_callback);
138 ev_io_stop(main_loop, client->write_callback);
139 FREE(client->write_callback);
140 if (client->timeout) {
141 ev_timer_stop(main_loop, client->timeout);
142 FREE(client->timeout);
143 }
144
145 free(client->buffer);
146
147 for (int i = 0; i < client->num_events; i++) {
148 free(client->events[i]);
149 }
150 free(client->events);
151 TAILQ_REMOVE(&all_clients, client, clients);
152 free(client);
153 }
154
155 /*
156 * Sends the specified event to all IPC clients which are currently connected
157 * and subscribed to this kind of event.
158 *
159 */
160 void ipc_send_event(const char *event, uint32_t message_type, const char *payload) {
161 ipc_client *current;
162 TAILQ_FOREACH (current, &all_clients, clients) {
163 for (int i = 0; i < current->num_events; i++) {
164 if (strcasecmp(current->events[i], event) == 0) {
165 ipc_send_client_message(current, strlen(payload), message_type, (uint8_t *)payload);
166 break;
167 }
168 }
169 }
170 }
171
172 /*
173 * For shutdown events, we send the reason for the shutdown.
174 */
175 static void ipc_send_shutdown_event(shutdown_reason_t reason) {
176 yajl_gen gen = ygenalloc();
177 y(map_open);
178
179 ystr("change");
180
181 if (reason == SHUTDOWN_REASON_RESTART) {
182 ystr("restart");
183 } else if (reason == SHUTDOWN_REASON_EXIT) {
184 ystr("exit");
185 }
186
187 y(map_close);
188
189 const unsigned char *payload;
190 ylength length;
191
192 y(get_buf, &payload, &length);
193 ipc_send_event("shutdown", I3_IPC_EVENT_SHUTDOWN, (const char *)payload);
194
195 y(free);
196 }
197
198 /*
199 * Calls shutdown() on each socket and closes it. This function is to be called
200 * when exiting or restarting only!
201 *
202 * exempt_fd is never closed. Set to -1 to close all fds.
203 *
204 */
205 void ipc_shutdown(shutdown_reason_t reason, int exempt_fd) {
206 ipc_send_shutdown_event(reason);
207
208 ipc_client *current;
209 while (!TAILQ_EMPTY(&all_clients)) {
210 current = TAILQ_FIRST(&all_clients);
211 if (current->fd != exempt_fd) {
212 shutdown(current->fd, SHUT_RDWR);
213 }
214 free_ipc_client(current, exempt_fd);
215 }
216 }
217
218 /*
219 * Executes the given command.
220 *
221 */
222 IPC_HANDLER(run_command) {
223 /* To get a properly terminated buffer, we copy
224 * message_size bytes out of the buffer */
225 char *command = sstrndup((const char *)message, message_size);
226 LOG("IPC: received: *%.4000s*\n", command);
227 yajl_gen gen = yajl_gen_alloc(NULL);
228
229 CommandResult *result = parse_command(command, gen, client);
230 free(command);
231
232 if (result->needs_tree_render)
233 tree_render();
234
235 command_result_free(result);
236
237 const unsigned char *reply;
238 ylength length;
239 yajl_gen_get_buf(gen, &reply, &length);
240
241 ipc_send_client_message(client, length, I3_IPC_REPLY_TYPE_COMMAND,
242 (const uint8_t *)reply);
243
244 yajl_gen_free(gen);
245 }
246
247 static void dump_rect(yajl_gen gen, const char *name, Rect r) {
248 ystr(name);
249 y(map_open);
250 ystr("x");
251 y(integer, r.x);
252 ystr("y");
253 y(integer, r.y);
254 ystr("width");
255 y(integer, r.width);
256 ystr("height");
257 y(integer, r.height);
258 y(map_close);
259 }
260
261 static void dump_gaps(yajl_gen gen, const char *name, gaps_t gaps) {
262 ystr(name);
263 y(map_open);
264 ystr("inner");
265 y(integer, gaps.inner);
266
267 // TODO: the i3ipc Python modules recognize gaps, but only inner/outer
268 // This is currently here to preserve compatibility with that
269 ystr("outer");
270 y(integer, gaps.top);
271
272 ystr("top");
273 y(integer, gaps.top);
274 ystr("right");
275 y(integer, gaps.right);
276 ystr("bottom");
277 y(integer, gaps.bottom);
278 ystr("left");
279 y(integer, gaps.left);
280 y(map_close);
281 }
282
283 static void dump_event_state_mask(yajl_gen gen, Binding *bind) {
284 y(array_open);
285 for (int i = 0; i < 20; i++) {
286 if (bind->event_state_mask & (1 << i)) {
287 switch (1 << i) {
288 case XCB_KEY_BUT_MASK_SHIFT:
289 ystr("shift");
290 break;
291 case XCB_KEY_BUT_MASK_LOCK:
292 ystr("lock");
293 break;
294 case XCB_KEY_BUT_MASK_CONTROL:
295 ystr("ctrl");
296 break;
297 case XCB_KEY_BUT_MASK_MOD_1:
298 ystr("Mod1");
299 break;
300 case XCB_KEY_BUT_MASK_MOD_2:
301 ystr("Mod2");
302 break;
303 case XCB_KEY_BUT_MASK_MOD_3:
304 ystr("Mod3");
305 break;
306 case XCB_KEY_BUT_MASK_MOD_4:
307 ystr("Mod4");
308 break;
309 case XCB_KEY_BUT_MASK_MOD_5:
310 ystr("Mod5");
311 break;
312 case XCB_KEY_BUT_MASK_BUTTON_1:
313 ystr("Button1");
314 break;
315 case XCB_KEY_BUT_MASK_BUTTON_2:
316 ystr("Button2");
317 break;
318 case XCB_KEY_BUT_MASK_BUTTON_3:
319 ystr("Button3");
320 break;
321 case XCB_KEY_BUT_MASK_BUTTON_4:
322 ystr("Button4");
323 break;
324 case XCB_KEY_BUT_MASK_BUTTON_5:
325 ystr("Button5");
326 break;
327 case (I3_XKB_GROUP_MASK_1 << 16):
328 ystr("Group1");
329 break;
330 case (I3_XKB_GROUP_MASK_2 << 16):
331 ystr("Group2");
332 break;
333 case (I3_XKB_GROUP_MASK_3 << 16):
334 ystr("Group3");
335 break;
336 case (I3_XKB_GROUP_MASK_4 << 16):
337 ystr("Group4");
338 break;
339 }
340 }
341 }
342 y(array_close);
343 }
344
345 static void dump_binding(yajl_gen gen, Binding *bind) {
346 y(map_open);
347 ystr("input_code");
348 y(integer, bind->keycode);
349
350 ystr("input_type");
351 ystr((const char *)(bind->input_type == B_KEYBOARD ? "keyboard" : "mouse"));
352
353 ystr("symbol");
354 if (bind->symbol == NULL)
355 y(null);
356 else
357 ystr(bind->symbol);
358
359 ystr("command");
360 ystr(bind->command);
361
362 // This key is only provided for compatibility, new programs should use
363 // event_state_mask instead.
364 ystr("mods");
365 dump_event_state_mask(gen, bind);
366
367 ystr("event_state_mask");
368 dump_event_state_mask(gen, bind);
369
370 y(map_close);
371 }
372
373 void dump_node(yajl_gen gen, struct Con *con, bool inplace_restart) {
374 y(map_open);
375 ystr("id");
376 y(integer, (uintptr_t)con);
377
378 ystr("type");
379 switch (con->type) {
380 case CT_ROOT:
381 ystr("root");
382 break;
383 case CT_OUTPUT:
384 ystr("output");
385 break;
386 case CT_CON:
387 ystr("con");
388 break;
389 case CT_FLOATING_CON:
390 ystr("floating_con");
391 break;
392 case CT_WORKSPACE:
393 ystr("workspace");
394 break;
395 case CT_DOCKAREA:
396 ystr("dockarea");
397 break;
398 }
399
400 /* provided for backwards compatibility only. */
401 ystr("orientation");
402 if (!con_is_split(con))
403 ystr("none");
404 else {
405 if (con_orientation(con) == HORIZ)
406 ystr("horizontal");
407 else
408 ystr("vertical");
409 }
410
411 ystr("scratchpad_state");
412 switch (con->scratchpad_state) {
413 case SCRATCHPAD_NONE:
414 ystr("none");
415 break;
416 case SCRATCHPAD_FRESH:
417 ystr("fresh");
418 break;
419 case SCRATCHPAD_CHANGED:
420 ystr("changed");
421 break;
422 }
423
424 ystr("percent");
425 if (con->percent == 0.0)
426 y(null);
427 else
428 y(double, con->percent);
429
430 ystr("urgent");
431 y(bool, con->urgent);
432
433 ystr("marks");
434 y(array_open);
435 mark_t *mark;
436 TAILQ_FOREACH (mark, &(con->marks_head), marks) {
437 ystr(mark->name);
438 }
439 y(array_close);
440
441 ystr("focused");
442 y(bool, (con == focused));
443
444 if (con->type != CT_ROOT && con->type != CT_OUTPUT) {
445 ystr("output");
446 ystr(con_get_output(con)->name);
447 }
448
449 ystr("layout");
450 switch (con->layout) {
451 case L_DEFAULT:
452 DLOG("About to dump layout=default, this is a bug in the code.\n");
453 assert(false);
454 break;
455 case L_SPLITV:
456 ystr("splitv");
457 break;
458 case L_SPLITH:
459 ystr("splith");
460 break;
461 case L_STACKED:
462 ystr("stacked");
463 break;
464 case L_TABBED:
465 ystr("tabbed");
466 break;
467 case L_DOCKAREA:
468 ystr("dockarea");
469 break;
470 case L_OUTPUT:
471 ystr("output");
472 break;
473 }
474
475 ystr("workspace_layout");
476 switch (con->workspace_layout) {
477 case L_DEFAULT:
478 ystr("default");
479 break;
480 case L_STACKED:
481 ystr("stacked");
482 break;
483 case L_TABBED:
484 ystr("tabbed");
485 break;
486 default:
487 DLOG("About to dump workspace_layout=%d (none of default/stacked/tabbed), this is a bug.\n", con->workspace_layout);
488 assert(false);
489 break;
490 }
491
492 ystr("last_split_layout");
493 switch (con->layout) {
494 case L_SPLITV:
495 ystr("splitv");
496 break;
497 default:
498 ystr("splith");
499 break;
500 }
501
502 ystr("border");
503 switch (con->border_style) {
504 case BS_NORMAL:
505 ystr("normal");
506 break;
507 case BS_NONE:
508 ystr("none");
509 break;
510 case BS_PIXEL:
511 ystr("pixel");
512 break;
513 }
514
515 ystr("current_border_width");
516 y(integer, con->current_border_width);
517
518 dump_rect(gen, "rect", con->rect);
519 dump_rect(gen, "deco_rect", con->deco_rect);
520 dump_rect(gen, "window_rect", con->window_rect);
521 dump_rect(gen, "geometry", con->geometry);
522
523 ystr("name");
524 if (con->window && con->window->name)
525 ystr(i3string_as_utf8(con->window->name));
526 else if (con->name != NULL)
527 ystr(con->name);
528 else
529 y(null);
530
531 if (con->title_format != NULL) {
532 ystr("title_format");
533 ystr(con->title_format);
534 }
535
536 if (con->type == CT_WORKSPACE) {
537 ystr("num");
538 y(integer, con->num);
539
540 dump_gaps(gen, "gaps", con->gaps);
541 }
542
543 ystr("window");
544 if (con->window)
545 y(integer, con->window->id);
546 else
547 y(null);
548
549 ystr("window_type");
550 if (con->window) {
551 if (con->window->window_type == A__NET_WM_WINDOW_TYPE_NORMAL) {
552 ystr("normal");
553 } else if (con->window->window_type == A__NET_WM_WINDOW_TYPE_DOCK) {
554 ystr("dock");
555 } else if (con->window->window_type == A__NET_WM_WINDOW_TYPE_DIALOG) {
556 ystr("dialog");
557 } else if (con->window->window_type == A__NET_WM_WINDOW_TYPE_UTILITY) {
558 ystr("utility");
559 } else if (con->window->window_type == A__NET_WM_WINDOW_TYPE_TOOLBAR) {
560 ystr("toolbar");
561 } else if (con->window->window_type == A__NET_WM_WINDOW_TYPE_SPLASH) {
562 ystr("splash");
563 } else if (con->window->window_type == A__NET_WM_WINDOW_TYPE_MENU) {
564 ystr("menu");
565 } else if (con->window->window_type == A__NET_WM_WINDOW_TYPE_DROPDOWN_MENU) {
566 ystr("dropdown_menu");
567 } else if (con->window->window_type == A__NET_WM_WINDOW_TYPE_POPUP_MENU) {
568 ystr("popup_menu");
569 } else if (con->window->window_type == A__NET_WM_WINDOW_TYPE_TOOLTIP) {
570 ystr("tooltip");
571 } else if (con->window->window_type == A__NET_WM_WINDOW_TYPE_NOTIFICATION) {
572 ystr("notification");
573 } else {
574 ystr("unknown");
575 }
576 } else
577 y(null);
578
579 if (con->window && !inplace_restart) {
580 /* Window properties are useless to preserve when restarting because
581 * they will be queried again anyway. However, for i3-save-tree(1),
582 * they are very useful and save i3-save-tree dealing with X11. */
583 ystr("window_properties");
584 y(map_open);
585
586 #define DUMP_PROPERTY(key, prop_name) \
587 do { \
588 if (con->window->prop_name != NULL) { \
589 ystr(key); \
590 ystr(con->window->prop_name); \
591 } \
592 } while (0)
593
594 DUMP_PROPERTY("class", class_class);
595 DUMP_PROPERTY("instance", class_instance);
596 DUMP_PROPERTY("window_role", role);
597
598 if (con->window->name != NULL) {
599 ystr("title");
600 ystr(i3string_as_utf8(con->window->name));
601 }
602
603 ystr("transient_for");
604 if (con->window->transient_for == XCB_NONE)
605 y(null);
606 else
607 y(integer, con->window->transient_for);
608
609 y(map_close);
610 }
611
612 ystr("nodes");
613 y(array_open);
614 Con *node;
615 if (con->type != CT_DOCKAREA || !inplace_restart) {
616 TAILQ_FOREACH (node, &(con->nodes_head), nodes) {
617 dump_node(gen, node, inplace_restart);
618 }
619 }
620 y(array_close);
621
622 ystr("floating_nodes");
623 y(array_open);
624 TAILQ_FOREACH (node, &(con->floating_head), floating_windows) {
625 dump_node(gen, node, inplace_restart);
626 }
627 y(array_close);
628
629 ystr("focus");
630 y(array_open);
631 TAILQ_FOREACH (node, &(con->focus_head), focused) {
632 y(integer, (uintptr_t)node);
633 }
634 y(array_close);
635
636 ystr("fullscreen_mode");
637 y(integer, con->fullscreen_mode);
638
639 ystr("sticky");
640 y(bool, con->sticky);
641
642 ystr("floating");
643 switch (con->floating) {
644 case FLOATING_AUTO_OFF:
645 ystr("auto_off");
646 break;
647 case FLOATING_AUTO_ON:
648 ystr("auto_on");
649 break;
650 case FLOATING_USER_OFF:
651 ystr("user_off");
652 break;
653 case FLOATING_USER_ON:
654 ystr("user_on");
655 break;
656 }
657
658 ystr("swallows");
659 y(array_open);
660 Match *match;
661 TAILQ_FOREACH (match, &(con->swallow_head), matches) {
662 /* We will generate a new restart_mode match specification after this
663 * loop, so skip this one. */
664 if (match->restart_mode)
665 continue;
666 y(map_open);
667 if (match->dock != M_DONTCHECK) {
668 ystr("dock");
669 y(integer, match->dock);
670 ystr("insert_where");
671 y(integer, match->insert_where);
672 }
673
674 #define DUMP_REGEX(re_name) \
675 do { \
676 if (match->re_name != NULL) { \
677 ystr(#re_name); \
678 ystr(match->re_name->pattern); \
679 } \
680 } while (0)
681
682 DUMP_REGEX(class);
683 DUMP_REGEX(instance);
684 DUMP_REGEX(window_role);
685 DUMP_REGEX(title);
686
687 #undef DUMP_REGEX
688 y(map_close);
689 }
690
691 if (inplace_restart) {
692 if (con->window != NULL) {
693 y(map_open);
694 ystr("id");
695 y(integer, con->window->id);
696 ystr("restart_mode");
697 y(bool, true);
698 y(map_close);
699 }
700 }
701 y(array_close);
702
703 if (inplace_restart && con->window != NULL) {
704 ystr("depth");
705 y(integer, con->depth);
706 }
707
708 if (inplace_restart && con->type == CT_ROOT && previous_workspace_name) {
709 ystr("previous_workspace_name");
710 ystr(previous_workspace_name);
711 }
712
713 y(map_close);
714 }
715
716 static void dump_bar_bindings(yajl_gen gen, Barconfig *config) {
717 if (TAILQ_EMPTY(&(config->bar_bindings)))
718 return;
719
720 ystr("bindings");
721 y(array_open);
722
723 struct Barbinding *current;
724 TAILQ_FOREACH (current, &(config->bar_bindings), bindings) {
725 y(map_open);
726
727 ystr("input_code");
728 y(integer, current->input_code);
729 ystr("command");
730 ystr(current->command);
731 ystr("release");
732 y(bool, current->release == B_UPON_KEYRELEASE);
733
734 y(map_close);
735 }
736
737 y(array_close);
738 }
739
740 static char *canonicalize_output_name(char *name) {
741 /* Do not canonicalize special output names. */
742 if (strcasecmp(name, "primary") == 0) {
743 return name;
744 }
745 Output *output = get_output_by_name(name, false);
746 return output ? output_primary_name(output) : name;
747 }
748
749 static void dump_bar_config(yajl_gen gen, Barconfig *config) {
750 y(map_open);
751
752 ystr("id");
753 ystr(config->id);
754
755 if (config->num_outputs > 0) {
756 ystr("outputs");
757 y(array_open);
758 for (int c = 0; c < config->num_outputs; c++) {
759 /* Convert monitor names (RandR ≥ 1.5) or output names
760 * (RandR < 1.5) into monitor names. This way, existing
761 * configs which use output names transparently keep
762 * working. */
763 ystr(canonicalize_output_name(config->outputs[c]));
764 }
765 y(array_close);
766 }
767
768 if (!TAILQ_EMPTY(&(config->tray_outputs))) {
769 ystr("tray_outputs");
770 y(array_open);
771
772 struct tray_output_t *tray_output;
773 TAILQ_FOREACH (tray_output, &(config->tray_outputs), tray_outputs) {
774 ystr(canonicalize_output_name(tray_output->output));
775 }
776
777 y(array_close);
778 }
779
780 #define YSTR_IF_SET(name) \
781 do { \
782 if (config->name) { \
783 ystr(#name); \
784 ystr(config->name); \
785 } \
786 } while (0)
787
788 ystr("tray_padding");
789 y(integer, config->tray_padding);
790
791 YSTR_IF_SET(socket_path);
792
793 ystr("mode");
794 switch (config->mode) {
795 case M_HIDE:
796 ystr("hide");
797 break;
798 case M_INVISIBLE:
799 ystr("invisible");
800 break;
801 case M_DOCK:
802 default:
803 ystr("dock");
804 break;
805 }
806
807 ystr("hidden_state");
808 switch (config->hidden_state) {
809 case S_SHOW:
810 ystr("show");
811 break;
812 case S_HIDE:
813 default:
814 ystr("hide");
815 break;
816 }
817
818 ystr("modifier");
819 y(integer, config->modifier);
820
821 dump_bar_bindings(gen, config);
822
823 ystr("position");
824 if (config->position == P_BOTTOM)
825 ystr("bottom");
826 else
827 ystr("top");
828
829 YSTR_IF_SET(status_command);
830 YSTR_IF_SET(font);
831
832 if (config->bar_height) {
833 ystr("bar_height");
834 y(integer, config->bar_height);
835 }
836
837 if (config->separator_symbol) {
838 ystr("separator_symbol");
839 ystr(config->separator_symbol);
840 }
841
842 ystr("workspace_buttons");
843 y(bool, !config->hide_workspace_buttons);
844
845 ystr("workspace_min_width");
846 y(integer, config->workspace_min_width);
847
848 ystr("strip_workspace_numbers");
849 y(bool, config->strip_workspace_numbers);
850
851 ystr("strip_workspace_name");
852 y(bool, config->strip_workspace_name);
853
854 ystr("binding_mode_indicator");
855 y(bool, !config->hide_binding_mode_indicator);
856
857 ystr("verbose");
858 y(bool, config->verbose);
859
860 #undef YSTR_IF_SET
861 #define YSTR_IF_SET(name) \
862 do { \
863 if (config->colors.name) { \
864 ystr(#name); \
865 ystr(config->colors.name); \
866 } \
867 } while (0)
868
869 ystr("colors");
870 y(map_open);
871 YSTR_IF_SET(background);
872 YSTR_IF_SET(statusline);
873 YSTR_IF_SET(separator);
874 YSTR_IF_SET(focused_background);
875 YSTR_IF_SET(focused_statusline);
876 YSTR_IF_SET(focused_separator);
877 YSTR_IF_SET(focused_workspace_border);
878 YSTR_IF_SET(focused_workspace_bg);
879 YSTR_IF_SET(focused_workspace_text);
880 YSTR_IF_SET(active_workspace_border);
881 YSTR_IF_SET(active_workspace_bg);
882 YSTR_IF_SET(active_workspace_text);
883 YSTR_IF_SET(inactive_workspace_border);
884 YSTR_IF_SET(inactive_workspace_bg);
885 YSTR_IF_SET(inactive_workspace_text);
886 YSTR_IF_SET(urgent_workspace_border);
887 YSTR_IF_SET(urgent_workspace_bg);
888 YSTR_IF_SET(urgent_workspace_text);
889 YSTR_IF_SET(binding_mode_border);
890 YSTR_IF_SET(binding_mode_bg);
891 YSTR_IF_SET(binding_mode_text);
892 y(map_close);
893
894 y(map_close);
895 #undef YSTR_IF_SET
896 }
897
898 IPC_HANDLER(tree) {
899 setlocale(LC_NUMERIC, "C");
900 yajl_gen gen = ygenalloc();
901 dump_node(gen, croot, false);
902 setlocale(LC_NUMERIC, "");
903
904 const unsigned char *payload;
905 ylength length;
906 y(get_buf, &payload, &length);
907
908 ipc_send_client_message(client, length, I3_IPC_REPLY_TYPE_TREE, payload);
909 y(free);
910 }
911
912 /*
913 * Formats the reply message for a GET_WORKSPACES request and sends it to the
914 * client
915 *
916 */
917 IPC_HANDLER(get_workspaces) {
918 yajl_gen gen = ygenalloc();
919 y(array_open);
920
921 Con *focused_ws = con_get_workspace(focused);
922
923 Con *output;
924 TAILQ_FOREACH (output, &(croot->nodes_head), nodes) {
925 if (con_is_internal(output))
926 continue;
927 Con *ws;
928 TAILQ_FOREACH (ws, &(output_get_content(output)->nodes_head), nodes) {
929 assert(ws->type == CT_WORKSPACE);
930 y(map_open);
931
932 ystr("id");
933 y(integer, (uintptr_t)ws);
934
935 ystr("num");
936 y(integer, ws->num);
937
938 ystr("name");
939 ystr(ws->name);
940
941 ystr("visible");
942 y(bool, workspace_is_visible(ws));
943
944 ystr("focused");
945 y(bool, ws == focused_ws);
946
947 ystr("rect");
948 y(map_open);
949 ystr("x");
950 y(integer, ws->rect.x);
951 ystr("y");
952 y(integer, ws->rect.y);
953 ystr("width");
954 y(integer, ws->rect.width);
955 ystr("height");
956 y(integer, ws->rect.height);
957 y(map_close);
958
959 ystr("output");
960 ystr(output->name);
961
962 ystr("urgent");
963 y(bool, ws->urgent);
964
965 y(map_close);
966 }
967 }
968
969 y(array_close);
970
971 const unsigned char *payload;
972 ylength length;
973 y(get_buf, &payload, &length);
974
975 ipc_send_client_message(client, length, I3_IPC_REPLY_TYPE_WORKSPACES, payload);
976 y(free);
977 }
978
979 /*
980 * Formats the reply message for a GET_OUTPUTS request and sends it to the
981 * client
982 *
983 */
984 IPC_HANDLER(get_outputs) {
985 yajl_gen gen = ygenalloc();
986 y(array_open);
987
988 Output *output;
989 TAILQ_FOREACH (output, &outputs, outputs) {
990 y(map_open);
991
992 ystr("name");
993 ystr(output_primary_name(output));
994
995 ystr("active");
996 y(bool, output->active);
997
998 ystr("primary");
999 y(bool, output->primary);
1000
1001 ystr("rect");
1002 y(map_open);
1003 ystr("x");
1004 y(integer, output->rect.x);
1005 ystr("y");
1006 y(integer, output->rect.y);
1007 ystr("width");
1008 y(integer, output->rect.width);
1009 ystr("height");
1010 y(integer, output->rect.height);
1011 y(map_close);
1012
1013 ystr("current_workspace");
1014 Con *ws = NULL;
1015 if (output->con && (ws = con_get_fullscreen_con(output->con, CF_OUTPUT)))
1016 ystr(ws->name);
1017 else
1018 y(null);
1019
1020 y(map_close);
1021 }
1022
1023 y(array_close);
1024
1025 const unsigned char *payload;
1026 ylength length;
1027 y(get_buf, &payload, &length);
1028
1029 ipc_send_client_message(client, length, I3_IPC_REPLY_TYPE_OUTPUTS, payload);
1030 y(free);
1031 }
1032
1033 /*
1034 * Formats the reply message for a GET_MARKS request and sends it to the
1035 * client
1036 *
1037 */
1038 IPC_HANDLER(get_marks) {
1039 yajl_gen gen = ygenalloc();
1040 y(array_open);
1041
1042 Con *con;
1043 TAILQ_FOREACH (con, &all_cons, all_cons) {
1044 mark_t *mark;
1045 TAILQ_FOREACH (mark, &(con->marks_head), marks) {
1046 ystr(mark->name);
1047 }
1048 }
1049
1050 y(array_close);
1051
1052 const unsigned char *payload;
1053 ylength length;
1054 y(get_buf, &payload, &length);
1055
1056 ipc_send_client_message(client, length, I3_IPC_REPLY_TYPE_MARKS, payload);
1057 y(free);
1058 }
1059
1060 /*
1061 * Returns the version of i3
1062 *
1063 */
1064 IPC_HANDLER(get_version) {
1065 yajl_gen gen = ygenalloc();
1066 y(map_open);
1067
1068 ystr("major");
1069 y(integer, MAJOR_VERSION);
1070
1071 ystr("minor");
1072 y(integer, MINOR_VERSION);
1073
1074 ystr("patch");
1075 y(integer, PATCH_VERSION);
1076
1077 ystr("human_readable");
1078 ystr(i3_version);
1079
1080 ystr("loaded_config_file_name");
1081 ystr(current_configpath);
1082
1083 y(map_close);
1084
1085 const unsigned char *payload;
1086 ylength length;
1087 y(get_buf, &payload, &length);
1088
1089 ipc_send_client_message(client, length, I3_IPC_REPLY_TYPE_VERSION, payload);
1090 y(free);
1091 }
1092
1093 /*
1094 * Formats the reply message for a GET_BAR_CONFIG request and sends it to the
1095 * client.
1096 *
1097 */
1098 IPC_HANDLER(get_bar_config) {
1099 yajl_gen gen = ygenalloc();
1100
1101 /* If no ID was passed, we return a JSON array with all IDs */
1102 if (message_size == 0) {
1103 y(array_open);
1104 Barconfig *current;
1105 TAILQ_FOREACH (current, &barconfigs, configs) {
1106 ystr(current->id);
1107 }
1108 y(array_close);
1109
1110 const unsigned char *payload;
1111 ylength length;
1112 y(get_buf, &payload, &length);
1113
1114 ipc_send_client_message(client, length, I3_IPC_REPLY_TYPE_BAR_CONFIG, payload);
1115 y(free);
1116 return;
1117 }
1118
1119 /* To get a properly terminated buffer, we copy
1120 * message_size bytes out of the buffer */
1121 char *bar_id = NULL;
1122 sasprintf(&bar_id, "%.*s", message_size, message);
1123 LOG("IPC: looking for config for bar ID \"%s\"\n", bar_id);
1124 Barconfig *current, *config = NULL;
1125 TAILQ_FOREACH (current, &barconfigs, configs) {
1126 if (strcmp(current->id, bar_id) != 0)
1127 continue;
1128
1129 config = current;
1130 break;
1131 }
1132 free(bar_id);
1133
1134 if (!config) {
1135 /* If we did not find a config for the given ID, the reply will contain
1136 * a null 'id' field. */
1137 y(map_open);
1138
1139 ystr("id");
1140 y(null);
1141
1142 y(map_close);
1143 } else {
1144 dump_bar_config(gen, config);
1145 }
1146
1147 const unsigned char *payload;
1148 ylength length;
1149 y(get_buf, &payload, &length);
1150
1151 ipc_send_client_message(client, length, I3_IPC_REPLY_TYPE_BAR_CONFIG, payload);
1152 y(free);
1153 }
1154
1155 /*
1156 * Returns a list of configured binding modes
1157 *
1158 */
1159 IPC_HANDLER(get_binding_modes) {
1160 yajl_gen gen = ygenalloc();
1161
1162 y(array_open);
1163 struct Mode *mode;
1164 SLIST_FOREACH (mode, &modes, modes) {
1165 ystr(mode->name);
1166 }
1167 y(array_close);
1168
1169 const unsigned char *payload;
1170 ylength length;
1171 y(get_buf, &payload, &length);
1172
1173 ipc_send_client_message(client, length, I3_IPC_REPLY_TYPE_BINDING_MODES, payload);
1174 y(free);
1175 }
1176
1177 /*
1178 * Callback for the YAJL parser (will be called when a string is parsed).
1179 *
1180 */
1181 static int add_subscription(void *extra, const unsigned char *s,
1182 ylength len) {
1183 ipc_client *client = extra;
1184
1185 DLOG("should add subscription to extra %p, sub %.*s\n", client, (int)len, s);
1186 int event = client->num_events;
1187
1188 client->num_events++;
1189 client->events = srealloc(client->events, client->num_events * sizeof(char *));
1190 /* We copy the string because it is not null-terminated and strndup()
1191 * is missing on some BSD systems */
1192 client->events[event] = scalloc(len + 1, 1);
1193 memcpy(client->events[event], s, len);
1194
1195 DLOG("client is now subscribed to:\n");
1196 for (int i = 0; i < client->num_events; i++) {
1197 DLOG("event %s\n", client->events[i]);
1198 }
1199 DLOG("(done)\n");
1200
1201 return 1;
1202 }
1203
1204 /*
1205 * Subscribes this connection to the event types which were given as a JSON
1206 * serialized array in the payload field of the message.
1207 *
1208 */
1209 IPC_HANDLER(subscribe) {
1210 yajl_handle p;
1211 yajl_status stat;
1212
1213 /* Setup the JSON parser */
1214 static yajl_callbacks callbacks = {
1215 .yajl_string = add_subscription,
1216 };
1217
1218 p = yalloc(&callbacks, (void *)client);
1219 stat = yajl_parse(p, (const unsigned char *)message, message_size);
1220 if (stat != yajl_status_ok) {
1221 unsigned char *err;
1222 err = yajl_get_error(p, true, (const unsigned char *)message,
1223 message_size);
1224 ELOG("YAJL parse error: %s\n", err);
1225 yajl_free_error(p, err);
1226
1227 const char *reply = "{\"success\":false}";
1228 ipc_send_client_message(client, strlen(reply), I3_IPC_REPLY_TYPE_SUBSCRIBE, (const uint8_t *)reply);
1229 yajl_free(p);
1230 return;
1231 }
1232 yajl_free(p);
1233 const char *reply = "{\"success\":true}";
1234 ipc_send_client_message(client, strlen(reply), I3_IPC_REPLY_TYPE_SUBSCRIBE, (const uint8_t *)reply);
1235
1236 if (client->first_tick_sent) {
1237 return;
1238 }
1239
1240 bool is_tick = false;
1241 for (int i = 0; i < client->num_events; i++) {
1242 if (strcmp(client->events[i], "tick") == 0) {
1243 is_tick = true;
1244 break;
1245 }
1246 }
1247 if (!is_tick) {
1248 return;
1249 }
1250
1251 client->first_tick_sent = true;
1252 const char *payload = "{\"first\":true,\"payload\":\"\"}";
1253 ipc_send_client_message(client, strlen(payload), I3_IPC_EVENT_TICK, (const uint8_t *)payload);
1254 }
1255
1256 /*
1257 * Returns the raw last loaded i3 configuration file contents.
1258 */
1259 IPC_HANDLER(get_config) {
1260 yajl_gen gen = ygenalloc();
1261
1262 y(map_open);
1263
1264 ystr("config");
1265 ystr(current_config);
1266
1267 y(map_close);
1268
1269 const unsigned char *payload;
1270 ylength length;
1271 y(get_buf, &payload, &length);
1272
1273 ipc_send_client_message(client, length, I3_IPC_REPLY_TYPE_CONFIG, payload);
1274 y(free);
1275 }
1276
1277 /*
1278 * Sends the tick event from the message payload to subscribers. Establishes a
1279 * synchronization point in event-related tests.
1280 */
1281 IPC_HANDLER(send_tick) {
1282 yajl_gen gen = ygenalloc();
1283
1284 y(map_open);
1285
1286 ystr("first");
1287 y(bool, false);
1288
1289 ystr("payload");
1290 yajl_gen_string(gen, (unsigned char *)message, message_size);
1291
1292 y(map_close);
1293
1294 const unsigned char *payload;
1295 ylength length;
1296 y(get_buf, &payload, &length);
1297
1298 ipc_send_event("tick", I3_IPC_EVENT_TICK, (const char *)payload);
1299 y(free);
1300
1301 const char *reply = "{\"success\":true}";
1302 ipc_send_client_message(client, strlen(reply), I3_IPC_REPLY_TYPE_TICK, (const uint8_t *)reply);
1303 DLOG("Sent tick event\n");
1304 }
1305
1306 struct sync_state {
1307 char *last_key;
1308 uint32_t rnd;
1309 xcb_window_t window;
1310 };
1311
1312 static int _sync_json_key(void *extra, const unsigned char *val, size_t len) {
1313 struct sync_state *state = extra;
1314 FREE(state->last_key);
1315 state->last_key = scalloc(len + 1, 1);
1316 memcpy(state->last_key, val, len);
1317 return 1;
1318 }
1319
1320 static int _sync_json_int(void *extra, long long val) {
1321 struct sync_state *state = extra;
1322 if (strcasecmp(state->last_key, "rnd") == 0) {
1323 state->rnd = val;
1324 } else if (strcasecmp(state->last_key, "window") == 0) {
1325 state->window = (xcb_window_t)val;
1326 }
1327 return 1;
1328 }
1329
1330 IPC_HANDLER(sync) {
1331 yajl_handle p;
1332 yajl_status stat;
1333
1334 /* Setup the JSON parser */
1335 static yajl_callbacks callbacks = {
1336 .yajl_map_key = _sync_json_key,
1337 .yajl_integer = _sync_json_int,
1338 };
1339
1340 struct sync_state state;
1341 memset(&state, '\0', sizeof(struct sync_state));
1342 p = yalloc(&callbacks, (void *)&state);
1343 stat = yajl_parse(p, (const unsigned char *)message, message_size);
1344 FREE(state.last_key);
1345 if (stat != yajl_status_ok) {
1346 unsigned char *err;
1347 err = yajl_get_error(p, true, (const unsigned char *)message,
1348 message_size);
1349 ELOG("YAJL parse error: %s\n", err);
1350 yajl_free_error(p, err);
1351
1352 const char *reply = "{\"success\":false}";
1353 ipc_send_client_message(client, strlen(reply), I3_IPC_REPLY_TYPE_SYNC, (const uint8_t *)reply);
1354 yajl_free(p);
1355 return;
1356 }
1357 yajl_free(p);
1358
1359 DLOG("received IPC sync request (rnd = %d, window = 0x%08x)\n", state.rnd, state.window);
1360 sync_respond(state.window, state.rnd);
1361 const char *reply = "{\"success\":true}";
1362 ipc_send_client_message(client, strlen(reply), I3_IPC_REPLY_TYPE_SYNC, (const uint8_t *)reply);
1363 }
1364
1365 /* The index of each callback function corresponds to the numeric
1366 * value of the message type (see include/i3/ipc.h) */
1367 handler_t handlers[12] = {
1368 handle_run_command,
1369 handle_get_workspaces,
1370 handle_subscribe,
1371 handle_get_outputs,
1372 handle_tree,
1373 handle_get_marks,
1374 handle_get_bar_config,
1375 handle_get_version,
1376 handle_get_binding_modes,
1377 handle_get_config,
1378 handle_send_tick,
1379 handle_sync,
1380 };
1381
1382 /*
1383 * Handler for activity on a client connection, receives a message from a
1384 * client.
1385 *
1386 * For now, the maximum message size is 2048. I’m not sure for what the
1387 * IPC interface will be used in the future, thus I’m not implementing a
1388 * mechanism for arbitrarily long messages, as it seems like overkill
1389 * at the moment.
1390 *
1391 */
1392 static void ipc_receive_message(EV_P_ struct ev_io *w, int revents) {
1393 uint32_t message_type;
1394 uint32_t message_length;
1395 uint8_t *message = NULL;
1396 ipc_client *client = (ipc_client *)w->data;
1397 assert(client->fd == w->fd);
1398
1399 int ret = ipc_recv_message(w->fd, &message_type, &message_length, &message);
1400 /* EOF or other error */
1401 if (ret < 0) {
1402 /* Was this a spurious read? See ev(3) */
1403 if (ret == -1 && errno == EAGAIN) {
1404 FREE(message);
1405 return;
1406 }
1407
1408 /* If not, there was some kind of error. We don’t bother and close the
1409 * connection. Delete the client from the list of clients. */
1410 free_ipc_client(client, -1);
1411 FREE(message);
1412 return;
1413 }
1414
1415 if (message_type >= (sizeof(handlers) / sizeof(handler_t)))
1416 DLOG("Unhandled message type: %d\n", message_type);
1417 else {
1418 handler_t h = handlers[message_type];
1419 h(client, message, 0, message_length, message_type);
1420 }
1421
1422 FREE(message);
1423 }
1424
1425 static void ipc_client_timeout(EV_P_ ev_timer *w, int revents) {
1426 /* No need to be polite and check for writeability, the other callback would
1427 * have been called by now. */
1428 ipc_client *client = (ipc_client *)w->data;
1429
1430 char *cmdline = NULL;
1431 #if defined(__linux__) && defined(SO_PEERCRED)
1432 struct ucred peercred;
1433 socklen_t so_len = sizeof(peercred);
1434 if (getsockopt(client->fd, SOL_SOCKET, SO_PEERCRED, &peercred, &so_len) != 0) {
1435 goto end;
1436 }
1437 char *exepath;
1438 sasprintf(&exepath, "/proc/%d/cmdline", peercred.pid);
1439
1440 int fd = open(exepath, O_RDONLY);
1441 free(exepath);
1442 if (fd == -1) {
1443 goto end;
1444 }
1445 char buf[512] = {'\0'}; /* cut off cmdline for the error message. */
1446 const ssize_t n = read(fd, buf, sizeof(buf));
1447 close(fd);
1448 if (n < 0) {
1449 goto end;
1450 }
1451 for (char *walk = buf; walk < buf + n - 1; walk++) {
1452 if (*walk == '\0') {
1453 *walk = ' ';
1454 }
1455 }
1456 cmdline = buf;
1457
1458 if (cmdline) {
1459 ELOG("client %p with pid %d and cmdline '%s' on fd %d timed out, killing\n", client, peercred.pid, cmdline, client->fd);
1460 }
1461
1462 end:
1463 #endif
1464 if (!cmdline) {
1465 ELOG("client %p on fd %d timed out, killing\n", client, client->fd);
1466 }
1467
1468 free_ipc_client(client, -1);
1469 }
1470
1471 static void ipc_socket_writeable_cb(EV_P_ ev_io *w, int revents) {
1472 DLOG("fd %d writeable\n", w->fd);
1473 ipc_client *client = (ipc_client *)w->data;
1474
1475 /* If this callback is called then there should be a corresponding active
1476 * timer. */
1477 assert(client->timeout != NULL);
1478 ipc_push_pending(client);
1479 }
1480
1481 /*
1482 * Handler for activity on the listening socket, meaning that a new client
1483 * has just connected and we should accept() him. Sets up the event handler
1484 * for activity on the new connection and inserts the file descriptor into
1485 * the list of clients.
1486 *
1487 */
1488 void ipc_new_client(EV_P_ struct ev_io *w, int revents) {
1489 struct sockaddr_un peer;
1490 socklen_t len = sizeof(struct sockaddr_un);
1491 int fd;
1492 if ((fd = accept(w->fd, (struct sockaddr *)&peer, &len)) < 0) {
1493 if (errno != EINTR) {
1494 perror("accept()");
1495 }
1496 return;
1497 }
1498
1499 /* Close this file descriptor on exec() */
1500 (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
1501
1502 ipc_new_client_on_fd(EV_A_ fd);
1503 }
1504
1505 /*
1506 * ipc_new_client_on_fd() only sets up the event handler
1507 * for activity on the new connection and inserts the file descriptor into
1508 * the list of clients.
1509 *
1510 * This variant is useful for the inherited IPC connection when restarting.
1511 *
1512 */
1513 ipc_client *ipc_new_client_on_fd(EV_P_ int fd) {
1514 set_nonblock(fd);
1515
1516 ipc_client *client = scalloc(1, sizeof(ipc_client));
1517 client->fd = fd;
1518
1519 client->read_callback = scalloc(1, sizeof(struct ev_io));
1520 client->read_callback->data = client;
1521 ev_io_init(client->read_callback, ipc_receive_message, fd, EV_READ);
1522 ev_io_start(EV_A_ client->read_callback);
1523
1524 client->write_callback = scalloc(1, sizeof(struct ev_io));
1525 client->write_callback->data = client;
1526 ev_io_init(client->write_callback, ipc_socket_writeable_cb, fd, EV_WRITE);
1527
1528 DLOG("IPC: new client connected on fd %d\n", fd);
1529 TAILQ_INSERT_TAIL(&all_clients, client, clients);
1530 return client;
1531 }
1532
1533 /*
1534 * Creates the UNIX domain socket at the given path, sets it to non-blocking
1535 * mode, bind()s and listen()s on it.
1536 *
1537 */
1538 int ipc_create_socket(const char *filename) {
1539 int sockfd;
1540
1541 FREE(current_socketpath);
1542
1543 char *resolved = resolve_tilde(filename);
1544 DLOG("Creating IPC-socket at %s\n", resolved);
1545 char *copy = sstrdup(resolved);
1546 const char *dir = dirname(copy);
1547 if (!path_exists(dir))
1548 mkdirp(dir, DEFAULT_DIR_MODE);
1549 free(copy);
1550
1551 /* Unlink the unix domain socket before */
1552 unlink(resolved);
1553
1554 if ((sockfd = socket(AF_LOCAL, SOCK_STREAM, 0)) < 0) {
1555 perror("socket()");
1556 free(resolved);
1557 return -1;
1558 }
1559
1560 (void)fcntl(sockfd, F_SETFD, FD_CLOEXEC);
1561
1562 struct sockaddr_un addr;
1563 memset(&addr, 0, sizeof(struct sockaddr_un));
1564 addr.sun_family = AF_LOCAL;
1565 strncpy(addr.sun_path, resolved, sizeof(addr.sun_path) - 1);
1566 if (bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0) {
1567 perror("bind()");
1568 free(resolved);
1569 return -1;
1570 }
1571
1572 set_nonblock(sockfd);
1573
1574 if (listen(sockfd, 5) < 0) {
1575 perror("listen()");
1576 free(resolved);
1577 return -1;
1578 }
1579
1580 current_socketpath = resolved;
1581 return sockfd;
1582 }
1583
1584 /*
1585 * Generates a json workspace event. Returns a dynamically allocated yajl
1586 * generator. Free with yajl_gen_free().
1587 */
1588 yajl_gen ipc_marshal_workspace_event(const char *change, Con *current, Con *old) {
1589 setlocale(LC_NUMERIC, "C");
1590 yajl_gen gen = ygenalloc();
1591
1592 y(map_open);
1593
1594 ystr("change");
1595 ystr(change);
1596
1597 ystr("current");
1598 if (current == NULL)
1599 y(null);
1600 else
1601 dump_node(gen, current, false);
1602
1603 ystr("old");
1604 if (old == NULL)
1605 y(null);
1606 else
1607 dump_node(gen, old, false);
1608
1609 y(map_close);
1610
1611 setlocale(LC_NUMERIC, "");
1612
1613 return gen;
1614 }
1615
1616 /*
1617 * For the workspace events we send, along with the usual "change" field, also
1618 * the workspace container in "current". For focus events, we send the
1619 * previously focused workspace in "old".
1620 */
1621 void ipc_send_workspace_event(const char *change, Con *current, Con *old) {
1622 yajl_gen gen = ipc_marshal_workspace_event(change, current, old);
1623
1624 const unsigned char *payload;
1625 ylength length;
1626 y(get_buf, &payload, &length);
1627
1628 ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, (const char *)payload);
1629
1630 y(free);
1631 }
1632
1633 /*
1634 * For the window events we send, along the usual "change" field,
1635 * also the window container, in "container".
1636 */
1637 void ipc_send_window_event(const char *property, Con *con) {
1638 DLOG("Issue IPC window %s event (con = %p, window = 0x%08x)\n",
1639 property, con, (con->window ? con->window->id : XCB_WINDOW_NONE));
1640
1641 setlocale(LC_NUMERIC, "C");
1642 yajl_gen gen = ygenalloc();
1643
1644 y(map_open);
1645
1646 ystr("change");
1647 ystr(property);
1648
1649 ystr("container");
1650 dump_node(gen, con, false);
1651
1652 y(map_close);
1653
1654 const unsigned char *payload;
1655 ylength length;
1656 y(get_buf, &payload, &length);
1657
1658 ipc_send_event("window", I3_IPC_EVENT_WINDOW, (const char *)payload);
1659 y(free);
1660 setlocale(LC_NUMERIC, "");
1661 }
1662
1663 /*
1664 * For the barconfig update events, we send the serialized barconfig.
1665 */
1666 void ipc_send_barconfig_update_event(Barconfig *barconfig) {
1667 DLOG("Issue barconfig_update event for id = %s\n", barconfig->id);
1668 setlocale(LC_NUMERIC, "C");
1669 yajl_gen gen = ygenalloc();
1670
1671 dump_bar_config(gen, barconfig);
1672
1673 const unsigned char *payload;
1674 ylength length;
1675 y(get_buf, &payload, &length);
1676
1677 ipc_send_event("barconfig_update", I3_IPC_EVENT_BARCONFIG_UPDATE, (const char *)payload);
1678 y(free);
1679 setlocale(LC_NUMERIC, "");
1680 }
1681
1682 /*
1683 * For the binding events, we send the serialized binding struct.
1684 */
1685 void ipc_send_binding_event(const char *event_type, Binding *bind) {
1686 DLOG("Issue IPC binding %s event (sym = %s, code = %d)\n", event_type, bind->symbol, bind->keycode);
1687
1688 setlocale(LC_NUMERIC, "C");
1689
1690 yajl_gen gen = ygenalloc();
1691
1692 y(map_open);
1693
1694 ystr("change");
1695 ystr(event_type);
1696
1697 ystr("binding");
1698 dump_binding(gen, bind);
1699
1700 y(map_close);
1701
1702 const unsigned char *payload;
1703 ylength length;
1704 y(get_buf, &payload, &length);
1705
1706 ipc_send_event("binding", I3_IPC_EVENT_BINDING, (const char *)payload);
1707
1708 y(free);
1709 setlocale(LC_NUMERIC, "");
1710 }
1711
1712 /*
1713 * Sends a restart reply to the IPC client on the specified fd.
1714 */
1715 void ipc_confirm_restart(ipc_client *client) {
1716 DLOG("ipc_confirm_restart(fd %d)\n", client->fd);
1717 static const char *reply = "[{\"success\":true}]";
1718 ipc_send_client_message(
1719 client, strlen(reply), I3_IPC_REPLY_TYPE_COMMAND,
1720 (const uint8_t *)reply);
1721 ipc_push_pending(client);
1722 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * key_press.c: key press handler
7 *
8 */
9 #include "all.h"
10
11 /*
12 * There was a KeyPress or KeyRelease (both events have the same fields). We
13 * compare this key code with our bindings table and pass the bound action to
14 * parse_command().
15 *
16 */
17 void handle_key_press(xcb_key_press_event_t *event) {
18 const bool key_release = (event->response_type == XCB_KEY_RELEASE);
19
20 last_timestamp = event->time;
21
22 DLOG("%s %d, state raw = 0x%x\n", (key_release ? "KeyRelease" : "KeyPress"), event->detail, event->state);
23
24 Binding *bind = get_binding_from_xcb_event((xcb_generic_event_t *)event);
25
26 /* if we couldn't find a binding, we are done */
27 if (bind == NULL)
28 return;
29
30 CommandResult *result = run_binding(bind, NULL);
31 command_result_free(result);
32 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * load_layout.c: Restore (parts of) the layout, for example after an inplace
7 * restart.
8 *
9 */
10 #include "all.h"
11
12 #include <yajl/yajl_common.h>
13 #include <yajl/yajl_gen.h>
14 #include <yajl/yajl_parse.h>
15 #include <yajl/yajl_version.h>
16
17 /* TODO: refactor the whole parsing thing */
18
19 static char *last_key;
20 static int incomplete;
21 static Con *json_node;
22 static Con *to_focus;
23 static bool parsing_gaps;
24 static bool parsing_swallows;
25 static bool parsing_rect;
26 static bool parsing_deco_rect;
27 static bool parsing_window_rect;
28 static bool parsing_geometry;
29 static bool parsing_focus;
30 static bool parsing_marks;
31 struct Match *current_swallow;
32 static bool swallow_is_empty;
33 static int num_marks;
34 /* We need to save each container that needs to be marked if we want to support
35 * marking non-leaf containers. In their case, the end_map for their children is
36 * called before their own end_map, so marking json_node would end up marking
37 * the latest child. We can't just mark containers immediately after we parse a
38 * mark because of #2511. */
39 struct pending_marks {
40 char *mark;
41 Con *con_to_be_marked;
42 } * marks;
43
44 /* This list is used for reordering the focus stack after parsing the 'focus'
45 * array. */
46 struct focus_mapping {
47 int old_id;
48
49 TAILQ_ENTRY(focus_mapping)
50 focus_mappings;
51 };
52
53 static TAILQ_HEAD(focus_mappings_head, focus_mapping) focus_mappings =
54 TAILQ_HEAD_INITIALIZER(focus_mappings);
55
56 static int json_start_map(void *ctx) {
57 LOG("start of map, last_key = %s\n", last_key);
58 if (parsing_swallows) {
59 LOG("creating new swallow\n");
60 current_swallow = smalloc(sizeof(Match));
61 match_init(current_swallow);
62 current_swallow->dock = M_DONTCHECK;
63 TAILQ_INSERT_TAIL(&(json_node->swallow_head), current_swallow, matches);
64 swallow_is_empty = true;
65 } else {
66 if (!parsing_rect && !parsing_deco_rect && !parsing_window_rect && !parsing_geometry && !parsing_gaps) {
67 if (last_key && strcasecmp(last_key, "floating_nodes") == 0) {
68 DLOG("New floating_node\n");
69 Con *ws = con_get_workspace(json_node);
70 json_node = con_new_skeleton(NULL, NULL);
71 json_node->name = NULL;
72 json_node->parent = ws;
73 DLOG("Parent is workspace = %p\n", ws);
74 } else {
75 Con *parent = json_node;
76 json_node = con_new_skeleton(NULL, NULL);
77 json_node->name = NULL;
78 json_node->parent = parent;
79 }
80 /* json_node is incomplete and should be removed if parsing fails */
81 incomplete++;
82 DLOG("incomplete = %d\n", incomplete);
83 }
84 }
85 return 1;
86 }
87
88 static int json_end_map(void *ctx) {
89 LOG("end of map\n");
90 if (!parsing_swallows && !parsing_rect && !parsing_deco_rect && !parsing_window_rect && !parsing_geometry && !parsing_gaps) {
91 /* Set a few default values to simplify manually crafted layout files. */
92 if (json_node->layout == L_DEFAULT) {
93 DLOG("Setting layout = L_SPLITH\n");
94 json_node->layout = L_SPLITH;
95 }
96
97 /* Sanity check: swallow criteria don’t make any sense on a split
98 * container. */
99 if (con_is_split(json_node) > 0 && !TAILQ_EMPTY(&(json_node->swallow_head))) {
100 DLOG("sanity check: removing swallows specification from split container\n");
101 while (!TAILQ_EMPTY(&(json_node->swallow_head))) {
102 Match *match = TAILQ_FIRST(&(json_node->swallow_head));
103 TAILQ_REMOVE(&(json_node->swallow_head), match, matches);
104 match_free(match);
105 free(match);
106 }
107 }
108
109 if (json_node->type == CT_WORKSPACE) {
110 /* Ensure the workspace has a name. */
111 DLOG("Attaching workspace. name = %s\n", json_node->name);
112 if (json_node->name == NULL || strcmp(json_node->name, "") == 0) {
113 json_node->name = sstrdup("unnamed");
114 }
115
116 /* Prevent name clashes when appending a workspace, e.g. when the
117 * user tries to restore a workspace called “1” but already has a
118 * workspace called “1”. */
119 char *base = sstrdup(json_node->name);
120 int cnt = 1;
121 while (get_existing_workspace_by_name(json_node->name) != NULL) {
122 FREE(json_node->name);
123 sasprintf(&(json_node->name), "%s_%d", base, cnt++);
124 }
125 free(base);
126
127 /* Set num accordingly so that i3bar will properly sort it. */
128 json_node->num = ws_name_to_number(json_node->name);
129 }
130
131 // When appending JSON layout files that only contain the workspace
132 // _contents_, we might not have an upfront signal that the
133 // container we’re currently parsing is a floating container (like
134 // the “floating_nodes” key of the workspace container itself).
135 // That’s why we make sure the con is attached at the right place
136 // in the hierarchy in case it’s floating.
137 if (json_node->type == CT_FLOATING_CON) {
138 DLOG("fixing parent which currently is %p / %s\n", json_node->parent, json_node->parent->name);
139 json_node->parent = con_get_workspace(json_node->parent);
140
141 // Also set a size if none was supplied, otherwise the placeholder
142 // window cannot be created as X11 requests with width=0 or
143 // height=0 are invalid.
144 if (rect_equals(json_node->rect, (Rect){0, 0, 0, 0})) {
145 DLOG("Geometry not set, combining children\n");
146 Con *child;
147 TAILQ_FOREACH (child, &(json_node->nodes_head), nodes) {
148 DLOG("child geometry: %d x %d\n", child->geometry.width, child->geometry.height);
149 json_node->rect.width += child->geometry.width;
150 json_node->rect.height = max(json_node->rect.height, child->geometry.height);
151 }
152 }
153
154 floating_check_size(json_node, false);
155 }
156
157 if (num_marks > 0) {
158 for (int i = 0; i < num_marks; i++) {
159 Con *con = marks[i].con_to_be_marked;
160 char *mark = marks[i].mark;
161 con_mark(con, mark, MM_ADD);
162 free(mark);
163 }
164
165 FREE(marks);
166 num_marks = 0;
167 }
168
169 LOG("attaching\n");
170 con_attach(json_node, json_node->parent, true);
171 LOG("Creating window\n");
172 x_con_init(json_node);
173
174 /* Fix erroneous JSON input regarding floating containers to avoid
175 * crashing, see #3901. */
176 const int old_floating_mode = json_node->floating;
177 if (old_floating_mode >= FLOATING_AUTO_ON && json_node->parent->type != CT_FLOATING_CON) {
178 LOG("Fixing floating node without CT_FLOATING_CON parent\n");
179
180 /* Force floating_enable to work */
181 json_node->floating = FLOATING_AUTO_OFF;
182 floating_enable(json_node, false);
183 json_node->floating = old_floating_mode;
184 }
185
186 json_node = json_node->parent;
187 incomplete--;
188 DLOG("incomplete = %d\n", incomplete);
189 }
190
191 if (parsing_swallows && swallow_is_empty) {
192 /* We parsed an empty swallow definition. This is an invalid layout
193 * definition, hence we reject it. */
194 ELOG("Layout file is invalid: found an empty swallow definition.\n");
195 return 0;
196 }
197
198 parsing_gaps = false;
199 parsing_rect = false;
200 parsing_deco_rect = false;
201 parsing_window_rect = false;
202 parsing_geometry = false;
203 return 1;
204 }
205
206 static int json_end_array(void *ctx) {
207 LOG("end of array\n");
208 if (!parsing_swallows && !parsing_focus && !parsing_marks) {
209 con_fix_percent(json_node);
210 }
211 if (parsing_swallows) {
212 parsing_swallows = false;
213 }
214 if (parsing_marks) {
215 parsing_marks = false;
216 }
217
218 if (parsing_focus) {
219 /* Clear the list of focus mappings */
220 struct focus_mapping *mapping;
221 TAILQ_FOREACH_REVERSE (mapping, &focus_mappings, focus_mappings_head, focus_mappings) {
222 LOG("focus (reverse) %d\n", mapping->old_id);
223 Con *con;
224 TAILQ_FOREACH (con, &(json_node->focus_head), focused) {
225 if (con->old_id != mapping->old_id)
226 continue;
227 LOG("got it! %p\n", con);
228 /* Move this entry to the top of the focus list. */
229 TAILQ_REMOVE(&(json_node->focus_head), con, focused);
230 TAILQ_INSERT_HEAD(&(json_node->focus_head), con, focused);
231 break;
232 }
233 }
234 while (!TAILQ_EMPTY(&focus_mappings)) {
235 mapping = TAILQ_FIRST(&focus_mappings);
236 TAILQ_REMOVE(&focus_mappings, mapping, focus_mappings);
237 free(mapping);
238 }
239 parsing_focus = false;
240 }
241 return 1;
242 }
243
244 static int json_key(void *ctx, const unsigned char *val, size_t len) {
245 LOG("key: %.*s\n", (int)len, val);
246 FREE(last_key);
247 last_key = scalloc(len + 1, 1);
248 memcpy(last_key, val, len);
249 if (strcasecmp(last_key, "swallows") == 0)
250 parsing_swallows = true;
251
252 if (strcasecmp(last_key, "gaps") == 0)
253 parsing_gaps = true;
254
255 if (strcasecmp(last_key, "rect") == 0)
256 parsing_rect = true;
257
258 if (strcasecmp(last_key, "deco_rect") == 0)
259 parsing_deco_rect = true;
260
261 if (strcasecmp(last_key, "window_rect") == 0)
262 parsing_window_rect = true;
263
264 if (strcasecmp(last_key, "geometry") == 0)
265 parsing_geometry = true;
266
267 if (strcasecmp(last_key, "focus") == 0)
268 parsing_focus = true;
269
270 if (strcasecmp(last_key, "marks") == 0) {
271 num_marks = 0;
272 parsing_marks = true;
273 }
274
275 return 1;
276 }
277
278 static int json_string(void *ctx, const unsigned char *val, size_t len) {
279 LOG("string: %.*s for key %s\n", (int)len, val, last_key);
280 if (parsing_swallows) {
281 char *sval;
282 sasprintf(&sval, "%.*s", len, val);
283 if (strcasecmp(last_key, "class") == 0) {
284 current_swallow->class = regex_new(sval);
285 swallow_is_empty = false;
286 } else if (strcasecmp(last_key, "instance") == 0) {
287 current_swallow->instance = regex_new(sval);
288 swallow_is_empty = false;
289 } else if (strcasecmp(last_key, "window_role") == 0) {
290 current_swallow->window_role = regex_new(sval);
291 swallow_is_empty = false;
292 } else if (strcasecmp(last_key, "title") == 0) {
293 current_swallow->title = regex_new(sval);
294 swallow_is_empty = false;
295 } else {
296 ELOG("swallow key %s unknown\n", last_key);
297 }
298 free(sval);
299 } else if (parsing_marks) {
300 char *mark;
301 sasprintf(&mark, "%.*s", (int)len, val);
302
303 marks = srealloc(marks, (++num_marks) * sizeof(struct pending_marks));
304 marks[num_marks - 1].mark = sstrdup(mark);
305 marks[num_marks - 1].con_to_be_marked = json_node;
306 } else {
307 if (strcasecmp(last_key, "name") == 0) {
308 json_node->name = scalloc(len + 1, 1);
309 memcpy(json_node->name, val, len);
310 } else if (strcasecmp(last_key, "title_format") == 0) {
311 json_node->title_format = scalloc(len + 1, 1);
312 memcpy(json_node->title_format, val, len);
313 } else if (strcasecmp(last_key, "sticky_group") == 0) {
314 json_node->sticky_group = scalloc(len + 1, 1);
315 memcpy(json_node->sticky_group, val, len);
316 LOG("sticky_group of this container is %s\n", json_node->sticky_group);
317 } else if (strcasecmp(last_key, "orientation") == 0) {
318 /* Upgrade path from older versions of i3 (doing an inplace restart
319 * to a newer version):
320 * "orientation" is dumped before "layout". Therefore, we store
321 * whether the orientation was horizontal or vertical in the
322 * last_split_layout. When we then encounter layout == "default",
323 * we will use the last_split_layout as layout instead. */
324 char *buf = NULL;
325 sasprintf(&buf, "%.*s", (int)len, val);
326 if (strcasecmp(buf, "none") == 0 ||
327 strcasecmp(buf, "horizontal") == 0)
328 json_node->last_split_layout = L_SPLITH;
329 else if (strcasecmp(buf, "vertical") == 0)
330 json_node->last_split_layout = L_SPLITV;
331 else
332 LOG("Unhandled orientation: %s\n", buf);
333 free(buf);
334 } else if (strcasecmp(last_key, "border") == 0) {
335 char *buf = NULL;
336 sasprintf(&buf, "%.*s", (int)len, val);
337 if (strcasecmp(buf, "none") == 0)
338 json_node->border_style = BS_NONE;
339 else if (strcasecmp(buf, "1pixel") == 0) {
340 json_node->border_style = BS_PIXEL;
341 json_node->current_border_width = 1;
342 } else if (strcasecmp(buf, "pixel") == 0)
343 json_node->border_style = BS_PIXEL;
344 else if (strcasecmp(buf, "normal") == 0)
345 json_node->border_style = BS_NORMAL;
346 else
347 LOG("Unhandled \"border\": %s\n", buf);
348 free(buf);
349 } else if (strcasecmp(last_key, "type") == 0) {
350 char *buf = NULL;
351 sasprintf(&buf, "%.*s", (int)len, val);
352 if (strcasecmp(buf, "root") == 0)
353 json_node->type = CT_ROOT;
354 else if (strcasecmp(buf, "output") == 0)
355 json_node->type = CT_OUTPUT;
356 else if (strcasecmp(buf, "con") == 0)
357 json_node->type = CT_CON;
358 else if (strcasecmp(buf, "floating_con") == 0)
359 json_node->type = CT_FLOATING_CON;
360 else if (strcasecmp(buf, "workspace") == 0)
361 json_node->type = CT_WORKSPACE;
362 else if (strcasecmp(buf, "dockarea") == 0)
363 json_node->type = CT_DOCKAREA;
364 else
365 LOG("Unhandled \"type\": %s\n", buf);
366 free(buf);
367 } else if (strcasecmp(last_key, "layout") == 0) {
368 char *buf = NULL;
369 sasprintf(&buf, "%.*s", (int)len, val);
370 if (strcasecmp(buf, "default") == 0)
371 /* This set above when we read "orientation". */
372 json_node->layout = json_node->last_split_layout;
373 else if (strcasecmp(buf, "stacked") == 0)
374 json_node->layout = L_STACKED;
375 else if (strcasecmp(buf, "tabbed") == 0)
376 json_node->layout = L_TABBED;
377 else if (strcasecmp(buf, "dockarea") == 0)
378 json_node->layout = L_DOCKAREA;
379 else if (strcasecmp(buf, "output") == 0)
380 json_node->layout = L_OUTPUT;
381 else if (strcasecmp(buf, "splith") == 0)
382 json_node->layout = L_SPLITH;
383 else if (strcasecmp(buf, "splitv") == 0)
384 json_node->layout = L_SPLITV;
385 else
386 LOG("Unhandled \"layout\": %s\n", buf);
387 free(buf);
388 } else if (strcasecmp(last_key, "workspace_layout") == 0) {
389 char *buf = NULL;
390 sasprintf(&buf, "%.*s", (int)len, val);
391 if (strcasecmp(buf, "default") == 0)
392 json_node->workspace_layout = L_DEFAULT;
393 else if (strcasecmp(buf, "stacked") == 0)
394 json_node->workspace_layout = L_STACKED;
395 else if (strcasecmp(buf, "tabbed") == 0)
396 json_node->workspace_layout = L_TABBED;
397 else
398 LOG("Unhandled \"workspace_layout\": %s\n", buf);
399 free(buf);
400 } else if (strcasecmp(last_key, "last_split_layout") == 0) {
401 char *buf = NULL;
402 sasprintf(&buf, "%.*s", (int)len, val);
403 if (strcasecmp(buf, "splith") == 0)
404 json_node->last_split_layout = L_SPLITH;
405 else if (strcasecmp(buf, "splitv") == 0)
406 json_node->last_split_layout = L_SPLITV;
407 else
408 LOG("Unhandled \"last_splitlayout\": %s\n", buf);
409 free(buf);
410 } else if (strcasecmp(last_key, "mark") == 0) {
411 DLOG("Found deprecated key \"mark\".\n");
412
413 char *buf = NULL;
414 sasprintf(&buf, "%.*s", (int)len, val);
415
416 con_mark(json_node, buf, MM_REPLACE);
417 } else if (strcasecmp(last_key, "floating") == 0) {
418 char *buf = NULL;
419 sasprintf(&buf, "%.*s", (int)len, val);
420 if (strcasecmp(buf, "auto_off") == 0)
421 json_node->floating = FLOATING_AUTO_OFF;
422 else if (strcasecmp(buf, "auto_on") == 0)
423 json_node->floating = FLOATING_AUTO_ON;
424 else if (strcasecmp(buf, "user_off") == 0)
425 json_node->floating = FLOATING_USER_OFF;
426 else if (strcasecmp(buf, "user_on") == 0)
427 json_node->floating = FLOATING_USER_ON;
428 free(buf);
429 } else if (strcasecmp(last_key, "scratchpad_state") == 0) {
430 char *buf = NULL;
431 sasprintf(&buf, "%.*s", (int)len, val);
432 if (strcasecmp(buf, "none") == 0)
433 json_node->scratchpad_state = SCRATCHPAD_NONE;
434 else if (strcasecmp(buf, "fresh") == 0)
435 json_node->scratchpad_state = SCRATCHPAD_FRESH;
436 else if (strcasecmp(buf, "changed") == 0)
437 json_node->scratchpad_state = SCRATCHPAD_CHANGED;
438 free(buf);
439 } else if (strcasecmp(last_key, "previous_workspace_name") == 0) {
440 FREE(previous_workspace_name);
441 previous_workspace_name = sstrndup((const char *)val, len);
442 }
443 }
444 return 1;
445 }
446
447 static int json_int(void *ctx, long long val) {
448 LOG("int %lld for key %s\n", val, last_key);
449 /* For backwards compatibility with i3 < 4.8 */
450 if (strcasecmp(last_key, "type") == 0)
451 json_node->type = val;
452
453 if (strcasecmp(last_key, "fullscreen_mode") == 0)
454 json_node->fullscreen_mode = val;
455
456 if (strcasecmp(last_key, "num") == 0)
457 json_node->num = val;
458
459 if (strcasecmp(last_key, "current_border_width") == 0)
460 json_node->current_border_width = val;
461
462 if (strcasecmp(last_key, "depth") == 0)
463 json_node->depth = val;
464
465 if (!parsing_swallows && strcasecmp(last_key, "id") == 0)
466 json_node->old_id = val;
467
468 if (parsing_focus) {
469 struct focus_mapping *focus_mapping = scalloc(1, sizeof(struct focus_mapping));
470 focus_mapping->old_id = val;
471 TAILQ_INSERT_TAIL(&focus_mappings, focus_mapping, focus_mappings);
472 }
473
474 if (parsing_rect || parsing_window_rect || parsing_geometry) {
475 Rect *r;
476 if (parsing_rect)
477 r = &(json_node->rect);
478 else if (parsing_window_rect)
479 r = &(json_node->window_rect);
480 else
481 r = &(json_node->geometry);
482 if (strcasecmp(last_key, "x") == 0)
483 r->x = val;
484 else if (strcasecmp(last_key, "y") == 0)
485 r->y = val;
486 else if (strcasecmp(last_key, "width") == 0)
487 r->width = val;
488 else if (strcasecmp(last_key, "height") == 0)
489 r->height = val;
490 else
491 ELOG("WARNING: unknown key %s in rect\n", last_key);
492 DLOG("rect now: (%d, %d, %d, %d)\n",
493 r->x, r->y, r->width, r->height);
494 }
495 if (parsing_swallows) {
496 if (strcasecmp(last_key, "id") == 0) {
497 current_swallow->id = val;
498 swallow_is_empty = false;
499 }
500 if (strcasecmp(last_key, "dock") == 0) {
501 current_swallow->dock = val;
502 swallow_is_empty = false;
503 }
504 if (strcasecmp(last_key, "insert_where") == 0) {
505 current_swallow->insert_where = val;
506 swallow_is_empty = false;
507 }
508 }
509 if (parsing_gaps) {
510 if (strcasecmp(last_key, "inner") == 0)
511 json_node->gaps.inner = val;
512 else if (strcasecmp(last_key, "top") == 0)
513 json_node->gaps.top = val;
514 else if (strcasecmp(last_key, "right") == 0)
515 json_node->gaps.right = val;
516 else if (strcasecmp(last_key, "bottom") == 0)
517 json_node->gaps.bottom = val;
518 else if (strcasecmp(last_key, "left") == 0)
519 json_node->gaps.left = val;
520 }
521
522 return 1;
523 }
524
525 static int json_bool(void *ctx, int val) {
526 LOG("bool %d for key %s\n", val, last_key);
527 if (strcasecmp(last_key, "focused") == 0 && val) {
528 to_focus = json_node;
529 }
530
531 if (strcasecmp(last_key, "sticky") == 0)
532 json_node->sticky = val;
533
534 if (parsing_swallows) {
535 if (strcasecmp(last_key, "restart_mode") == 0) {
536 current_swallow->restart_mode = val;
537 swallow_is_empty = false;
538 }
539 }
540
541 return 1;
542 }
543
544 static int json_double(void *ctx, double val) {
545 LOG("double %f for key %s\n", val, last_key);
546 if (strcasecmp(last_key, "percent") == 0) {
547 json_node->percent = val;
548 }
549 return 1;
550 }
551
552 static json_content_t content_result;
553 static int content_level;
554
555 static int json_determine_content_deeper(void *ctx) {
556 content_level++;
557 return 1;
558 }
559
560 static int json_determine_content_shallower(void *ctx) {
561 content_level--;
562 return 1;
563 }
564
565 static int json_determine_content_string(void *ctx, const unsigned char *val, size_t len) {
566 if (strcasecmp(last_key, "type") != 0 || content_level > 1)
567 return 1;
568
569 DLOG("string = %.*s, last_key = %s\n", (int)len, val, last_key);
570 if (strncasecmp((const char *)val, "workspace", len) == 0)
571 content_result = JSON_CONTENT_WORKSPACE;
572 return 0;
573 }
574
575 /*
576 * Returns true if the provided JSON could be parsed by yajl.
577 *
578 */
579 bool json_validate(const char *buf, const size_t len) {
580 bool valid = true;
581 yajl_handle hand = yajl_alloc(NULL, NULL, NULL);
582 /* Allowing comments allows for more user-friendly layout files. */
583 yajl_config(hand, yajl_allow_comments, true);
584 /* Allow multiple values, i.e. multiple nodes to attach */
585 yajl_config(hand, yajl_allow_multiple_values, true);
586
587 setlocale(LC_NUMERIC, "C");
588 if (yajl_parse(hand, (const unsigned char *)buf, len) != yajl_status_ok) {
589 unsigned char *str = yajl_get_error(hand, 1, (const unsigned char *)buf, len);
590 ELOG("JSON parsing error: %s\n", str);
591 yajl_free_error(hand, str);
592 valid = false;
593 }
594 setlocale(LC_NUMERIC, "");
595
596 yajl_complete_parse(hand);
597 yajl_free(hand);
598
599 return valid;
600 }
601
602 /* Parses the given JSON file until it encounters the first “type” property to
603 * determine whether the file contains workspaces or regular containers, which
604 * is important to know when deciding where (and how) to append the contents.
605 * */
606 json_content_t json_determine_content(const char *buf, const size_t len) {
607 // We default to JSON_CONTENT_CON because it is legal to not include
608 // “"type": "con"” in the JSON files for better readability.
609 content_result = JSON_CONTENT_CON;
610 content_level = 0;
611 static yajl_callbacks callbacks = {
612 .yajl_string = json_determine_content_string,
613 .yajl_map_key = json_key,
614 .yajl_start_array = json_determine_content_deeper,
615 .yajl_start_map = json_determine_content_deeper,
616 .yajl_end_map = json_determine_content_shallower,
617 .yajl_end_array = json_determine_content_shallower,
618 };
619 yajl_handle hand = yajl_alloc(&callbacks, NULL, NULL);
620 /* Allowing comments allows for more user-friendly layout files. */
621 yajl_config(hand, yajl_allow_comments, true);
622 /* Allow multiple values, i.e. multiple nodes to attach */
623 yajl_config(hand, yajl_allow_multiple_values, true);
624 setlocale(LC_NUMERIC, "C");
625 const yajl_status stat = yajl_parse(hand, (const unsigned char *)buf, len);
626 if (stat != yajl_status_ok && stat != yajl_status_client_canceled) {
627 unsigned char *str = yajl_get_error(hand, 1, (const unsigned char *)buf, len);
628 ELOG("JSON parsing error: %s\n", str);
629 yajl_free_error(hand, str);
630 }
631
632 setlocale(LC_NUMERIC, "");
633 yajl_complete_parse(hand);
634 yajl_free(hand);
635
636 return content_result;
637 }
638
639 void tree_append_json(Con *con, const char *buf, const size_t len, char **errormsg) {
640 static yajl_callbacks callbacks = {
641 .yajl_boolean = json_bool,
642 .yajl_integer = json_int,
643 .yajl_double = json_double,
644 .yajl_string = json_string,
645 .yajl_start_map = json_start_map,
646 .yajl_map_key = json_key,
647 .yajl_end_map = json_end_map,
648 .yajl_end_array = json_end_array,
649 };
650 yajl_handle hand = yajl_alloc(&callbacks, NULL, NULL);
651 /* Allowing comments allows for more user-friendly layout files. */
652 yajl_config(hand, yajl_allow_comments, true);
653 /* Allow multiple values, i.e. multiple nodes to attach */
654 yajl_config(hand, yajl_allow_multiple_values, true);
655 /* We don't need to validate that the input is valid UTF8 here.
656 * tree_append_json is called in two cases:
657 * 1. With the append_layout command. json_validate is called first and will
658 * fail on invalid UTF8 characters so we don't need to recheck.
659 * 2. With an in-place restart. The rest of the codebase should be
660 * responsible for producing valid UTF8 JSON output. If not,
661 * tree_append_json will just preserve invalid UTF8 strings in the tree
662 * instead of failing to parse the layout file which could lead to
663 * problems like in #3156.
664 * Either way, disabling UTF8 validation slightly speeds up yajl. */
665 yajl_config(hand, yajl_dont_validate_strings, true);
666 json_node = con;
667 to_focus = NULL;
668 parsing_gaps = false;
669 incomplete = 0;
670 parsing_swallows = false;
671 parsing_rect = false;
672 parsing_deco_rect = false;
673 parsing_window_rect = false;
674 parsing_geometry = false;
675 parsing_focus = false;
676 parsing_marks = false;
677 setlocale(LC_NUMERIC, "C");
678 const yajl_status stat = yajl_parse(hand, (const unsigned char *)buf, len);
679 if (stat != yajl_status_ok) {
680 unsigned char *str = yajl_get_error(hand, 1, (const unsigned char *)buf, len);
681 ELOG("JSON parsing error: %s\n", str);
682 if (errormsg != NULL)
683 *errormsg = sstrdup((const char *)str);
684 yajl_free_error(hand, str);
685 while (incomplete-- > 0) {
686 Con *parent = json_node->parent;
687 DLOG("freeing incomplete container %p\n", json_node);
688 if (json_node == to_focus) {
689 to_focus = NULL;
690 }
691 con_free(json_node);
692 json_node = parent;
693 }
694 }
695
696 /* In case not all containers were restored, we need to fix the
697 * percentages, otherwise i3 will crash immediately when rendering the
698 * next time. */
699 con_fix_percent(con);
700
701 setlocale(LC_NUMERIC, "");
702 yajl_complete_parse(hand);
703 yajl_free(hand);
704
705 if (to_focus) {
706 con_activate(to_focus);
707 }
708 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * log.c: Logging functions.
7 *
8 */
9 #include <config.h>
10
11 #include <stdarg.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdbool.h>
15 #include <stdlib.h>
16 #include <sys/time.h>
17 #include <unistd.h>
18 #include <fcntl.h>
19 #include <sys/mman.h>
20 #include <sys/stat.h>
21 #include <errno.h>
22 #if !defined(__OpenBSD__)
23 #include <pthread.h>
24 #endif
25
26 #include "util.h"
27 #include "log.h"
28 #include "i3.h"
29 #include "libi3.h"
30 #include "shmlog.h"
31
32 #if defined(__APPLE__)
33 #include <sys/sysctl.h>
34 #endif
35
36 static bool debug_logging = false;
37 static bool verbose = false;
38 static FILE *errorfile;
39 char *errorfilename;
40
41 /* SHM logging variables */
42
43 /* The name for the SHM (/i3-log-%pid). Will end up on /dev/shm on most
44 * systems. Global so that we can clean up at exit. */
45 char *shmlogname = "";
46 /* Size limit for the SHM log, by default 25 MiB. Can be overwritten using the
47 * flag --shmlog-size. */
48 int shmlog_size = 0;
49 /* If enabled, logbuffer will point to a memory mapping of the i3 SHM log. */
50 static char *logbuffer;
51 /* A pointer (within logbuffer) where data will be written to next. */
52 static char *logwalk;
53 /* A pointer to the shmlog header */
54 static i3_shmlog_header *header;
55 /* A pointer to the byte where we last wrapped. Necessary to not print the
56 * left-overs at the end of the ringbuffer. */
57 static char *loglastwrap;
58 /* Size (in bytes) of the i3 SHM log. */
59 static int logbuffer_size;
60 /* File descriptor for shm_open. */
61 static int logbuffer_shm;
62 /* Size (in bytes) of physical memory */
63 static long long physical_mem_bytes;
64
65 /*
66 * Writes the offsets for the next write and for the last wrap to the
67 * shmlog_header.
68 * Necessary to print the i3 SHM log in the correct order.
69 *
70 */
71 static void store_log_markers(void) {
72 header->offset_next_write = (logwalk - logbuffer);
73 header->offset_last_wrap = (loglastwrap - logbuffer);
74 header->size = logbuffer_size;
75 }
76
77 /*
78 * Initializes logging by creating an error logfile in /tmp (or
79 * XDG_RUNTIME_DIR, see get_process_filename()).
80 *
81 * Will be called twice if --shmlog-size is specified.
82 *
83 */
84 void init_logging(void) {
85 if (!errorfilename) {
86 if (!(errorfilename = get_process_filename("errorlog")))
87 fprintf(stderr, "Could not initialize errorlog\n");
88 else {
89 errorfile = fopen(errorfilename, "w");
90 if (!errorfile) {
91 fprintf(stderr, "Could not initialize errorlog on %s: %s\n",
92 errorfilename, strerror(errno));
93 } else {
94 if (fcntl(fileno(errorfile), F_SETFD, FD_CLOEXEC)) {
95 fprintf(stderr, "Could not set close-on-exec flag\n");
96 }
97 }
98 }
99 }
100 if (physical_mem_bytes == 0) {
101 #if defined(__APPLE__)
102 int mib[2] = {CTL_HW, HW_MEMSIZE};
103 size_t length = sizeof(long long);
104 sysctl(mib, 2, &physical_mem_bytes, &length, NULL, 0);
105 #else
106 physical_mem_bytes = (long long)sysconf(_SC_PHYS_PAGES) *
107 sysconf(_SC_PAGESIZE);
108 #endif
109 }
110 /* Start SHM logging if shmlog_size is > 0. shmlog_size is SHMLOG_SIZE by
111 * default on development versions, and 0 on release versions. If it is
112 * not > 0, the user has turned it off, so let's close the logbuffer. */
113 if (shmlog_size > 0 && logbuffer == NULL)
114 open_logbuffer();
115 else if (shmlog_size <= 0 && logbuffer)
116 close_logbuffer();
117 atexit(purge_zerobyte_logfile);
118 }
119
120 /*
121 * Opens the logbuffer.
122 *
123 */
124 void open_logbuffer(void) {
125 /* Reserve 1% of the RAM for the logfile, but at max 25 MiB.
126 * For 512 MiB of RAM this will lead to a 5 MiB log buffer.
127 * At the moment (2011-12-10), no testcase leads to an i3 log
128 * of more than ~ 600 KiB. */
129 logbuffer_size = min(physical_mem_bytes * 0.01, shmlog_size);
130 #if defined(__FreeBSD__)
131 sasprintf(&shmlogname, "/tmp/i3-log-%d", getpid());
132 #else
133 sasprintf(&shmlogname, "/i3-log-%d", getpid());
134 #endif
135 logbuffer_shm = shm_open(shmlogname, O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
136 if (logbuffer_shm == -1) {
137 fprintf(stderr, "Could not shm_open SHM segment for the i3 log: %s\n", strerror(errno));
138 return;
139 }
140
141 #if defined(__OpenBSD__) || defined(__APPLE__)
142 if (ftruncate(logbuffer_shm, logbuffer_size) == -1) {
143 fprintf(stderr, "Could not ftruncate SHM segment for the i3 log: %s\n", strerror(errno));
144 #else
145 int ret;
146 if ((ret = posix_fallocate(logbuffer_shm, 0, logbuffer_size)) != 0) {
147 fprintf(stderr, "Could not ftruncate SHM segment for the i3 log: %s\n", strerror(ret));
148 #endif
149 close(logbuffer_shm);
150 shm_unlink(shmlogname);
151 return;
152 }
153
154 logbuffer = mmap(NULL, logbuffer_size, PROT_READ | PROT_WRITE, MAP_SHARED, logbuffer_shm, 0);
155 if (logbuffer == MAP_FAILED) {
156 close_logbuffer();
157 fprintf(stderr, "Could not mmap SHM segment for the i3 log: %s\n", strerror(errno));
158 return;
159 }
160
161 /* Initialize with 0-bytes, just to be sure… */
162 memset(logbuffer, '\0', logbuffer_size);
163
164 header = (i3_shmlog_header *)logbuffer;
165
166 #if !defined(__OpenBSD__)
167 pthread_condattr_t cond_attr;
168 pthread_condattr_init(&cond_attr);
169 if (pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED) != 0)
170 fprintf(stderr, "pthread_condattr_setpshared() failed, i3-dump-log -f will not work!\n");
171 pthread_cond_init(&(header->condvar), &cond_attr);
172 #endif
173
174 logwalk = logbuffer + sizeof(i3_shmlog_header);
175 loglastwrap = logbuffer + logbuffer_size;
176 store_log_markers();
177 }
178
179 /*
180 * Closes the logbuffer.
181 *
182 */
183 void close_logbuffer(void) {
184 close(logbuffer_shm);
185 shm_unlink(shmlogname);
186 free(shmlogname);
187 logbuffer = NULL;
188 shmlogname = "";
189 }
190
191 /*
192 * Set verbosity of i3. If verbose is set to true, informative messages will
193 * be printed to stdout. If verbose is set to false, only errors will be
194 * printed.
195 *
196 */
197 void set_verbosity(bool _verbose) {
198 verbose = _verbose;
199 }
200
201 /*
202 * Get debug logging.
203 *
204 */
205 bool get_debug_logging(void) {
206 return debug_logging;
207 }
208
209 /*
210 * Set debug logging.
211 *
212 */
213 void set_debug_logging(const bool _debug_logging) {
214 debug_logging = _debug_logging;
215 }
216
217 /*
218 * Logs the given message to stdout (if print is true) while prefixing the
219 * current time to it. Additionally, the message will be saved in the i3 SHM
220 * log if enabled.
221 * This is to be called by *LOG() which includes filename/linenumber/function.
222 *
223 */
224 static void vlog(const bool print, const char *fmt, va_list args) {
225 /* Precisely one page to not consume too much memory but to hold enough
226 * data to be useful. */
227 static char message[4096];
228 static struct tm result;
229 static time_t t;
230 static struct tm *tmp;
231 static size_t len;
232
233 /* Get current time */
234 t = time(NULL);
235 /* Convert time to local time (determined by the locale) */
236 tmp = localtime_r(&t, &result);
237 /* Generate time prefix */
238 len = strftime(message, sizeof(message), "%x %X - ", tmp);
239
240 /*
241 * logbuffer print
242 * ----------------
243 * true true format message, save, print
244 * true false format message, save
245 * false true print message only
246 * false false INVALID, never called
247 */
248 if (!logbuffer) {
249 #ifdef DEBUG_TIMING
250 struct timeval tv;
251 gettimeofday(&tv, NULL);
252 printf("%s%d.%d - ", message, tv.tv_sec, tv.tv_usec);
253 #else
254 printf("%s", message);
255 #endif
256 vprintf(fmt, args);
257 } else {
258 len += vsnprintf(message + len, sizeof(message) - len, fmt, args);
259 if (len >= sizeof(message)) {
260 fprintf(stderr, "BUG: single log message > 4k\n");
261
262 /* vsnprintf returns the number of bytes that *would have been written*,
263 * not the actual amount written. Thus, limit len to sizeof(message) to avoid
264 * memory corruption and outputting garbage later. */
265 len = sizeof(message);
266
267 /* Punch in a newline so the next log message is not dangling at
268 * the end of the truncated message. */
269 message[len - 2] = '\n';
270 }
271
272 /* If there is no space for the current message in the ringbuffer, we
273 * need to wrap and write to the beginning again. */
274 if (len >= (size_t)(logbuffer_size - (logwalk - logbuffer))) {
275 loglastwrap = logwalk;
276 logwalk = logbuffer + sizeof(i3_shmlog_header);
277 store_log_markers();
278 header->wrap_count++;
279 }
280
281 /* Copy the buffer, move the write pointer to the byte after our
282 * current message. */
283 strncpy(logwalk, message, len);
284 logwalk += len;
285
286 store_log_markers();
287
288 #if !defined(__OpenBSD__)
289 /* Wake up all (i3-dump-log) processes waiting for condvar. */
290 pthread_cond_broadcast(&(header->condvar));
291 #endif
292
293 if (print)
294 fwrite(message, len, 1, stdout);
295 }
296 }
297
298 /*
299 * Logs the given message to stdout while prefixing the current time to it,
300 * but only if verbose mode is activated.
301 *
302 */
303 void verboselog(char *fmt, ...) {
304 va_list args;
305
306 if (!logbuffer && !verbose)
307 return;
308
309 va_start(args, fmt);
310 vlog(verbose, fmt, args);
311 va_end(args);
312 }
313
314 /*
315 * Logs the given message to stdout while prefixing the current time to it.
316 *
317 */
318 void errorlog(char *fmt, ...) {
319 va_list args;
320
321 va_start(args, fmt);
322 vlog(true, fmt, args);
323 va_end(args);
324
325 /* also log to the error logfile, if opened */
326 va_start(args, fmt);
327 vfprintf(errorfile, fmt, args);
328 fflush(errorfile);
329 va_end(args);
330 }
331
332 /*
333 * Logs the given message to stdout while prefixing the current time to it,
334 * but only if debug logging was activated.
335 * This is to be called by DLOG() which includes filename/linenumber
336 *
337 */
338 void debuglog(char *fmt, ...) {
339 va_list args;
340
341 if (!logbuffer && !(debug_logging))
342 return;
343
344 va_start(args, fmt);
345 vlog(debug_logging, fmt, args);
346 va_end(args);
347 }
348
349 /*
350 * Deletes the unused log files. Useful if i3 exits immediately, eg.
351 * because --get-socketpath was called. We don't care for syscall
352 * failures. This function is invoked automatically when exiting.
353 */
354 void purge_zerobyte_logfile(void) {
355 struct stat st;
356 char *slash;
357
358 if (!errorfilename)
359 return;
360
361 /* don't delete the log file if it contains something */
362 if ((stat(errorfilename, &st)) == -1 || st.st_size > 0)
363 return;
364
365 if (unlink(errorfilename) == -1)
366 return;
367
368 if ((slash = strrchr(errorfilename, '/')) != NULL) {
369 *slash = '\0';
370 /* possibly fails with ENOTEMPTY if there are files (or
371 * sockets) left. */
372 rmdir(errorfilename);
373 }
374 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * main.c: Initialization, main loop
7 *
8 */
9 #include "all.h"
10
11 #include <ev.h>
12 #include <fcntl.h>
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <sys/un.h>
16 #include <sys/time.h>
17 #include <sys/resource.h>
18 #include <sys/mman.h>
19 #include <sys/stat.h>
20 #include <libgen.h>
21 #include "shmlog.h"
22
23 #ifdef I3_ASAN_ENABLED
24 #include <sanitizer/lsan_interface.h>
25 #endif
26
27 #include "sd-daemon.h"
28
29 /* The original value of RLIMIT_CORE when i3 was started. We need to restore
30 * this before starting any other process, since we set RLIMIT_CORE to
31 * RLIM_INFINITY for i3 debugging versions. */
32 struct rlimit original_rlimit_core;
33
34 /* The number of file descriptors passed via socket activation. */
35 int listen_fds;
36
37 /* We keep the xcb_prepare watcher around to be able to enable and disable it
38 * temporarily for drag_pointer(). */
39 static struct ev_prepare *xcb_prepare;
40
41 char **start_argv;
42
43 xcb_connection_t *conn;
44 /* The screen (0 when you are using DISPLAY=:0) of the connection 'conn' */
45 int conn_screen;
46
47 /* Display handle for libstartup-notification */
48 SnDisplay *sndisplay;
49
50 /* The last timestamp we got from X11 (timestamps are included in some events
51 * and are used for some things, like determining a unique ID in startup
52 * notification). */
53 xcb_timestamp_t last_timestamp = XCB_CURRENT_TIME;
54
55 xcb_screen_t *root_screen;
56 xcb_window_t root;
57
58 /* Color depth, visual id and colormap to use when creating windows and
59 * pixmaps. Will use 32 bit depth and an appropriate visual, if available,
60 * otherwise the root window’s default (usually 24 bit TrueColor). */
61 uint8_t root_depth;
62 xcb_visualtype_t *visual_type;
63 xcb_colormap_t colormap;
64
65 struct ev_loop *main_loop;
66
67 xcb_key_symbols_t *keysyms;
68
69 /* Default shmlog size if not set by user. */
70 const int default_shmlog_size = 25 * 1024 * 1024;
71
72 /* The list of key bindings */
73 struct bindings_head *bindings;
74
75 /* The list of exec-lines */
76 struct autostarts_head autostarts = TAILQ_HEAD_INITIALIZER(autostarts);
77
78 /* The list of exec_always lines */
79 struct autostarts_always_head autostarts_always = TAILQ_HEAD_INITIALIZER(autostarts_always);
80
81 /* The list of assignments */
82 struct assignments_head assignments = TAILQ_HEAD_INITIALIZER(assignments);
83
84 /* The list of workspace assignments (which workspace should end up on which
85 * output) */
86 struct ws_assignments_head ws_assignments = TAILQ_HEAD_INITIALIZER(ws_assignments);
87
88 /* We hope that those are supported and set them to true */
89 bool xkb_supported = true;
90 bool shape_supported = true;
91
92 bool force_xinerama = false;
93
94 /* Define all atoms as global variables */
95 #define xmacro(atom) xcb_atom_t A_##atom;
96 #include "atoms.xmacro"
97 #undef xmacro
98
99 /*
100 * This callback is only a dummy, see xcb_prepare_cb.
101 * See also man libev(3): "ev_prepare" and "ev_check" - customise your event loop
102 *
103 */
104 static void xcb_got_event(EV_P_ struct ev_io *w, int revents) {
105 /* empty, because xcb_prepare_cb are used */
106 }
107
108 /*
109 * Called just before the event loop sleeps. Ensures xcb’s incoming and outgoing
110 * queues are empty so that any activity will trigger another event loop
111 * iteration, and hence another xcb_prepare_cb invocation.
112 *
113 */
114 static void xcb_prepare_cb(EV_P_ ev_prepare *w, int revents) {
115 /* Process all queued (and possibly new) events before the event loop
116 sleeps. */
117 xcb_generic_event_t *event;
118
119 while ((event = xcb_poll_for_event(conn)) != NULL) {
120 if (event->response_type == 0) {
121 if (event_is_ignored(event->sequence, 0))
122 DLOG("Expected X11 Error received for sequence %x\n", event->sequence);
123 else {
124 xcb_generic_error_t *error = (xcb_generic_error_t *)event;
125 DLOG("X11 Error received (probably harmless)! sequence 0x%x, error_code = %d\n",
126 error->sequence, error->error_code);
127 }
128 free(event);
129 continue;
130 }
131
132 /* Strip off the highest bit (set if the event is generated) */
133 int type = (event->response_type & 0x7F);
134
135 handle_event(type, event);
136
137 free(event);
138 }
139
140 /* Flush all queued events to X11. */
141 xcb_flush(conn);
142 }
143
144 /*
145 * Enable or disable the main X11 event handling function.
146 * This is used by drag_pointer() which has its own, modal event handler, which
147 * takes precedence over the normal event handler.
148 *
149 */
150 void main_set_x11_cb(bool enable) {
151 DLOG("Setting main X11 callback to enabled=%d\n", enable);
152 if (enable) {
153 ev_prepare_start(main_loop, xcb_prepare);
154 /* Trigger the watcher explicitly to handle all remaining X11 events.
155 * drag_pointer()’s event handler exits in the middle of the loop. */
156 ev_feed_event(main_loop, xcb_prepare, 0);
157 } else {
158 ev_prepare_stop(main_loop, xcb_prepare);
159 }
160 }
161
162 /*
163 * Exit handler which destroys the main_loop. Will trigger cleanup handlers.
164 *
165 */
166 static void i3_exit(void) {
167 if (*shmlogname != '\0') {
168 fprintf(stderr, "Closing SHM log \"%s\"\n", shmlogname);
169 fflush(stderr);
170 shm_unlink(shmlogname);
171 }
172 ipc_shutdown(SHUTDOWN_REASON_EXIT, -1);
173 unlink(config.ipc_socket_path);
174 xcb_disconnect(conn);
175
176 /* We need ev >= 4 for the following code. Since it is not *that* important (it
177 * only makes sure that there are no i3-nagbar instances left behind) we still
178 * support old systems with libev 3. */
179 #if EV_VERSION_MAJOR >= 4
180 ev_loop_destroy(main_loop);
181 #endif
182
183 #ifdef I3_ASAN_ENABLED
184 __lsan_do_leak_check();
185 #endif
186 }
187
188 /*
189 * (One-shot) Handler for all signals with default action "Core", see signal(7)
190 *
191 * Unlinks the SHM log and re-raises the signal.
192 *
193 */
194 static void handle_core_signal(int sig, siginfo_t *info, void *data) {
195 if (*shmlogname != '\0') {
196 shm_unlink(shmlogname);
197 }
198 raise(sig);
199 }
200
201 /*
202 * (One-shot) Handler for all signals with default action "Term", see signal(7)
203 *
204 * Exits the program gracefully.
205 *
206 */
207 static void handle_term_signal(struct ev_loop *loop, ev_signal *signal, int revents) {
208 /* We exit gracefully here in the sense that cleanup handlers
209 * installed via atexit are invoked. */
210 exit(128 + signal->signum);
211 }
212
213 /*
214 * Set up handlers for all signals with default action "Term", see signal(7)
215 *
216 */
217 static void setup_term_handlers(void) {
218 static struct ev_signal signal_watchers[6];
219 size_t num_watchers = sizeof(signal_watchers) / sizeof(signal_watchers[0]);
220
221 /* We have to rely on libev functionality here and should not use
222 * sigaction handlers because we need to invoke the exit handlers
223 * and cannot do so from an asynchronous signal handling context as
224 * not all code triggered during exit is signal safe (and exiting
225 * the main loop from said handler is not easily possible). libev's
226 * signal handlers does not impose such a constraint on us. */
227 ev_signal_init(&signal_watchers[0], handle_term_signal, SIGHUP);
228 ev_signal_init(&signal_watchers[1], handle_term_signal, SIGINT);
229 ev_signal_init(&signal_watchers[2], handle_term_signal, SIGALRM);
230 ev_signal_init(&signal_watchers[3], handle_term_signal, SIGTERM);
231 ev_signal_init(&signal_watchers[4], handle_term_signal, SIGUSR1);
232 ev_signal_init(&signal_watchers[5], handle_term_signal, SIGUSR1);
233 for (size_t i = 0; i < num_watchers; i++) {
234 ev_signal_start(main_loop, &signal_watchers[i]);
235 /* The signal handlers should not block ev_run from returning
236 * and so none of the signal handlers should hold a reference to
237 * the main loop. */
238 ev_unref(main_loop);
239 }
240 }
241
242 static int parse_restart_fd(void) {
243 const char *restart_fd = getenv("_I3_RESTART_FD");
244 if (restart_fd == NULL) {
245 return -1;
246 }
247
248 long int fd = -1;
249 if (!parse_long(restart_fd, &fd, 10)) {
250 ELOG("Malformed _I3_RESTART_FD \"%s\"\n", restart_fd);
251 return -1;
252 }
253 return fd;
254 }
255
256 int main(int argc, char *argv[]) {
257 /* Keep a symbol pointing to the I3_VERSION string constant so that we have
258 * it in gdb backtraces. */
259 static const char *_i3_version __attribute__((used)) = I3_VERSION;
260 char *override_configpath = NULL;
261 bool autostart = true;
262 char *layout_path = NULL;
263 bool delete_layout_path = false;
264 bool disable_randr15 = false;
265 char *fake_outputs = NULL;
266 bool disable_signalhandler = false;
267 bool only_check_config = false;
268 static struct option long_options[] = {
269 {"no-autostart", no_argument, 0, 'a'},
270 {"config", required_argument, 0, 'c'},
271 {"version", no_argument, 0, 'v'},
272 {"moreversion", no_argument, 0, 'm'},
273 {"more-version", no_argument, 0, 'm'},
274 {"more_version", no_argument, 0, 'm'},
275 {"help", no_argument, 0, 'h'},
276 {"layout", required_argument, 0, 'L'},
277 {"restart", required_argument, 0, 0},
278 {"force-xinerama", no_argument, 0, 0},
279 {"force_xinerama", no_argument, 0, 0},
280 {"disable-randr15", no_argument, 0, 0},
281 {"disable_randr15", no_argument, 0, 0},
282 {"disable-signalhandler", no_argument, 0, 0},
283 {"shmlog-size", required_argument, 0, 0},
284 {"shmlog_size", required_argument, 0, 0},
285 {"get-socketpath", no_argument, 0, 0},
286 {"get_socketpath", no_argument, 0, 0},
287 {"fake_outputs", required_argument, 0, 0},
288 {"fake-outputs", required_argument, 0, 0},
289 {"force-old-config-parser-v4.4-only", no_argument, 0, 0},
290 {0, 0, 0, 0}};
291 int option_index = 0, opt;
292
293 setlocale(LC_ALL, "");
294
295 /* Get the RLIMIT_CORE limit at startup time to restore this before
296 * starting processes. */
297 getrlimit(RLIMIT_CORE, &original_rlimit_core);
298
299 /* Disable output buffering to make redirects in .xsession actually useful for debugging */
300 if (!isatty(fileno(stdout)))
301 setbuf(stdout, NULL);
302
303 srand(time(NULL));
304
305 /* Init logging *before* initializing debug_build to guarantee early
306 * (file) logging. */
307 init_logging();
308
309 /* On release builds, disable SHM logging by default. */
310 shmlog_size = (is_debug_build() || strstr(argv[0], "i3-with-shmlog") != NULL ? default_shmlog_size : 0);
311
312 start_argv = argv;
313
314 while ((opt = getopt_long(argc, argv, "c:CvmaL:hld:V", long_options, &option_index)) != -1) {
315 switch (opt) {
316 case 'a':
317 LOG("Autostart disabled using -a\n");
318 autostart = false;
319 break;
320 case 'L':
321 FREE(layout_path);
322 layout_path = sstrdup(optarg);
323 delete_layout_path = false;
324 break;
325 case 'c':
326 FREE(override_configpath);
327 override_configpath = sstrdup(optarg);
328 break;
329 case 'C':
330 LOG("Checking configuration file only (-C)\n");
331 only_check_config = true;
332 break;
333 case 'v':
334 printf("i3 version %s © 2009 Michael Stapelberg and contributors\n", i3_version);
335 exit(EXIT_SUCCESS);
336 break;
337 case 'm':
338 printf("Binary i3 version: %s © 2009 Michael Stapelberg and contributors\n", i3_version);
339 display_running_version();
340 exit(EXIT_SUCCESS);
341 break;
342 case 'V':
343 set_verbosity(true);
344 break;
345 case 'd':
346 LOG("Enabling debug logging\n");
347 set_debug_logging(true);
348 break;
349 case 'l':
350 /* DEPRECATED, ignored for the next 3 versions (3.e, 3.f, 3.g) */
351 break;
352 case 0:
353 if (strcmp(long_options[option_index].name, "force-xinerama") == 0 ||
354 strcmp(long_options[option_index].name, "force_xinerama") == 0) {
355 force_xinerama = true;
356 ELOG("Using Xinerama instead of RandR. This option should be "
357 "avoided at all cost because it does not refresh the list "
358 "of screens, so you cannot configure displays at runtime. "
359 "Please check if your driver really does not support RandR "
360 "and disable this option as soon as you can.\n");
361 break;
362 } else if (strcmp(long_options[option_index].name, "disable-randr15") == 0 ||
363 strcmp(long_options[option_index].name, "disable_randr15") == 0) {
364 disable_randr15 = true;
365 break;
366 } else if (strcmp(long_options[option_index].name, "disable-signalhandler") == 0) {
367 disable_signalhandler = true;
368 break;
369 } else if (strcmp(long_options[option_index].name, "get-socketpath") == 0 ||
370 strcmp(long_options[option_index].name, "get_socketpath") == 0) {
371 char *socket_path = root_atom_contents("I3_SOCKET_PATH", NULL, 0);
372 if (socket_path) {
373 printf("%s\n", socket_path);
374 exit(EXIT_SUCCESS);
375 }
376
377 exit(EXIT_FAILURE);
378 } else if (strcmp(long_options[option_index].name, "shmlog-size") == 0 ||
379 strcmp(long_options[option_index].name, "shmlog_size") == 0) {
380 shmlog_size = atoi(optarg);
381 /* Re-initialize logging immediately to get as many
382 * logmessages as possible into the SHM log. */
383 init_logging();
384 LOG("Limiting SHM log size to %d bytes\n", shmlog_size);
385 break;
386 } else if (strcmp(long_options[option_index].name, "restart") == 0) {
387 FREE(layout_path);
388 layout_path = sstrdup(optarg);
389 delete_layout_path = true;
390 break;
391 } else if (strcmp(long_options[option_index].name, "fake-outputs") == 0 ||
392 strcmp(long_options[option_index].name, "fake_outputs") == 0) {
393 LOG("Initializing fake outputs: %s\n", optarg);
394 fake_outputs = sstrdup(optarg);
395 break;
396 } else if (strcmp(long_options[option_index].name, "force-old-config-parser-v4.4-only") == 0) {
397 ELOG("You are passing --force-old-config-parser-v4.4-only, but that flag was removed by now.\n");
398 break;
399 }
400 /* fall-through */
401 default:
402 fprintf(stderr, "Usage: %s [-c configfile] [-d all] [-a] [-v] [-V] [-C]\n", argv[0]);
403 fprintf(stderr, "\n");
404 fprintf(stderr, "\t-a disable autostart ('exec' lines in config)\n");
405 fprintf(stderr, "\t-c <file> use the provided configfile instead\n");
406 fprintf(stderr, "\t-C validate configuration file and exit\n");
407 fprintf(stderr, "\t-d all enable debug output\n");
408 fprintf(stderr, "\t-L <file> path to the serialized layout during restarts\n");
409 fprintf(stderr, "\t-v display version and exit\n");
410 fprintf(stderr, "\t-V enable verbose mode\n");
411 fprintf(stderr, "\n");
412 fprintf(stderr, "\t--force-xinerama\n"
413 "\tUse Xinerama instead of RandR.\n"
414 "\tThis option should only be used if you are stuck with the\n"
415 "\told nVidia closed source driver (older than 302.17), which does\n"
416 "\tnot support RandR.\n");
417 fprintf(stderr, "\n");
418 fprintf(stderr, "\t--get-socketpath\n"
419 "\tRetrieve the i3 IPC socket path from X11, print it, then exit.\n");
420 fprintf(stderr, "\n");
421 fprintf(stderr, "\t--shmlog-size <limit>\n"
422 "\tLimits the size of the i3 SHM log to <limit> bytes. Setting this\n"
423 "\tto 0 disables SHM logging entirely.\n"
424 "\tThe default is %d bytes.\n",
425 shmlog_size);
426 fprintf(stderr, "\n");
427 fprintf(stderr, "If you pass plain text arguments, i3 will interpret them as a command\n"
428 "to send to a currently running i3 (like i3-msg). This allows you to\n"
429 "use nice and logical commands, such as:\n"
430 "\n"
431 "\ti3 border none\n"
432 "\ti3 floating toggle\n"
433 "\ti3 kill window\n"
434 "\n");
435 exit(opt == 'h' ? EXIT_SUCCESS : EXIT_FAILURE);
436 }
437 }
438
439 if (only_check_config) {
440 exit(load_configuration(override_configpath, C_VALIDATE) ? EXIT_SUCCESS : EXIT_FAILURE);
441 }
442
443 /* If the user passes more arguments, we act like i3-msg would: Just send
444 * the arguments as an IPC message to i3. This allows for nice semantic
445 * commands such as 'i3 border none'. */
446 if (optind < argc) {
447 /* We enable verbose mode so that the user knows what’s going on.
448 * This should make it easier to find mistakes when the user passes
449 * arguments by mistake. */
450 set_verbosity(true);
451
452 LOG("Additional arguments passed. Sending them as a command to i3.\n");
453 char *payload = NULL;
454 while (optind < argc) {
455 if (!payload) {
456 payload = sstrdup(argv[optind]);
457 } else {
458 char *both;
459 sasprintf(&both, "%s %s", payload, argv[optind]);
460 free(payload);
461 payload = both;
462 }
463 optind++;
464 }
465 DLOG("Command is: %s (%zd bytes)\n", payload, strlen(payload));
466 char *socket_path = root_atom_contents("I3_SOCKET_PATH", NULL, 0);
467 if (!socket_path) {
468 ELOG("Could not get i3 IPC socket path\n");
469 return 1;
470 }
471
472 int sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
473 if (sockfd == -1)
474 err(EXIT_FAILURE, "Could not create socket");
475
476 struct sockaddr_un addr;
477 memset(&addr, 0, sizeof(struct sockaddr_un));
478 addr.sun_family = AF_LOCAL;
479 strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
480 FREE(socket_path);
481 if (connect(sockfd, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
482 err(EXIT_FAILURE, "Could not connect to i3");
483
484 if (ipc_send_message(sockfd, strlen(payload), I3_IPC_MESSAGE_TYPE_RUN_COMMAND,
485 (uint8_t *)payload) == -1)
486 err(EXIT_FAILURE, "IPC: write()");
487 FREE(payload);
488
489 uint32_t reply_length;
490 uint32_t reply_type;
491 uint8_t *reply;
492 int ret;
493 if ((ret = ipc_recv_message(sockfd, &reply_type, &reply_length, &reply)) != 0) {
494 if (ret == -1)
495 err(EXIT_FAILURE, "IPC: read()");
496 return 1;
497 }
498 if (reply_type != I3_IPC_REPLY_TYPE_COMMAND)
499 errx(EXIT_FAILURE, "IPC: received reply of type %d but expected %d (COMMAND)", reply_type, I3_IPC_REPLY_TYPE_COMMAND);
500 printf("%.*s\n", reply_length, reply);
501 FREE(reply);
502 return 0;
503 }
504
505 /* Enable logging to handle the case when the user did not specify --shmlog-size */
506 init_logging();
507
508 /* Try to enable core dumps by default when running a debug build */
509 if (is_debug_build()) {
510 struct rlimit limit = {RLIM_INFINITY, RLIM_INFINITY};
511 setrlimit(RLIMIT_CORE, &limit);
512
513 /* The following code is helpful, but not required. We thus don’t pay
514 * much attention to error handling, non-linux or other edge cases. */
515 LOG("CORE DUMPS: You are running a development version of i3, so coredumps were automatically enabled (ulimit -c unlimited).\n");
516 size_t cwd_size = 1024;
517 char *cwd = smalloc(cwd_size);
518 char *cwd_ret;
519 while ((cwd_ret = getcwd(cwd, cwd_size)) == NULL && errno == ERANGE) {
520 cwd_size = cwd_size * 2;
521 cwd = srealloc(cwd, cwd_size);
522 }
523 if (cwd_ret != NULL)
524 LOG("CORE DUMPS: Your current working directory is \"%s\".\n", cwd);
525 int patternfd;
526 if ((patternfd = open("/proc/sys/kernel/core_pattern", O_RDONLY)) >= 0) {
527 memset(cwd, '\0', cwd_size);
528 if (read(patternfd, cwd, cwd_size) > 0)
529 /* a trailing newline is included in cwd */
530 LOG("CORE DUMPS: Your core_pattern is: %s", cwd);
531 close(patternfd);
532 }
533 free(cwd);
534 }
535
536 LOG("i3 %s starting\n", i3_version);
537
538 conn = xcb_connect(NULL, &conn_screen);
539 if (xcb_connection_has_error(conn))
540 errx(EXIT_FAILURE, "Cannot open display");
541
542 sndisplay = sn_xcb_display_new(conn, NULL, NULL);
543
544 /* Initialize the libev event loop. This needs to be done before loading
545 * the config file because the parser will install an ev_child watcher
546 * for the nagbar when config errors are found. */
547 main_loop = EV_DEFAULT;
548 if (main_loop == NULL)
549 die("Could not initialize libev. Bad LIBEV_FLAGS?\n");
550
551 root_screen = xcb_aux_get_screen(conn, conn_screen);
552 root = root_screen->root;
553
554 /* Place requests for the atoms we need as soon as possible */
555 #define xmacro(atom) \
556 xcb_intern_atom_cookie_t atom##_cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom);
557 #include "atoms.xmacro"
558 #undef xmacro
559
560 root_depth = root_screen->root_depth;
561 colormap = root_screen->default_colormap;
562 visual_type = xcb_aux_find_visual_by_attrs(root_screen, -1, 32);
563 if (visual_type != NULL) {
564 root_depth = xcb_aux_get_depth_of_visual(root_screen, visual_type->visual_id);
565 colormap = xcb_generate_id(conn);
566
567 xcb_void_cookie_t cm_cookie = xcb_create_colormap_checked(conn,
568 XCB_COLORMAP_ALLOC_NONE,
569 colormap,
570 root,
571 visual_type->visual_id);
572
573 xcb_generic_error_t *error = xcb_request_check(conn, cm_cookie);
574 if (error != NULL) {
575 ELOG("Could not create colormap. Error code: %d\n", error->error_code);
576 exit(EXIT_FAILURE);
577 }
578 } else {
579 visual_type = get_visualtype(root_screen);
580 }
581
582 init_dpi();
583
584 DLOG("root_depth = %d, visual_id = 0x%08x.\n", root_depth, visual_type->visual_id);
585 DLOG("root_screen->height_in_pixels = %d, root_screen->height_in_millimeters = %d\n",
586 root_screen->height_in_pixels, root_screen->height_in_millimeters);
587 DLOG("One logical pixel corresponds to %d physical pixels on this display.\n", logical_px(1));
588
589 xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(conn, root);
590 xcb_query_pointer_cookie_t pointercookie = xcb_query_pointer(conn, root);
591
592 /* Setup NetWM atoms */
593 #define xmacro(name) \
594 do { \
595 xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, name##_cookie, NULL); \
596 if (!reply) { \
597 ELOG("Could not get atom " #name "\n"); \
598 exit(-1); \
599 } \
600 A_##name = reply->atom; \
601 free(reply); \
602 } while (0);
603 #include "atoms.xmacro"
604 #undef xmacro
605
606 load_configuration(override_configpath, C_LOAD);
607
608 if (config.ipc_socket_path == NULL) {
609 /* Fall back to a file name in /tmp/ based on the PID */
610 if ((config.ipc_socket_path = getenv("I3SOCK")) == NULL)
611 config.ipc_socket_path = get_process_filename("ipc-socket");
612 else
613 config.ipc_socket_path = sstrdup(config.ipc_socket_path);
614 }
615
616 if (config.force_xinerama) {
617 force_xinerama = true;
618 }
619
620 xcb_void_cookie_t cookie;
621 cookie = xcb_change_window_attributes_checked(conn, root, XCB_CW_EVENT_MASK, (uint32_t[]){ROOT_EVENT_MASK});
622 xcb_generic_error_t *error = xcb_request_check(conn, cookie);
623 if (error != NULL) {
624 ELOG("Another window manager seems to be running (X error %d)\n", error->error_code);
625 #ifdef I3_ASAN_ENABLED
626 __lsan_do_leak_check();
627 #endif
628 return 1;
629 }
630
631 xcb_get_geometry_reply_t *greply = xcb_get_geometry_reply(conn, gcookie, NULL);
632 if (greply == NULL) {
633 ELOG("Could not get geometry of the root window, exiting\n");
634 return 1;
635 }
636 DLOG("root geometry reply: (%d, %d) %d x %d\n", greply->x, greply->y, greply->width, greply->height);
637
638 xcursor_load_cursors();
639
640 /* Set a cursor for the root window (otherwise the root window will show no
641 cursor until the first client is launched). */
642 xcursor_set_root_cursor(XCURSOR_CURSOR_POINTER);
643
644 const xcb_query_extension_reply_t *extreply;
645 xcb_prefetch_extension_data(conn, &xcb_xkb_id);
646 xcb_prefetch_extension_data(conn, &xcb_shape_id);
647
648 extreply = xcb_get_extension_data(conn, &xcb_xkb_id);
649 xkb_supported = extreply->present;
650 if (!extreply->present) {
651 DLOG("xkb is not present on this server\n");
652 } else {
653 DLOG("initializing xcb-xkb\n");
654 xcb_xkb_use_extension(conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION);
655 xcb_xkb_select_events(conn,
656 XCB_XKB_ID_USE_CORE_KBD,
657 XCB_XKB_EVENT_TYPE_STATE_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY | XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY,
658 0,
659 XCB_XKB_EVENT_TYPE_STATE_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY | XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY,
660 0xff,
661 0xff,
662 NULL);
663
664 /* Setting both, XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE and
665 * XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED, will lead to the
666 * X server sending us the full XKB state in KeyPress and KeyRelease:
667 * https://cgit.freedesktop.org/xorg/xserver/tree/xkb/xkbEvents.c?h=xorg-server-1.20.0#n927
668 *
669 * XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT enable detectable autorepeat:
670 * https://www.x.org/releases/current/doc/kbproto/xkbproto.html#Detectable_Autorepeat
671 * This affects bindings using the --release flag: instead of getting multiple KeyRelease
672 * events we get only one event when the key is physically released by the user.
673 */
674 const uint32_t mask = XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE |
675 XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED |
676 XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT;
677 xcb_xkb_per_client_flags_reply_t *pcf_reply;
678 /* The last three parameters are unset because they are only relevant
679 * when using a feature called “automatic reset of boolean controls”:
680 * https://www.x.org/releases/X11R7.7/doc/kbproto/xkbproto.html#Automatic_Reset_of_Boolean_Controls
681 * */
682 pcf_reply = xcb_xkb_per_client_flags_reply(
683 conn,
684 xcb_xkb_per_client_flags(
685 conn,
686 XCB_XKB_ID_USE_CORE_KBD,
687 mask,
688 mask,
689 0 /* uint32_t ctrlsToChange */,
690 0 /* uint32_t autoCtrls */,
691 0 /* uint32_t autoCtrlsValues */),
692 NULL);
693
694 #define PCF_REPLY_ERROR(_value) \
695 do { \
696 if (pcf_reply == NULL || !(pcf_reply->value & (_value))) { \
697 ELOG("Could not set " #_value "\n"); \
698 } \
699 } while (0)
700
701 PCF_REPLY_ERROR(XCB_XKB_PER_CLIENT_FLAG_GRABS_USE_XKB_STATE);
702 PCF_REPLY_ERROR(XCB_XKB_PER_CLIENT_FLAG_LOOKUP_STATE_WHEN_GRABBED);
703 PCF_REPLY_ERROR(XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT);
704
705 free(pcf_reply);
706 xkb_base = extreply->first_event;
707 }
708
709 /* Check for Shape extension. We want to handle input shapes which is
710 * introduced in 1.1. */
711 extreply = xcb_get_extension_data(conn, &xcb_shape_id);
712 if (extreply->present) {
713 shape_base = extreply->first_event;
714 xcb_shape_query_version_cookie_t cookie = xcb_shape_query_version(conn);
715 xcb_shape_query_version_reply_t *version =
716 xcb_shape_query_version_reply(conn, cookie, NULL);
717 shape_supported = version && version->minor_version >= 1;
718 free(version);
719 } else {
720 shape_supported = false;
721 }
722 if (!shape_supported) {
723 DLOG("shape 1.1 is not present on this server\n");
724 }
725
726 restore_connect();
727
728 property_handlers_init();
729
730 ewmh_setup_hints();
731
732 keysyms = xcb_key_symbols_alloc(conn);
733
734 xcb_numlock_mask = aio_get_mod_mask_for(XCB_NUM_LOCK, keysyms);
735
736 if (!load_keymap())
737 die("Could not load keymap\n");
738
739 translate_keysyms();
740 grab_all_keys(conn);
741
742 bool needs_tree_init = true;
743 if (layout_path != NULL) {
744 LOG("Trying to restore the layout from \"%s\".\n", layout_path);
745 needs_tree_init = !tree_restore(layout_path, greply);
746 if (delete_layout_path) {
747 unlink(layout_path);
748 const char *dir = dirname(layout_path);
749 /* possibly fails with ENOTEMPTY if there are files (or
750 * sockets) left. */
751 rmdir(dir);
752 }
753 }
754 if (needs_tree_init)
755 tree_init(greply);
756
757 free(greply);
758
759 /* Setup fake outputs for testing */
760 if (fake_outputs == NULL && config.fake_outputs != NULL)
761 fake_outputs = config.fake_outputs;
762
763 if (fake_outputs != NULL) {
764 fake_outputs_init(fake_outputs);
765 FREE(fake_outputs);
766 config.fake_outputs = NULL;
767 } else if (force_xinerama) {
768 /* Force Xinerama (for drivers which don't support RandR yet, esp. the
769 * nVidia binary graphics driver), when specified either in the config
770 * file or on command-line */
771 xinerama_init();
772 } else {
773 DLOG("Checking for XRandR...\n");
774 randr_init(&randr_base, disable_randr15 || config.disable_randr15);
775 }
776
777 /* We need to force disabling outputs which have been loaded from the
778 * layout file but are no longer active. This can happen if the output has
779 * been disabled in the short time between writing the restart layout file
780 * and restarting i3. See #2326. */
781 if (layout_path != NULL && randr_base > -1) {
782 Con *con;
783 TAILQ_FOREACH (con, &(croot->nodes_head), nodes) {
784 Output *output;
785 TAILQ_FOREACH (output, &outputs, outputs) {
786 if (output->active || strcmp(con->name, output_primary_name(output)) != 0)
787 continue;
788
789 /* This will correctly correlate the output with its content
790 * container. We need to make the connection to properly
791 * disable the output. */
792 if (output->con == NULL) {
793 output_init_con(output);
794 output->changed = false;
795 }
796
797 output->to_be_disabled = true;
798 randr_disable_output(output);
799 }
800 }
801 }
802 FREE(layout_path);
803
804 scratchpad_fix_resolution();
805
806 xcb_query_pointer_reply_t *pointerreply;
807 Output *output = NULL;
808 if (!(pointerreply = xcb_query_pointer_reply(conn, pointercookie, NULL))) {
809 ELOG("Could not query pointer position, using first screen\n");
810 } else {
811 DLOG("Pointer at %d, %d\n", pointerreply->root_x, pointerreply->root_y);
812 output = get_output_containing(pointerreply->root_x, pointerreply->root_y);
813 if (!output) {
814 ELOG("ERROR: No screen at (%d, %d), starting on the first screen\n",
815 pointerreply->root_x, pointerreply->root_y);
816 }
817 }
818 if (!output) {
819 output = get_first_output();
820 }
821 con_activate(con_descend_focused(output_get_content(output->con)));
822 free(pointerreply);
823
824 tree_render();
825
826 /* Create the UNIX domain socket for IPC */
827 int ipc_socket = ipc_create_socket(config.ipc_socket_path);
828 if (ipc_socket == -1) {
829 ELOG("Could not create the IPC socket, IPC disabled\n");
830 } else {
831 struct ev_io *ipc_io = scalloc(1, sizeof(struct ev_io));
832 ev_io_init(ipc_io, ipc_new_client, ipc_socket, EV_READ);
833 ev_io_start(main_loop, ipc_io);
834 }
835
836 /* Also handle the UNIX domain sockets passed via socket activation. The
837 * parameter 1 means "remove the environment variables", we don’t want to
838 * pass these to child processes. */
839 listen_fds = sd_listen_fds(0);
840 if (listen_fds < 0)
841 ELOG("socket activation: Error in sd_listen_fds\n");
842 else if (listen_fds == 0)
843 DLOG("socket activation: no sockets passed\n");
844 else {
845 int flags;
846 for (int fd = SD_LISTEN_FDS_START;
847 fd < (SD_LISTEN_FDS_START + listen_fds);
848 fd++) {
849 DLOG("socket activation: also listening on fd %d\n", fd);
850
851 /* sd_listen_fds() enables FD_CLOEXEC by default.
852 * However, we need to keep the file descriptors open for in-place
853 * restarting, therefore we explicitly disable FD_CLOEXEC. */
854 if ((flags = fcntl(fd, F_GETFD)) < 0 ||
855 fcntl(fd, F_SETFD, flags & ~FD_CLOEXEC) < 0) {
856 ELOG("Could not disable FD_CLOEXEC on fd %d\n", fd);
857 }
858
859 struct ev_io *ipc_io = scalloc(1, sizeof(struct ev_io));
860 ev_io_init(ipc_io, ipc_new_client, fd, EV_READ);
861 ev_io_start(main_loop, ipc_io);
862 }
863 }
864
865 {
866 const int restart_fd = parse_restart_fd();
867 if (restart_fd != -1) {
868 DLOG("serving restart fd %d", restart_fd);
869 ipc_client *client = ipc_new_client_on_fd(main_loop, restart_fd);
870 ipc_confirm_restart(client);
871 unsetenv("_I3_RESTART_FD");
872 }
873 }
874
875 /* Set up i3 specific atoms like I3_SOCKET_PATH and I3_CONFIG_PATH */
876 x_set_i3_atoms();
877 ewmh_update_workarea();
878
879 /* Set the ewmh desktop properties. */
880 ewmh_update_desktop_properties();
881
882 struct ev_io *xcb_watcher = scalloc(1, sizeof(struct ev_io));
883 xcb_prepare = scalloc(1, sizeof(struct ev_prepare));
884
885 ev_io_init(xcb_watcher, xcb_got_event, xcb_get_file_descriptor(conn), EV_READ);
886 ev_io_start(main_loop, xcb_watcher);
887
888 ev_prepare_init(xcb_prepare, xcb_prepare_cb);
889 ev_prepare_start(main_loop, xcb_prepare);
890
891 xcb_flush(conn);
892
893 /* What follows is a fugly consequence of X11 protocol race conditions like
894 * the following: In an i3 in-place restart, i3 will reparent all windows
895 * to the root window, then exec() itself. In the new process, it calls
896 * manage_existing_windows. However, in case any application sent a
897 * generated UnmapNotify message to the WM (as GIMP does), this message
898 * will be handled by i3 *after* managing the window, thus i3 thinks the
899 * window just closed itself. In reality, the message was sent in the time
900 * period where i3 wasn’t running yet.
901 *
902 * To prevent this, we grab the server (disables processing of any other
903 * connections), then discard all pending events (since we didn’t do
904 * anything, there cannot be any meaningful responses), then ungrab the
905 * server. */
906 xcb_grab_server(conn);
907 {
908 xcb_aux_sync(conn);
909 xcb_generic_event_t *event;
910 while ((event = xcb_poll_for_event(conn)) != NULL) {
911 if (event->response_type == 0) {
912 free(event);
913 continue;
914 }
915
916 /* Strip off the highest bit (set if the event is generated) */
917 int type = (event->response_type & 0x7F);
918
919 /* We still need to handle MapRequests which are sent in the
920 * timespan starting from when we register as a window manager and
921 * this piece of code which drops events. */
922 if (type == XCB_MAP_REQUEST)
923 handle_event(type, event);
924
925 free(event);
926 }
927 manage_existing_windows(root);
928 }
929 xcb_ungrab_server(conn);
930
931 if (autostart) {
932 LOG("This is not an in-place restart, copying root window contents to a pixmap\n");
933 xcb_screen_t *root = xcb_aux_get_screen(conn, conn_screen);
934 uint16_t width = root->width_in_pixels;
935 uint16_t height = root->height_in_pixels;
936 xcb_pixmap_t pixmap = xcb_generate_id(conn);
937 xcb_gcontext_t gc = xcb_generate_id(conn);
938
939 xcb_create_pixmap(conn, root->root_depth, pixmap, root->root, width, height);
940
941 xcb_create_gc(conn, gc, root->root,
942 XCB_GC_FUNCTION | XCB_GC_PLANE_MASK | XCB_GC_FILL_STYLE | XCB_GC_SUBWINDOW_MODE,
943 (uint32_t[]){XCB_GX_COPY, ~0, XCB_FILL_STYLE_SOLID, XCB_SUBWINDOW_MODE_INCLUDE_INFERIORS});
944
945 xcb_copy_area(conn, root->root, pixmap, gc, 0, 0, 0, 0, width, height);
946 xcb_change_window_attributes(conn, root->root, XCB_CW_BACK_PIXMAP, (uint32_t[]){pixmap});
947 xcb_flush(conn);
948 xcb_free_gc(conn, gc);
949 xcb_free_pixmap(conn, pixmap);
950 }
951
952 #if defined(__OpenBSD__)
953 if (pledge("stdio rpath wpath cpath proc exec unix", NULL) == -1)
954 err(EXIT_FAILURE, "pledge");
955 #endif
956
957 if (!disable_signalhandler)
958 setup_signal_handler();
959 else {
960 struct sigaction action;
961
962 action.sa_sigaction = handle_core_signal;
963 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
964 sigemptyset(&action.sa_mask);
965
966 /* Catch all signals with default action "Core", see signal(7) */
967 if (sigaction(SIGQUIT, &action, NULL) == -1 ||
968 sigaction(SIGILL, &action, NULL) == -1 ||
969 sigaction(SIGABRT, &action, NULL) == -1 ||
970 sigaction(SIGFPE, &action, NULL) == -1 ||
971 sigaction(SIGSEGV, &action, NULL) == -1)
972 ELOG("Could not setup signal handler.\n");
973 }
974
975 setup_term_handlers();
976 /* Ignore SIGPIPE to survive errors when an IPC client disconnects
977 * while we are sending them a message */
978 signal(SIGPIPE, SIG_IGN);
979
980 /* Autostarting exec-lines */
981 if (autostart) {
982 while (!TAILQ_EMPTY(&autostarts)) {
983 struct Autostart *exec = TAILQ_FIRST(&autostarts);
984
985 LOG("auto-starting %s\n", exec->command);
986 start_application(exec->command, exec->no_startup_id);
987
988 FREE(exec->command);
989 TAILQ_REMOVE(&autostarts, exec, autostarts);
990 FREE(exec);
991 }
992 }
993
994 /* Autostarting exec_always-lines */
995 while (!TAILQ_EMPTY(&autostarts_always)) {
996 struct Autostart *exec_always = TAILQ_FIRST(&autostarts_always);
997
998 LOG("auto-starting (always!) %s\n", exec_always->command);
999 start_application(exec_always->command, exec_always->no_startup_id);
1000
1001 FREE(exec_always->command);
1002 TAILQ_REMOVE(&autostarts_always, exec_always, autostarts_always);
1003 FREE(exec_always);
1004 }
1005
1006 /* Start i3bar processes for all configured bars */
1007 Barconfig *barconfig;
1008 TAILQ_FOREACH (barconfig, &barconfigs, configs) {
1009 char *command = NULL;
1010 sasprintf(&command, "%s %s --bar_id=%s --socket=\"%s\"",
1011 barconfig->i3bar_command ? barconfig->i3bar_command : "exec i3bar",
1012 barconfig->verbose ? "-V" : "",
1013 barconfig->id, current_socketpath);
1014 LOG("Starting bar process: %s\n", command);
1015 start_application(command, true);
1016 free(command);
1017 }
1018
1019 /* Make sure to destroy the event loop to invoke the cleanup callbacks
1020 * when calling exit() */
1021 atexit(i3_exit);
1022
1023 ev_loop(main_loop, 0);
1024 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * manage.c: Initially managing new windows (or existing ones on restart).
7 *
8 */
9 #include "all.h"
10
11 #include "yajl_utils.h"
12
13 #include <yajl/yajl_gen.h>
14
15 /*
16 * Match frame and window depth. This is needed because X will refuse to reparent a
17 * window whose background is ParentRelative under a window with a different depth.
18 *
19 */
20 static xcb_window_t _match_depth(i3Window *win, Con *con) {
21 xcb_window_t old_frame = XCB_NONE;
22 if (con->depth != win->depth) {
23 old_frame = con->frame.id;
24 con->depth = win->depth;
25 x_con_reframe(con);
26 }
27 return old_frame;
28 }
29
30 /*
31 * Remove all match criteria, the first swallowed window wins.
32 *
33 */
34 static void _remove_matches(Con *con) {
35 while (!TAILQ_EMPTY(&(con->swallow_head))) {
36 Match *first = TAILQ_FIRST(&(con->swallow_head));
37 TAILQ_REMOVE(&(con->swallow_head), first, matches);
38 match_free(first);
39 free(first);
40 }
41 }
42
43 /*
44 * Go through all existing windows (if the window manager is restarted) and manage them
45 *
46 */
47 void manage_existing_windows(xcb_window_t root) {
48 xcb_query_tree_reply_t *reply;
49 int i, len;
50 xcb_window_t *children;
51 xcb_get_window_attributes_cookie_t *cookies;
52
53 /* Get the tree of windows whose parent is the root window (= all) */
54 if ((reply = xcb_query_tree_reply(conn, xcb_query_tree(conn, root), 0)) == NULL)
55 return;
56
57 len = xcb_query_tree_children_length(reply);
58 cookies = smalloc(len * sizeof(*cookies));
59
60 /* Request the window attributes for every window */
61 children = xcb_query_tree_children(reply);
62 for (i = 0; i < len; ++i)
63 cookies[i] = xcb_get_window_attributes(conn, children[i]);
64
65 /* Call manage_window with the attributes for every window */
66 for (i = 0; i < len; ++i)
67 manage_window(children[i], cookies[i], true);
68
69 free(reply);
70 free(cookies);
71 }
72
73 /*
74 * Restores the geometry of each window by reparenting it to the root window
75 * at the position of its frame.
76 *
77 * This is to be called *only* before exiting/restarting i3 because of evil
78 * side-effects which are to be expected when continuing to run i3.
79 *
80 */
81 void restore_geometry(void) {
82 DLOG("Restoring geometry\n");
83
84 Con *con;
85 TAILQ_FOREACH (con, &all_cons, all_cons) {
86 if (con->window) {
87 DLOG("Re-adding X11 border of %d px\n", con->border_width);
88 con->window_rect.width += (2 * con->border_width);
89 con->window_rect.height += (2 * con->border_width);
90 xcb_set_window_rect(conn, con->window->id, con->window_rect);
91 DLOG("placing window %08x at %d %d\n", con->window->id, con->rect.x, con->rect.y);
92 xcb_reparent_window(conn, con->window->id, root,
93 con->rect.x, con->rect.y);
94 }
95 }
96
97 /* Strictly speaking, this line doesn’t really belong here, but since we
98 * are syncing, let’s un-register as a window manager first */
99 xcb_change_window_attributes(conn, root, XCB_CW_EVENT_MASK, (uint32_t[]){XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT});
100
101 /* Make sure our changes reach the X server, we restart/exit now */
102 xcb_aux_sync(conn);
103 }
104
105 /*
106 * Do some sanity checks and then reparent the window.
107 *
108 */
109 void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cookie,
110 bool needs_to_be_mapped) {
111 DLOG("window 0x%08x\n", window);
112
113 xcb_drawable_t d = {window};
114 xcb_get_geometry_cookie_t geomc;
115 xcb_get_geometry_reply_t *geom;
116 xcb_get_window_attributes_reply_t *attr = NULL;
117
118 xcb_get_property_cookie_t wm_type_cookie, strut_cookie, state_cookie,
119 utf8_title_cookie, title_cookie,
120 class_cookie, leader_cookie, transient_cookie,
121 role_cookie, startup_id_cookie, wm_hints_cookie,
122 wm_normal_hints_cookie, motif_wm_hints_cookie, wm_user_time_cookie, wm_desktop_cookie;
123
124 geomc = xcb_get_geometry(conn, d);
125
126 /* Check if the window is mapped (it could be not mapped when intializing and
127 calling manage_window() for every window) */
128 if ((attr = xcb_get_window_attributes_reply(conn, cookie, 0)) == NULL) {
129 DLOG("Could not get attributes\n");
130 xcb_discard_reply(conn, geomc.sequence);
131 return;
132 }
133
134 if (needs_to_be_mapped && attr->map_state != XCB_MAP_STATE_VIEWABLE) {
135 xcb_discard_reply(conn, geomc.sequence);
136 goto out;
137 }
138
139 /* Don’t manage clients with the override_redirect flag */
140 if (attr->override_redirect) {
141 xcb_discard_reply(conn, geomc.sequence);
142 goto out;
143 }
144
145 /* Check if the window is already managed */
146 if (con_by_window_id(window) != NULL) {
147 DLOG("already managed (by con %p)\n", con_by_window_id(window));
148 xcb_discard_reply(conn, geomc.sequence);
149 goto out;
150 }
151
152 /* Get the initial geometry (position, size, …) */
153 if ((geom = xcb_get_geometry_reply(conn, geomc, 0)) == NULL) {
154 DLOG("could not get geometry\n");
155 goto out;
156 }
157
158 uint32_t values[1];
159
160 /* Set a temporary event mask for the new window, consisting only of
161 * PropertyChange and StructureNotify. We need to be notified of
162 * PropertyChanges because the client can change its properties *after* we
163 * requested them but *before* we actually reparented it and have set our
164 * final event mask.
165 * We need StructureNotify because the client may unmap the window before
166 * we get to re-parent it.
167 * If this request fails, we assume the client has already unmapped the
168 * window between the MapRequest and our event mask change. */
169 values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE |
170 XCB_EVENT_MASK_STRUCTURE_NOTIFY;
171 xcb_void_cookie_t event_mask_cookie =
172 xcb_change_window_attributes_checked(conn, window, XCB_CW_EVENT_MASK, values);
173 if (xcb_request_check(conn, event_mask_cookie) != NULL) {
174 LOG("Could not change event mask, the window probably already disappeared.\n");
175 goto out;
176 }
177
178 #define GET_PROPERTY(atom, len) xcb_get_property(conn, false, window, atom, XCB_GET_PROPERTY_TYPE_ANY, 0, len)
179
180 wm_type_cookie = GET_PROPERTY(A__NET_WM_WINDOW_TYPE, UINT32_MAX);
181 strut_cookie = GET_PROPERTY(A__NET_WM_STRUT_PARTIAL, UINT32_MAX);
182 state_cookie = GET_PROPERTY(A__NET_WM_STATE, UINT32_MAX);
183 utf8_title_cookie = GET_PROPERTY(A__NET_WM_NAME, 128);
184 leader_cookie = GET_PROPERTY(A_WM_CLIENT_LEADER, UINT32_MAX);
185 transient_cookie = GET_PROPERTY(XCB_ATOM_WM_TRANSIENT_FOR, UINT32_MAX);
186 title_cookie = GET_PROPERTY(XCB_ATOM_WM_NAME, 128);
187 class_cookie = GET_PROPERTY(XCB_ATOM_WM_CLASS, 128);
188 role_cookie = GET_PROPERTY(A_WM_WINDOW_ROLE, 128);
189 startup_id_cookie = GET_PROPERTY(A__NET_STARTUP_ID, 512);
190 wm_hints_cookie = xcb_icccm_get_wm_hints(conn, window);
191 wm_normal_hints_cookie = xcb_icccm_get_wm_normal_hints(conn, window);
192 motif_wm_hints_cookie = GET_PROPERTY(A__MOTIF_WM_HINTS, 5 * sizeof(uint64_t));
193 wm_user_time_cookie = GET_PROPERTY(A__NET_WM_USER_TIME, UINT32_MAX);
194 wm_desktop_cookie = GET_PROPERTY(A__NET_WM_DESKTOP, UINT32_MAX);
195
196 i3Window *cwindow = scalloc(1, sizeof(i3Window));
197 cwindow->id = window;
198 cwindow->depth = get_visual_depth(attr->visual);
199
200 int *buttons = bindings_get_buttons_to_grab();
201 xcb_grab_buttons(conn, window, buttons);
202 FREE(buttons);
203
204 /* update as much information as possible so far (some replies may be NULL) */
205 window_update_class(cwindow, xcb_get_property_reply(conn, class_cookie, NULL));
206 window_update_name_legacy(cwindow, xcb_get_property_reply(conn, title_cookie, NULL));
207 window_update_name(cwindow, xcb_get_property_reply(conn, utf8_title_cookie, NULL));
208 window_update_leader(cwindow, xcb_get_property_reply(conn, leader_cookie, NULL));
209 window_update_transient_for(cwindow, xcb_get_property_reply(conn, transient_cookie, NULL));
210 window_update_strut_partial(cwindow, xcb_get_property_reply(conn, strut_cookie, NULL));
211 window_update_role(cwindow, xcb_get_property_reply(conn, role_cookie, NULL));
212 bool urgency_hint;
213 window_update_hints(cwindow, xcb_get_property_reply(conn, wm_hints_cookie, NULL), &urgency_hint);
214 border_style_t motif_border_style = BS_NORMAL;
215 window_update_motif_hints(cwindow, xcb_get_property_reply(conn, motif_wm_hints_cookie, NULL), &motif_border_style);
216 window_update_normal_hints(cwindow, xcb_get_property_reply(conn, wm_normal_hints_cookie, NULL), geom);
217 xcb_get_property_reply_t *type_reply = xcb_get_property_reply(conn, wm_type_cookie, NULL);
218 xcb_get_property_reply_t *state_reply = xcb_get_property_reply(conn, state_cookie, NULL);
219
220 xcb_get_property_reply_t *startup_id_reply;
221 startup_id_reply = xcb_get_property_reply(conn, startup_id_cookie, NULL);
222 char *startup_ws = startup_workspace_for_window(cwindow, startup_id_reply);
223 DLOG("startup workspace = %s\n", startup_ws);
224
225 /* Get _NET_WM_DESKTOP if it was set. */
226 xcb_get_property_reply_t *wm_desktop_reply;
227 wm_desktop_reply = xcb_get_property_reply(conn, wm_desktop_cookie, NULL);
228 cwindow->wm_desktop = NET_WM_DESKTOP_NONE;
229 if (wm_desktop_reply != NULL && xcb_get_property_value_length(wm_desktop_reply) != 0) {
230 uint32_t *wm_desktops = xcb_get_property_value(wm_desktop_reply);
231 cwindow->wm_desktop = (int32_t)wm_desktops[0];
232 }
233 FREE(wm_desktop_reply);
234
235 /* check if the window needs WM_TAKE_FOCUS */
236 cwindow->needs_take_focus = window_supports_protocol(cwindow->id, A_WM_TAKE_FOCUS);
237
238 /* read the preferred _NET_WM_WINDOW_TYPE atom */
239 cwindow->window_type = xcb_get_preferred_window_type(type_reply);
240
241 /* Where to start searching for a container that swallows the new one? */
242 Con *search_at = croot;
243
244 if (xcb_reply_contains_atom(type_reply, A__NET_WM_WINDOW_TYPE_DOCK)) {
245 LOG("This window is of type dock\n");
246 Output *output = get_output_containing(geom->x, geom->y);
247 if (output != NULL) {
248 DLOG("Starting search at output %s\n", output_primary_name(output));
249 search_at = output->con;
250 }
251
252 /* find out the desired position of this dock window */
253 if (cwindow->reserved.top > 0 && cwindow->reserved.bottom == 0) {
254 DLOG("Top dock client\n");
255 cwindow->dock = W_DOCK_TOP;
256 } else if (cwindow->reserved.top == 0 && cwindow->reserved.bottom > 0) {
257 DLOG("Bottom dock client\n");
258 cwindow->dock = W_DOCK_BOTTOM;
259 } else {
260 DLOG("Ignoring invalid reserved edges (_NET_WM_STRUT_PARTIAL), using position as fallback:\n");
261 if (geom->y < (int16_t)(search_at->rect.height / 2)) {
262 DLOG("geom->y = %d < rect.height / 2 = %d, it is a top dock client\n",
263 geom->y, (search_at->rect.height / 2));
264 cwindow->dock = W_DOCK_TOP;
265 } else {
266 DLOG("geom->y = %d >= rect.height / 2 = %d, it is a bottom dock client\n",
267 geom->y, (search_at->rect.height / 2));
268 cwindow->dock = W_DOCK_BOTTOM;
269 }
270 }
271 }
272
273 DLOG("Initial geometry: (%d, %d, %d, %d)\n", geom->x, geom->y, geom->width, geom->height);
274
275 /* See if any container swallows this new window */
276 Match *match = NULL;
277 Con *nc = con_for_window(search_at, cwindow, &match);
278 const bool match_from_restart_mode = (match && match->restart_mode);
279 if (nc == NULL) {
280 Con *wm_desktop_ws = NULL;
281 Assignment *assignment;
282
283 /* If not, check if it is assigned to a specific workspace */
284 if ((assignment = assignment_for(cwindow, A_TO_WORKSPACE)) ||
285 (assignment = assignment_for(cwindow, A_TO_WORKSPACE_NUMBER))) {
286 DLOG("Assignment matches (%p)\n", match);
287
288 Con *assigned_ws = NULL;
289 if (assignment->type == A_TO_WORKSPACE_NUMBER) {
290 long parsed_num = ws_name_to_number(assignment->dest.workspace);
291
292 assigned_ws = get_existing_workspace_by_num(parsed_num);
293 }
294 /* A_TO_WORKSPACE type assignment or fallback from A_TO_WORKSPACE_NUMBER
295 * when the target workspace number does not exist yet. */
296 if (!assigned_ws) {
297 assigned_ws = workspace_get(assignment->dest.workspace, NULL);
298 }
299
300 nc = con_descend_tiling_focused(assigned_ws);
301 DLOG("focused on ws %s: %p / %s\n", assigned_ws->name, nc, nc->name);
302 if (nc->type == CT_WORKSPACE)
303 nc = tree_open_con(nc, cwindow);
304 else
305 nc = tree_open_con(nc->parent, cwindow);
306
307 /* set the urgency hint on the window if the workspace is not visible */
308 if (!workspace_is_visible(assigned_ws))
309 urgency_hint = true;
310 } else if (cwindow->wm_desktop != NET_WM_DESKTOP_NONE &&
311 cwindow->wm_desktop != NET_WM_DESKTOP_ALL &&
312 (wm_desktop_ws = ewmh_get_workspace_by_index(cwindow->wm_desktop)) != NULL) {
313 /* If _NET_WM_DESKTOP is set to a specific desktop, we open it
314 * there. Note that we ignore the special value 0xFFFFFFFF here
315 * since such a window will be made sticky anyway. */
316
317 DLOG("Using workspace %p / %s because _NET_WM_DESKTOP = %d.\n",
318 wm_desktop_ws, wm_desktop_ws->name, cwindow->wm_desktop);
319
320 nc = con_descend_tiling_focused(wm_desktop_ws);
321 if (nc->type == CT_WORKSPACE)
322 nc = tree_open_con(nc, cwindow);
323 else
324 nc = tree_open_con(nc->parent, cwindow);
325 } else if (startup_ws) {
326 /* If it was started on a specific workspace, we want to open it there. */
327 DLOG("Using workspace on which this application was started (%s)\n", startup_ws);
328 nc = con_descend_tiling_focused(workspace_get(startup_ws, NULL));
329 DLOG("focused on ws %s: %p / %s\n", startup_ws, nc, nc->name);
330 if (nc->type == CT_WORKSPACE)
331 nc = tree_open_con(nc, cwindow);
332 else
333 nc = tree_open_con(nc->parent, cwindow);
334 } else {
335 /* If not, insert it at the currently focused position */
336 if (focused->type == CT_CON && con_accepts_window(focused)) {
337 LOG("using current container, focused = %p, focused->name = %s\n",
338 focused, focused->name);
339 nc = focused;
340 } else
341 nc = tree_open_con(NULL, cwindow);
342 }
343
344 if ((assignment = assignment_for(cwindow, A_TO_OUTPUT))) {
345 con_move_to_output_name(nc, assignment->dest.output, true);
346 }
347 } else {
348 /* M_BELOW inserts the new window as a child of the one which was
349 * matched (e.g. dock areas) */
350 if (match != NULL && match->insert_where == M_BELOW) {
351 nc = tree_open_con(nc, cwindow);
352 }
353
354 /* If M_BELOW is not used, the container is replaced. This happens with
355 * "swallows" criteria that are used for stored layouts, in which case
356 * we need to remove that criterion, because they should only be valid
357 * once. */
358 if (match != NULL && match->insert_where != M_BELOW) {
359 DLOG("Removing match %p from container %p\n", match, nc);
360 TAILQ_REMOVE(&(nc->swallow_head), match, matches);
361 match_free(match);
362 FREE(match);
363 }
364 }
365
366 DLOG("new container = %p\n", nc);
367 if (nc->window != NULL && nc->window != cwindow) {
368 if (!restore_kill_placeholder(nc->window->id)) {
369 DLOG("Uh?! Container without a placeholder, but with a window, has swallowed this to-be-managed window?!\n");
370 } else {
371 /* Remove remaining criteria, the first swallowed window wins. */
372 _remove_matches(nc);
373 }
374 }
375 xcb_window_t old_frame = XCB_NONE;
376 if (nc->window != cwindow && nc->window != NULL) {
377 window_free(nc->window);
378 old_frame = _match_depth(cwindow, nc);
379 }
380 nc->window = cwindow;
381 x_reinit(nc);
382
383 nc->border_width = geom->border_width;
384
385 char *name;
386 sasprintf(&name, "[i3 con] container around %p", cwindow);
387 x_set_name(nc, name);
388 free(name);
389
390 /* handle fullscreen containers */
391 Con *ws = con_get_workspace(nc);
392 Con *fs = con_get_fullscreen_covering_ws(ws);
393
394 if (xcb_reply_contains_atom(state_reply, A__NET_WM_STATE_FULLSCREEN)) {
395 /* If this window is already fullscreen (after restarting!), skip
396 * toggling fullscreen, that would drop it out of fullscreen mode. */
397 if (fs != nc) {
398 Output *output = get_output_with_dimensions((Rect){geom->x, geom->y, geom->width, geom->height});
399 /* If the requested window geometry spans the whole area
400 * of an output, move the window to that output. This is
401 * needed e.g. for LibreOffice Impress multi-monitor
402 * presentations to work out of the box. */
403 if (output != NULL)
404 con_move_to_output(nc, output, false);
405 con_toggle_fullscreen(nc, CF_OUTPUT);
406 }
407 fs = NULL;
408 }
409
410 bool set_focus = false;
411
412 if (fs == NULL) {
413 DLOG("Not in fullscreen mode, focusing\n");
414 if (!cwindow->dock) {
415 /* Check that the workspace is visible and on the same output as
416 * the current focused container. If the window was assigned to an
417 * invisible workspace, we should not steal focus. */
418 Con *current_output = con_get_output(focused);
419 Con *target_output = con_get_output(ws);
420
421 if (workspace_is_visible(ws) && current_output == target_output) {
422 if (!match_from_restart_mode) {
423 set_focus = true;
424 } else {
425 DLOG("not focusing, matched with restart_mode == true\n");
426 }
427 } else {
428 DLOG("workspace not visible, not focusing\n");
429 }
430 } else {
431 DLOG("dock, not focusing\n");
432 }
433 } else {
434 DLOG("fs = %p, ws = %p, not focusing\n", fs, ws);
435 /* Insert the new container in focus stack *after* the currently
436 * focused (fullscreen) con. This way, the new container will be
437 * focused after we return from fullscreen mode */
438 Con *first = TAILQ_FIRST(&(nc->parent->focus_head));
439 if (first != nc) {
440 /* We only modify the focus stack if the container is not already
441 * the first one. This can happen when existing containers swallow
442 * new windows, for example when restarting. */
443 TAILQ_REMOVE(&(nc->parent->focus_head), nc, focused);
444 TAILQ_INSERT_AFTER(&(nc->parent->focus_head), first, nc, focused);
445 }
446 }
447
448 /* set floating if necessary */
449 bool want_floating = false;
450 if (xcb_reply_contains_atom(type_reply, A__NET_WM_WINDOW_TYPE_DIALOG) ||
451 xcb_reply_contains_atom(type_reply, A__NET_WM_WINDOW_TYPE_UTILITY) ||
452 xcb_reply_contains_atom(type_reply, A__NET_WM_WINDOW_TYPE_TOOLBAR) ||
453 xcb_reply_contains_atom(type_reply, A__NET_WM_WINDOW_TYPE_SPLASH) ||
454 xcb_reply_contains_atom(state_reply, A__NET_WM_STATE_MODAL) ||
455 (cwindow->max_width > 0 && cwindow->max_height > 0 &&
456 cwindow->min_height == cwindow->max_height &&
457 cwindow->min_width == cwindow->max_width)) {
458 LOG("This window is a dialog window, setting floating\n");
459 want_floating = true;
460 }
461
462 if (xcb_reply_contains_atom(state_reply, A__NET_WM_STATE_STICKY))
463 nc->sticky = true;
464
465 /* We ignore the hint for an internal workspace because windows in the
466 * scratchpad also have this value, but upon restarting i3 we don't want
467 * them to become sticky windows. */
468 if (cwindow->wm_desktop == NET_WM_DESKTOP_ALL && (ws == NULL || !con_is_internal(ws))) {
469 DLOG("This window has _NET_WM_DESKTOP = 0xFFFFFFFF. Will float it and make it sticky.\n");
470 nc->sticky = true;
471 want_floating = true;
472 }
473
474 FREE(state_reply);
475 FREE(type_reply);
476
477 if (cwindow->transient_for != XCB_NONE ||
478 (cwindow->leader != XCB_NONE &&
479 cwindow->leader != cwindow->id &&
480 con_by_window_id(cwindow->leader) != NULL)) {
481 LOG("This window is transient for another window, setting floating\n");
482 want_floating = true;
483
484 if (config.popup_during_fullscreen == PDF_LEAVE_FULLSCREEN &&
485 fs != NULL) {
486 LOG("There is a fullscreen window, leaving fullscreen mode\n");
487 con_toggle_fullscreen(fs, CF_OUTPUT);
488 } else if (config.popup_during_fullscreen == PDF_SMART &&
489 fs != NULL &&
490 fs->window != NULL) {
491 i3Window *transient_win = cwindow;
492 while (transient_win != NULL &&
493 transient_win->transient_for != XCB_NONE) {
494 if (transient_win->transient_for == fs->window->id) {
495 LOG("This floating window belongs to the fullscreen window (popup_during_fullscreen == smart)\n");
496 set_focus = true;
497 break;
498 }
499 Con *next_transient = con_by_window_id(transient_win->transient_for);
500 if (next_transient == NULL)
501 break;
502 /* Some clients (e.g. x11-ssh-askpass) actually set
503 * WM_TRANSIENT_FOR to their own window id, so break instead of
504 * looping endlessly. */
505 if (transient_win == next_transient->window)
506 break;
507 transient_win = next_transient->window;
508 }
509 }
510 }
511
512 /* dock clients cannot be floating, that makes no sense */
513 if (cwindow->dock)
514 want_floating = false;
515
516 /* Store the requested geometry. The width/height gets raised to at least
517 * 75x50 when entering floating mode, which is the minimum size for a
518 * window to be useful (smaller windows are usually overlays/toolbars/…
519 * which are not managed by the wm anyways). We store the original geometry
520 * here because it’s used for dock clients. */
521 if (nc->geometry.width == 0)
522 nc->geometry = (Rect){geom->x, geom->y, geom->width, geom->height};
523
524 if (motif_border_style != BS_NORMAL) {
525 DLOG("MOTIF_WM_HINTS specifies decorations (border_style = %d)\n", motif_border_style);
526 if (want_floating) {
527 con_set_border_style(nc, motif_border_style, config.default_floating_border_width);
528 } else {
529 con_set_border_style(nc, motif_border_style, config.default_border_width);
530 }
531 }
532
533 if (want_floating) {
534 DLOG("geometry = %d x %d\n", nc->geometry.width, nc->geometry.height);
535 /* automatically set the border to the default value if a motif border
536 * was not specified */
537 bool automatic_border = (motif_border_style == BS_NORMAL);
538
539 floating_enable(nc, automatic_border);
540 nc->floating = FLOATING_AUTO_ON;
541 }
542
543 /* explicitly set the border width to the default */
544 if (nc->current_border_width == -1) {
545 nc->current_border_width = (want_floating ? config.default_floating_border_width : config.default_border_width);
546 }
547
548 /* to avoid getting an UnmapNotify event due to reparenting, we temporarily
549 * declare no interest in any state change event of this window */
550 values[0] = XCB_NONE;
551 xcb_change_window_attributes(conn, window, XCB_CW_EVENT_MASK, values);
552
553 xcb_void_cookie_t rcookie = xcb_reparent_window_checked(conn, window, nc->frame.id, 0, 0);
554 if (xcb_request_check(conn, rcookie) != NULL) {
555 LOG("Could not reparent the window, aborting\n");
556 goto geom_out;
557 }
558
559 values[0] = CHILD_EVENT_MASK & ~XCB_EVENT_MASK_ENTER_WINDOW;
560 xcb_change_window_attributes(conn, window, XCB_CW_EVENT_MASK, values);
561 xcb_flush(conn);
562
563 /* Put the client inside the save set. Upon termination (whether killed or
564 * normal exit does not matter) of the window manager, these clients will
565 * be correctly reparented to their most closest living ancestor (=
566 * cleanup) */
567 xcb_change_save_set(conn, XCB_SET_MODE_INSERT, window);
568
569 if (shape_supported) {
570 /* Receive ShapeNotify events whenever the client altered its window
571 * shape. */
572 xcb_shape_select_input(conn, window, true);
573
574 /* Check if the window is shaped. Sadly, we can check only for the
575 * bounding shape, not for the input shape. */
576 xcb_shape_query_extents_cookie_t cookie =
577 xcb_shape_query_extents(conn, window);
578 xcb_shape_query_extents_reply_t *reply =
579 xcb_shape_query_extents_reply(conn, cookie, NULL);
580 if (reply != NULL && reply->bounding_shaped) {
581 cwindow->shaped = true;
582 }
583 FREE(reply);
584 }
585
586 /* Check if any assignments match */
587 run_assignments(cwindow);
588
589 /* 'ws' may be invalid because of the assignments, e.g. when the user uses
590 * "move window to workspace 1", but had it assigned to workspace 2. */
591 ws = con_get_workspace(nc);
592
593 /* If this window was put onto an invisible workspace (via assignments), we
594 * render this workspace. It wouldn’t be rendered in our normal code path
595 * because only the visible workspaces get rendered.
596 *
597 * By rendering the workspace, we assign proper coordinates (read: not
598 * width=0, height=0) to the window, which is important for windows who
599 * actually use them to position their GUI elements, e.g. rhythmbox. */
600 if (ws && !workspace_is_visible(ws)) {
601 /* This is a bit hackish: we need to copy the content container’s rect
602 * to the workspace, because calling render_con() on the content
603 * container would also take the shortcut and not render the invisible
604 * workspace at all. However, just calling render_con() on the
605 * workspace isn’t enough either — it needs the rect. */
606 ws->rect = ws->parent->rect;
607 render_con(ws, false);
608 /* Disable setting focus, otherwise we’d move focus to an invisible
609 * workspace, which we generally prevent (e.g. in
610 * con_move_to_workspace). */
611 set_focus = false;
612 }
613 render_con(croot, false);
614
615 cwindow->managed_since = time(NULL);
616
617 /* Send an event about window creation */
618 ipc_send_window_event("new", nc);
619
620 if (set_focus && assignment_for(cwindow, A_NO_FOCUS) != NULL) {
621 /* The first window on a workspace should always be focused. We have to
622 * compare with == 1 because the container has already been inserted at
623 * this point. */
624 if (con_num_windows(ws) == 1) {
625 DLOG("This is the first window on this workspace, ignoring no_focus.\n");
626 } else {
627 DLOG("no_focus was set for con = %p, not setting focus.\n", nc);
628 set_focus = false;
629 }
630 }
631
632 if (set_focus) {
633 DLOG("Checking con = %p for _NET_WM_USER_TIME.\n", nc);
634
635 uint32_t *wm_user_time;
636 xcb_get_property_reply_t *wm_user_time_reply = xcb_get_property_reply(conn, wm_user_time_cookie, NULL);
637 if (wm_user_time_reply != NULL && xcb_get_property_value_length(wm_user_time_reply) != 0 &&
638 (wm_user_time = xcb_get_property_value(wm_user_time_reply)) &&
639 wm_user_time[0] == 0) {
640 DLOG("_NET_WM_USER_TIME set to 0, not focusing con = %p.\n", nc);
641 set_focus = false;
642 }
643
644 FREE(wm_user_time_reply);
645 } else {
646 xcb_discard_reply(conn, wm_user_time_cookie.sequence);
647 }
648
649 if (set_focus) {
650 /* Even if the client doesn't want focus, we still need to focus the
651 * container to not break focus workflows. Our handling towards X will
652 * take care of not setting the input focus. However, one exception to
653 * this are clients using the globally active input model which we
654 * don't want to focus at all. */
655 if (nc->window->doesnt_accept_focus && !nc->window->needs_take_focus) {
656 set_focus = false;
657 }
658 }
659
660 /* Defer setting focus after the 'new' event has been sent to ensure the
661 * proper window event sequence. */
662 if (set_focus && nc->mapped) {
663 DLOG("Now setting focus.\n");
664 con_activate(nc);
665 }
666
667 tree_render();
668
669 /* Destroy the old frame if we had to reframe the container. This needs to be done
670 * after rendering in order to prevent the background from flickering in its place. */
671 if (old_frame != XCB_NONE) {
672 xcb_destroy_window(conn, old_frame);
673 }
674
675 /* Windows might get managed with the urgency hint already set (Pidgin is
676 * known to do that), so check for that and handle the hint accordingly.
677 * This code needs to be in this part of manage_window() because the window
678 * needs to be on the final workspace first. */
679 con_set_urgency(nc, urgency_hint);
680
681 /* Update _NET_WM_DESKTOP. We invalidate the cached value first to force an update. */
682 cwindow->wm_desktop = NET_WM_DESKTOP_NONE;
683 ewmh_update_wm_desktop();
684
685 /* If a sticky window was mapped onto another workspace, make sure to pop it to the front. */
686 output_push_sticky_windows(focused);
687
688 geom_out:
689 free(geom);
690 out:
691 free(attr);
692 }
693
694 /*
695 * Remanages a window: performs a swallow check and runs assignments.
696 * Returns con for the window regardless if it updated.
697 *
698 */
699 Con *remanage_window(Con *con) {
700 Match *match;
701 Con *nc = con_for_window(croot, con->window, &match);
702 if (nc == NULL || nc->window == NULL || nc->window == con->window) {
703 run_assignments(con->window);
704 return con;
705 }
706 /* Make sure the placeholder that wants to swallow this window didn't spawn
707 * after the window to follow current behavior: adding a placeholder won't
708 * swallow windows currently managed. */
709 if (nc->window->managed_since > con->window->managed_since) {
710 run_assignments(con->window);
711 return con;
712 }
713
714 if (!restore_kill_placeholder(nc->window->id)) {
715 DLOG("Uh?! Container without a placeholder, but with a window, has swallowed this managed window?!\n");
716 } else {
717 _remove_matches(nc);
718 }
719 window_free(nc->window);
720
721 xcb_window_t old_frame = _match_depth(con->window, nc);
722
723 x_reparent_child(nc, con);
724
725 bool moved_workpaces = (con_get_workspace(nc) != con_get_workspace(con));
726
727 con_merge_into(con, nc);
728
729 /* Destroy the old frame if we had to reframe the container. This needs to be done
730 * after rendering in order to prevent the background from flickering in its place. */
731 if (old_frame != XCB_NONE) {
732 xcb_destroy_window(conn, old_frame);
733 }
734
735 run_assignments(nc->window);
736
737 if (moved_workpaces) {
738 /* If the window is associated with a startup sequence, delete it so
739 * child windows won't be created on the old workspace. */
740 startup_sequence_delete_by_window(nc->window);
741
742 ewmh_update_wm_desktop();
743 }
744
745 return nc;
746 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * A "match" is a data structure which acts like a mask or expression to match
7 * certain windows or not. For example, when using commands, you can specify a
8 * command like this: [title="*Firefox*"] kill. The title member of the match
9 * data structure will then be filled and i3 will check each window using
10 * match_matches_window() to find the windows affected by this command.
11 *
12 */
13 #include "all.h"
14
15 /* From sys/time.h, not sure if it’s available on all systems. */
16 #define _i3_timercmp(a, b, CMP) \
17 (((a).tv_sec == (b).tv_sec) ? ((a).tv_usec CMP(b).tv_usec) : ((a).tv_sec CMP(b).tv_sec))
18
19 /*
20 * Initializes the Match data structure. This function is necessary because the
21 * members representing boolean values (like dock) need to be initialized with
22 * -1 instead of 0.
23 *
24 */
25 void match_init(Match *match) {
26 memset(match, 0, sizeof(Match));
27 match->urgent = U_DONTCHECK;
28 match->window_mode = WM_ANY;
29 /* we use this as the placeholder value for "not set". */
30 match->window_type = UINT32_MAX;
31 }
32
33 /*
34 * Check if a match is empty. This is necessary while parsing commands to see
35 * whether the user specified a match at all.
36 *
37 */
38 bool match_is_empty(Match *match) {
39 /* we cannot simply use memcmp() because the structure is part of a
40 * TAILQ and I don’t want to start with things like assuming that the
41 * last member of a struct really is at the end in memory… */
42 return (match->title == NULL &&
43 match->mark == NULL &&
44 match->application == NULL &&
45 match->class == NULL &&
46 match->instance == NULL &&
47 match->window_role == NULL &&
48 match->workspace == NULL &&
49 match->urgent == U_DONTCHECK &&
50 match->id == XCB_NONE &&
51 match->window_type == UINT32_MAX &&
52 match->con_id == NULL &&
53 match->dock == M_NODOCK &&
54 match->window_mode == WM_ANY);
55 }
56
57 /*
58 * Copies the data of a match from src to dest.
59 *
60 */
61 void match_copy(Match *dest, Match *src) {
62 memcpy(dest, src, sizeof(Match));
63
64 /* The DUPLICATE_REGEX macro creates a new regular expression from the
65 * ->pattern of the old one. It therefore does use a little more memory then
66 * with a refcounting system, but it’s easier this way. */
67 #define DUPLICATE_REGEX(field) \
68 do { \
69 if (src->field != NULL) \
70 dest->field = regex_new(src->field->pattern); \
71 } while (0)
72
73 DUPLICATE_REGEX(title);
74 DUPLICATE_REGEX(mark);
75 DUPLICATE_REGEX(application);
76 DUPLICATE_REGEX(class);
77 DUPLICATE_REGEX(instance);
78 DUPLICATE_REGEX(window_role);
79 DUPLICATE_REGEX(workspace);
80 }
81
82 /*
83 * Check if a match data structure matches the given window.
84 *
85 */
86 bool match_matches_window(Match *match, i3Window *window) {
87 LOG("Checking window 0x%08x (class %s)\n", window->id, window->class_class);
88
89 #define GET_FIELD_str(field) (field)
90 #define GET_FIELD_i3string(field) (i3string_as_utf8(field))
91 #define CHECK_WINDOW_FIELD(match_field, window_field, type) \
92 do { \
93 if (match->match_field != NULL) { \
94 const char *window_field_str = window->window_field == NULL \
95 ? "" \
96 : GET_FIELD_##type(window->window_field); \
97 if (strcmp(match->match_field->pattern, "__focused__") == 0 && \
98 focused && focused->window && focused->window->window_field && \
99 strcmp(window_field_str, GET_FIELD_##type(focused->window->window_field)) == 0) { \
100 LOG("window " #match_field " matches focused window\n"); \
101 } else if (regex_matches(match->match_field, window_field_str)) { \
102 LOG("window " #match_field " matches (%s)\n", window_field_str); \
103 } else { \
104 return false; \
105 } \
106 } \
107 } while (0)
108
109 CHECK_WINDOW_FIELD(class, class_class, str);
110 CHECK_WINDOW_FIELD(instance, class_instance, str);
111
112 if (match->id != XCB_NONE) {
113 if (window->id == match->id) {
114 LOG("match made by window id (%d)\n", window->id);
115 } else {
116 LOG("window id does not match\n");
117 return false;
118 }
119 }
120
121 CHECK_WINDOW_FIELD(title, name, i3string);
122 CHECK_WINDOW_FIELD(window_role, role, str);
123
124 if (match->window_type != UINT32_MAX) {
125 if (window->window_type == match->window_type) {
126 LOG("window_type matches (%i)\n", match->window_type);
127 } else {
128 return false;
129 }
130 }
131
132 Con *con = NULL;
133 if (match->urgent == U_LATEST) {
134 /* if the window isn't urgent, no sense in searching */
135 if (window->urgent.tv_sec == 0) {
136 return false;
137 }
138 /* if we find a window that is newer than this one, bail */
139 TAILQ_FOREACH (con, &all_cons, all_cons) {
140 if ((con->window != NULL) &&
141 _i3_timercmp(con->window->urgent, window->urgent, >)) {
142 return false;
143 }
144 }
145 LOG("urgent matches latest\n");
146 }
147
148 if (match->urgent == U_OLDEST) {
149 /* if the window isn't urgent, no sense in searching */
150 if (window->urgent.tv_sec == 0) {
151 return false;
152 }
153 /* if we find a window that is older than this one (and not 0), bail */
154 TAILQ_FOREACH (con, &all_cons, all_cons) {
155 if ((con->window != NULL) &&
156 (con->window->urgent.tv_sec != 0) &&
157 _i3_timercmp(con->window->urgent, window->urgent, <)) {
158 return false;
159 }
160 }
161 LOG("urgent matches oldest\n");
162 }
163
164 if (match->workspace != NULL) {
165 if ((con = con_by_window_id(window->id)) == NULL)
166 return false;
167
168 Con *ws = con_get_workspace(con);
169 if (ws == NULL)
170 return false;
171
172 if (strcmp(match->workspace->pattern, "__focused__") == 0 &&
173 strcmp(ws->name, con_get_workspace(focused)->name) == 0) {
174 LOG("workspace matches focused workspace\n");
175 } else if (regex_matches(match->workspace, ws->name)) {
176 LOG("workspace matches (%s)\n", ws->name);
177 } else {
178 return false;
179 }
180 }
181
182 if (match->dock != M_DONTCHECK) {
183 if ((window->dock == W_DOCK_TOP && match->dock == M_DOCK_TOP) ||
184 (window->dock == W_DOCK_BOTTOM && match->dock == M_DOCK_BOTTOM) ||
185 ((window->dock == W_DOCK_TOP || window->dock == W_DOCK_BOTTOM) &&
186 match->dock == M_DOCK_ANY) ||
187 (window->dock == W_NODOCK && match->dock == M_NODOCK)) {
188 LOG("dock status matches\n");
189 } else {
190 LOG("dock status does not match\n");
191 return false;
192 }
193 }
194
195 if (match->mark != NULL) {
196 if ((con = con_by_window_id(window->id)) == NULL)
197 return false;
198
199 bool matched = false;
200 mark_t *mark;
201 TAILQ_FOREACH (mark, &(con->marks_head), marks) {
202 if (regex_matches(match->mark, mark->name)) {
203 matched = true;
204 break;
205 }
206 }
207
208 if (matched) {
209 LOG("mark matches\n");
210 } else {
211 LOG("mark does not match\n");
212 return false;
213 }
214 }
215
216 if (match->window_mode != WM_ANY) {
217 if ((con = con_by_window_id(window->id)) == NULL) {
218 return false;
219 }
220
221 switch (match->window_mode) {
222 case WM_TILING_AUTO:
223 if (con->floating != FLOATING_AUTO_OFF) {
224 return false;
225 }
226 break;
227 case WM_TILING_USER:
228 if (con->floating != FLOATING_USER_OFF) {
229 return false;
230 }
231 break;
232 case WM_TILING:
233 if (con_inside_floating(con) != NULL) {
234 return false;
235 }
236 break;
237 case WM_FLOATING_AUTO:
238 if (con->floating != FLOATING_AUTO_ON) {
239 return false;
240 }
241 break;
242 case WM_FLOATING_USER:
243 if (con->floating != FLOATING_USER_ON) {
244 return false;
245 }
246 break;
247 case WM_FLOATING:
248 if (con_inside_floating(con) == NULL) {
249 return false;
250 }
251 break;
252 case WM_ANY:
253 assert(false);
254 }
255
256 LOG("window_mode matches\n");
257 }
258
259 return true;
260 }
261
262 /*
263 * Frees the given match. It must not be used afterwards!
264 *
265 */
266 void match_free(Match *match) {
267 FREE(match->error);
268 regex_free(match->title);
269 regex_free(match->application);
270 regex_free(match->class);
271 regex_free(match->instance);
272 regex_free(match->mark);
273 regex_free(match->window_role);
274 regex_free(match->workspace);
275 }
276
277 /*
278 * Interprets a ctype=cvalue pair and adds it to the given match specification.
279 *
280 */
281 void match_parse_property(Match *match, const char *ctype, const char *cvalue) {
282 assert(match != NULL);
283 DLOG("ctype=*%s*, cvalue=*%s*\n", ctype, cvalue);
284
285 if (strcmp(ctype, "class") == 0) {
286 regex_free(match->class);
287 match->class = regex_new(cvalue);
288 return;
289 }
290
291 if (strcmp(ctype, "instance") == 0) {
292 regex_free(match->instance);
293 match->instance = regex_new(cvalue);
294 return;
295 }
296
297 if (strcmp(ctype, "window_role") == 0) {
298 regex_free(match->window_role);
299 match->window_role = regex_new(cvalue);
300 return;
301 }
302
303 if (strcmp(ctype, "con_id") == 0) {
304 if (strcmp(cvalue, "__focused__") == 0) {
305 match->con_id = focused;
306 return;
307 }
308
309 long parsed;
310 if (!parse_long(cvalue, &parsed, 0)) {
311 ELOG("Could not parse con id \"%s\"\n", cvalue);
312 match->error = sstrdup("invalid con_id");
313 } else {
314 match->con_id = (Con *)parsed;
315 DLOG("id as int = %p\n", match->con_id);
316 }
317 return;
318 }
319
320 if (strcmp(ctype, "id") == 0) {
321 long parsed;
322 if (!parse_long(cvalue, &parsed, 0)) {
323 ELOG("Could not parse window id \"%s\"\n", cvalue);
324 match->error = sstrdup("invalid id");
325 } else {
326 match->id = parsed;
327 DLOG("window id as int = %d\n", match->id);
328 }
329 return;
330 }
331
332 if (strcmp(ctype, "window_type") == 0) {
333 if (strcasecmp(cvalue, "normal") == 0) {
334 match->window_type = A__NET_WM_WINDOW_TYPE_NORMAL;
335 } else if (strcasecmp(cvalue, "dialog") == 0) {
336 match->window_type = A__NET_WM_WINDOW_TYPE_DIALOG;
337 } else if (strcasecmp(cvalue, "utility") == 0) {
338 match->window_type = A__NET_WM_WINDOW_TYPE_UTILITY;
339 } else if (strcasecmp(cvalue, "toolbar") == 0) {
340 match->window_type = A__NET_WM_WINDOW_TYPE_TOOLBAR;
341 } else if (strcasecmp(cvalue, "splash") == 0) {
342 match->window_type = A__NET_WM_WINDOW_TYPE_SPLASH;
343 } else if (strcasecmp(cvalue, "menu") == 0) {
344 match->window_type = A__NET_WM_WINDOW_TYPE_MENU;
345 } else if (strcasecmp(cvalue, "dropdown_menu") == 0) {
346 match->window_type = A__NET_WM_WINDOW_TYPE_DROPDOWN_MENU;
347 } else if (strcasecmp(cvalue, "popup_menu") == 0) {
348 match->window_type = A__NET_WM_WINDOW_TYPE_POPUP_MENU;
349 } else if (strcasecmp(cvalue, "tooltip") == 0) {
350 match->window_type = A__NET_WM_WINDOW_TYPE_TOOLTIP;
351 } else if (strcasecmp(cvalue, "notification") == 0) {
352 match->window_type = A__NET_WM_WINDOW_TYPE_NOTIFICATION;
353 } else {
354 ELOG("unknown window_type value \"%s\"\n", cvalue);
355 match->error = sstrdup("unknown window_type value");
356 }
357
358 return;
359 }
360
361 if (strcmp(ctype, "con_mark") == 0) {
362 regex_free(match->mark);
363 match->mark = regex_new(cvalue);
364 return;
365 }
366
367 if (strcmp(ctype, "title") == 0) {
368 regex_free(match->title);
369 match->title = regex_new(cvalue);
370 return;
371 }
372
373 if (strcmp(ctype, "urgent") == 0) {
374 if (strcasecmp(cvalue, "latest") == 0 ||
375 strcasecmp(cvalue, "newest") == 0 ||
376 strcasecmp(cvalue, "recent") == 0 ||
377 strcasecmp(cvalue, "last") == 0) {
378 match->urgent = U_LATEST;
379 } else if (strcasecmp(cvalue, "oldest") == 0 ||
380 strcasecmp(cvalue, "first") == 0) {
381 match->urgent = U_OLDEST;
382 }
383 return;
384 }
385
386 if (strcmp(ctype, "workspace") == 0) {
387 regex_free(match->workspace);
388 match->workspace = regex_new(cvalue);
389 return;
390 }
391
392 if (strcmp(ctype, "tiling") == 0) {
393 match->window_mode = WM_TILING;
394 return;
395 }
396
397 if (strcmp(ctype, "tiling_from") == 0 &&
398 cvalue != NULL &&
399 strcmp(cvalue, "auto") == 0) {
400 match->window_mode = WM_TILING_AUTO;
401 return;
402 }
403
404 if (strcmp(ctype, "tiling_from") == 0 &&
405 cvalue != NULL &&
406 strcmp(cvalue, "user") == 0) {
407 match->window_mode = WM_TILING_USER;
408 return;
409 }
410
411 if (strcmp(ctype, "floating") == 0) {
412 match->window_mode = WM_FLOATING;
413 return;
414 }
415
416 if (strcmp(ctype, "floating_from") == 0 &&
417 cvalue != NULL &&
418 strcmp(cvalue, "auto") == 0) {
419 match->window_mode = WM_FLOATING_AUTO;
420 return;
421 }
422
423 if (strcmp(ctype, "floating_from") == 0 &&
424 cvalue != NULL &&
425 strcmp(cvalue, "user") == 0) {
426 match->window_mode = WM_FLOATING_USER;
427 return;
428 }
429
430 ELOG("Unknown criterion: %s\n", ctype);
431 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * move.c: Moving containers into some direction.
7 *
8 */
9 #include "all.h"
10
11 /*
12 * Returns the lowest container in the tree that has both a and b as descendants.
13 *
14 */
15 static Con *lowest_common_ancestor(Con *a, Con *b) {
16 Con *parent_a = a;
17 while (parent_a) {
18 Con *parent_b = b;
19 while (parent_b) {
20 if (parent_a == parent_b) {
21 return parent_a;
22 }
23 parent_b = parent_b->parent;
24 }
25 parent_a = parent_a->parent;
26 }
27 assert(false);
28 }
29
30 /*
31 * Returns the direct child of ancestor that contains con.
32 *
33 */
34 static Con *child_containing_con_recursively(Con *ancestor, Con *con) {
35 Con *child = con;
36 while (child && child->parent != ancestor) {
37 child = child->parent;
38 assert(child->parent);
39 }
40 return child;
41 }
42
43 /*
44 * Returns true if the given container is the focused descendant of ancestor, recursively.
45 *
46 */
47 static bool is_focused_descendant(Con *con, Con *ancestor) {
48 Con *current = con;
49 while (current != ancestor) {
50 if (TAILQ_FIRST(&(current->parent->focus_head)) != current) {
51 return false;
52 }
53 current = current->parent;
54 assert(current->parent);
55 }
56 return true;
57 }
58
59 /*
60 * This function detaches 'con' from its parent and inserts it either before or
61 * after 'target'.
62 *
63 */
64 void insert_con_into(Con *con, Con *target, position_t position) {
65 Con *parent = target->parent;
66 /* We need to preserve the old con->parent. While it might still be used to
67 * insert the entry before/after it, we call the on_remove_child callback
68 * afterwards which might then close the con if it is empty. */
69 Con *old_parent = con->parent;
70
71 /* We compare the focus order of the children of the lowest common ancestor. If con or
72 * its ancestor is before target's ancestor then con should be placed before the target
73 * in the focus stack. */
74 Con *lca = lowest_common_ancestor(con, parent);
75 if (lca == con) {
76 ELOG("Container is being inserted into one of its descendants.\n");
77 return;
78 }
79
80 Con *con_ancestor = child_containing_con_recursively(lca, con);
81 Con *target_ancestor = child_containing_con_recursively(lca, target);
82 bool moves_focus_from_ancestor = is_focused_descendant(con, con_ancestor);
83 bool focus_before;
84
85 /* Determine if con is going to be placed before or after target in the parent's focus stack. */
86 if (con_ancestor == target_ancestor) {
87 /* Happens when the target is con's old parent. Eg with layout V [ A H [ B C ] ],
88 * if we move C up. Target will be H. */
89 focus_before = moves_focus_from_ancestor;
90 } else {
91 /* Look at the focus stack order of the children of the lowest common ancestor. */
92 Con *current;
93 TAILQ_FOREACH (current, &(lca->focus_head), focused) {
94 if (current == con_ancestor || current == target_ancestor) {
95 break;
96 }
97 }
98 focus_before = (current == con_ancestor);
99 }
100
101 /* If con is the focused container in our old ancestor we place the new ancestor
102 * before the old ancestor in the focus stack. Example:
103 * Consider the layout [ H [ V1 [ A* B ] V2 [ C ] ] ] where A is focused. We move to
104 * a second workspace and from there we move A to the right and switch back to the
105 * original workspace. Without the change focus would move to B instead of staying
106 * with A. */
107 if (moves_focus_from_ancestor && focus_before) {
108 Con *place = TAILQ_PREV(con_ancestor, focus_head, focused);
109 TAILQ_REMOVE(&(lca->focus_head), target_ancestor, focused);
110 if (place) {
111 TAILQ_INSERT_AFTER(&(lca->focus_head), place, target_ancestor, focused);
112 } else {
113 TAILQ_INSERT_HEAD(&(lca->focus_head), target_ancestor, focused);
114 }
115 }
116
117 con_detach(con);
118 con_fix_percent(con->parent);
119
120 /* When moving to a workspace, we respect the user’s configured
121 * workspace_layout */
122 if (parent->type == CT_WORKSPACE) {
123 Con *split = workspace_attach_to(parent);
124 if (split != parent) {
125 DLOG("Got a new split con, using that one instead\n");
126 con->parent = split;
127 con_attach(con, split, false);
128 DLOG("attached\n");
129 con->percent = 0.0;
130 con_fix_percent(split);
131 con = split;
132 DLOG("ok, continuing with con %p instead\n", con);
133 con_detach(con);
134 }
135 }
136
137 con->parent = parent;
138
139 if (parent == lca) {
140 if (focus_before) {
141 /* Example layout: H [ A B* ], we move A up/down. 'target' will be H. */
142 TAILQ_INSERT_BEFORE(target, con, focused);
143 } else {
144 /* Example layout: H [ A B* ], we move A up/down. 'target' will be H. */
145 TAILQ_INSERT_AFTER(&(parent->focus_head), target, con, focused);
146 }
147 } else {
148 if (focus_before) {
149 /* Example layout: V [ H [ A B ] C* ], we move C up. 'target' will be A. */
150 TAILQ_INSERT_HEAD(&(parent->focus_head), con, focused);
151 } else {
152 /* Example layout: V [ H [ A* B ] C ], we move C up. 'target' will be A. */
153 TAILQ_INSERT_TAIL(&(parent->focus_head), con, focused);
154 }
155 }
156
157 if (position == BEFORE) {
158 TAILQ_INSERT_BEFORE(target, con, nodes);
159 } else if (position == AFTER) {
160 TAILQ_INSERT_AFTER(&(parent->nodes_head), target, con, nodes);
161 }
162
163 /* Pretend the con was just opened with regards to size percent values.
164 * Since the con is moved to a completely different con, the old value
165 * does not make sense anyways. */
166 con->percent = 0.0;
167 con_fix_percent(parent);
168
169 CALL(old_parent, on_remove_child);
170 }
171
172 /*
173 * This function detaches 'con' from its parent and puts it in the given
174 * workspace. Position is determined by the direction of movement into the
175 * workspace container.
176 *
177 */
178 static void attach_to_workspace(Con *con, Con *ws, direction_t direction) {
179 con_detach(con);
180 Con *old_parent = con->parent;
181 con->parent = ws;
182
183 if (direction == D_RIGHT || direction == D_DOWN) {
184 TAILQ_INSERT_HEAD(&(ws->nodes_head), con, nodes);
185 } else {
186 TAILQ_INSERT_TAIL(&(ws->nodes_head), con, nodes);
187 }
188 TAILQ_INSERT_TAIL(&(ws->focus_head), con, focused);
189
190 /* Pretend the con was just opened with regards to size percent values.
191 * Since the con is moved to a completely different con, the old value
192 * does not make sense anyways. */
193 con->percent = 0.0;
194 con_fix_percent(ws);
195
196 con_fix_percent(old_parent);
197 CALL(old_parent, on_remove_child);
198 }
199
200 /*
201 * Moves the given container to the closest output in the given direction if
202 * such an output exists.
203 *
204 */
205 static void move_to_output_directed(Con *con, direction_t direction) {
206 Output *current_output = get_output_for_con(con);
207 Output *output = get_output_next(direction, current_output, CLOSEST_OUTPUT);
208
209 if (!output) {
210 DLOG("No output in this direction found. Not moving.\n");
211 return;
212 }
213
214 Con *ws = NULL;
215 GREP_FIRST(ws, output_get_content(output->con), workspace_is_visible(child));
216
217 if (!ws) {
218 DLOG("No workspace on output in this direction found. Not moving.\n");
219 return;
220 }
221
222 Con *old_ws = con_get_workspace(con);
223 const bool moves_focus = (focused == con);
224 attach_to_workspace(con, ws, direction);
225 if (moves_focus) {
226 /* workspace_show will not correctly update the active workspace because
227 * the focused container, con, is now a child of ws. To work around this
228 * and still produce the correct workspace focus events (see
229 * 517-regress-move-direction-ipc.t) we need to temporarily set focused
230 * to the old workspace. */
231 focused = old_ws;
232 workspace_show(ws);
233 con_focus(con);
234 }
235
236 /* force re-painting the indicators */
237 FREE(con->deco_render_params);
238
239 ipc_send_window_event("move", con);
240 tree_flatten(croot);
241 ewmh_update_wm_desktop();
242 }
243
244 /*
245 * Moves the given container in the given direction
246 *
247 */
248 void tree_move(Con *con, direction_t direction) {
249 position_t position;
250 Con *target;
251
252 DLOG("Moving in direction %d\n", direction);
253
254 /* 1: get the first parent with the same orientation */
255
256 if (con->type == CT_WORKSPACE) {
257 DLOG("Not moving workspace\n");
258 return;
259 }
260
261 if (con->fullscreen_mode == CF_GLOBAL) {
262 DLOG("Not moving fullscreen global container\n");
263 return;
264 }
265
266 if ((con->fullscreen_mode == CF_OUTPUT) ||
267 (con->parent->type == CT_WORKSPACE && con_num_children(con->parent) == 1)) {
268 /* This is the only con on this workspace */
269 move_to_output_directed(con, direction);
270 return;
271 }
272
273 orientation_t o = orientation_from_direction(direction);
274
275 Con *same_orientation = con_parent_with_orientation(con, o);
276 /* The do {} while is used to 'restart' at this point with a different
277 * same_orientation, see the very last lines before the end of this block
278 * */
279 do {
280 /* There is no parent container with the same orientation */
281 if (!same_orientation) {
282 if (con_is_floating(con)) {
283 /* this is a floating con, we just disable floating */
284 floating_disable(con);
285 return;
286 }
287 if (con_inside_floating(con)) {
288 /* 'con' should be moved out of a floating container */
289 DLOG("Inside floating, moving to workspace\n");
290 attach_to_workspace(con, con_get_workspace(con), direction);
291 goto end;
292 }
293 DLOG("Force-changing orientation\n");
294 ws_force_orientation(con_get_workspace(con), o);
295 same_orientation = con_parent_with_orientation(con, o);
296 }
297
298 /* easy case: the move is within this container */
299 if (same_orientation == con->parent) {
300 Con *swap = (direction == D_LEFT || direction == D_UP)
301 ? TAILQ_PREV(con, nodes_head, nodes)
302 : TAILQ_NEXT(con, nodes);
303 if (swap) {
304 if (!con_is_leaf(swap)) {
305 DLOG("Moving into our bordering branch\n");
306 target = con_descend_direction(swap, direction);
307 position = (con_orientation(target->parent) != o ||
308 direction == D_UP ||
309 direction == D_LEFT
310 ? AFTER
311 : BEFORE);
312 insert_con_into(con, target, position);
313 goto end;
314 }
315
316 DLOG("Swapping with sibling.\n");
317 if (direction == D_LEFT || direction == D_UP) {
318 TAILQ_SWAP(swap, con, &(swap->parent->nodes_head), nodes);
319 } else {
320 TAILQ_SWAP(con, swap, &(swap->parent->nodes_head), nodes);
321 }
322
323 ipc_send_window_event("move", con);
324 return;
325 }
326
327 if (con->parent == con_get_workspace(con)) {
328 /* If we couldn't find a place to move it on this workspace, try
329 * to move it to a workspace on a different output */
330 move_to_output_directed(con, direction);
331 return;
332 }
333
334 /* If there was no con with which we could swap the current one,
335 * search again, but starting one level higher. */
336 same_orientation = con_parent_with_orientation(con->parent, o);
337 }
338 } while (same_orientation == NULL);
339
340 /* this time, we have to move to another container */
341 /* This is the container *above* 'con' (an ancestor of con) which is inside
342 * 'same_orientation' */
343 Con *above = con;
344 while (above->parent != same_orientation)
345 above = above->parent;
346
347 /* Enforce the fullscreen focus restrictions. */
348 if (!con_fullscreen_permits_focusing(above->parent)) {
349 LOG("Cannot move out of fullscreen container\n");
350 return;
351 }
352
353 DLOG("above = %p\n", above);
354
355 Con *next = (direction == D_UP || direction == D_LEFT ? TAILQ_PREV(above, nodes_head, nodes) : TAILQ_NEXT(above, nodes));
356
357 if (next && !con_is_leaf(next)) {
358 DLOG("Moving into the bordering branch of our adjacent container\n");
359 target = con_descend_direction(next, direction);
360 position = (con_orientation(target->parent) != o ||
361 direction == D_UP ||
362 direction == D_LEFT
363 ? AFTER
364 : BEFORE);
365 insert_con_into(con, target, position);
366 } else if (!next &&
367 con->parent->parent->type == CT_WORKSPACE &&
368 con->parent->layout != L_DEFAULT &&
369 con_num_children(con->parent) == 1) {
370 /* Con is the lone child of a non-default layout container at the edge
371 * of the workspace. Treat it as though the workspace is its parent
372 * and move it to the next output. */
373 DLOG("Grandparent is workspace\n");
374 move_to_output_directed(con, direction);
375 return;
376 } else {
377 DLOG("Moving into container above\n");
378 position = (direction == D_UP || direction == D_LEFT ? BEFORE : AFTER);
379 insert_con_into(con, above, position);
380 }
381
382 end:
383 /* force re-painting the indicators */
384 FREE(con->deco_render_params);
385
386 ipc_send_window_event("move", con);
387 tree_flatten(croot);
388 ewmh_update_wm_desktop();
389 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * output.c: Output (monitor) related functions.
7 *
8 */
9 #include "all.h"
10
11 /*
12 * Returns the content container below the given output container.
13 *
14 */
15 Con *output_get_content(Con *output) {
16 Con *child;
17
18 TAILQ_FOREACH (child, &(output->nodes_head), nodes) {
19 if (child->type == CT_CON) {
20 return child;
21 }
22 }
23
24 return NULL;
25 }
26
27 /*
28 * Returns an 'output' corresponding to one of left/right/down/up or a specific
29 * output name.
30 *
31 */
32 Output *get_output_from_string(Output *current_output, const char *output_str) {
33 if (strcasecmp(output_str, "current") == 0) {
34 return get_output_for_con(focused);
35 } else if (strcasecmp(output_str, "left") == 0) {
36 return get_output_next_wrap(D_LEFT, current_output);
37 } else if (strcasecmp(output_str, "right") == 0) {
38 return get_output_next_wrap(D_RIGHT, current_output);
39 } else if (strcasecmp(output_str, "up") == 0) {
40 return get_output_next_wrap(D_UP, current_output);
41 } else if (strcasecmp(output_str, "down") == 0) {
42 return get_output_next_wrap(D_DOWN, current_output);
43 }
44
45 return get_output_by_name(output_str, true);
46 }
47
48 /*
49 * Retrieves the primary name of an output.
50 *
51 */
52 char *output_primary_name(Output *output) {
53 return SLIST_FIRST(&output->names_head)->name;
54 }
55
56 Output *get_output_for_con(Con *con) {
57 Con *output_con = con_get_output(con);
58 Output *output = get_output_by_name(output_con->name, true);
59 assert(output != NULL);
60
61 return output;
62 }
63
64 /*
65 * Iterates over all outputs and pushes sticky windows to the currently visible
66 * workspace on that output.
67 *
68 * old_focus is used to determine if a sticky window is going to be focused.
69 * old_focus might be different than the currently focused container because the
70 * caller might need to temporarily change the focus and then call
71 * output_push_sticky_windows. For example, workspace_show needs to set focus to
72 * one of its descendants first, then call output_push_sticky_windows that
73 * should focus a sticky window if it was the focused in the previous workspace.
74 *
75 */
76 void output_push_sticky_windows(Con *old_focus) {
77 Con *output;
78 TAILQ_FOREACH (output, &(croot->focus_head), focused) {
79 Con *workspace, *visible_ws = NULL;
80 GREP_FIRST(visible_ws, output_get_content(output), workspace_is_visible(child));
81
82 /* We use this loop instead of TAILQ_FOREACH to avoid problems if the
83 * sticky window was the last window on that workspace as moving it in
84 * this case will close the workspace. */
85 for (workspace = TAILQ_FIRST(&(output_get_content(output)->focus_head));
86 workspace != TAILQ_END(&(output_get_content(output)->focus_head));) {
87 Con *current_ws = workspace;
88 workspace = TAILQ_NEXT(workspace, focused);
89
90 /* Since moving the windows actually removes them from the list of
91 * floating windows on this workspace, here too we need to use
92 * another loop than TAILQ_FOREACH. */
93 Con *child;
94 for (child = TAILQ_FIRST(&(current_ws->focus_head));
95 child != TAILQ_END(&(current_ws->focus_head));) {
96 Con *current = child;
97 child = TAILQ_NEXT(child, focused);
98 if (current->type != CT_FLOATING_CON || !con_is_sticky(current)) {
99 continue;
100 }
101
102 bool ignore_focus = (old_focus == NULL) || (current != old_focus->parent);
103 con_move_to_workspace(current, visible_ws, true, false, ignore_focus);
104 if (!ignore_focus) {
105 Con *current_ws = con_get_workspace(focused);
106 con_activate(con_descend_focused(current));
107 /* Pushing sticky windows shouldn't change the focused workspace. */
108 con_activate(con_descend_focused(current_ws));
109 }
110 }
111 }
112 }
113 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * For more information on RandR, please see the X.org RandR specification at
7 * https://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt
8 * (take your time to read it completely, it answers all questions).
9 *
10 */
11 #include "all.h"
12
13 #include <time.h>
14 #include <xcb/randr.h>
15
16 /* Pointer to the result of the query for primary output */
17 xcb_randr_get_output_primary_reply_t *primary;
18
19 /* Stores all outputs available in your current session. */
20 struct outputs_head outputs = TAILQ_HEAD_INITIALIZER(outputs);
21
22 /* This is the output covering the root window */
23 static Output *root_output;
24 static bool has_randr_1_5 = false;
25
26 /*
27 * Get a specific output by its internal X11 id. Used by randr_query_outputs
28 * to check if the output is new (only in the first scan) or if we are
29 * re-scanning.
30 *
31 */
32 static Output *get_output_by_id(xcb_randr_output_t id) {
33 Output *output;
34 TAILQ_FOREACH (output, &outputs, outputs) {
35 if (output->id == id) {
36 return output;
37 }
38 }
39
40 return NULL;
41 }
42
43 /*
44 * Returns the output with the given name or NULL.
45 * If require_active is true, only active outputs are considered.
46 *
47 */
48 Output *get_output_by_name(const char *name, const bool require_active) {
49 Output *output;
50 bool get_primary = (strcasecmp("primary", name) == 0);
51 TAILQ_FOREACH (output, &outputs, outputs) {
52 if (output->primary && get_primary) {
53 return output;
54 }
55 if (require_active && !output->active) {
56 continue;
57 }
58 struct output_name *output_name;
59 SLIST_FOREACH (output_name, &output->names_head, names) {
60 if (strcasecmp(output_name->name, name) == 0) {
61 return output;
62 }
63 }
64 }
65
66 return NULL;
67 }
68
69 /*
70 * Returns the first output which is active.
71 *
72 */
73 Output *get_first_output(void) {
74 Output *output, *result = NULL;
75
76 TAILQ_FOREACH (output, &outputs, outputs) {
77 if (output->active) {
78 if (output->primary) {
79 return output;
80 }
81 if (!result) {
82 result = output;
83 }
84 }
85 }
86
87 if (result) {
88 return result;
89 }
90
91 die("No usable outputs available.\n");
92 }
93
94 /*
95 * Check whether there are any active outputs (excluding the root output).
96 *
97 */
98 static bool any_randr_output_active(void) {
99 Output *output;
100
101 TAILQ_FOREACH (output, &outputs, outputs) {
102 if (output != root_output && !output->to_be_disabled && output->active)
103 return true;
104 }
105
106 return false;
107 }
108
109 /*
110 * Returns the active (!) output which contains the coordinates x, y or NULL
111 * if there is no output which contains these coordinates.
112 *
113 */
114 Output *get_output_containing(unsigned int x, unsigned int y) {
115 Output *output;
116 TAILQ_FOREACH (output, &outputs, outputs) {
117 if (!output->active)
118 continue;
119 DLOG("comparing x=%d y=%d with x=%d and y=%d width %d height %d\n",
120 x, y, output->rect.x, output->rect.y, output->rect.width, output->rect.height);
121 if (x >= output->rect.x && x < (output->rect.x + output->rect.width) &&
122 y >= output->rect.y && y < (output->rect.y + output->rect.height))
123 return output;
124 }
125
126 return NULL;
127 }
128
129 /*
130 * Returns the active output which contains the midpoint of the given rect. If
131 * such an output doesn't exist, returns the output which contains most of the
132 * rectangle or NULL if there is no output which intersects with it.
133 *
134 */
135 Output *get_output_from_rect(Rect rect) {
136 unsigned int mid_x = rect.x + rect.width / 2;
137 unsigned int mid_y = rect.y + rect.height / 2;
138 Output *output = get_output_containing(mid_x, mid_y);
139
140 return output ? output : output_containing_rect(rect);
141 }
142
143 /*
144 * Returns the active output which spans exactly the area specified by
145 * rect or NULL if there is no output like this.
146 *
147 */
148 Output *get_output_with_dimensions(Rect rect) {
149 Output *output;
150 TAILQ_FOREACH (output, &outputs, outputs) {
151 if (!output->active)
152 continue;
153 DLOG("comparing x=%d y=%d %dx%d with x=%d and y=%d %dx%d\n",
154 rect.x, rect.y, rect.width, rect.height,
155 output->rect.x, output->rect.y, output->rect.width, output->rect.height);
156 if (rect.x == output->rect.x && rect.width == output->rect.width &&
157 rect.y == output->rect.y && rect.height == output->rect.height)
158 return output;
159 }
160
161 return NULL;
162 }
163
164 /*
165 * In output_containing_rect, we check if any active output contains part of the container.
166 * We do this by checking if the output rect is intersected by the Rect.
167 * This is the 2-dimensional counterpart of get_output_containing.
168 * Returns the output with the maximum intersecting area.
169 *
170 */
171 Output *output_containing_rect(Rect rect) {
172 Output *output;
173 int lx = rect.x, uy = rect.y;
174 int rx = rect.x + rect.width, by = rect.y + rect.height;
175 long max_area = 0;
176 Output *result = NULL;
177 TAILQ_FOREACH (output, &outputs, outputs) {
178 if (!output->active)
179 continue;
180 int lx_o = (int)output->rect.x, uy_o = (int)output->rect.y;
181 int rx_o = (int)(output->rect.x + output->rect.width), by_o = (int)(output->rect.y + output->rect.height);
182 DLOG("comparing x=%d y=%d with x=%d and y=%d width %d height %d\n",
183 rect.x, rect.y, output->rect.x, output->rect.y, output->rect.width, output->rect.height);
184 int left = max(lx, lx_o);
185 int right = min(rx, rx_o);
186 int bottom = min(by, by_o);
187 int top = max(uy, uy_o);
188 if (left < right && bottom > top) {
189 long area = (right - left) * (bottom - top);
190 if (area > max_area) {
191 result = output;
192 }
193 }
194 }
195 return result;
196 }
197
198 /*
199 * Like get_output_next with close_far == CLOSEST_OUTPUT, but wraps.
200 *
201 * For example if get_output_next(D_DOWN, x, FARTHEST_OUTPUT) = NULL, then
202 * get_output_next_wrap(D_DOWN, x) will return the topmost output.
203 *
204 * This function always returns a output: if no active outputs can be found,
205 * current itself is returned.
206 *
207 */
208 Output *get_output_next_wrap(direction_t direction, Output *current) {
209 Output *best = get_output_next(direction, current, CLOSEST_OUTPUT);
210 /* If no output can be found, wrap */
211 if (!best) {
212 direction_t opposite;
213 if (direction == D_RIGHT)
214 opposite = D_LEFT;
215 else if (direction == D_LEFT)
216 opposite = D_RIGHT;
217 else if (direction == D_DOWN)
218 opposite = D_UP;
219 else
220 opposite = D_DOWN;
221 best = get_output_next(opposite, current, FARTHEST_OUTPUT);
222 }
223 if (!best)
224 best = current;
225 DLOG("current = %s, best = %s\n", output_primary_name(current), output_primary_name(best));
226 return best;
227 }
228
229 /*
230 * Gets the output which is the next one in the given direction.
231 *
232 * If close_far == CLOSEST_OUTPUT, then the output next to the current one will
233 * selected. If close_far == FARTHEST_OUTPUT, the output which is the last one
234 * in the given direction will be selected.
235 *
236 * NULL will be returned when no active outputs are present in the direction
237 * specified (note that “current” counts as such an output).
238 *
239 */
240 Output *get_output_next(direction_t direction, Output *current, output_close_far_t close_far) {
241 Rect *cur = &(current->rect),
242 *other;
243 Output *output,
244 *best = NULL;
245 TAILQ_FOREACH (output, &outputs, outputs) {
246 if (!output->active)
247 continue;
248
249 other = &(output->rect);
250
251 if ((direction == D_RIGHT && other->x > cur->x) ||
252 (direction == D_LEFT && other->x < cur->x)) {
253 /* Skip the output when it doesn’t overlap the other one’s y
254 * coordinate at all. */
255 if ((other->y + other->height) <= cur->y ||
256 (cur->y + cur->height) <= other->y)
257 continue;
258 } else if ((direction == D_DOWN && other->y > cur->y) ||
259 (direction == D_UP && other->y < cur->y)) {
260 /* Skip the output when it doesn’t overlap the other one’s x
261 * coordinate at all. */
262 if ((other->x + other->width) <= cur->x ||
263 (cur->x + cur->width) <= other->x)
264 continue;
265 } else
266 continue;
267
268 /* No candidate yet? Start with this one. */
269 if (!best) {
270 best = output;
271 continue;
272 }
273
274 if (close_far == CLOSEST_OUTPUT) {
275 /* Is this output better (closer to the current output) than our
276 * current best bet? */
277 if ((direction == D_RIGHT && other->x < best->rect.x) ||
278 (direction == D_LEFT && other->x > best->rect.x) ||
279 (direction == D_DOWN && other->y < best->rect.y) ||
280 (direction == D_UP && other->y > best->rect.y)) {
281 best = output;
282 continue;
283 }
284 } else {
285 /* Is this output better (farther to the current output) than our
286 * current best bet? */
287 if ((direction == D_RIGHT && other->x > best->rect.x) ||
288 (direction == D_LEFT && other->x < best->rect.x) ||
289 (direction == D_DOWN && other->y > best->rect.y) ||
290 (direction == D_UP && other->y < best->rect.y)) {
291 best = output;
292 continue;
293 }
294 }
295 }
296
297 DLOG("current = %s, best = %s\n", output_primary_name(current), (best ? output_primary_name(best) : "NULL"));
298 return best;
299 }
300
301 /*
302 * Creates an output covering the root window.
303 *
304 */
305 Output *create_root_output(xcb_connection_t *conn) {
306 Output *s = scalloc(1, sizeof(Output));
307
308 s->active = false;
309 s->rect.x = 0;
310 s->rect.y = 0;
311 s->rect.width = root_screen->width_in_pixels;
312 s->rect.height = root_screen->height_in_pixels;
313
314 struct output_name *output_name = scalloc(1, sizeof(struct output_name));
315 output_name->name = "xroot-0";
316 SLIST_INIT(&s->names_head);
317 SLIST_INSERT_HEAD(&s->names_head, output_name, names);
318
319 return s;
320 }
321
322 /*
323 * Initializes a CT_OUTPUT Con (searches existing ones from inplace restart
324 * before) to use for the given Output.
325 *
326 */
327 void output_init_con(Output *output) {
328 Con *con = NULL, *current;
329 bool reused = false;
330
331 DLOG("init_con for output %s\n", output_primary_name(output));
332
333 /* Search for a Con with that name directly below the root node. There
334 * might be one from a restored layout. */
335 TAILQ_FOREACH (current, &(croot->nodes_head), nodes) {
336 if (strcmp(current->name, output_primary_name(output)) != 0)
337 continue;
338
339 con = current;
340 reused = true;
341 DLOG("Using existing con %p / %s\n", con, con->name);
342 break;
343 }
344
345 if (con == NULL) {
346 con = con_new(croot, NULL);
347 FREE(con->name);
348 con->name = sstrdup(output_primary_name(output));
349 con->type = CT_OUTPUT;
350 con->layout = L_OUTPUT;
351 con_fix_percent(croot);
352 }
353 con->rect = output->rect;
354 output->con = con;
355
356 char *name;
357 sasprintf(&name, "[i3 con] output %s", con->name);
358 x_set_name(con, name);
359 FREE(name);
360
361 if (reused) {
362 DLOG("Not adding workspace, this was a reused con\n");
363 return;
364 }
365
366 DLOG("Changing layout, adding top/bottom dockarea\n");
367 Con *topdock = con_new(NULL, NULL);
368 topdock->type = CT_DOCKAREA;
369 topdock->layout = L_DOCKAREA;
370 /* this container swallows dock clients */
371 Match *match = scalloc(1, sizeof(Match));
372 match_init(match);
373 match->dock = M_DOCK_TOP;
374 match->insert_where = M_BELOW;
375 TAILQ_INSERT_TAIL(&(topdock->swallow_head), match, matches);
376
377 FREE(topdock->name);
378 topdock->name = sstrdup("topdock");
379
380 sasprintf(&name, "[i3 con] top dockarea %s", con->name);
381 x_set_name(topdock, name);
382 FREE(name);
383 DLOG("attaching\n");
384 con_attach(topdock, con, false);
385
386 /* content container */
387
388 DLOG("adding main content container\n");
389 Con *content = con_new(NULL, NULL);
390 content->type = CT_CON;
391 content->layout = L_SPLITH;
392 FREE(content->name);
393 content->name = sstrdup("content");
394
395 sasprintf(&name, "[i3 con] content %s", con->name);
396 x_set_name(content, name);
397 FREE(name);
398 con_attach(content, con, false);
399
400 /* bottom dock container */
401 Con *bottomdock = con_new(NULL, NULL);
402 bottomdock->type = CT_DOCKAREA;
403 bottomdock->layout = L_DOCKAREA;
404 /* this container swallows dock clients */
405 match = scalloc(1, sizeof(Match));
406 match_init(match);
407 match->dock = M_DOCK_BOTTOM;
408 match->insert_where = M_BELOW;
409 TAILQ_INSERT_TAIL(&(bottomdock->swallow_head), match, matches);
410
411 FREE(bottomdock->name);
412 bottomdock->name = sstrdup("bottomdock");
413
414 sasprintf(&name, "[i3 con] bottom dockarea %s", con->name);
415 x_set_name(bottomdock, name);
416 FREE(name);
417 DLOG("attaching\n");
418 con_attach(bottomdock, con, false);
419
420 /* Change focus to the content container */
421 TAILQ_REMOVE(&(con->focus_head), content, focused);
422 TAILQ_INSERT_HEAD(&(con->focus_head), content, focused);
423 }
424
425 /*
426 * Initializes at least one workspace for this output, trying the following
427 * steps until there is at least one workspace:
428 *
429 * • Move existing workspaces, which are assigned to be on the given output, to
430 * the output.
431 * • Create the first assigned workspace for this output.
432 * • Create the first unused workspace.
433 *
434 */
435 void init_ws_for_output(Output *output) {
436 Con *content = output_get_content(output->con);
437 Con *previous_focus = con_get_workspace(focused);
438
439 /* go through all assignments and move the existing workspaces to this output */
440 struct Workspace_Assignment *assignment;
441 TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) {
442 if (!output_triggers_assignment(output, assignment)) {
443 continue;
444 }
445 Con *workspace = get_existing_workspace_by_name(assignment->name);
446 if (workspace == NULL)
447 continue;
448
449 /* check that this workspace is not already attached (that means the
450 * user configured this assignment twice) */
451 Con *workspace_out = con_get_output(workspace);
452 if (workspace_out == output->con) {
453 LOG("Workspace \"%s\" assigned to output \"%s\", but it is already "
454 "there. Do you have two assignment directives for the same "
455 "workspace in your configuration file?\n",
456 workspace->name, output_primary_name(output));
457 continue;
458 }
459
460 DLOG("Moving workspace \"%s\" from output \"%s\" to \"%s\" due to assignment\n",
461 workspace->name, workspace_out->name, output_primary_name(output));
462 /* Need to copy output's rect since content is not yet rendered. We
463 * can't call render_con here because render_output only proceeds if a
464 * workspace exists. */
465 content->rect = output->con->rect;
466 workspace_move_to_output(workspace, output);
467 }
468
469 /* Temporarily set the focused container, might not be initialized yet. */
470 focused = content;
471
472 /* if a workspace exists, we are done now */
473 if (!TAILQ_EMPTY(&(content->nodes_head))) {
474 /* ensure that one of the workspaces is actually visible (in fullscreen
475 * mode), if they were invisible before, this might not be the case. */
476 Con *visible = NULL;
477 GREP_FIRST(visible, content, child->fullscreen_mode == CF_OUTPUT);
478 if (!visible) {
479 visible = TAILQ_FIRST(&(content->nodes_head));
480 workspace_show(visible);
481 }
482 goto restore_focus;
483 }
484
485 /* otherwise, we create the first assigned ws for this output */
486 TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) {
487 if (!output_triggers_assignment(output, assignment)) {
488 continue;
489 }
490
491 LOG("Initializing first assigned workspace \"%s\" for output \"%s\"\n",
492 assignment->name, assignment->output);
493 workspace_show_by_name(assignment->name);
494 goto restore_focus;
495 }
496
497 /* if there is still no workspace, we create the first free workspace */
498 DLOG("Now adding a workspace\n");
499 workspace_show(create_workspace_on_output(output, content));
500
501 restore_focus:
502 if (previous_focus) {
503 workspace_show(previous_focus);
504 }
505 }
506
507 /*
508 * This function needs to be called when changing the mode of an output when
509 * it already has some workspaces (or a bar window) assigned.
510 *
511 * It reconfigures the bar window for the new mode, copies the new rect into
512 * each workspace on this output and forces all windows on the affected
513 * workspaces to be reconfigured.
514 *
515 * It is necessary to call render_layout() afterwards.
516 *
517 */
518 static void output_change_mode(xcb_connection_t *conn, Output *output) {
519 DLOG("Output mode changed, updating rect\n");
520 assert(output->con != NULL);
521 output->con->rect = output->rect;
522
523 Con *content, *workspace, *child;
524
525 /* Point content to the container of the workspaces */
526 content = output_get_content(output->con);
527
528 /* Fix the position of all floating windows on this output.
529 * The 'rect' of each workspace will be updated in src/render.c. */
530 TAILQ_FOREACH (workspace, &(content->nodes_head), nodes) {
531 TAILQ_FOREACH (child, &(workspace->floating_head), floating_windows) {
532 floating_fix_coordinates(child, &(workspace->rect), &(output->con->rect));
533 }
534 }
535
536 /* If default_orientation is NO_ORIENTATION, we change the orientation of
537 * the workspaces and their children depending on output resolution. This is
538 * only done for workspaces with maximum one child. */
539 if (config.default_orientation == NO_ORIENTATION) {
540 TAILQ_FOREACH (workspace, &(content->nodes_head), nodes) {
541 /* Workspaces with more than one child are left untouched because
542 * we do not want to change an existing layout. */
543 if (con_num_children(workspace) > 1)
544 continue;
545
546 workspace->layout = (output->rect.height > output->rect.width) ? L_SPLITV : L_SPLITH;
547 DLOG("Setting workspace [%d,%s]'s layout to %d.\n", workspace->num, workspace->name, workspace->layout);
548 if ((child = TAILQ_FIRST(&(workspace->nodes_head)))) {
549 if (child->layout == L_SPLITV || child->layout == L_SPLITH)
550 child->layout = workspace->layout;
551 DLOG("Setting child [%d,%s]'s layout to %d.\n", child->num, child->name, child->layout);
552 }
553 }
554 }
555 }
556
557 /*
558 * randr_query_outputs_15 uses RandR ≥ 1.5 to update outputs.
559 *
560 */
561 static bool randr_query_outputs_15(void) {
562 #if XCB_RANDR_MINOR_VERSION < 5
563 return false;
564 #else
565 /* RandR 1.5 available at compile-time, i.e. libxcb is new enough */
566 if (!has_randr_1_5) {
567 return false;
568 }
569 /* RandR 1.5 available at run-time (supported by the server and not
570 * disabled by the user) */
571 DLOG("Querying outputs using RandR 1.5\n");
572 xcb_generic_error_t *err;
573 xcb_randr_get_monitors_reply_t *monitors =
574 xcb_randr_get_monitors_reply(
575 conn, xcb_randr_get_monitors(conn, root, true), &err);
576 if (err != NULL) {
577 ELOG("Could not get RandR monitors: X11 error code %d\n", err->error_code);
578 free(err);
579 /* Fall back to RandR ≤ 1.4 */
580 return false;
581 }
582
583 /* Mark all outputs as to_be_disabled, since xcb_randr_get_monitors() will
584 * only return active outputs. */
585 Output *output;
586 TAILQ_FOREACH (output, &outputs, outputs) {
587 if (output != root_output) {
588 output->to_be_disabled = true;
589 }
590 }
591
592 DLOG("%d RandR monitors found (timestamp %d)\n",
593 xcb_randr_get_monitors_monitors_length(monitors),
594 monitors->timestamp);
595
596 xcb_randr_monitor_info_iterator_t iter;
597 for (iter = xcb_randr_get_monitors_monitors_iterator(monitors);
598 iter.rem;
599 xcb_randr_monitor_info_next(&iter)) {
600 const xcb_randr_monitor_info_t *monitor_info = iter.data;
601 xcb_get_atom_name_reply_t *atom_reply =
602 xcb_get_atom_name_reply(
603 conn, xcb_get_atom_name(conn, monitor_info->name), &err);
604 if (err != NULL) {
605 ELOG("Could not get RandR monitor name: X11 error code %d\n", err->error_code);
606 free(err);
607 continue;
608 }
609 char *name;
610 sasprintf(&name, "%.*s",
611 xcb_get_atom_name_name_length(atom_reply),
612 xcb_get_atom_name_name(atom_reply));
613 free(atom_reply);
614
615 Output *new = get_output_by_name(name, false);
616 if (new == NULL) {
617 new = scalloc(1, sizeof(Output));
618
619 SLIST_INIT(&new->names_head);
620
621 /* Register associated output names in addition to the monitor name */
622 xcb_randr_output_t *randr_outputs = xcb_randr_monitor_info_outputs(monitor_info);
623 int randr_output_len = xcb_randr_monitor_info_outputs_length(monitor_info);
624 for (int i = 0; i < randr_output_len; i++) {
625 xcb_randr_output_t randr_output = randr_outputs[i];
626
627 xcb_randr_get_output_info_reply_t *info =
628 xcb_randr_get_output_info_reply(conn,
629 xcb_randr_get_output_info(conn, randr_output, monitors->timestamp),
630 NULL);
631
632 if (info != NULL && info->crtc != XCB_NONE) {
633 char *oname;
634 sasprintf(&oname, "%.*s",
635 xcb_randr_get_output_info_name_length(info),
636 xcb_randr_get_output_info_name(info));
637
638 if (strcmp(name, oname) != 0) {
639 struct output_name *output_name = scalloc(1, sizeof(struct output_name));
640 output_name->name = sstrdup(oname);
641 SLIST_INSERT_HEAD(&new->names_head, output_name, names);
642 } else {
643 free(oname);
644 }
645 }
646 FREE(info);
647 }
648
649 /* Insert the monitor name last, so that it's used as the primary name */
650 struct output_name *output_name = scalloc(1, sizeof(struct output_name));
651 output_name->name = sstrdup(name);
652 SLIST_INSERT_HEAD(&new->names_head, output_name, names);
653
654 if (monitor_info->primary) {
655 TAILQ_INSERT_HEAD(&outputs, new, outputs);
656 } else {
657 TAILQ_INSERT_TAIL(&outputs, new, outputs);
658 }
659 }
660 /* We specified get_active == true in xcb_randr_get_monitors(), so we
661 * will only receive active outputs. */
662 new->active = true;
663 new->to_be_disabled = false;
664
665 new->primary = monitor_info->primary;
666
667 new->changed =
668 update_if_necessary(&(new->rect.x), monitor_info->x) |
669 update_if_necessary(&(new->rect.y), monitor_info->y) |
670 update_if_necessary(&(new->rect.width), monitor_info->width) |
671 update_if_necessary(&(new->rect.height), monitor_info->height);
672
673 DLOG("name %s, x %d, y %d, width %d px, height %d px, width %d mm, height %d mm, primary %d, automatic %d\n",
674 name,
675 monitor_info->x, monitor_info->y, monitor_info->width, monitor_info->height,
676 monitor_info->width_in_millimeters, monitor_info->height_in_millimeters,
677 monitor_info->primary, monitor_info->automatic);
678 free(name);
679 }
680 free(monitors);
681 return true;
682 #endif
683 }
684
685 /*
686 * Gets called by randr_query_outputs_14() for each output. The function adds
687 * new outputs to the list of outputs, checks if the mode of existing outputs
688 * has been changed or if an existing output has been disabled. It will then
689 * change either the "changed" or the "to_be_deleted" flag of the output, if
690 * appropriate.
691 *
692 */
693 static void handle_output(xcb_connection_t *conn, xcb_randr_output_t id,
694 xcb_randr_get_output_info_reply_t *output,
695 xcb_timestamp_t cts,
696 xcb_randr_get_screen_resources_current_reply_t *res) {
697 /* each CRT controller has a position in which we are interested in */
698 xcb_randr_get_crtc_info_reply_t *crtc;
699
700 Output *new = get_output_by_id(id);
701 bool existing = (new != NULL);
702 if (!existing) {
703 new = scalloc(1, sizeof(Output));
704 SLIST_INIT(&new->names_head);
705 }
706 new->id = id;
707 new->primary = (primary && primary->output == id);
708 while (!SLIST_EMPTY(&new->names_head)) {
709 FREE(SLIST_FIRST(&new->names_head)->name);
710 struct output_name *old_head = SLIST_FIRST(&new->names_head);
711 SLIST_REMOVE_HEAD(&new->names_head, names);
712 FREE(old_head);
713 }
714 struct output_name *output_name = scalloc(1, sizeof(struct output_name));
715 sasprintf(&output_name->name, "%.*s",
716 xcb_randr_get_output_info_name_length(output),
717 xcb_randr_get_output_info_name(output));
718 SLIST_INSERT_HEAD(&new->names_head, output_name, names);
719
720 DLOG("found output with name %s\n", output_primary_name(new));
721
722 /* Even if no CRTC is used at the moment, we store the output so that
723 * we do not need to change the list ever again (we only update the
724 * position/size) */
725 if (output->crtc == XCB_NONE) {
726 if (!existing) {
727 if (new->primary)
728 TAILQ_INSERT_HEAD(&outputs, new, outputs);
729 else
730 TAILQ_INSERT_TAIL(&outputs, new, outputs);
731 } else if (new->active)
732 new->to_be_disabled = true;
733 return;
734 }
735
736 xcb_randr_get_crtc_info_cookie_t icookie;
737 icookie = xcb_randr_get_crtc_info(conn, output->crtc, cts);
738 if ((crtc = xcb_randr_get_crtc_info_reply(conn, icookie, NULL)) == NULL) {
739 DLOG("Skipping output %s: could not get CRTC (%p)\n",
740 output_primary_name(new), crtc);
741 free(new);
742 return;
743 }
744
745 bool updated = update_if_necessary(&(new->rect.x), crtc->x) |
746 update_if_necessary(&(new->rect.y), crtc->y) |
747 update_if_necessary(&(new->rect.width), crtc->width) |
748 update_if_necessary(&(new->rect.height), crtc->height);
749 free(crtc);
750 new->active = (new->rect.width != 0 && new->rect.height != 0);
751 if (!new->active) {
752 DLOG("width/height 0/0, disabling output\n");
753 return;
754 }
755
756 DLOG("mode: %dx%d+%d+%d\n", new->rect.width, new->rect.height,
757 new->rect.x, new->rect.y);
758
759 /* If we don’t need to change an existing output or if the output
760 * does not exist in the first place, the case is simple: we either
761 * need to insert the new output or we are done. */
762 if (!updated || !existing) {
763 if (!existing) {
764 if (new->primary)
765 TAILQ_INSERT_HEAD(&outputs, new, outputs);
766 else
767 TAILQ_INSERT_TAIL(&outputs, new, outputs);
768 }
769 return;
770 }
771
772 new->changed = true;
773 }
774
775 /*
776 * randr_query_outputs_14 uses RandR ≤ 1.4 to update outputs.
777 *
778 */
779 static void randr_query_outputs_14(void) {
780 DLOG("Querying outputs using RandR ≤ 1.4\n");
781
782 /* Get screen resources (primary output, crtcs, outputs, modes) */
783 xcb_randr_get_screen_resources_current_cookie_t rcookie;
784 rcookie = xcb_randr_get_screen_resources_current(conn, root);
785 xcb_randr_get_output_primary_cookie_t pcookie;
786 pcookie = xcb_randr_get_output_primary(conn, root);
787
788 if ((primary = xcb_randr_get_output_primary_reply(conn, pcookie, NULL)) == NULL)
789 ELOG("Could not get RandR primary output\n");
790 else
791 DLOG("primary output is %08x\n", primary->output);
792
793 xcb_randr_get_screen_resources_current_reply_t *res =
794 xcb_randr_get_screen_resources_current_reply(conn, rcookie, NULL);
795 if (res == NULL) {
796 ELOG("Could not query screen resources.\n");
797 return;
798 }
799
800 /* timestamp of the configuration so that we get consistent replies to all
801 * requests (if the configuration changes between our different calls) */
802 const xcb_timestamp_t cts = res->config_timestamp;
803
804 const int len = xcb_randr_get_screen_resources_current_outputs_length(res);
805
806 /* an output is VGA-1, LVDS-1, etc. (usually physical video outputs) */
807 xcb_randr_output_t *randr_outputs = xcb_randr_get_screen_resources_current_outputs(res);
808
809 /* Request information for each output */
810 xcb_randr_get_output_info_cookie_t ocookie[len];
811 for (int i = 0; i < len; i++)
812 ocookie[i] = xcb_randr_get_output_info(conn, randr_outputs[i], cts);
813
814 /* Loop through all outputs available for this X11 screen */
815 for (int i = 0; i < len; i++) {
816 xcb_randr_get_output_info_reply_t *output;
817
818 if ((output = xcb_randr_get_output_info_reply(conn, ocookie[i], NULL)) == NULL)
819 continue;
820
821 handle_output(conn, randr_outputs[i], output, cts, res);
822 free(output);
823 }
824
825 FREE(res);
826 }
827
828 /*
829 * Move the content of an outputs container to the first output.
830 *
831 * TODO: Maybe use an on_destroy callback which is implement differently for
832 * different container types (CT_CONTENT vs. CT_DOCKAREA)?
833 *
834 */
835 static void move_content(Con *con) {
836 Con *first = get_first_output()->con;
837 Con *first_content = output_get_content(first);
838
839 /* We need to move the workspaces from the disappearing output to the first output */
840 /* 1: Get the con to focus next */
841 Con *next = focused;
842
843 /* 2: iterate through workspaces and re-assign them, fixing the coordinates
844 * of floating containers as we go */
845 Con *current;
846 Con *old_content = output_get_content(con);
847 while (!TAILQ_EMPTY(&(old_content->nodes_head))) {
848 current = TAILQ_FIRST(&(old_content->nodes_head));
849 if (current != next && TAILQ_EMPTY(&(current->focus_head))) {
850 /* the workspace is empty and not focused, get rid of it */
851 DLOG("Getting rid of current = %p / %s (empty, unfocused)\n", current, current->name);
852 tree_close_internal(current, DONT_KILL_WINDOW, false);
853 continue;
854 }
855 DLOG("Detaching current = %p / %s\n", current, current->name);
856 con_detach(current);
857 DLOG("Re-attaching current = %p / %s\n", current, current->name);
858 con_attach(current, first_content, false);
859 DLOG("Fixing the coordinates of floating containers\n");
860 Con *floating_con;
861 TAILQ_FOREACH (floating_con, &(current->floating_head), floating_windows) {
862 floating_fix_coordinates(floating_con, &(con->rect), &(first->rect));
863 }
864 }
865
866 /* Restore focus after con_detach / con_attach. next can be NULL, see #3523. */
867 if (next) {
868 DLOG("now focusing next = %p\n", next);
869 con_focus(next);
870 workspace_show(con_get_workspace(next));
871 }
872
873 /* 3: move the dock clients to the first output */
874 Con *child;
875 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
876 if (child->type != CT_DOCKAREA) {
877 continue;
878 }
879 DLOG("Handling dock con %p\n", child);
880 Con *dock;
881 while (!TAILQ_EMPTY(&(child->nodes_head))) {
882 dock = TAILQ_FIRST(&(child->nodes_head));
883 Con *nc;
884 Match *match;
885 nc = con_for_window(first, dock->window, &match);
886 DLOG("Moving dock client %p to nc %p\n", dock, nc);
887 con_detach(dock);
888 DLOG("Re-attaching\n");
889 con_attach(dock, nc, false);
890 DLOG("Done\n");
891 }
892 }
893
894 DLOG("Destroying disappearing con %p\n", con);
895 tree_close_internal(con, DONT_KILL_WINDOW, true);
896 }
897
898 /*
899 * (Re-)queries the outputs via RandR and stores them in the list of outputs.
900 *
901 * If no outputs are found use the root window.
902 *
903 */
904 void randr_query_outputs(void) {
905 Output *output, *other;
906
907 if (!randr_query_outputs_15()) {
908 randr_query_outputs_14();
909 }
910
911 /* If there's no randr output, enable the output covering the root window. */
912 if (any_randr_output_active()) {
913 DLOG("Active RandR output found. Disabling root output.\n");
914 if (root_output && root_output->active) {
915 root_output->to_be_disabled = true;
916 }
917 } else {
918 DLOG("No active RandR output found. Enabling root output.\n");
919 root_output->active = true;
920 }
921
922 /* Check for clones, disable the clones and reduce the mode to the
923 * lowest common mode */
924 TAILQ_FOREACH (output, &outputs, outputs) {
925 if (!output->active || output->to_be_disabled)
926 continue;
927 DLOG("output %p / %s, position (%d, %d), checking for clones\n",
928 output, output_primary_name(output), output->rect.x, output->rect.y);
929
930 for (other = output;
931 other != TAILQ_END(&outputs);
932 other = TAILQ_NEXT(other, outputs)) {
933 if (other == output || !other->active || other->to_be_disabled)
934 continue;
935
936 if (other->rect.x != output->rect.x ||
937 other->rect.y != output->rect.y)
938 continue;
939
940 DLOG("output %p has the same position, its mode = %d x %d\n",
941 other, other->rect.width, other->rect.height);
942 uint32_t width = min(other->rect.width, output->rect.width);
943 uint32_t height = min(other->rect.height, output->rect.height);
944
945 if (update_if_necessary(&(output->rect.width), width) |
946 update_if_necessary(&(output->rect.height), height))
947 output->changed = true;
948
949 update_if_necessary(&(other->rect.width), width);
950 update_if_necessary(&(other->rect.height), height);
951
952 DLOG("disabling output %p (%s)\n", other, output_primary_name(other));
953 other->to_be_disabled = true;
954
955 DLOG("new output mode %d x %d, other mode %d x %d\n",
956 output->rect.width, output->rect.height,
957 other->rect.width, other->rect.height);
958 }
959 }
960
961 /* Ensure that all outputs which are active also have a con. This is
962 * necessary because in the next step, a clone might get disabled. Example:
963 * LVDS1 active, VGA1 gets activated as a clone of LVDS1 (has no con).
964 * LVDS1 gets disabled. */
965 TAILQ_FOREACH (output, &outputs, outputs) {
966 if (output->active && output->con == NULL) {
967 DLOG("Need to initialize a Con for output %s\n", output_primary_name(output));
968 output_init_con(output);
969 output->changed = false;
970 }
971 }
972
973 /* Ensure that all containers with type CT_OUTPUT have a valid
974 * corresponding entry in outputs. This can happen in situations related to
975 * those mentioned #3767 e.g. when a CT_OUTPUT is created from an in-place
976 * restart's layout but the output is disabled by a randr query happening
977 * at the same time. */
978 Con *con;
979 for (con = TAILQ_FIRST(&(croot->nodes_head)); con;) {
980 Con *next = TAILQ_NEXT(con, nodes);
981 if (!con_is_internal(con) && get_output_by_name(con->name, true) == NULL) {
982 DLOG("No output %s found, moving its old content to first output\n", con->name);
983 move_content(con);
984 }
985 con = next;
986 }
987
988 /* Handle outputs which have a new mode or are disabled now (either
989 * because the user disabled them or because they are clones) */
990 TAILQ_FOREACH (output, &outputs, outputs) {
991 if (output->to_be_disabled) {
992 randr_disable_output(output);
993 }
994
995 if (output->changed) {
996 output_change_mode(conn, output);
997 output->changed = false;
998 }
999 }
1000
1001 /* Just go through each active output and assign one workspace */
1002 TAILQ_FOREACH (output, &outputs, outputs) {
1003 if (!output->active)
1004 continue;
1005 Con *content = output_get_content(output->con);
1006 if (!TAILQ_EMPTY(&(content->nodes_head)))
1007 continue;
1008 DLOG("Should add ws for output %s\n", output_primary_name(output));
1009 init_ws_for_output(output);
1010 }
1011
1012 /* Focus the primary screen, if possible */
1013 TAILQ_FOREACH (output, &outputs, outputs) {
1014 if (!output->primary || !output->con)
1015 continue;
1016
1017 DLOG("Focusing primary output %s\n", output_primary_name(output));
1018 Con *content = output_get_content(output->con);
1019 Con *ws = TAILQ_FIRST(&(content)->focus_head);
1020 workspace_show(ws);
1021 }
1022
1023 /* render_layout flushes */
1024 tree_render();
1025
1026 FREE(primary);
1027 }
1028
1029 /*
1030 * Disables the output and moves its content.
1031 *
1032 */
1033 void randr_disable_output(Output *output) {
1034 assert(output->to_be_disabled);
1035
1036 output->active = false;
1037 DLOG("Output %s disabled, re-assigning workspaces/docks\n", output_primary_name(output));
1038
1039 if (output->con != NULL) {
1040 /* clear the pointer before move_content calls tree_close_internal in which the memory is freed */
1041 Con *con = output->con;
1042 output->con = NULL;
1043 move_content(con);
1044 }
1045
1046 output->to_be_disabled = false;
1047 output->changed = false;
1048 }
1049
1050 static void fallback_to_root_output(void) {
1051 root_output->active = true;
1052 output_init_con(root_output);
1053 init_ws_for_output(root_output);
1054 }
1055
1056 /*
1057 * We have just established a connection to the X server and need the initial
1058 * XRandR information to setup workspaces for each screen.
1059 *
1060 */
1061 void randr_init(int *event_base, const bool disable_randr15) {
1062 const xcb_query_extension_reply_t *extreply;
1063
1064 root_output = create_root_output(conn);
1065 TAILQ_INSERT_TAIL(&outputs, root_output, outputs);
1066
1067 extreply = xcb_get_extension_data(conn, &xcb_randr_id);
1068 if (!extreply->present) {
1069 DLOG("RandR is not present, activating root output.\n");
1070 fallback_to_root_output();
1071 return;
1072 }
1073
1074 xcb_generic_error_t *err;
1075 xcb_randr_query_version_reply_t *randr_version =
1076 xcb_randr_query_version_reply(
1077 conn, xcb_randr_query_version(conn, XCB_RANDR_MAJOR_VERSION, XCB_RANDR_MINOR_VERSION), &err);
1078 if (err != NULL) {
1079 ELOG("Could not query RandR version: X11 error code %d\n", err->error_code);
1080 free(err);
1081 fallback_to_root_output();
1082 return;
1083 }
1084
1085 has_randr_1_5 = (randr_version->major_version >= 1) &&
1086 (randr_version->minor_version >= 5) &&
1087 !disable_randr15;
1088
1089 free(randr_version);
1090
1091 randr_query_outputs();
1092
1093 if (event_base != NULL)
1094 *event_base = extreply->first_event;
1095
1096 xcb_randr_select_input(conn, root,
1097 XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE |
1098 XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE |
1099 XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE |
1100 XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY);
1101
1102 xcb_flush(conn);
1103 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * regex.c: Interface to libPCRE (perl compatible regular expressions).
7 *
8 */
9 #include "all.h"
10
11 /*
12 * Creates a new 'regex' struct containing the given pattern and a PCRE
13 * compiled regular expression. Also, calls pcre_study because this regex will
14 * most likely be used often (like for every new window and on every relevant
15 * property change of existing windows).
16 *
17 * Returns NULL if the pattern could not be compiled into a regular expression
18 * (and ELOGs an appropriate error message).
19 *
20 */
21 struct regex *regex_new(const char *pattern) {
22 const char *error;
23 int errorcode, offset;
24
25 struct regex *re = scalloc(1, sizeof(struct regex));
26 re->pattern = sstrdup(pattern);
27 int options = PCRE_UTF8;
28 /* We use PCRE_UCP so that \B, \b, \D, \d, \S, \s, \W, \w and some POSIX
29 * character classes play nicely with Unicode */
30 options |= PCRE_UCP;
31 while (!(re->regex = pcre_compile2(pattern, options, &errorcode, &error, &offset, NULL))) {
32 /* If the error is that PCRE was not compiled with UTF-8 support we
33 * disable it and try again */
34 if (errorcode == 32) {
35 options &= ~PCRE_UTF8;
36 continue;
37 }
38 ELOG("PCRE regular expression compilation failed at %d: %s\n",
39 offset, error);
40 regex_free(re);
41 return NULL;
42 }
43 re->extra = pcre_study(re->regex, 0, &error);
44 /* If an error happened, we print the error message, but continue.
45 * Studying the regular expression leads to faster matching, but it’s not
46 * absolutely necessary. */
47 if (error) {
48 ELOG("PCRE regular expression studying failed: %s\n", error);
49 }
50 return re;
51 }
52
53 /*
54 * Frees the given regular expression. It must not be used afterwards!
55 *
56 */
57 void regex_free(struct regex *regex) {
58 if (!regex)
59 return;
60 FREE(regex->pattern);
61 FREE(regex->regex);
62 FREE(regex->extra);
63 FREE(regex);
64 }
65
66 /*
67 * Checks if the given regular expression matches the given input and returns
68 * true if it does. In either case, it logs the outcome using LOG(), so it will
69 * be visible without debug logging.
70 *
71 */
72 bool regex_matches(struct regex *regex, const char *input) {
73 int rc;
74
75 /* We use strlen() because pcre_exec() expects the length of the input
76 * string in bytes */
77 if ((rc = pcre_exec(regex->regex, regex->extra, input, strlen(input), 0, 0, NULL, 0)) == 0) {
78 LOG("Regular expression \"%s\" matches \"%s\"\n",
79 regex->pattern, input);
80 return true;
81 }
82
83 if (rc == PCRE_ERROR_NOMATCH) {
84 LOG("Regular expression \"%s\" does not match \"%s\"\n",
85 regex->pattern, input);
86 return false;
87 }
88
89 ELOG("PCRE error %d while trying to use regular expression \"%s\" on input \"%s\", see pcreapi(3)\n",
90 rc, regex->pattern, input);
91 return false;
92 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * render.c: Renders (determines position/sizes) the layout tree, updating the
7 * various rects. Needs to be pushed to X11 (see x.c) to be visible.
8 *
9 */
10 #include "all.h"
11
12 /* Forward declarations */
13 static int *precalculate_sizes(Con *con, render_params *p);
14 static void render_root(Con *con, Con *fullscreen);
15 static void render_output(Con *con);
16 static void render_con_split(Con *con, Con *child, render_params *p, int i);
17 static void render_con_stacked(Con *con, Con *child, render_params *p, int i);
18 static void render_con_tabbed(Con *con, Con *child, render_params *p, int i);
19 static void render_con_dockarea(Con *con, Con *child, render_params *p);
20 bool should_inset_con(Con *con, int children);
21 bool has_adjacent_container(Con *con, direction_t direction);
22
23 /*
24 * Returns the height for the decorations
25 */
26 int render_deco_height(void) {
27 int deco_height = config.font.height + 4;
28 if (config.font.height & 0x01)
29 ++deco_height;
30 return deco_height;
31 }
32
33 /*
34 * "Renders" the given container (and its children), meaning that all rects are
35 * updated correctly. Note that this function does not call any xcb_*
36 * functions, so the changes are completely done in memory only (and
37 * side-effect free). As soon as you call x_push_changes(), the changes will be
38 * updated in X11.
39 *
40 */
41 void render_con(Con *con, bool already_inset) {
42 render_params params = {
43 .rect = con->rect,
44 .x = con->rect.x,
45 .y = con->rect.y,
46 .children = con_num_children(con)};
47
48 DLOG("Rendering node %p / %s / layout %d / children %d\n", con, con->name,
49 con->layout, params.children);
50
51 bool should_inset = should_inset_con(con, params.children);
52 if (!already_inset && should_inset) {
53 gaps_t gaps = calculate_effective_gaps(con);
54 Rect inset = (Rect){
55 has_adjacent_container(con, D_LEFT) ? gaps.inner : gaps.left,
56 has_adjacent_container(con, D_UP) ? gaps.inner : gaps.top,
57 has_adjacent_container(con, D_RIGHT) ? -gaps.inner : -gaps.right,
58 has_adjacent_container(con, D_DOWN) ? -gaps.inner : -gaps.bottom};
59 inset.width -= inset.x;
60 inset.height -= inset.y;
61
62 if (con->fullscreen_mode == CF_NONE) {
63 params.rect = rect_add(params.rect, inset);
64 con->rect = rect_add(con->rect, inset);
65 if (con->window) {
66 con->window_rect = rect_add(con->window_rect, inset);
67 }
68 }
69 inset.height = 0;
70 if (con->deco_rect.width != 0 && con->deco_rect.height != 0) {
71 con->deco_rect = rect_add(con->deco_rect, inset);
72 }
73
74 params.x = con->rect.x;
75 params.y = con->rect.y;
76 }
77
78 int i = 0;
79 con->mapped = true;
80
81 /* if this container contains a window, set the coordinates */
82 if (con->window) {
83 /* depending on the border style, the rect of the child window
84 * needs to be smaller */
85 Rect *inset = &(con->window_rect);
86 *inset = (Rect){0, 0, con->rect.width, con->rect.height};
87 if (con->fullscreen_mode == CF_NONE) {
88 *inset = rect_add(*inset, con_border_style_rect(con));
89 }
90
91 /* Obey x11 border */
92 inset->width -= (2 * con->border_width);
93 inset->height -= (2 * con->border_width);
94
95 *inset = rect_sanitize_dimensions(*inset);
96
97 /* NB: We used to respect resize increment size hints for tiling
98 * windows up until commit 0db93d9 here. However, since all terminal
99 * emulators cope with ignoring the size hints in a better way than we
100 * can (by providing their fake-transparency or background color), this
101 * code was removed. See also https://bugs.i3wm.org/540 */
102
103 DLOG("child will be at %dx%d with size %dx%d\n", inset->x, inset->y, inset->width, inset->height);
104 }
105
106 /* Check for fullscreen nodes */
107 Con *fullscreen = NULL;
108 if (con->type != CT_OUTPUT) {
109 fullscreen = con_get_fullscreen_con(con, (con->type == CT_ROOT ? CF_GLOBAL : CF_OUTPUT));
110 }
111 if (fullscreen) {
112 fullscreen->rect = params.rect;
113 x_raise_con(fullscreen);
114 render_con(fullscreen, false);
115 /* Fullscreen containers are either global (underneath the CT_ROOT
116 * container) or per-output (underneath the CT_CONTENT container). For
117 * global fullscreen containers, we cannot abort rendering here yet,
118 * because the floating windows (with popup_during_fullscreen smart)
119 * have not yet been rendered (see the CT_ROOT code path below). See
120 * also https://bugs.i3wm.org/1393 */
121 if (con->type != CT_ROOT) {
122 return;
123 }
124 }
125
126 /* find the height for the decorations */
127 params.deco_height = render_deco_height();
128
129 /* precalculate the sizes to be able to correct rounding errors */
130 params.sizes = precalculate_sizes(con, &params);
131
132 if (con->layout == L_OUTPUT) {
133 /* Skip i3-internal outputs */
134 if (con_is_internal(con))
135 goto free_params;
136 render_output(con);
137 } else if (con->type == CT_ROOT) {
138 render_root(con, fullscreen);
139 } else {
140 Con *child;
141 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
142 assert(params.children > 0);
143
144 if (con->layout == L_SPLITH || con->layout == L_SPLITV) {
145 render_con_split(con, child, &params, i);
146 } else if (con->layout == L_STACKED) {
147 render_con_stacked(con, child, &params, i);
148 } else if (con->layout == L_TABBED) {
149 render_con_tabbed(con, child, &params, i);
150 } else if (con->layout == L_DOCKAREA) {
151 render_con_dockarea(con, child, &params);
152 }
153
154 child->rect = rect_sanitize_dimensions(child->rect);
155
156 DLOG("child at (%d, %d) with (%d x %d)\n",
157 child->rect.x, child->rect.y, child->rect.width, child->rect.height);
158 x_raise_con(child);
159 render_con(child, should_inset || already_inset);
160 i++;
161 }
162
163 /* in a stacking or tabbed container, we ensure the focused client is raised */
164 if (con->layout == L_STACKED || con->layout == L_TABBED) {
165 TAILQ_FOREACH_REVERSE (child, &(con->focus_head), focus_head, focused) {
166 x_raise_con(child);
167 }
168 if ((child = TAILQ_FIRST(&(con->focus_head)))) {
169 /* By rendering the stacked container again, we handle the case
170 * that we have a non-leaf-container inside the stack. In that
171 * case, the children of the non-leaf-container need to be
172 * raised as well. */
173 render_con(child, true);
174 }
175
176 if (params.children != 1)
177 /* Raise the stack con itself. This will put the stack
178 * decoration on top of every stack window. That way, when a
179 * new window is opened in the stack, the old window will not
180 * obscure part of the decoration (it’s unmapped afterwards). */
181 x_raise_con(con);
182 }
183 }
184
185 free_params:
186 FREE(params.sizes);
187 }
188
189 static int *precalculate_sizes(Con *con, render_params *p) {
190 if ((con->layout != L_SPLITH && con->layout != L_SPLITV) || p->children <= 0) {
191 return NULL;
192 }
193
194 int *sizes = smalloc(p->children * sizeof(int));
195 assert(!TAILQ_EMPTY(&con->nodes_head));
196
197 Con *child;
198 int i = 0, assigned = 0;
199 int total = con_rect_size_in_orientation(con);
200 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
201 double percentage = child->percent > 0.0 ? child->percent : 1.0 / p->children;
202 assigned += sizes[i++] = lround(percentage * total);
203 }
204 assert(assigned == total ||
205 (assigned > total && assigned - total <= p->children * 2) ||
206 (assigned < total && total - assigned <= p->children * 2));
207 int signal = assigned < total ? 1 : -1;
208 while (assigned != total) {
209 for (i = 0; i < p->children && assigned != total; ++i) {
210 sizes[i] += signal;
211 assigned += signal;
212 }
213 }
214
215 return sizes;
216 }
217
218 static void render_root(Con *con, Con *fullscreen) {
219 Con *output;
220 if (!fullscreen) {
221 TAILQ_FOREACH (output, &(con->nodes_head), nodes) {
222 render_con(output, false);
223 }
224 }
225
226 /* We need to render floating windows after rendering all outputs’
227 * tiling windows because they need to be on top of *every* output at
228 * all times. This is important when the user places floating
229 * windows/containers so that they overlap on another output. */
230 DLOG("Rendering floating windows:\n");
231 TAILQ_FOREACH (output, &(con->nodes_head), nodes) {
232 if (con_is_internal(output))
233 continue;
234 /* Get the active workspace of that output */
235 Con *content = output_get_content(output);
236 if (!content || TAILQ_EMPTY(&(content->focus_head))) {
237 DLOG("Skipping this output because it is currently being destroyed.\n");
238 continue;
239 }
240 Con *workspace = TAILQ_FIRST(&(content->focus_head));
241 Con *fullscreen = con_get_fullscreen_covering_ws(workspace);
242 Con *child;
243 TAILQ_FOREACH (child, &(workspace->floating_head), floating_windows) {
244 if (fullscreen != NULL) {
245 /* Don’t render floating windows when there is a fullscreen
246 * window on that workspace. Necessary to make floating
247 * fullscreen work correctly (ticket #564). Exception to the
248 * above rule: smart popup_during_fullscreen handling (popups
249 * belonging to the fullscreen app will be rendered). */
250 if (config.popup_during_fullscreen != PDF_SMART || fullscreen->window == NULL) {
251 continue;
252 }
253
254 Con *floating_child = con_descend_focused(child);
255 Con *transient_con = floating_child;
256 bool is_transient_for = false;
257 while (transient_con != NULL &&
258 transient_con->window != NULL &&
259 transient_con->window->transient_for != XCB_NONE) {
260 DLOG("transient_con = 0x%08x, transient_con->window->transient_for = 0x%08x, fullscreen_id = 0x%08x\n",
261 transient_con->window->id, transient_con->window->transient_for, fullscreen->window->id);
262 if (transient_con->window->transient_for == fullscreen->window->id) {
263 is_transient_for = true;
264 break;
265 }
266 Con *next_transient = con_by_window_id(transient_con->window->transient_for);
267 if (next_transient == NULL)
268 break;
269 /* Some clients (e.g. x11-ssh-askpass) actually set
270 * WM_TRANSIENT_FOR to their own window id, so break instead of
271 * looping endlessly. */
272 if (transient_con == next_transient)
273 break;
274 transient_con = next_transient;
275 }
276
277 if (!is_transient_for)
278 continue;
279 else {
280 DLOG("Rendering floating child even though in fullscreen mode: "
281 "floating->transient_for (0x%08x) --> fullscreen->id (0x%08x)\n",
282 floating_child->window->transient_for, fullscreen->window->id);
283 }
284 }
285 DLOG("floating child at (%d,%d) with %d x %d\n",
286 child->rect.x, child->rect.y, child->rect.width, child->rect.height);
287 x_raise_con(child);
288 render_con(child, true);
289 }
290 }
291 }
292
293 /*
294 * Renders a container with layout L_OUTPUT. In this layout, all CT_DOCKAREAs
295 * get the height of their content and the remaining CT_CON gets the rest.
296 *
297 */
298 static void render_output(Con *con) {
299 Con *child, *dockchild;
300
301 int x = con->rect.x;
302 int y = con->rect.y;
303 int height = con->rect.height;
304
305 /* Find the content container and ensure that there is exactly one. Also
306 * check for any non-CT_DOCKAREA clients. */
307 Con *content = NULL;
308 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
309 if (child->type == CT_CON) {
310 if (content != NULL) {
311 DLOG("More than one CT_CON on output container\n");
312 assert(false);
313 }
314 content = child;
315 } else if (child->type != CT_DOCKAREA) {
316 DLOG("Child %p of type %d is inside the OUTPUT con\n", child, child->type);
317 assert(false);
318 }
319 }
320
321 if (content == NULL) {
322 DLOG("Skipping this output because it is currently being destroyed.\n");
323 return;
324 }
325
326 /* We need to find out if there is a fullscreen con on the current workspace
327 * and take the short-cut to render it directly (the user does not want to
328 * see the dockareas in that case) */
329 Con *ws = con_get_fullscreen_con(content, CF_OUTPUT);
330 if (!ws) {
331 DLOG("Skipping this output because it is currently being destroyed.\n");
332 return;
333 }
334 Con *fullscreen = con_get_fullscreen_con(ws, CF_OUTPUT);
335 if (fullscreen) {
336 fullscreen->rect = con->rect;
337 x_raise_con(fullscreen);
338 render_con(fullscreen, false);
339 return;
340 }
341
342 /* First pass: determine the height of all CT_DOCKAREAs (the sum of their
343 * children) and figure out how many pixels we have left for the rest */
344 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
345 if (child->type != CT_DOCKAREA)
346 continue;
347
348 child->rect.height = 0;
349 TAILQ_FOREACH (dockchild, &(child->nodes_head), nodes) {
350 child->rect.height += dockchild->geometry.height;
351 }
352
353 height -= child->rect.height;
354 }
355
356 /* Second pass: Set the widths/heights */
357 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
358 if (child->type == CT_CON) {
359 child->rect.x = x;
360 child->rect.y = y;
361 child->rect.width = con->rect.width;
362 child->rect.height = height;
363 }
364
365 child->rect.x = x;
366 child->rect.y = y;
367 child->rect.width = con->rect.width;
368
369 child->deco_rect.x = 0;
370 child->deco_rect.y = 0;
371 child->deco_rect.width = 0;
372 child->deco_rect.height = 0;
373
374 y += child->rect.height;
375
376 DLOG("child at (%d, %d) with (%d x %d)\n",
377 child->rect.x, child->rect.y, child->rect.width, child->rect.height);
378 x_raise_con(child);
379 render_con(child, child->type == CT_DOCKAREA);
380 }
381 }
382
383 static void render_con_split(Con *con, Con *child, render_params *p, int i) {
384 assert(con->layout == L_SPLITH || con->layout == L_SPLITV);
385
386 if (con->layout == L_SPLITH) {
387 child->rect.x = p->x;
388 child->rect.y = p->y;
389 child->rect.width = p->sizes[i];
390 child->rect.height = p->rect.height;
391 p->x += child->rect.width;
392 } else {
393 child->rect.x = p->x;
394 child->rect.y = p->y;
395 child->rect.width = p->rect.width;
396 child->rect.height = p->sizes[i];
397 p->y += child->rect.height;
398 }
399
400 /* first we have the decoration, if this is a leaf node */
401 if (con_is_leaf(child)) {
402 if (child->border_style == BS_NORMAL) {
403 /* TODO: make a function for relative coords? */
404 child->deco_rect.x = child->rect.x - con->rect.x;
405 child->deco_rect.y = child->rect.y - con->rect.y;
406
407 child->rect.y += p->deco_height;
408 child->rect.height -= p->deco_height;
409
410 child->deco_rect.width = child->rect.width;
411 child->deco_rect.height = p->deco_height;
412 } else {
413 child->deco_rect.x = 0;
414 child->deco_rect.y = 0;
415 child->deco_rect.width = 0;
416 child->deco_rect.height = 0;
417 }
418 }
419 }
420
421 static void render_con_stacked(Con *con, Con *child, render_params *p, int i) {
422 assert(con->layout == L_STACKED);
423
424 child->rect.x = p->x;
425 child->rect.y = p->y;
426 child->rect.width = p->rect.width;
427 child->rect.height = p->rect.height;
428
429 child->deco_rect.x = p->x - con->rect.x;
430 child->deco_rect.y = p->y - con->rect.y + (i * p->deco_height);
431 child->deco_rect.width = child->rect.width;
432 child->deco_rect.height = p->deco_height;
433
434 if (p->children > 1 || (child->border_style != BS_PIXEL && child->border_style != BS_NONE)) {
435 child->rect.y += (p->deco_height * p->children);
436 child->rect.height -= (p->deco_height * p->children);
437 }
438 }
439
440 static void render_con_tabbed(Con *con, Con *child, render_params *p, int i) {
441 assert(con->layout == L_TABBED);
442
443 child->rect.x = p->x;
444 child->rect.y = p->y;
445 child->rect.width = p->rect.width;
446 child->rect.height = p->rect.height;
447
448 child->deco_rect.width = floor((float)child->rect.width / p->children);
449 child->deco_rect.x = p->x - con->rect.x + i * child->deco_rect.width;
450 child->deco_rect.y = p->y - con->rect.y;
451
452 /* Since the tab width may be something like 31,6 px per tab, we
453 * let the last tab have all the extra space (0,6 * children). */
454 if (i == (p->children - 1)) {
455 child->deco_rect.width += (child->rect.width - (child->deco_rect.x + child->deco_rect.width));
456 }
457
458 if (p->children > 1 || (child->border_style != BS_PIXEL && child->border_style != BS_NONE)) {
459 child->rect.y += p->deco_height;
460 child->rect.height -= p->deco_height;
461 child->deco_rect.height = p->deco_height;
462 } else {
463 child->deco_rect.height = (child->border_style == BS_PIXEL ? 1 : 0);
464 }
465 }
466
467 static void render_con_dockarea(Con *con, Con *child, render_params *p) {
468 assert(con->layout == L_DOCKAREA);
469
470 child->rect.x = p->x;
471 child->rect.y = p->y;
472 child->rect.width = p->rect.width;
473 child->rect.height = child->geometry.height;
474
475 child->deco_rect.x = 0;
476 child->deco_rect.y = 0;
477 child->deco_rect.width = 0;
478 child->deco_rect.height = 0;
479 p->y += child->rect.height;
480 }
481
482 /*
483 * Decides whether the container should be inset.
484 */
485 bool should_inset_con(Con *con, int children) {
486 /* Don't inset floating containers and workspaces. */
487 if (con->type == CT_FLOATING_CON || con->type == CT_WORKSPACE)
488 return false;
489
490 if (con_is_leaf(con))
491 return true;
492
493 return (con->layout == L_STACKED || con->layout == L_TABBED) && children > 0;
494 }
495
496 /*
497 * Returns whether the given container has an adjacent container in the
498 * specified direction. In other words, this returns true if and only if
499 * the container is not touching the edge of the screen in that direction.
500 */
501 bool has_adjacent_container(Con *con, direction_t direction) {
502 Con *workspace = con_get_workspace(con);
503 Con *fullscreen = con_get_fullscreen_con(workspace, CF_GLOBAL);
504 if (fullscreen == NULL)
505 fullscreen = con_get_fullscreen_con(workspace, CF_OUTPUT);
506
507 /* If this container is fullscreen by itself, there's no adjacent container. */
508 if (con == fullscreen)
509 return false;
510
511 Con *first = con;
512 Con *second = NULL;
513 bool found_neighbor = resize_find_tiling_participants(&first, &second, direction, false);
514 if (!found_neighbor)
515 return false;
516
517 /* If we have an adjacent container and nothing is fullscreen, we consider it. */
518 if (fullscreen == NULL)
519 return true;
520
521 /* For fullscreen containers, only consider the adjacent container if it is also fullscreen. */
522 return con_has_parent(con, fullscreen) && con_has_parent(second, fullscreen);
523 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * resize.c: Interactive resizing.
7 *
8 */
9 #include "all.h"
10
11 /*
12 * This is an ugly data structure which we need because there is no standard
13 * way of having nested functions (only available as a gcc extension at the
14 * moment, clang doesn’t support it) or blocks (only available as a clang
15 * extension and only on Mac OS X systems at the moment).
16 *
17 */
18 struct callback_params {
19 orientation_t orientation;
20 Con *output;
21 xcb_window_t helpwin;
22 uint32_t *new_position;
23 bool *threshold_exceeded;
24 };
25
26 DRAGGING_CB(resize_callback) {
27 const struct callback_params *params = extra;
28 Con *output = params->output;
29 DLOG("new x = %d, y = %d\n", new_x, new_y);
30
31 if (!*params->threshold_exceeded) {
32 xcb_map_window(conn, params->helpwin);
33 /* Warp pointer in the same way as resize_graphical_handler() would do
34 * if threshold wasn't enabled, but also take into account travelled
35 * distance. */
36 if (params->orientation == HORIZ) {
37 xcb_warp_pointer(conn, XCB_NONE, event->root, 0, 0, 0, 0,
38 *params->new_position + new_x - event->root_x,
39 new_y);
40 } else {
41 xcb_warp_pointer(conn, XCB_NONE, event->root, 0, 0, 0, 0,
42 new_x,
43 *params->new_position + new_y - event->root_y);
44 }
45 *params->threshold_exceeded = true;
46 return;
47 }
48
49 if (params->orientation == HORIZ) {
50 /* Check if the new coordinates are within screen boundaries */
51 if (new_x > (output->rect.x + output->rect.width - 25) ||
52 new_x < (output->rect.x + 25))
53 return;
54
55 *(params->new_position) = new_x;
56 xcb_configure_window(conn, params->helpwin, XCB_CONFIG_WINDOW_X, params->new_position);
57 } else {
58 if (new_y > (output->rect.y + output->rect.height - 25) ||
59 new_y < (output->rect.y + 25))
60 return;
61
62 *(params->new_position) = new_y;
63 xcb_configure_window(conn, params->helpwin, XCB_CONFIG_WINDOW_Y, params->new_position);
64 }
65
66 xcb_flush(conn);
67 }
68
69 bool resize_find_tiling_participants(Con **current, Con **other, direction_t direction, bool both_sides) {
70 DLOG("Find two participants for resizing container=%p in direction=%i\n", other, direction);
71 Con *first = *current;
72 Con *second = NULL;
73 if (first == NULL) {
74 DLOG("Current container is NULL, aborting.\n");
75 return false;
76 }
77
78 /* Go up in the tree and search for a container to resize */
79 const orientation_t search_orientation = orientation_from_direction(direction);
80 const bool dir_backwards = (direction == D_UP || direction == D_LEFT);
81 while (first->type != CT_WORKSPACE &&
82 first->type != CT_FLOATING_CON &&
83 second == NULL) {
84 /* get the appropriate first container with the matching
85 * orientation (skip stacked/tabbed cons) */
86 if ((con_orientation(first->parent) != search_orientation) ||
87 (first->parent->layout == L_STACKED) ||
88 (first->parent->layout == L_TABBED)) {
89 first = first->parent;
90 continue;
91 }
92
93 /* get the counterpart for this resizement */
94 if (dir_backwards) {
95 second = TAILQ_PREV(first, nodes_head, nodes);
96 if (second == NULL && both_sides == true) {
97 second = TAILQ_NEXT(first, nodes);
98 }
99 } else {
100 second = TAILQ_NEXT(first, nodes);
101 if (second == NULL && both_sides == true) {
102 second = TAILQ_PREV(first, nodes_head, nodes);
103 }
104 }
105
106 if (second == NULL) {
107 DLOG("No second container in this direction found, trying to look further up in the tree...\n");
108 first = first->parent;
109 }
110 }
111
112 DLOG("Found participants: first=%p and second=%p.\n", first, second);
113 *current = first;
114 *other = second;
115 if (first == NULL || second == NULL) {
116 DLOG("Could not find two participants for this resize request.\n");
117 return false;
118 }
119
120 return true;
121 }
122
123 /*
124 * Calculate the minimum percent needed for the given container to be at least 1
125 * pixel.
126 *
127 */
128 double percent_for_1px(Con *con) {
129 const int parent_size = con_rect_size_in_orientation(con->parent);
130 /* deco_rect.height is subtracted from each child in render_con_split */
131 const int min_size = (con_orientation(con->parent) == HORIZ ? 1 : 1 + con->deco_rect.height);
132 return ((double)min_size / (double)parent_size);
133 }
134
135 /*
136 * Resize the two given containers using the given amount of pixels or
137 * percentage points. One of the two needs to be 0. A positive amount means
138 * growing the first container while a negative means shrinking it.
139 * Returns false when the resize would result in one of the two containers
140 * having less than 1 pixel of size.
141 *
142 */
143 bool resize_neighboring_cons(Con *first, Con *second, int px, int ppt) {
144 assert(px * ppt == 0);
145
146 Con *parent = first->parent;
147 double new_first_percent;
148 double new_second_percent;
149 if (ppt) {
150 new_first_percent = first->percent + ((double)ppt / 100.0);
151 new_second_percent = second->percent - ((double)ppt / 100.0);
152 } else {
153 /* Convert px change to change in percentages */
154 const double pct = (double)px / (double)con_rect_size_in_orientation(first->parent);
155 new_first_percent = first->percent + pct;
156 new_second_percent = second->percent - pct;
157 }
158 /* Ensure that no container will be less than 1 pixel in the resizing
159 * direction. */
160 if (new_first_percent < percent_for_1px(first) || new_second_percent < percent_for_1px(second)) {
161 return false;
162 }
163
164 first->percent = new_first_percent;
165 second->percent = new_second_percent;
166 con_fix_percent(parent);
167 return true;
168 }
169
170 void resize_graphical_handler(Con *first, Con *second, orientation_t orientation,
171 const xcb_button_press_event_t *event,
172 bool use_threshold) {
173 Con *output = con_get_output(first);
174 DLOG("x = %d, width = %d\n", output->rect.x, output->rect.width);
175
176 x_mask_event_mask(~XCB_EVENT_MASK_ENTER_WINDOW);
177 xcb_flush(conn);
178
179 uint32_t mask = 0;
180 uint32_t values[2];
181
182 mask = XCB_CW_OVERRIDE_REDIRECT;
183 values[0] = 1;
184
185 /* Open a new window, the resizebar. Grab the pointer and move the window
186 * around as the user moves the pointer. */
187 xcb_window_t grabwin = create_window(conn, output->rect, XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT,
188 XCB_WINDOW_CLASS_INPUT_ONLY, XCURSOR_CURSOR_POINTER, true, mask, values);
189
190 /* Keep track of the coordinate orthogonal to motion so we can determine the
191 * length of the resize afterward. */
192 uint32_t initial_position, new_position;
193
194 /* Configure the resizebar and snap the pointer. The resizebar runs along
195 * the rect of the second con and follows the motion of the pointer. */
196 Rect helprect;
197 helprect.x = second->rect.x;
198 helprect.y = second->rect.y;
199 if (orientation == HORIZ) {
200 helprect.width = logical_px(2);
201 helprect.height = second->rect.height;
202 initial_position = second->rect.x;
203 } else {
204 helprect.width = second->rect.width;
205 helprect.height = logical_px(2);
206 initial_position = second->rect.y;
207 }
208
209 mask = XCB_CW_BACK_PIXEL;
210 values[0] = config.client.focused.border.colorpixel;
211
212 mask |= XCB_CW_OVERRIDE_REDIRECT;
213 values[1] = 1;
214
215 xcb_window_t helpwin = create_window(conn, helprect, XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT,
216 XCB_WINDOW_CLASS_INPUT_OUTPUT, (orientation == HORIZ ? XCURSOR_CURSOR_RESIZE_HORIZONTAL : XCURSOR_CURSOR_RESIZE_VERTICAL), false, mask, values);
217
218 if (!use_threshold) {
219 xcb_map_window(conn, helpwin);
220 if (orientation == HORIZ) {
221 xcb_warp_pointer(conn, XCB_NONE, event->root, 0, 0, 0, 0,
222 second->rect.x, event->root_y);
223 } else {
224 xcb_warp_pointer(conn, XCB_NONE, event->root, 0, 0, 0, 0,
225 event->root_x, second->rect.y);
226 }
227 }
228
229 xcb_circulate_window(conn, XCB_CIRCULATE_RAISE_LOWEST, helpwin);
230
231 xcb_flush(conn);
232
233 /* `new_position' will be updated by the `resize_callback'. */
234 new_position = initial_position;
235
236 bool threshold_exceeded = !use_threshold;
237
238 const struct callback_params params = {orientation, output, helpwin, &new_position, &threshold_exceeded};
239
240 /* Re-render the tree before returning to the event loop (drag_pointer()
241 * runs its own event-loop) in case if there are unrendered updates. */
242 tree_render();
243
244 /* `drag_pointer' blocks until the drag is completed. */
245 drag_result_t drag_result = drag_pointer(NULL, event, grabwin, 0, use_threshold, resize_callback, &params);
246
247 xcb_destroy_window(conn, helpwin);
248 xcb_destroy_window(conn, grabwin);
249 xcb_flush(conn);
250
251 /* User cancelled the drag so no action should be taken. */
252 if (drag_result == DRAG_REVERT) {
253 return;
254 }
255
256 int pixels = (new_position - initial_position);
257 DLOG("Done, pixels = %d\n", pixels);
258
259 /* No change; no action needed. */
260 if (pixels == 0) {
261 return;
262 }
263
264 /* if we got thus far, the containers must have valid percentages. */
265 assert(first->percent > 0.0);
266 assert(second->percent > 0.0);
267 const bool result = resize_neighboring_cons(first, second, pixels, 0);
268 DLOG("Graphical resize %s: first->percent = %f, second->percent = %f.\n",
269 result ? "successful" : "failed", first->percent, second->percent);
270 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * restore_layout.c: Everything for restored containers that is not pure state
7 * parsing (which can be found in load_layout.c).
8 *
9 *
10 */
11 #include "all.h"
12
13 #ifdef I3_ASAN_ENABLED
14 #include <sanitizer/lsan_interface.h>
15 #endif
16
17 #define TEXT_PADDING logical_px(2)
18
19 typedef struct placeholder_state {
20 /** The X11 placeholder window. */
21 xcb_window_t window;
22 /** The container to which this placeholder window belongs. */
23 Con *con;
24
25 /** Current size of the placeholder window (to detect size changes). */
26 Rect rect;
27
28 /** The drawable surface */
29 surface_t surface;
30
31 TAILQ_ENTRY(placeholder_state)
32 state;
33 } placeholder_state;
34
35 static TAILQ_HEAD(state_head, placeholder_state) state_head =
36 TAILQ_HEAD_INITIALIZER(state_head);
37
38 static xcb_connection_t *restore_conn;
39
40 static struct ev_io *xcb_watcher;
41 static struct ev_prepare *xcb_prepare;
42
43 static void restore_handle_event(int type, xcb_generic_event_t *event);
44
45 /* Documentation for these functions can be found in src/main.c, starting at xcb_got_event */
46 static void restore_xcb_got_event(EV_P_ struct ev_io *w, int revents) {
47 }
48
49 static void restore_xcb_prepare_cb(EV_P_ ev_prepare *w, int revents) {
50 xcb_generic_event_t *event;
51
52 if (xcb_connection_has_error(restore_conn)) {
53 DLOG("restore X11 connection has an error, reconnecting\n");
54 restore_connect();
55 return;
56 }
57
58 while ((event = xcb_poll_for_event(restore_conn)) != NULL) {
59 if (event->response_type == 0) {
60 xcb_generic_error_t *error = (xcb_generic_error_t *)event;
61 DLOG("X11 Error received (probably harmless)! sequence 0x%x, error_code = %d\n",
62 error->sequence, error->error_code);
63 free(event);
64 continue;
65 }
66
67 /* Strip off the highest bit (set if the event is generated) */
68 int type = (event->response_type & 0x7F);
69
70 restore_handle_event(type, event);
71
72 free(event);
73 }
74
75 xcb_flush(restore_conn);
76 }
77
78 /*
79 * Opens a separate connection to X11 for placeholder windows when restoring
80 * layouts. This is done as a safety measure (users can xkill a placeholder
81 * window without killing their window manager) and for better isolation, both
82 * on the wire to X11 and thus also in the code.
83 *
84 */
85 void restore_connect(void) {
86 if (restore_conn != NULL) {
87 /* This is not the initial connect, but a reconnect, most likely
88 * because our X11 connection was killed (e.g. by a user with xkill. */
89 ev_io_stop(main_loop, xcb_watcher);
90 ev_prepare_stop(main_loop, xcb_prepare);
91
92 placeholder_state *state;
93 while (!TAILQ_EMPTY(&state_head)) {
94 state = TAILQ_FIRST(&state_head);
95 TAILQ_REMOVE(&state_head, state, state);
96 free(state);
97 }
98
99 /* xcb_disconnect leaks memory in libxcb versions earlier than 1.11,
100 * but it’s the right function to call. See
101 * https://cgit.freedesktop.org/xcb/libxcb/commit/src/xcb_conn.c?id=4dcbfd77b
102 */
103 xcb_disconnect(restore_conn);
104 free(xcb_watcher);
105 free(xcb_prepare);
106 }
107
108 int screen;
109 restore_conn = xcb_connect(NULL, &screen);
110 if (restore_conn == NULL || xcb_connection_has_error(restore_conn)) {
111 if (restore_conn != NULL) {
112 xcb_disconnect(restore_conn);
113 }
114 #ifdef I3_ASAN_ENABLED
115 __lsan_do_leak_check();
116 #endif
117 errx(EXIT_FAILURE, "Cannot open display");
118 }
119
120 xcb_watcher = scalloc(1, sizeof(struct ev_io));
121 xcb_prepare = scalloc(1, sizeof(struct ev_prepare));
122
123 ev_io_init(xcb_watcher, restore_xcb_got_event, xcb_get_file_descriptor(restore_conn), EV_READ);
124 ev_io_start(main_loop, xcb_watcher);
125
126 ev_prepare_init(xcb_prepare, restore_xcb_prepare_cb);
127 ev_prepare_start(main_loop, xcb_prepare);
128 }
129
130 static void update_placeholder_contents(placeholder_state *state) {
131 const color_t foreground = config.client.placeholder.text;
132 const color_t background = config.client.placeholder.background;
133
134 draw_util_clear_surface(&(state->surface), background);
135
136 // TODO: make i3font functions per-connection, at least these two for now…?
137 xcb_flush(restore_conn);
138 xcb_aux_sync(restore_conn);
139
140 Match *swallows;
141 int n = 0;
142 TAILQ_FOREACH (swallows, &(state->con->swallow_head), matches) {
143 char *serialized = NULL;
144
145 #define APPEND_REGEX(re_name) \
146 do { \
147 if (swallows->re_name != NULL) { \
148 sasprintf(&serialized, "%s%s" #re_name "=\"%s\"", (serialized ? serialized : "["), (serialized ? " " : ""), swallows->re_name->pattern); \
149 } \
150 } while (0)
151
152 APPEND_REGEX(class);
153 APPEND_REGEX(instance);
154 APPEND_REGEX(window_role);
155 APPEND_REGEX(title);
156
157 if (serialized == NULL) {
158 DLOG("This swallows specification is not serializable?!\n");
159 continue;
160 }
161
162 sasprintf(&serialized, "%s]", serialized);
163 DLOG("con %p (placeholder 0x%08x) line %d: %s\n", state->con, state->window, n, serialized);
164
165 i3String *str = i3string_from_utf8(serialized);
166 draw_util_text(str, &(state->surface), foreground, background,
167 TEXT_PADDING,
168 (n * (config.font.height + TEXT_PADDING)) + TEXT_PADDING,
169 state->rect.width - 2 * TEXT_PADDING);
170 i3string_free(str);
171 n++;
172 free(serialized);
173 }
174
175 // TODO: render the watch symbol in a bigger font
176 i3String *line = i3string_from_utf8("⌚");
177 int text_width = predict_text_width(line);
178 int x = (state->rect.width / 2) - (text_width / 2);
179 int y = (state->rect.height / 2) - (config.font.height / 2);
180 draw_util_text(line, &(state->surface), foreground, background, x, y, text_width);
181 i3string_free(line);
182 xcb_flush(restore_conn);
183 xcb_aux_sync(restore_conn);
184 }
185
186 static void open_placeholder_window(Con *con) {
187 if (con_is_leaf(con) &&
188 (con->window == NULL || con->window->id == XCB_NONE) &&
189 !TAILQ_EMPTY(&(con->swallow_head)) &&
190 con->type == CT_CON) {
191 xcb_window_t placeholder = create_window(
192 restore_conn,
193 con->rect,
194 XCB_COPY_FROM_PARENT,
195 XCB_COPY_FROM_PARENT,
196 XCB_WINDOW_CLASS_INPUT_OUTPUT,
197 XCURSOR_CURSOR_POINTER,
198 true,
199 XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK,
200 (uint32_t[]){
201 config.client.placeholder.background.colorpixel,
202 XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY,
203 });
204 /* Make i3 not focus this window. */
205 xcb_icccm_wm_hints_t hints;
206 xcb_icccm_wm_hints_set_none(&hints);
207 xcb_icccm_wm_hints_set_input(&hints, 0);
208 xcb_icccm_set_wm_hints(restore_conn, placeholder, &hints);
209 /* Set the same name as was stored in the layout file. While perhaps
210 * slightly confusing in the first instant, this brings additional
211 * clarity to which placeholder is waiting for which actual window. */
212 if (con->name != NULL)
213 xcb_change_property(restore_conn, XCB_PROP_MODE_REPLACE, placeholder,
214 A__NET_WM_NAME, A_UTF8_STRING, 8, strlen(con->name), con->name);
215 DLOG("Created placeholder window 0x%08x for leaf container %p / %s\n",
216 placeholder, con, con->name);
217
218 placeholder_state *state = scalloc(1, sizeof(placeholder_state));
219 state->window = placeholder;
220 state->con = con;
221 state->rect = con->rect;
222
223 draw_util_surface_init(restore_conn, &(state->surface), placeholder, get_visualtype(root_screen), state->rect.width, state->rect.height);
224 update_placeholder_contents(state);
225 TAILQ_INSERT_TAIL(&state_head, state, state);
226
227 /* create temporary id swallow to match the placeholder */
228 Match *temp_id = smalloc(sizeof(Match));
229 match_init(temp_id);
230 temp_id->dock = M_DONTCHECK;
231 temp_id->id = placeholder;
232 TAILQ_INSERT_HEAD(&(con->swallow_head), temp_id, matches);
233 }
234
235 Con *child;
236 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
237 open_placeholder_window(child);
238 }
239 TAILQ_FOREACH (child, &(con->floating_head), floating_windows) {
240 open_placeholder_window(child);
241 }
242 }
243
244 /*
245 * Open placeholder windows for all children of parent. The placeholder window
246 * will vanish as soon as a real window is swallowed by the container. Until
247 * then, it exposes the criteria that must be fulfilled for a window to be
248 * swallowed by this container.
249 *
250 */
251 void restore_open_placeholder_windows(Con *parent) {
252 Con *child;
253 TAILQ_FOREACH (child, &(parent->nodes_head), nodes) {
254 open_placeholder_window(child);
255 }
256 TAILQ_FOREACH (child, &(parent->floating_head), floating_windows) {
257 open_placeholder_window(child);
258 }
259
260 xcb_flush(restore_conn);
261 }
262
263 /*
264 * Kill the placeholder window, if placeholder refers to a placeholder window.
265 * This function is called when manage.c puts a window into an existing
266 * container. In order not to leak resources, we need to destroy the window and
267 * all associated X11 objects (pixmap/gc).
268 *
269 */
270 bool restore_kill_placeholder(xcb_window_t placeholder) {
271 placeholder_state *state;
272 TAILQ_FOREACH (state, &state_head, state) {
273 if (state->window != placeholder)
274 continue;
275
276 xcb_destroy_window(restore_conn, state->window);
277 draw_util_surface_free(restore_conn, &(state->surface));
278 TAILQ_REMOVE(&state_head, state, state);
279 free(state);
280 DLOG("placeholder window 0x%08x destroyed.\n", placeholder);
281 return true;
282 }
283
284 DLOG("0x%08x is not a placeholder window, ignoring.\n", placeholder);
285 return false;
286 }
287
288 static void expose_event(xcb_expose_event_t *event) {
289 placeholder_state *state;
290 TAILQ_FOREACH (state, &state_head, state) {
291 if (state->window != event->window)
292 continue;
293
294 DLOG("refreshing window 0x%08x contents (con %p)\n", state->window, state->con);
295
296 update_placeholder_contents(state);
297
298 return;
299 }
300
301 ELOG("Received ExposeEvent for unknown window 0x%08x\n", event->window);
302 }
303
304 /*
305 * Window size has changed. Update the width/height, then recreate the back
306 * buffer pixmap and the accompanying graphics context and force an immediate
307 * re-rendering.
308 *
309 */
310 static void configure_notify(xcb_configure_notify_event_t *event) {
311 placeholder_state *state;
312 TAILQ_FOREACH (state, &state_head, state) {
313 if (state->window != event->window)
314 continue;
315
316 DLOG("ConfigureNotify: window 0x%08x has now width=%d, height=%d (con %p)\n",
317 state->window, event->width, event->height, state->con);
318
319 state->rect.width = event->width;
320 state->rect.height = event->height;
321
322 draw_util_surface_set_size(&(state->surface), state->rect.width, state->rect.height);
323
324 update_placeholder_contents(state);
325
326 return;
327 }
328
329 ELOG("Received ConfigureNotify for unknown window 0x%08x\n", event->window);
330 }
331
332 static void restore_handle_event(int type, xcb_generic_event_t *event) {
333 switch (type) {
334 case XCB_EXPOSE:
335 if (((xcb_expose_event_t *)event)->count == 0) {
336 expose_event((xcb_expose_event_t *)event);
337 }
338
339 break;
340 case XCB_CONFIGURE_NOTIFY:
341 configure_notify((xcb_configure_notify_event_t *)event);
342 break;
343 default:
344 DLOG("Received unhandled X11 event of type %d\n", type);
345 break;
346 }
347 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * scratchpad.c: Moving windows to the scratchpad and making them visible again.
7 *
8 */
9 #include "all.h"
10
11 /*
12 * Moves the specified window to the __i3_scratch workspace, making it floating
13 * and setting the appropriate scratchpad_state.
14 *
15 * Gets called upon the command 'move scratchpad'.
16 *
17 */
18 void scratchpad_move(Con *con) {
19 if (con->type == CT_WORKSPACE) {
20 LOG("'move scratchpad' used on a workspace \"%s\". Calling it "
21 "recursively on all windows on this workspace.\n",
22 con->name);
23 Con *current;
24 current = TAILQ_FIRST(&(con->focus_head));
25 while (current) {
26 Con *next = TAILQ_NEXT(current, focused);
27 scratchpad_move(current);
28 current = next;
29 }
30 return;
31 }
32 DLOG("should move con %p to __i3_scratch\n", con);
33
34 Con *__i3_scratch = workspace_get("__i3_scratch", NULL);
35 if (con_get_workspace(con) == __i3_scratch) {
36 DLOG("This window is already on __i3_scratch.\n");
37 return;
38 }
39
40 /* If the current con is in fullscreen mode, we need to disable that,
41 * as a scratchpad window should never be in fullscreen mode */
42 con_disable_fullscreen(con);
43
44 /* 1: Ensure the window or any parent is floating. From now on, we deal
45 * with the CT_FLOATING_CON. We use automatic == false because the user
46 * made the choice that this window should be a scratchpad (and floating).
47 */
48 Con *maybe_floating_con = con_inside_floating(con);
49 if (maybe_floating_con == NULL) {
50 floating_enable(con, false);
51 con = con->parent;
52 } else {
53 con = maybe_floating_con;
54 }
55
56 /* 2: Send the window to the __i3_scratch workspace, mainting its
57 * coordinates and not warping the pointer. */
58 con_move_to_workspace(con, __i3_scratch, true, true, false);
59
60 /* 3: If this is the first time this window is used as a scratchpad, we set
61 * the scratchpad_state to SCRATCHPAD_FRESH. The window will then be
62 * adjusted in size according to what the user specifies. */
63 if (con->scratchpad_state == SCRATCHPAD_NONE) {
64 DLOG("This window was never used as a scratchpad before.\n");
65 if (con == maybe_floating_con) {
66 DLOG("It was in floating mode before, set scratchpad state to changed.\n");
67 con->scratchpad_state = SCRATCHPAD_CHANGED;
68 } else {
69 DLOG("It was in tiling mode before, set scratchpad state to fresh.\n");
70 con->scratchpad_state = SCRATCHPAD_FRESH;
71 }
72 }
73 }
74
75 /*
76 * Either shows the top-most scratchpad window (con == NULL) or shows the
77 * specified con (if it is scratchpad window).
78 *
79 * When called with con == NULL and the currently focused window is a
80 * scratchpad window, this serves as a shortcut to hide it again (so the user
81 * can press the same key to quickly look something up).
82 *
83 */
84 bool scratchpad_show(Con *con) {
85 DLOG("should show scratchpad window %p\n", con);
86 Con *__i3_scratch = workspace_get("__i3_scratch", NULL);
87 Con *floating;
88
89 /* If this was 'scratchpad show' without criteria, we check if the
90 * currently focused window is a scratchpad window and should be hidden
91 * again. */
92 if (!con &&
93 (floating = con_inside_floating(focused)) &&
94 floating->scratchpad_state != SCRATCHPAD_NONE) {
95 DLOG("Focused window is a scratchpad window, hiding it.\n");
96 scratchpad_move(focused);
97 return true;
98 }
99
100 /* If the current con or any of its parents are in fullscreen mode, we
101 * first need to disable it before showing the scratchpad con. */
102 Con *fs = focused;
103 while (fs && fs->fullscreen_mode == CF_NONE)
104 fs = fs->parent;
105
106 if (fs && fs->type != CT_WORKSPACE) {
107 con_toggle_fullscreen(fs, CF_OUTPUT);
108 }
109
110 /* If this was 'scratchpad show' without criteria, we check if there is a
111 * unfocused scratchpad on the current workspace and focus it */
112 Con *walk_con;
113 Con *focused_ws = con_get_workspace(focused);
114 TAILQ_FOREACH (walk_con, &(focused_ws->floating_head), floating_windows) {
115 if (!con && (floating = con_inside_floating(walk_con)) &&
116 floating->scratchpad_state != SCRATCHPAD_NONE &&
117 floating != con_inside_floating(focused)) {
118 DLOG("Found an unfocused scratchpad window on this workspace\n");
119 DLOG("Focusing it: %p\n", walk_con);
120 /* use con_descend_tiling_focused to get the last focused
121 * window inside this scratch container in order to
122 * keep the focus the same within this container */
123 con_activate(con_descend_tiling_focused(walk_con));
124 return true;
125 }
126 }
127
128 /* If this was 'scratchpad show' without criteria, we check if there is a
129 * visible scratchpad window on another workspace. In this case we move it
130 * to the current workspace. */
131 focused_ws = con_get_workspace(focused);
132 TAILQ_FOREACH (walk_con, &all_cons, all_cons) {
133 Con *walk_ws = con_get_workspace(walk_con);
134 if (!con && walk_ws &&
135 !con_is_internal(walk_ws) && focused_ws != walk_ws &&
136 (floating = con_inside_floating(walk_con)) &&
137 floating->scratchpad_state != SCRATCHPAD_NONE) {
138 DLOG("Found a visible scratchpad window on another workspace,\n");
139 DLOG("moving it to this workspace: con = %p\n", walk_con);
140 con_move_to_workspace(floating, focused_ws, true, false, false);
141 con_activate(con_descend_focused(walk_con));
142 return true;
143 }
144 }
145
146 /* If this was 'scratchpad show' with criteria, we check if the window
147 * is actually in the scratchpad */
148 if (con && con->parent->scratchpad_state == SCRATCHPAD_NONE) {
149 DLOG("Window is not in the scratchpad, doing nothing.\n");
150 return false;
151 }
152
153 /* If this was 'scratchpad show' with criteria, we check if it matches a
154 * currently visible scratchpad window and hide it. */
155 Con *active = con_get_workspace(focused);
156 Con *current = con_get_workspace(con);
157 if (con &&
158 (floating = con_inside_floating(con)) &&
159 floating->scratchpad_state != SCRATCHPAD_NONE &&
160 current != __i3_scratch) {
161 /* If scratchpad window is on the active workspace, then we should hide
162 * it, otherwise we should move it to the active workspace. */
163 if (current == active) {
164 DLOG("Window is a scratchpad window, hiding it.\n");
165 scratchpad_move(con);
166 return true;
167 }
168 }
169
170 if (con == NULL) {
171 /* Use the container on __i3_scratch which is highest in the focus
172 * stack. When moving windows to __i3_scratch, they get inserted at the
173 * bottom of the stack. */
174 con = TAILQ_FIRST(&(__i3_scratch->floating_head));
175
176 if (!con) {
177 LOG("You don't have any scratchpad windows yet.\n");
178 LOG("Use 'move scratchpad' to move a window to the scratchpad.\n");
179 return false;
180 }
181 } else {
182 /* We used a criterion, so we need to do what follows (moving,
183 * resizing) on the floating parent. */
184 con = con_inside_floating(con);
185 }
186
187 /* 1: Move the window from __i3_scratch to the current workspace. */
188 con_move_to_workspace(con, active, true, false, false);
189
190 /* 2: Adjust the size if this window was not adjusted yet. */
191 if (con->scratchpad_state == SCRATCHPAD_FRESH) {
192 DLOG("Adjusting size of this window.\n");
193 Con *output = con_get_output(con);
194 con->rect.width = output->rect.width * 0.5;
195 con->rect.height = output->rect.height * 0.75;
196 floating_check_size(con, false);
197 floating_center(con, con_get_workspace(con)->rect);
198 }
199
200 /* Activate active workspace if window is from another workspace to ensure
201 * proper focus. */
202 if (current != active) {
203 workspace_show(active);
204 }
205
206 con_activate(con_descend_focused(con));
207
208 return true;
209 }
210
211 /*
212 * Greatest common divisor, implemented only for the least common multiple
213 * below.
214 *
215 */
216 static int _gcd(const int m, const int n) {
217 if (n == 0)
218 return m;
219 return _gcd(n, (m % n));
220 }
221
222 /*
223 * Least common multiple. We use it to determine the (ideally not too large)
224 * resolution for the __i3 pseudo-output on which the scratchpad is on (see
225 * below). We could just multiply the resolutions, but for some pathetic cases
226 * (many outputs), using the LCM will achieve better results.
227 *
228 * Man, when you were learning about these two algorithms for the first time,
229 * did you think you’d ever need them in a real-world software project of
230 * yours? I certainly didn’t until now. :-D
231 *
232 */
233 static int _lcm(const int m, const int n) {
234 const int o = _gcd(m, n);
235 return ((m * n) / o);
236 }
237
238 /*
239 * When starting i3 initially (and after each change to the connected outputs),
240 * this function fixes the resolution of the __i3 pseudo-output. When that
241 * resolution is not set to a function which shares a common divisor with every
242 * active output’s resolution, floating point calculation errors will lead to
243 * the scratchpad window moving when shown repeatedly.
244 *
245 */
246 void scratchpad_fix_resolution(void) {
247 Con *__i3_scratch = workspace_get("__i3_scratch", NULL);
248 Con *__i3_output = con_get_output(__i3_scratch);
249 DLOG("Current resolution: (%d, %d) %d x %d\n",
250 __i3_output->rect.x, __i3_output->rect.y,
251 __i3_output->rect.width, __i3_output->rect.height);
252 Con *output;
253 int new_width = -1,
254 new_height = -1;
255 TAILQ_FOREACH (output, &(croot->nodes_head), nodes) {
256 if (output == __i3_output)
257 continue;
258 DLOG("output %s's resolution: (%d, %d) %d x %d\n",
259 output->name, output->rect.x, output->rect.y,
260 output->rect.width, output->rect.height);
261 if (new_width == -1) {
262 new_width = output->rect.width;
263 new_height = output->rect.height;
264 } else {
265 new_width = _lcm(new_width, output->rect.width);
266 new_height = _lcm(new_height, output->rect.height);
267 }
268 }
269
270 Rect old_rect = __i3_output->rect;
271
272 DLOG("new width = %d, new height = %d\n",
273 new_width, new_height);
274 __i3_output->rect.width = new_width;
275 __i3_output->rect.height = new_height;
276
277 Rect new_rect = __i3_output->rect;
278
279 if (rect_equals(new_rect, old_rect)) {
280 DLOG("Scratchpad size unchanged.\n");
281 return;
282 }
283
284 DLOG("Fixing coordinates of scratchpad windows\n");
285 Con *con;
286 TAILQ_FOREACH (con, &(__i3_scratch->floating_head), floating_windows) {
287 floating_fix_coordinates(con, &old_rect, &new_rect);
288 }
289 }
0 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1
2 /***
3 Copyright 2010 Lennart Poettering
4
5 Permission is hereby granted, free of charge, to any person
6 obtaining a copy of this software and associated documentation files
7 (the "Software"), to deal in the Software without restriction,
8 including without limitation the rights to use, copy, modify, merge,
9 publish, distribute, sublicense, and/or sell copies of the Software,
10 and to permit persons to whom the Software is furnished to do so,
11 subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be
14 included in all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 SOFTWARE.
24 ***/
25
26 #ifndef _GNU_SOURCE
27 #define _GNU_SOURCE
28 #endif
29
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <sys/socket.h>
33 #include <sys/un.h>
34 #include <sys/fcntl.h>
35 #include <netinet/in.h>
36 #include <stdlib.h>
37 #include <errno.h>
38 #include <unistd.h>
39 #include <string.h>
40 #include <stdarg.h>
41 #include <stdio.h>
42 #include <stddef.h>
43
44 #include "sd-daemon.h"
45
46 int sd_listen_fds(int unset_environment) {
47 int r, fd;
48 const char *e;
49 char *p = NULL;
50 unsigned long l;
51
52 if (!(e = getenv("LISTEN_PID"))) {
53 r = 0;
54 goto finish;
55 }
56
57 errno = 0;
58 l = strtoul(e, &p, 10);
59
60 if (errno != 0) {
61 r = -errno;
62 goto finish;
63 }
64
65 if (!p || *p || l <= 0) {
66 r = -EINVAL;
67 goto finish;
68 }
69
70 /* Is this for us? */
71 if (getpid() != (pid_t)l) {
72 r = 0;
73 goto finish;
74 }
75
76 if (!(e = getenv("LISTEN_FDS"))) {
77 r = 0;
78 goto finish;
79 }
80
81 errno = 0;
82 l = strtoul(e, &p, 10);
83
84 if (errno != 0) {
85 r = -errno;
86 goto finish;
87 }
88
89 if (!p || *p) {
90 r = -EINVAL;
91 goto finish;
92 }
93
94 for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int)l; fd++) {
95 int flags;
96
97 if ((flags = fcntl(fd, F_GETFD)) < 0) {
98 r = -errno;
99 goto finish;
100 }
101
102 if (flags & FD_CLOEXEC)
103 continue;
104
105 if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
106 r = -errno;
107 goto finish;
108 }
109 }
110
111 r = (int)l;
112
113 finish:
114 if (unset_environment) {
115 unsetenv("LISTEN_PID");
116 unsetenv("LISTEN_FDS");
117 }
118
119 return r;
120 }
121
122 int sd_is_fifo(int fd, const char *path) {
123 struct stat st_fd;
124
125 if (fd < 0)
126 return -EINVAL;
127
128 memset(&st_fd, 0, sizeof(st_fd));
129 if (fstat(fd, &st_fd) < 0)
130 return -errno;
131
132 if (!S_ISFIFO(st_fd.st_mode))
133 return 0;
134
135 if (path) {
136 struct stat st_path;
137
138 memset(&st_path, 0, sizeof(st_path));
139 if (stat(path, &st_path) < 0) {
140 if (errno == ENOENT || errno == ENOTDIR)
141 return 0;
142
143 return -errno;
144 }
145
146 return st_path.st_dev == st_fd.st_dev &&
147 st_path.st_ino == st_fd.st_ino;
148 }
149
150 return 1;
151 }
152
153 static int sd_is_socket_internal(int fd, int type, int listening) {
154 struct stat st_fd;
155
156 if (fd < 0 || type < 0)
157 return -EINVAL;
158
159 if (fstat(fd, &st_fd) < 0)
160 return -errno;
161
162 if (!S_ISSOCK(st_fd.st_mode))
163 return 0;
164
165 if (type != 0) {
166 int other_type = 0;
167 socklen_t l = sizeof(other_type);
168
169 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &other_type, &l) < 0)
170 return -errno;
171
172 if (l != sizeof(other_type))
173 return -EINVAL;
174
175 if (other_type != type)
176 return 0;
177 }
178
179 if (listening >= 0) {
180 int accepting = 0;
181 socklen_t l = sizeof(accepting);
182
183 if (getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &accepting, &l) < 0)
184 return -errno;
185
186 if (l != sizeof(accepting))
187 return -EINVAL;
188
189 if (!accepting != !listening)
190 return 0;
191 }
192
193 return 1;
194 }
195
196 union sockaddr_union {
197 struct sockaddr sa;
198 struct sockaddr_in in4;
199 struct sockaddr_in6 in6;
200 struct sockaddr_un un;
201 struct sockaddr_storage storage;
202 };
203
204 int sd_is_socket(int fd, int family, int type, int listening) {
205 int r;
206
207 if (family < 0)
208 return -EINVAL;
209
210 if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
211 return r;
212
213 if (family > 0) {
214 union sockaddr_union sockaddr;
215 socklen_t l;
216
217 memset(&sockaddr, 0, sizeof(sockaddr));
218 l = sizeof(sockaddr);
219
220 if (getsockname(fd, &sockaddr.sa, &l) < 0)
221 return -errno;
222
223 if (l < sizeof(sa_family_t))
224 return -EINVAL;
225
226 return sockaddr.sa.sa_family == family;
227 }
228
229 return 1;
230 }
231
232 int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) {
233 union sockaddr_union sockaddr;
234 socklen_t l;
235 int r;
236
237 if (family != 0 && family != AF_INET && family != AF_INET6)
238 return -EINVAL;
239
240 if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
241 return r;
242
243 memset(&sockaddr, 0, sizeof(sockaddr));
244 l = sizeof(sockaddr);
245
246 if (getsockname(fd, &sockaddr.sa, &l) < 0)
247 return -errno;
248
249 if (l < sizeof(sa_family_t))
250 return -EINVAL;
251
252 if (sockaddr.sa.sa_family != AF_INET &&
253 sockaddr.sa.sa_family != AF_INET6)
254 return 0;
255
256 if (family > 0)
257 if (sockaddr.sa.sa_family != family)
258 return 0;
259
260 if (port > 0) {
261 if (sockaddr.sa.sa_family == AF_INET) {
262 if (l < sizeof(struct sockaddr_in))
263 return -EINVAL;
264
265 return htons(port) == sockaddr.in4.sin_port;
266 } else {
267 if (l < sizeof(struct sockaddr_in6))
268 return -EINVAL;
269
270 return htons(port) == sockaddr.in6.sin6_port;
271 }
272 }
273
274 return 1;
275 }
276
277 int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) {
278 union sockaddr_union sockaddr;
279 socklen_t l;
280 int r;
281
282 if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
283 return r;
284
285 memset(&sockaddr, 0, sizeof(sockaddr));
286 l = sizeof(sockaddr);
287
288 if (getsockname(fd, &sockaddr.sa, &l) < 0)
289 return -errno;
290
291 if (l < sizeof(sa_family_t))
292 return -EINVAL;
293
294 if (sockaddr.sa.sa_family != AF_UNIX)
295 return 0;
296
297 if (path) {
298 if (length <= 0)
299 length = strlen(path);
300
301 if (length <= 0)
302 /* Unnamed socket */
303 return l == offsetof(struct sockaddr_un, sun_path);
304
305 if (path[0])
306 /* Normal path socket */
307 return (l >= offsetof(struct sockaddr_un, sun_path) + length + 1) &&
308 memcmp(path, sockaddr.un.sun_path, length + 1) == 0;
309 else
310 /* Abstract namespace socket */
311 return (l == offsetof(struct sockaddr_un, sun_path) + length) &&
312 memcmp(path, sockaddr.un.sun_path, length) == 0;
313 }
314
315 return 1;
316 }
317
318 int sd_notify(int unset_environment, const char *state) {
319 #if defined(DISABLE_SYSTEMD) || !defined(__linux__) || !defined(SOCK_CLOEXEC)
320 return 0;
321 #else
322 int fd = -1, r;
323 struct msghdr msghdr;
324 struct iovec iovec;
325 union sockaddr_union sockaddr;
326 const char *e;
327
328 if (!state) {
329 r = -EINVAL;
330 goto finish;
331 }
332
333 if (!(e = getenv("NOTIFY_SOCKET")))
334 return 0;
335
336 /* Must be an abstract socket, or an absolute path */
337 if ((e[0] != '@' && e[0] != '/') || e[1] == 0) {
338 r = -EINVAL;
339 goto finish;
340 }
341
342 if ((fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0)) < 0) {
343 r = -errno;
344 goto finish;
345 }
346
347 memset(&sockaddr, 0, sizeof(sockaddr));
348 sockaddr.sa.sa_family = AF_UNIX;
349 strncpy(sockaddr.un.sun_path, e, sizeof(sockaddr.un.sun_path));
350
351 if (sockaddr.un.sun_path[0] == '@')
352 sockaddr.un.sun_path[0] = 0;
353
354 memset(&iovec, 0, sizeof(iovec));
355 iovec.iov_base = (char *)state;
356 iovec.iov_len = strlen(state);
357
358 memset(&msghdr, 0, sizeof(msghdr));
359 msghdr.msg_name = &sockaddr;
360 msghdr.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(e);
361
362 if (msghdr.msg_namelen > sizeof(struct sockaddr_un))
363 msghdr.msg_namelen = sizeof(struct sockaddr_un);
364
365 msghdr.msg_iov = &iovec;
366 msghdr.msg_iovlen = 1;
367
368 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0) {
369 r = -errno;
370 goto finish;
371 }
372
373 r = 1;
374
375 finish:
376 if (unset_environment)
377 unsetenv("NOTIFY_SOCKET");
378
379 if (fd >= 0)
380 close(fd);
381
382 return r;
383 #endif
384 }
385
386 int sd_notifyf(int unset_environment, const char *format, ...) {
387 #if defined(DISABLE_SYSTEMD) || !defined(__linux__)
388 return 0;
389 #else
390 va_list ap;
391 char *p = NULL;
392 int r;
393
394 va_start(ap, format);
395 r = vasprintf(&p, format, ap);
396 va_end(ap);
397
398 if (r < 0 || !p)
399 return -ENOMEM;
400
401 r = sd_notify(unset_environment, p);
402 free(p);
403
404 return r;
405 #endif
406 }
407
408 int sd_booted(void) {
409 #if defined(DISABLE_SYSTEMD) || !defined(__linux__)
410 return 0;
411 #else
412
413 struct stat a, b;
414
415 /* We simply test whether the systemd cgroup hierarchy is mounted */
416
417 if (lstat("/sys/fs/cgroup", &a) < 0)
418 return 0;
419
420 if (lstat("/sys/fs/cgroup/systemd", &b) < 0)
421 return 0;
422
423 return a.st_dev != b.st_dev;
424 #endif
425 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 */
7 #include "all.h"
8
9 #include <ev.h>
10 #include <iconv.h>
11 #include <signal.h>
12 #include <sys/wait.h>
13
14 #include <xcb/xcb_event.h>
15
16 #include <X11/keysym.h>
17
18 typedef struct dialog_t {
19 xcb_window_t id;
20 xcb_colormap_t colormap;
21 Rect dims;
22 surface_t surface;
23
24 TAILQ_ENTRY(dialog_t)
25 dialogs;
26 } dialog_t;
27
28 static TAILQ_HEAD(dialogs_head, dialog_t) dialogs = TAILQ_HEAD_INITIALIZER(dialogs);
29 static int raised_signal;
30 static int backtrace_done = 0;
31
32 static int sighandler_backtrace(void);
33 static void sighandler_setup(void);
34 static void sighandler_create_dialogs(void);
35 static void sighandler_destroy_dialogs(void);
36 static void sighandler_handle_expose(void);
37 static void sighandler_draw_dialog(dialog_t *dialog);
38 static void sighandler_handle_key_press(xcb_key_press_event_t *event);
39
40 static i3String *message_intro;
41 static i3String *message_intro2;
42 static i3String *message_option_backtrace;
43 static i3String *message_option_restart;
44 static i3String *message_option_forget;
45 static int dialog_width;
46 static int dialog_height;
47
48 static int border_width = 2;
49 static int margin = 4;
50
51 /*
52 * Attach gdb to pid_parent and dump a backtrace to i3-backtrace.$pid in the
53 * tmpdir
54 */
55 static int sighandler_backtrace(void) {
56 char *tmpdir = getenv("TMPDIR");
57 if (tmpdir == NULL)
58 tmpdir = "/tmp";
59
60 pid_t pid_parent = getpid();
61
62 char *filename = NULL;
63 int suffix = 0;
64 /* Find a unique filename for the backtrace (since the PID of i3 stays the
65 * same), so that we don’t overwrite earlier backtraces. */
66 do {
67 FREE(filename);
68 sasprintf(&filename, "%s/i3-backtrace.%d.%d.txt", tmpdir, pid_parent, suffix);
69 suffix++;
70 } while (path_exists(filename));
71
72 pid_t pid_gdb = fork();
73 if (pid_gdb < 0) {
74 DLOG("Failed to fork for GDB\n");
75 return -1;
76 } else if (pid_gdb == 0) {
77 /* child */
78 int stdin_pipe[2],
79 stdout_pipe[2];
80
81 if (pipe(stdin_pipe) == -1) {
82 ELOG("Failed to init stdin_pipe\n");
83 return -1;
84 }
85 if (pipe(stdout_pipe) == -1) {
86 ELOG("Failed to init stdout_pipe\n");
87 return -1;
88 }
89
90 /* close standard streams in case i3 is started from a terminal; gdb
91 * needs to run without controlling terminal for it to work properly in
92 * this situation */
93 close(STDIN_FILENO);
94 close(STDOUT_FILENO);
95 close(STDERR_FILENO);
96
97 /* We provide pipe file descriptors for stdin/stdout because gdb < 7.5
98 * crashes otherwise, see
99 * https://sourceware.org/bugzilla/show_bug.cgi?id=14114 */
100 dup2(stdin_pipe[0], STDIN_FILENO);
101 dup2(stdout_pipe[1], STDOUT_FILENO);
102
103 char *pid_s, *gdb_log_cmd;
104 sasprintf(&pid_s, "%d", pid_parent);
105 sasprintf(&gdb_log_cmd, "set logging file %s", filename);
106
107 char *args[] = {
108 "gdb",
109 start_argv[0],
110 "-p",
111 pid_s,
112 "-batch",
113 "-nx",
114 "-ex", gdb_log_cmd,
115 "-ex", "set logging on",
116 "-ex", "bt full",
117 "-ex", "quit",
118 NULL};
119 execvp(args[0], args);
120 DLOG("Failed to exec GDB\n");
121 exit(EXIT_FAILURE);
122 }
123 int status = 0;
124
125 waitpid(pid_gdb, &status, 0);
126
127 /* see if the backtrace was successful or not */
128 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
129 DLOG("GDB did not run properly\n");
130 return -1;
131 } else if (!path_exists(filename)) {
132 DLOG("GDB executed successfully, but no backtrace was generated\n");
133 return -1;
134 }
135 return 1;
136 }
137
138 static void sighandler_setup(void) {
139 border_width = logical_px(border_width);
140 margin = logical_px(margin);
141
142 int num_lines = 5;
143 message_intro = i3string_from_utf8("i3 has just crashed. Please report a bug for this.");
144 message_intro2 = i3string_from_utf8("To debug this problem, you can either attach gdb or choose from the following options:");
145 message_option_backtrace = i3string_from_utf8("- 'b' to save a backtrace (requires gdb)");
146 message_option_restart = i3string_from_utf8("- 'r' to restart i3 in-place");
147 message_option_forget = i3string_from_utf8("- 'f' to forget the previous layout and restart i3");
148
149 int width_longest_message = predict_text_width(message_intro2);
150
151 dialog_width = width_longest_message + 2 * border_width + 2 * margin;
152 dialog_height = num_lines * config.font.height + 2 * border_width + 2 * margin;
153 }
154
155 static void sighandler_create_dialogs(void) {
156 Output *output;
157 TAILQ_FOREACH (output, &outputs, outputs) {
158 if (!output->active) {
159 continue;
160 }
161
162 dialog_t *dialog = scalloc(1, sizeof(struct dialog_t));
163 TAILQ_INSERT_TAIL(&dialogs, dialog, dialogs);
164
165 xcb_visualid_t visual = get_visualid_by_depth(root_depth);
166 dialog->colormap = xcb_generate_id(conn);
167 xcb_create_colormap(conn, XCB_COLORMAP_ALLOC_NONE, dialog->colormap, root, visual);
168
169 uint32_t mask = 0;
170 uint32_t values[4];
171 int i = 0;
172
173 /* Needs to be set in the case of a 32-bit root depth. */
174 mask |= XCB_CW_BACK_PIXEL;
175 values[i++] = root_screen->black_pixel;
176
177 /* Needs to be set in the case of a 32-bit root depth. */
178 mask |= XCB_CW_BORDER_PIXEL;
179 values[i++] = root_screen->black_pixel;
180
181 mask |= XCB_CW_OVERRIDE_REDIRECT;
182 values[i++] = 1;
183
184 /* Needs to be set in the case of a 32-bit root depth. */
185 mask |= XCB_CW_COLORMAP;
186 values[i++] = dialog->colormap;
187
188 dialog->dims.x = output->rect.x + (output->rect.width / 2);
189 dialog->dims.y = output->rect.y + (output->rect.height / 2);
190 dialog->dims.width = dialog_width;
191 dialog->dims.height = dialog_height;
192
193 /* Make sure the dialog is centered. */
194 dialog->dims.x -= dialog->dims.width / 2;
195 dialog->dims.y -= dialog->dims.height / 2;
196
197 dialog->id = create_window(conn, dialog->dims, root_depth, visual,
198 XCB_WINDOW_CLASS_INPUT_OUTPUT, XCURSOR_CURSOR_POINTER,
199 true, mask, values);
200
201 draw_util_surface_init(conn, &(dialog->surface), dialog->id, get_visualtype_by_id(visual),
202 dialog->dims.width, dialog->dims.height);
203
204 xcb_grab_keyboard(conn, false, dialog->id, XCB_CURRENT_TIME, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
205
206 /* Confine the pointer to the crash dialog. */
207 xcb_grab_pointer(conn, false, dialog->id, XCB_NONE, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, dialog->id,
208 XCB_NONE, XCB_CURRENT_TIME);
209 }
210
211 sighandler_handle_expose();
212 xcb_flush(conn);
213 }
214
215 static void sighandler_destroy_dialogs(void) {
216 while (!TAILQ_EMPTY(&dialogs)) {
217 dialog_t *dialog = TAILQ_FIRST(&dialogs);
218
219 xcb_free_colormap(conn, dialog->colormap);
220 draw_util_surface_free(conn, &(dialog->surface));
221 xcb_destroy_window(conn, dialog->id);
222
223 TAILQ_REMOVE(&dialogs, dialog, dialogs);
224 free(dialog);
225 }
226
227 xcb_flush(conn);
228 }
229
230 static void sighandler_handle_expose(void) {
231 dialog_t *current;
232 TAILQ_FOREACH (current, &dialogs, dialogs) {
233 sighandler_draw_dialog(current);
234 }
235
236 xcb_flush(conn);
237 }
238
239 static void sighandler_draw_dialog(dialog_t *dialog) {
240 const color_t black = draw_util_hex_to_color("#000000");
241 const color_t white = draw_util_hex_to_color("#FFFFFF");
242 const color_t red = draw_util_hex_to_color("#FF0000");
243
244 /* Start with a clean slate and draw a red border. */
245 draw_util_clear_surface(&(dialog->surface), red);
246 draw_util_rectangle(&(dialog->surface), black, border_width, border_width,
247 dialog->dims.width - 2 * border_width, dialog->dims.height - 2 * border_width);
248
249 int y = border_width + margin;
250 const int x = border_width + margin;
251 const int max_width = dialog->dims.width - 2 * x;
252
253 draw_util_text(message_intro, &(dialog->surface), white, black, x, y, max_width);
254 y += config.font.height;
255
256 draw_util_text(message_intro2, &(dialog->surface), white, black, x, y, max_width);
257 y += config.font.height;
258
259 char *bt_color = "#FFFFFF";
260 if (backtrace_done < 0) {
261 bt_color = "#AA0000";
262 } else if (backtrace_done > 0) {
263 bt_color = "#00AA00";
264 }
265 draw_util_text(message_option_backtrace, &(dialog->surface), draw_util_hex_to_color(bt_color), black, x, y, max_width);
266 y += config.font.height;
267
268 draw_util_text(message_option_restart, &(dialog->surface), white, black, x, y, max_width);
269 y += config.font.height;
270
271 draw_util_text(message_option_forget, &(dialog->surface), white, black, x, y, max_width);
272 y += config.font.height;
273 }
274
275 static void sighandler_handle_key_press(xcb_key_press_event_t *event) {
276 uint16_t state = event->state;
277
278 /* Apparently, after activating numlock once, the numlock modifier
279 * stays turned on (use xev(1) to verify). So, to resolve useful
280 * keysyms, we remove the numlock flag from the event state */
281 state &= ~xcb_numlock_mask;
282
283 xcb_keysym_t sym = xcb_key_press_lookup_keysym(keysyms, event, state);
284
285 if (sym == 'b') {
286 DLOG("User issued core-dump command.\n");
287
288 /* fork and exec/attach GDB to the parent to get a backtrace in the
289 * tmpdir */
290 backtrace_done = sighandler_backtrace();
291 sighandler_handle_expose();
292 } else if (sym == 'r') {
293 sighandler_destroy_dialogs();
294 i3_restart(false);
295 } else if (sym == 'f') {
296 sighandler_destroy_dialogs();
297 i3_restart(true);
298 }
299 }
300
301 static void handle_signal(int sig, siginfo_t *info, void *data) {
302 DLOG("i3 crashed. SIG: %d\n", sig);
303
304 struct sigaction action;
305 action.sa_handler = SIG_DFL;
306 action.sa_flags = 0;
307 sigemptyset(&action.sa_mask);
308 sigaction(sig, &action, NULL);
309 raised_signal = sig;
310
311 sighandler_setup();
312 sighandler_create_dialogs();
313
314 xcb_generic_event_t *event;
315 /* Yay, more own eventhandlers… */
316 while ((event = xcb_wait_for_event(conn))) {
317 /* Strip off the highest bit (set if the event is generated) */
318 int type = (event->response_type & 0x7F);
319 switch (type) {
320 case XCB_KEY_PRESS:
321 sighandler_handle_key_press((xcb_key_press_event_t *)event);
322 break;
323 case XCB_EXPOSE:
324 if (((xcb_expose_event_t *)event)->count == 0) {
325 sighandler_handle_expose();
326 }
327
328 break;
329 }
330
331 free(event);
332 }
333 }
334
335 /*
336 * Configured a signal handler to gracefully handle crashes and allow the user
337 * to generate a backtrace and rescue their session.
338 *
339 */
340 void setup_signal_handler(void) {
341 struct sigaction action;
342
343 action.sa_sigaction = handle_signal;
344 action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
345 sigemptyset(&action.sa_mask);
346
347 /* Catch all signals with default action "Core", see signal(7) */
348 if (sigaction(SIGQUIT, &action, NULL) == -1 ||
349 sigaction(SIGILL, &action, NULL) == -1 ||
350 sigaction(SIGABRT, &action, NULL) == -1 ||
351 sigaction(SIGFPE, &action, NULL) == -1 ||
352 sigaction(SIGSEGV, &action, NULL) == -1)
353 ELOG("Could not setup signal handler.\n");
354 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * startup.c: Startup notification code. Ensures a startup notification context
7 * is setup when launching applications. We store the current
8 * workspace to open windows in that startup notification context on
9 * the appropriate workspace.
10 *
11 */
12 #include "all.h"
13
14 #include "sd-daemon.h"
15
16 #include <sys/types.h>
17 #include <sys/wait.h>
18 #include <paths.h>
19
20 #define SN_API_NOT_YET_FROZEN 1
21 #include <libsn/sn-launcher.h>
22
23 static TAILQ_HEAD(startup_sequence_head, Startup_Sequence) startup_sequences =
24 TAILQ_HEAD_INITIALIZER(startup_sequences);
25
26 /*
27 * After 60 seconds, a timeout will be triggered for each startup sequence.
28 *
29 * The timeout will just trigger completion of the sequence, so the normal
30 * completion process takes place (startup_monitor_event will free it).
31 *
32 */
33 static void startup_timeout(EV_P_ ev_timer *w, int revents) {
34 const char *id = sn_launcher_context_get_startup_id(w->data);
35 DLOG("Timeout for startup sequence %s\n", id);
36
37 struct Startup_Sequence *current, *sequence = NULL;
38 TAILQ_FOREACH (current, &startup_sequences, sequences) {
39 if (strcmp(current->id, id) != 0)
40 continue;
41
42 sequence = current;
43 break;
44 }
45
46 /* Unref the context (for the timeout itself, see start_application) */
47 sn_launcher_context_unref(w->data);
48
49 if (!sequence) {
50 DLOG("Sequence already deleted, nevermind.\n");
51 free(w);
52 return;
53 }
54
55 /* Complete the startup sequence, will trigger its deletion. */
56 sn_launcher_context_complete(w->data);
57 free(w);
58 }
59
60 /*
61 * Some applications (such as Firefox) mark a startup sequence as completed
62 * *before* they even map a window. Therefore, we cannot entirely delete the
63 * startup sequence once it’s marked as complete. Instead, we’ll mark it for
64 * deletion in 30 seconds and use that chance to delete old sequences.
65 *
66 * This function returns the number of active (!) startup notifications, that
67 * is, those which are not marked for deletion yet. This is used for changing
68 * the root window cursor.
69 *
70 */
71 static int _prune_startup_sequences(void) {
72 time_t current_time = time(NULL);
73 int active_sequences = 0;
74
75 /* Traverse the list and delete everything which was marked for deletion 30
76 * seconds ago or earlier. */
77 struct Startup_Sequence *current, *next;
78 for (next = TAILQ_FIRST(&startup_sequences);
79 next != TAILQ_END(&startup_sequences);) {
80 current = next;
81 next = TAILQ_NEXT(next, sequences);
82
83 if (current->delete_at == 0) {
84 active_sequences++;
85 continue;
86 }
87
88 if (current_time <= current->delete_at)
89 continue;
90
91 startup_sequence_delete(current);
92 }
93
94 return active_sequences;
95 }
96
97 /*
98 * Deletes a startup sequence, ignoring whether its timeout has elapsed.
99 * Useful when e.g. a window is moved between workspaces and its children
100 * shouldn't spawn on the original workspace.
101 *
102 */
103 void startup_sequence_delete(struct Startup_Sequence *sequence) {
104 assert(sequence != NULL);
105 DLOG("Deleting startup sequence %s, delete_at = %lld, current_time = %lld\n",
106 sequence->id, (long long)sequence->delete_at, (long long)time(NULL));
107
108 /* Unref the context, will be free()d */
109 sn_launcher_context_unref(sequence->context);
110
111 /* Delete our internal sequence */
112 TAILQ_REMOVE(&startup_sequences, sequence, sequences);
113
114 free(sequence->id);
115 free(sequence->workspace);
116 FREE(sequence);
117 }
118
119 /*
120 * Starts the given application by passing it through a shell. We use double
121 * fork to avoid zombie processes. As the started application’s parent exits
122 * (immediately), the application is reparented to init (process-id 1), which
123 * correctly handles children, so we don’t have to do it :-).
124 *
125 * The shell used to start applications is the system's bourne shell (i.e.,
126 * /bin/sh).
127 *
128 * The no_startup_id flag determines whether a startup notification context
129 * (and ID) should be created, which is the default and encouraged behavior.
130 *
131 */
132 void start_application(const char *command, bool no_startup_id) {
133 SnLauncherContext *context = NULL;
134
135 if (!no_startup_id) {
136 /* Create a startup notification context to monitor the progress of this
137 * startup. */
138 context = sn_launcher_context_new(sndisplay, conn_screen);
139 sn_launcher_context_set_name(context, "i3");
140 sn_launcher_context_set_description(context, "exec command in i3");
141 /* Chop off everything starting from the first space (if there are any
142 * spaces in the command), since we don’t want the parameters. */
143 char *first_word = sstrdup(command);
144 char *space = strchr(first_word, ' ');
145 if (space)
146 *space = '\0';
147 sn_launcher_context_initiate(context, "i3", first_word, last_timestamp);
148 free(first_word);
149
150 /* Trigger a timeout after 60 seconds */
151 struct ev_timer *timeout = scalloc(1, sizeof(struct ev_timer));
152 ev_timer_init(timeout, startup_timeout, 60.0, 0.);
153 timeout->data = context;
154 ev_timer_start(main_loop, timeout);
155
156 LOG("startup id = %s\n", sn_launcher_context_get_startup_id(context));
157
158 /* Save the ID and current workspace in our internal list of startup
159 * sequences */
160 Con *ws = con_get_workspace(focused);
161 struct Startup_Sequence *sequence = scalloc(1, sizeof(struct Startup_Sequence));
162 sequence->id = sstrdup(sn_launcher_context_get_startup_id(context));
163 sequence->workspace = sstrdup(ws->name);
164 sequence->context = context;
165 TAILQ_INSERT_TAIL(&startup_sequences, sequence, sequences);
166
167 /* Increase the refcount once (it starts with 1, so it will be 2 now) for
168 * the timeout. Even if the sequence gets completed, the timeout still
169 * needs the context (but will unref it then) */
170 sn_launcher_context_ref(context);
171 }
172
173 LOG("executing: %s\n", command);
174 if (fork() == 0) {
175 /* Child process */
176 setsid();
177 setrlimit(RLIMIT_CORE, &original_rlimit_core);
178 /* Close all socket activation file descriptors explicitly, we disabled
179 * FD_CLOEXEC to keep them open when restarting i3. */
180 for (int fd = SD_LISTEN_FDS_START;
181 fd < (SD_LISTEN_FDS_START + listen_fds);
182 fd++) {
183 close(fd);
184 }
185 unsetenv("LISTEN_PID");
186 unsetenv("LISTEN_FDS");
187 signal(SIGPIPE, SIG_DFL);
188 if (fork() == 0) {
189 /* Setup the environment variable(s) */
190 if (!no_startup_id)
191 sn_launcher_context_setup_child_process(context);
192 setenv("I3SOCK", current_socketpath, 1);
193
194 execl(_PATH_BSHELL, _PATH_BSHELL, "-c", command, NULL);
195 /* not reached */
196 }
197 _exit(EXIT_SUCCESS);
198 }
199 wait(0);
200
201 if (!no_startup_id) {
202 /* Change the pointer of the root window to indicate progress */
203 xcursor_set_root_cursor(XCURSOR_CURSOR_WATCH);
204 }
205 }
206
207 /*
208 * Called by libstartup-notification when something happens
209 *
210 */
211 void startup_monitor_event(SnMonitorEvent *event, void *userdata) {
212 SnStartupSequence *snsequence;
213
214 snsequence = sn_monitor_event_get_startup_sequence(event);
215
216 /* Get the corresponding internal startup sequence */
217 const char *id = sn_startup_sequence_get_id(snsequence);
218 struct Startup_Sequence *current, *sequence = NULL;
219 TAILQ_FOREACH (current, &startup_sequences, sequences) {
220 if (strcmp(current->id, id) != 0)
221 continue;
222
223 sequence = current;
224 break;
225 }
226
227 if (!sequence) {
228 DLOG("Got event for startup sequence that we did not initiate (ID = %s). Ignoring.\n", id);
229 return;
230 }
231
232 switch (sn_monitor_event_get_type(event)) {
233 case SN_MONITOR_EVENT_COMPLETED:
234 DLOG("startup sequence %s completed\n", sn_startup_sequence_get_id(snsequence));
235
236 /* Mark the given sequence for deletion in 30 seconds. */
237 time_t current_time = time(NULL);
238 sequence->delete_at = current_time + 30;
239 DLOG("Will delete startup sequence %s at timestamp %lld\n",
240 sequence->id, (long long)sequence->delete_at);
241
242 if (_prune_startup_sequences() == 0) {
243 DLOG("No more startup sequences running, changing root window cursor to default pointer.\n");
244 /* Change the pointer of the root window to indicate progress */
245 xcursor_set_root_cursor(XCURSOR_CURSOR_POINTER);
246 }
247 break;
248 default:
249 /* ignore */
250 break;
251 }
252 }
253
254 /*
255 * Renames workspaces that are mentioned in the startup sequences.
256 *
257 */
258 void startup_sequence_rename_workspace(const char *old_name, const char *new_name) {
259 struct Startup_Sequence *current;
260 TAILQ_FOREACH (current, &startup_sequences, sequences) {
261 if (strcmp(current->workspace, old_name) != 0)
262 continue;
263 DLOG("Renaming workspace \"%s\" to \"%s\" in startup sequence %s.\n",
264 old_name, new_name, current->id);
265 free(current->workspace);
266 current->workspace = sstrdup(new_name);
267 }
268 }
269
270 /*
271 * Gets the stored startup sequence for the _NET_STARTUP_ID of a given window.
272 *
273 */
274 struct Startup_Sequence *startup_sequence_get(i3Window *cwindow,
275 xcb_get_property_reply_t *startup_id_reply, bool ignore_mapped_leader) {
276 /* The _NET_STARTUP_ID is only needed during this function, so we get it
277 * here and don’t save it in the 'cwindow'. */
278 if (startup_id_reply == NULL || xcb_get_property_value_length(startup_id_reply) == 0) {
279 FREE(startup_id_reply);
280 DLOG("No _NET_STARTUP_ID set on window 0x%08x\n", cwindow->id);
281 if (cwindow->leader == XCB_NONE)
282 return NULL;
283
284 /* This is a special case that causes the leader's startup sequence
285 * to only be returned if it has never been mapped, useful primarily
286 * when trying to delete a sequence.
287 *
288 * It's generally inappropriate to delete a leader's sequence when
289 * moving a child window, but if the leader has no container, it's
290 * likely permanently unmapped and the child is the "real" window. */
291 if (ignore_mapped_leader && con_by_window_id(cwindow->leader) != NULL) {
292 DLOG("Ignoring leader window 0x%08x\n", cwindow->leader);
293 return NULL;
294 }
295
296 DLOG("Checking leader window 0x%08x\n", cwindow->leader);
297
298 xcb_get_property_cookie_t cookie;
299
300 cookie = xcb_get_property(conn, false, cwindow->leader,
301 A__NET_STARTUP_ID, XCB_GET_PROPERTY_TYPE_ANY, 0, 512);
302 startup_id_reply = xcb_get_property_reply(conn, cookie, NULL);
303
304 if (startup_id_reply == NULL ||
305 xcb_get_property_value_length(startup_id_reply) == 0) {
306 FREE(startup_id_reply);
307 DLOG("No _NET_STARTUP_ID set on the leader either\n");
308 return NULL;
309 }
310 }
311
312 char *startup_id;
313 sasprintf(&startup_id, "%.*s", xcb_get_property_value_length(startup_id_reply),
314 (char *)xcb_get_property_value(startup_id_reply));
315 struct Startup_Sequence *current, *sequence = NULL;
316 TAILQ_FOREACH (current, &startup_sequences, sequences) {
317 if (strcmp(current->id, startup_id) != 0)
318 continue;
319
320 sequence = current;
321 break;
322 }
323
324 if (!sequence) {
325 DLOG("WARNING: This sequence (ID %s) was not found\n", startup_id);
326 free(startup_id);
327 free(startup_id_reply);
328 return NULL;
329 }
330
331 free(startup_id);
332 free(startup_id_reply);
333
334 return sequence;
335 }
336
337 /*
338 * Checks if the given window belongs to a startup notification by checking if
339 * the _NET_STARTUP_ID property is set on the window (or on its leader, if it’s
340 * unset).
341 *
342 * If so, returns the workspace on which the startup was initiated.
343 * Returns NULL otherwise.
344 *
345 */
346 char *startup_workspace_for_window(i3Window *cwindow, xcb_get_property_reply_t *startup_id_reply) {
347 struct Startup_Sequence *sequence = startup_sequence_get(cwindow, startup_id_reply, false);
348 if (sequence == NULL)
349 return NULL;
350
351 /* If the startup sequence's time span has elapsed, delete it. */
352 time_t current_time = time(NULL);
353 if (sequence->delete_at > 0 && current_time > sequence->delete_at) {
354 DLOG("Deleting expired startup sequence %s\n", sequence->id);
355 startup_sequence_delete(sequence);
356 return NULL;
357 }
358
359 return sequence->workspace;
360 }
361
362 /*
363 * Deletes the startup sequence for a window if it exists.
364 *
365 */
366 void startup_sequence_delete_by_window(i3Window *win) {
367 struct Startup_Sequence *sequence;
368 xcb_get_property_cookie_t cookie;
369 xcb_get_property_reply_t *startup_id_reply;
370
371 cookie = xcb_get_property(conn, false, win->id, A__NET_STARTUP_ID,
372 XCB_GET_PROPERTY_TYPE_ANY, 0, 512);
373 startup_id_reply = xcb_get_property_reply(conn, cookie, NULL);
374
375 sequence = startup_sequence_get(win, startup_id_reply, true);
376 if (sequence != NULL) {
377 startup_sequence_delete(sequence);
378 }
379 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * sync.c: i3 sync protocol: https://i3wm.org/docs/testsuite.html#i3_sync
7 *
8 */
9 #include "all.h"
10
11 void sync_respond(xcb_window_t window, uint32_t rnd) {
12 DLOG("[i3 sync protocol] Sending random value %d back to X11 window 0x%08x\n", rnd, window);
13
14 void *reply = scalloc(32, 1);
15 xcb_client_message_event_t *ev = reply;
16
17 ev->response_type = XCB_CLIENT_MESSAGE;
18 ev->window = window;
19 ev->type = A_I3_SYNC;
20 ev->format = 32;
21 ev->data.data32[0] = window;
22 ev->data.data32[1] = rnd;
23
24 xcb_send_event(conn, false, window, XCB_EVENT_MASK_NO_EVENT, (char *)ev);
25 xcb_flush(conn);
26 free(reply);
27 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * tree.c: Everything that primarily modifies the layout tree data structure.
7 *
8 */
9 #include "all.h"
10
11 struct Con *croot;
12 struct Con *focused;
13
14 struct all_cons_head all_cons = TAILQ_HEAD_INITIALIZER(all_cons);
15
16 /*
17 * Create the pseudo-output __i3. Output-independent workspaces such as
18 * __i3_scratch will live there.
19 *
20 */
21 static Con *_create___i3(void) {
22 Con *__i3 = con_new(croot, NULL);
23 FREE(__i3->name);
24 __i3->name = sstrdup("__i3");
25 __i3->type = CT_OUTPUT;
26 __i3->layout = L_OUTPUT;
27 con_fix_percent(croot);
28 x_set_name(__i3, "[i3 con] pseudo-output __i3");
29 /* For retaining the correct position/size of a scratchpad window, the
30 * dimensions of the real outputs should be multiples of the __i3
31 * pseudo-output. Ensuring that is the job of scratchpad_fix_resolution()
32 * which gets called after this function and after detecting all the
33 * outputs (or whenever an output changes). */
34 __i3->rect.width = 1280;
35 __i3->rect.height = 1024;
36
37 /* Add a content container. */
38 DLOG("adding main content container\n");
39 Con *content = con_new(NULL, NULL);
40 content->type = CT_CON;
41 FREE(content->name);
42 content->name = sstrdup("content");
43 content->layout = L_SPLITH;
44
45 x_set_name(content, "[i3 con] content __i3");
46 con_attach(content, __i3, false);
47
48 /* Attach the __i3_scratch workspace. */
49 Con *ws = con_new(NULL, NULL);
50 ws->type = CT_WORKSPACE;
51 ws->num = -1;
52 ws->name = sstrdup("__i3_scratch");
53 ws->layout = L_SPLITH;
54 con_attach(ws, content, false);
55 x_set_name(ws, "[i3 con] workspace __i3_scratch");
56 ws->fullscreen_mode = CF_OUTPUT;
57
58 return __i3;
59 }
60
61 /*
62 * Loads tree from 'path' (used for in-place restarts).
63 *
64 */
65 bool tree_restore(const char *path, xcb_get_geometry_reply_t *geometry) {
66 bool result = false;
67 char *globbed = resolve_tilde(path);
68 char *buf = NULL;
69
70 if (!path_exists(globbed)) {
71 LOG("%s does not exist, not restoring tree\n", globbed);
72 goto out;
73 }
74
75 ssize_t len;
76 if ((len = slurp(globbed, &buf)) < 0) {
77 /* slurp already logged an error. */
78 goto out;
79 }
80
81 /* TODO: refactor the following */
82 croot = con_new(NULL, NULL);
83 croot->rect = (Rect){
84 geometry->x,
85 geometry->y,
86 geometry->width,
87 geometry->height};
88 focused = croot;
89
90 tree_append_json(focused, buf, len, NULL);
91
92 DLOG("appended tree, using new root\n");
93 croot = TAILQ_FIRST(&(croot->nodes_head));
94 if (!croot) {
95 /* tree_append_json failed. Continuing here would segfault. */
96 goto out;
97 }
98 DLOG("new root = %p\n", croot);
99 Con *out = TAILQ_FIRST(&(croot->nodes_head));
100 DLOG("out = %p\n", out);
101 Con *ws = TAILQ_FIRST(&(out->nodes_head));
102 DLOG("ws = %p\n", ws);
103
104 /* For in-place restarting into v4.2, we need to make sure the new
105 * pseudo-output __i3 is present. */
106 if (strcmp(out->name, "__i3") != 0) {
107 DLOG("Adding pseudo-output __i3 during inplace restart\n");
108 Con *__i3 = _create___i3();
109 /* Ensure that it is the first output, other places in the code make
110 * that assumption. */
111 TAILQ_REMOVE(&(croot->nodes_head), __i3, nodes);
112 TAILQ_INSERT_HEAD(&(croot->nodes_head), __i3, nodes);
113 }
114
115 restore_open_placeholder_windows(croot);
116 result = true;
117
118 out:
119 free(globbed);
120 free(buf);
121 return result;
122 }
123
124 /*
125 * Initializes the tree by creating the root node. The CT_OUTPUT Cons below the
126 * root node are created in randr.c for each Output.
127 *
128 */
129 void tree_init(xcb_get_geometry_reply_t *geometry) {
130 croot = con_new(NULL, NULL);
131 FREE(croot->name);
132 croot->name = "root";
133 croot->type = CT_ROOT;
134 croot->layout = L_SPLITH;
135 croot->rect = (Rect){
136 geometry->x,
137 geometry->y,
138 geometry->width,
139 geometry->height};
140
141 _create___i3();
142 }
143
144 /*
145 * Opens an empty container in the current container
146 *
147 */
148 Con *tree_open_con(Con *con, i3Window *window) {
149 if (con == NULL) {
150 /* every focusable Con has a parent (outputs have parent root) */
151 con = focused->parent;
152 /* If the parent is an output, we are on a workspace. In this case,
153 * the new container needs to be opened as a leaf of the workspace. */
154 if (con->parent->type == CT_OUTPUT && con->type != CT_DOCKAREA) {
155 con = focused;
156 }
157
158 /* If the currently focused container is a floating container, we
159 * attach the new container to the currently focused spot in its
160 * workspace. */
161 if (con->type == CT_FLOATING_CON) {
162 con = con_descend_tiling_focused(con->parent);
163 if (con->type != CT_WORKSPACE)
164 con = con->parent;
165 }
166 DLOG("con = %p\n", con);
167 }
168
169 assert(con != NULL);
170
171 /* 3. create the container and attach it to its parent */
172 Con *new = con_new(con, window);
173 new->layout = L_SPLITH;
174
175 /* 4: re-calculate child->percent for each child */
176 con_fix_percent(con);
177
178 return new;
179 }
180
181 /*
182 * Closes the given container including all children.
183 * Returns true if the container was killed or false if just WM_DELETE was sent
184 * and the window is expected to kill itself.
185 *
186 * The dont_kill_parent flag is specified when the function calls itself
187 * recursively while deleting a containers children.
188 *
189 */
190 bool tree_close_internal(Con *con, kill_window_t kill_window, bool dont_kill_parent) {
191 Con *parent = con->parent;
192
193 /* remove the urgency hint of the workspace (if set) */
194 if (con->urgent) {
195 con_set_urgency(con, false);
196 con_update_parents_urgency(con);
197 workspace_update_urgent_flag(con_get_workspace(con));
198 }
199
200 DLOG("closing %p, kill_window = %d\n", con, kill_window);
201 Con *child, *nextchild;
202 bool abort_kill = false;
203 /* We cannot use TAILQ_FOREACH because the children get deleted
204 * in their parent’s nodes_head */
205 for (child = TAILQ_FIRST(&(con->nodes_head)); child;) {
206 nextchild = TAILQ_NEXT(child, nodes);
207 DLOG("killing child=%p\n", child);
208 if (!tree_close_internal(child, kill_window, true)) {
209 abort_kill = true;
210 }
211 child = nextchild;
212 }
213
214 if (abort_kill) {
215 DLOG("One of the children could not be killed immediately (WM_DELETE sent), aborting.\n");
216 return false;
217 }
218
219 if (con->window != NULL) {
220 if (kill_window != DONT_KILL_WINDOW) {
221 x_window_kill(con->window->id, kill_window);
222 return false;
223 } else {
224 xcb_void_cookie_t cookie;
225 /* Ignore any further events by clearing the event mask,
226 * unmap the window,
227 * then reparent it to the root window. */
228 xcb_change_window_attributes(conn, con->window->id,
229 XCB_CW_EVENT_MASK, (uint32_t[]){XCB_NONE});
230 xcb_unmap_window(conn, con->window->id);
231 cookie = xcb_reparent_window(conn, con->window->id, root, con->rect.x, con->rect.y);
232
233 /* Ignore X11 errors for the ReparentWindow request.
234 * X11 Errors are returned when the window was already destroyed */
235 add_ignore_event(cookie.sequence, 0);
236
237 /* We are no longer handling this window, thus set WM_STATE to
238 * WM_STATE_WITHDRAWN (see ICCCM 4.1.3.1) */
239 long data[] = {XCB_ICCCM_WM_STATE_WITHDRAWN, XCB_NONE};
240 cookie = xcb_change_property(conn, XCB_PROP_MODE_REPLACE,
241 con->window->id, A_WM_STATE, A_WM_STATE, 32, 2, data);
242
243 /* Remove the window from the save set. All windows in the save set
244 * will be mapped when i3 closes its connection (e.g. when
245 * restarting). This is not what we want, since some apps keep
246 * unmapped windows around and don’t expect them to suddenly be
247 * mapped. See https://bugs.i3wm.org/1617 */
248 xcb_change_save_set(conn, XCB_SET_MODE_DELETE, con->window->id);
249
250 /* Stop receiving ShapeNotify events. */
251 if (shape_supported) {
252 xcb_shape_select_input(conn, con->window->id, false);
253 }
254
255 /* Ignore X11 errors for the ReparentWindow request.
256 * X11 Errors are returned when the window was already destroyed */
257 add_ignore_event(cookie.sequence, 0);
258 }
259 ipc_send_window_event("close", con);
260 window_free(con->window);
261 con->window = NULL;
262 }
263
264 Con *ws = con_get_workspace(con);
265
266 /* Figure out which container to focus next before detaching 'con'. */
267 Con *next = (con == focused) ? con_next_focused(con) : NULL;
268 DLOG("next = %p, focused = %p\n", next, focused);
269
270 /* Detach the container so that it will not be rendered anymore. */
271 con_detach(con);
272
273 /* disable urgency timer, if needed */
274 if (con->urgency_timer != NULL) {
275 DLOG("Removing urgency timer of con %p\n", con);
276 workspace_update_urgent_flag(ws);
277 ev_timer_stop(main_loop, con->urgency_timer);
278 FREE(con->urgency_timer);
279 }
280
281 if (con->type != CT_FLOATING_CON) {
282 /* If the container is *not* floating, we might need to re-distribute
283 * percentage values for the resized containers. */
284 con_fix_percent(parent);
285 }
286
287 /* Render the tree so that the surrounding containers take up the space
288 * which 'con' does no longer occupy. If we don’t render here, there will
289 * be a gap in our containers and that could trigger an EnterNotify for an
290 * underlying container, see ticket #660.
291 *
292 * Rendering has to be avoided when dont_kill_parent is set (when
293 * tree_close_internal calls itself recursively) because the tree is in a
294 * non-renderable state during that time. */
295 if (!dont_kill_parent)
296 tree_render();
297
298 /* kill the X11 part of this container */
299 x_con_kill(con);
300
301 if (ws == con) {
302 DLOG("Closing workspace container %s, updating EWMH atoms\n", ws->name);
303 ewmh_update_desktop_properties();
304 }
305
306 con_free(con);
307
308 if (next) {
309 con_activate(next);
310 } else {
311 DLOG("not changing focus, the container was not focused before\n");
312 }
313
314 /* check if the parent container is empty now and close it */
315 if (!dont_kill_parent)
316 CALL(parent, on_remove_child);
317
318 return true;
319 }
320
321 /*
322 * Splits (horizontally or vertically) the given container by creating a new
323 * container which contains the old one and the future ones.
324 *
325 */
326 void tree_split(Con *con, orientation_t orientation) {
327 if (con_is_floating(con)) {
328 DLOG("Floating containers can't be split.\n");
329 return;
330 }
331
332 if (con->type == CT_WORKSPACE) {
333 if (con_num_children(con) < 2) {
334 if (con_num_children(con) == 0) {
335 DLOG("Changing workspace_layout to L_DEFAULT\n");
336 con->workspace_layout = L_DEFAULT;
337 }
338 DLOG("Changing orientation of workspace\n");
339 con->layout = (orientation == HORIZ) ? L_SPLITH : L_SPLITV;
340 return;
341 } else {
342 /* if there is more than one container on the workspace
343 * move them into a new container and handle this instead */
344 con = workspace_encapsulate(con);
345 }
346 }
347
348 Con *parent = con->parent;
349
350 /* Force re-rendering to make the indicator border visible. */
351 con_force_split_parents_redraw(con);
352
353 /* if we are in a container whose parent contains only one
354 * child (its split functionality is unused so far), we just change the
355 * orientation (more intuitive than splitting again) */
356 if (con_num_children(parent) == 1 &&
357 (parent->layout == L_SPLITH ||
358 parent->layout == L_SPLITV)) {
359 parent->layout = (orientation == HORIZ) ? L_SPLITH : L_SPLITV;
360 DLOG("Just changing orientation of existing container\n");
361 return;
362 }
363
364 DLOG("Splitting in orientation %d\n", orientation);
365
366 /* 2: replace it with a new Con */
367 Con *new = con_new(NULL, NULL);
368 TAILQ_REPLACE(&(parent->nodes_head), con, new, nodes);
369 TAILQ_REPLACE(&(parent->focus_head), con, new, focused);
370 new->parent = parent;
371 new->layout = (orientation == HORIZ) ? L_SPLITH : L_SPLITV;
372
373 /* 3: swap 'percent' (resize factor) */
374 new->percent = con->percent;
375 con->percent = 0.0;
376
377 /* 4: add it as a child to the new Con */
378 con_attach(con, new, false);
379 }
380
381 /*
382 * Moves focus one level up. Returns true if focus changed.
383 *
384 */
385 bool level_up(void) {
386 /* Skip over floating containers and go directly to the grandparent
387 * (which should always be a workspace) */
388 if (focused->parent->type == CT_FLOATING_CON) {
389 con_activate(focused->parent->parent);
390 return true;
391 }
392
393 /* We can focus up to the workspace, but not any higher in the tree */
394 if ((focused->parent->type != CT_CON &&
395 focused->parent->type != CT_WORKSPACE) ||
396 focused->type == CT_WORKSPACE) {
397 ELOG("'focus parent': Focus is already on the workspace, cannot go higher than that.\n");
398 return false;
399 }
400 con_activate(focused->parent);
401 return true;
402 }
403
404 /*
405 * Moves focus one level down. Returns true if focus changed.
406 *
407 */
408 bool level_down(void) {
409 /* Go down the focus stack of the current node */
410 Con *next = TAILQ_FIRST(&(focused->focus_head));
411 if (next == TAILQ_END(&(focused->focus_head))) {
412 DLOG("cannot go down\n");
413 return false;
414 } else if (next->type == CT_FLOATING_CON) {
415 /* Floating cons shouldn't be directly focused; try immediately
416 * going to the grandchild of the focused con. */
417 Con *child = TAILQ_FIRST(&(next->focus_head));
418 if (child == TAILQ_END(&(next->focus_head))) {
419 DLOG("cannot go down\n");
420 return false;
421 } else
422 next = TAILQ_FIRST(&(next->focus_head));
423 }
424
425 con_activate(next);
426 return true;
427 }
428
429 static void mark_unmapped(Con *con) {
430 Con *current;
431
432 con->mapped = false;
433 TAILQ_FOREACH (current, &(con->nodes_head), nodes) {
434 mark_unmapped(current);
435 }
436 if (con->type == CT_WORKSPACE) {
437 /* We need to call mark_unmapped on floating nodes as well since we can
438 * make containers floating. */
439 TAILQ_FOREACH (current, &(con->floating_head), floating_windows) {
440 mark_unmapped(current);
441 }
442 }
443 }
444
445 /*
446 * Renders the tree, that is rendering all outputs using render_con() and
447 * pushing the changes to X11 using x_push_changes().
448 *
449 */
450 void tree_render(void) {
451 if (croot == NULL)
452 return;
453
454 DLOG("-- BEGIN RENDERING --\n");
455 /* Reset map state for all nodes in tree */
456 /* TODO: a nicer method to walk all nodes would be good, maybe? */
457 mark_unmapped(croot);
458 croot->mapped = true;
459
460 render_con(croot, false);
461
462 x_push_changes(croot);
463 DLOG("-- END RENDERING --\n");
464 }
465
466 static Con *get_tree_next_workspace(Con *con, direction_t direction) {
467 if (con_get_fullscreen_con(con, CF_GLOBAL)) {
468 DLOG("Cannot change workspace while in global fullscreen mode.\n");
469 return NULL;
470 }
471
472 Output *current_output = get_output_containing(con->rect.x, con->rect.y);
473 if (!current_output) {
474 return NULL;
475 }
476 DLOG("Current output is %s\n", output_primary_name(current_output));
477
478 Output *next_output = get_output_next(direction, current_output, CLOSEST_OUTPUT);
479 if (!next_output) {
480 return NULL;
481 }
482 DLOG("Next output is %s\n", output_primary_name(next_output));
483
484 /* Find visible workspace on next output */
485 Con *workspace = NULL;
486 GREP_FIRST(workspace, output_get_content(next_output->con), workspace_is_visible(child));
487 return workspace;
488 }
489
490 /*
491 * Returns the next / previous container to focus in the given direction. Does
492 * not modify focus and ensures focus restrictions for fullscreen containers
493 * are respected.
494 *
495 */
496 static Con *get_tree_next(Con *con, direction_t direction) {
497 const bool previous = position_from_direction(direction) == BEFORE;
498 const orientation_t orientation = orientation_from_direction(direction);
499
500 Con *first_wrap = NULL;
501
502 if (con->type == CT_WORKSPACE) {
503 /* Special case for FOCUS_WRAPPING_WORKSPACE: allow the focus to leave
504 * the workspace only when a workspace is selected. */
505 goto handle_workspace;
506 }
507
508 while (con->type != CT_WORKSPACE) {
509 if (con->fullscreen_mode == CF_OUTPUT) {
510 /* We've reached a fullscreen container. Directional focus should
511 * now operate on the workspace level. */
512 con = con_get_workspace(con);
513 break;
514 } else if (con->fullscreen_mode == CF_GLOBAL) {
515 /* Focus changes should happen only inside the children of a global
516 * fullscreen container. */
517 return first_wrap;
518 }
519
520 Con *const parent = con->parent;
521 if (con->type == CT_FLOATING_CON) {
522 if (orientation != HORIZ) {
523 /* up/down does not change floating containers */
524 return NULL;
525 }
526
527 /* left/right focuses the previous/next floating container */
528 Con *next = previous ? TAILQ_PREV(con, floating_head, floating_windows)
529 : TAILQ_NEXT(con, floating_windows);
530 /* If there is no next/previous container, wrap */
531 if (!next) {
532 next = previous ? TAILQ_LAST(&(parent->floating_head), floating_head)
533 : TAILQ_FIRST(&(parent->floating_head));
534 }
535 /* Our parent does not list us in floating heads? */
536 assert(next);
537
538 return next;
539 }
540
541 if (con_num_children(parent) > 1 && con_orientation(parent) == orientation) {
542 Con *const next = previous ? TAILQ_PREV(con, nodes_head, nodes)
543 : TAILQ_NEXT(con, nodes);
544 if (next && con_fullscreen_permits_focusing(next)) {
545 return next;
546 }
547
548 Con *const wrap = previous ? TAILQ_LAST(&(parent->nodes_head), nodes_head)
549 : TAILQ_FIRST(&(parent->nodes_head));
550 switch (config.focus_wrapping) {
551 case FOCUS_WRAPPING_OFF:
552 break;
553 case FOCUS_WRAPPING_WORKSPACE:
554 case FOCUS_WRAPPING_ON:
555 if (!first_wrap && con_fullscreen_permits_focusing(wrap)) {
556 first_wrap = wrap;
557 }
558 break;
559 case FOCUS_WRAPPING_FORCE:
560 /* 'force' should always return to ensure focus doesn't
561 * leave the parent. */
562 if (next) {
563 return NULL; /* blocked by fullscreen */
564 }
565 return con_fullscreen_permits_focusing(wrap) ? wrap : NULL;
566 }
567 }
568
569 con = parent;
570 }
571
572 assert(con->type == CT_WORKSPACE);
573 if (config.focus_wrapping == FOCUS_WRAPPING_WORKSPACE) {
574 return first_wrap;
575 }
576
577 handle_workspace:;
578 Con *workspace = get_tree_next_workspace(con, direction);
579 return workspace ? workspace : first_wrap;
580 }
581
582 /*
583 * Changes focus in the given direction
584 *
585 */
586 void tree_next(Con *con, direction_t direction) {
587 Con *next = get_tree_next(con, direction);
588 if (!next) {
589 return;
590 }
591 if (next->type == CT_WORKSPACE) {
592 /* Show next workspace and focus appropriate container if possible. */
593 /* Use descend_focused first to give higher priority to floating or
594 * tiling fullscreen containers. */
595 Con *focus = con_descend_focused(next);
596 if (focus->fullscreen_mode == CF_NONE) {
597 Con *focus_tiling = con_descend_tiling_focused(next);
598 /* If descend_tiling returned a workspace then focus is either a
599 * floating container or the same workspace. */
600 if (focus_tiling != next) {
601 focus = focus_tiling;
602 }
603 }
604
605 workspace_show(next);
606 con_activate(focus);
607 x_set_warp_to(&(focus->rect));
608 return;
609 } else if (next->type == CT_FLOATING_CON) {
610 /* Raise the floating window on top of other windows preserving relative
611 * stack order */
612 Con *parent = next->parent;
613 while (TAILQ_LAST(&(parent->floating_head), floating_head) != next) {
614 Con *last = TAILQ_LAST(&(parent->floating_head), floating_head);
615 TAILQ_REMOVE(&(parent->floating_head), last, floating_windows);
616 TAILQ_INSERT_HEAD(&(parent->floating_head), last, floating_windows);
617 }
618 }
619
620 workspace_show(con_get_workspace(next));
621 con_activate(con_descend_focused(next));
622 }
623
624 /*
625 * Get the previous / next sibling
626 *
627 */
628 Con *get_tree_next_sibling(Con *con, position_t direction) {
629 Con *to_focus = (direction == BEFORE ? TAILQ_PREV(con, nodes_head, nodes)
630 : TAILQ_NEXT(con, nodes));
631 if (to_focus && con_fullscreen_permits_focusing(to_focus)) {
632 return to_focus;
633 }
634 return NULL;
635 }
636
637 /*
638 * tree_flatten() removes pairs of redundant split containers, e.g.:
639 * [workspace, horizontal]
640 * [v-split] [child3]
641 * [h-split]
642 * [child1] [child2]
643 * In this example, the v-split and h-split container are redundant.
644 * Such a situation can be created by moving containers in a direction which is
645 * not the orientation of their parent container. i3 needs to create a new
646 * split container then and if you move containers this way multiple times,
647 * redundant chains of split-containers can be the result.
648 *
649 */
650 void tree_flatten(Con *con) {
651 Con *current, *child, *parent = con->parent;
652 DLOG("Checking if I can flatten con = %p / %s\n", con, con->name);
653
654 /* We only consider normal containers without windows */
655 if (con->type != CT_CON ||
656 parent->layout == L_OUTPUT || /* con == "content" */
657 con->window != NULL)
658 goto recurse;
659
660 /* Ensure it got only one child */
661 child = TAILQ_FIRST(&(con->nodes_head));
662 if (child == NULL || TAILQ_NEXT(child, nodes) != NULL)
663 goto recurse;
664
665 DLOG("child = %p, con = %p, parent = %p\n", child, con, parent);
666
667 /* The child must have a different orientation than the con but the same as
668 * the con’s parent to be redundant */
669 if (!con_is_split(con) ||
670 !con_is_split(child) ||
671 (con->layout != L_SPLITH && con->layout != L_SPLITV) ||
672 (child->layout != L_SPLITH && child->layout != L_SPLITV) ||
673 con_orientation(con) == con_orientation(child) ||
674 con_orientation(child) != con_orientation(parent))
675 goto recurse;
676
677 DLOG("Alright, I have to flatten this situation now. Stay calm.\n");
678 /* 1: save focus */
679 Con *focus_next = TAILQ_FIRST(&(child->focus_head));
680
681 DLOG("detaching...\n");
682 /* 2: re-attach the children to the parent before con */
683 while (!TAILQ_EMPTY(&(child->nodes_head))) {
684 current = TAILQ_FIRST(&(child->nodes_head));
685 DLOG("detaching current=%p / %s\n", current, current->name);
686 con_detach(current);
687 DLOG("re-attaching\n");
688 /* We don’t use con_attach() here because for a CT_CON, the special
689 * case handling of con_attach() does not trigger. So all it would do
690 * is calling TAILQ_INSERT_AFTER, but with the wrong container. So we
691 * directly use the TAILQ macros. */
692 current->parent = parent;
693 TAILQ_INSERT_BEFORE(con, current, nodes);
694 DLOG("attaching to focus list\n");
695 TAILQ_INSERT_TAIL(&(parent->focus_head), current, focused);
696 current->percent = con->percent;
697 }
698 DLOG("re-attached all\n");
699
700 /* 3: restore focus, if con was focused */
701 if (focus_next != NULL &&
702 TAILQ_FIRST(&(parent->focus_head)) == con) {
703 DLOG("restoring focus to focus_next=%p\n", focus_next);
704 TAILQ_REMOVE(&(parent->focus_head), focus_next, focused);
705 TAILQ_INSERT_HEAD(&(parent->focus_head), focus_next, focused);
706 DLOG("restored focus.\n");
707 }
708
709 /* 4: close the redundant cons */
710 DLOG("closing redundant cons\n");
711 tree_close_internal(con, DONT_KILL_WINDOW, true);
712
713 /* Well, we got to abort the recursion here because we destroyed the
714 * container. However, if tree_flatten() is called sufficiently often,
715 * there can’t be the situation of having two pairs of redundant containers
716 * at once. Therefore, we can safely abort the recursion on this level
717 * after flattening. */
718 return;
719
720 recurse:
721 /* We cannot use normal foreach here because tree_flatten might close the
722 * current container. */
723 current = TAILQ_FIRST(&(con->nodes_head));
724 while (current != NULL) {
725 Con *next = TAILQ_NEXT(current, nodes);
726 tree_flatten(current);
727 current = next;
728 }
729
730 current = TAILQ_FIRST(&(con->floating_head));
731 while (current != NULL) {
732 Con *next = TAILQ_NEXT(current, floating_windows);
733 tree_flatten(current);
734 current = next;
735 }
736 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * util.c: Utility functions, which can be useful everywhere within i3 (see
7 * also libi3).
8 *
9 */
10 #include "all.h"
11
12 #include <sys/wait.h>
13 #include <stdarg.h>
14 #if defined(__OpenBSD__)
15 #include <sys/cdefs.h>
16 #endif
17 #include <fcntl.h>
18 #include <pwd.h>
19 #include <yajl/yajl_version.h>
20 #include <libgen.h>
21 #include <ctype.h>
22
23 #define SN_API_NOT_YET_FROZEN 1
24 #include <libsn/sn-launcher.h>
25
26 int min(int a, int b) {
27 return (a < b ? a : b);
28 }
29
30 int max(int a, int b) {
31 return (a > b ? a : b);
32 }
33
34 bool rect_contains(Rect rect, uint32_t x, uint32_t y) {
35 return (x >= rect.x &&
36 x <= (rect.x + rect.width) &&
37 y >= rect.y &&
38 y <= (rect.y + rect.height));
39 }
40
41 Rect rect_add(Rect a, Rect b) {
42 return (Rect){a.x + b.x,
43 a.y + b.y,
44 a.width + b.width,
45 a.height + b.height};
46 }
47
48 Rect rect_sub(Rect a, Rect b) {
49 return (Rect){a.x - b.x,
50 a.y - b.y,
51 a.width - b.width,
52 a.height - b.height};
53 }
54
55 Rect rect_sanitize_dimensions(Rect rect) {
56 rect.width = (int32_t)rect.width <= 0 ? 1 : rect.width;
57 rect.height = (int32_t)rect.height <= 0 ? 1 : rect.height;
58 return rect;
59 }
60
61 bool rect_equals(Rect a, Rect b) {
62 return a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height;
63 }
64
65 /*
66 * Returns true if the name consists of only digits.
67 *
68 */
69 __attribute__((pure)) bool name_is_digits(const char *name) {
70 /* positive integers and zero are interpreted as numbers */
71 for (size_t i = 0; i < strlen(name); i++)
72 if (!isdigit(name[i]))
73 return false;
74
75 return true;
76 }
77
78 /*
79 * Set 'out' to the layout_t value for the given layout. The function
80 * returns true on success or false if the passed string is not a valid
81 * layout name.
82 *
83 */
84 bool layout_from_name(const char *layout_str, layout_t *out) {
85 if (strcmp(layout_str, "default") == 0) {
86 *out = L_DEFAULT;
87 return true;
88 } else if (strcasecmp(layout_str, "stacked") == 0 ||
89 strcasecmp(layout_str, "stacking") == 0) {
90 *out = L_STACKED;
91 return true;
92 } else if (strcasecmp(layout_str, "tabbed") == 0) {
93 *out = L_TABBED;
94 return true;
95 } else if (strcasecmp(layout_str, "splitv") == 0) {
96 *out = L_SPLITV;
97 return true;
98 } else if (strcasecmp(layout_str, "splith") == 0) {
99 *out = L_SPLITH;
100 return true;
101 }
102
103 return false;
104 }
105
106 /*
107 * Parses the workspace name as a number. Returns -1 if the workspace should be
108 * interpreted as a "named workspace".
109 *
110 */
111 int ws_name_to_number(const char *name) {
112 /* positive integers and zero are interpreted as numbers */
113 char *endptr = NULL;
114 errno = 0;
115 long long parsed_num = strtoll(name, &endptr, 10);
116 if (errno != 0 || parsed_num > INT32_MAX || parsed_num < 0 || endptr == name) {
117 parsed_num = -1;
118 }
119
120 return parsed_num;
121 }
122
123 /*
124 * Updates *destination with new_value and returns true if it was changed or false
125 * if it was the same
126 *
127 */
128 bool update_if_necessary(uint32_t *destination, const uint32_t new_value) {
129 uint32_t old_value = *destination;
130
131 return ((*destination = new_value) != old_value);
132 }
133
134 /*
135 * exec()s an i3 utility, for example the config file migration script or
136 * i3-nagbar. This function first searches $PATH for the given utility named,
137 * then falls back to the dirname() of the i3 executable path and then falls
138 * back to the dirname() of the target of /proc/self/exe (on linux).
139 *
140 * This function should be called after fork()ing.
141 *
142 * The first argument of the given argv vector will be overwritten with the
143 * executable name, so pass NULL.
144 *
145 * If the utility cannot be found in any of these locations, it exits with
146 * return code 2.
147 *
148 */
149 void exec_i3_utility(char *name, char *argv[]) {
150 /* start the migration script, search PATH first */
151 char *migratepath = name;
152 argv[0] = migratepath;
153 execvp(migratepath, argv);
154
155 /* if the script is not in path, maybe the user installed to a strange
156 * location and runs the i3 binary with an absolute path. We use
157 * argv[0]’s dirname */
158 char *pathbuf = sstrdup(start_argv[0]);
159 char *dir = dirname(pathbuf);
160 sasprintf(&migratepath, "%s/%s", dir, name);
161 argv[0] = migratepath;
162 execvp(migratepath, argv);
163
164 #if defined(__linux__)
165 /* on linux, we have one more fall-back: dirname(/proc/self/exe) */
166 char buffer[BUFSIZ];
167 if (readlink("/proc/self/exe", buffer, BUFSIZ) == -1) {
168 warn("could not read /proc/self/exe");
169 _exit(EXIT_FAILURE);
170 }
171 dir = dirname(buffer);
172 sasprintf(&migratepath, "%s/%s", dir, name);
173 argv[0] = migratepath;
174 execvp(migratepath, argv);
175 #endif
176
177 warn("Could not start %s", name);
178 _exit(2);
179 }
180
181 /*
182 * Checks if the given path exists by calling stat().
183 *
184 */
185 bool path_exists(const char *path) {
186 struct stat buf;
187 return (stat(path, &buf) == 0);
188 }
189
190 /*
191 * Goes through the list of arguments (for exec()) and add/replace the given option,
192 * including the option name, its argument, and the option character.
193 */
194 static char **add_argument(char **original, char *opt_char, char *opt_arg, char *opt_name) {
195 int num_args;
196 for (num_args = 0; original[num_args] != NULL; num_args++)
197 ;
198 char **result = scalloc(num_args + 3, sizeof(char *));
199
200 /* copy the arguments, but skip the ones we'll replace */
201 int write_index = 0;
202 bool skip_next = false;
203 for (int i = 0; i < num_args; ++i) {
204 if (skip_next) {
205 skip_next = false;
206 continue;
207 }
208 if (!strcmp(original[i], opt_char) ||
209 (opt_name && !strcmp(original[i], opt_name))) {
210 if (opt_arg)
211 skip_next = true;
212 continue;
213 }
214 result[write_index++] = original[i];
215 }
216
217 /* add the arguments we'll replace */
218 result[write_index++] = opt_char;
219 result[write_index] = opt_arg;
220
221 return result;
222 }
223
224 #define y(x, ...) yajl_gen_##x(gen, ##__VA_ARGS__)
225 #define ystr(str) yajl_gen_string(gen, (unsigned char *)str, strlen(str))
226
227 static char *store_restart_layout(void) {
228 setlocale(LC_NUMERIC, "C");
229 yajl_gen gen = yajl_gen_alloc(NULL);
230
231 dump_node(gen, croot, true);
232
233 setlocale(LC_NUMERIC, "");
234
235 const unsigned char *payload;
236 size_t length;
237 y(get_buf, &payload, &length);
238
239 /* create a temporary file if one hasn't been specified, or just
240 * resolve the tildes in the specified path */
241 char *filename;
242 if (config.restart_state_path == NULL) {
243 filename = get_process_filename("restart-state");
244 if (!filename)
245 return NULL;
246 } else {
247 filename = resolve_tilde(config.restart_state_path);
248 }
249
250 /* create the directory, it could have been cleaned up before restarting or
251 * may not exist at all in case it was user-specified. */
252 char *filenamecopy = sstrdup(filename);
253 char *base = dirname(filenamecopy);
254 DLOG("Creating \"%s\" for storing the restart layout\n", base);
255 if (mkdirp(base, DEFAULT_DIR_MODE) != 0)
256 ELOG("Could not create \"%s\" for storing the restart layout, layout will be lost.\n", base);
257 free(filenamecopy);
258
259 int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
260 if (fd == -1) {
261 perror("open()");
262 free(filename);
263 return NULL;
264 }
265
266 if (writeall(fd, payload, length) == -1) {
267 ELOG("Could not write restart layout to \"%s\", layout will be lost: %s\n", filename, strerror(errno));
268 free(filename);
269 close(fd);
270 return NULL;
271 }
272
273 close(fd);
274
275 if (length > 0) {
276 DLOG("layout: %.*s\n", (int)length, payload);
277 }
278
279 y(free);
280
281 return filename;
282 }
283
284 /*
285 * Restart i3 in-place
286 * appends -a to argument list to disable autostart
287 *
288 */
289 void i3_restart(bool forget_layout) {
290 char *restart_filename = forget_layout ? NULL : store_restart_layout();
291
292 kill_nagbar(&config_error_nagbar_pid, true);
293 kill_nagbar(&command_error_nagbar_pid, true);
294
295 restore_geometry();
296
297 ipc_shutdown(SHUTDOWN_REASON_RESTART, -1);
298
299 LOG("restarting \"%s\"...\n", start_argv[0]);
300 /* make sure -a is in the argument list or add it */
301 start_argv = add_argument(start_argv, "-a", NULL, NULL);
302
303 /* make debuglog-on persist */
304 if (get_debug_logging()) {
305 start_argv = add_argument(start_argv, "-d", "all", NULL);
306 }
307
308 /* replace -r <file> so that the layout is restored */
309 if (restart_filename != NULL) {
310 start_argv = add_argument(start_argv, "--restart", restart_filename, "-r");
311 }
312
313 execvp(start_argv[0], start_argv);
314
315 /* not reached */
316 }
317
318 /*
319 * Escapes the given string if a pango font is currently used.
320 * If the string has to be escaped, the input string will be free'd.
321 *
322 */
323 char *pango_escape_markup(char *input) {
324 if (!font_is_pango())
325 return input;
326
327 char *escaped = g_markup_escape_text(input, -1);
328 FREE(input);
329
330 return escaped;
331 }
332
333 /*
334 * Handler which will be called when we get a SIGCHLD for the nagbar, meaning
335 * it exited (or could not be started, depending on the exit code).
336 *
337 */
338 static void nagbar_exited(EV_P_ ev_child *watcher, int revents) {
339 ev_child_stop(EV_A_ watcher);
340
341 if (!WIFEXITED(watcher->rstatus)) {
342 ELOG("ERROR: i3-nagbar did not exit normally.\n");
343 return;
344 }
345
346 int exitcode = WEXITSTATUS(watcher->rstatus);
347 DLOG("i3-nagbar process exited with status %d\n", exitcode);
348 if (exitcode == 2) {
349 ELOG("ERROR: i3-nagbar could not be found. Is it correctly installed on your system?\n");
350 }
351
352 *((pid_t *)watcher->data) = -1;
353 }
354
355 /*
356 * Cleanup handler. Will be called when i3 exits. Kills i3-nagbar with signal
357 * SIGKILL (9) to make sure there are no left-over i3-nagbar processes.
358 *
359 */
360 static void nagbar_cleanup(EV_P_ ev_cleanup *watcher, int revent) {
361 pid_t *nagbar_pid = (pid_t *)watcher->data;
362 if (*nagbar_pid != -1) {
363 LOG("Sending SIGKILL (%d) to i3-nagbar with PID %d\n", SIGKILL, *nagbar_pid);
364 kill(*nagbar_pid, SIGKILL);
365 }
366 }
367
368 /*
369 * Starts an i3-nagbar instance with the given parameters. Takes care of
370 * handling SIGCHLD and killing i3-nagbar when i3 exits.
371 *
372 * The resulting PID will be stored in *nagbar_pid and can be used with
373 * kill_nagbar() to kill the bar later on.
374 *
375 */
376 void start_nagbar(pid_t *nagbar_pid, char *argv[]) {
377 if (*nagbar_pid != -1) {
378 DLOG("i3-nagbar already running (PID %d), not starting again.\n", *nagbar_pid);
379 return;
380 }
381
382 *nagbar_pid = fork();
383 if (*nagbar_pid == -1) {
384 warn("Could not fork()");
385 return;
386 }
387
388 /* child */
389 if (*nagbar_pid == 0)
390 exec_i3_utility("i3-nagbar", argv);
391
392 DLOG("Starting i3-nagbar with PID %d\n", *nagbar_pid);
393
394 /* parent */
395 /* install a child watcher */
396 ev_child *child = smalloc(sizeof(ev_child));
397 ev_child_init(child, &nagbar_exited, *nagbar_pid, 0);
398 child->data = nagbar_pid;
399 ev_child_start(main_loop, child);
400
401 /* install a cleanup watcher (will be called when i3 exits and i3-nagbar is
402 * still running) */
403 ev_cleanup *cleanup = smalloc(sizeof(ev_cleanup));
404 ev_cleanup_init(cleanup, nagbar_cleanup);
405 cleanup->data = nagbar_pid;
406 ev_cleanup_start(main_loop, cleanup);
407 }
408
409 /*
410 * Kills the i3-nagbar process, if *nagbar_pid != -1.
411 *
412 * If wait_for_it is set (restarting i3), this function will waitpid(),
413 * otherwise, ev is assumed to handle it (reloading).
414 *
415 */
416 void kill_nagbar(pid_t *nagbar_pid, bool wait_for_it) {
417 if (*nagbar_pid == -1)
418 return;
419
420 if (kill(*nagbar_pid, SIGTERM) == -1)
421 warn("kill(configerror_nagbar) failed");
422
423 if (!wait_for_it)
424 return;
425
426 /* When restarting, we don’t enter the ev main loop anymore and after the
427 * exec(), our old pid is no longer watched. So, ev won’t handle SIGCHLD
428 * for us and we would end up with a <defunct> process. Therefore we
429 * waitpid() here. */
430 waitpid(*nagbar_pid, NULL, 0);
431 }
432
433 /*
434 * Converts a string into a long using strtol().
435 * This is a convenience wrapper checking the parsing result. It returns true
436 * if the number could be parsed.
437 */
438 bool parse_long(const char *str, long *out, int base) {
439 char *end = NULL;
440 long result = strtol(str, &end, base);
441 if (result == LONG_MIN || result == LONG_MAX || result < 0 || (end != NULL && *end != '\0')) {
442 *out = result;
443 return false;
444 }
445
446 *out = result;
447 return true;
448 }
449
450 /*
451 * Slurp reads path in its entirety into buf, returning the length of the file
452 * or -1 if the file could not be read. buf is set to a buffer of appropriate
453 * size, or NULL if -1 is returned.
454 *
455 */
456 ssize_t slurp(const char *path, char **buf) {
457 FILE *f;
458 if ((f = fopen(path, "r")) == NULL) {
459 ELOG("Cannot open file \"%s\": %s\n", path, strerror(errno));
460 return -1;
461 }
462 struct stat stbuf;
463 if (fstat(fileno(f), &stbuf) != 0) {
464 ELOG("Cannot fstat() \"%s\": %s\n", path, strerror(errno));
465 fclose(f);
466 return -1;
467 }
468 /* Allocate one extra NUL byte to make the buffer usable with C string
469 * functions. yajl doesn’t need this, but this makes slurp safer. */
470 *buf = scalloc(stbuf.st_size + 1, 1);
471 size_t n = fread(*buf, 1, stbuf.st_size, f);
472 fclose(f);
473 if ((ssize_t)n != stbuf.st_size) {
474 ELOG("File \"%s\" could not be read entirely: got %zd, want %" PRIi64 "\n", path, n, (int64_t)stbuf.st_size);
475 FREE(*buf);
476 return -1;
477 }
478 return (ssize_t)n;
479 }
480
481 /*
482 * Convert a direction to its corresponding orientation.
483 *
484 */
485 orientation_t orientation_from_direction(direction_t direction) {
486 return (direction == D_LEFT || direction == D_RIGHT) ? HORIZ : VERT;
487 }
488
489 /*
490 * Convert a direction to its corresponding position.
491 *
492 */
493 position_t position_from_direction(direction_t direction) {
494 return (direction == D_LEFT || direction == D_UP) ? BEFORE : AFTER;
495 }
496
497 /*
498 * Convert orientation and position to the corresponding direction.
499 *
500 */
501 direction_t direction_from_orientation_position(orientation_t orientation, position_t position) {
502 if (orientation == HORIZ) {
503 return position == BEFORE ? D_LEFT : D_RIGHT;
504 } else {
505 return position == BEFORE ? D_UP : D_DOWN;
506 }
507 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * Stores the latest Git commit identifier so that it can be linked into i3
7 * and used dynamically without recompiling every object file.
8 *
9 */
10 #include <config.h>
11
12 const char *i3_version = I3_VERSION;
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * window.c: Updates window attributes (X11 hints/properties).
7 *
8 */
9 #include "all.h"
10
11 /*
12 * Frees an i3Window and all its members.
13 *
14 */
15 void window_free(i3Window *win) {
16 FREE(win->class_class);
17 FREE(win->class_instance);
18 i3string_free(win->name);
19 FREE(win->ran_assignments);
20 FREE(win);
21 }
22
23 /*
24 * Updates the WM_CLASS (consisting of the class and instance) for the
25 * given window.
26 *
27 */
28 void window_update_class(i3Window *win, xcb_get_property_reply_t *prop) {
29 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
30 DLOG("WM_CLASS not set.\n");
31 FREE(prop);
32 return;
33 }
34
35 /* We cannot use asprintf here since this property contains two
36 * null-terminated strings (for compatibility reasons). Instead, we
37 * use strdup() on both strings */
38 const size_t prop_length = xcb_get_property_value_length(prop);
39 char *new_class = xcb_get_property_value(prop);
40 const size_t class_class_index = strnlen(new_class, prop_length) + 1;
41
42 FREE(win->class_instance);
43 FREE(win->class_class);
44
45 win->class_instance = sstrndup(new_class, prop_length);
46 if (class_class_index < prop_length)
47 win->class_class = sstrndup(new_class + class_class_index, prop_length - class_class_index);
48 else
49 win->class_class = NULL;
50 LOG("WM_CLASS changed to %s (instance), %s (class)\n",
51 win->class_instance, win->class_class);
52
53 free(prop);
54 }
55
56 /*
57 * Updates the name by using _NET_WM_NAME (encoded in UTF-8) for the given
58 * window. Further updates using window_update_name_legacy will be ignored.
59 *
60 */
61 void window_update_name(i3Window *win, xcb_get_property_reply_t *prop) {
62 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
63 DLOG("_NET_WM_NAME not specified, not changing\n");
64 FREE(prop);
65 return;
66 }
67
68 i3string_free(win->name);
69
70 /* Truncate the name at the first zero byte. See #3515. */
71 const int len = xcb_get_property_value_length(prop);
72 char *name = sstrndup(xcb_get_property_value(prop), len);
73 win->name = i3string_from_utf8(name);
74 free(name);
75
76 Con *con = con_by_window_id(win->id);
77 if (con != NULL && con->title_format != NULL) {
78 i3String *name = con_parse_title_format(con);
79 ewmh_update_visible_name(win->id, i3string_as_utf8(name));
80 I3STRING_FREE(name);
81 }
82 win->name_x_changed = true;
83 LOG("_NET_WM_NAME changed to \"%s\"\n", i3string_as_utf8(win->name));
84
85 win->uses_net_wm_name = true;
86
87 free(prop);
88 }
89
90 /*
91 * Updates the name by using WM_NAME (encoded in COMPOUND_TEXT). We do not
92 * touch what the client sends us but pass it to xcb_image_text_8. To get
93 * proper unicode rendering, the application has to use _NET_WM_NAME (see
94 * window_update_name()).
95 *
96 */
97 void window_update_name_legacy(i3Window *win, xcb_get_property_reply_t *prop) {
98 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
99 DLOG("WM_NAME not set (_NET_WM_NAME is what you want anyways).\n");
100 FREE(prop);
101 return;
102 }
103
104 /* ignore update when the window is known to already have a UTF-8 name */
105 if (win->uses_net_wm_name) {
106 free(prop);
107 return;
108 }
109
110 i3string_free(win->name);
111 const int len = xcb_get_property_value_length(prop);
112 char *name = sstrndup(xcb_get_property_value(prop), len);
113 win->name = i3string_from_utf8(name);
114 free(name);
115
116 Con *con = con_by_window_id(win->id);
117 if (con != NULL && con->title_format != NULL) {
118 i3String *name = con_parse_title_format(con);
119 ewmh_update_visible_name(win->id, i3string_as_utf8(name));
120 I3STRING_FREE(name);
121 }
122
123 LOG("WM_NAME changed to \"%s\"\n", i3string_as_utf8(win->name));
124 LOG("Using legacy window title. Note that in order to get Unicode window "
125 "titles in i3, the application has to set _NET_WM_NAME (UTF-8)\n");
126
127 win->name_x_changed = true;
128
129 free(prop);
130 }
131
132 /*
133 * Updates the CLIENT_LEADER (logical parent window).
134 *
135 */
136 void window_update_leader(i3Window *win, xcb_get_property_reply_t *prop) {
137 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
138 DLOG("CLIENT_LEADER not set on window 0x%08x.\n", win->id);
139 win->leader = XCB_NONE;
140 FREE(prop);
141 return;
142 }
143
144 xcb_window_t *leader = xcb_get_property_value(prop);
145 if (leader == NULL) {
146 free(prop);
147 return;
148 }
149
150 DLOG("Client leader changed to %08x\n", *leader);
151
152 win->leader = *leader;
153
154 free(prop);
155 }
156
157 /*
158 * Updates the TRANSIENT_FOR (logical parent window).
159 *
160 */
161 void window_update_transient_for(i3Window *win, xcb_get_property_reply_t *prop) {
162 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
163 DLOG("TRANSIENT_FOR not set on window 0x%08x.\n", win->id);
164 win->transient_for = XCB_NONE;
165 FREE(prop);
166 return;
167 }
168
169 xcb_window_t transient_for;
170 if (!xcb_icccm_get_wm_transient_for_from_reply(&transient_for, prop)) {
171 free(prop);
172 return;
173 }
174
175 DLOG("Transient for changed to 0x%08x (window 0x%08x)\n", transient_for, win->id);
176
177 win->transient_for = transient_for;
178
179 free(prop);
180 }
181
182 /*
183 * Updates the _NET_WM_STRUT_PARTIAL (reserved pixels at the screen edges)
184 *
185 */
186 void window_update_strut_partial(i3Window *win, xcb_get_property_reply_t *prop) {
187 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
188 DLOG("_NET_WM_STRUT_PARTIAL not set.\n");
189 FREE(prop);
190 return;
191 }
192
193 uint32_t *strut;
194 if (!(strut = xcb_get_property_value(prop))) {
195 free(prop);
196 return;
197 }
198
199 DLOG("Reserved pixels changed to: left = %d, right = %d, top = %d, bottom = %d\n",
200 strut[0], strut[1], strut[2], strut[3]);
201
202 win->reserved = (struct reservedpx){strut[0], strut[1], strut[2], strut[3]};
203
204 free(prop);
205 }
206
207 /*
208 * Updates the WM_WINDOW_ROLE
209 *
210 */
211 void window_update_role(i3Window *win, xcb_get_property_reply_t *prop) {
212 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
213 DLOG("WM_WINDOW_ROLE not set.\n");
214 FREE(prop);
215 return;
216 }
217
218 char *new_role;
219 sasprintf(&new_role, "%.*s", xcb_get_property_value_length(prop),
220 (char *)xcb_get_property_value(prop));
221 FREE(win->role);
222 win->role = new_role;
223 LOG("WM_WINDOW_ROLE changed to \"%s\"\n", win->role);
224
225 free(prop);
226 }
227
228 /*
229 * Updates the _NET_WM_WINDOW_TYPE property.
230 *
231 */
232 void window_update_type(i3Window *window, xcb_get_property_reply_t *reply) {
233 xcb_atom_t new_type = xcb_get_preferred_window_type(reply);
234 free(reply);
235 if (new_type == XCB_NONE) {
236 DLOG("cannot read _NET_WM_WINDOW_TYPE from window.\n");
237 return;
238 }
239
240 window->window_type = new_type;
241 LOG("_NET_WM_WINDOW_TYPE changed to %i.\n", window->window_type);
242
243 run_assignments(window);
244 }
245
246 /*
247 * Updates the WM_NORMAL_HINTS
248 *
249 */
250 bool window_update_normal_hints(i3Window *win, xcb_get_property_reply_t *reply, xcb_get_geometry_reply_t *geom) {
251 bool changed = false;
252 xcb_size_hints_t size_hints;
253
254 /* If the hints were already in this event, use them, if not, request them */
255 bool success;
256 if (reply != NULL) {
257 success = xcb_icccm_get_wm_size_hints_from_reply(&size_hints, reply);
258 } else {
259 success = xcb_icccm_get_wm_normal_hints_reply(conn, xcb_icccm_get_wm_normal_hints_unchecked(conn, win->id), &size_hints, NULL);
260 }
261 if (!success) {
262 DLOG("Could not get WM_NORMAL_HINTS\n");
263 return false;
264 }
265
266 #define ASSIGN_IF_CHANGED(original, new) \
267 do { \
268 if (original != new) { \
269 original = new; \
270 changed = true; \
271 } \
272 } while (0)
273
274 if ((size_hints.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE)) {
275 DLOG("Minimum size: %d (width) x %d (height)\n", size_hints.min_width, size_hints.min_height);
276
277 ASSIGN_IF_CHANGED(win->min_width, size_hints.min_width);
278 ASSIGN_IF_CHANGED(win->min_height, size_hints.min_height);
279 }
280
281 if ((size_hints.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE)) {
282 DLOG("Maximum size: %d (width) x %d (height)\n", size_hints.max_width, size_hints.max_height);
283
284 int max_width = max(0, size_hints.max_width);
285 int max_height = max(0, size_hints.max_height);
286
287 ASSIGN_IF_CHANGED(win->max_width, max_width);
288 ASSIGN_IF_CHANGED(win->max_height, max_height);
289 } else {
290 DLOG("Clearing maximum size\n");
291
292 ASSIGN_IF_CHANGED(win->max_width, 0);
293 ASSIGN_IF_CHANGED(win->max_height, 0);
294 }
295
296 if ((size_hints.flags & XCB_ICCCM_SIZE_HINT_P_RESIZE_INC)) {
297 DLOG("Size increments: %d (width) x %d (height)\n", size_hints.width_inc, size_hints.height_inc);
298
299 if (size_hints.width_inc > 0 && size_hints.width_inc < 0xFFFF) {
300 ASSIGN_IF_CHANGED(win->width_increment, size_hints.width_inc);
301 } else {
302 ASSIGN_IF_CHANGED(win->width_increment, 0);
303 }
304
305 if (size_hints.height_inc > 0 && size_hints.height_inc < 0xFFFF) {
306 ASSIGN_IF_CHANGED(win->height_increment, size_hints.height_inc);
307 } else {
308 ASSIGN_IF_CHANGED(win->height_increment, 0);
309 }
310 } else {
311 DLOG("Clearing size increments\n");
312
313 ASSIGN_IF_CHANGED(win->width_increment, 0);
314 ASSIGN_IF_CHANGED(win->height_increment, 0);
315 }
316
317 /* The base width / height is the desired size of the window. */
318 if (size_hints.flags & XCB_ICCCM_SIZE_HINT_BASE_SIZE &&
319 (win->base_width >= 0) && (win->base_height >= 0)) {
320 DLOG("Base size: %d (width) x %d (height)\n", size_hints.base_width, size_hints.base_height);
321
322 ASSIGN_IF_CHANGED(win->base_width, size_hints.base_width);
323 ASSIGN_IF_CHANGED(win->base_height, size_hints.base_height);
324 } else {
325 DLOG("Clearing base size\n");
326
327 ASSIGN_IF_CHANGED(win->base_width, 0);
328 ASSIGN_IF_CHANGED(win->base_height, 0);
329 }
330
331 if (geom != NULL &&
332 (size_hints.flags & XCB_ICCCM_SIZE_HINT_US_POSITION || size_hints.flags & XCB_ICCCM_SIZE_HINT_P_POSITION) &&
333 (size_hints.flags & XCB_ICCCM_SIZE_HINT_US_SIZE || size_hints.flags & XCB_ICCCM_SIZE_HINT_P_SIZE)) {
334 DLOG("Setting geometry x=%d y=%d w=%d h=%d\n", size_hints.x, size_hints.y, size_hints.width, size_hints.height);
335 geom->x = size_hints.x;
336 geom->y = size_hints.y;
337 geom->width = size_hints.width;
338 geom->height = size_hints.height;
339 }
340
341 /* If no aspect ratio was set or if it was invalid, we ignore the hints */
342 if (size_hints.flags & XCB_ICCCM_SIZE_HINT_P_ASPECT &&
343 (size_hints.min_aspect_num >= 0) && (size_hints.min_aspect_den > 0) &&
344 (size_hints.max_aspect_num >= 0) && (size_hints.max_aspect_den > 0)) {
345 /* Convert numerator/denominator to a double */
346 double min_aspect = (double)size_hints.min_aspect_num / size_hints.min_aspect_den;
347 double max_aspect = (double)size_hints.max_aspect_num / size_hints.max_aspect_den;
348 DLOG("Aspect ratio set: minimum %f, maximum %f\n", min_aspect, max_aspect);
349 if (fabs(win->min_aspect_ratio - min_aspect) > DBL_EPSILON) {
350 win->min_aspect_ratio = min_aspect;
351 changed = true;
352 }
353 if (fabs(win->max_aspect_ratio - max_aspect) > DBL_EPSILON) {
354 win->max_aspect_ratio = max_aspect;
355 changed = true;
356 }
357 } else {
358 DLOG("Clearing aspect ratios\n");
359
360 ASSIGN_IF_CHANGED(win->min_aspect_ratio, 0.0);
361 ASSIGN_IF_CHANGED(win->max_aspect_ratio, 0.0);
362 }
363
364 return changed;
365 }
366
367 /*
368 * Updates the WM_HINTS (we only care about the input focus handling part).
369 *
370 */
371 void window_update_hints(i3Window *win, xcb_get_property_reply_t *prop, bool *urgency_hint) {
372 if (urgency_hint != NULL)
373 *urgency_hint = false;
374
375 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
376 DLOG("WM_HINTS not set.\n");
377 FREE(prop);
378 return;
379 }
380
381 xcb_icccm_wm_hints_t hints;
382
383 if (!xcb_icccm_get_wm_hints_from_reply(&hints, prop)) {
384 DLOG("Could not get WM_HINTS\n");
385 free(prop);
386 return;
387 }
388
389 if (hints.flags & XCB_ICCCM_WM_HINT_INPUT) {
390 win->doesnt_accept_focus = !hints.input;
391 LOG("WM_HINTS.input changed to \"%d\"\n", hints.input);
392 }
393
394 if (urgency_hint != NULL)
395 *urgency_hint = (xcb_icccm_wm_hints_get_urgency(&hints) != 0);
396
397 free(prop);
398 }
399
400 /*
401 * Updates the MOTIF_WM_HINTS. The container's border style should be set to
402 * `motif_border_style' if border style is not BS_NORMAL.
403 *
404 * i3 only uses this hint when it specifies a window should have no
405 * title bar, or no decorations at all, which is how most window managers
406 * handle it.
407 *
408 * The EWMH spec intended to replace Motif hints with _NET_WM_WINDOW_TYPE, but
409 * it is still in use by popular widget toolkits such as GTK+ and Java AWT.
410 *
411 */
412 void window_update_motif_hints(i3Window *win, xcb_get_property_reply_t *prop, border_style_t *motif_border_style) {
413 /* This implementation simply mirrors Gnome's Metacity. Official
414 * documentation of this hint is nowhere to be found.
415 * For more information see:
416 * https://people.gnome.org/~tthurman/docs/metacity/xprops_8h-source.html
417 * https://stackoverflow.com/questions/13787553/detect-if-a-x11-window-has-decorations
418 */
419 #define MWM_HINTS_FLAGS_FIELD 0
420 #define MWM_HINTS_DECORATIONS_FIELD 2
421
422 #define MWM_HINTS_DECORATIONS (1 << 1)
423 #define MWM_DECOR_ALL (1 << 0)
424 #define MWM_DECOR_BORDER (1 << 1)
425 #define MWM_DECOR_TITLE (1 << 3)
426
427 if (motif_border_style != NULL)
428 *motif_border_style = BS_NORMAL;
429
430 if (prop == NULL || xcb_get_property_value_length(prop) == 0) {
431 FREE(prop);
432 return;
433 }
434
435 /* The property consists of an array of 5 uint32_t's. The first value is a
436 * bit mask of what properties the hint will specify. We are only interested
437 * in MWM_HINTS_DECORATIONS because it indicates that the third value of the
438 * array tells us which decorations the window should have, each flag being
439 * a particular decoration. Notice that X11 (Xlib) often mentions 32-bit
440 * fields which in reality are implemented using unsigned long variables
441 * (64-bits long on amd64 for example). On the other hand,
442 * xcb_get_property_value() behaves strictly according to documentation,
443 * i.e. returns 32-bit data fields. */
444 uint32_t *motif_hints = (uint32_t *)xcb_get_property_value(prop);
445
446 if (motif_border_style != NULL &&
447 motif_hints[MWM_HINTS_FLAGS_FIELD] & MWM_HINTS_DECORATIONS) {
448 if (motif_hints[MWM_HINTS_DECORATIONS_FIELD] & MWM_DECOR_ALL ||
449 motif_hints[MWM_HINTS_DECORATIONS_FIELD] & MWM_DECOR_TITLE)
450 *motif_border_style = BS_NORMAL;
451 else if (motif_hints[MWM_HINTS_DECORATIONS_FIELD] & MWM_DECOR_BORDER)
452 *motif_border_style = BS_PIXEL;
453 else
454 *motif_border_style = BS_NONE;
455 }
456
457 FREE(prop);
458
459 #undef MWM_HINTS_FLAGS_FIELD
460 #undef MWM_HINTS_DECORATIONS_FIELD
461 #undef MWM_HINTS_DECORATIONS
462 #undef MWM_DECOR_ALL
463 #undef MWM_DECOR_BORDER
464 #undef MWM_DECOR_TITLE
465 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * workspace.c: Modifying workspaces, accessing them, moving containers to
7 * workspaces.
8 *
9 */
10 #include "all.h"
11 #include "yajl_utils.h"
12
13 /*
14 * Stores a copy of the name of the last used workspace for the workspace
15 * back-and-forth switching.
16 *
17 */
18 char *previous_workspace_name = NULL;
19
20 /* NULL-terminated list of workspace names (in order) extracted from
21 * keybindings. */
22 static char **binding_workspace_names = NULL;
23
24 /*
25 * Returns the workspace with the given name or NULL if such a workspace does
26 * not exist.
27 *
28 */
29 Con *get_existing_workspace_by_name(const char *name) {
30 Con *output, *workspace = NULL;
31 TAILQ_FOREACH (output, &(croot->nodes_head), nodes) {
32 GREP_FIRST(workspace, output_get_content(output), !strcasecmp(child->name, name));
33 }
34
35 return workspace;
36 }
37
38 /*
39 * Returns the workspace with the given number or NULL if such a workspace does
40 * not exist.
41 *
42 */
43 Con *get_existing_workspace_by_num(int num) {
44 Con *output, *workspace = NULL;
45 TAILQ_FOREACH (output, &(croot->nodes_head), nodes) {
46 GREP_FIRST(workspace, output_get_content(output), child->num == num);
47 }
48
49 return workspace;
50 }
51
52 /*
53 * Sets ws->layout to splith/splitv if default_orientation was specified in the
54 * configfile. Otherwise, it uses splith/splitv depending on whether the output
55 * is higher than wide.
56 *
57 */
58 static void _workspace_apply_default_orientation(Con *ws) {
59 /* If default_orientation is set to NO_ORIENTATION we determine
60 * orientation depending on output resolution. */
61 if (config.default_orientation == NO_ORIENTATION) {
62 Con *output = con_get_output(ws);
63 ws->layout = (output->rect.height > output->rect.width) ? L_SPLITV : L_SPLITH;
64 ws->rect = output->rect;
65 DLOG("Auto orientation. Workspace size set to (%d,%d), setting layout to %d.\n",
66 output->rect.width, output->rect.height, ws->layout);
67 } else {
68 ws->layout = (config.default_orientation == HORIZ) ? L_SPLITH : L_SPLITV;
69 }
70 }
71
72 /*
73 * Returns the first output that is assigned to a workspace specified by the
74 * given name or number or NULL if no such output exists. If there is a
75 * workspace with a matching name and another workspace with a matching number,
76 * the output assigned to the first one is returned.
77 * The order of the 'ws_assignments' queue is respected: if multiple assignments
78 * match the specified workspace, the first one is returned.
79 * If 'name' is NULL it will be ignored.
80 * If 'parsed_num' is -1 it will be ignored.
81 *
82 */
83 static Con *get_assigned_output(const char *name, long parsed_num) {
84 Con *output = NULL;
85 struct Workspace_Assignment *assignment;
86 TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) {
87 if (assignment->output == NULL) {
88 continue;
89 }
90
91 if (name && strcmp(assignment->name, name) == 0) {
92 DLOG("Found workspace name assignment to output \"%s\"\n", assignment->output);
93 Output *assigned_by_name = get_output_by_name(assignment->output, true);
94 if (assigned_by_name) {
95 /* When the name matches exactly, skip numbered assignments. */
96 return assigned_by_name->con;
97 }
98 } else if (!output && /* Only keep the first numbered assignment. */
99 parsed_num != -1 &&
100 name_is_digits(assignment->name) &&
101 ws_name_to_number(assignment->name) == parsed_num) {
102 DLOG("Found workspace number assignment to output \"%s\"\n", assignment->output);
103 Output *assigned_by_num = get_output_by_name(assignment->output, true);
104 if (assigned_by_num) {
105 output = assigned_by_num->con;
106 }
107 }
108 }
109
110 return output;
111 }
112
113 /*
114 * Returns true if the first output assigned to a workspace with the given
115 * workspace assignment is the same as the given output.
116 */
117 bool output_triggers_assignment(Output *output, struct Workspace_Assignment *assignment) {
118 Con *assigned = get_assigned_output(assignment->name, -1);
119 return assigned && assigned == output->con;
120 }
121
122 /*
123 * Returns a pointer to the workspace with the given number (starting at 0),
124 * creating the workspace if necessary (by allocating the necessary amount of
125 * memory and initializing the data structures correctly).
126 *
127 */
128 Con *workspace_get(const char *num, bool *created) {
129 Con *workspace = get_existing_workspace_by_name(num);
130
131 if (workspace == NULL) {
132 LOG("Creating new workspace \"%s\"\n", num);
133 gaps_t gaps = (gaps_t){0, 0, 0, 0, 0};
134
135 /* We set workspace->num to the number if this workspace’s name begins
136 * with a positive number. Otherwise it’s a named ws and num will be
137 * -1. */
138 long parsed_num = ws_name_to_number(num);
139
140 struct Workspace_Assignment *assignment;
141 TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) {
142 if (strcmp(assignment->name, num) == 0) {
143 gaps = assignment->gaps;
144 break;
145 } else if (parsed_num != -1 && name_is_digits(assignment->name) && ws_name_to_number(assignment->name) == parsed_num) {
146 gaps = assignment->gaps;
147 }
148 }
149
150 Con *output = get_assigned_output(num, parsed_num);
151 /* if an assignment is not found, we create this workspace on the current output */
152 if (!output) {
153 output = con_get_output(focused);
154 }
155
156 Con *content = output_get_content(output);
157 LOG("got output %p with content %p\n", output, content);
158 /* We need to attach this container after setting its type. con_attach
159 * will handle CT_WORKSPACEs differently */
160 workspace = con_new(NULL, NULL);
161 char *name;
162 sasprintf(&name, "[i3 con] workspace %s", num);
163 x_set_name(workspace, name);
164 free(name);
165 workspace->type = CT_WORKSPACE;
166 FREE(workspace->name);
167 workspace->name = sstrdup(num);
168 workspace->workspace_layout = config.default_layout;
169 workspace->num = parsed_num;
170 LOG("num = %d\n", workspace->num);
171 workspace->gaps = gaps;
172
173 workspace->parent = content;
174 _workspace_apply_default_orientation(workspace);
175
176 con_attach(workspace, content, false);
177
178 ipc_send_workspace_event("init", workspace, NULL);
179 ewmh_update_desktop_properties();
180 if (created != NULL)
181 *created = true;
182 } else if (created != NULL) {
183 *created = false;
184 }
185
186 return workspace;
187 }
188
189 /*
190 * Extracts workspace names from keybindings (e.g. “web” from “bindsym $mod+1
191 * workspace web”), so that when an output needs a workspace, i3 can start with
192 * the first configured one. Needs to be called before reorder_bindings() so
193 * that the config-file order is used, not the i3-internal order.
194 *
195 */
196 void extract_workspace_names_from_bindings(void) {
197 Binding *bind;
198 int n = 0;
199 if (binding_workspace_names != NULL) {
200 for (int i = 0; binding_workspace_names[i] != NULL; i++) {
201 free(binding_workspace_names[i]);
202 }
203 FREE(binding_workspace_names);
204 }
205 TAILQ_FOREACH (bind, bindings, bindings) {
206 DLOG("binding with command %s\n", bind->command);
207 if (strlen(bind->command) < strlen("workspace ") ||
208 strncasecmp(bind->command, "workspace", strlen("workspace")) != 0)
209 continue;
210 DLOG("relevant command = %s\n", bind->command);
211 const char *target = bind->command + strlen("workspace ");
212 while (*target == ' ' || *target == '\t')
213 target++;
214 /* We check if this is the workspace
215 * next/prev/next_on_output/prev_on_output/back_and_forth command.
216 * Beware: The workspace names "next", "prev", "next_on_output",
217 * "prev_on_output", "back_and_forth" and "current" are OK,
218 * so we check before stripping the double quotes */
219 if (strncasecmp(target, "next", strlen("next")) == 0 ||
220 strncasecmp(target, "prev", strlen("prev")) == 0 ||
221 strncasecmp(target, "next_on_output", strlen("next_on_output")) == 0 ||
222 strncasecmp(target, "prev_on_output", strlen("prev_on_output")) == 0 ||
223 strncasecmp(target, "back_and_forth", strlen("back_and_forth")) == 0 ||
224 strncasecmp(target, "current", strlen("current")) == 0)
225 continue;
226 if (strncasecmp(target, "--no-auto-back-and-forth", strlen("--no-auto-back-and-forth")) == 0) {
227 target += strlen("--no-auto-back-and-forth");
228 while (*target == ' ' || *target == '\t')
229 target++;
230 }
231 if (strncasecmp(target, "number", strlen("number")) == 0) {
232 target += strlen("number");
233 while (*target == ' ' || *target == '\t')
234 target++;
235 }
236 char *target_name = parse_string(&target, false);
237 if (target_name == NULL)
238 continue;
239 if (strncasecmp(target_name, "__", strlen("__")) == 0) {
240 LOG("Cannot create workspace \"%s\". Names starting with __ are i3-internal.\n", target);
241 free(target_name);
242 continue;
243 }
244 DLOG("Saving workspace name \"%s\"\n", target_name);
245
246 binding_workspace_names = srealloc(binding_workspace_names, ++n * sizeof(char *));
247 binding_workspace_names[n - 1] = target_name;
248 }
249 binding_workspace_names = srealloc(binding_workspace_names, ++n * sizeof(char *));
250 binding_workspace_names[n - 1] = NULL;
251 }
252
253 /*
254 * Returns a pointer to a new workspace in the given output. The workspace
255 * is created attached to the tree hierarchy through the given content
256 * container.
257 *
258 */
259 Con *create_workspace_on_output(Output *output, Con *content) {
260 /* add a workspace to this output */
261 char *name;
262 bool exists = true;
263 Con *ws = con_new(NULL, NULL);
264 ws->type = CT_WORKSPACE;
265
266 /* try the configured workspace bindings first to find a free name */
267 for (int n = 0; binding_workspace_names[n] != NULL; n++) {
268 char *target_name = binding_workspace_names[n];
269 /* Ensure that this workspace is not assigned to a different output —
270 * otherwise we would create it, then move it over to its output, then
271 * find a new workspace, etc… */
272 Con *assigned = get_assigned_output(target_name, -1);
273 if (assigned && assigned != output->con) {
274 continue;
275 }
276
277 exists = (get_existing_workspace_by_name(target_name) != NULL);
278 if (!exists) {
279 ws->name = sstrdup(target_name);
280 /* Set ->num to the number of the workspace, if the name actually
281 * is a number or starts with a number */
282 ws->num = ws_name_to_number(ws->name);
283 LOG("Used number %d for workspace with name %s\n", ws->num, ws->name);
284
285 break;
286 }
287 }
288
289 if (exists) {
290 /* get the next unused workspace number */
291 DLOG("Getting next unused workspace by number\n");
292 int c = 0;
293 while (exists) {
294 c++;
295 Con *assigned = get_assigned_output(NULL, c);
296 exists = (get_existing_workspace_by_num(c) || (assigned && assigned != output->con));
297 DLOG("result for ws %d: exists = %d\n", c, exists);
298 }
299 ws->num = c;
300 sasprintf(&(ws->name), "%d", c);
301 }
302
303 struct Workspace_Assignment *assignment;
304 TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) {
305 if (strcmp(assignment->name, ws->name) == 0) {
306 ws->gaps = assignment->gaps;
307 break;
308 }
309 }
310
311 con_attach(ws, content, false);
312
313 sasprintf(&name, "[i3 con] workspace %s", ws->name);
314 x_set_name(ws, name);
315 free(name);
316
317 ws->fullscreen_mode = CF_OUTPUT;
318
319 ws->workspace_layout = config.default_layout;
320 _workspace_apply_default_orientation(ws);
321
322 ipc_send_workspace_event("init", ws, NULL);
323 return ws;
324 }
325
326 /*
327 * Returns true if the workspace is currently visible. Especially important for
328 * multi-monitor environments, as they can have multiple currenlty active
329 * workspaces.
330 *
331 */
332 bool workspace_is_visible(Con *ws) {
333 Con *output = con_get_output(ws);
334 if (output == NULL)
335 return false;
336 Con *fs = con_get_fullscreen_con(output, CF_OUTPUT);
337 LOG("workspace visible? fs = %p, ws = %p\n", fs, ws);
338 return (fs == ws);
339 }
340
341 /*
342 * XXX: we need to clean up all this recursive walking code.
343 *
344 */
345 static Con *_get_sticky(Con *con, const char *sticky_group, Con *exclude) {
346 Con *current;
347
348 TAILQ_FOREACH (current, &(con->nodes_head), nodes) {
349 if (current != exclude &&
350 current->sticky_group != NULL &&
351 current->window != NULL &&
352 strcmp(current->sticky_group, sticky_group) == 0)
353 return current;
354
355 Con *recurse = _get_sticky(current, sticky_group, exclude);
356 if (recurse != NULL)
357 return recurse;
358 }
359
360 TAILQ_FOREACH (current, &(con->floating_head), floating_windows) {
361 if (current != exclude &&
362 current->sticky_group != NULL &&
363 current->window != NULL &&
364 strcmp(current->sticky_group, sticky_group) == 0)
365 return current;
366
367 Con *recurse = _get_sticky(current, sticky_group, exclude);
368 if (recurse != NULL)
369 return recurse;
370 }
371
372 return NULL;
373 }
374
375 /*
376 * Reassigns all child windows in sticky containers. Called when the user
377 * changes workspaces.
378 *
379 * XXX: what about sticky containers which contain containers?
380 *
381 */
382 static void workspace_reassign_sticky(Con *con) {
383 Con *current;
384 /* 1: go through all containers */
385
386 /* handle all children and floating windows of this node */
387 TAILQ_FOREACH (current, &(con->nodes_head), nodes) {
388 if (current->sticky_group == NULL) {
389 workspace_reassign_sticky(current);
390 continue;
391 }
392
393 LOG("Ah, this one is sticky: %s / %p\n", current->name, current);
394 /* 2: find a window which we can re-assign */
395 Con *output = con_get_output(current);
396 Con *src = _get_sticky(output, current->sticky_group, current);
397
398 if (src == NULL) {
399 LOG("No window found for this sticky group\n");
400 workspace_reassign_sticky(current);
401 continue;
402 }
403
404 x_move_win(src, current);
405 current->window = src->window;
406 current->mapped = true;
407 src->window = NULL;
408 src->mapped = false;
409
410 x_reparent_child(current, src);
411
412 LOG("re-assigned window from src %p to dest %p\n", src, current);
413 }
414
415 TAILQ_FOREACH (current, &(con->floating_head), floating_windows) {
416 workspace_reassign_sticky(current);
417 }
418 }
419
420 /*
421 * Callback to reset the urgent flag of the given con to false. May be started by
422 * workspace_show to avoid urgency hints being lost by switching to a workspace
423 * focusing the con.
424 *
425 */
426 static void workspace_defer_update_urgent_hint_cb(EV_P_ ev_timer *w, int revents) {
427 Con *con = w->data;
428
429 ev_timer_stop(main_loop, con->urgency_timer);
430 FREE(con->urgency_timer);
431
432 if (con->urgent) {
433 DLOG("Resetting urgency flag of con %p by timer\n", con);
434 con_set_urgency(con, false);
435 con_update_parents_urgency(con);
436 workspace_update_urgent_flag(con_get_workspace(con));
437 ipc_send_window_event("urgent", con);
438 tree_render();
439 }
440 }
441
442 /*
443 * Switches to the given workspace
444 *
445 */
446 void workspace_show(Con *workspace) {
447 Con *current, *old = NULL;
448
449 /* safe-guard against showing i3-internal workspaces like __i3_scratch */
450 if (con_is_internal(workspace))
451 return;
452
453 /* disable fullscreen for the other workspaces and get the workspace we are
454 * currently on. */
455 TAILQ_FOREACH (current, &(workspace->parent->nodes_head), nodes) {
456 if (current->fullscreen_mode == CF_OUTPUT)
457 old = current;
458 current->fullscreen_mode = CF_NONE;
459 }
460
461 /* enable fullscreen for the target workspace. If it happens to be the
462 * same one we are currently on anyways, we can stop here. */
463 workspace->fullscreen_mode = CF_OUTPUT;
464 current = con_get_workspace(focused);
465 if (workspace == current) {
466 DLOG("Not switching, already there.\n");
467 return;
468 }
469
470 /* Used to correctly update focus when pushing sticky windows. Holds the
471 * previously focused container in the same output as workspace. For
472 * example, if a sticky window is focused and then we switch focus to a
473 * workspace in another output and then switch to a third workspace in the
474 * first output, the sticky window needs to be refocused. */
475 Con *old_focus = old ? con_descend_focused(old) : NULL;
476
477 /* Remember currently focused workspace for switching back to it later with
478 * the 'workspace back_and_forth' command.
479 * NOTE: We have to duplicate the name as the original will be freed when
480 * the corresponding workspace is cleaned up.
481 * NOTE: Internal cons such as __i3_scratch (when a scratchpad window is
482 * focused) are skipped, see bug #868. */
483 if (current && !con_is_internal(current)) {
484 FREE(previous_workspace_name);
485 previous_workspace_name = sstrdup(current->name);
486 DLOG("Setting previous_workspace_name = %s\n", previous_workspace_name);
487 }
488
489 workspace_reassign_sticky(workspace);
490
491 DLOG("switching to %p / %s\n", workspace, workspace->name);
492 Con *next = con_descend_focused(workspace);
493
494 /* Memorize current output */
495 Con *old_output = con_get_output(focused);
496
497 /* Display urgency hint for a while if the newly visible workspace would
498 * focus and thereby immediately destroy it */
499 if (next->urgent && (int)(config.workspace_urgency_timer * 1000) > 0) {
500 /* focus for now… */
501 next->urgent = false;
502 con_focus(next);
503
504 /* … but immediately reset urgency flags; they will be set to false by
505 * the timer callback in case the container is focused at the time of
506 * its expiration */
507 focused->urgent = true;
508 workspace->urgent = true;
509
510 if (focused->urgency_timer == NULL) {
511 DLOG("Deferring reset of urgency flag of con %p on newly shown workspace %p\n",
512 focused, workspace);
513 focused->urgency_timer = scalloc(1, sizeof(struct ev_timer));
514 /* use a repeating timer to allow for easy resets */
515 ev_timer_init(focused->urgency_timer, workspace_defer_update_urgent_hint_cb,
516 config.workspace_urgency_timer, config.workspace_urgency_timer);
517 focused->urgency_timer->data = focused;
518 ev_timer_start(main_loop, focused->urgency_timer);
519 } else {
520 DLOG("Resetting urgency timer of con %p on workspace %p\n",
521 focused, workspace);
522 ev_timer_again(main_loop, focused->urgency_timer);
523 }
524 } else
525 con_focus(next);
526
527 ipc_send_workspace_event("focus", workspace, current);
528
529 DLOG("old = %p / %s\n", old, (old ? old->name : "(null)"));
530 /* Close old workspace if necessary. This must be done *after* doing
531 * urgency handling, because tree_close_internal() will do a con_focus() on the next
532 * client, which will clear the urgency flag too early. Also, there is no
533 * way for con_focus() to know about when to clear urgency immediately and
534 * when to defer it. */
535 if (old && TAILQ_EMPTY(&(old->nodes_head)) && TAILQ_EMPTY(&(old->floating_head))) {
536 /* check if this workspace is currently visible */
537 if (!workspace_is_visible(old)) {
538 LOG("Closing old workspace (%p / %s), it is empty\n", old, old->name);
539 yajl_gen gen = ipc_marshal_workspace_event("empty", old, NULL);
540 tree_close_internal(old, DONT_KILL_WINDOW, false);
541
542 const unsigned char *payload;
543 ylength length;
544 y(get_buf, &payload, &length);
545 ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, (const char *)payload);
546
547 y(free);
548
549 /* Avoid calling output_push_sticky_windows later with a freed container. */
550 if (old == old_focus) {
551 old_focus = NULL;
552 }
553
554 ewmh_update_desktop_properties();
555 }
556 }
557
558 workspace->fullscreen_mode = CF_OUTPUT;
559 LOG("focused now = %p / %s\n", focused, focused->name);
560
561 /* Set mouse pointer */
562 Con *new_output = con_get_output(focused);
563 if (old_output != new_output) {
564 x_set_warp_to(&next->rect);
565 }
566
567 /* Update the EWMH hints */
568 ewmh_update_current_desktop();
569
570 /* Push any sticky windows to the now visible workspace. */
571 output_push_sticky_windows(old_focus);
572 }
573
574 /*
575 * Looks up the workspace by name and switches to it.
576 *
577 */
578 void workspace_show_by_name(const char *num) {
579 Con *workspace;
580 workspace = workspace_get(num, NULL);
581 workspace_show(workspace);
582 }
583
584 /*
585 * Focuses the next workspace.
586 *
587 */
588 Con *workspace_next(void) {
589 Con *current = con_get_workspace(focused);
590 Con *next = NULL, *first = NULL, *first_opposite = NULL;
591 Con *output;
592
593 if (current->num == -1) {
594 /* If currently a named workspace, find next named workspace. */
595 if ((next = TAILQ_NEXT(current, nodes)) != NULL)
596 return next;
597 bool found_current = false;
598 TAILQ_FOREACH (output, &(croot->nodes_head), nodes) {
599 /* Skip outputs starting with __, they are internal. */
600 if (con_is_internal(output))
601 continue;
602 NODES_FOREACH (output_get_content(output)) {
603 if (child->type != CT_WORKSPACE)
604 continue;
605 if (!first)
606 first = child;
607 if (!first_opposite || (child->num != -1 && child->num < first_opposite->num))
608 first_opposite = child;
609 if (child == current) {
610 found_current = true;
611 } else if (child->num == -1 && found_current) {
612 next = child;
613 return next;
614 }
615 }
616 }
617 } else {
618 /* If currently a numbered workspace, find next numbered workspace. */
619 TAILQ_FOREACH (output, &(croot->nodes_head), nodes) {
620 /* Skip outputs starting with __, they are internal. */
621 if (con_is_internal(output))
622 continue;
623 NODES_FOREACH (output_get_content(output)) {
624 if (child->type != CT_WORKSPACE)
625 continue;
626 if (!first || (child->num != -1 && child->num < first->num))
627 first = child;
628 if (!first_opposite && child->num == -1)
629 first_opposite = child;
630 if (child->num == -1)
631 break;
632 /* Need to check child against current and next because we are
633 * traversing multiple lists and thus are not guaranteed the
634 * relative order between the list of workspaces. */
635 if (current->num < child->num && (!next || child->num < next->num))
636 next = child;
637 }
638 }
639 }
640
641 if (!next)
642 next = first_opposite ? first_opposite : first;
643
644 return next;
645 }
646
647 /*
648 * Focuses the previous workspace.
649 *
650 */
651 Con *workspace_prev(void) {
652 Con *current = con_get_workspace(focused);
653 Con *prev = NULL, *first_opposite = NULL, *last = NULL;
654 Con *output;
655
656 if (current->num == -1) {
657 /* If named workspace, find previous named workspace. */
658 prev = TAILQ_PREV(current, nodes_head, nodes);
659 if (prev && prev->num != -1)
660 prev = NULL;
661 if (!prev) {
662 bool found_current = false;
663 TAILQ_FOREACH_REVERSE (output, &(croot->nodes_head), nodes_head, nodes) {
664 /* Skip outputs starting with __, they are internal. */
665 if (con_is_internal(output))
666 continue;
667 NODES_FOREACH_REVERSE (output_get_content(output)) {
668 if (child->type != CT_WORKSPACE)
669 continue;
670 if (!last)
671 last = child;
672 if (!first_opposite || (child->num != -1 && child->num > first_opposite->num))
673 first_opposite = child;
674 if (child == current) {
675 found_current = true;
676 } else if (child->num == -1 && found_current) {
677 prev = child;
678 return prev;
679 }
680 }
681 }
682 }
683 } else {
684 /* If numbered workspace, find previous numbered workspace. */
685 TAILQ_FOREACH_REVERSE (output, &(croot->nodes_head), nodes_head, nodes) {
686 /* Skip outputs starting with __, they are internal. */
687 if (con_is_internal(output))
688 continue;
689 NODES_FOREACH_REVERSE (output_get_content(output)) {
690 if (child->type != CT_WORKSPACE)
691 continue;
692 if (!last || (child->num != -1 && last->num < child->num))
693 last = child;
694 if (!first_opposite && child->num == -1)
695 first_opposite = child;
696 if (child->num == -1)
697 continue;
698 /* Need to check child against current and previous because we
699 * are traversing multiple lists and thus are not guaranteed
700 * the relative order between the list of workspaces. */
701 if (current->num > child->num && (!prev || child->num > prev->num))
702 prev = child;
703 }
704 }
705 }
706
707 if (!prev)
708 prev = first_opposite ? first_opposite : last;
709
710 return prev;
711 }
712
713 /*
714 * Focuses the next workspace on the same output.
715 *
716 */
717 Con *workspace_next_on_output(void) {
718 Con *current = con_get_workspace(focused);
719 Con *next = NULL;
720 Con *output = con_get_output(focused);
721
722 if (current->num == -1) {
723 /* If currently a named workspace, find next named workspace. */
724 next = TAILQ_NEXT(current, nodes);
725 } else {
726 /* If currently a numbered workspace, find next numbered workspace. */
727 NODES_FOREACH (output_get_content(output)) {
728 if (child->type != CT_WORKSPACE)
729 continue;
730 if (child->num == -1)
731 break;
732 /* Need to check child against current and next because we are
733 * traversing multiple lists and thus are not guaranteed the
734 * relative order between the list of workspaces. */
735 if (current->num < child->num && (!next || child->num < next->num))
736 next = child;
737 }
738 }
739
740 /* Find next named workspace. */
741 if (!next) {
742 bool found_current = false;
743 NODES_FOREACH (output_get_content(output)) {
744 if (child->type != CT_WORKSPACE)
745 continue;
746 if (child == current) {
747 found_current = true;
748 } else if (child->num == -1 && (current->num != -1 || found_current)) {
749 next = child;
750 goto workspace_next_on_output_end;
751 }
752 }
753 }
754
755 /* Find first workspace. */
756 if (!next) {
757 NODES_FOREACH (output_get_content(output)) {
758 if (child->type != CT_WORKSPACE)
759 continue;
760 if (!next || (child->num != -1 && child->num < next->num))
761 next = child;
762 }
763 }
764 workspace_next_on_output_end:
765 return next;
766 }
767
768 /*
769 * Focuses the previous workspace on same output.
770 *
771 */
772 Con *workspace_prev_on_output(void) {
773 Con *current = con_get_workspace(focused);
774 Con *prev = NULL;
775 Con *output = con_get_output(focused);
776 DLOG("output = %s\n", output->name);
777
778 if (current->num == -1) {
779 /* If named workspace, find previous named workspace. */
780 prev = TAILQ_PREV(current, nodes_head, nodes);
781 if (prev && prev->num != -1)
782 prev = NULL;
783 } else {
784 /* If numbered workspace, find previous numbered workspace. */
785 NODES_FOREACH_REVERSE (output_get_content(output)) {
786 if (child->type != CT_WORKSPACE || child->num == -1)
787 continue;
788 /* Need to check child against current and previous because we
789 * are traversing multiple lists and thus are not guaranteed
790 * the relative order between the list of workspaces. */
791 if (current->num > child->num && (!prev || child->num > prev->num))
792 prev = child;
793 }
794 }
795
796 /* Find previous named workspace. */
797 if (!prev) {
798 bool found_current = false;
799 NODES_FOREACH_REVERSE (output_get_content(output)) {
800 if (child->type != CT_WORKSPACE)
801 continue;
802 if (child == current) {
803 found_current = true;
804 } else if (child->num == -1 && (current->num != -1 || found_current)) {
805 prev = child;
806 goto workspace_prev_on_output_end;
807 }
808 }
809 }
810
811 /* Find last workspace. */
812 if (!prev) {
813 NODES_FOREACH_REVERSE (output_get_content(output)) {
814 if (child->type != CT_WORKSPACE)
815 continue;
816 if (!prev || child->num > prev->num)
817 prev = child;
818 }
819 }
820
821 workspace_prev_on_output_end:
822 return prev;
823 }
824
825 /*
826 * Focuses the previously focused workspace.
827 *
828 */
829 void workspace_back_and_forth(void) {
830 if (!previous_workspace_name) {
831 DLOG("No previous workspace name set. Not switching.\n");
832 return;
833 }
834
835 workspace_show_by_name(previous_workspace_name);
836 }
837
838 /*
839 * Returns the previously focused workspace con, or NULL if unavailable.
840 *
841 */
842 Con *workspace_back_and_forth_get(void) {
843 if (!previous_workspace_name) {
844 DLOG("No previous workspace name set.\n");
845 return NULL;
846 }
847
848 Con *workspace;
849 workspace = workspace_get(previous_workspace_name, NULL);
850
851 return workspace;
852 }
853
854 static bool get_urgency_flag(Con *con) {
855 Con *child;
856 TAILQ_FOREACH (child, &(con->nodes_head), nodes) {
857 if (child->urgent || get_urgency_flag(child)) {
858 return true;
859 }
860 }
861
862 TAILQ_FOREACH (child, &(con->floating_head), floating_windows) {
863 if (child->urgent || get_urgency_flag(child)) {
864 return true;
865 }
866 }
867
868 return false;
869 }
870
871 /*
872 * Goes through all clients on the given workspace and updates the workspace’s
873 * urgent flag accordingly.
874 *
875 */
876 void workspace_update_urgent_flag(Con *ws) {
877 bool old_flag = ws->urgent;
878 ws->urgent = get_urgency_flag(ws);
879 DLOG("Workspace urgency flag changed from %d to %d\n", old_flag, ws->urgent);
880
881 if (old_flag != ws->urgent)
882 ipc_send_workspace_event("urgent", ws, NULL);
883 }
884
885 /*
886 * 'Forces' workspace orientation by moving all cons into a new split-con with
887 * the same layout as the workspace and then changing the workspace layout.
888 *
889 */
890 void ws_force_orientation(Con *ws, orientation_t orientation) {
891 /* 1: create a new split container */
892 Con *split = con_new(NULL, NULL);
893 split->parent = ws;
894
895 /* 2: copy layout from workspace */
896 split->layout = ws->layout;
897
898 /* 3: move the existing cons of this workspace below the new con */
899 Con **focus_order = get_focus_order(ws);
900
901 DLOG("Moving cons\n");
902 while (!TAILQ_EMPTY(&(ws->nodes_head))) {
903 Con *child = TAILQ_FIRST(&(ws->nodes_head));
904 con_detach(child);
905 con_attach(child, split, true);
906 }
907
908 set_focus_order(split, focus_order);
909 free(focus_order);
910
911 /* 4: switch workspace layout */
912 ws->layout = (orientation == HORIZ) ? L_SPLITH : L_SPLITV;
913 DLOG("split->layout = %d, ws->layout = %d\n", split->layout, ws->layout);
914
915 /* 5: attach the new split container to the workspace */
916 DLOG("Attaching new split (%p) to ws (%p)\n", split, ws);
917 con_attach(split, ws, false);
918
919 /* 6: fix the percentages */
920 con_fix_percent(ws);
921 }
922
923 /*
924 * Called when a new con (with a window, not an empty or split con) should be
925 * attached to the workspace (for example when managing a new window or when
926 * moving an existing window to the workspace level).
927 *
928 * Depending on the workspace_layout setting, this function either returns the
929 * workspace itself (default layout) or creates a new stacked/tabbed con and
930 * returns that.
931 *
932 */
933 Con *workspace_attach_to(Con *ws) {
934 DLOG("Attaching a window to workspace %p / %s\n", ws, ws->name);
935
936 if (ws->workspace_layout == L_DEFAULT) {
937 DLOG("Default layout, just attaching it to the workspace itself.\n");
938 return ws;
939 }
940
941 DLOG("Non-default layout, creating a new split container\n");
942 /* 1: create a new split container */
943 Con *new = con_new(NULL, NULL);
944 new->parent = ws;
945
946 /* 2: set the requested layout on the split con */
947 new->layout = ws->workspace_layout;
948
949 /* 4: attach the new split container to the workspace */
950 DLOG("Attaching new split %p to workspace %p\n", new, ws);
951 con_attach(new, ws, false);
952
953 /* 5: fix the percentages */
954 con_fix_percent(ws);
955
956 return new;
957 }
958
959 /*
960 * Creates a new container and re-parents all of children from the given
961 * workspace into it.
962 *
963 * The container inherits the layout from the workspace.
964 */
965 Con *workspace_encapsulate(Con *ws) {
966 if (TAILQ_EMPTY(&(ws->nodes_head))) {
967 ELOG("Workspace %p / %s has no children to encapsulate\n", ws, ws->name);
968 return NULL;
969 }
970
971 Con *new = con_new(NULL, NULL);
972 new->parent = ws;
973 new->layout = ws->layout;
974
975 Con **focus_order = get_focus_order(ws);
976
977 DLOG("Moving children of workspace %p / %s into container %p\n",
978 ws, ws->name, new);
979 Con *child;
980 while (!TAILQ_EMPTY(&(ws->nodes_head))) {
981 child = TAILQ_FIRST(&(ws->nodes_head));
982 con_detach(child);
983 con_attach(child, new, true);
984 }
985
986 set_focus_order(new, focus_order);
987 free(focus_order);
988
989 con_attach(new, ws, true);
990
991 return new;
992 }
993
994 /*
995 * Move the given workspace to the specified output.
996 */
997 void workspace_move_to_output(Con *ws, Output *output) {
998 DLOG("Moving workspace %p / %s to output %p / \"%s\".\n", ws, ws->name, output, output_primary_name(output));
999
1000 Output *current_output = get_output_for_con(ws);
1001 Con *content = output_get_content(output->con);
1002 DLOG("got output %p with content %p\n", output, content);
1003
1004 if (ws->parent == content) {
1005 DLOG("Nothing to do, workspace already there\n");
1006 return;
1007 }
1008
1009 Con *previously_visible_ws = TAILQ_FIRST(&(content->focus_head));
1010 if (previously_visible_ws) {
1011 DLOG("Previously visible workspace = %p / %s\n", previously_visible_ws, previously_visible_ws->name);
1012 } else {
1013 DLOG("No previously visible workspace on output.\n");
1014 }
1015
1016 bool workspace_was_visible = workspace_is_visible(ws);
1017 if (con_num_children(ws->parent) == 1) {
1018 DLOG("Creating a new workspace to replace \"%s\" (last on its output).\n", ws->name);
1019
1020 /* check if we can find a workspace assigned to this output */
1021 bool used_assignment = false;
1022 struct Workspace_Assignment *assignment;
1023 TAILQ_FOREACH (assignment, &ws_assignments, ws_assignments) {
1024 bool attached;
1025 int num;
1026 if (!output_triggers_assignment(current_output, assignment)) {
1027 continue;
1028 }
1029 /* check if this workspace's name or num is already attached to the tree */
1030 num = ws_name_to_number(assignment->name);
1031 attached = ((num == -1) ? get_existing_workspace_by_name(assignment->name) : get_existing_workspace_by_num(num)) != NULL;
1032 if (attached) {
1033 continue;
1034 }
1035
1036 /* so create the workspace referenced to by this assignment */
1037 DLOG("Creating workspace from assignment %s.\n", assignment->name);
1038 workspace_get(assignment->name, NULL);
1039 used_assignment = true;
1040 break;
1041 }
1042
1043 /* if we couldn't create the workspace using an assignment, create it on
1044 * the output. Workspace init IPC events are sent either by
1045 * workspace_get or create_workspace_on_output. */
1046 if (!used_assignment) {
1047 create_workspace_on_output(current_output, ws->parent);
1048 }
1049 }
1050 DLOG("Detaching\n");
1051
1052 /* detach from the old output and attach to the new output */
1053 Con *old_content = ws->parent;
1054 con_detach(ws);
1055 if (workspace_was_visible) {
1056 /* The workspace which we just detached was visible, so focus the next
1057 * one in the focus-stack. */
1058 Con *focus_ws = TAILQ_FIRST(&(old_content->focus_head));
1059 DLOG("workspace was visible, focusing %p / %s now\n", focus_ws, focus_ws->name);
1060 workspace_show(focus_ws);
1061 }
1062 con_attach(ws, content, false);
1063
1064 /* fix the coordinates of the floating containers */
1065 Con *floating_con;
1066 TAILQ_FOREACH (floating_con, &(ws->floating_head), floating_windows) {
1067 floating_fix_coordinates(floating_con, &(old_content->rect), &(content->rect));
1068 }
1069
1070 ipc_send_workspace_event("move", ws, NULL);
1071 if (workspace_was_visible) {
1072 /* Focus the moved workspace on the destination output. */
1073 workspace_show(ws);
1074 }
1075
1076 ewmh_update_desktop_properties();
1077
1078 if (!previously_visible_ws) {
1079 return;
1080 }
1081
1082 /* NB: We cannot simply work with previously_visible_ws since it might have
1083 * been cleaned up by workspace_show() already, depending on the focus
1084 * order/number of other workspaces on the output. Instead, we loop through
1085 * the available workspaces and only work with previously_visible_ws if we
1086 * still find it. */
1087 TAILQ_FOREACH (ws, &(content->nodes_head), nodes) {
1088 if (ws != previously_visible_ws) {
1089 continue;
1090 }
1091
1092 /* Call the on_remove_child callback of the workspace which previously
1093 * was visible on the destination output. Since it is no longer visible,
1094 * it might need to get cleaned up. */
1095 CALL(previously_visible_ws, on_remove_child);
1096 break;
1097 }
1098 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * x.c: Interface to X11, transfers our in-memory state to X11 (see also
7 * render.c). Basically a big state machine.
8 *
9 */
10 #include "all.h"
11
12 #ifndef MAX
13 #define MAX(x, y) ((x) > (y) ? (x) : (y))
14 #endif
15
16 /* Stores the X11 window ID of the currently focused window */
17 xcb_window_t focused_id = XCB_NONE;
18
19 /* Because 'focused_id' might be reset to force input focus, we separately keep
20 * track of the X11 window ID to be able to always tell whether the focused
21 * window actually changed. */
22 static xcb_window_t last_focused = XCB_NONE;
23
24 /* Stores coordinates to warp mouse pointer to if set */
25 static Rect *warp_to;
26
27 /*
28 * Describes the X11 state we may modify (map state, position, window stack).
29 * There is one entry per container. The state represents the current situation
30 * as X11 sees it (with the exception of the order in the state_head CIRCLEQ,
31 * which represents the order that will be pushed to X11, while old_state_head
32 * represents the current order). It will be updated in x_push_changes().
33 *
34 */
35 typedef struct con_state {
36 xcb_window_t id;
37 bool mapped;
38 bool unmap_now;
39 bool child_mapped;
40 bool is_hidden;
41
42 /* The con for which this state is. */
43 Con *con;
44
45 /* For reparenting, we have a flag (need_reparent) and the X ID of the old
46 * frame this window was in. The latter is necessary because we need to
47 * ignore UnmapNotify events (by changing the window event mask). */
48 bool need_reparent;
49 xcb_window_t old_frame;
50
51 /* The container was child of floating container during the previous call of
52 * x_push_node(). This is used to remove the shape when the container is no
53 * longer floating. */
54 bool was_floating;
55
56 Rect rect;
57 Rect window_rect;
58
59 bool initial;
60
61 char *name;
62
63 CIRCLEQ_ENTRY(con_state)
64 state;
65
66 CIRCLEQ_ENTRY(con_state)
67 old_state;
68
69 TAILQ_ENTRY(con_state)
70 initial_mapping_order;
71 } con_state;
72
73 CIRCLEQ_HEAD(state_head, con_state)
74 state_head =
75 CIRCLEQ_HEAD_INITIALIZER(state_head);
76
77 CIRCLEQ_HEAD(old_state_head, con_state)
78 old_state_head =
79 CIRCLEQ_HEAD_INITIALIZER(old_state_head);
80
81 TAILQ_HEAD(initial_mapping_head, con_state)
82 initial_mapping_head =
83 TAILQ_HEAD_INITIALIZER(initial_mapping_head);
84
85 /*
86 * Returns the container state for the given frame. This function always
87 * returns a container state (otherwise, there is a bug in the code and the
88 * container state of a container for which x_con_init() was not called was
89 * requested).
90 *
91 */
92 static con_state *state_for_frame(xcb_window_t window) {
93 con_state *state;
94 CIRCLEQ_FOREACH (state, &state_head, state) {
95 if (state->id == window) {
96 return state;
97 }
98 }
99
100 /* TODO: better error handling? */
101 ELOG("No state found for window 0x%08x\n", window);
102 assert(false);
103 return NULL;
104 }
105
106 /*
107 * Changes the atoms on the root window and the windows themselves to properly
108 * reflect the current focus for ewmh compliance.
109 *
110 */
111 static void change_ewmh_focus(xcb_window_t new_focus, xcb_window_t old_focus) {
112 if (new_focus == old_focus) {
113 return;
114 }
115
116 ewmh_update_active_window(new_focus);
117
118 if (new_focus != XCB_WINDOW_NONE) {
119 ewmh_update_focused(new_focus, true);
120 }
121
122 if (old_focus != XCB_WINDOW_NONE) {
123 ewmh_update_focused(old_focus, false);
124 }
125 }
126
127 /*
128 * Initializes the X11 part for the given container. Called exactly once for
129 * every container from con_new().
130 *
131 */
132 void x_con_init(Con *con) {
133 /* TODO: maybe create the window when rendering first? we could then even
134 * get the initial geometry right */
135
136 uint32_t mask = 0;
137 uint32_t values[5];
138
139 xcb_visualid_t visual = get_visualid_by_depth(con->depth);
140 xcb_colormap_t win_colormap;
141 if (con->depth != root_depth) {
142 /* We need to create a custom colormap. */
143 win_colormap = xcb_generate_id(conn);
144 xcb_create_colormap(conn, XCB_COLORMAP_ALLOC_NONE, win_colormap, root, visual);
145 con->colormap = win_colormap;
146 } else {
147 /* Use the default colormap. */
148 win_colormap = colormap;
149 con->colormap = XCB_NONE;
150 }
151
152 /* We explicitly set a background color and border color (even though we
153 * don’t even have a border) because the X11 server requires us to when
154 * using 32 bit color depths, see
155 * https://stackoverflow.com/questions/3645632 */
156 mask |= XCB_CW_BACK_PIXEL;
157 values[0] = root_screen->black_pixel;
158
159 mask |= XCB_CW_BORDER_PIXEL;
160 values[1] = root_screen->black_pixel;
161
162 /* our own frames should not be managed */
163 mask |= XCB_CW_OVERRIDE_REDIRECT;
164 values[2] = 1;
165
166 /* see include/xcb.h for the FRAME_EVENT_MASK */
167 mask |= XCB_CW_EVENT_MASK;
168 values[3] = FRAME_EVENT_MASK & ~XCB_EVENT_MASK_ENTER_WINDOW;
169
170 mask |= XCB_CW_COLORMAP;
171 values[4] = win_colormap;
172
173 Rect dims = {-15, -15, 10, 10};
174 xcb_window_t frame_id = create_window(conn, dims, con->depth, visual, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCURSOR_CURSOR_POINTER, false, mask, values);
175 draw_util_surface_init(conn, &(con->frame), frame_id, get_visualtype_by_id(visual), dims.width, dims.height);
176 xcb_change_property(conn,
177 XCB_PROP_MODE_REPLACE,
178 con->frame.id,
179 XCB_ATOM_WM_CLASS,
180 XCB_ATOM_STRING,
181 8,
182 (strlen("i3-frame") + 1) * 2,
183 "i3-frame\0i3-frame\0");
184
185 struct con_state *state = scalloc(1, sizeof(struct con_state));
186 state->id = con->frame.id;
187 state->mapped = false;
188 state->initial = true;
189 DLOG("Adding window 0x%08x to lists\n", state->id);
190 CIRCLEQ_INSERT_HEAD(&state_head, state, state);
191 CIRCLEQ_INSERT_HEAD(&old_state_head, state, old_state);
192 TAILQ_INSERT_TAIL(&initial_mapping_head, state, initial_mapping_order);
193 DLOG("adding new state for window id 0x%08x\n", state->id);
194 }
195
196 /*
197 * Re-initializes the associated X window state for this container. You have
198 * to call this when you assign a client to an empty container to ensure that
199 * its state gets updated correctly.
200 *
201 */
202 void x_reinit(Con *con) {
203 struct con_state *state;
204
205 if ((state = state_for_frame(con->frame.id)) == NULL) {
206 ELOG("window state not found\n");
207 return;
208 }
209
210 DLOG("resetting state %p to initial\n", state);
211 state->initial = true;
212 state->child_mapped = false;
213 state->con = con;
214 memset(&(state->window_rect), 0, sizeof(Rect));
215 }
216
217 /*
218 * Reparents the child window of the given container (necessary for sticky
219 * containers). The reparenting happens in the next call of x_push_changes().
220 *
221 */
222 void x_reparent_child(Con *con, Con *old) {
223 struct con_state *state;
224 if ((state = state_for_frame(con->frame.id)) == NULL) {
225 ELOG("window state for con not found\n");
226 return;
227 }
228
229 state->need_reparent = true;
230 state->old_frame = old->frame.id;
231 }
232
233 /*
234 * Moves a child window from Container src to Container dest.
235 *
236 */
237 void x_move_win(Con *src, Con *dest) {
238 struct con_state *state_src, *state_dest;
239
240 if ((state_src = state_for_frame(src->frame.id)) == NULL) {
241 ELOG("window state for src not found\n");
242 return;
243 }
244
245 if ((state_dest = state_for_frame(dest->frame.id)) == NULL) {
246 ELOG("window state for dest not found\n");
247 return;
248 }
249
250 state_dest->con = state_src->con;
251 state_src->con = NULL;
252
253 if (rect_equals(state_dest->window_rect, (Rect){0, 0, 0, 0})) {
254 memcpy(&(state_dest->window_rect), &(state_src->window_rect), sizeof(Rect));
255 DLOG("COPYING RECT\n");
256 }
257 }
258
259 static void _x_con_kill(Con *con) {
260 con_state *state;
261
262 if (con->colormap != XCB_NONE) {
263 xcb_free_colormap(conn, con->colormap);
264 }
265
266 draw_util_surface_free(conn, &(con->frame));
267 draw_util_surface_free(conn, &(con->frame_buffer));
268 xcb_free_pixmap(conn, con->frame_buffer.id);
269 con->frame_buffer.id = XCB_NONE;
270 state = state_for_frame(con->frame.id);
271 CIRCLEQ_REMOVE(&state_head, state, state);
272 CIRCLEQ_REMOVE(&old_state_head, state, old_state);
273 TAILQ_REMOVE(&initial_mapping_head, state, initial_mapping_order);
274 FREE(state->name);
275 free(state);
276
277 /* Invalidate focused_id to correctly focus new windows with the same ID */
278 if (con->frame.id == focused_id) {
279 focused_id = XCB_NONE;
280 }
281 if (con->frame.id == last_focused) {
282 last_focused = XCB_NONE;
283 }
284 }
285
286 /*
287 * Kills the window decoration associated with the given container.
288 *
289 */
290 void x_con_kill(Con *con) {
291 _x_con_kill(con);
292 xcb_destroy_window(conn, con->frame.id);
293 }
294
295 /*
296 * Completely reinitializes the container's frame, without destroying the old window.
297 *
298 */
299 void x_con_reframe(Con *con) {
300 _x_con_kill(con);
301 x_con_init(con);
302 }
303
304 /*
305 * Returns true if the client supports the given protocol atom (like WM_DELETE_WINDOW)
306 *
307 */
308 bool window_supports_protocol(xcb_window_t window, xcb_atom_t atom) {
309 xcb_get_property_cookie_t cookie;
310 xcb_icccm_get_wm_protocols_reply_t protocols;
311 bool result = false;
312
313 cookie = xcb_icccm_get_wm_protocols(conn, window, A_WM_PROTOCOLS);
314 if (xcb_icccm_get_wm_protocols_reply(conn, cookie, &protocols, NULL) != 1)
315 return false;
316
317 /* Check if the client’s protocols have the requested atom set */
318 for (uint32_t i = 0; i < protocols.atoms_len; i++)
319 if (protocols.atoms[i] == atom)
320 result = true;
321
322 xcb_icccm_get_wm_protocols_reply_wipe(&protocols);
323
324 return result;
325 }
326
327 /*
328 * Kills the given X11 window using WM_DELETE_WINDOW (if supported).
329 *
330 */
331 void x_window_kill(xcb_window_t window, kill_window_t kill_window) {
332 /* if this window does not support WM_DELETE_WINDOW, we kill it the hard way */
333 if (!window_supports_protocol(window, A_WM_DELETE_WINDOW)) {
334 if (kill_window == KILL_WINDOW) {
335 LOG("Killing specific window 0x%08x\n", window);
336 xcb_destroy_window(conn, window);
337 } else {
338 LOG("Killing the X11 client which owns window 0x%08x\n", window);
339 xcb_kill_client(conn, window);
340 }
341 return;
342 }
343
344 /* Every X11 event is 32 bytes long. Therefore, XCB will copy 32 bytes.
345 * In order to properly initialize these bytes, we allocate 32 bytes even
346 * though we only need less for an xcb_configure_notify_event_t */
347 void *event = scalloc(32, 1);
348 xcb_client_message_event_t *ev = event;
349
350 ev->response_type = XCB_CLIENT_MESSAGE;
351 ev->window = window;
352 ev->type = A_WM_PROTOCOLS;
353 ev->format = 32;
354 ev->data.data32[0] = A_WM_DELETE_WINDOW;
355 ev->data.data32[1] = XCB_CURRENT_TIME;
356
357 LOG("Sending WM_DELETE to the client\n");
358 xcb_send_event(conn, false, window, XCB_EVENT_MASK_NO_EVENT, (char *)ev);
359 xcb_flush(conn);
360 free(event);
361 }
362
363 static void x_draw_title_border(Con *con, struct deco_render_params *p) {
364 assert(con->parent != NULL);
365
366 Rect *dr = &(con->deco_rect);
367
368 /* Left */
369 draw_util_rectangle(&(con->parent->frame_buffer), p->color->border,
370 dr->x, dr->y, 1, dr->height);
371
372 /* Right */
373 draw_util_rectangle(&(con->parent->frame_buffer), p->color->border,
374 dr->x + dr->width - 1, dr->y, 1, dr->height);
375
376 /* Top */
377 draw_util_rectangle(&(con->parent->frame_buffer), p->color->border,
378 dr->x, dr->y, dr->width, 1);
379
380 /* Bottom */
381 draw_util_rectangle(&(con->parent->frame_buffer), p->color->border,
382 dr->x, dr->y + dr->height - 1, dr->width, 1);
383 }
384
385 static void x_draw_decoration_after_title(Con *con, struct deco_render_params *p) {
386 assert(con->parent != NULL);
387
388 Rect *dr = &(con->deco_rect);
389
390 /* Redraw the right border to cut off any text that went past it.
391 * This is necessary when the text was drawn using XCB since cutting text off
392 * automatically does not work there. For pango rendering, this isn't necessary. */
393 if (!font_is_pango()) {
394 /* We actually only redraw the far right two pixels as that is the
395 * distance we keep from the edge (not the entire border width).
396 * Redrawing the entire border would cause text to be cut off. */
397 draw_util_rectangle(&(con->parent->frame_buffer), p->color->background,
398 dr->x + dr->width - 2 * logical_px(1),
399 dr->y,
400 2 * logical_px(1),
401 dr->height);
402 }
403
404 /* Redraw the border. */
405 x_draw_title_border(con, p);
406 }
407
408 /*
409 * Get rectangles representing the border around the child window. Some borders
410 * are adjacent to the screen-edge and thus not returned. Return value is the
411 * number of rectangles.
412 *
413 */
414 static size_t x_get_border_rectangles(Con *con, xcb_rectangle_t rectangles[4]) {
415 size_t count = 0;
416 int border_style = con_border_style(con);
417
418 if (border_style != BS_NONE && con_is_leaf(con)) {
419 adjacent_t borders_to_hide = con_adjacent_borders(con) & config.hide_edge_borders;
420 Rect br = con_border_style_rect(con);
421
422 if (!(borders_to_hide & ADJ_LEFT_SCREEN_EDGE)) {
423 rectangles[count++] = (xcb_rectangle_t){
424 .x = 0,
425 .y = 0,
426 .width = br.x,
427 .height = con->rect.height,
428 };
429 }
430 if (!(borders_to_hide & ADJ_RIGHT_SCREEN_EDGE)) {
431 rectangles[count++] = (xcb_rectangle_t){
432 .x = con->rect.width + (br.width + br.x),
433 .y = 0,
434 .width = -(br.width + br.x),
435 .height = con->rect.height,
436 };
437 }
438 if (!(borders_to_hide & ADJ_LOWER_SCREEN_EDGE)) {
439 rectangles[count++] = (xcb_rectangle_t){
440 .x = br.x,
441 .y = con->rect.height + (br.height + br.y),
442 .width = con->rect.width + br.width,
443 .height = -(br.height + br.y),
444 };
445 }
446 /* pixel border have an additional line at the top */
447 if (border_style == BS_PIXEL && !(borders_to_hide & ADJ_UPPER_SCREEN_EDGE)) {
448 rectangles[count++] = (xcb_rectangle_t){
449 .x = br.x,
450 .y = 0,
451 .width = con->rect.width + br.width,
452 .height = br.y,
453 };
454 }
455 }
456
457 return count;
458 }
459
460 /*
461 * Draws the decoration of the given container onto its parent.
462 *
463 */
464 void x_draw_decoration(Con *con) {
465 Con *parent = con->parent;
466 bool leaf = con_is_leaf(con);
467
468 /* This code needs to run for:
469 * • leaf containers
470 * • non-leaf containers which are in a stacked/tabbed container
471 *
472 * It does not need to run for:
473 * • direct children of outputs or dockareas
474 * • floating containers (they don’t have a decoration)
475 */
476 if ((!leaf &&
477 parent->layout != L_STACKED &&
478 parent->layout != L_TABBED) ||
479 parent->type == CT_OUTPUT ||
480 parent->type == CT_DOCKAREA ||
481 con->type == CT_FLOATING_CON)
482 return;
483
484 /* Skip containers whose height is 0 (for example empty dockareas) */
485 if (con->rect.height == 0)
486 return;
487
488 /* Skip containers whose pixmap has not yet been created (can happen when
489 * decoration rendering happens recursively for a window for which
490 * x_push_node() was not yet called) */
491 if (leaf && con->frame_buffer.id == XCB_NONE)
492 return;
493
494 /* 1: build deco_params and compare with cache */
495 struct deco_render_params *p = scalloc(1, sizeof(struct deco_render_params));
496
497 /* find out which colors to use */
498 if (con->urgent)
499 p->color = &config.client.urgent;
500 else if (con == focused || con_inside_focused(con))
501 p->color = &config.client.focused;
502 else if (con == TAILQ_FIRST(&(parent->focus_head)))
503 p->color = &config.client.focused_inactive;
504 else
505 p->color = &config.client.unfocused;
506
507 p->border_style = con_border_style(con);
508
509 Rect *r = &(con->rect);
510 Rect *w = &(con->window_rect);
511 p->con_rect = (struct width_height){r->width, r->height};
512 p->con_window_rect = (struct width_height){w->width, w->height};
513 p->con_deco_rect = con->deco_rect;
514 p->background = config.client.background;
515 p->con_is_leaf = con_is_leaf(con);
516 p->parent_layout = con->parent->layout;
517
518 if (con->deco_render_params != NULL &&
519 (con->window == NULL || !con->window->name_x_changed) &&
520 !parent->pixmap_recreated &&
521 !con->pixmap_recreated &&
522 !con->mark_changed &&
523 memcmp(p, con->deco_render_params, sizeof(struct deco_render_params)) == 0) {
524 free(p);
525 goto copy_pixmaps;
526 }
527
528 Con *next = con;
529 while ((next = TAILQ_NEXT(next, nodes))) {
530 FREE(next->deco_render_params);
531 }
532
533 FREE(con->deco_render_params);
534 con->deco_render_params = p;
535
536 if (con->window != NULL && con->window->name_x_changed)
537 con->window->name_x_changed = false;
538
539 parent->pixmap_recreated = false;
540 con->pixmap_recreated = false;
541 con->mark_changed = false;
542
543 /* 2: draw the client.background, but only for the parts around the window_rect */
544 if (con->window != NULL) {
545 /* top area */
546 draw_util_rectangle(&(con->frame_buffer), config.client.background,
547 0, 0, r->width, w->y);
548 /* bottom area */
549 draw_util_rectangle(&(con->frame_buffer), config.client.background,
550 0, w->y + w->height, r->width, r->height - (w->y + w->height));
551 /* left area */
552 draw_util_rectangle(&(con->frame_buffer), config.client.background,
553 0, 0, w->x, r->height);
554 /* right area */
555 draw_util_rectangle(&(con->frame_buffer), config.client.background,
556 w->x + w->width, 0, r->width - (w->x + w->width), r->height);
557 }
558
559 /* 3: draw a rectangle in border color around the client */
560 if (p->border_style != BS_NONE && p->con_is_leaf) {
561 /* Fill the border. We don’t just fill the whole rectangle because some
562 * children are not freely resizable and we want their background color
563 * to "shine through". */
564 xcb_rectangle_t rectangles[4];
565 size_t rectangles_count = x_get_border_rectangles(con, rectangles);
566 for (size_t i = 0; i < rectangles_count; i++) {
567 draw_util_rectangle(&(con->frame_buffer), p->color->child_border,
568 rectangles[i].x,
569 rectangles[i].y,
570 rectangles[i].width,
571 rectangles[i].height);
572 }
573
574 /* Highlight the side of the border at which the next window will be
575 * opened if we are rendering a single window within a split container
576 * (which is undistinguishable from a single window outside a split
577 * container otherwise. */
578 Rect br = con_border_style_rect(con);
579 if (TAILQ_NEXT(con, nodes) == NULL &&
580 TAILQ_PREV(con, nodes_head, nodes) == NULL &&
581 con->parent->type != CT_FLOATING_CON) {
582 if (p->parent_layout == L_SPLITH) {
583 draw_util_rectangle(&(con->frame_buffer), p->color->indicator,
584 r->width + (br.width + br.x), br.y, -(br.width + br.x), r->height + br.height);
585 } else if (p->parent_layout == L_SPLITV) {
586 draw_util_rectangle(&(con->frame_buffer), p->color->indicator,
587 br.x, r->height + (br.height + br.y), r->width + br.width, -(br.height + br.y));
588 }
589 }
590 }
591
592 /* if this is a borderless/1pixel window, we don’t need to render the
593 * decoration. */
594 if (p->border_style != BS_NORMAL)
595 goto copy_pixmaps;
596
597 /* If the parent hasn't been set up yet, skip the decoration rendering
598 * for now. */
599 if (parent->frame_buffer.id == XCB_NONE)
600 goto copy_pixmaps;
601
602 /* For the first child, we clear the parent pixmap to ensure there's no
603 * garbage left on there. This is important to avoid tearing when using
604 * transparency. */
605 if (con == TAILQ_FIRST(&(con->parent->nodes_head))) {
606 draw_util_clear_surface(&(con->parent->frame_buffer), COLOR_TRANSPARENT);
607 FREE(con->parent->deco_render_params);
608 }
609
610 /* 4: paint the bar */
611 draw_util_rectangle(&(parent->frame_buffer), p->color->background,
612 con->deco_rect.x, con->deco_rect.y, con->deco_rect.width, con->deco_rect.height);
613
614 /* 5: draw title border */
615 x_draw_title_border(con, p);
616
617 /* 6: draw the title */
618 int text_offset_y = (con->deco_rect.height - config.font.height) / 2;
619
620 const int title_padding = logical_px(2);
621 const int deco_width = (int)con->deco_rect.width;
622 int mark_width = 0;
623 if (config.show_marks && !TAILQ_EMPTY(&(con->marks_head))) {
624 char *formatted_mark = sstrdup("");
625 bool had_visible_mark = false;
626
627 mark_t *mark;
628 TAILQ_FOREACH (mark, &(con->marks_head), marks) {
629 if (mark->name[0] == '_')
630 continue;
631 had_visible_mark = true;
632
633 char *buf;
634 sasprintf(&buf, "%s[%s]", formatted_mark, mark->name);
635 free(formatted_mark);
636 formatted_mark = buf;
637 }
638
639 if (had_visible_mark) {
640 i3String *mark = i3string_from_utf8(formatted_mark);
641 mark_width = predict_text_width(mark);
642
643 int mark_offset_x = (config.title_align == ALIGN_RIGHT)
644 ? title_padding
645 : deco_width - mark_width - title_padding;
646
647 draw_util_text(mark, &(parent->frame_buffer),
648 p->color->text, p->color->background,
649 con->deco_rect.x + mark_offset_x,
650 con->deco_rect.y + text_offset_y, mark_width);
651 I3STRING_FREE(mark);
652
653 mark_width += title_padding;
654 }
655
656 FREE(formatted_mark);
657 }
658
659 i3String *title = NULL;
660 struct Window *win = con->window;
661 if (win == NULL) {
662 if (con->title_format == NULL) {
663 char *_title;
664 char *tree = con_get_tree_representation(con);
665 sasprintf(&_title, "i3: %s", tree);
666 free(tree);
667
668 title = i3string_from_utf8(_title);
669 FREE(_title);
670 } else {
671 title = con_parse_title_format(con);
672 }
673 } else {
674 title = con->title_format == NULL ? win->name : con_parse_title_format(con);
675 }
676 if (title == NULL) {
677 goto copy_pixmaps;
678 }
679
680 int title_offset_x;
681 switch (config.title_align) {
682 case ALIGN_LEFT:
683 /* (pad)[text ](pad)[mark + its pad) */
684 title_offset_x = title_padding;
685 break;
686 case ALIGN_CENTER:
687 /* (pad)[ text ](pad)[mark + its pad)
688 * To center the text inside its allocated space, the surface
689 * between the brackets, we use the formula
690 * (surface_width - predict_text_width) / 2
691 * where surface_width = deco_width - 2 * pad - mark_width
692 * so, offset = pad + (surface_width - predict_text_width) / 2 =
693 * = … = (deco_width - mark_width - predict_text_width) / 2 */
694 title_offset_x = max(title_padding, (deco_width - mark_width - predict_text_width(title)) / 2);
695 break;
696 case ALIGN_RIGHT:
697 /* [mark + its pad](pad)[ text](pad) */
698 title_offset_x = max(title_padding + mark_width, deco_width - title_padding - predict_text_width(title));
699 break;
700 }
701
702 draw_util_text(title, &(parent->frame_buffer),
703 p->color->text, p->color->background,
704 con->deco_rect.x + title_offset_x,
705 con->deco_rect.y + text_offset_y,
706 deco_width - mark_width - 2 * title_padding);
707
708 if (win == NULL || con->title_format != NULL) {
709 I3STRING_FREE(title);
710 }
711
712 x_draw_decoration_after_title(con, p);
713 copy_pixmaps:
714 draw_util_copy_surface(&(con->frame_buffer), &(con->frame), 0, 0, 0, 0, con->rect.width, con->rect.height);
715 }
716
717 /*
718 * Recursively calls x_draw_decoration. This cannot be done in x_push_node
719 * because x_push_node uses focus order to recurse (see the comment above)
720 * while drawing the decoration needs to happen in the actual order.
721 *
722 */
723 void x_deco_recurse(Con *con) {
724 Con *current;
725 bool leaf = TAILQ_EMPTY(&(con->nodes_head)) &&
726 TAILQ_EMPTY(&(con->floating_head));
727 con_state *state = state_for_frame(con->frame.id);
728
729 if (!leaf) {
730 TAILQ_FOREACH (current, &(con->nodes_head), nodes) {
731 x_deco_recurse(current);
732 }
733
734 TAILQ_FOREACH (current, &(con->floating_head), floating_windows) {
735 x_deco_recurse(current);
736 }
737
738 if (state->mapped) {
739 draw_util_copy_surface(&(con->frame_buffer), &(con->frame), 0, 0, 0, 0, con->rect.width, con->rect.height);
740 }
741 }
742
743 if ((con->type != CT_ROOT && con->type != CT_OUTPUT) &&
744 (!leaf || con->mapped))
745 x_draw_decoration(con);
746 }
747
748 /*
749 * Sets or removes the _NET_WM_STATE_HIDDEN property on con if necessary.
750 *
751 */
752 static void set_hidden_state(Con *con) {
753 if (con->window == NULL) {
754 return;
755 }
756
757 con_state *state = state_for_frame(con->frame.id);
758 bool should_be_hidden = con_is_hidden(con);
759 if (should_be_hidden == state->is_hidden)
760 return;
761
762 if (should_be_hidden) {
763 DLOG("setting _NET_WM_STATE_HIDDEN for con = %p\n", con);
764 xcb_add_property_atom(conn, con->window->id, A__NET_WM_STATE, A__NET_WM_STATE_HIDDEN);
765 } else {
766 DLOG("removing _NET_WM_STATE_HIDDEN for con = %p\n", con);
767 xcb_remove_property_atom(conn, con->window->id, A__NET_WM_STATE, A__NET_WM_STATE_HIDDEN);
768 }
769
770 state->is_hidden = should_be_hidden;
771 }
772
773 /*
774 * Set the container frame shape as the union of the window shape and the
775 * shape of the frame borders.
776 */
777 static void x_shape_frame(Con *con, xcb_shape_sk_t shape_kind) {
778 assert(con->window);
779
780 xcb_shape_combine(conn, XCB_SHAPE_SO_SET, shape_kind, shape_kind,
781 con->frame.id,
782 con->window_rect.x + con->border_width,
783 con->window_rect.y + con->border_width,
784 con->window->id);
785 xcb_rectangle_t rectangles[4];
786 size_t rectangles_count = x_get_border_rectangles(con, rectangles);
787 if (rectangles_count) {
788 xcb_shape_rectangles(conn, XCB_SHAPE_SO_UNION, shape_kind,
789 XCB_CLIP_ORDERING_UNSORTED, con->frame.id,
790 0, 0, rectangles_count, rectangles);
791 }
792 }
793
794 /*
795 * Reset the container frame shape.
796 */
797 static void x_unshape_frame(Con *con, xcb_shape_sk_t shape_kind) {
798 assert(con->window);
799
800 xcb_shape_mask(conn, XCB_SHAPE_SO_SET, shape_kind, con->frame.id, 0, 0, XCB_PIXMAP_NONE);
801 }
802
803 /*
804 * Shape or unshape container frame based on the con state.
805 */
806 static void set_shape_state(Con *con, bool need_reshape) {
807 if (!shape_supported || con->window == NULL) {
808 return;
809 }
810
811 struct con_state *state;
812 if ((state = state_for_frame(con->frame.id)) == NULL) {
813 ELOG("window state for con %p not found\n", con);
814 return;
815 }
816
817 if (need_reshape && con_is_floating(con)) {
818 /* We need to reshape the window frame only if it already has shape. */
819 if (con->window->shaped) {
820 x_shape_frame(con, XCB_SHAPE_SK_BOUNDING);
821 }
822 if (con->window->input_shaped) {
823 x_shape_frame(con, XCB_SHAPE_SK_INPUT);
824 }
825 }
826
827 if (state->was_floating && !con_is_floating(con)) {
828 /* Remove the shape when container is no longer floating. */
829 if (con->window->shaped) {
830 x_unshape_frame(con, XCB_SHAPE_SK_BOUNDING);
831 }
832 if (con->window->input_shaped) {
833 x_unshape_frame(con, XCB_SHAPE_SK_INPUT);
834 }
835 }
836 }
837
838 /*
839 * This function pushes the properties of each node of the layout tree to
840 * X11 if they have changed (like the map state, position of the window, …).
841 * It recursively traverses all children of the given node.
842 *
843 */
844 void x_push_node(Con *con) {
845 Con *current;
846 con_state *state;
847 Rect rect = con->rect;
848
849 //DLOG("Pushing changes for node %p / %s\n", con, con->name);
850 state = state_for_frame(con->frame.id);
851
852 if (state->name != NULL) {
853 DLOG("pushing name %s for con %p\n", state->name, con);
854
855 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, con->frame.id,
856 XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, strlen(state->name), state->name);
857 FREE(state->name);
858 }
859
860 if (con->window == NULL) {
861 /* Calculate the height of all window decorations which will be drawn on to
862 * this frame. */
863 uint32_t max_y = 0, max_height = 0;
864 TAILQ_FOREACH (current, &(con->nodes_head), nodes) {
865 Rect *dr = &(current->deco_rect);
866 if (dr->y >= max_y && dr->height >= max_height) {
867 max_y = dr->y;
868 max_height = dr->height;
869 }
870 }
871 rect.height = max_y + max_height;
872 if (rect.height == 0)
873 con->mapped = false;
874 }
875
876 bool need_reshape = false;
877
878 /* reparent the child window (when the window was moved due to a sticky
879 * container) */
880 if (state->need_reparent && con->window != NULL) {
881 DLOG("Reparenting child window\n");
882
883 /* Temporarily set the event masks to XCB_NONE so that we won’t get
884 * UnmapNotify events (otherwise the handler would close the container).
885 * These events are generated automatically when reparenting. */
886 uint32_t values[] = {XCB_NONE};
887 xcb_change_window_attributes(conn, state->old_frame, XCB_CW_EVENT_MASK, values);
888 xcb_change_window_attributes(conn, con->window->id, XCB_CW_EVENT_MASK, values);
889
890 xcb_reparent_window(conn, con->window->id, con->frame.id, 0, 0);
891
892 values[0] = FRAME_EVENT_MASK;
893 xcb_change_window_attributes(conn, state->old_frame, XCB_CW_EVENT_MASK, values);
894 values[0] = CHILD_EVENT_MASK;
895 xcb_change_window_attributes(conn, con->window->id, XCB_CW_EVENT_MASK, values);
896
897 state->old_frame = XCB_NONE;
898 state->need_reparent = false;
899
900 con->ignore_unmap++;
901 DLOG("ignore_unmap for reparenting of con %p (win 0x%08x) is now %d\n",
902 con, con->window->id, con->ignore_unmap);
903
904 need_reshape = true;
905 }
906
907 /* We need to update shape when window frame dimensions is updated. */
908 need_reshape |= state->rect.width != rect.width ||
909 state->rect.height != rect.height ||
910 state->window_rect.width != con->window_rect.width ||
911 state->window_rect.height != con->window_rect.height;
912
913 /* We need to set shape when container becomes floating. */
914 need_reshape |= con_is_floating(con) && !state->was_floating;
915
916 /* The pixmap of a borderless leaf container will not be used except
917 * for the titlebar in a stack or tabs (issue #1013). */
918 bool is_pixmap_needed = (con->border_style != BS_NONE ||
919 !con_is_leaf(con) ||
920 con->parent->layout == L_STACKED ||
921 con->parent->layout == L_TABBED);
922
923 /* The root con and output cons will never require a pixmap. In particular for the
924 * __i3 output, this will likely not work anyway because it might be ridiculously
925 * large, causing an XCB_ALLOC error. */
926 if (con->type == CT_ROOT || con->type == CT_OUTPUT)
927 is_pixmap_needed = false;
928
929 bool fake_notify = false;
930 /* Set new position if rect changed (and if height > 0) or if the pixmap
931 * needs to be recreated */
932 if ((is_pixmap_needed && con->frame_buffer.id == XCB_NONE) || (!rect_equals(state->rect, rect) &&
933 rect.height > 0)) {
934 /* We first create the new pixmap, then render to it, set it as the
935 * background and only afterwards change the window size. This reduces
936 * flickering. */
937
938 bool has_rect_changed = (state->rect.x != rect.x || state->rect.y != rect.y ||
939 state->rect.width != rect.width || state->rect.height != rect.height);
940
941 /* Check if the container has an unneeded pixmap left over from
942 * previously having a border or titlebar. */
943 if (!is_pixmap_needed && con->frame_buffer.id != XCB_NONE) {
944 draw_util_surface_free(conn, &(con->frame_buffer));
945 xcb_free_pixmap(conn, con->frame_buffer.id);
946 con->frame_buffer.id = XCB_NONE;
947 }
948
949 if (is_pixmap_needed && (has_rect_changed || con->frame_buffer.id == XCB_NONE)) {
950 if (con->frame_buffer.id == XCB_NONE) {
951 con->frame_buffer.id = xcb_generate_id(conn);
952 } else {
953 draw_util_surface_free(conn, &(con->frame_buffer));
954 xcb_free_pixmap(conn, con->frame_buffer.id);
955 }
956
957 uint16_t win_depth = root_depth;
958 if (con->window)
959 win_depth = con->window->depth;
960
961 /* Ensure we have valid dimensions for our surface. */
962 // TODO This is probably a bug in the condition above as we should never enter this path
963 // for height == 0. Also, we should probably handle width == 0 the same way.
964 int width = MAX((int32_t)rect.width, 1);
965 int height = MAX((int32_t)rect.height, 1);
966
967 xcb_create_pixmap(conn, win_depth, con->frame_buffer.id, con->frame.id, width, height);
968 draw_util_surface_init(conn, &(con->frame_buffer), con->frame_buffer.id,
969 get_visualtype_by_id(get_visualid_by_depth(win_depth)), width, height);
970
971 /* For the graphics context, we disable GraphicsExposure events.
972 * Those will be sent when a CopyArea request cannot be fulfilled
973 * properly due to parts of the source being unmapped or otherwise
974 * unavailable. Since we always copy from pixmaps to windows, this
975 * is not a concern for us. */
976 xcb_change_gc(conn, con->frame_buffer.gc, XCB_GC_GRAPHICS_EXPOSURES, (uint32_t[]){0});
977
978 draw_util_surface_set_size(&(con->frame), width, height);
979 con->pixmap_recreated = true;
980
981 /* Don’t render the decoration for windows inside a stack which are
982 * not visible right now */
983 // TODO Should this work the same way for L_TABBED?
984 if (!con->parent ||
985 con->parent->layout != L_STACKED ||
986 TAILQ_FIRST(&(con->parent->focus_head)) == con)
987 /* Render the decoration now to make the correct decoration visible
988 * from the very first moment. Later calls will be cached, so this
989 * doesn’t hurt performance. */
990 x_deco_recurse(con);
991 }
992
993 DLOG("setting rect (%d, %d, %d, %d)\n", rect.x, rect.y, rect.width, rect.height);
994 /* flush to ensure that the following commands are sent in a single
995 * buffer and will be processed directly afterwards (the contents of a
996 * window get lost when resizing it, therefore we want to provide it as
997 * fast as possible) */
998 xcb_flush(conn);
999 xcb_set_window_rect(conn, con->frame.id, rect);
1000 if (con->frame_buffer.id != XCB_NONE) {
1001 draw_util_copy_surface(&(con->frame_buffer), &(con->frame), 0, 0, 0, 0, con->rect.width, con->rect.height);
1002 }
1003 xcb_flush(conn);
1004
1005 memcpy(&(state->rect), &rect, sizeof(Rect));
1006 fake_notify = true;
1007 }
1008
1009 /* dito, but for child windows */
1010 if (con->window != NULL &&
1011 !rect_equals(state->window_rect, con->window_rect)) {
1012 DLOG("setting window rect (%d, %d, %d, %d)\n",
1013 con->window_rect.x, con->window_rect.y, con->window_rect.width, con->window_rect.height);
1014 xcb_set_window_rect(conn, con->window->id, con->window_rect);
1015 memcpy(&(state->window_rect), &(con->window_rect), sizeof(Rect));
1016 fake_notify = true;
1017 }
1018
1019 set_shape_state(con, need_reshape);
1020
1021 /* Map if map state changed, also ensure that the child window
1022 * is changed if we are mapped and there is a new, unmapped child window.
1023 * Unmaps are handled in x_push_node_unmaps(). */
1024 if ((state->mapped != con->mapped || (con->window != NULL && !state->child_mapped)) &&
1025 con->mapped) {
1026 xcb_void_cookie_t cookie;
1027
1028 if (con->window != NULL) {
1029 /* Set WM_STATE_NORMAL because GTK applications don’t want to
1030 * drag & drop if we don’t. Also, xprop(1) needs it. */
1031 long data[] = {XCB_ICCCM_WM_STATE_NORMAL, XCB_NONE};
1032 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, con->window->id,
1033 A_WM_STATE, A_WM_STATE, 32, 2, data);
1034 }
1035
1036 uint32_t values[1];
1037 if (!state->child_mapped && con->window != NULL) {
1038 cookie = xcb_map_window(conn, con->window->id);
1039
1040 /* We are interested in EnterNotifys as soon as the window is
1041 * mapped */
1042 values[0] = CHILD_EVENT_MASK;
1043 xcb_change_window_attributes(conn, con->window->id, XCB_CW_EVENT_MASK, values);
1044 DLOG("mapping child window (serial %d)\n", cookie.sequence);
1045 state->child_mapped = true;
1046 }
1047
1048 cookie = xcb_map_window(conn, con->frame.id);
1049
1050 values[0] = FRAME_EVENT_MASK;
1051 xcb_change_window_attributes(conn, con->frame.id, XCB_CW_EVENT_MASK, values);
1052
1053 /* copy the pixmap contents to the frame window immediately after mapping */
1054 if (con->frame_buffer.id != XCB_NONE) {
1055 draw_util_copy_surface(&(con->frame_buffer), &(con->frame), 0, 0, 0, 0, con->rect.width, con->rect.height);
1056 }
1057 xcb_flush(conn);
1058
1059 DLOG("mapping container %08x (serial %d)\n", con->frame.id, cookie.sequence);
1060 state->mapped = con->mapped;
1061 }
1062
1063 state->unmap_now = (state->mapped != con->mapped) && !con->mapped;
1064 state->was_floating = con_is_floating(con);
1065
1066 if (fake_notify) {
1067 DLOG("Sending fake configure notify\n");
1068 fake_absolute_configure_notify(con);
1069 }
1070
1071 set_hidden_state(con);
1072
1073 /* Handle all children and floating windows of this node. We recurse
1074 * in focus order to display the focused client in a stack first when
1075 * switching workspaces (reduces flickering). */
1076 TAILQ_FOREACH (current, &(con->focus_head), focused) {
1077 x_push_node(current);
1078 }
1079 }
1080
1081 /*
1082 * Same idea as in x_push_node(), but this function only unmaps windows. It is
1083 * necessary to split this up to handle new fullscreen clients properly: The
1084 * new window needs to be mapped and focus needs to be set *before* the
1085 * underlying windows are unmapped. Otherwise, focus will revert to the
1086 * PointerRoot and will then be set to the new window, generating unnecessary
1087 * FocusIn/FocusOut events.
1088 *
1089 */
1090 static void x_push_node_unmaps(Con *con) {
1091 Con *current;
1092 con_state *state;
1093
1094 //DLOG("Pushing changes (with unmaps) for node %p / %s\n", con, con->name);
1095 state = state_for_frame(con->frame.id);
1096
1097 /* map/unmap if map state changed, also ensure that the child window
1098 * is changed if we are mapped *and* in initial state (meaning the
1099 * container was empty before, but now got a child) */
1100 if (state->unmap_now) {
1101 xcb_void_cookie_t cookie;
1102 if (con->window != NULL) {
1103 /* Set WM_STATE_WITHDRAWN, it seems like Java apps need it */
1104 long data[] = {XCB_ICCCM_WM_STATE_WITHDRAWN, XCB_NONE};
1105 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, con->window->id,
1106 A_WM_STATE, A_WM_STATE, 32, 2, data);
1107 }
1108
1109 cookie = xcb_unmap_window(conn, con->frame.id);
1110 DLOG("unmapping container %p / %s (serial %d)\n", con, con->name, cookie.sequence);
1111 /* we need to increase ignore_unmap for this container (if it
1112 * contains a window) and for every window "under" this one which
1113 * contains a window */
1114 if (con->window != NULL) {
1115 con->ignore_unmap++;
1116 DLOG("ignore_unmap for con %p (frame 0x%08x) now %d\n", con, con->frame.id, con->ignore_unmap);
1117 }
1118 state->mapped = con->mapped;
1119 }
1120
1121 /* handle all children and floating windows of this node */
1122 TAILQ_FOREACH (current, &(con->nodes_head), nodes) {
1123 x_push_node_unmaps(current);
1124 }
1125
1126 TAILQ_FOREACH (current, &(con->floating_head), floating_windows) {
1127 x_push_node_unmaps(current);
1128 }
1129 }
1130
1131 /*
1132 * Returns true if the given container is currently attached to its parent.
1133 *
1134 * TODO: Remove once #1185 has been fixed
1135 */
1136 static bool is_con_attached(Con *con) {
1137 if (con->parent == NULL)
1138 return false;
1139
1140 Con *current;
1141 TAILQ_FOREACH (current, &(con->parent->nodes_head), nodes) {
1142 if (current == con)
1143 return true;
1144 }
1145
1146 return false;
1147 }
1148
1149 /*
1150 * Pushes all changes (state of each node, see x_push_node() and the window
1151 * stack) to X11.
1152 *
1153 * NOTE: We need to push the stack first so that the windows have the correct
1154 * stacking order. This is relevant for workspace switching where we map the
1155 * windows because mapping may generate EnterNotify events. When they are
1156 * generated in the wrong order, this will cause focus problems when switching
1157 * workspaces.
1158 *
1159 */
1160 void x_push_changes(Con *con) {
1161 con_state *state;
1162 xcb_query_pointer_cookie_t pointercookie;
1163
1164 /* If we need to warp later, we request the pointer position as soon as possible */
1165 if (warp_to) {
1166 pointercookie = xcb_query_pointer(conn, root);
1167 }
1168
1169 DLOG("-- PUSHING WINDOW STACK --\n");
1170 //DLOG("Disabling EnterNotify\n");
1171 /* We need to keep SubstructureRedirect around, otherwise clients can send
1172 * ConfigureWindow requests and get them applied directly instead of having
1173 * them become ConfigureRequests that i3 handles. */
1174 uint32_t values[1] = {XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT};
1175 CIRCLEQ_FOREACH_REVERSE (state, &state_head, state) {
1176 if (state->mapped)
1177 xcb_change_window_attributes(conn, state->id, XCB_CW_EVENT_MASK, values);
1178 }
1179 //DLOG("Done, EnterNotify disabled\n");
1180 bool order_changed = false;
1181 bool stacking_changed = false;
1182
1183 /* count first, necessary to (re)allocate memory for the bottom-to-top
1184 * stack afterwards */
1185 int cnt = 0;
1186 CIRCLEQ_FOREACH_REVERSE (state, &state_head, state) {
1187 if (con_has_managed_window(state->con)) {
1188 cnt++;
1189 }
1190 }
1191
1192 /* The bottom-to-top window stack of all windows which are managed by i3.
1193 * Used for x_get_window_stack(). */
1194 static xcb_window_t *client_list_windows = NULL;
1195 static int client_list_count = 0;
1196
1197 if (cnt != client_list_count) {
1198 client_list_windows = srealloc(client_list_windows, sizeof(xcb_window_t) * cnt);
1199 client_list_count = cnt;
1200 }
1201
1202 xcb_window_t *walk = client_list_windows;
1203
1204 /* X11 correctly represents the stack if we push it from bottom to top */
1205 CIRCLEQ_FOREACH_REVERSE (state, &state_head, state) {
1206 if (con_has_managed_window(state->con))
1207 memcpy(walk++, &(state->con->window->id), sizeof(xcb_window_t));
1208
1209 //DLOG("stack: 0x%08x\n", state->id);
1210 con_state *prev = CIRCLEQ_PREV(state, state);
1211 con_state *old_prev = CIRCLEQ_PREV(state, old_state);
1212 if (prev != old_prev)
1213 order_changed = true;
1214 if ((state->initial || order_changed) && prev != CIRCLEQ_END(&state_head)) {
1215 stacking_changed = true;
1216 //DLOG("Stacking 0x%08x above 0x%08x\n", prev->id, state->id);
1217 uint32_t mask = 0;
1218 mask |= XCB_CONFIG_WINDOW_SIBLING;
1219 mask |= XCB_CONFIG_WINDOW_STACK_MODE;
1220 uint32_t values[] = {state->id, XCB_STACK_MODE_ABOVE};
1221
1222 xcb_configure_window(conn, prev->id, mask, values);
1223 }
1224 state->initial = false;
1225 }
1226
1227 /* If we re-stacked something (or a new window appeared), we need to update
1228 * the _NET_CLIENT_LIST and _NET_CLIENT_LIST_STACKING hints */
1229 if (stacking_changed) {
1230 DLOG("Client list changed (%i clients)\n", cnt);
1231 ewmh_update_client_list_stacking(client_list_windows, client_list_count);
1232
1233 walk = client_list_windows;
1234
1235 /* reorder by initial mapping */
1236 TAILQ_FOREACH (state, &initial_mapping_head, initial_mapping_order) {
1237 if (con_has_managed_window(state->con))
1238 *walk++ = state->con->window->id;
1239 }
1240
1241 ewmh_update_client_list(client_list_windows, client_list_count);
1242 }
1243
1244 DLOG("PUSHING CHANGES\n");
1245 x_push_node(con);
1246
1247 if (warp_to) {
1248 xcb_query_pointer_reply_t *pointerreply = xcb_query_pointer_reply(conn, pointercookie, NULL);
1249 if (!pointerreply) {
1250 ELOG("Could not query pointer position, not warping pointer\n");
1251 } else {
1252 int mid_x = warp_to->x + (warp_to->width / 2);
1253 int mid_y = warp_to->y + (warp_to->height / 2);
1254
1255 Output *current = get_output_containing(pointerreply->root_x, pointerreply->root_y);
1256 Output *target = get_output_containing(mid_x, mid_y);
1257 if (current != target) {
1258 /* Ignore MotionNotify events generated by warping */
1259 xcb_change_window_attributes(conn, root, XCB_CW_EVENT_MASK, (uint32_t[]){XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT});
1260 xcb_warp_pointer(conn, XCB_NONE, root, 0, 0, 0, 0, mid_x, mid_y);
1261 xcb_change_window_attributes(conn, root, XCB_CW_EVENT_MASK, (uint32_t[]){ROOT_EVENT_MASK});
1262 }
1263
1264 free(pointerreply);
1265 }
1266 warp_to = NULL;
1267 }
1268
1269 //DLOG("Re-enabling EnterNotify\n");
1270 values[0] = FRAME_EVENT_MASK;
1271 CIRCLEQ_FOREACH_REVERSE (state, &state_head, state) {
1272 if (state->mapped)
1273 xcb_change_window_attributes(conn, state->id, XCB_CW_EVENT_MASK, values);
1274 }
1275 //DLOG("Done, EnterNotify re-enabled\n");
1276
1277 x_deco_recurse(con);
1278
1279 xcb_window_t to_focus = focused->frame.id;
1280 if (focused->window != NULL)
1281 to_focus = focused->window->id;
1282
1283 if (focused_id != to_focus) {
1284 if (!focused->mapped) {
1285 DLOG("Not updating focus (to %p / %s), focused window is not mapped.\n", focused, focused->name);
1286 /* Invalidate focused_id to correctly focus new windows with the same ID */
1287 focused_id = XCB_NONE;
1288 } else {
1289 if (focused->window != NULL &&
1290 focused->window->needs_take_focus &&
1291 focused->window->doesnt_accept_focus) {
1292 DLOG("Updating focus by sending WM_TAKE_FOCUS to window 0x%08x (focused: %p / %s)\n",
1293 to_focus, focused, focused->name);
1294 send_take_focus(to_focus, last_timestamp);
1295
1296 change_ewmh_focus((con_has_managed_window(focused) ? focused->window->id : XCB_WINDOW_NONE), last_focused);
1297
1298 if (to_focus != last_focused && is_con_attached(focused))
1299 ipc_send_window_event("focus", focused);
1300 } else {
1301 DLOG("Updating focus (focused: %p / %s) to X11 window 0x%08x\n", focused, focused->name, to_focus);
1302 /* We remove XCB_EVENT_MASK_FOCUS_CHANGE from the event mask to get
1303 * no focus change events for our own focus changes. We only want
1304 * these generated by the clients. */
1305 if (focused->window != NULL) {
1306 values[0] = CHILD_EVENT_MASK & ~(XCB_EVENT_MASK_FOCUS_CHANGE);
1307 xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values);
1308 }
1309 xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, to_focus, last_timestamp);
1310 if (focused->window != NULL) {
1311 values[0] = CHILD_EVENT_MASK;
1312 xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values);
1313 }
1314
1315 change_ewmh_focus((con_has_managed_window(focused) ? focused->window->id : XCB_WINDOW_NONE), last_focused);
1316
1317 if (to_focus != XCB_NONE && to_focus != last_focused && focused->window != NULL && is_con_attached(focused))
1318 ipc_send_window_event("focus", focused);
1319 }
1320
1321 focused_id = last_focused = to_focus;
1322 }
1323 }
1324
1325 if (focused_id == XCB_NONE) {
1326 /* If we still have no window to focus, we focus the EWMH window instead. We use this rather than the
1327 * root window in order to avoid an X11 fallback mechanism causing a ghosting effect (see #1378). */
1328 DLOG("Still no window focused, better set focus to the EWMH support window (%d)\n", ewmh_window);
1329 xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, ewmh_window, last_timestamp);
1330 change_ewmh_focus(XCB_WINDOW_NONE, last_focused);
1331
1332 focused_id = ewmh_window;
1333 last_focused = XCB_NONE;
1334 }
1335
1336 xcb_flush(conn);
1337 DLOG("ENDING CHANGES\n");
1338
1339 /* Disable EnterWindow events for windows which will be unmapped in
1340 * x_push_node_unmaps() now. Unmapping windows happens when switching
1341 * workspaces. We want to avoid getting EnterNotifies during that phase
1342 * because they would screw up our focus. One of these cases is having a
1343 * stack with two windows. If the first window is focused and gets
1344 * unmapped, the second one appears under the cursor and therefore gets an
1345 * EnterNotify event. */
1346 values[0] = FRAME_EVENT_MASK & ~XCB_EVENT_MASK_ENTER_WINDOW;
1347 CIRCLEQ_FOREACH_REVERSE (state, &state_head, state) {
1348 if (!state->unmap_now)
1349 continue;
1350 xcb_change_window_attributes(conn, state->id, XCB_CW_EVENT_MASK, values);
1351 }
1352
1353 /* Push all pending unmaps */
1354 x_push_node_unmaps(con);
1355
1356 /* save the current stack as old stack */
1357 CIRCLEQ_FOREACH (state, &state_head, state) {
1358 CIRCLEQ_REMOVE(&old_state_head, state, old_state);
1359 CIRCLEQ_INSERT_TAIL(&old_state_head, state, old_state);
1360 }
1361 //CIRCLEQ_FOREACH(state, &old_state_head, old_state) {
1362 // DLOG("old stack: 0x%08x\n", state->id);
1363 //}
1364
1365 xcb_flush(conn);
1366 }
1367
1368 /*
1369 * Raises the specified container in the internal stack of X windows. The
1370 * next call to x_push_changes() will make the change visible in X11.
1371 *
1372 */
1373 void x_raise_con(Con *con) {
1374 con_state *state;
1375 state = state_for_frame(con->frame.id);
1376 //DLOG("raising in new stack: %p / %s / %s / xid %08x\n", con, con->name, con->window ? con->window->name_json : "", state->id);
1377
1378 CIRCLEQ_REMOVE(&state_head, state, state);
1379 CIRCLEQ_INSERT_HEAD(&state_head, state, state);
1380 }
1381
1382 /*
1383 * Sets the WM_NAME property (so, no UTF8, but used only for debugging anyways)
1384 * of the given name. Used for properly tagging the windows for easily spotting
1385 * i3 windows in xwininfo -root -all.
1386 *
1387 */
1388 void x_set_name(Con *con, const char *name) {
1389 struct con_state *state;
1390
1391 if ((state = state_for_frame(con->frame.id)) == NULL) {
1392 ELOG("window state not found\n");
1393 return;
1394 }
1395
1396 FREE(state->name);
1397 state->name = sstrdup(name);
1398 }
1399
1400 /*
1401 * Set up the I3_SHMLOG_PATH atom.
1402 *
1403 */
1404 void update_shmlog_atom(void) {
1405 if (*shmlogname == '\0') {
1406 xcb_delete_property(conn, root, A_I3_SHMLOG_PATH);
1407 } else {
1408 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root,
1409 A_I3_SHMLOG_PATH, A_UTF8_STRING, 8,
1410 strlen(shmlogname), shmlogname);
1411 }
1412 }
1413
1414 /*
1415 * Sets up i3 specific atoms (I3_SOCKET_PATH and I3_CONFIG_PATH)
1416 *
1417 */
1418 void x_set_i3_atoms(void) {
1419 pid_t pid = getpid();
1420 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_SOCKET_PATH, A_UTF8_STRING, 8,
1421 (current_socketpath == NULL ? 0 : strlen(current_socketpath)),
1422 current_socketpath);
1423 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_PID, XCB_ATOM_CARDINAL, 32, 1, &pid);
1424 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_CONFIG_PATH, A_UTF8_STRING, 8,
1425 strlen(current_configpath), current_configpath);
1426 update_shmlog_atom();
1427 }
1428
1429 /*
1430 * Set warp_to coordinates. This will trigger on the next call to
1431 * x_push_changes().
1432 *
1433 */
1434 void x_set_warp_to(Rect *rect) {
1435 if (config.mouse_warping != POINTER_WARPING_NONE)
1436 warp_to = rect;
1437 }
1438
1439 /*
1440 * Applies the given mask to the event mask of every i3 window decoration X11
1441 * window. This is useful to disable EnterNotify while resizing so that focus
1442 * is untouched.
1443 *
1444 */
1445 void x_mask_event_mask(uint32_t mask) {
1446 uint32_t values[] = {FRAME_EVENT_MASK & mask};
1447
1448 con_state *state;
1449 CIRCLEQ_FOREACH_REVERSE (state, &state_head, state) {
1450 if (state->mapped)
1451 xcb_change_window_attributes(conn, state->id, XCB_CW_EVENT_MASK, values);
1452 }
1453 }
1454
1455 /*
1456 * Enables or disables nonrectangular shape of the container frame.
1457 */
1458 void x_set_shape(Con *con, xcb_shape_sk_t kind, bool enable) {
1459 struct con_state *state;
1460 if ((state = state_for_frame(con->frame.id)) == NULL) {
1461 ELOG("window state for con %p not found\n", con);
1462 return;
1463 }
1464
1465 switch (kind) {
1466 case XCB_SHAPE_SK_BOUNDING:
1467 con->window->shaped = enable;
1468 break;
1469 case XCB_SHAPE_SK_INPUT:
1470 con->window->input_shaped = enable;
1471 break;
1472 default:
1473 ELOG("Received unknown shape event kind for con %p. This is a bug.\n",
1474 con);
1475 return;
1476 }
1477
1478 if (con_is_floating(con)) {
1479 if (enable) {
1480 x_shape_frame(con, kind);
1481 } else {
1482 x_unshape_frame(con, kind);
1483 }
1484
1485 xcb_flush(conn);
1486 }
1487 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * xcb.c: Helper functions for easier usage of XCB
7 *
8 */
9 #include "all.h"
10
11 unsigned int xcb_numlock_mask;
12
13 /*
14 * Convenience wrapper around xcb_create_window which takes care of depth, generating an ID and checking
15 * for errors.
16 *
17 */
18 xcb_window_t create_window(xcb_connection_t *conn, Rect dims,
19 uint16_t depth, xcb_visualid_t visual, uint16_t window_class,
20 enum xcursor_cursor_t cursor, bool map, uint32_t mask, uint32_t *values) {
21 xcb_window_t result = xcb_generate_id(conn);
22
23 /* If the window class is XCB_WINDOW_CLASS_INPUT_ONLY, we copy depth and
24 * visual id from the parent window. */
25 if (window_class == XCB_WINDOW_CLASS_INPUT_ONLY) {
26 depth = XCB_COPY_FROM_PARENT;
27 visual = XCB_COPY_FROM_PARENT;
28 }
29
30 xcb_void_cookie_t gc_cookie = xcb_create_window(conn,
31 depth,
32 result, /* the window id */
33 root, /* parent == root */
34 dims.x, dims.y, dims.width, dims.height, /* dimensions */
35 0, /* border = 0, we draw our own */
36 window_class,
37 visual,
38 mask,
39 values);
40
41 xcb_generic_error_t *error = xcb_request_check(conn, gc_cookie);
42 if (error != NULL) {
43 ELOG("Could not create window. Error code: %d.\n", error->error_code);
44 }
45
46 /* Set the cursor */
47 uint32_t cursor_values[] = {xcursor_get_cursor(cursor)};
48 xcb_change_window_attributes(conn, result, XCB_CW_CURSOR, cursor_values);
49
50 /* Map the window (= make it visible) */
51 if (map)
52 xcb_map_window(conn, result);
53
54 return result;
55 }
56
57 /*
58 * Generates a configure_notify_event with absolute coordinates (relative to the X root
59 * window, not to the client’s frame) for the given client.
60 *
61 */
62 void fake_absolute_configure_notify(Con *con) {
63 xcb_rectangle_t absolute;
64 if (con->window == NULL)
65 return;
66
67 absolute.x = con->rect.x + con->window_rect.x;
68 absolute.y = con->rect.y + con->window_rect.y;
69 absolute.width = con->window_rect.width;
70 absolute.height = con->window_rect.height;
71
72 DLOG("fake rect = (%d, %d, %d, %d)\n", absolute.x, absolute.y, absolute.width, absolute.height);
73
74 fake_configure_notify(conn, absolute, con->window->id, con->border_width);
75 }
76
77 /*
78 * Sends the WM_TAKE_FOCUS ClientMessage to the given window
79 *
80 */
81 void send_take_focus(xcb_window_t window, xcb_timestamp_t timestamp) {
82 /* Every X11 event is 32 bytes long. Therefore, XCB will copy 32 bytes.
83 * In order to properly initialize these bytes, we allocate 32 bytes even
84 * though we only need less for an xcb_configure_notify_event_t */
85 void *event = scalloc(32, 1);
86 xcb_client_message_event_t *ev = event;
87
88 ev->response_type = XCB_CLIENT_MESSAGE;
89 ev->window = window;
90 ev->type = A_WM_PROTOCOLS;
91 ev->format = 32;
92 ev->data.data32[0] = A_WM_TAKE_FOCUS;
93 ev->data.data32[1] = timestamp;
94
95 DLOG("Sending WM_TAKE_FOCUS to the client\n");
96 xcb_send_event(conn, false, window, XCB_EVENT_MASK_NO_EVENT, (char *)ev);
97 free(event);
98 }
99
100 /*
101 * Configures the given window to have the size/position specified by given rect
102 *
103 */
104 void xcb_set_window_rect(xcb_connection_t *conn, xcb_window_t window, Rect r) {
105 xcb_void_cookie_t cookie;
106 cookie = xcb_configure_window(conn, window,
107 XCB_CONFIG_WINDOW_X |
108 XCB_CONFIG_WINDOW_Y |
109 XCB_CONFIG_WINDOW_WIDTH |
110 XCB_CONFIG_WINDOW_HEIGHT,
111 &(r.x));
112 /* ignore events which are generated because we configured a window */
113 add_ignore_event(cookie.sequence, -1);
114 }
115
116 /*
117 * Returns the first supported _NET_WM_WINDOW_TYPE atom.
118 *
119 */
120 xcb_atom_t xcb_get_preferred_window_type(xcb_get_property_reply_t *reply) {
121 if (reply == NULL || xcb_get_property_value_length(reply) == 0)
122 return XCB_NONE;
123
124 xcb_atom_t *atoms;
125 if ((atoms = xcb_get_property_value(reply)) == NULL)
126 return XCB_NONE;
127
128 for (int i = 0; i < xcb_get_property_value_length(reply) / (reply->format / 8); i++) {
129 if (atoms[i] == A__NET_WM_WINDOW_TYPE_NORMAL ||
130 atoms[i] == A__NET_WM_WINDOW_TYPE_DIALOG ||
131 atoms[i] == A__NET_WM_WINDOW_TYPE_UTILITY ||
132 atoms[i] == A__NET_WM_WINDOW_TYPE_TOOLBAR ||
133 atoms[i] == A__NET_WM_WINDOW_TYPE_SPLASH ||
134 atoms[i] == A__NET_WM_WINDOW_TYPE_MENU ||
135 atoms[i] == A__NET_WM_WINDOW_TYPE_DROPDOWN_MENU ||
136 atoms[i] == A__NET_WM_WINDOW_TYPE_POPUP_MENU ||
137 atoms[i] == A__NET_WM_WINDOW_TYPE_TOOLTIP ||
138 atoms[i] == A__NET_WM_WINDOW_TYPE_NOTIFICATION) {
139 return atoms[i];
140 }
141 }
142
143 return XCB_NONE;
144 }
145
146 /*
147 * Returns true if the given reply contains the given atom.
148 *
149 */
150 bool xcb_reply_contains_atom(xcb_get_property_reply_t *prop, xcb_atom_t atom) {
151 if (prop == NULL || xcb_get_property_value_length(prop) == 0)
152 return false;
153
154 xcb_atom_t *atoms;
155 if ((atoms = xcb_get_property_value(prop)) == NULL)
156 return false;
157
158 for (int i = 0; i < xcb_get_property_value_length(prop) / (prop->format / 8); i++)
159 if (atoms[i] == atom)
160 return true;
161
162 return false;
163 }
164
165 /*
166 * Get depth of visual specified by visualid
167 *
168 */
169 uint16_t get_visual_depth(xcb_visualid_t visual_id) {
170 xcb_depth_iterator_t depth_iter;
171
172 depth_iter = xcb_screen_allowed_depths_iterator(root_screen);
173 for (; depth_iter.rem; xcb_depth_next(&depth_iter)) {
174 xcb_visualtype_iterator_t visual_iter;
175
176 visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
177 for (; visual_iter.rem; xcb_visualtype_next(&visual_iter)) {
178 if (visual_id == visual_iter.data->visual_id) {
179 return depth_iter.data->depth;
180 }
181 }
182 }
183 return 0;
184 }
185
186 /*
187 * Get visual type specified by visualid
188 *
189 */
190 xcb_visualtype_t *get_visualtype_by_id(xcb_visualid_t visual_id) {
191 xcb_depth_iterator_t depth_iter;
192
193 depth_iter = xcb_screen_allowed_depths_iterator(root_screen);
194 for (; depth_iter.rem; xcb_depth_next(&depth_iter)) {
195 xcb_visualtype_iterator_t visual_iter;
196
197 visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
198 for (; visual_iter.rem; xcb_visualtype_next(&visual_iter)) {
199 if (visual_id == visual_iter.data->visual_id) {
200 return visual_iter.data;
201 }
202 }
203 }
204 return 0;
205 }
206
207 /*
208 * Get visualid with specified depth
209 *
210 */
211 xcb_visualid_t get_visualid_by_depth(uint16_t depth) {
212 xcb_depth_iterator_t depth_iter;
213
214 depth_iter = xcb_screen_allowed_depths_iterator(root_screen);
215 for (; depth_iter.rem; xcb_depth_next(&depth_iter)) {
216 if (depth_iter.data->depth != depth)
217 continue;
218
219 xcb_visualtype_iterator_t visual_iter;
220
221 visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
222 if (!visual_iter.rem)
223 continue;
224 return visual_iter.data->visual_id;
225 }
226 return 0;
227 }
228
229 /*
230 * Add an atom to a list of atoms the given property defines.
231 * This is useful, for example, for manipulating _NET_WM_STATE.
232 *
233 */
234 void xcb_add_property_atom(xcb_connection_t *conn, xcb_window_t window, xcb_atom_t property, xcb_atom_t atom) {
235 xcb_change_property(conn, XCB_PROP_MODE_APPEND, window, property, XCB_ATOM_ATOM, 32, 1, (uint32_t[]){atom});
236 }
237
238 /*
239 * Remove an atom from a list of atoms the given property defines without
240 * removing any other potentially set atoms. This is useful, for example, for
241 * manipulating _NET_WM_STATE.
242 *
243 */
244 void xcb_remove_property_atom(xcb_connection_t *conn, xcb_window_t window, xcb_atom_t property, xcb_atom_t atom) {
245 xcb_grab_server(conn);
246
247 xcb_get_property_reply_t *reply =
248 xcb_get_property_reply(conn,
249 xcb_get_property(conn, false, window, property, XCB_GET_PROPERTY_TYPE_ANY, 0, 4096), NULL);
250 if (reply == NULL || xcb_get_property_value_length(reply) == 0)
251 goto release_grab;
252 xcb_atom_t *atoms = xcb_get_property_value(reply);
253 if (atoms == NULL) {
254 goto release_grab;
255 }
256
257 {
258 int num = 0;
259 const int current_size = xcb_get_property_value_length(reply) / (reply->format / 8);
260 xcb_atom_t values[current_size];
261 for (int i = 0; i < current_size; i++) {
262 if (atoms[i] != atom)
263 values[num++] = atoms[i];
264 }
265
266 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, window, property, XCB_ATOM_ATOM, 32, num, values);
267 }
268
269 release_grab:
270 FREE(reply);
271 xcb_ungrab_server(conn);
272 }
273
274 /*
275 * Grab the specified buttons on a window when managing it.
276 *
277 */
278 void xcb_grab_buttons(xcb_connection_t *conn, xcb_window_t window, int *buttons) {
279 int i = 0;
280 while (buttons[i] > 0) {
281 xcb_grab_button(conn, false, window, XCB_EVENT_MASK_BUTTON_PRESS, XCB_GRAB_MODE_SYNC,
282 XCB_GRAB_MODE_ASYNC, root, XCB_NONE, buttons[i], XCB_BUTTON_MASK_ANY);
283
284 i++;
285 }
286 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * xcursor.c: xcursor support for themed cursors.
7 *
8 */
9 #include <config.h>
10
11 #include <assert.h>
12 #include <err.h>
13 #include <xcb/xcb_cursor.h>
14
15 #include "i3.h"
16 #include "xcb.h"
17 #include "xcursor.h"
18
19 static xcb_cursor_context_t *ctx;
20 static xcb_cursor_t cursors[XCURSOR_CURSOR_MAX];
21
22 void xcursor_load_cursors(void) {
23 if (xcb_cursor_context_new(conn, root_screen, &ctx) < 0) {
24 errx(EXIT_FAILURE, "Cannot allocate xcursor context");
25 }
26 #define LOAD_CURSOR(constant, name) \
27 do { \
28 cursors[constant] = xcb_cursor_load_cursor(ctx, name); \
29 } while (0)
30 LOAD_CURSOR(XCURSOR_CURSOR_POINTER, "left_ptr");
31 LOAD_CURSOR(XCURSOR_CURSOR_RESIZE_HORIZONTAL, "sb_h_double_arrow");
32 LOAD_CURSOR(XCURSOR_CURSOR_RESIZE_VERTICAL, "sb_v_double_arrow");
33 LOAD_CURSOR(XCURSOR_CURSOR_WATCH, "watch");
34 LOAD_CURSOR(XCURSOR_CURSOR_MOVE, "fleur");
35 LOAD_CURSOR(XCURSOR_CURSOR_TOP_LEFT_CORNER, "top_left_corner");
36 LOAD_CURSOR(XCURSOR_CURSOR_TOP_RIGHT_CORNER, "top_right_corner");
37 LOAD_CURSOR(XCURSOR_CURSOR_BOTTOM_LEFT_CORNER, "bottom_left_corner");
38 LOAD_CURSOR(XCURSOR_CURSOR_BOTTOM_RIGHT_CORNER, "bottom_right_corner");
39 #undef LOAD_CURSOR
40 }
41
42 /*
43 * Sets the cursor of the root window to the 'pointer' cursor.
44 *
45 * This function is called when i3 is initialized, because with some login
46 * managers, the root window will not have a cursor otherwise.
47 *
48 */
49 void xcursor_set_root_cursor(int cursor_id) {
50 xcb_change_window_attributes(conn, root, XCB_CW_CURSOR,
51 (uint32_t[]){xcursor_get_cursor(cursor_id)});
52 }
53
54 xcb_cursor_t xcursor_get_cursor(enum xcursor_cursor_t c) {
55 assert(c < XCURSOR_CURSOR_MAX);
56 return cursors[c];
57 }
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * This is LEGACY code (we support RandR, which can do much more than
7 * Xinerama), but necessary for the poor users of the nVidia binary
8 * driver which does not support RandR in 2011 *sigh*.
9 *
10 */
11 #include "all.h"
12
13 #include <xcb/xinerama.h>
14
15 static int num_screens;
16
17 /*
18 * Looks in outputs for the Output whose start coordinates are x, y
19 *
20 */
21 static Output *get_screen_at(unsigned int x, unsigned int y) {
22 Output *output;
23 TAILQ_FOREACH (output, &outputs, outputs) {
24 if (output->rect.x == x && output->rect.y == y) {
25 return output;
26 }
27 }
28
29 return NULL;
30 }
31
32 /*
33 * Gets the Xinerama screens and converts them to virtual Outputs (only one screen for two
34 * Xinerama screen which are configured in clone mode) in the given screenlist
35 *
36 */
37 static void query_screens(xcb_connection_t *conn) {
38 xcb_xinerama_query_screens_reply_t *reply;
39 xcb_xinerama_screen_info_t *screen_info;
40
41 reply = xcb_xinerama_query_screens_reply(conn, xcb_xinerama_query_screens_unchecked(conn), NULL);
42 if (!reply) {
43 ELOG("Couldn't get Xinerama screens\n");
44 return;
45 }
46 screen_info = xcb_xinerama_query_screens_screen_info(reply);
47 int screens = xcb_xinerama_query_screens_screen_info_length(reply);
48
49 for (int screen = 0; screen < screens; screen++) {
50 Output *s = get_screen_at(screen_info[screen].x_org, screen_info[screen].y_org);
51 if (s != NULL) {
52 DLOG("Re-used old Xinerama screen %p\n", s);
53 /* This screen already exists. We use the littlest screen so that the user
54 can always see the complete workspace */
55 s->rect.width = min(s->rect.width, screen_info[screen].width);
56 s->rect.height = min(s->rect.height, screen_info[screen].height);
57 } else {
58 s = scalloc(1, sizeof(Output));
59 struct output_name *output_name = scalloc(1, sizeof(struct output_name));
60 sasprintf(&output_name->name, "xinerama-%d", num_screens);
61 SLIST_INIT(&s->names_head);
62 SLIST_INSERT_HEAD(&s->names_head, output_name, names);
63 DLOG("Created new Xinerama screen %s (%p)\n", output_primary_name(s), s);
64 s->active = true;
65 s->rect.x = screen_info[screen].x_org;
66 s->rect.y = screen_info[screen].y_org;
67 s->rect.width = screen_info[screen].width;
68 s->rect.height = screen_info[screen].height;
69 /* We always treat the screen at 0x0 as the primary screen */
70 if (s->rect.x == 0 && s->rect.y == 0)
71 TAILQ_INSERT_HEAD(&outputs, s, outputs);
72 else
73 TAILQ_INSERT_TAIL(&outputs, s, outputs);
74 output_init_con(s);
75 init_ws_for_output(s);
76 num_screens++;
77 }
78
79 DLOG("found Xinerama screen: %d x %d at %d x %d\n",
80 screen_info[screen].width, screen_info[screen].height,
81 screen_info[screen].x_org, screen_info[screen].y_org);
82 }
83
84 free(reply);
85
86 if (num_screens == 0) {
87 ELOG("No screens found. Please fix your setup. i3 will exit now.\n");
88 exit(EXIT_SUCCESS);
89 }
90 }
91
92 /*
93 * This creates the root_output (borrowed from randr.c) and uses it
94 * as the sole output for this session.
95 *
96 */
97 static void use_root_output(xcb_connection_t *conn) {
98 Output *s = create_root_output(conn);
99 s->active = true;
100 TAILQ_INSERT_TAIL(&outputs, s, outputs);
101 output_init_con(s);
102 init_ws_for_output(s);
103 }
104
105 /*
106 * We have just established a connection to the X server and need the initial Xinerama
107 * information to setup workspaces for each screen.
108 *
109 */
110 void xinerama_init(void) {
111 if (!xcb_get_extension_data(conn, &xcb_xinerama_id)->present) {
112 DLOG("Xinerama extension not found, using root output.\n");
113 use_root_output(conn);
114 } else {
115 xcb_xinerama_is_active_reply_t *reply;
116 reply = xcb_xinerama_is_active_reply(conn, xcb_xinerama_is_active(conn), NULL);
117
118 if (reply == NULL || !reply->state) {
119 DLOG("Xinerama is not active (in your X-Server), using root output.\n");
120 use_root_output(conn);
121 } else
122 query_screens(conn);
123
124 FREE(reply);
125 }
126 }
0 testsuite-*
1 latest
2 Makefile
3 Makefile.old
4 .last_run_timings.json
5 _Inline
6 inc
7 META.yml
8 i3-cfg-for-*
9 -
0 #!/usr/bin/env perl
1 # vim:ts=4:sw=4:expandtab
2 use strict; use warnings;
3 use ExtUtils::MakeMaker;
4
5 WriteMakefile(
6 NAME => 'i3-testsuite',
7 MIN_PERL_VERSION => '5.010000', # 5.10.0
8 PREREQ_PM => {
9 'AnyEvent' => 0,
10 'X11::XCB' => '0.12',
11 'Inline' => 0,
12 'Inline::C' => 0,
13 'ExtUtils::PkgConfig' => 0,
14 'Test::More' => '0.94',
15 'IPC::Run' => 0,
16 },
17 PM => {}, # do not install any files from this directory
18 clean => {
19 FILES => 'testsuite-* latest i3-cfg-for-*',
20 },
21 # This is a pure-Perl distribution:
22 linkext => {
23 LINKTYPE => '',
24 },
25 );
26
27 package MY;
28 sub test { } # do not run the tests while installing
29
30 # do not rename the Makefile
31 sub clean {
32 my $section = shift->SUPER::clean(@_);
33 $section =~ s/^\t\Q$_\E\n$//m for
34 '- $(MV) $(FIRST_MAKEFILE) $(MAKEFILE_OLD) $(DEV_NULL)';
35 $section;
36 }
0 #!/usr/bin/env perl
1 # vim:ts=4:sw=4:expandtab
2 # © 2010 Michael Stapelberg and contributors
3 package complete_run;
4 use strict;
5 use warnings;
6 use v5.10;
7 use utf8;
8 # the following are modules which ship with Perl (>= 5.10):
9 use Pod::Usage;
10 use File::Temp qw(tempfile tempdir);
11 use Getopt::Long;
12 use POSIX ();
13 use TAP::Harness;
14 use TAP::Parser;
15 use TAP::Parser::Aggregator;
16 use Time::HiRes qw(time);
17 use IO::Handle;
18
19 # these are shipped with the testsuite
20 use lib qw(@abs_top_builddir@/testcases/lib @abs_top_srcdir@/testcases/lib @abs_top_srcdir@/AnyEvent-I3/blib/lib);
21 use i3test::Util qw(slurp);
22 use StartXServer;
23 use StatusLine;
24 use TestWorker;
25 # the following modules are not shipped with Perl
26 use AnyEvent;
27 use AnyEvent::Util;
28 use AnyEvent::Handle;
29 use AnyEvent::I3 qw(:all);
30 use X11::XCB::Connection;
31 use JSON::XS; # AnyEvent::I3 depends on it, too.
32
33 binmode STDOUT, ':utf8';
34 binmode STDERR, ':utf8';
35
36 # Close superfluous file descriptors which were passed by running in a VIM
37 # subshell or situations like that.
38 AnyEvent::Util::close_all_fds_except(0, 1, 2);
39
40 our @CLEANUP;
41
42 # convenience wrapper to write to the log file
43 my $log;
44 sub Log { say $log "@_" }
45
46 my %timings;
47 my $help = 0;
48 # Number of tests to run in parallel. Important to know how many Xephyr
49 # instances we need to start (unless @displays are given). Defaults to
50 # num_cores * 2.
51 my $parallel = undef;
52 my @displays = ();
53 my %options = (
54 valgrind => 0,
55 strace => 0,
56 xtrace => 0,
57 coverage => 0,
58 restart => 0,
59 xvfb => 1,
60 );
61 my $keep_xserver_output = 0;
62
63 my $result = GetOptions(
64 "coverage-testing" => \$options{coverage},
65 "keep-xserver-output" => \$keep_xserver_output,
66 "valgrind" => \$options{valgrind},
67 "strace" => \$options{strace},
68 "xtrace" => \$options{xtrace},
69 "xvfb!" => \$options{xvfb},
70 "display=s" => \@displays,
71 "parallel=i" => \$parallel,
72 "help|?" => \$help,
73 );
74
75 pod2usage(-verbose => 2, -exitcode => 0) if $help;
76
77 # Check for missing executables
78 my @binaries = qw(
79 @abs_top_builddir@/i3
80 @abs_top_builddir@/i3bar/i3bar
81 @abs_top_builddir@/i3-config-wizard/i3-config-wizard
82 @abs_top_builddir@/i3-dump-log/i3-dump-log
83 @abs_top_builddir@/i3-input/i3-input
84 @abs_top_builddir@/i3-msg/i3-msg
85 @abs_top_builddir@/i3-nagbar/i3-nagbar
86 );
87
88 foreach my $binary (@binaries) {
89 die "$binary executable not found, did you run “make”?" unless -e $binary;
90 die "$binary is not an executable" unless -x $binary;
91 }
92
93 my @test_binaries = qw(
94 @abs_top_builddir@/test.commands_parser
95 @abs_top_builddir@/test.config_parser
96 @abs_top_builddir@/test.inject_randr15
97 );
98
99 foreach my $binary (@test_binaries) {
100 die "$binary executable not found, did you run “make check”?" unless -e $binary;
101 die "$binary is not an executable" unless -x $binary;
102 }
103
104 $ENV{PATH} = join(':',
105 '@abs_top_builddir@/i3-nagbar',
106 '@abs_top_builddir@/i3-msg',
107 '@abs_top_builddir@/i3-input',
108 '@abs_top_builddir@/i3-dump-log',
109 '@abs_top_builddir@/i3-config-wizard',
110 '@abs_top_builddir@/i3bar',
111 '@abs_top_builddir@',
112 '@abs_top_srcdir@',
113 $ENV{PATH});
114
115 qx(Xephyr -help 2>&1);
116 die "Xephyr was not found in your path. Please install Xephyr (xserver-xephyr on Debian)." if $?;
117
118 qx(xvfb-run --help 2>&1);
119 if ($? && $options{xvfb}) {
120 say "xvfb-run not found, not running tests under xvfb. Install the xvfb package to speed up tests";
121 $options{xvfb} = 0;
122 }
123
124 if ($options{xvfb}) {
125 for (my $n = 99; $n < 120; $n++) {
126 my $path = File::Temp::tmpnam($ENV{TMPDIR} // "/tmp", "i3-testsXXXXXX");
127 if (!defined(POSIX::mkfifo($path, 0600))) {
128 die "mkfifo: $!";
129 }
130 my $pid = fork // die "fork: $!";
131 if ($pid == 0) {
132 # Child
133
134 # Xvfb checks whether the parent ignores USR1 and sends USR1 to the
135 # parent when ready, so that the wait call will be interrupted. We
136 # can’t implement this in Perl, as Perl’s waitpid transparently
137 # handles -EINTR.
138 exec('/bin/sh', '-c', qq|trap "exit" INT; trap : USR1; (trap '' USR1; exec Xvfb :$n -screen 0 640x480x8 -nolisten tcp) & PID=\$!; wait; if ! kill -0 \$PID 2>/dev/null; then echo 1:\$PID > $path; else echo 0:\$PID > $path; wait \$PID; fi|);
139 die "exec: $!";
140 }
141 chomp(my $kill = slurp($path));
142 unlink($path);
143 my ($code, $xvfbpid) = ($kill =~ m,^([0-1]):(.*)$,);
144 next unless $code eq '0';
145
146 $ENV{DISPLAY} = ":$n";
147 say "Running tests under Xvfb display $ENV{DISPLAY}";
148
149 push(@CLEANUP, sub {
150 kill(15, $xvfbpid);
151 });
152 last;
153 }
154 }
155
156 @displays = split(/,/, join(',', @displays));
157 @displays = map { s/ //g; $_ } @displays;
158
159 # 2: get a list of all testcases
160 my @testfiles = @ARGV;
161
162 # if no files were passed on command line, run all tests from t/
163 if (scalar @testfiles == 0) {
164 @testfiles = <@abs_top_srcdir@/testcases/t/*.t> if @testfiles == 0;
165 } else {
166 @testfiles = map {
167 # Fully qualify each specified file if necessary
168 if (! -e $_) {
169 $_ = "@abs_top_srcdir@/testcases/$_";
170 }
171 $_
172 } @testfiles;
173 }
174
175 my $numtests = scalar @testfiles;
176
177 # No displays specified, let’s start some Xephyr instances.
178 if (@displays == 0) {
179 @displays = start_xserver($parallel, $numtests, $keep_xserver_output);
180 }
181
182 # 1: create an output directory for this test-run
183 my $outdir = "testsuite-";
184 $outdir .= POSIX::strftime("%Y-%m-%d-%H-%M-%S-", localtime());
185 $outdir .= `git describe --tags`;
186 chomp($outdir);
187 mkdir($outdir) or die "Could not create $outdir";
188 unlink("latest") if -l "latest";
189 symlink("$outdir", "latest") or die "Could not symlink latest to $outdir";
190
191
192 # connect to all displays for two reasons:
193 # 1: check if the display actually works
194 # 2: keep the connection open so that i3 is not the only client. this prevents
195 # the X server from exiting
196 my @single_worker;
197 for my $display (@displays) {
198 my $screen;
199 my $x = X11::XCB::Connection->new(display => $display);
200 if ($x->has_error) {
201 die "Could not connect to display $display\n";
202 } else {
203 # start a TestWorker for each display
204 push @single_worker, worker($display, $x, $outdir, \%options);
205 }
206 }
207
208 # Read previous timing information, if available. We will be able to roughly
209 # predict the test duration and schedule a good order for the tests.
210 my $timingsjson = slurp('.last_run_timings.json') if -e '.last_run_timings.json';
211 %timings = %{decode_json($timingsjson)} if length($timingsjson) > 0;
212
213 # Re-order the files so that those which took the longest time in the previous
214 # run will be started at the beginning to not delay the whole run longer than
215 # necessary.
216 @testfiles = map { $_->[0] }
217 sort { $b->[1] <=> $a->[1] }
218 map { [$_, $timings{$_} // 999] } @testfiles;
219
220 # Run 000-load-deps.t first to bail out early when dependencies are missing.
221 my ($loadtest) = grep { $_ =~ m,t/000-load-deps.t$, } @testfiles;
222 if (defined($loadtest)) {
223 @testfiles = ($loadtest, grep { $_ ne $loadtest } @testfiles);
224 }
225
226 # Run 533-randr15.t last because it destructively modifies the RandR
227 # configuration of the X session, interfering with any test started afterwards.
228 my ($randrtest) = grep { $_ =~ m,t/533-randr15.t$, } @testfiles;
229 if (defined($randrtest)) {
230 @testfiles = ((grep { $_ ne $randrtest } @testfiles), $randrtest);
231 }
232
233 printf("\nRough time estimate for this run: %.2f seconds\n\n", $timings{GLOBAL})
234 if exists($timings{GLOBAL});
235
236 # Forget the old timings, we don’t necessarily run the same set of tests as
237 # before. Otherwise we would end up with left-overs.
238 %timings = (GLOBAL => time());
239
240 my $logfile = "$outdir/complete-run.log";
241 open $log, '>', $logfile or die "Could not create '$logfile': $!";
242 $log->autoflush(1);
243 say "Writing logfile to '$logfile'...";
244
245 # 3: run all tests
246 my @done;
247 my $num = @testfiles;
248 my $harness = TAP::Harness->new({ });
249
250 my $aggregator = TAP::Parser::Aggregator->new();
251 $aggregator->start();
252
253 status_init(displays => \@displays, tests => $num);
254
255 my $single_cv = AE::cv;
256
257 # We start tests concurrently: For each display, one test gets started. Every
258 # test starts another test after completing.
259 for (@single_worker) {
260 $single_cv->begin;
261 take_job($_, $single_cv, \@testfiles);
262 }
263
264 $single_cv->recv;
265
266 $aggregator->stop();
267
268 # print empty lines to separate failed tests from statuslines
269 print "\n\n";
270
271 for (@done) {
272 my ($test, $output) = @$_;
273 say "no output for $test" unless $output;
274 Log "output for $test:";
275 Log $output;
276 # print error messages of failed tests
277 say for $output =~ /^not ok.+\n+((?:^#.+\n)+)/mg
278 }
279
280 # 4: print summary
281 $harness->summary($aggregator);
282
283 close $log;
284
285 # 5: Save the timings for better scheduling/prediction next run.
286 $timings{GLOBAL} = time() - $timings{GLOBAL};
287 open(my $fh, '>', '.last_run_timings.json');
288 print $fh encode_json(\%timings);
289 close($fh);
290
291 # 6: Print the slowest test files.
292 my @slowest = map { $_->[0] }
293 sort { $b->[1] <=> $a->[1] }
294 map { [$_, $timings{$_}] }
295 grep { !/^GLOBAL$/ } keys %timings;
296 say '';
297 say 'The slowest tests are:';
298 printf("\t%s with %.2f seconds\n", $_, $timings{$_})
299 for @slowest[0..($#slowest > 4 ? 4 : $#slowest)];
300
301 # When we are running precisely one test, print the output. Makes developing
302 # with a single testcase easier.
303 if ($numtests == 1) {
304 say '';
305 say 'Test output:';
306 say slurp($logfile);
307 }
308
309 END { cleanup() }
310
311 # Report logfiles that match “(Leak|Address)Sanitizer:”.
312 my @logs_with_leaks;
313 for my $log (<$outdir/i3-log-for-*>) {
314 if (slurp($log) =~ /(Leak|Address)Sanitizer:/) {
315 push @logs_with_leaks, $log;
316 }
317 }
318 if (scalar @logs_with_leaks > 0) {
319 say "\nThe following test logfiles contain AddressSanitizer or LeakSanitizer reports:";
320 for my $log (sort @logs_with_leaks) {
321 say "\t$log";
322 }
323 }
324
325 exit ($aggregator->failed > 0);
326
327 #
328 # Takes a test from the beginning of @testfiles and runs it.
329 #
330 # The TAP::Parser (which reads the test output) will get called as soon as
331 # there is some activity on the stdout file descriptor of the test process
332 # (using an AnyEvent->io watcher).
333 #
334 # When a test completes and @done contains $num entries, the $cv condvar gets
335 # triggered to finish testing.
336 #
337 sub take_job {
338 my ($worker, $cv, $tests) = @_;
339
340 my $test = shift @$tests
341 or return $cv->end;
342
343 my $display = $worker->{display};
344
345 Log status($display, "$test: starting");
346 $timings{$test} = time();
347 worker_next($worker, $test);
348
349 # create a TAP::Parser with an in-memory fh
350 my $output;
351 my $parser = TAP::Parser->new({
352 source => do { open(my $fh, '<', \$output); $fh },
353 });
354
355 my $ipc = $worker->{ipc};
356
357 my $w;
358 $w = AnyEvent->io(
359 fh => $ipc,
360 poll => 'r',
361 cb => sub {
362 state $tests_completed = 0;
363 state $partial = '';
364
365 sysread($ipc, my $buf, 4096) or die "sysread: $!";
366
367 if ($partial) {
368 $buf = $partial . $buf;
369 $partial = '';
370 }
371
372 # make sure we feed TAP::Parser complete lines so it doesn't blow up
373 if (substr($buf, -1, 1) ne "\n") {
374 my $nl = rindex($buf, "\n");
375 if ($nl == -1) {
376 $partial = $buf;
377 return;
378 }
379
380 # strip partial from buffer
381 $partial = substr($buf, $nl + 1, '');
382 }
383
384 # count lines before stripping eof-marker otherwise we might
385 # end up with for (1 .. 0) { } which would effectivly skip the loop
386 my $lines = $buf =~ tr/\n//;
387 my $t_eof = $buf =~ s/^$TestWorker::EOF$//m;
388
389 $output .= $buf;
390
391 for (1 .. $lines) {
392 my $result = $parser->next;
393 next unless defined($result);
394 if ($result->is_test) {
395 $tests_completed++;
396 status($display, "$test: [$tests_completed/??] ");
397 } elsif ($result->is_bailout) {
398 Log status($display, "$test: BAILOUT");
399 status_completed(scalar @done);
400 say "";
401 say "test $test bailed out: " . $result->explanation;
402 exit 1;
403 }
404 }
405
406 return unless $t_eof;
407
408 Log status($display, "$test: finished");
409 $timings{$test} = time() - $timings{$test};
410 status_completed(scalar @done);
411
412 $aggregator->add($test, $parser);
413 push @done, [ $test, $output ];
414
415 undef $w;
416 take_job($worker, $cv, $tests);
417 }
418 );
419 }
420
421 sub cleanup {
422 my $exitcode = $?;
423 $_->() for @CLEANUP;
424 exit $exitcode;
425 }
426
427 # must be in a begin block because we C<exit 0> above
428 BEGIN {
429 $SIG{$_} = sub {
430 require Carp; Carp::cluck("Caught SIG$_[0]\n");
431 cleanup();
432 } for qw(INT TERM QUIT KILL PIPE)
433 }
434
435 __END__
436
437 =head1 NAME
438
439 complete-run.pl - Run the i3 testsuite
440
441 =head1 SYNOPSIS
442
443 complete-run.pl [files...]
444
445 =head1 EXAMPLE
446
447 To run the whole testsuite on a reasonable number of Xephyr instances (your
448 running X11 will not be touched), run:
449 ./complete-run.pl
450
451 To run only a specific test (useful when developing a new feature), run:
452 ./complete-run t/100-fullscreen.t
453
454 =head1 OPTIONS
455
456 =over 8
457
458 =item B<--display>
459
460 Specifies which X11 display should be used. Can be specified multiple times and
461 will parallelize the tests:
462
463 # Run tests on the second X server
464 ./complete-run.pl -d :1
465
466 # Run four tests in parallel on some Xephyr servers
467 ./complete-run.pl -d :1,:2,:3,:4
468
469 Note that it is not necessary to specify this anymore. If omitted,
470 complete-run.pl will start (num_cores * 2) Xephyr instances.
471
472 =item B<--valgrind>
473
474 Runs i3 under valgrind to find memory problems. The output will be available in
475 C<latest/valgrind-for-$test.log>.
476
477 =item B<--strace>
478
479 Runs i3 under strace to trace system calls. The output will be available in
480 C<latest/strace-for-$test.log>.
481
482 =item B<--xtrace>
483
484 Runs i3 under xtrace to trace X11 requests/replies. The output will be
485 available in C<latest/xtrace-for-$test.log>.
486
487 =item B<--xvfb>
488
489 =item B<--no-xvfb>
490
491 Enable or disable running tests under Xvfb. Enabled by default.
492
493 =item B<--coverage-testing>
494
495 Generates a test coverage report at C<latest/i3-coverage>. Exits i3 cleanly
496 during tests (instead of kill -9) to make coverage testing work properly.
497
498 =item B<--parallel>
499
500 Number of Xephyr instances to start (if you don't want to start num_cores * 2
501 instances for some reason).
502
503 # Run all tests on a single Xephyr instance
504 ./complete-run.pl -p 1
505
506 =back
0 # ISO 10646 = Unicode
1 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
2
3 # Use Mouse+Mod1 to drag floating windows to their wanted position
4 floating_modifier Mod1
5
6 # Open empty container
7 bindsym Mod1+Shift+Return open
8
9 # Start terminal (Mod1+Enter)
10 bindsym Mod1+Return exec /usr/bin/urxvt
11
12 # Start dmenu (Mod1+p)
13 bindsym Mod1+p exec /usr/bin/dmenu_run
14
15 # Horizontal orientation
16 bindsym Mod1+h split h
17
18 # Vertical orientation
19 bindsym Mod1+v split v
20
21 # Fullscreen (Mod1+f)
22 bindsym Mod1+f fullscreen toggle
23
24 # Stacking (Mod1+s)
25 bindsym Mod1+s layout stacking
26
27 # Tabbed (Mod1+w)
28 bindsym Mod1+w layout tabbed
29
30 # Default (Mod1+l)
31 bindsym Mod1+l layout default
32
33 # toggle tiling / floating
34 bindsym Mod1+Shift+space mode toggle
35
36 bindsym Mod1+u level up
37 #bindsym Mod1+d level down
38
39 # Kill current client (Mod1+c)
40 bindsym Mod1+c kill
41
42 # Restore saved JSON layout
43 bindsym Mod1+y restore /home/michael/i3/layout.json
44
45 # Restart i3
46 bindsym Mod1+Shift+c restart
47 # Reload i3
48 bindsym Mod1+Shift+j reload
49 # Exit i3
50 bindsym Mod1+Shift+l exit
51
52 # Focus (Mod1+n/r/t/d)
53 bindsym Mod1+n prev h
54 bindsym Mod1+r next v
55 bindsym Mod1+t prev v
56 bindsym Mod1+d next h
57
58 # alternatively, you can use the cursor keys:
59 bindsym Mod1+Left prev h
60 bindsym Mod1+Right next h
61 bindsym Mod1+Down next v
62 bindsym Mod1+Up prev v
63
64 # Move
65 bindsym Mod1+Shift+n move left
66 bindsym Mod1+Shift+r move down
67 bindsym Mod1+Shift+t move up
68 bindsym Mod1+Shift+d move right
69
70 # alternatively, you can use the cursor keys:
71 bindsym Mod1+Shift+Left move left
72 bindsym Mod1+Shift+Right move right
73 bindsym Mod1+Shift+Down move down
74 bindsym Mod1+Shift+Up move up
75
76 # Workspaces (Mod1+1/2/…)
77 bindsym Mod1+1 workspace 1
78 bindsym Mod1+2 workspace 2
79 bindsym Mod1+3 workspace 3
80 bindsym Mod1+4 workspace 4
81 bindsym Mod1+5 workspace 5
82 bindsym Mod1+6 workspace 6
83 bindsym Mod1+7 workspace 7
84 bindsym Mod1+8 workspace 8
85 bindsym Mod1+9 workspace 9
86 bindsym Mod1+0 workspace 10
87
88 # Move to Workspaces
89 bindsym Mod1+Shift+1 move workspace 1
90 bindsym Mod1+Shift+2 move workspace 2
91 bindsym Mod1+Shift+3 move workspace 3
92 bindsym Mod1+Shift+4 move workspace 4
93 bindsym Mod1+Shift+5 move workspace 5
94 bindsym Mod1+Shift+6 move workspace 6
95 bindsym Mod1+Shift+7 move workspace 7
96 bindsym Mod1+Shift+8 move workspace 8
97 bindsym Mod1+Shift+9 move workspace 9
98 bindsym Mod1+Shift+0 move workspace 10
0 /*
1 * vim:ts=4:sw=4:expandtab
2 *
3 * i3 - an improved dynamic tiling window manager
4 * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
5 *
6 * inject_randr1.5.c: An X11 proxy which interprets RandR 1.5 GetMonitors
7 * requests and overwrites their reply with a custom reply.
8 *
9 * This tool can be refactored as necessary in order to perform the same
10 * purpose for other request types. The RandR 1.5 specific portions of the code
11 * have been marked as such to make such a refactoring easier.
12 *
13 */
14 #include "all.h"
15
16 #include <ev.h>
17 #include <fcntl.h>
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <sys/un.h>
21 #include <sys/time.h>
22 #include <sys/resource.h>
23 #include <sys/mman.h>
24 #include <sys/stat.h>
25 #include <sys/wait.h>
26 #include <libgen.h>
27
28 static void uds_connection_cb(EV_P_ ev_io *w, int revents);
29 static void read_client_setup_request_cb(EV_P_ ev_io *w, int revents);
30 static void read_server_setup_reply_cb(EV_P_ ev_io *w, int revents);
31 static void read_client_x11_packet_cb(EV_P_ ev_io *w, int revents);
32 static void read_server_x11_packet_cb(EV_P_ ev_io *w, int revents);
33
34 static char *sun_path = NULL;
35
36 static void cleanup_socket(void) {
37 if (sun_path != NULL) {
38 unlink(sun_path);
39 free(sun_path);
40 sun_path = NULL;
41 }
42 }
43
44 struct injected_reply {
45 void *buf;
46 off_t len;
47 };
48
49 /* BEGIN RandR 1.5 specific */
50 static struct injected_reply getmonitors_reply = {NULL, 0};
51 static struct injected_reply getoutputinfo_reply = {NULL, 0};
52 /* END RandR 1.5 specific */
53
54 #define XCB_PAD(i) (-(i)&3)
55
56 struct connstate {
57 /* clientw is a libev watcher for the connection which we accept()ed. */
58 ev_io *clientw;
59
60 /* serverw is a libev watcher for the connection to X11 which we initiated
61 * on behalf of the client. */
62 ev_io *serverw;
63
64 /* sequence is the client-side sequence number counter. In X11’s wire
65 * encoding, sequence counters are not included in requests, only in
66 * replies. */
67 int sequence;
68
69 /* BEGIN RandR 1.5 specific */
70 /* sequence number of the most recent GetExtension request for RANDR */
71 int getext_randr;
72 /* sequence number of the most recent RRGetMonitors request */
73 int getmonitors;
74 /* sequence number of the most recent RRGetOutputInfo request */
75 int getoutputinfo;
76
77 int randr_major_opcode;
78 /* END RandR 1.5 specific */
79 };
80
81 /*
82 * Returns 0 on EOF
83 * Returns -1 on error (with errno from read() untouched)
84 *
85 */
86 static size_t readall_into(void *buffer, const size_t len, int fd) {
87 size_t read_bytes = 0;
88 while (read_bytes < len) {
89 ssize_t n = read(fd, buffer + read_bytes, len - read_bytes);
90 if (n <= 0) {
91 return n;
92 }
93 read_bytes += (size_t)n;
94 }
95 return read_bytes;
96 }
97
98 /*
99 * Exits the program with an error if the read failed.
100 *
101 */
102 static void must_read(int n) {
103 if (n == -1) {
104 err(EXIT_FAILURE, "read()");
105 }
106 if (n == 0) {
107 errx(EXIT_FAILURE, "EOF");
108 }
109 }
110
111 /*
112 * Exits the program with an error if the write failed.
113 *
114 */
115 static void must_write(int n) {
116 if (n == -1) {
117 err(EXIT_FAILURE, "write()");
118 }
119 }
120
121 static void uds_connection_cb(EV_P_ ev_io *w, int revents) {
122 struct sockaddr_un addr;
123 socklen_t addrlen = sizeof(addr);
124 const int clientfd = accept(w->fd, (struct sockaddr *)&addr, &addrlen);
125 if (clientfd == -1) {
126 if (errno == EINTR) {
127 return;
128 }
129 err(EXIT_FAILURE, "accept()");
130 }
131
132 struct connstate *connstate = scalloc(1, sizeof(struct connstate));
133
134 ev_io *clientw = scalloc(1, sizeof(ev_io));
135 connstate->clientw = clientw;
136 clientw->data = connstate;
137 ev_io_init(clientw, read_client_setup_request_cb, clientfd, EV_READ);
138 ev_io_start(EV_A_ clientw);
139 }
140
141 // https://www.x.org/releases/current/doc/xproto/x11protocol.html#Encoding::Connection_Setup
142 static void read_client_setup_request_cb(EV_P_ ev_io *w, int revents) {
143 ev_io_stop(EV_A_ w);
144 struct connstate *connstate = (struct connstate *)w->data;
145
146 /* Read X11 setup request in its entirety. */
147 xcb_setup_request_t setup_request;
148 must_read(readall_into(&setup_request, sizeof(setup_request), w->fd));
149
150 /* Establish a connection to X11. */
151 int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
152 if (fd == -1) {
153 err(EXIT_FAILURE, "socket()");
154 }
155
156 char *host;
157 int displayp;
158 if (xcb_parse_display(getenv("DISPLAY"), &host, &displayp, NULL) == 0) {
159 errx(EXIT_FAILURE, "Could not parse DISPLAY=%s", getenv("DISPLAY"));
160 }
161 free(host);
162
163 struct sockaddr_un addr;
164 memset(&addr, 0, sizeof(addr));
165 addr.sun_family = AF_LOCAL;
166 snprintf(addr.sun_path, sizeof(addr.sun_path), "/tmp/.X11-unix/X%d", displayp);
167 if (connect(fd, (const struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) {
168 err(EXIT_FAILURE, "connect(%s)", addr.sun_path);
169 }
170
171 /* Relay setup request. */
172 must_write(writeall(fd, &setup_request, sizeof(setup_request)));
173
174 if (setup_request.authorization_protocol_name_len > 0 ||
175 setup_request.authorization_protocol_data_len > 0) {
176 const size_t authlen = setup_request.authorization_protocol_name_len +
177 XCB_PAD(setup_request.authorization_protocol_name_len) +
178 setup_request.authorization_protocol_data_len +
179 XCB_PAD(setup_request.authorization_protocol_data_len);
180 void *buf = smalloc(authlen);
181 must_read(readall_into(buf, authlen, w->fd));
182 must_write(writeall(fd, buf, authlen));
183 free(buf);
184 }
185
186 /* Wait for a response from the X11 server. */
187 ev_io *serverw = scalloc(1, sizeof(ev_io));
188 connstate->serverw = serverw;
189 serverw->data = connstate;
190 ev_io_init(serverw, read_server_setup_reply_cb, fd, EV_READ);
191 ev_io_start(EV_A_ serverw);
192 }
193
194 static void read_server_setup_reply_cb(EV_P_ ev_io *w, int revents) {
195 struct connstate *connstate = (struct connstate *)w->data;
196 xcb_setup_failed_t setup_failed;
197 must_read(readall_into(&setup_failed, sizeof(setup_failed), w->fd));
198
199 switch (setup_failed.status) {
200 case 0:
201 errx(EXIT_FAILURE, "error authenticating at the X11 server");
202
203 case 2:
204 errx(EXIT_FAILURE, "two-factor auth not implemented");
205
206 case 1:
207 must_write(writeall(connstate->clientw->fd, &setup_failed, sizeof(xcb_setup_failed_t)));
208 const size_t len = (setup_failed.length * 4);
209 void *buf = smalloc(len);
210 must_read(readall_into(buf, len, w->fd));
211 must_write(writeall(connstate->clientw->fd, buf, len));
212 free(buf);
213
214 ev_set_cb(connstate->clientw, read_client_x11_packet_cb);
215 ev_set_cb(connstate->serverw, read_server_x11_packet_cb);
216 ev_io_start(EV_A_ connstate->clientw);
217 break;
218
219 default:
220 errx(EXIT_FAILURE, "X11 protocol error: expected setup_failed.status in [0..2], got %d", setup_failed.status);
221 }
222 }
223
224 // https://www.x.org/releases/current/doc/xproto/x11protocol.html#request_format
225 typedef struct {
226 uint8_t opcode;
227 uint8_t pad0;
228 uint16_t length;
229 } generic_x11_request_t;
230
231 // https://www.x.org/releases/current/doc/xproto/x11protocol.html#reply_format
232 typedef struct {
233 uint8_t code; /* if 1, this is a reply. if 0, this is an error. else, an event */
234 uint8_t pad0;
235 uint16_t sequence;
236 uint32_t length;
237 } generic_x11_reply_t;
238
239 static void read_client_x11_packet_cb(EV_P_ ev_io *w, int revents) {
240 struct connstate *connstate = (struct connstate *)w->data;
241
242 void *request = smalloc(sizeof(generic_x11_request_t));
243 must_read(readall_into(request, sizeof(generic_x11_request_t), connstate->clientw->fd));
244 const size_t len = (((generic_x11_request_t *)request)->length * 4);
245 if (len > sizeof(generic_x11_request_t)) {
246 request = srealloc(request, len);
247 must_read(readall_into(request + sizeof(generic_x11_request_t),
248 len - sizeof(generic_x11_request_t),
249 connstate->clientw->fd));
250 }
251
252 // XXX: sequence counter wrapping is not implemented, but should not be
253 // necessary given that this tool is scoped for test cases.
254 connstate->sequence++;
255
256 /* BEGIN RandR 1.5 specific */
257 const uint8_t opcode = ((generic_x11_request_t *)request)->opcode;
258 if (opcode == XCB_QUERY_EXTENSION) {
259 xcb_query_extension_request_t *req = request;
260 const char *name = request + sizeof(xcb_query_extension_request_t);
261 if (req->name_len == strlen("RANDR") &&
262 strncmp(name, "RANDR", strlen("RANDR")) == 0) {
263 connstate->getext_randr = connstate->sequence;
264 }
265 } else if (opcode == connstate->randr_major_opcode) {
266 const uint8_t randr_opcode = ((generic_x11_request_t *)request)->pad0;
267 if (randr_opcode == XCB_RANDR_GET_MONITORS) {
268 connstate->getmonitors = connstate->sequence;
269 } else if (randr_opcode == XCB_RANDR_GET_OUTPUT_INFO) {
270 connstate->getoutputinfo = connstate->sequence;
271 }
272 }
273 /* END RandR 1.5 specific */
274
275 must_write(writeall(connstate->serverw->fd, request, len));
276 free(request);
277 }
278
279 static bool handle_sequence(struct connstate *connstate, uint16_t sequence) {
280 /* BEGIN RandR 1.5 specific */
281 if (sequence == connstate->getmonitors) {
282 printf("RRGetMonitors reply!\n");
283 if (getmonitors_reply.buf != NULL) {
284 printf("injecting reply\n");
285 ((generic_x11_reply_t *)getmonitors_reply.buf)->sequence = sequence;
286 must_write(writeall(connstate->clientw->fd, getmonitors_reply.buf, getmonitors_reply.len));
287 return true;
288 }
289 }
290
291 if (sequence == connstate->getoutputinfo) {
292 printf("RRGetOutputInfo reply!\n");
293 if (getoutputinfo_reply.buf != NULL) {
294 printf("injecting reply\n");
295 ((generic_x11_reply_t *)getoutputinfo_reply.buf)->sequence = sequence;
296 must_write(writeall(connstate->clientw->fd, getoutputinfo_reply.buf, getoutputinfo_reply.len));
297 return true;
298 }
299 }
300 /* END RandR 1.5 specific */
301
302 return false;
303 }
304
305 static void read_server_x11_packet_cb(EV_P_ ev_io *w, int revents) {
306 struct connstate *connstate = (struct connstate *)w->data;
307 // all packets from the server are at least 32 bytes in length
308 size_t len = 32;
309 void *packet = smalloc(len);
310 must_read(readall_into(packet, len, connstate->serverw->fd));
311 switch (((generic_x11_reply_t *)packet)->code) {
312 case 0: { // error
313 const uint16_t sequence = ((xcb_request_error_t *)packet)->sequence;
314 if (handle_sequence(connstate, sequence)) {
315 free(packet);
316 return;
317 }
318 break;
319 }
320 case 1: // reply
321 len += ((generic_x11_reply_t *)packet)->length * 4;
322 if (len > 32) {
323 packet = srealloc(packet, len);
324 must_read(readall_into(packet + 32, len - 32, connstate->serverw->fd));
325 }
326
327 /* BEGIN RandR 1.5 specific */
328 const uint16_t sequence = ((generic_x11_reply_t *)packet)->sequence;
329
330 if (sequence == connstate->getext_randr) {
331 xcb_query_extension_reply_t *reply = packet;
332 connstate->randr_major_opcode = reply->major_opcode;
333 }
334 /* END RandR 1.5 specific */
335
336 if (handle_sequence(connstate, sequence)) {
337 free(packet);
338 return;
339 }
340
341 break;
342
343 default: // event
344 break;
345 }
346 must_write(writeall(connstate->clientw->fd, packet, len));
347 free(packet);
348 }
349
350 static void child_cb(EV_P_ ev_child *w, int revents) {
351 ev_child_stop(EV_A_ w);
352 if (WIFEXITED(w->rstatus)) {
353 exit(WEXITSTATUS(w->rstatus));
354 } else {
355 exit(WTERMSIG(w->rstatus) + 128);
356 }
357 }
358
359 static void must_read_reply(const char *filename, struct injected_reply *reply) {
360 FILE *f;
361 if ((f = fopen(filename, "r")) == NULL) {
362 err(EXIT_FAILURE, "fopen(%s)", filename);
363 }
364 struct stat stbuf;
365 if (fstat(fileno(f), &stbuf) != 0) {
366 err(EXIT_FAILURE, "fstat(%s)", filename);
367 }
368 reply->len = stbuf.st_size;
369 reply->buf = smalloc(stbuf.st_size);
370 int n = fread(reply->buf, 1, stbuf.st_size, f);
371 if (n != stbuf.st_size) {
372 err(EXIT_FAILURE, "fread(%s)", filename);
373 }
374 fclose(f);
375 }
376
377 int main(int argc, char *argv[]) {
378 static struct option long_options[] = {
379 {"getmonitors_reply", required_argument, 0, 0},
380 {"getoutputinfo_reply", required_argument, 0, 0},
381 {0, 0, 0, 0},
382 };
383 char *options_string = "";
384 int opt;
385 int option_index = 0;
386
387 while ((opt = getopt_long(argc, argv, options_string, long_options, &option_index)) != -1) {
388 switch (opt) {
389 case 0: {
390 const char *option_name = long_options[option_index].name;
391 if (strcmp(option_name, "getmonitors_reply") == 0) {
392 must_read_reply(optarg, &getmonitors_reply);
393 } else if (strcmp(option_name, "getoutputinfo_reply") == 0) {
394 must_read_reply(optarg, &getoutputinfo_reply);
395 }
396 break;
397 }
398 default:
399 exit(EXIT_FAILURE);
400 }
401 }
402
403 if (optind >= argc) {
404 errx(EXIT_FAILURE, "syntax: %s [options] <command>", argv[0]);
405 }
406
407 int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
408 if (fd == -1) {
409 err(EXIT_FAILURE, "socket(AF_UNIX)");
410 }
411
412 if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
413 warn("Could not set FD_CLOEXEC");
414 }
415
416 struct sockaddr_un addr;
417 memset(&addr, 0, sizeof(struct sockaddr_un));
418 addr.sun_family = AF_UNIX;
419 int i;
420 bool bound = false;
421 for (i = 0; i < 100; i++) {
422 /* XXX: The path to X11 sockets differs on some platforms (e.g. Trusted
423 * Solaris, HPUX), but since libxcb doesn’t provide a function to
424 * generate the path, we’ll just have to hard-code it for now. */
425 snprintf(addr.sun_path, sizeof(addr.sun_path), "/tmp/.X11-unix/X%d", i);
426
427 if (bind(fd, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) == -1) {
428 warn("bind(%s)", addr.sun_path);
429 } else {
430 bound = true;
431 /* Let the user know bind() was successful, so that they know the
432 * error messages can be disregarded. */
433 fprintf(stderr, "Successfuly bound to %s\n", addr.sun_path);
434 sun_path = sstrdup(addr.sun_path);
435 break;
436 }
437 }
438
439 if (!bound) {
440 err(EXIT_FAILURE, "bind()");
441 }
442
443 atexit(cleanup_socket);
444
445 /* This program will be started for each testcase which requires it, so we
446 * expect precisely one connection. */
447 if (listen(fd, 1) == -1) {
448 err(EXIT_FAILURE, "listen()");
449 }
450
451 pid_t child = fork();
452 if (child == -1) {
453 err(EXIT_FAILURE, "fork()");
454 }
455 if (child == 0) {
456 char *display;
457 sasprintf(&display, ":%d", i);
458 setenv("DISPLAY", display, 1);
459 free(display);
460
461 char **child_args = argv + optind;
462 execvp(child_args[0], child_args);
463 err(EXIT_FAILURE, "exec()");
464 }
465
466 struct ev_loop *loop = ev_default_loop(0);
467
468 ev_child cw;
469 ev_child_init(&cw, child_cb, child, 0);
470 ev_child_start(loop, &cw);
471
472 ev_io watcher;
473 ev_io_init(&watcher, uds_connection_cb, fd, EV_READ);
474 ev_io_start(loop, &watcher);
475
476 ev_run(loop, 0);
477 }
0 package SocketActivation;
1 # vim:ts=4:sw=4:expandtab
2
3 use strict;
4 use warnings;
5 use IO::Socket::UNIX; # core
6 use Cwd qw(abs_path); # core
7 use POSIX qw(:fcntl_h); # core
8 use AnyEvent::Handle; # not core
9 use AnyEvent::Util; # not core
10 use Exporter 'import';
11 use v5.10;
12
13 our @EXPORT = qw(activate_i3);
14
15 #
16 # Starts i3 using socket activation. Creates a listening socket (with bind +
17 # listen) which is then passed to i3, who in turn calls accept and handles the
18 # requests.
19 #
20 # Since the kernel buffers the connect, the parent process can connect to the
21 # socket immediately after forking. It then sends a request and waits until it
22 # gets an answer. Obviously, i3 has to be initialized to actually answer the
23 # request.
24 #
25 # This way, we can wait *precisely* the amount of time which i3 waits to get
26 # ready, which is a *HUGE* speed gain (and a lot more robust) in comparison to
27 # using sleep() with a fixed amount of time.
28 #
29 # unix_socket_path: Location of the socket to use for the activation
30 # display: X11 $ENV{DISPLAY}
31 # configfile: path to the configuration file to use
32 # logpath: path to the logfile to which i3 will append
33 # cv: an AnyEvent->condvar which will be triggered once i3 is ready
34 #
35 sub activate_i3 {
36 my %args = @_;
37
38 # remove the old unix socket
39 unlink($args{unix_socket_path});
40
41 my $socket = IO::Socket::UNIX->new(
42 Listen => 1,
43 Local => $args{unix_socket_path},
44 );
45
46 my $pid = fork;
47 if (!defined($pid)) {
48 die "could not fork()";
49 }
50 if ($pid == 0) {
51 # Start a process group so that in the parent, we can kill the entire
52 # process group and immediately kill i3bar and any other child
53 # processes.
54 setpgrp;
55
56 $ENV{LISTEN_PID} = $$;
57 $ENV{LISTEN_FDS} = 1;
58 delete $ENV{DESKTOP_STARTUP_ID};
59 delete $ENV{I3SOCK};
60 # $SHELL could be set to fish, which will horribly break running shell
61 # commands via i3’s exec feature. This happened e.g. when having
62 # “set-option -g default-shell "/usr/bin/fish"” in ~/.tmux.conf
63 delete $ENV{SHELL};
64 unless ($args{dont_create_temp_dir}) {
65 $ENV{XDG_RUNTIME_DIR} = '/tmp/i3-testsuite/';
66 mkdir $ENV{XDG_RUNTIME_DIR};
67 }
68 $ENV{DISPLAY} = $args{display};
69
70 # We are about to exec, but we did not modify $^F to include $socket
71 # when creating the socket (because the file descriptor could have a
72 # number != 3 which would lead to i3 leaking a file descriptor). This
73 # caused Perl to set the FD_CLOEXEC flag, which would close $socket on
74 # exec(), effectively *NOT* passing $socket to the new process.
75 # Therefore, we explicitly clear FD_CLOEXEC (the only flag right now)
76 # by setting the flags to 0.
77 POSIX::fcntl($socket, F_SETFD, 0) or die "Could not clear fd flags: $!";
78
79 # If the socket does not use file descriptor 3 by chance already, we
80 # close fd 3 and dup2() the socket to 3.
81 if (fileno($socket) != 3) {
82 POSIX::close(3);
83 POSIX::dup2(fileno($socket), 3);
84 POSIX::close(fileno($socket));
85 }
86
87 # Make sure no file descriptors are open. Strangely, I got an open file
88 # descriptor pointing to AnyEvent/Impl/EV.pm when testing.
89 AnyEvent::Util::close_all_fds_except(0, 1, 2, 3);
90
91 # Construct the command to launch i3. Use maximum debug level, disable
92 # the interactive signalhandler to make it crash immediately instead.
93 # Also disable logging to SHM since we redirect the logs anyways.
94 # Force Xinerama because we use Xdmx for multi-monitor tests.
95 my $i3cmd = q|i3 --shmlog-size=0 --disable-signalhandler|;
96 if (!defined($args{inject_randr15})) {
97 $i3cmd .= q| --force-xinerama|;
98 }
99 if (!$args{validate_config}) {
100 # We only set logging if i3 is actually started, but not if we only
101 # validate the config file. This is to keep logging to a minimum as
102 # such a test will likely want to inspect the log file.
103 $i3cmd .= q| -V -d all|;
104 }
105
106 # For convenience:
107 my $outdir = $args{outdir};
108 my $test = $args{testname};
109
110 if ($args{restart}) {
111 $i3cmd .= ' -L ' . abs_path('restart-state.golden');
112 }
113
114 if ($args{validate_config}) {
115 $i3cmd .= ' -C';
116 }
117
118 if ($args{valgrind}) {
119 $i3cmd =
120 qq|valgrind --log-file="$outdir/valgrind-for-$test.log" | .
121 qq|--suppressions="./valgrind.supp" | .
122 qq|--leak-check=full --track-origins=yes --num-callers=20 | .
123 qq|--tool=memcheck -- $i3cmd|;
124 }
125
126 my $logfile = "$outdir/i3-log-for-$test";
127 # Append to $logfile instead of overwriting because i3 might be
128 # run multiple times in one testcase.
129 my $cmd = "exec $i3cmd -c $args{configfile} >>$logfile 2>&1";
130
131 if ($args{strace}) {
132 my $out = "$outdir/strace-for-$test.log";
133
134 # We overwrite LISTEN_PID with the correct process ID to make
135 # socket activation work (LISTEN_PID has to match getpid(),
136 # otherwise the LISTEN_FDS will be treated as a left-over).
137 $cmd = qq|strace -fvy -s2048 -o "$out" -- | .
138 'sh -c "export LISTEN_PID=\$\$; ' . $cmd . '"';
139 }
140
141 if ($args{xtrace}) {
142 my $out = "$outdir/xtrace-for-$test.log";
143
144 # See comment in $args{strace} branch.
145 $cmd = qq|xtrace -n -o "$out" -- | .
146 'sh -c "export LISTEN_PID=\$\$; ' . $cmd . '"';
147 }
148
149 if ($args{inject_randr15}) {
150 # See comment in $args{strace} branch.
151 $cmd = 'test.inject_randr15 --getmonitors_reply="' .
152 $args{inject_randr15} . '" ' .
153 ($args{inject_randr15_outputinfo}
154 ? '--getoutputinfo_reply="' .
155 $args{inject_randr15_outputinfo} . '" '
156 : '') .
157 '-- ' .
158 'sh -c "export LISTEN_PID=\$\$; ' . $cmd . '"';
159 }
160
161 # We need to use the shell due to using output redirections.
162 exec '/bin/sh', '-c', $cmd;
163
164 # if we are still here, i3 could not be found or exec failed. bail out.
165 exit 1;
166 }
167
168 # close the socket, the child process should be the only one which keeps a file
169 # descriptor on the listening socket.
170 $socket->close;
171
172 if ($args{validate_config}) {
173 $args{cv}->send(1);
174 return $pid;
175 }
176
177 # We now connect (will succeed immediately) and send a request afterwards.
178 # As soon as the reply is there, i3 is considered ready.
179 my $cl = IO::Socket::UNIX->new(Peer => $args{unix_socket_path});
180 my $hdl;
181 $hdl = AnyEvent::Handle->new(
182 fh => $cl,
183 on_error => sub {
184 $hdl->destroy;
185 $args{cv}->send(0);
186 });
187
188 # send a get_tree message without payload
189 $hdl->push_write('i3-ipc' . pack("LL", 0, 4));
190
191 # wait for the reply
192 $hdl->push_read(chunk => 1, => sub {
193 my ($h, $line) = @_;
194 $args{cv}->send(1);
195 undef $hdl;
196 });
197
198 return $pid;
199 }
200
201 1
0 package StartXServer;
1 # vim:ts=4:sw=4:expandtab
2
3 use strict;
4 use warnings;
5 use Exporter 'import';
6 use Time::HiRes qw(sleep);
7 use i3test::Util qw(slurp);
8 use v5.10;
9
10 our @EXPORT = qw(start_xserver);
11
12 my @pids;
13 my $x_socketpath = '/tmp/.X11-unix/X';
14
15 # forks an X server process
16 sub fork_xserver {
17 my $keep_xserver_output = shift;
18 my $displaynum = shift;
19 my $pid = fork();
20 die "Could not fork: $!" unless defined($pid);
21 if ($pid == 0) {
22 # Child, close stdout/stderr, then start Xephyr
23 if (!$keep_xserver_output) {
24 close STDOUT;
25 close STDERR;
26 }
27
28 exec @_;
29 exit 1;
30 }
31 push(@complete_run::CLEANUP, sub {
32 kill(15, $pid);
33 # Unlink the X11 socket, Xdmx seems to leave it there.
34 unlink($x_socketpath . $displaynum);
35 });
36
37 push @pids, $pid;
38
39 return $x_socketpath . $displaynum;
40 }
41
42 # Blocks until the socket paths specified in the given array reference actually
43 # exist.
44 sub wait_for_x {
45 my ($sockets_waiting) = @_;
46
47 # Wait until Xdmx actually runs. Pretty ugly solution, but as long as we
48 # can’t socket-activate X11…
49 while (1) {
50 @$sockets_waiting = grep { ! -S $_ } @$sockets_waiting;
51 last unless @$sockets_waiting;
52 sleep 0.1;
53 }
54 }
55
56 =head2 start_xserver($parallel)
57
58 Starts C<$parallel> (or number of cores * 2 if undef) Xephyr processes (see
59 https://www.freedesktop.org/wiki/Software/Xephyr/) and returns two arrayrefs: a
60 list of X11 display numbers to the Xephyr processes and a list of PIDs of the
61 processes.
62
63 =cut
64
65 sub start_xserver {
66 my ($parallel, $numtests, $keep_xserver_output) = @_;
67
68 my @displays = ();
69 my @childpids = ();
70
71 # Yeah, I know it’s non-standard, but Perl’s POSIX module doesn’t have
72 # _SC_NPROCESSORS_CONF.
73 my $num_cores;
74 if (-e '/proc/cpuinfo') {
75 my $cpuinfo = slurp('/proc/cpuinfo');
76 $num_cores = scalar grep { /model name/ } split("\n", $cpuinfo);
77 }
78 # If /proc/cpuinfo does not exist, we fall back to 2 cores.
79 $num_cores ||= 2;
80
81 # If unset, we use num_cores * 2.
82 $parallel ||= ($num_cores * 2);
83
84 # If we are running a small number of tests, don’t over-parallelize.
85 $parallel = $numtests if $numtests < $parallel;
86
87 # First get the last used display number, then increment it by one.
88 # Effectively falls back to 1 if no X server is running.
89 my ($displaynum) = reverse sort { $a <=> $b } map{ /(\d+)$/ } glob($x_socketpath . '*');
90 $displaynum++;
91
92 say "Starting $parallel Xephyr instances, starting at :$displaynum...";
93
94 $SIG{CHLD} = sub {
95 my $child = waitpid -1, POSIX::WNOHANG;
96 @pids = grep { $_ != $child } @pids;
97 return unless @pids == 0;
98 print STDERR "All X server processes died.\n";
99 print STDERR "Use ./complete-run.pl --parallel 1 --keep-xserver-output\n";
100 exit 1;
101 };
102
103 my @sockets_waiting;
104 for (1 .. $parallel) {
105 my $socket = fork_xserver($keep_xserver_output, $displaynum,
106 'Xephyr', ":$displaynum", '-screen', '1280x800',
107 '-nolisten', 'tcp', '-name', "i3test");
108 push(@displays, ":$displaynum");
109 push(@sockets_waiting, $socket);
110 $displaynum++;
111 }
112
113 wait_for_x(\@sockets_waiting);
114
115 return @displays;
116 }
117
118 1
0 package StatusLine;
1 use strict; use warnings;
2
3 # enable autoflush on STDOUT.
4 # this is essential, because we print our statuslines without a newline
5 $| = 1;
6
7 use Exporter 'import';
8 our @EXPORT = qw/status_init status status_completed/;
9
10 my $ansi_clear_line = "\033[2K";
11 my $ansi_save_cursor = "\0337";
12 my $ansi_restore_cursor = "\0338";
13 my %ansi_line_upwards;
14
15 my $tests_total;
16
17 sub noninteractive {
18 # CONTINUOUS_INTEGRATION gets set when running under Travis, see
19 # https://docs.travis-ci.com/user/ci-environment/ and
20 # https://github.com/travis-ci/travis-ci/issues/1337
21 return (! -t STDOUT) || (
22 defined($ENV{CONTINUOUS_INTEGRATION}) &&
23 $ENV{CONTINUOUS_INTEGRATION} eq 'true');
24 }
25
26 # setup %ansi_line_upwards to map all working displays to the
27 # specific movement commands and initialize all status lines
28 sub status_init {
29 my %args = @_;
30 my $displays = $args{displays};
31 $tests_total = $args{tests};
32
33 return if noninteractive();
34
35 for my $n (1 .. @$displays) {
36 # since we are moving upwards, get $display in reverse order
37 my $display = $displays->[-$n];
38
39 $ansi_line_upwards{$display} = "\033[$n\101";
40
41 # print an empty line for this status line
42 print "\n";
43 }
44
45 status_completed(0);
46 }
47
48 # generates the status text, prints it in the appropriate line
49 # and returns it, so it can be used in conjunction with C<Log()>
50 sub status {
51 my ($display, $msg) = @_;
52 my $status = "[$display] $msg";
53
54 return $status if noninteractive();
55
56 print
57 $ansi_save_cursor,
58 $ansi_line_upwards{$display},
59 $ansi_clear_line,
60 $status,
61 $ansi_restore_cursor;
62
63 return $status;
64 }
65
66 sub status_completed {
67 my $num = shift;
68
69 return if noninteractive();
70
71 print
72 $ansi_save_cursor,
73 $ansi_clear_line,
74 "completed $num of $tests_total tests",
75 $ansi_restore_cursor;
76 }
77
78
79 __PACKAGE__ __END__
0 # vim:ts=4:sw=4:sts=4:expandtab
1 package TestWorker;
2 use strict; use warnings;
3 use v5.10;
4
5 use Socket qw(AF_UNIX SOCK_DGRAM PF_UNSPEC);
6 use IO::Handle; # for ->autoflush
7
8 use POSIX ();
9
10 use Errno qw(EAGAIN);
11
12 use Exporter 'import';
13 our @EXPORT = qw(worker worker_next);
14
15 use File::Basename qw(basename);
16 my @x;
17 my $options;
18
19 sub worker {
20 my ($display, $x, $outdir, $optref) = @_;
21
22 # make sure $x hangs around
23 push @x, $x;
24
25 # store the options hashref
26 $options = $optref;
27
28 socketpair(my $ipc_child, my $ipc, AF_UNIX, SOCK_DGRAM, PF_UNSPEC)
29 or die "socketpair: $!";
30
31 $ipc->autoflush(1);
32 $ipc_child->autoflush(1);
33
34 my $worker = {
35 display => $display,
36 ipc => $ipc,
37 };
38
39 my $pid = fork // die "could not fork: $!";
40
41 if ($pid == 0) {
42 close $ipc;
43 undef @complete_run::CLEANUP;
44 # reap dead test children
45 $SIG{CHLD} = sub { waitpid -1, POSIX::WNOHANG };
46
47 $worker->{ipc} = $ipc_child;
48
49 # Preload the i3test module: reduces user CPU from 25s to 18s
50 require i3test;
51
52 worker_wait($worker, $outdir);
53 exit 23;
54
55 }
56
57 close $ipc_child;
58 push @complete_run::CLEANUP, sub {
59 # signal via empty line to exit itself
60 syswrite($ipc, "\n") or kill('TERM', $pid);
61 waitpid $pid, 0;
62 };
63
64 return $worker;
65
66 }
67
68 our $EOF = "# end of file\n";
69 sub worker_wait {
70 my ($self, $outdir) = @_;
71
72 my $ipc = $self->{ipc};
73 my $ipc_fd = fileno($ipc);
74
75 while (1) {
76 my $file = $ipc->getline;
77 if (!defined($file)) {
78 next if $! == EAGAIN;
79 last;
80 }
81 chomp $file;
82
83 exit unless $file;
84
85 die "tried to launch nonexistent testfile $file: $!\n"
86 unless -e $file;
87
88 # start a new and self contained process:
89 # whatever happens in the testfile should *NOT* affect us.
90
91 my $pid = fork // die "could not fork: $!";
92 if ($pid == 0) {
93 undef @complete_run::CLEANUP;
94 local $SIG{CHLD};
95
96 $0 = $file;
97
98 # Re-seed rand() so that File::Temp’s tempnam produces different
99 # results, making a TOCTOU between e.g. t/175-startup-notification.t
100 # and t/180-fd-leaks.t less likely.
101 srand(time ^ $$);
102
103 POSIX::dup2($ipc_fd, 0);
104 POSIX::dup2($ipc_fd, 1);
105 POSIX::dup2(1, 2);
106
107 # get Test::Builder singleton
108 my $test = Test::Builder->new;
109
110 # Test::Builder dups stdout/stderr while loading.
111 # we need to reset them here to point to $ipc
112 $test->output(\*STDOUT);
113 $test->failure_output(\*STDERR);
114 $test->todo_output(\*STDOUT);
115
116 @ENV{qw(HOME DISPLAY TESTNAME OUTDIR VALGRIND STRACE XTRACE COVERAGE RESTART)}
117 = ($outdir,
118 $self->{display},
119 basename($file),
120 $outdir,
121 $options->{valgrind},
122 $options->{strace},
123 $options->{xtrace},
124 $options->{coverage},
125 $options->{restart});
126
127 package main;
128 local $@;
129 do $file;
130 $test->ok(undef, "$@") if $@;
131
132 # XXX hack, we need to trigger the read watcher once more
133 # to signal eof to TAP::Parser
134 print $EOF;
135
136 exit 0;
137 }
138 }
139 }
140
141 sub worker_next {
142 my ($self, $file) = @_;
143
144 my $ipc = $self->{ipc};
145 syswrite $ipc, "$file\n" or die "syswrite: $!";
146 }
147
148 __PACKAGE__ __END__
0 package i3test::Test;
1 # vim:ts=4:sw=4:expandtab
2
3 use base 'Test::Builder::Module';
4
5 our @EXPORT = qw(
6 is_num_children
7 is_num_fullscreen
8 cmp_float
9 does_i3_live
10 );
11
12 my $CLASS = __PACKAGE__;
13
14 =head1 NAME
15
16 i3test::Test - Additional test instructions for use in i3 testcases
17
18 =head1 SYNOPSIS
19
20 use i3test;
21
22 my $ws = fresh_workspace;
23 is_num_children($ws, 0, 'no containers on this workspace yet');
24 cmd 'open';
25 is_num_children($ws, 1, 'one container after "open"');
26
27 done_testing;
28
29 =head1 DESCRIPTION
30
31 This module provides convenience methods for i3 testcases. If you notice that a
32 certain pattern is present in 5 or more test cases, it should most likely be
33 moved into this module.
34
35 =head1 EXPORT
36
37 =head2 is_num_children($workspace, $expected, $test_name)
38
39 Gets the number of children on the given workspace and verifies that they match
40 the expected amount of children.
41
42 is_num_children('1', 0, 'no containers on workspace 1 at startup');
43
44 =cut
45
46 sub is_num_children {
47 my ($workspace, $num_children, $name) = @_;
48 my $tb = $CLASS->builder;
49
50 my $con = i3test::get_ws($workspace);
51 $tb->ok(defined($con), "Workspace $workspace exists");
52 if (!defined($con)) {
53 $tb->skip("Workspace does not exist, skipping is_num_children");
54 return;
55 }
56
57 my $got_num_children = scalar @{$con->{nodes}};
58
59 $tb->is_num($got_num_children, $num_children, $name);
60 }
61
62 =head2 is_num_fullscreen($workspace, $expected, $test_name)
63
64 Gets the number of fullscreen containers on the given workspace and verifies that
65 they match the expected amount.
66
67 is_num_fullscreen('1', 0, 'no fullscreen containers on workspace 1');
68
69 =cut
70 sub is_num_fullscreen {
71 my ($workspace, $num_fullscreen, $name) = @_;
72 my $workspace_content = i3test::get_ws($workspace);
73 my $tb = $CLASS->builder;
74
75 my $nodes = scalar grep { $_->{fullscreen_mode} != 0 } @{$workspace_content->{nodes}->[0]->{nodes}};
76 my $cons = scalar grep { $_->{fullscreen_mode} != 0 } @{$workspace_content->{nodes}};
77 my $floating = scalar grep { $_->{fullscreen_mode} != 0 } @{$workspace_content->{floating_nodes}->[0]->{nodes}};
78 $tb->is_num($nodes + $cons + $floating, $num_fullscreen, $name);
79 }
80
81 =head2 cmp_float($a, $b)
82
83 Compares floating point numbers C<$a> and C<$b> and returns true if they differ
84 less then 1e-6.
85
86 $tmp = fresh_workspace;
87
88 open_window for (1..4);
89
90 cmd 'resize grow width 10 px or 25 ppt';
91
92 ($nodes, $focus) = get_ws_content($tmp);
93 ok(cmp_float($nodes->[0]->{percent}, 0.166666666666667), 'first window got 16%');
94 ok(cmp_float($nodes->[1]->{percent}, 0.166666666666667), 'second window got 16%');
95 ok(cmp_float($nodes->[2]->{percent}, 0.166666666666667), 'third window got 16%');
96 ok(cmp_float($nodes->[3]->{percent}, 0.50), 'fourth window got 50%');
97
98 =cut
99 sub cmp_float {
100 my ($a, $b, $name) = @_;
101 my $tb = $CLASS->builder;
102
103 $tb->cmp_ok(abs($a - $b), '<', 1e-6, $name);
104 }
105
106 =head2 does_i3_live
107
108 Returns true if the layout tree can still be received from i3.
109
110 # i3 used to crash on invalid commands in revision X
111 cmd 'invalid command';
112 does_i3_live;
113
114 =cut
115 sub does_i3_live {
116 my $tree = i3test::i3(i3test::get_socket_path())->get_tree->recv;
117 my @nodes = @{$tree->{nodes}};
118 my $tb = $CLASS->builder;
119 $tb->ok((@nodes > 0), 'i3 still lives');
120 }
121
122 =head1 AUTHOR
123
124 Michael Stapelberg <[email protected]>
125
126 =cut
127
128 1
0 package i3test::Util;
1 # vim:ts=4:sw=4:expandtab
2
3 use strict;
4 use warnings;
5 use v5.10;
6
7 use X11::XCB qw(GET_PROPERTY_TYPE_ANY);
8 use X11::XCB::Connection;
9
10 use Exporter qw(import);
11 our @EXPORT = qw(
12 slurp
13 get_socket_path
14 );
15
16 =encoding utf-8
17
18 =head1 NAME
19
20 i3test::Util - General utility functions
21
22 =cut
23
24 =head1 EXPORT
25
26 =cut
27
28 =head2 slurp($fn)
29
30 Reads the entire file specified in the arguments and returns the content.
31
32 =cut
33 sub slurp {
34 my ($file) = @_;
35 my $content = do {
36 local $/ = undef;
37 open my $fh, "<", $file or die "could not open $file: $!";
38 <$fh>;
39 };
40
41 return $content;
42 }
43
44 =head2 get_socket_path([X11::XCB::Connection])
45
46 Gets the socket path from the C<I3_SOCKET_PATH> atom stored on the X11 root
47 window.
48
49 =cut
50 sub get_socket_path {
51 my ($x) = @_;
52 $x //= X11::XCB::Connection->new();
53 my $atom = $x->atom(name => 'I3_SOCKET_PATH');
54 my $cookie = $x->get_property(0, $x->get_root_window(), $atom->id, GET_PROPERTY_TYPE_ANY, 0, 256);
55 my $reply = $x->get_property_reply($cookie->{sequence});
56 my $socketpath = $reply->{value};
57 if ($socketpath eq "/tmp/nested-$ENV{DISPLAY}") {
58 $socketpath .= '-activation';
59 }
60 return $socketpath;
61 }
62
63 =head1 AUTHOR
64
65 Michael Stapelberg <[email protected]>
66
67 =cut
68
69 1
0 package i3test::XTEST;
1 # vim:ts=4:sw=4:expandtab
2
3 use strict;
4 use warnings;
5 use v5.10;
6
7 use Test::More;
8 use i3test::Util qw(get_socket_path);
9 use lib qw(@abs_top_srcdir@/AnyEvent-I3/blib/lib);
10 use AnyEvent::I3;
11 use ExtUtils::PkgConfig;
12
13 use Exporter ();
14 our @EXPORT = qw(
15 inlinec_connect
16 xtest_sync_with
17 xtest_sync_with_i3
18 set_xkb_group
19 xtest_key_press
20 xtest_key_release
21 xtest_button_press
22 xtest_button_release
23 binding_events
24 );
25
26 =encoding utf-8
27
28 =head1 NAME
29
30 i3test::XTEST - Inline::C wrappers for xcb-xtest and xcb-xkb
31
32 =cut
33
34 # We need to use libxcb-xkb because xdotool cannot trigger ISO_Next_Group
35 # anymore: it contains code to set the XKB group to 1 and then restore the
36 # previous group, effectively rendering any keys that switch groups
37 # ineffective.
38 my %sn_config;
39 BEGIN {
40 %sn_config = ExtUtils::PkgConfig->find('xcb-xkb xcb-xtest xcb-util');
41 }
42
43 use Inline C => Config => LIBS => $sn_config{libs}, CCFLAGS => $sn_config{cflags};
44 use Inline C => <<'END_OF_C_CODE';
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 #include <unistd.h>
49 #include <stdbool.h>
50 #include <stdint.h>
51
52 #include <xcb/xcb.h>
53 #include <xcb/xkb.h>
54 #include <xcb/xtest.h>
55 #include <xcb/xcb_aux.h>
56
57 static xcb_connection_t *conn = NULL;
58 static xcb_window_t sync_window;
59 static xcb_window_t root_window;
60 static xcb_atom_t i3_sync_atom;
61
62 bool inlinec_connect() {
63 int screen;
64
65 if ((conn = xcb_connect(NULL, &screen)) == NULL ||
66 xcb_connection_has_error(conn)) {
67 if (conn != NULL) {
68 xcb_disconnect(conn);
69 }
70 fprintf(stderr, "Could not connect to X11\n");
71 return false;
72 }
73
74 if (!xcb_get_extension_data(conn, &xcb_xkb_id)->present) {
75 fprintf(stderr, "XKB not present\n");
76 return false;
77 }
78
79 if (!xcb_get_extension_data(conn, &xcb_test_id)->present) {
80 fprintf(stderr, "XTEST not present\n");
81 return false;
82 }
83
84 xcb_generic_error_t *err = NULL;
85 xcb_xkb_use_extension_reply_t *usereply;
86 usereply = xcb_xkb_use_extension_reply(
87 conn, xcb_xkb_use_extension(conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION), &err);
88 if (err != NULL || usereply == NULL) {
89 fprintf(stderr, "xcb_xkb_use_extension() failed\n");
90 free(err);
91 return false;
92 }
93 free(usereply);
94
95 xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, xcb_intern_atom(conn, 0, strlen("I3_SYNC"), "I3_SYNC"), NULL);
96 i3_sync_atom = reply->atom;
97 free(reply);
98
99 xcb_screen_t *root_screen = xcb_aux_get_screen(conn, screen);
100 root_window = root_screen->root;
101 sync_window = xcb_generate_id(conn);
102 xcb_create_window(conn,
103 XCB_COPY_FROM_PARENT, // depth
104 sync_window, // window
105 root_window, // parent
106 -15, // x
107 -15, // y
108 1, // width
109 1, // height
110 0, // border_width
111 XCB_WINDOW_CLASS_INPUT_OUTPUT, // class
112 XCB_COPY_FROM_PARENT, // visual
113 XCB_CW_OVERRIDE_REDIRECT, // value_mask
114 (uint32_t[]){
115 1, // override_redirect
116 }); // value_list
117
118 return true;
119 }
120
121 void xtest_sync_with(int window) {
122 xcb_client_message_event_t ev;
123 memset(&ev, '\0', sizeof(xcb_client_message_event_t));
124
125 const int nonce = rand() % 255;
126
127 ev.response_type = XCB_CLIENT_MESSAGE;
128 ev.window = sync_window;
129 ev.type = i3_sync_atom;
130 ev.format = 32;
131 ev.data.data32[0] = sync_window;
132 ev.data.data32[1] = nonce;
133
134 xcb_send_event(conn, false, (xcb_window_t)window, XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (char *)&ev);
135 xcb_flush(conn);
136
137 xcb_generic_event_t *event = NULL;
138 while (1) {
139 free(event);
140 if ((event = xcb_wait_for_event(conn)) == NULL) {
141 break;
142 }
143 if (event->response_type == 0) {
144 fprintf(stderr, "X11 Error received! sequence %x\n", event->sequence);
145 continue;
146 }
147
148 /* Strip off the highest bit (set if the event is generated) */
149 const int type = (event->response_type & 0x7F);
150 switch (type) {
151 case XCB_CLIENT_MESSAGE: {
152 xcb_client_message_event_t *ev = (xcb_client_message_event_t *)event;
153 {
154 const uint32_t got = ev->data.data32[0];
155 const uint32_t want = sync_window;
156 if (got != want) {
157 fprintf(stderr, "Ignoring ClientMessage: unknown window: got %d, want %d\n", got, want);
158 continue;
159 }
160 }
161 {
162 const uint32_t got = ev->data.data32[1];
163 const uint32_t want = nonce;
164 if (got != want) {
165 fprintf(stderr, "Ignoring ClientMessage: unknown nonce: got %d, want %d\n", got, want);
166 continue;
167 }
168 }
169 return;
170 }
171 default:
172 fprintf(stderr, "Unexpected X11 event of type %d received (XCB_CLIENT_MESSAGE = %d)\n", type, XCB_CLIENT_MESSAGE);
173 break;
174 }
175 }
176 free(event);
177 }
178
179 void xtest_sync_with_i3() {
180 xtest_sync_with((int)root_window);
181 }
182
183 // NOTE: while |group| should be a uint8_t, Inline::C will not define the
184 // function unless we use an int.
185 bool set_xkb_group(int group) {
186 xcb_generic_error_t *err = NULL;
187 // Needs libxcb ≥ 1.11 so that we have the following bug fix:
188 // https://cgit.freedesktop.org/xcb/proto/commit/src/xkb.xml?id=8d7ee5b6ba4cf343f7df70372a3e1f85b82aeed7
189 xcb_void_cookie_t cookie = xcb_xkb_latch_lock_state_checked(
190 conn,
191 XCB_XKB_ID_USE_CORE_KBD, /* deviceSpec */
192 0, /* affectModLocks */
193 0, /* modLocks */
194 1, /* lockGroup */
195 group, /* groupLock */
196 0, /* affectModLatches */
197 0, /* latchGroup */
198 0); /* groupLatch */
199 if ((err = xcb_request_check(conn, cookie)) != NULL) {
200 fprintf(stderr, "X error code %d\n", err->error_code);
201 free(err);
202 return false;
203 }
204 return true;
205 }
206
207 bool xtest_input(int type, int detail, int x, int y) {
208 xcb_generic_error_t *err;
209 xcb_void_cookie_t cookie;
210
211 cookie = xcb_test_fake_input_checked(
212 conn,
213 type, /* type */
214 detail, /* detail */
215 XCB_CURRENT_TIME, /* time */
216 XCB_NONE, /* root */
217 x, /* rootX */
218 y, /* rootY */
219 XCB_NONE); /* deviceid */
220 if ((err = xcb_request_check(conn, cookie)) != NULL) {
221 fprintf(stderr, "X error code %d\n", err->error_code);
222 free(err);
223 return false;
224 }
225
226 return true;
227 }
228
229 bool xtest_key(int type, int detail) {
230 return xtest_input(type, detail, 0, 0);
231 }
232
233 bool xtest_key_press(int detail) {
234 return xtest_key(XCB_KEY_PRESS, detail);
235 }
236
237 bool xtest_key_release(int detail) {
238 return xtest_key(XCB_KEY_RELEASE, detail);
239 }
240
241 bool xtest_button_press(int button, int x, int y) {
242 return xtest_input(XCB_BUTTON_PRESS, button, x, y);
243 }
244
245 bool xtest_button_release(int button, int x, int y) {
246 return xtest_input(XCB_BUTTON_RELEASE, button, x, y);
247 }
248
249 END_OF_C_CODE
250
251 sub import {
252 my ($class, %args) = @_;
253 ok(inlinec_connect(), 'Connect to X11, verify XKB and XTEST are present (via Inline::C)');
254 goto \&Exporter::import;
255 }
256
257 =head1 EXPORT
258
259 =cut
260
261 =head2 set_xkb_group($group)
262
263 Changes the current XKB group from the default of 1 to C<$group>, which must be
264 one of 1, 2, 3, 4.
265
266 Returns false when there was an X11 error changing the group, true otherwise.
267
268 =head2 xtest_key_press($detail)
269
270 Sends a KeyPress event via XTEST, with the specified C<$detail>, i.e. key code.
271 Use C<xev(1)> to find key codes.
272
273 Returns false when there was an X11 error, true otherwise.
274
275 =head2 xtest_key_release($detail)
276
277 Sends a KeyRelease event via XTEST, with the specified C<$detail>, i.e. key code.
278 Use C<xev(1)> to find key codes.
279
280 Returns false when there was an X11 error, true otherwise.
281
282 =head2 xtest_button_press($button, $x, $y)
283
284 Sends a ButtonPress event via XTEST, with the specified C<$button>.
285
286 Returns false when there was an X11 error, true otherwise.
287
288 =head2 xtest_button_release($button, $x, $y)
289
290 Sends a ButtonRelease event via XTEST, with the specified C<$button>.
291
292 Returns false when there was an X11 error, true otherwise.
293
294 =head2 xtest_sync_with($window)
295
296 Ensures the specified window has processed all X11 events which were triggered
297 by this module, provided the window response to the i3 sync protocol.
298
299 =head2 xtest_sync_with_i3()
300
301 Ensures i3 has processed all X11 events which were triggered by this module.
302
303 =head1 AUTHOR
304
305 Michael Stapelberg <[email protected]>
306
307 =cut
308
309 1
0 package i3test;
1 # vim:ts=4:sw=4:expandtab
2 use strict; use warnings;
3
4 use File::Temp qw(tmpnam tempfile tempdir);
5 use Test::Builder;
6 use X11::XCB::Rect;
7 use X11::XCB::Window;
8 use X11::XCB qw(:all);
9 use lib qw(@abs_top_srcdir@/AnyEvent-I3/blib/lib);
10 use AnyEvent::I3;
11 use List::Util qw(first);
12 use Time::HiRes qw(sleep);
13 use Cwd qw(abs_path);
14 use POSIX ':sys_wait_h';
15 use Scalar::Util qw(blessed);
16 use SocketActivation;
17 use i3test::Util qw(slurp);
18
19 use v5.10;
20
21 # preload
22 use Test::More ();
23 use Data::Dumper ();
24
25 use Exporter ();
26 our @EXPORT = qw(
27 get_workspace_names
28 get_output_for_workspace
29 get_unused_workspace
30 fresh_workspace
31 get_ws_content
32 get_ws
33 get_focused
34 open_empty_con
35 open_window
36 open_floating_window
37 get_dock_clients
38 cmd
39 sync_with_i3
40 exit_gracefully
41 exit_forcefully
42 workspace_exists
43 focused_ws
44 get_socket_path
45 launch_with_config
46 get_i3_log
47 wait_for_event
48 wait_for_map
49 wait_for_unmap
50 $x
51 kill_all_windows
52 events_for
53 listen_for_binding
54 is_net_wm_state_focused
55 cmp_tree
56 );
57
58 =head1 NAME
59
60 i3test - Testcase setup module
61
62 =encoding utf-8
63
64 =head1 SYNOPSIS
65
66 use i3test;
67
68 my $ws = fresh_workspace;
69 is_num_children($ws, 0, 'no containers on this workspace yet');
70 cmd 'open';
71 is_num_children($ws, 1, 'one container after "open"');
72
73 done_testing;
74
75 =head1 DESCRIPTION
76
77 This module is used in every i3 testcase and takes care of automatically
78 starting i3 before any test instructions run. It also saves you typing of lots
79 of boilerplate in every test file.
80
81
82 i3test automatically "use"s C<Test::More>, C<Data::Dumper>, C<AnyEvent::I3>,
83 C<Time::HiRes>’s C<sleep> and C<i3test::Test> so that all of them are available
84 to you in your testcase.
85
86 See also C<i3test::Test> (L<https://build.i3wm.org/docs/lib-i3test-test.html>)
87 which provides additional test instructions (like C<ok> or C<is>).
88
89 =cut
90
91 my $tester = Test::Builder->new();
92 my $_cached_socket_path = undef;
93 my $_sync_window = undef;
94 my $tmp_socket_path = undef;
95
96 our $x;
97
98 BEGIN {
99 my $window_count = 0;
100 sub counter_window {
101 return $window_count++;
102 }
103 }
104
105 my $i3_pid;
106 my $i3_autostart;
107
108 END {
109 # Skip the remaining cleanup for testcases which set i3_autostart => 0:
110 return if !defined($i3_pid) && !$i3_autostart;
111
112 # don't trigger SIGCHLD handler
113 local $SIG{CHLD};
114
115 # From perldoc -v '$?':
116 # Inside an "END" subroutine $? contains the value
117 # that is going to be given to "exit()".
118 #
119 # Since waitpid sets $?, we need to localize it,
120 # otherwise TAP would be misinterpreted our return status
121 local $?;
122
123 # When measuring code coverage, try to exit i3 cleanly (otherwise, .gcda
124 # files are not written)
125 if ($ENV{COVERAGE} || $ENV{VALGRIND}) {
126 exit_gracefully($i3_pid, "/tmp/nested-$ENV{DISPLAY}");
127
128 } else {
129 kill(-9, $i3_pid)
130 or $tester->BAIL_OUT("could not kill i3: $!");
131
132 waitpid $i3_pid, 0;
133 }
134 }
135
136 sub import {
137 my ($class, %args) = @_;
138 my $pkg = caller;
139
140 $x ||= i3test::X11->new;
141 # set the pointer to a predictable position in case a previous test has
142 # disturbed it
143 $x->warp_pointer(
144 0, # src_window (None)
145 $x->get_root_window(), # dst_window (None)
146 0, # src_x
147 0, # src_y
148 0, # src_width
149 0, # src_height
150 0, # dst_x
151 0); # dst_y
152 # Synchronize with X11 to ensure the pointer has been warped before i3
153 # starts up.
154 $x->get_input_focus_reply($x->get_input_focus()->{sequence});
155
156 $i3_autostart = delete($args{i3_autostart}) // 1;
157 my $i3_config = delete($args{i3_config}) // '-default';
158
159 my $cv = launch_with_config($i3_config, dont_block => 1)
160 if $i3_autostart;
161
162 my $test_more_args = '';
163 $test_more_args = join(' ', 'qw(', %args, ')') if keys %args;
164 local $@;
165 eval << "__";
166 package $pkg;
167 use Test::More $test_more_args;
168 use Data::Dumper;
169 use AnyEvent::I3;
170 use Time::HiRes qw(sleep);
171 use i3test::Test;
172 __
173 $tester->BAIL_OUT("$@") if $@;
174 feature->import(":5.10");
175 strict->import;
176 warnings->import;
177
178 $cv->recv if $i3_autostart;
179
180 @_ = ($class);
181 goto \&Exporter::import;
182 }
183
184 =head1 EXPORT
185
186 =head2 wait_for_event($timeout, $callback)
187
188 Waits for the next event and calls the given callback for every event to
189 determine if this is the event we are waiting for.
190
191 Can be used to wait until a window is mapped, until a ClientMessage is
192 received, etc.
193
194 wait_for_event 0.25, sub { $_[0]->{response_type} == MAP_NOTIFY };
195
196 =cut
197 sub wait_for_event {
198 my ($timeout, $cb) = @_;
199
200 $x->flush;
201
202 while (defined(my $event = $x->wait_for_event)) {
203 return 1 if $cb->($event);
204 }
205 }
206
207 =head2 wait_for_map($window)
208
209 Thin wrapper around wait_for_event which waits for MAP_NOTIFY.
210 Make sure to include 'structure_notify' in the window’s event_mask attribute.
211
212 This function is called by C<open_window>, so in most cases, you don’t need to
213 call it on your own. If you need special setup of the window before mapping,
214 you might have to map it on your own and use this function:
215
216 my $window = open_window(dont_map => 1);
217 # Do something special with the window first
218 # …
219
220 # Now map it and wait until it’s been mapped
221 $window->map;
222 wait_for_map($window);
223
224 =cut
225 sub wait_for_map {
226 my ($win) = @_;
227 my $id = (blessed($win) && $win->isa('X11::XCB::Window')) ? $win->id : $win;
228 wait_for_event 4, sub {
229 $_[0]->{response_type} == MAP_NOTIFY and $_[0]->{window} == $id
230 };
231 }
232
233 =head2 wait_for_unmap($window)
234
235 Wrapper around C<wait_for_event> which waits for UNMAP_NOTIFY. Also calls
236 C<sync_with_i3> to make sure i3 also picked up and processed the UnmapNotify
237 event.
238
239 my $ws = fresh_workspace;
240 my $window = open_window;
241 is_num_children($ws, 1, 'one window on workspace');
242 $window->unmap;
243 wait_for_unmap;
244 is_num_children($ws, 0, 'no more windows on this workspace');
245
246 =cut
247 sub wait_for_unmap {
248 my ($win) = @_;
249 # my $id = (blessed($win) && $win->isa('X11::XCB::Window')) ? $win->id : $win;
250 wait_for_event 4, sub {
251 $_[0]->{response_type} == UNMAP_NOTIFY # and $_[0]->{window} == $id
252 };
253 sync_with_i3();
254 }
255
256 =head2 open_window([ $args ])
257
258 Opens a new window (see C<X11::XCB::Window>), maps it, waits until it got mapped
259 and synchronizes with i3.
260
261 The following arguments can be passed:
262
263 =over 4
264
265 =item class
266
267 The X11 window class (e.g. WINDOW_CLASS_INPUT_OUTPUT), not to be confused with
268 the WM_CLASS!
269
270 =item rect
271
272 An arrayref with 4 members specifying the initial geometry (position and size)
273 of the window, e.g. C<< [ 0, 100, 70, 50 ] >> for a window appearing at x=0, y=100
274 with width=70 and height=50.
275
276 Note that this is entirely irrelevant for tiling windows.
277
278 =item background_color
279
280 The background pixel color of the window, formatted as "#rrggbb", like HTML
281 color codes (e.g. #c0c0c0). This is useful to tell windows apart when actually
282 watching the testcases.
283
284 =item event_mask
285
286 An arrayref containing strings which describe the X11 event mask we use for that
287 window. The default is C<< [ 'structure_notify' ] >>.
288
289 =item name
290
291 The window’s C<_NET_WM_NAME> (UTF-8 window title). By default, this is "Window
292 n" with n being replaced by a counter to keep windows apart.
293
294 =item dont_map
295
296 Set to a true value to avoid mapping the window (making it visible).
297
298 =item before_map
299
300 A coderef which is called before the window is mapped (unless C<dont_map> is
301 true). The freshly created C<$window> is passed as C<$_> and as the first
302 argument.
303
304 =back
305
306 The default values are equivalent to this call:
307
308 open_window(
309 class => WINDOW_CLASS_INPUT_OUTPUT
310 rect => [ 0, 0, 30, 30 ]
311 background_color => '#c0c0c0'
312 event_mask => [ 'structure_notify' ]
313 name => 'Window <n>'
314 );
315
316 Usually, though, calls are simpler:
317
318 my $top_window = open_window;
319
320 To identify the resulting window object in i3 commands, use the id property:
321
322 my $top_window = open_window;
323 cmd '[id="' . $top_window->id . '"] kill';
324
325 =cut
326 sub open_window {
327 my %args = @_ == 1 ? %{$_[0]} : @_;
328
329 my $dont_map = delete $args{dont_map};
330 my $before_map = delete $args{before_map};
331
332 $args{class} //= WINDOW_CLASS_INPUT_OUTPUT;
333 $args{rect} //= [ 0, 0, 30, 30 ];
334 $args{background_color} //= '#c0c0c0';
335 $args{event_mask} //= [ 'structure_notify' ];
336 $args{name} //= 'Window ' . counter_window();
337
338 my $window = $x->root->create_child(%args);
339 $window->add_hint('input');
340
341 if ($before_map) {
342 # TODO: investigate why _create is not needed
343 $window->_create;
344 $before_map->($window) for $window;
345 }
346
347 return $window if $dont_map;
348
349 $window->map;
350 wait_for_map($window);
351
352 # MapWindow is sent before i3 even starts rendering: the window is placed at
353 # temporary off-screen coordinates first, and x_push_changes() sends further
354 # X11 requests to set focus etc. Hence, we sync with i3 before continuing.
355 sync_with_i3();
356
357 return $window;
358 }
359
360 =head2 open_floating_window([ $args ])
361
362 Thin wrapper around open_window which sets window_type to
363 C<_NET_WM_WINDOW_TYPE_UTILITY> to make the window floating.
364
365 The arguments are the same as those of C<open_window>.
366
367 =cut
368 sub open_floating_window {
369 my %args = @_ == 1 ? %{$_[0]} : @_;
370
371 $args{window_type} = $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY');
372
373 return open_window(\%args);
374 }
375
376 sub open_empty_con {
377 my ($i3) = @_;
378
379 my $reply = $i3->command('open')->recv;
380 return $reply->[0]->{id};
381 }
382
383 =head2 get_workspace_names()
384
385 Returns an arrayref containing the name of every workspace (regardless of its
386 output) which currently exists.
387
388 my $workspace_names = get_workspace_names;
389 is(scalar @$workspace_names, 3, 'three workspaces exist currently');
390
391 =cut
392 sub get_workspace_names {
393 my $i3 = i3(get_socket_path());
394 my $tree = $i3->get_tree->recv;
395 my @outputs = @{$tree->{nodes}};
396 my @cons;
397 for my $output (@outputs) {
398 next if $output->{name} eq '__i3';
399 # get the first CT_CON of each output
400 my $content = first { $_->{type} eq 'con' } @{$output->{nodes}};
401 @cons = (@cons, @{$content->{nodes}});
402 }
403 [ map { $_->{name} } @cons ]
404 }
405
406 =head2 get_output_for_workspace()
407
408 Returns the name of the output on which this workspace resides
409
410 cmd 'focus output fake-1';
411 cmd 'workspace 1';
412 is(get_output_for_workspace('1', 'fake-0', 'Workspace 1 in output fake-0');
413
414 =cut
415 sub get_output_for_workspace {
416 my $ws_name = shift @_;
417 my $i3 = i3(get_socket_path());
418 my $tree = $i3->get_tree->recv;
419 my @outputs = @{$tree->{nodes}};
420
421 foreach (grep { not $_->{name} =~ /^__/ } @outputs) {
422 my $output = $_->{name};
423 foreach (grep { $_->{name} =~ "content" } @{$_->{nodes}}) {
424 return $output if $_->{nodes}[0]->{name} =~ $ws_name;
425 }
426 }
427 }
428
429 =head2 get_unused_workspace
430
431 Returns a workspace name which has not yet been used. See also
432 C<fresh_workspace> which directly switches to an unused workspace.
433
434 my $ws = get_unused_workspace;
435 cmd "workspace $ws";
436
437 =cut
438 sub get_unused_workspace {
439 my @names = get_workspace_names();
440 my $tmp;
441 do { $tmp = tmpnam() } while ((scalar grep { $_ eq $tmp } @names) > 0);
442 $tmp
443 }
444
445 =head2 fresh_workspace([ $args ])
446
447 Switches to an unused workspace and returns the name of that workspace.
448
449 Optionally switches to the specified output first.
450
451 my $ws = fresh_workspace;
452
453 # Get a fresh workspace on the second output.
454 my $ws = fresh_workspace(output => 1);
455
456 =cut
457 sub fresh_workspace {
458 my %args = @_;
459 if (exists($args{output})) {
460 my $i3 = i3(get_socket_path());
461 my $tree = $i3->get_tree->recv;
462 my $output = first { $_->{name} eq "fake-$args{output}" }
463 @{$tree->{nodes}};
464 die "BUG: Could not find output $args{output}" unless defined($output);
465 # Get the focused workspace on that output and switch to it.
466 my $content = first { $_->{type} eq 'con' } @{$output->{nodes}};
467 my $focused = $content->{focus}->[0];
468 my $workspace = first { $_->{id} == $focused } @{$content->{nodes}};
469 $workspace = $workspace->{name};
470 cmd("workspace $workspace");
471 }
472
473 my $unused = get_unused_workspace;
474 cmd("workspace $unused");
475 $unused
476 }
477
478 =head2 get_ws($workspace)
479
480 Returns the container (from the i3 layout tree) which represents C<$workspace>.
481
482 my $ws = fresh_workspace;
483 my $ws_con = get_ws($ws);
484 ok(!$ws_con->{urgent}, 'fresh workspace not marked urgent');
485
486 Here is an example which counts the number of urgent containers recursively,
487 starting from the workspace container:
488
489 sub count_urgent {
490 my ($con) = @_;
491
492 my @children = (@{$con->{nodes}}, @{$con->{floating_nodes}});
493 my $urgent = grep { $_->{urgent} } @children;
494 $urgent += count_urgent($_) for @children;
495 return $urgent;
496 }
497 my $urgent = count_urgent(get_ws($ws));
498 is($urgent, 3, "three urgent windows on workspace $ws");
499
500
501 =cut
502 sub get_ws {
503 my ($name) = @_;
504 my $i3 = i3(get_socket_path());
505 my $tree = $i3->get_tree->recv;
506
507 my @outputs = @{$tree->{nodes}};
508 my @workspaces;
509 for my $output (@outputs) {
510 # get the first CT_CON of each output
511 my $content = first { $_->{type} eq 'con' } @{$output->{nodes}};
512 @workspaces = (@workspaces, @{$content->{nodes}});
513 }
514
515 # as there can only be one workspace with this name, we can safely
516 # return the first entry
517 return first { $_->{name} eq $name } @workspaces;
518 }
519
520 =head2 get_ws_content($workspace)
521
522 Returns the content (== tree, starting from the node of a workspace)
523 of a workspace. If called in array context, also includes the focus
524 stack of the workspace.
525
526 my $nodes = get_ws_content($ws);
527 is(scalar @$nodes, 4, 'there are four containers at workspace-level');
528
529 Or, in array context:
530
531 my $window = open_window;
532 my ($nodes, $focus) = get_ws_content($ws);
533 is($focus->[0], $window->id, 'newly opened window focused');
534
535 Note that this function does not do recursion for you! It only returns the
536 containers B<on workspace level>. If you want to work with all containers (even
537 nested ones) on a workspace, you have to use recursion:
538
539 # NB: This function does not count floating windows
540 sub count_urgent {
541 my ($nodes) = @_;
542
543 my $urgent = 0;
544 for my $con (@$nodes) {
545 $urgent++ if $con->{urgent};
546 $urgent += count_urgent($con->{nodes});
547 }
548
549 return $urgent;
550 }
551 my $nodes = get_ws_content($ws);
552 my $urgent = count_urgent($nodes);
553 is($urgent, 3, "three urgent windows on workspace $ws");
554
555 If you also want to deal with floating windows, you have to use C<get_ws>
556 instead and access C<< ->{nodes} >> and C<< ->{floating_nodes} >> on your own.
557
558 =cut
559 sub get_ws_content {
560 my ($name) = @_;
561 my $con = get_ws($name);
562 return wantarray ? ($con->{nodes}, $con->{focus}) : $con->{nodes};
563 }
564
565 =head2 get_focused($workspace)
566
567 Returns the container ID of the currently focused container on C<$workspace>.
568
569 Note that the container ID is B<not> the X11 window ID, so comparing the result
570 of C<get_focused> with a window's C<< ->{id} >> property does B<not> work.
571
572 my $ws = fresh_workspace;
573 my $first_window = open_window;
574 my $first_id = get_focused();
575
576 my $second_window = open_window;
577 my $second_id = get_focused();
578
579 cmd 'focus left';
580
581 is(get_focused($ws), $first_id, 'second window focused');
582
583 =cut
584 sub get_focused {
585 my ($ws) = @_;
586 my $con = get_ws($ws);
587
588 my @focused = @{$con->{focus}};
589 my $lf;
590 while (@focused > 0) {
591 $lf = $focused[0];
592 last unless defined($con->{focus});
593 @focused = @{$con->{focus}};
594 my @cons = grep { $_->{id} == $lf } (@{$con->{nodes}}, @{$con->{'floating_nodes'}});
595 $con = $cons[0];
596 }
597
598 return $lf;
599 }
600
601 =head2 get_dock_clients([ $dockarea ])
602
603 Returns an array of all dock containers in C<$dockarea> (one of "top" or
604 "bottom"). If C<$dockarea> is not specified, returns an array of all dock
605 containers in any dockarea.
606
607 my @docked = get_dock_clients;
608 is(scalar @docked, 0, 'no dock clients yet');
609
610 =cut
611 sub get_dock_clients {
612 my $which = shift;
613
614 my $tree = i3(get_socket_path())->get_tree->recv;
615 my @outputs = @{$tree->{nodes}};
616 # Children of all dockareas
617 my @docked;
618 for my $output (@outputs) {
619 if (!defined($which)) {
620 @docked = (@docked, map { @{$_->{nodes}} }
621 grep { $_->{type} eq 'dockarea' }
622 @{$output->{nodes}});
623 } elsif ($which eq 'top') {
624 my $first = first { $_->{type} eq 'dockarea' } @{$output->{nodes}};
625 @docked = (@docked, @{$first->{nodes}}) if defined($first);
626 } elsif ($which eq 'bottom') {
627 my @matching = grep { $_->{type} eq 'dockarea' } @{$output->{nodes}};
628 my $last = $matching[-1];
629 @docked = (@docked, @{$last->{nodes}}) if defined($last);
630 }
631 }
632 return @docked;
633 }
634
635 =head2 cmd($command)
636
637 Sends the specified command to i3 and returns the output.
638
639 my $ws = unused_workspace;
640 cmd "workspace $ws";
641 cmd 'focus right';
642
643 =cut
644 sub cmd {
645 i3(get_socket_path())->command(@_)->recv
646 }
647
648 =head2 workspace_exists($workspace)
649
650 Returns true if C<$workspace> is the name of an existing workspace.
651
652 my $old_ws = focused_ws;
653 # switch away from where we currently are
654 fresh_workspace;
655
656 ok(workspace_exists($old_ws), 'old workspace still exists');
657
658 =cut
659 sub workspace_exists {
660 my ($name) = @_;
661 (scalar grep { $_ eq $name } @{get_workspace_names()}) > 0;
662 }
663
664 =head2 focused_ws
665
666 Returns the name of the currently focused workspace.
667
668 my $ws = focused_ws;
669 is($ws, '1', 'i3 starts on workspace 1');
670
671 =cut
672 sub focused_ws {
673 my $i3 = i3(get_socket_path());
674 my $tree = $i3->get_tree->recv;
675 my $focused = $tree->{focus}->[0];
676 my $output = first { $_->{id} == $focused } @{$tree->{nodes}};
677 my $content = first { $_->{type} eq 'con' } @{$output->{nodes}};
678 my $first = first { $_->{fullscreen_mode} == 1 } @{$content->{nodes}};
679 return $first->{name}
680 }
681
682 =head2 sync_with_i3([ $args ])
683
684 Sends an I3_SYNC ClientMessage with a random value to the root window.
685 i3 will reply with the same value, but, due to the order of events it
686 processes, only after all other events are done.
687
688 This can be used to ensure the results of a cmd 'focus left' are pushed to
689 X11 and that C<< $x->input_focus >> returns the correct value afterwards.
690
691 See also L<https://build.i3wm.org/docs/testsuite.html> for a longer explanation.
692
693 my $window = open_window;
694 $window->add_hint('urgency');
695 # Ensure i3 picked up the change
696 sync_with_i3;
697
698 The only time when you need to use the C<no_cache> argument is when you just
699 killed your own X11 connection:
700
701 cmd 'kill client';
702 # We need to re-establish the X11 connection which we just killed :).
703 $x = i3test::X11->new;
704 sync_with_i3(no_cache => 1);
705
706 =cut
707 sub sync_with_i3 {
708 my %args = @_ == 1 ? %{$_[0]} : @_;
709
710 # Since we need a (mapped) window for receiving a ClientMessage, we create
711 # one on the first call of sync_with_i3. It will be re-used in all
712 # subsequent calls.
713 if (!exists($args{window_id}) &&
714 (!defined($_sync_window) || exists($args{no_cache}))) {
715 $_sync_window = open_window(
716 rect => [ -15, -15, 10, 10 ],
717 override_redirect => 1,
718 dont_map => 1,
719 );
720 }
721
722 my $window_id = delete $args{window_id};
723 $window_id //= $_sync_window->id;
724
725 my $root = $x->get_root_window();
726 # Generate a random number to identify this particular ClientMessage.
727 my $myrnd = int(rand(255)) + 1;
728
729 # Generate a ClientMessage, see xcb_client_message_t
730 my $msg = pack "CCSLLLLLLL",
731 CLIENT_MESSAGE, # response_type
732 32, # format
733 0, # sequence
734 $root, # destination window
735 $x->atom(name => 'I3_SYNC')->id,
736
737 $window_id, # data[0]: our own window id
738 $myrnd, # data[1]: a random value to identify the request
739 0,
740 0,
741 0;
742
743 # Send it to the root window -- since i3 uses the SubstructureRedirect
744 # event mask, it will get the ClientMessage.
745 $x->send_event(0, $root, EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
746
747 return $myrnd if $args{dont_wait_for_event};
748
749 # now wait until the reply is here
750 return wait_for_event 4, sub {
751 my ($event) = @_;
752 # TODO: const
753 return 0 unless $event->{response_type} == 161;
754
755 my ($win, $rnd) = unpack "LL", $event->{data};
756 return ($rnd == $myrnd);
757 };
758 }
759
760 =head2 exit_gracefully($pid, [ $socketpath ])
761
762 Tries to exit i3 gracefully (with the 'exit' cmd) or kills the PID if that fails.
763
764 If C<$socketpath> is not specified, C<get_socket_path()> will be called.
765
766 You only need to use this function if you have launched i3 on your own with
767 C<launch_with_config>. Otherwise, it will be automatically called when the
768 testcase ends.
769
770 use i3test i3_autostart => 0;
771 my $pid = launch_with_config($config);
772 # …
773 exit_gracefully($pid);
774
775 =cut
776 sub exit_gracefully {
777 my ($pid, $socketpath) = @_;
778 $socketpath ||= get_socket_path();
779
780 my $exited = 0;
781 eval {
782 say "Exiting i3 cleanly...";
783 i3($socketpath)->command('exit')->recv;
784 $exited = 1;
785 };
786
787 if (!$exited) {
788 kill(9, $pid)
789 or $tester->BAIL_OUT("could not kill i3: $!");
790 }
791
792 if ($socketpath =~ m,^/tmp/i3-test-socket-,) {
793 unlink($socketpath);
794 }
795
796 waitpid $pid, 0;
797 undef $i3_pid;
798 }
799
800 =head2 exit_forcefully($pid, [ $signal ])
801
802 Tries to exit i3 forcefully by sending a signal (defaults to SIGTERM).
803
804 You only need to use this function if you want to test signal handling
805 (in which case you must have launched i3 on your own with
806 C<launch_with_config>).
807
808 use i3test i3_autostart => 0;
809 my $pid = launch_with_config($config);
810 # …
811 exit_forcefully($pid);
812
813 =cut
814 sub exit_forcefully {
815 my ($pid, $signal) = @_;
816 $signal ||= 'TERM';
817
818 # Send the given signal to the i3 instance and wait for up to 10s
819 # for it to terminate.
820 kill($signal, $pid)
821 or $tester->BAIL_OUT("could not kill i3: $!");
822 my $status;
823 my $timeout = 10;
824 do {
825 $status = waitpid $pid, WNOHANG;
826
827 if ($status <= 0) {
828 sleep(1);
829 $timeout--;
830 }
831 } while ($status <= 0 && $timeout > 0);
832
833 if ($status <= 0) {
834 kill('KILL', $pid)
835 or $tester->BAIL_OUT("could not kill i3: $!");
836 waitpid $pid, 0;
837 }
838 undef $i3_pid;
839 }
840
841 =head2 get_socket_path([ $cache ])
842
843 Gets the socket path from the C<I3_SOCKET_PATH> atom stored on the X11 root
844 window. After the first call, this function will return a cached version of the
845 socket path unless you specify a false value for C<$cache>.
846
847 my $i3 = i3(get_socket_path());
848 $i3->command('nop test example')->recv;
849
850 To avoid caching:
851
852 my $i3 = i3(get_socket_path(0));
853
854 =cut
855 sub get_socket_path {
856 my ($cache) = @_;
857 $cache //= 1;
858
859 if ($cache && defined($_cached_socket_path)) {
860 return $_cached_socket_path;
861 }
862 my $socketpath = i3test::Util::get_socket_path($x);
863 $_cached_socket_path = $socketpath;
864 return $socketpath;
865 }
866
867 =head2 launch_with_config($config, [ $args ])
868
869 Launches a new i3 process with C<$config> as configuration file. Useful for
870 tests which test specific config file directives.
871
872 use i3test i3_autostart => 0;
873
874 my $config = <<EOT;
875 # i3 config file (v4)
876 for_window [class="borderless"] border none
877 for_window [title="special borderless title"] border none
878 EOT
879
880 my $pid = launch_with_config($config);
881
882 # …
883
884 exit_gracefully($pid);
885
886 =cut
887 sub launch_with_config {
888 my ($config, %args) = @_;
889
890 $tmp_socket_path = "/tmp/nested-$ENV{DISPLAY}";
891
892 $args{dont_create_temp_dir} //= 0;
893 $args{validate_config} //= 0;
894
895 my ($fh, $tmpfile) = tempfile("i3-cfg-for-$ENV{TESTNAME}-XXXXX", UNLINK => 1);
896
897 say $fh "ipc-socket $tmp_socket_path"
898 unless $args{dont_add_socket_path};
899
900 if ($config ne '-default') {
901 print $fh $config;
902 } else {
903 open(my $conf_fh, '<', '@abs_top_srcdir@/testcases/i3-test.config')
904 or $tester->BAIL_OUT("could not open default config: $!");
905 local $/;
906 say $fh scalar <$conf_fh>;
907 }
908
909 close($fh);
910
911 my $cv = AnyEvent->condvar;
912 $i3_pid = activate_i3(
913 unix_socket_path => "$tmp_socket_path-activation",
914 display => $ENV{DISPLAY},
915 configfile => $tmpfile,
916 outdir => $ENV{OUTDIR},
917 testname => $ENV{TESTNAME},
918 valgrind => $ENV{VALGRIND},
919 strace => $ENV{STRACE},
920 xtrace => $ENV{XTRACE},
921 restart => $ENV{RESTART},
922 cv => $cv,
923 dont_create_temp_dir => $args{dont_create_temp_dir},
924 validate_config => $args{validate_config},
925 inject_randr15 => $args{inject_randr15},
926 inject_randr15_outputinfo => $args{inject_randr15_outputinfo},
927 );
928
929 # If we called i3 with -C, we wait for it to exit and then return as
930 # there's nothing else we need to do.
931 if ($args{validate_config}) {
932 $cv->recv;
933 waitpid $i3_pid, 0;
934
935 # We need this since exit_gracefully will not be called in this case.
936 undef $i3_pid;
937
938 return ${^CHILD_ERROR_NATIVE};
939 }
940
941 # force update of the cached socket path in lib/i3test
942 # as soon as i3 has started
943 $cv->cb(sub { get_socket_path(0) });
944
945 return $cv if $args{dont_block};
946
947 # blockingly wait until i3 is ready
948 $cv->recv;
949
950 return $i3_pid;
951 }
952
953 =head2 get_i3_log
954
955 Returns the content of the log file for the current test.
956
957 =cut
958 sub get_i3_log {
959 my $logfile = "$ENV{OUTDIR}/i3-log-for-$ENV{TESTNAME}";
960 return slurp($logfile);
961 }
962
963 =head2 kill_all_windows
964
965 Kills all windows to clean up between tests.
966
967 =cut
968 sub kill_all_windows {
969 # Sync in case not all windows are managed by i3 just yet.
970 sync_with_i3;
971 cmd '[title=".*"] kill';
972 }
973
974 =head2 events_for($subscribecb, [ $rettype ], [ $eventcbs ])
975
976 Helper function which returns an array containing all events of type $rettype
977 which were generated by i3 while $subscribecb was running.
978
979 Set $eventcbs to subscribe to multiple event types and/or perform your own event
980 aggregation.
981
982 =cut
983 sub events_for {
984 my ($subscribecb, $rettype, $eventcbs) = @_;
985
986 my @events;
987 $eventcbs //= {};
988 if (defined($rettype)) {
989 $eventcbs->{$rettype} = sub { push @events, shift };
990 }
991 my $subscribed = AnyEvent->condvar;
992 my $flushed = AnyEvent->condvar;
993 $eventcbs->{tick} = sub {
994 my ($event) = @_;
995 if ($event->{first}) {
996 $subscribed->send($event);
997 } else {
998 $flushed->send($event);
999 }
1000 };
1001 my $i3 = i3(get_socket_path(0));
1002 $i3->connect->recv;
1003 $i3->subscribe($eventcbs)->recv;
1004 $subscribed->recv;
1005 # Subscription established, run the callback.
1006 $subscribecb->();
1007 # Now generate a tick event, which we know we’ll receive (and at which point
1008 # all other events have been received).
1009 my $nonce = int(rand(255)) + 1;
1010 $i3->send_tick($nonce);
1011
1012 my $tick = $flushed->recv;
1013 $tester->is_eq($tick->{payload}, $nonce, 'tick nonce received');
1014 return @events;
1015 }
1016
1017 =head2 listen_for_binding($cb)
1018
1019 Helper function to evaluate whether sending KeyPress/KeyRelease events via XTEST
1020 triggers an i3 key binding or not. Expects key bindings to be configured in the
1021 form “bindsym <binding> nop <binding>”, e.g. “bindsym Mod4+Return nop
1022 Mod4+Return”.
1023
1024 is(listen_for_binding(
1025 sub {
1026 xtest_key_press(133); # Super_L
1027 xtest_key_press(36); # Return
1028 xtest_key_release(36); # Return
1029 xtest_key_release(133); # Super_L
1030 xtest_sync_with_i3;
1031 },
1032 ),
1033 'Mod4+Return',
1034 'triggered the "Mod4+Return" keybinding');
1035
1036 =cut
1037
1038 sub listen_for_binding {
1039 my ($cb) = @_;
1040 my $triggered = AnyEvent->condvar;
1041 my @events = events_for(
1042 $cb,
1043 'binding');
1044
1045 $tester->is_eq(scalar @events, 1, 'Received precisely one event');
1046 $tester->is_eq($events[0]->{change}, 'run', 'change is "run"');
1047 # We look at the command (which is “nop <binding>”) because that is easier
1048 # than re-assembling the string representation of $event->{binding}.
1049 my $command = $events[0]->{binding}->{command};
1050 $command =~ s/^nop //g;
1051 return $command;
1052 }
1053
1054 =head2 is_net_wm_state_focused
1055
1056 Returns true if the given window has the _NET_WM_STATE_FOCUSED atom.
1057
1058 ok(is_net_wm_state_focused($window), '_NET_WM_STATE_FOCUSED set');
1059
1060 =cut
1061 sub is_net_wm_state_focused {
1062 my ($window) = @_;
1063
1064 sync_with_i3;
1065 my $atom = $x->atom(name => '_NET_WM_STATE_FOCUSED');
1066 my $cookie = $x->get_property(
1067 0,
1068 $window->{id},
1069 $x->atom(name => '_NET_WM_STATE')->id,
1070 GET_PROPERTY_TYPE_ANY,
1071 0,
1072 4096
1073 );
1074
1075 my $reply = $x->get_property_reply($cookie->{sequence});
1076 my $len = $reply->{length};
1077 return 0 if $len == 0;
1078
1079 my @atoms = unpack("L$len", $reply->{value});
1080 for (my $i = 0; $i < $len; $i++) {
1081 return 1 if $atoms[$i] == $atom->id;
1082 }
1083
1084 return 0;
1085 }
1086
1087 =head2 cmp_tree([ $args ])
1088
1089 Compares the tree layout before and after an operation inside a subtest.
1090
1091 The following arguments can be passed:
1092
1093 =over 4
1094
1095 =item layout_before
1096
1097 Required argument. The initial layout to be created. For example,
1098 'H[ V[ a* S[ b c ] d ] e ]' or 'V[a b] T[c d*]'.
1099 The layout will be converted to a JSON file which will be passed to i3's
1100 append_layout command.
1101
1102 The syntax's rules, assertions and limitations are:
1103
1104 =over 8
1105
1106 =item 1.
1107
1108 Upper case letters H, V, S, T mean horizontal, vertical, stacked and tabbed
1109 layout respectively. They must be followed by an opening square bracket and must
1110 be closed with a closing square bracket.
1111 Each of the non-leaf containers is marked with their corresponding letter
1112 followed by a number indicating the position of the container relative to other
1113 containers of the same type. For example, 'H[V[xxx] V[xxx] H[xxx]]' will mark
1114 the non-leaf containers as H1, V1, V2, H2.
1115
1116 =item 2.
1117
1118 Spaces are ignored.
1119
1120 =item 3.
1121
1122 Other alphanumeric characters mean a new window which uses the provided
1123 character for its class and name. Eg 'H[a b]' will open windows with classes 'a'
1124 and 'b' inside a horizontal split. Windows use a single character for their
1125 class, eg 'H[xxx]' will open 3 windows with class 'x'.
1126
1127 =item 4.
1128
1129 Asterisks after a window mean that the window must be focused after the layout
1130 is loaded. Currently, focusing non-leaf containers must be done manually, in the
1131 callback (C<cb>) function.
1132
1133 =back
1134
1135 =item cb
1136
1137 Subroutine to be called after the layout provided by C<layout_before> is created
1138 but before the resulting layout (C<layout_after>) is checked.
1139
1140 =item layout_after
1141
1142 Required argument. The final layout in which the tree is expected to be after
1143 the callback is called. Uses the same syntax with C<layout_before>.
1144 For non-leaf containers, their layout (horizontal, vertical, stacked, tabbed)
1145 is compared with the corresponding letter (H, V, S, T).
1146 For leaf containers, their name is compared with the provided alphanumeric.
1147
1148 =item ws
1149
1150 The workspace in which the layout will be created. Will switch focus to it. If
1151 not provided, a new one is created.
1152
1153 =item msg
1154
1155 Message to prepend to the subtest's name. If not empty, it will be followed by ': '.
1156
1157 =item dont_kill
1158
1159 By default, all windows are killed before the C<layout_before> layout is loaded.
1160 Set to 1 to avoid this.
1161
1162 =back
1163
1164 =cut
1165 sub cmp_tree {
1166 local $Test::Builder::Level = $Test::Builder::Level + 1;
1167
1168 my %args = @_;
1169 my $ws = $args{ws};
1170 if (defined($ws)) {
1171 cmd "workspace $ws";
1172 } else {
1173 $ws = fresh_workspace;
1174 }
1175 my $msg = '';
1176 if ($args{msg}) {
1177 $msg = $args{msg} . ': ';
1178 }
1179 die unless $args{layout_before};
1180 die unless $args{layout_after};
1181
1182 kill_all_windows unless $args{dont_kill};
1183 my @windows = create_layout($args{layout_before});
1184 Test::More::subtest $msg . $args{layout_before} . ' -> ' . $args{layout_after} => sub {
1185 $args{cb}->(\@windows) if $args{cb};
1186 verify_layout($args{layout_after}, $ws);
1187 };
1188
1189 return @windows;
1190 }
1191
1192 sub create_layout {
1193 my $layout = shift;
1194
1195 my $focus;
1196 my @windows = ();
1197 my $r = '';
1198 my $depth = 0;
1199 my %layout_counts = (H => 0, V => 0, S => 0, T => 0);
1200
1201 foreach my $char (split('', $layout)) {
1202 if ($char eq 'H') {
1203 $r = $r . '{"layout": "splith",';
1204 $r = $r . '"marks": ["H' . ++$layout_counts{H} . '"],';
1205 } elsif ($char eq 'V') {
1206 $r = $r . '{"layout": "splitv",';
1207 $r = $r . '"marks": ["V' . ++$layout_counts{V} . '"],';
1208 } elsif ($char eq 'S') {
1209 $r = $r . '{"layout": "stacked",';
1210 $r = $r . '"marks": ["S' . ++$layout_counts{S} . '"],';
1211 } elsif ($char eq 'T') {
1212 $r = $r . '{"layout": "tabbed",';
1213 $r = $r . '"marks": ["T' . ++$layout_counts{T} . '"],';
1214 } elsif ($char eq '[') {
1215 $depth++;
1216 $r = $r . '"nodes": [';
1217 } elsif ($char eq ']') {
1218 # End of nodes array: delete trailing comma.
1219 chop $r;
1220 # When we are at depth 0 we need to split using newlines, making
1221 # multiple "JSON texts".
1222 $depth--;
1223 $r = $r . ']}' . ($depth == 0 ? "\n" : ',');
1224 } elsif ($char eq ' ') {
1225 } elsif ($char eq '*') {
1226 $focus = $windows[$#windows];
1227 } elsif ($char =~ /[[:alnum:]]/) {
1228 push @windows, $char;
1229
1230 $r = $r . '{"swallows": [{';
1231 $r = $r . '"class": "^' . "$char" . '$"';
1232 $r = $r . '}]}' . ($depth == 0 ? "\n" : ',');
1233 } else {
1234 die "Could not understand $char";
1235 }
1236 }
1237
1238 die "Invalid layout, depth is $depth > 0" unless $depth == 0;
1239
1240 Test::More::diag($r);
1241 my ($fh, $tmpfile) = tempfile("layout-XXXXXX", UNLINK => 1);
1242 print $fh "$r\n";
1243 close($fh);
1244
1245 my $return = cmd "append_layout $tmpfile";
1246 die 'Could not parse layout json file' unless $return->[0]->{success};
1247
1248 my @result_windows;
1249 push @result_windows, open_window(wm_class => "$_", name => "$_") foreach @windows;
1250 cmd '[class=' . $focus . '] focus' if $focus;
1251
1252 return @result_windows;
1253 }
1254
1255 sub verify_layout {
1256 my ($layout, $ws) = @_;
1257
1258 my $nodes = get_ws_content($ws);
1259 my %counters;
1260 my $depth = 0;
1261 my $node;
1262
1263 foreach my $char (split('', $layout)) {
1264 my $node_name;
1265 my $node_layout;
1266 if ($char eq 'H') {
1267 $node_layout = 'splith';
1268 } elsif ($char eq 'V') {
1269 $node_layout = 'splitv';
1270 } elsif ($char eq 'S') {
1271 $node_layout = 'stacked';
1272 } elsif ($char eq 'T') {
1273 $node_layout = 'tabbed';
1274 } elsif ($char eq '[') {
1275 $depth++;
1276 delete $counters{$depth};
1277 } elsif ($char eq ']') {
1278 $depth--;
1279 } elsif ($char eq ' ') {
1280 } elsif ($char eq '*') {
1281 $tester->is_eq($node->{focused}, 1, 'Correct node focused');
1282 } elsif ($char =~ /[[:alnum:]]/) {
1283 $node_name = $char;
1284 } else {
1285 die "Could not understand $char";
1286 }
1287
1288 if ($node_layout || $node_name) {
1289 if (exists($counters{$depth})) {
1290 $counters{$depth} = $counters{$depth} + 1;
1291 } else {
1292 $counters{$depth} = 0;
1293 }
1294
1295 $node = $nodes->[$counters{0}];
1296 for my $i (1 .. $depth) {
1297 $node = $node->{nodes}->[$counters{$i}];
1298 }
1299
1300 if ($node_layout) {
1301 $tester->is_eq($node->{layout}, $node_layout, "Layouts match in depth $depth, node number " . $counters{$depth});
1302 } else {
1303 $tester->is_eq($node->{name}, $node_name, "Names match in depth $depth, node number " . $counters{$depth});
1304 }
1305 }
1306 }
1307 }
1308
1309
1310
1311 =head1 AUTHOR
1312
1313 Michael Stapelberg <[email protected]>
1314
1315 =cut
1316
1317 package i3test::X11;
1318 use parent 'X11::XCB::Connection';
1319
1320 sub input_focus {
1321 my $self = shift;
1322 i3test::sync_with_i3();
1323
1324 return $self->SUPER::input_focus(@_);
1325 }
1326
1327 1
0 #!/usr/bin/env perl
1 # vim:ts=4:sw=4:expandtab
2 # © 2012 Michael Stapelberg and contributors
3 # Script to create a new testcase from a template.
4 #
5 # # Create (and edit) a new test for moving floating windows
6 # ./new-test floating move
7 #
8 # # Create (and edit) a multi-monitor test for moving workspaces
9 # ./new-test -m move workspaces
10
11 use strict;
12 use warnings;
13 use File::Basename qw(basename);
14 use Getopt::Long;
15 use v5.10;
16
17 my $usage = <<'EOF';
18 Script to create a new testcase from a template.
19
20 # Create (and edit) a new test for moving floating windows
21 ./new-test floating move
22
23 # Create (and edit) a multi-monitor test for moving workspaces
24 ./new-test -m move workspaces
25 EOF
26
27 my $multi_monitor;
28
29 my $result = GetOptions(
30 'multi-monitor|mm' => \$multi_monitor
31 );
32
33 my $testname = join(' ', @ARGV);
34 $testname =~ s/ /-/g;
35
36 unless (length $testname) {
37 say $usage;
38 exit(0);
39 }
40
41 my $header = <<'EOF';
42 #!perl
43 # vim:ts=4:sw=4:expandtab
44 #
45 # Please read the following documents before working on tests:
46 # • https://build.i3wm.org/docs/testsuite.html
47 # (or docs/testsuite)
48 #
49 # • https://build.i3wm.org/docs/lib-i3test.html
50 # (alternatively: perldoc ./testcases/lib/i3test.pm)
51 #
52 # • https://build.i3wm.org/docs/ipc.html
53 # (or docs/ipc)
54 #
55 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
56 # (unless you are already familiar with Perl)
57 #
58 # TODO: Description of this file.
59 # Ticket: #999
60 # Bug still in: #GITREV#
61 EOF
62
63 # Figure out the next test filename.
64 my @files;
65 if ($multi_monitor) {
66 @files = grep { basename($_) =~ /^5/ } <t/*.t>;
67 } else {
68 @files = grep { basename($_) !~ /^5/ } <t/*.t>;
69 }
70 my ($latest) = sort { $b cmp $a } @files;
71 my ($num) = (basename($latest) =~ /^([0-9]+)/);
72 my $filename = "t/" . ($num+1) . "-" . lc($testname) . ".t";
73
74 # Get the current git revision.
75 chomp(my $gitrev = qx(git describe --tags));
76 $header =~ s/#GITREV#/$gitrev/g;
77
78 # Create the file based on our template.
79 open(my $fh, '>', $filename);
80 print $fh $header;
81 if ($multi_monitor) {
82 print $fh <<'EOF';
83 use i3test i3_autostart => 0;
84
85 my $config = <<EOT;
86 # i3 config file (v4)
87 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
88
89 fake-outputs 1024x768+0+0,1024x768+1024+0
90 EOT
91
92 my $pid = launch_with_config($config);
93
94
95 exit_gracefully($pid);
96
97 done_testing;
98 EOF
99 } else {
100 print $fh <<'EOF';
101 use i3test;
102
103
104 done_testing;
105 EOF
106 }
107 close($fh);
108
109 my $editor = $ENV{EDITOR};
110 $editor ||= 'vi';
111 exec $editor, $filename;
0 {"id":6752976,"type":0,"orientation":"none","percent":null,"urgent":false,"focused":false,"layout":"default","border":"none","rect":{"x":0,"y":0,"width":1280,"height":1024},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"root","window":null,"nodes":[{"id":6809472,"type":1,"orientation":"none","percent":1,"urgent":false,"focused":false,"layout":"output","border":"none","rect":{"x":0,"y":0,"width":1280,"height":1024},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"xroot-0","window":null,"nodes":[{"id":6810064,"type":5,"orientation":"vertical","percent":null,"urgent":false,"focused":false,"layout":"dockarea","border":"none","rect":{"x":0,"y":0,"width":1280,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"topdock","window":null,"nodes":[],"floating_nodes":[],"focus":[],"fullscreen_mode":0,"swallows":[{"dock":2,"insert_where":2}]},{"id":6831664,"type":2,"orientation":"none","percent":null,"urgent":false,"focused":false,"layout":"default","border":"none","rect":{"x":0,"y":0,"width":1280,"height":1024},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"content","window":null,"nodes":[{"id":6832880,"type":4,"orientation":"horizontal","percent":null,"urgent":false,"focused":true,"layout":"default","border":"none","rect":{"x":0,"y":0,"width":1280,"height":1024},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"1","num":1,"window":null,"nodes":[],"floating_nodes":[],"focus":[],"fullscreen_mode":1,"swallows":[]}],"floating_nodes":[],"focus":[6832880],"fullscreen_mode":0,"swallows":[]},{"id":6832224,"type":5,"orientation":"vertical","percent":null,"urgent":false,"focused":false,"layout":"dockarea","border":"none","rect":{"x":0,"y":1024,"width":1280,"height":0},"window_rect":{"x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"bottomdock","window":null,"nodes":[],"floating_nodes":[],"focus":[],"fullscreen_mode":0,"swallows":[{"dock":3,"insert_where":2}]}],"floating_nodes":[],"focus":[6831664,6810064,6832224],"fullscreen_mode":0,"swallows":[]}],"floating_nodes":[],"focus":[6809472],"fullscreen_mode":0,"swallows":[]}
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2
3 use Test::More;
4
5 BEGIN {
6 my @deps = qw(
7 X11::XCB::Connection
8 X11::XCB::Window
9 AnyEvent
10 IPC::Run
11 ExtUtils::PkgConfig
12 Inline
13 );
14 for my $dep (@deps) {
15 use_ok($dep) or BAIL_OUT(qq|The Perl module "$dep" could not be loaded. Please see https://build.i3wm.org/docs/testsuite.html#_installing_the_dependencies|);
16 }
17 }
18
19 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17
18 my $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
19
20 my $window = open_window(rect => $original_rect, dont_map => 1);
21 isa_ok($window, 'X11::XCB::Window');
22
23 is_deeply($window->rect, $original_rect, "rect unmodified before mapping");
24
25 $window->map;
26 wait_for_map $window;
27
28 my $new_rect = $window->rect;
29 ok(!eq_hash($new_rect, $original_rect), "Window got repositioned");
30
31 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # checks if i3 supports I3_SYNC
17 #
18 use i3test;
19
20 my $result = sync_with_i3;
21 ok($result, 'syncing was successful');
22
23 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17
18 fresh_workspace;
19
20 #####################################################################
21 # Ensure IPC works by switching workspaces
22 #####################################################################
23
24 # Create a window so we can get a focus different from NULL
25 my $window = open_window;
26
27 my $focus = $x->input_focus;
28
29 # Switch to another workspace
30 fresh_workspace;
31
32 sync_with_i3;
33 my $new_focus = $x->input_focus;
34 isnt($focus, $new_focus, "Focus changed");
35
36 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17
18 my $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
19
20 my $window = open_window(
21 rect => $original_rect,
22 override_redirect => 1,
23 dont_map => 1,
24 );
25
26 isa_ok($window, 'X11::XCB::Window');
27
28 is_deeply($window->rect, $original_rect, "rect unmodified before mapping");
29
30 $window->map;
31
32 my $new_rect = $window->rect;
33 isa_ok($new_rect, 'X11::XCB::Rect');
34
35 is_deeply($new_rect, $original_rect, "window untouched");
36
37 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17
18 # Create a floating window which is smaller than the minimum enforced size of i3
19 my $window = open_floating_window;
20
21 isa_ok($window, 'X11::XCB::Window');
22
23 my ($absolute, $top) = $window->rect;
24
25 ok($window->mapped, 'Window is mapped');
26 cmp_ok($absolute->{width}, '>=', 75, 'i3 raised the width to 75');
27 cmp_ok($absolute->{height}, '>=', 50, 'i3 raised the height to 50');
28
29 ok($absolute->{x} != 0 && $absolute->{y} != 0, 'i3 did not map it to (0x0)');
30
31 $window->unmap;
32
33 $window = open_floating_window(rect => [ 20, 20, 80, 90 ]);
34
35 isa_ok($window, 'X11::XCB::Window');
36
37 ($absolute, $top) = $window->rect;
38
39 cmp_ok($absolute->{width}, '==', 80, "i3 let the width at 80");
40 cmp_ok($absolute->{height}, '==', 90, "i3 let the height at 90");
41
42 cmp_ok($top->{x}, '==', 20, 'i3 mapped it to x=20');
43 cmp_ok($top->{y}, '==', 20, 'i3 mapped it to y=20');
44
45 $window->unmap;
46
47 #####################################################################
48 # check that a tiling window which is then made floating still has
49 # at least the size of its initial geometry
50 #####################################################################
51
52 $window = open_window(rect => [ 1, 1, 80, 90 ]);
53
54 isa_ok($window, 'X11::XCB::Window');
55
56 cmd 'floating enable';
57 sync_with_i3;
58
59 ($absolute, $top) = $window->rect;
60
61 cmp_ok($absolute->{width}, '==', 80, "i3 let the width at 80");
62 cmp_ok($absolute->{height}, '==', 90, "i3 let the height at 90");
63
64 $window->unmap;
65
66 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17 use List::Util qw(first);
18
19 my $i3 = i3(get_socket_path());
20
21 my $tmp = fresh_workspace;
22
23 # get the output of this workspace
24 my $tree = $i3->get_tree->recv;
25 my @outputs = @{$tree->{nodes}};
26 my $output;
27 for my $o (@outputs) {
28 # get the first CT_CON of each output
29 my $content = first { $_->{type} eq 'con' } @{$o->{nodes}};
30 if (defined(first { $_->{name} eq $tmp } @{$content->{nodes}})) {
31 $output = $o;
32 last;
33 }
34 }
35
36 ##################################
37 # map a window, then fullscreen it
38 ##################################
39
40 my $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
41
42 my $window = open_window(
43 rect => $original_rect,
44 dont_map => 1,
45 );
46
47 isa_ok($window, 'X11::XCB::Window');
48
49 is_deeply($window->rect, $original_rect, "rect unmodified before mapping");
50
51 $window->map;
52
53 wait_for_map $window;
54
55 # open another container to make the window get only half of the screen
56 cmd 'open';
57
58 my $new_rect = $window->rect;
59 ok(!eq_hash($new_rect, $original_rect), "Window got repositioned");
60 $original_rect = $new_rect;
61
62 $window->fullscreen(1);
63
64 sync_with_i3;
65
66 $new_rect = $window->rect;
67 ok(!eq_hash($new_rect, $original_rect), "Window got repositioned after fullscreen");
68
69 my $orect = $output->{rect};
70 my $wrect = $new_rect;
71
72 # see if the window really is fullscreen. 20 px for borders are allowed
73 my $threshold = 20;
74 ok(($wrect->{x} - $orect->{x}) < $threshold, 'x coordinate fullscreen');
75 ok(($wrect->{y} - $orect->{y}) < $threshold, 'y coordinate fullscreen');
76 ok(abs($wrect->{width} - $orect->{width}) < $threshold, 'width coordinate fullscreen');
77 ok(abs($wrect->{height} - $orect->{height}) < $threshold, 'height coordinate fullscreen');
78
79
80 $window->unmap;
81
82 #########################################################
83 # test with a window which is fullscreened before mapping
84 #########################################################
85
86 # open another container because the empty one will swallow the window we
87 # map in a second
88 cmd 'open';
89
90 $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
91 $window = open_window(
92 rect => $original_rect,
93 dont_map => 1,
94 );
95
96 is_deeply($window->rect, $original_rect, "rect unmodified before mapping");
97
98 $window->fullscreen(1);
99 $window->map;
100
101 wait_for_map $window;
102
103 $new_rect = $window->rect;
104 ok(!eq_hash($new_rect, $original_rect), "Window got repositioned after fullscreen");
105 ok($window->mapped, "Window is mapped after opening it in fullscreen mode");
106
107 $wrect = $new_rect;
108
109 # see if the window really is fullscreen. 20 px for borders are allowed
110 ok(($wrect->{x} - $orect->{x}) < $threshold, 'x coordinate fullscreen');
111 ok(($wrect->{y} - $orect->{y}) < $threshold, 'y coordinate fullscreen');
112 ok(abs($wrect->{width} - $orect->{width}) < $threshold, 'width coordinate fullscreen');
113 ok(abs($wrect->{height} - $orect->{height}) < $threshold, 'height coordinate fullscreen');
114
115 ################################################################################
116 # Verify that when one window wants to go into fullscreen mode, the old
117 # fullscreen window will be replaced.
118 ################################################################################
119
120 $original_rect = X11::XCB::Rect->new(x => 0, y => 0, width => 30, height => 30);
121 my $swindow = open_window(
122 rect => $original_rect,
123 dont_map => 1,
124 );
125
126 $swindow->map;
127
128 sync_with_i3;
129
130 ok(!$swindow->mapped, 'window not mapped while fullscreen window active');
131
132 $new_rect = $swindow->rect;
133 ok(!eq_hash($new_rect, $original_rect), "Window got repositioned");
134
135 $swindow->fullscreen(1);
136 sync_with_i3;
137
138 is_num_fullscreen($tmp, 1, 'amount of fullscreen windows');
139
140 $window->fullscreen(0);
141 sync_with_i3;
142 is_num_fullscreen($tmp, 1, 'amount of fullscreen windows');
143
144 ok($swindow->mapped, 'window mapped after other fullscreen ended');
145
146 ###########################################################################
147 # as $swindow is out of state at the moment (it requested to be fullscreen,
148 # but the WM denied), we check what happens if we go out of fullscreen now
149 # (nothing should happen)
150 ###########################################################################
151
152 $swindow->fullscreen(0);
153 sync_with_i3;
154
155 is_num_fullscreen($tmp, 0, 'amount of fullscreen windows after disabling');
156
157 cmd 'fullscreen';
158
159 is_num_fullscreen($tmp, 1, 'amount of fullscreen windows after fullscreen command');
160
161 cmd 'fullscreen';
162
163 is_num_fullscreen($tmp, 0, 'amount of fullscreen windows after fullscreen command');
164
165 # clean up the workspace so that it will be cleaned when switching away
166 cmd 'kill' for (@{get_ws_content($tmp)});
167
168 ################################################################################
169 # Verify that changing focus while in fullscreen does not work.
170 ################################################################################
171
172 $tmp = fresh_workspace;
173
174 my $other = open_window;
175 is($x->input_focus, $other->id, 'other window focused');
176
177 $window = open_window;
178 is($x->input_focus, $window->id, 'window focused');
179
180 cmd 'fullscreen';
181 is($x->input_focus, $window->id, 'fullscreen window focused');
182
183 cmd 'focus left';
184 is($x->input_focus, $window->id, 'fullscreen window still focused');
185
186 ################################################################################
187 # Verify that changing workspace while in global fullscreen does not work.
188 ################################################################################
189
190 $tmp = fresh_workspace;
191 $window = open_window;
192
193 cmd 'fullscreen global';
194 is($x->input_focus, $window->id, 'window focused');
195 is(focused_ws(), $tmp, 'workspace selected');
196
197 $other = get_unused_workspace;
198 cmd "workspace $other";
199 is($x->input_focus, $window->id, 'window still focused');
200 is(focused_ws(), $tmp, 'workspace still selected');
201
202 # leave global fullscreen so that is does not interfere with the other tests
203 $window->fullscreen(0);
204 sync_with_i3;
205
206 ################################################################################
207 # Verify that fullscreening a window on a second workspace and moving it onto
208 # the first workspace unfullscreens the first window.
209 ################################################################################
210
211 my $tmp2 = fresh_workspace;
212 $swindow = open_window;
213
214 cmd 'fullscreen';
215
216 is_num_fullscreen($tmp2, 1, 'one fullscreen window on second ws');
217
218 cmd "move workspace $tmp";
219
220 is_num_fullscreen($tmp2, 0, 'no fullscreen windows on second ws');
221 is_num_fullscreen($tmp, 1, 'one fullscreen window on first ws');
222
223 $swindow->fullscreen(0);
224 sync_with_i3;
225
226 # Verify that $swindow was the one that initially remained fullscreen.
227 is_num_fullscreen($tmp, 0, 'no fullscreen windows on first ws');
228
229 ################################################################################
230 # Verify that opening a window with _NET_WM_STATE_FULLSCREEN unfullscreens any
231 # existing container on the workspace and fullscreens the newly opened window.
232 ################################################################################
233
234 $tmp = fresh_workspace;
235
236 $window = open_window();
237
238 cmd "fullscreen";
239
240 is_num_fullscreen($tmp, 1, 'one fullscreen window on ws');
241 is($x->input_focus, $window->id, 'fullscreen window focused');
242
243 $swindow = open_window({
244 fullscreen => 1
245 });
246
247 is_num_fullscreen($tmp, 1, 'one fullscreen window on ws');
248 is($x->input_focus, $swindow->id, 'fullscreen window focused');
249
250 ################################################################################
251 # Verify that command ‘fullscreen enable’ works and is idempotent.
252 ################################################################################
253
254 $tmp = fresh_workspace;
255
256 $window = open_window;
257 is($x->input_focus, $window->id, 'window focused');
258 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
259
260 cmd 'fullscreen enable';
261 is($x->input_focus, $window->id, 'window still focused');
262 is_num_fullscreen($tmp, 1, 'one fullscreen window on workspace');
263
264 cmd 'fullscreen enable';
265 is($x->input_focus, $window->id, 'window still focused');
266 is_num_fullscreen($tmp, 1, 'still one fullscreen window on workspace');
267
268 $window->fullscreen(0);
269 sync_with_i3;
270 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
271
272 ################################################################################
273 # Verify that command ‘fullscreen enable global’ works and is idempotent.
274 ################################################################################
275
276 $tmp = fresh_workspace;
277
278 $window = open_window;
279 is($x->input_focus, $window->id, 'window focused');
280 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
281
282 cmd 'fullscreen enable global';
283 is($x->input_focus, $window->id, 'window still focused');
284 is_num_fullscreen($tmp, 1, 'one fullscreen window on workspace');
285
286 cmd 'fullscreen enable global';
287 is($x->input_focus, $window->id, 'window still focused');
288 is_num_fullscreen($tmp, 1, 'still one fullscreen window on workspace');
289
290 $window->fullscreen(0);
291 sync_with_i3;
292 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
293
294 ################################################################################
295 # Verify that command ‘fullscreen disable’ works and is idempotent.
296 ################################################################################
297
298 $tmp = fresh_workspace;
299
300 $window = open_window;
301 is($x->input_focus, $window->id, 'window focused');
302 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
303
304 $window->fullscreen(1);
305 sync_with_i3;
306 is_num_fullscreen($tmp, 1, 'one fullscreen window on workspace');
307
308 cmd 'fullscreen disable';
309 is($x->input_focus, $window->id, 'window still focused');
310 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
311
312 cmd 'fullscreen disable';
313 is($x->input_focus, $window->id, 'window still focused');
314 is_num_fullscreen($tmp, 0, 'still no fullscreen window on workspace');
315
316 ################################################################################
317 # Verify that command ‘fullscreen toggle’ works.
318 ################################################################################
319
320 $tmp = fresh_workspace;
321
322 $window = open_window;
323 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
324
325 cmd 'fullscreen toggle';
326 is($x->input_focus, $window->id, 'window still focused');
327 is_num_fullscreen($tmp, 1, 'one fullscreen window on workspace');
328
329 cmd 'fullscreen toggle';
330 is($x->input_focus, $window->id, 'window still focused');
331 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
332
333 ################################################################################
334 # Verify that a window’s fullscreen is disabled when another one is enabled
335 # on the same workspace. The new fullscreen window should be focused.
336 ################################################################################
337
338 $tmp = fresh_workspace;
339
340 $window = open_window;
341 $other = open_window;
342
343 is($x->input_focus, $other->id, 'other window focused');
344 is_num_fullscreen($tmp, 0, 'no fullscreen window on workspace');
345
346 cmd 'fullscreen enable';
347 is($x->input_focus, $other->id, 'other window focused');
348 is_num_fullscreen($tmp, 1, 'one fullscreen window on workspace');
349
350 cmd '[id="' . $window->id . '"] fullscreen enable';
351 is($x->input_focus, $window->id, 'window focused');
352 is_num_fullscreen($tmp, 1, 'one fullscreen window on workspace');
353
354 ################################################################################
355 # Verify that when a global fullscreen is enabled the window is focused and
356 # its workspace is selected, so that disabling the fullscreen keeps the window
357 # focused and visible.
358 ################################################################################
359
360 $tmp = fresh_workspace;
361
362 $window = open_window;
363
364 is($x->input_focus, $window->id, 'window focused');
365
366 cmd 'workspace ' . get_unused_workspace;
367 isnt($x->input_focus, $window->id, 'window not focused');
368 isnt(focused_ws(), $tmp, 'workspace not selected');
369
370 cmd '[id="' . $window->id . '"] fullscreen enable global';
371 is($x->input_focus, $window->id, 'window focused');
372
373 cmd 'fullscreen disable';
374 is($x->input_focus, $window->id, 'window still focused');
375 is(focused_ws(), $tmp, 'workspace selected');
376
377 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17
18 my $tmp = fresh_workspace;
19
20 #####################################################################
21 # Create two windows and make sure focus switching works
22 #####################################################################
23
24 # Change mode of the container to "default" for following tests
25 cmd 'layout default';
26 cmd 'split v';
27
28 my $top = open_window;
29 my $mid = open_window;
30 my $bottom = open_window;
31
32 #
33 # Returns the input focus after sending the given command to i3 via IPC
34 # end sleeping for half a second to make sure i3 reacted
35 #
36 sub focus_after {
37 my ($msg, $win_id) = @_;
38
39 if (defined($win_id)) {
40 cmd "[id=$win_id] $msg";
41 } else {
42 cmd $msg;
43 }
44 return $x->input_focus;
45 }
46
47 my $focus = $x->input_focus;
48 is($focus, $bottom->id, "Latest window focused");
49
50 $focus = focus_after('focus up');
51 is($focus, $mid->id, "Middle window focused");
52
53 $focus = focus_after('focus up');
54 is($focus, $top->id, "Top window focused");
55
56 # Same using command criteria
57 $focus = focus_after('focus up', $bottom->id);
58 is($focus, $mid->id, "Middle window focused");
59
60 cmd 'focus down';
61 $focus = focus_after('focus up', $mid->id);
62 is($focus, $top->id, "Top window focused");
63
64 #####################################################################
65 # Test focus wrapping
66 #####################################################################
67
68 $focus = focus_after('focus up');
69 is($focus, $bottom->id, "Bottom window focused (wrapping to the top works)");
70
71 $focus = focus_after('focus down');
72 is($focus, $top->id, "Top window focused (wrapping to the bottom works)");
73
74 #####################################################################
75 # Test focus is only successful if there was a window that could be
76 # matched.
77 #####################################################################
78
79 my $result = cmd '[con_mark=__does_not_exist] focus';
80 is($result->[0]->{success}, 0, 'focus is unsuccessful if no window was matched');
81
82 #####################################################################
83
84 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17 use X11::XCB 'PROP_MODE_REPLACE';
18 use List::Util qw(first);
19
20 #####################################################################
21 # verify that there is no dock window yet
22 #####################################################################
23
24 # Children of all dockareas
25 my @docked = get_dock_clients;
26 is(@docked, 0, 'no dock clients yet');
27
28 #####################################################################
29 # Create a dock window and see if it gets managed
30 #####################################################################
31
32 my $screens = $x->screens;
33
34 # Get the primary screen
35 my $primary = first { $_->primary } @{$screens};
36
37 # TODO: focus the primary screen before
38 my $window = open_window({
39 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
40 });
41
42 my $rect = $window->rect;
43 is($rect->width, $primary->rect->width, 'dock client is as wide as the screen');
44 is($rect->height, 30, 'height is unchanged');
45
46 #####################################################################
47 # check that we can find it in the layout tree at the expected position
48 #####################################################################
49
50 @docked = get_dock_clients('top');
51 is(@docked, 1, 'one dock client found');
52
53 # verify the position/size
54 my $docknode = $docked[0];
55
56 is($docknode->{rect}->{x}, 0, 'dock node placed at x=0');
57 is($docknode->{rect}->{y}, 0, 'dock node placed at y=0');
58 is($docknode->{rect}->{width}, $primary->rect->width, 'dock node as wide as the screen');
59 is($docknode->{rect}->{height}, 30, 'dock node has unchanged height');
60
61 #####################################################################
62 # check that re-configuring the height works
63 #####################################################################
64
65 $window->rect(X11::XCB::Rect->new(x => 0, y => 0, width => 50, height => 40));
66
67 sync_with_i3;
68
69 @docked = get_dock_clients('top');
70 is(@docked, 1, 'one dock client found');
71
72 # verify the position/size
73 $docknode = $docked[0];
74
75 is($docknode->{rect}->{x}, 0, 'dock node placed at x=0');
76 is($docknode->{rect}->{y}, 0, 'dock node placed at y=0');
77 is($docknode->{rect}->{width}, $primary->rect->width, 'dock node as wide as the screen');
78 is($docknode->{rect}->{height}, 40, 'dock height changed');
79
80 $window->destroy;
81
82 wait_for_unmap $window;
83
84 @docked = get_dock_clients();
85 is(@docked, 0, 'no more dock clients');
86
87 #####################################################################
88 # check if it gets placed on bottom (by coordinates)
89 #####################################################################
90
91 $window = open_window({
92 rect => [ 0, 1000, 30, 30 ],
93 background_color => '#FF0000',
94 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
95 });
96
97 $rect = $window->rect;
98 is($rect->width, $primary->rect->width, 'dock client is as wide as the screen');
99 is($rect->height, 30, 'height is unchanged');
100
101 @docked = get_dock_clients('bottom');
102 is(@docked, 1, 'dock client on bottom');
103
104 $window->destroy;
105
106 wait_for_unmap $window;
107
108 @docked = get_dock_clients();
109 is(@docked, 0, 'no more dock clients');
110
111 #####################################################################
112 # check if it gets placed on bottom (by hint)
113 #####################################################################
114
115 $window = open_window({
116 dont_map => 1,
117 rect => [ 0, 1000, 30, 30 ],
118 background_color => '#FF0000',
119 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
120 });
121
122 $window->_create();
123
124 # Add a _NET_WM_STRUT_PARTIAL hint
125 my $atomname = $x->atom(name => '_NET_WM_STRUT_PARTIAL');
126 my $atomtype = $x->atom(name => 'CARDINAL');
127
128 $x->change_property(
129 PROP_MODE_REPLACE,
130 $window->id,
131 $atomname->id,
132 $atomtype->id,
133 32, # 32 bit integer
134 12,
135 pack('L12', 0, 0, 16, 0, 0, 0, 0, 0, 0, 1280, 0, 0)
136 );
137
138 $window->map;
139
140 wait_for_map $window;
141
142 @docked = get_dock_clients('top');
143 is(@docked, 1, 'dock client on top');
144
145 # now change strut_partial to reserve space on the bottom and the dock should
146 # be moved to the bottom dock area
147 $x->change_property(
148 PROP_MODE_REPLACE,
149 $window->id,
150 $atomname->id,
151 $atomtype->id,
152 32, # 32 bit integer
153 12,
154 pack('L12', 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 1280, 0)
155 );
156
157 sync_with_i3;
158 @docked = get_dock_clients('bottom');
159 is(@docked, 1, 'dock client on bottom');
160
161 $window->destroy;
162
163 wait_for_unmap $window;
164
165 @docked = get_dock_clients();
166 is(@docked, 0, 'no more dock clients');
167
168 $window = open_window({
169 dont_map => 1,
170 rect => [ 0, 1000, 30, 30 ],
171 background_color => '#FF0000',
172 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
173 });
174
175 $window->_create();
176
177 # Add a _NET_WM_STRUT_PARTIAL hint
178 $atomname = $x->atom(name => '_NET_WM_STRUT_PARTIAL');
179 $atomtype = $x->atom(name => 'CARDINAL');
180
181 $x->change_property(
182 PROP_MODE_REPLACE,
183 $window->id,
184 $atomname->id,
185 $atomtype->id,
186 32, # 32 bit integer
187 12,
188 pack('L12', 0, 0, 0, 16, 0, 0, 0, 0, 0, 1280, 0, 0)
189 );
190
191 $window->map;
192
193 wait_for_map $window;
194
195 @docked = get_dock_clients('bottom');
196 is(@docked, 1, 'dock client on bottom');
197
198 $window->destroy;
199
200
201 #####################################################################
202 # regression test: transient dock client
203 #####################################################################
204
205 my $fwindow = open_window({
206 dont_map => 1,
207 background_color => '#FF0000',
208 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
209 });
210
211 $fwindow->transient_for($window);
212 $fwindow->map;
213
214 wait_for_map $fwindow;
215
216 does_i3_live;
217
218 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Checks if the focus is correctly restored, when creating a floating client
17 # over an unfocused tiling client and destroying the floating one again.
18
19 use i3test;
20
21 fresh_workspace;
22
23 cmd 'split h';
24 my $tiled_left = open_window;
25 my $tiled_right = open_window;
26
27 # Get input focus before creating the floating window
28 my $focus = $x->input_focus;
29
30 # Create a floating window which is smaller than the minimum enforced size of i3
31 my $window = open_floating_window;
32
33 is($x->input_focus, $window->id, 'floating window focused');
34
35 $window->unmap;
36
37 wait_for_unmap $window;
38
39 is($x->input_focus, $focus, 'Focus correctly restored');
40
41 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17 use File::Temp;
18
19 my $tmp = fresh_workspace;
20
21 cmd 'split h';
22
23 #####################################################################
24 # Create two windows and make sure focus switching works
25 #####################################################################
26
27 my $top = open_window;
28 my $mid = open_window;
29 my $bottom = open_window;
30
31 #
32 # Returns the input focus after sending the given command to i3 via IPC
33 # and syncing with i3
34 #
35 sub focus_after {
36 my $msg = shift;
37
38 cmd $msg;
39 return $x->input_focus;
40 }
41
42 my $focus = $x->input_focus;
43 is($focus, $bottom->id, "Latest window focused");
44
45 $focus = focus_after('focus left');
46 is($focus, $mid->id, "Middle window focused");
47
48 #####################################################################
49 # Now goto a mark which does not exist
50 #####################################################################
51
52 my $random_mark = mktemp('mark.XXXXXX');
53
54 $focus = focus_after(qq|[con_mark="$random_mark"] focus|);
55 is($focus, $mid->id, "focus unchanged");
56
57 cmd "mark $random_mark";
58
59 $focus = focus_after('focus left');
60 is($focus, $top->id, "Top window focused");
61
62 $focus = focus_after(qq|[con_mark="$random_mark"] focus|);
63 is($focus, $mid->id, "goto worked");
64
65 # check that we can specify multiple criteria
66
67 $focus = focus_after('focus left');
68 is($focus, $top->id, "Top window focused");
69
70 $focus = focus_after(qq|[con_mark="$random_mark" con_mark="$random_mark"] focus|);
71 is($focus, $mid->id, "goto worked");
72
73 #####################################################################
74 # Set the same mark multiple times and see if focus works correctly
75 #####################################################################
76
77 $focus = focus_after('focus left');
78 is($focus, $top->id, "Top window focused");
79
80 cmd "mark $random_mark";
81
82 $focus = focus_after(qq|[con_mark="$random_mark"] focus|);
83 is($focus, $top->id, "focus unchanged after goto");
84
85 $focus = focus_after('focus right');
86 is($focus, $mid->id, "mid window focused");
87
88 $focus = focus_after(qq|[con_mark="$random_mark"] focus|);
89 is($focus, $top->id, "goto worked");
90
91 #####################################################################
92 # Check whether the focus command will switch to a different
93 # workspace if necessary
94 #####################################################################
95
96 my $tmp2 = fresh_workspace;
97
98 is(focused_ws(), $tmp2, 'tmp2 now focused');
99
100 cmd qq|[con_mark="$random_mark"] focus|;
101
102 is(focused_ws(), $tmp, 'tmp now focused');
103
104 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17
18 fresh_workspace;
19
20 #####################################################################
21 # Create a floating window and see if resizing works
22 #####################################################################
23
24 my $window = open_floating_window;
25
26 # See if configurerequests cause window movements (they should not)
27 my ($a, $t) = $window->rect;
28 $window->rect(X11::XCB::Rect->new(x => $a->x, y => $a->y, width => $a->width, height => $a->height));
29
30 sync_with_i3;
31
32 my ($na, $nt) = $window->rect;
33 is_deeply($na, $a, 'Rects are equal after configurerequest');
34
35 sub test_resize {
36 $window->rect(X11::XCB::Rect->new(x => 0, y => 0, width => 100, height => 100));
37
38 sync_with_i3;
39
40 my ($absolute, $top) = $window->rect;
41
42 # Make sure the width/height are different from what we’re gonna test, so
43 # that the test will work.
44 isnt($absolute->width, 300, 'width != 300');
45 isnt($absolute->height, 500, 'height != 500');
46
47 $window->rect(X11::XCB::Rect->new(x => 0, y => 0, width => 300, height => 500));
48
49 sync_with_i3;
50
51 ($absolute, $top) = $window->rect;
52
53 is($absolute->width, 300, 'width = 300');
54 is($absolute->height, 500, 'height = 500');
55 }
56
57 # Test with default border
58 test_resize;
59
60 # Test borderless
61 cmd 'border none';
62
63 test_resize;
64
65 # Test with 1-px-border
66 cmd 'border 1pixel';
67
68 test_resize;
69
70 ################################################################################
71 # Check if we can position a floating window out of bounds. The Xephyr screen
72 # is 1280x1024, so x=2864, y=893 is out of bounds.
73 ################################################################################
74
75 ($a, $t) = $window->rect;
76 $window->rect(X11::XCB::Rect->new(
77 x => 2864,
78 y => 893,
79 width => $a->width,
80 height => $a->height));
81
82 sync_with_i3;
83
84 ($a, $t) = $window->rect;
85 cmp_ok($a->x, '<', 1280, 'X not moved out of bounds');
86 cmp_ok($a->y, '<', 1024, 'Y not moved out of bounds');
87
88 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test i3_autostart => 0;
17 use List::Util qw(first);
18
19 my $_NET_WM_STATE_REMOVE = 0;
20 my $_NET_WM_STATE_ADD = 1;
21 my $_NET_WM_STATE_TOGGLE = 2;
22
23 sub set_urgency {
24 my ($win, $urgent_flag, $type) = @_;
25 if ($type == 1) {
26 # Because X11::XCB does not keep track of clearing the urgency hint
27 # when receiving focus, we just delete it in all cases and then re-set
28 # it if appropriate.
29 $win->delete_hint('urgency');
30 $win->add_hint('urgency') if ($urgent_flag);
31 } elsif ($type == 2) {
32 my $msg = pack "CCSLLLLLL",
33 X11::XCB::CLIENT_MESSAGE, # response_type
34 32, # format
35 0, # sequence
36 $win->id, # window
37 $x->atom(name => '_NET_WM_STATE')->id, # message type
38 ($urgent_flag ? $_NET_WM_STATE_ADD : $_NET_WM_STATE_REMOVE), # data32[0]
39 $x->atom(name => '_NET_WM_STATE_DEMANDS_ATTENTION')->id, # data32[1]
40 0, # data32[2]
41 0, # data32[3]
42 0; # data32[4]
43
44 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
45 }
46 }
47
48 my $config = <<EOT;
49 # i3 config file (v4)
50 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
51
52 force_display_urgency_hint 0ms
53 EOT
54
55 my ($type, $tmp, $w1, $w2);
56 for ($type = 1; $type <= 2; $type++) {
57 my $pid = launch_with_config($config);
58 $tmp = fresh_workspace;
59
60 #####################################################################
61 # Create two windows and put them in stacking mode
62 #####################################################################
63
64 cmd 'split v';
65
66 my $top = open_window;
67 my $bottom = open_window;
68
69 my @urgent = grep { $_->{urgent} } @{get_ws_content($tmp)};
70 is(@urgent, 0, 'no window got the urgent flag');
71
72 # cmd 'layout stacking';
73
74 #####################################################################
75 # Add the urgency hint, switch to a different workspace and back again
76 #####################################################################
77 set_urgency($top, 1, $type);
78 sync_with_i3;
79
80 my @content = @{get_ws_content($tmp)};
81 @urgent = grep { $_->{urgent} } @content;
82 my $top_info = first { $_->{window} == $top->id } @content;
83 my $bottom_info = first { $_->{window} == $bottom->id } @content;
84
85 ok($top_info->{urgent}, 'top window is marked urgent');
86 ok(!$bottom_info->{urgent}, 'bottom window is not marked urgent');
87 is(@urgent, 1, 'exactly one window got the urgent flag');
88
89 cmd '[id="' . $top->id . '"] focus';
90
91 @urgent = grep { $_->{urgent} } @{get_ws_content($tmp)};
92 is(@urgent, 0, 'no window got the urgent flag after focusing');
93
94 set_urgency($top, 1, $type);
95 sync_with_i3;
96
97 @urgent = grep { $_->{urgent} } @{get_ws_content($tmp)};
98 is(@urgent, 0, 'no window got the urgent flag after re-setting urgency hint');
99
100 #####################################################################
101 # Check if the workspace urgency hint gets set/cleared correctly
102 #####################################################################
103
104 my $ws = get_ws($tmp);
105 ok(!$ws->{urgent}, 'urgent flag not set on workspace');
106
107 my $otmp = fresh_workspace;
108
109 set_urgency($top, 1, $type);
110 sync_with_i3;
111
112 $ws = get_ws($tmp);
113 ok($ws->{urgent}, 'urgent flag set on workspace');
114
115 cmd "workspace $tmp";
116
117 $ws = get_ws($tmp);
118 ok(!$ws->{urgent}, 'urgent flag not set on workspace after switching');
119
120 ################################################################################
121 # Use the 'urgent' criteria to switch to windows which have the urgency hint set.
122 ################################################################################
123
124 # Go to a new workspace, open a different window, verify focus is on it.
125 $otmp = fresh_workspace;
126 my $different_window = open_window;
127 is($x->input_focus, $different_window->id, 'new window focused');
128
129 # Add the urgency hint on the other window.
130 set_urgency($top, 1, $type);
131 sync_with_i3;
132
133 # Now try to switch to that window and see if focus changes.
134 cmd '[urgent=latest] focus';
135 isnt($x->input_focus, $different_window->id, 'window no longer focused');
136 is($x->input_focus, $top->id, 'urgent window focused');
137
138 ################################################################################
139 # Same thing, but with multiple windows and using the 'urgency=latest' criteria
140 # (verify that it works in the correct order).
141 ################################################################################
142
143 cmd "workspace $otmp";
144 is($x->input_focus, $different_window->id, 'new window focused again');
145
146 set_urgency($top, 1, $type);
147 sync_with_i3;
148
149 set_urgency($bottom, 1, $type);
150 sync_with_i3;
151
152 cmd '[urgent=latest] focus';
153 is($x->input_focus, $bottom->id, 'latest urgent window focused');
154 set_urgency($bottom, 0, $type);
155 sync_with_i3;
156
157 cmd '[urgent=latest] focus';
158 is($x->input_focus, $top->id, 'second urgent window focused');
159 set_urgency($top, 0, $type);
160 sync_with_i3;
161
162 ################################################################################
163 # Same thing, but with multiple windows and using the 'urgency=oldest' criteria
164 # (verify that it works in the correct order).
165 ################################################################################
166
167 cmd "workspace $otmp";
168 is($x->input_focus, $different_window->id, 'new window focused again');
169
170 set_urgency($top, 1, $type);
171 sync_with_i3;
172
173 set_urgency($bottom, 1, $type);
174 sync_with_i3;
175
176 cmd '[urgent=oldest] focus';
177 is($x->input_focus, $top->id, 'oldest urgent window focused');
178 set_urgency($top, 0, $type);
179 sync_with_i3;
180
181 cmd '[urgent=oldest] focus';
182 is($x->input_focus, $bottom->id, 'oldest urgent window focused');
183 set_urgency($bottom, 0, $type);
184 sync_with_i3;
185
186 ################################################################################
187 # Check if urgent flag gets propagated to parent containers
188 ################################################################################
189
190 cmd 'split v';
191
192
193
194 sub count_urgent {
195 my ($con) = @_;
196
197 my @children = (@{$con->{nodes}}, @{$con->{floating_nodes}});
198 my $urgent = grep { $_->{urgent} } @children;
199 $urgent += count_urgent($_) for @children;
200 return $urgent;
201 }
202
203 $tmp = fresh_workspace;
204
205 my $win1 = open_window;
206 my $win2 = open_window;
207 cmd 'layout stacked';
208 cmd 'split vertical';
209 my $win3 = open_window;
210 my $win4 = open_window;
211 cmd 'split horizontal' ;
212 my $win5 = open_window;
213 my $win6 = open_window;
214
215 sync_with_i3;
216
217
218 my $urgent = count_urgent(get_ws($tmp));
219 is($urgent, 0, 'no window got the urgent flag');
220
221 cmd '[id="' . $win2->id . '"] focus';
222 sync_with_i3;
223 set_urgency($win5, 1, $type);
224 set_urgency($win6, 1, $type);
225 sync_with_i3;
226
227 # we should have 5 urgent cons. win5, win6 and their 3 split parents.
228
229 $urgent = count_urgent(get_ws($tmp));
230 is($urgent, 5, '2 windows and 3 split containers got the urgent flag');
231
232 cmd '[id="' . $win5->id . '"] focus';
233 sync_with_i3;
234
235 # now win5 and still the split parents should be urgent.
236 $urgent = count_urgent(get_ws($tmp));
237 is($urgent, 4, '1 window and 3 split containers got the urgent flag');
238
239 cmd '[id="' . $win6->id . '"] focus';
240 sync_with_i3;
241
242 # now now window should be urgent.
243 $urgent = count_urgent(get_ws($tmp));
244 is($urgent, 0, 'All urgent flags got cleared');
245
246 ################################################################################
247 # Regression test: Check that urgent floating containers work properly (ticket
248 # #821)
249 ################################################################################
250
251 $tmp = fresh_workspace;
252 my $floating_win = open_floating_window;
253
254 # switch away
255 fresh_workspace;
256
257 set_urgency($floating_win, 1, $type);
258 sync_with_i3;
259
260 cmd "workspace $tmp";
261
262 does_i3_live;
263
264 ###############################################################################
265 # Check if the urgency hint is still set when the urgent window is killed
266 ###############################################################################
267
268 my $ws1 = fresh_workspace;
269 my $ws2 = fresh_workspace;
270 cmd "workspace $ws1";
271 $w1 = open_window;
272 $w2 = open_window;
273 cmd "workspace $ws2";
274 sync_with_i3;
275 set_urgency($w1, 1, $type);
276 sync_with_i3;
277 cmd '[id="' . $w1->id . '"] kill';
278 sync_with_i3;
279 my $w = get_ws($ws1);
280 is($w->{urgent}, 0, 'Urgent flag no longer set after killing the window ' .
281 'from another workspace');
282
283 ##############################################################################
284 # Check if urgent flag can be unset if we move the window out of the container
285 ##############################################################################
286 $tmp = fresh_workspace;
287 cmd 'layout tabbed';
288 $w1 = open_window;
289 $w2 = open_window;
290 sync_with_i3;
291 cmd '[id="' . $w2->id . '"] focus';
292 sync_with_i3;
293 cmd 'split v';
294 cmd 'layout stacked';
295 my $w3 = open_window;
296 sync_with_i3;
297 cmd '[id="' . $w2->id . '"] focus';
298 sync_with_i3;
299 set_urgency($w3, 1, $type);
300 sync_with_i3;
301 cmd 'focus parent';
302 sync_with_i3;
303 cmd 'move right';
304 cmd '[id="' . $w3->id . '"] focus';
305 sync_with_i3;
306 $ws = get_ws($tmp);
307 ok(!$ws->{urgent}, 'urgent flag not set on workspace');
308
309 ##############################################################################
310 # Regression test for #1187: Urgency hint moves to new workspace when moving
311 # a container to another workspace.
312 ##############################################################################
313
314 my $tmp_source = fresh_workspace;
315 my $tmp_target = fresh_workspace;
316 cmd 'workspace ' . $tmp_source;
317 sync_with_i3;
318 $w1 = open_window;
319 $w2 = open_window;
320 sync_with_i3;
321 cmd '[id="' . $w1->id . '"] focus';
322 sync_with_i3;
323 cmd 'mark urgent_con';
324 cmd '[id="' . $w2->id . '"] focus';
325 set_urgency($w1, 1, $type);
326 sync_with_i3;
327 cmd '[con_mark="urgent_con"] move container to workspace ' . $tmp_target;
328 sync_with_i3;
329 my $source_ws = get_ws($tmp_source);
330 my $target_ws = get_ws($tmp_target);
331 ok(!$source_ws->{urgent}, 'Source workspace is no longer marked urgent');
332 is($target_ws->{urgent}, 1, 'Target workspace is now marked urgent');
333
334 ##############################################################################
335 # Test that moving an unfocused container doesn't reset its urgency hint.
336 ##############################################################################
337 $tmp = fresh_workspace;
338 $win1 = open_window;
339 $win2 = open_window;
340 cmd 'split v';
341 $win3 = open_window;
342 set_urgency($win1, 1, $type);
343 sync_with_i3;
344
345 my $win1_info;
346
347 @content = @{get_ws_content($tmp)};
348 $win1_info = first { $_->{window} == $win1->id } @content;
349 ok($win1_info->{urgent}, 'win1 window is marked urgent');
350
351 cmd '[id="' . $win1->id . '"] move right';
352 cmd '[id="' . $win1->id . '"] move right';
353 @content = @{get_ws_content($tmp)};
354 $win1_info = first { $_->{window} == $win1->id } @content;
355 ok($win1_info->{urgent}, 'win1 window is still marked urgent after moving');
356
357 cmd '[id="' . $win1->id . '"] focus';
358 @content = @{get_ws_content($tmp)};
359 $win1_info = first { $_->{window} == $win1->id } @content;
360 ok(!$win1_info->{urgent}, 'win1 window is not marked urgent after focusing');
361
362 ##############################################################################
363
364 exit_gracefully($pid);
365 }
366
367 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17
18 my $tmp = fresh_workspace;
19
20 ####################################################################################
21 # first part: test if a floating window will be correctly positioned above its leader
22 #
23 # This is verified by opening two windows, then opening a floating window above the
24 # right one, then above the left one. If the floating windows are all positioned alike,
25 # one of both (depending on your screen resolution) will be positioned wrong.
26 ####################################################################################
27
28 my $left = open_window({ name => 'Left' });
29 my $right = open_window({ name => 'Right' });
30
31 my ($abs, $rgeom) = $right->rect;
32
33 my $child = open_floating_window({
34 dont_map => 1,
35 name => 'Child window',
36 });
37 $child->client_leader($right);
38 $child->map;
39
40 ok(wait_for_map($child), 'child window mapped');
41
42 my $cgeom;
43 ($abs, $cgeom) = $child->rect;
44 cmp_ok($cgeom->x, '>=', $rgeom->x, 'Child X >= right container X');
45
46 my $child2 = open_floating_window({
47 dont_map => 1,
48 name => 'Child window 2',
49 });
50 $child2->client_leader($left);
51 $child2->map;
52
53 ok(wait_for_map($child2), 'second child window mapped');
54
55 ($abs, $cgeom) = $child2->rect;
56 cmp_ok(($cgeom->x + $cgeom->width), '<', $rgeom->x, 'child above left window');
57
58 # check wm_transient_for
59 my $fwindow = open_window({ dont_map => 1 });
60 $fwindow->transient_for($right);
61 $fwindow->map;
62
63 ok(wait_for_map($fwindow), 'transient window mapped');
64
65 my ($absolute, $top) = $fwindow->rect;
66 ok($absolute->{x} != 0 && $absolute->{y} != 0, 'i3 did not map it to (0x0)');
67
68 SKIP: {
69 skip "(workspace placement by client_leader not yet implemented)", 3;
70
71 #####################################################################
72 # Create a parent window
73 #####################################################################
74
75 my $window = open_window({ dont_map => 1, name => 'Parent window' });
76 $window->map;
77
78 ok(wait_for_map($window), 'parent window mapped');
79
80 #########################################################################
81 # Switch to a different workspace and open a child window. It should be opened
82 # on the old workspace.
83 #########################################################################
84 fresh_workspace;
85
86 my $child = open_window({ dont_map => 1, name => 'Child window' });
87 $child->client_leader($window);
88 $child->map;
89
90 ok(wait_for_map($child), 'child window mapped');
91
92 isnt($x->input_focus, $child->id, "Child window focused");
93
94 # Switch back
95 cmd "workspace $tmp";
96
97 is($x->input_focus, $child->id, "Child window focused");
98
99 }
100
101 ################################################################################
102 # Verify that transient_for can be set and unset.
103 ################################################################################
104
105 $tmp = fresh_workspace;
106
107 $fwindow = open_window({ dont_map => 1 });
108 $fwindow->transient_for($right);
109 $fwindow->map;
110
111 wait_for_map($fwindow);
112
113 my $floating_con = get_ws($tmp)->{floating_nodes}[0]->{nodes}[0];
114 is($floating_con->{window_properties}->{transient_for}, $right->id, 'WM_TRANSIENT_FOR properly parsed');
115
116 $x->delete_property($fwindow->id, $x->atom(name => 'WM_TRANSIENT_FOR')->id);
117 $x->flush;
118
119 sync_with_i3;
120
121 $floating_con = get_ws($tmp)->{floating_nodes}[0]->{nodes}[0];
122 is($floating_con->{window_properties}->{transient_for}, undef, 'WM_TRANSIENT_FOR properly removed');
123
124 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17
18 my $old_ws = get_ws(focused_ws());
19
20 # We are switching to an empty workpspace from an empty workspace, so we expect
21 # to receive "init", "focus", and "empty".
22 my @events = events_for(
23 sub { cmd 'workspace 2' },
24 'workspace');
25
26 my $current_ws = get_ws(focused_ws());
27
28 is(scalar @events, 3, 'Received 3 events');
29 is($events[0]->{change}, 'init', 'First event has change = init');
30 is($events[0]->{current}->{id}, $current_ws->{id}, 'the "current" property contains the initted workspace con');
31
32 is($events[1]->{change}, 'focus', 'Second event has change = focus');
33 is($events[1]->{current}->{id}, $current_ws->{id}, 'the "current" property should contain the focused workspace con');
34 is($events[1]->{old}->{id}, $old_ws->{id}, 'the "old" property should contain the workspace con that was focused last');
35
36 is($events[2]->{change}, 'empty', 'Third event has change = empty');
37 is($events[2]->{current}->{id}, $old_ws->{id}, 'the "current" property should contain the emptied workspace con');
38
39 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17 use List::Util qw(first);
18
19 # to not depend on List::MoreUtils
20 sub all (&@) {
21 my $cb = shift;
22 for (@_) {
23 return 0 unless $cb->();
24 }
25 return 1;
26 }
27
28 sub none (&@) {
29 my $cb = shift;
30 for (@_) {
31 return 0 if $cb->();
32 }
33 return 1;
34 }
35
36 my $i3 = i3(get_socket_path());
37
38 ####################
39 # Request tree
40 ####################
41
42 my $tree = $i3->get_tree->recv;
43
44 # a unique value
45 my $ignore = \"";
46
47 my $expected = {
48 fullscreen_mode => 0,
49 sticky => $ignore,
50 nodes => $ignore,
51 window => undef,
52 name => 'root',
53 orientation => $ignore,
54 type => 'root',
55 window_type => undef,
56 id => $ignore,
57 rect => $ignore,
58 deco_rect => $ignore,
59 window_rect => $ignore,
60 geometry => $ignore,
61 swallows => $ignore,
62 percent => undef,
63 layout => 'splith',
64 floating => 'auto_off',
65 last_split_layout => 'splith',
66 scratchpad_state => 'none',
67 focus => $ignore,
68 focused => JSON::XS::false,
69 urgent => JSON::XS::false,
70 border => 'normal',
71 'floating_nodes' => $ignore,
72 workspace_layout => 'default',
73 current_border_width => -1,
74 marks => $ignore,
75 };
76
77 # a shallow copy is sufficient, since we only ignore values at the root
78 my $tree_copy = { %$tree };
79
80 for (keys %$expected) {
81 my $val = $expected->{$_};
82
83 # delete unwanted keys, so we can use is_deeply()
84 if (ref($val) eq 'SCALAR' and $val == $ignore) {
85 delete $tree_copy->{$_};
86 delete $expected->{$_};
87 }
88 }
89
90 is_deeply($tree_copy, $expected, 'root node OK');
91
92 my @nodes = @{$tree->{nodes}};
93
94 ok(@nodes > 0, 'root node has at least one leaf');
95
96 ok((all { $_->{type} eq 'output' } @nodes), 'all nodes are of type CT_OUTPUT');
97 ok((none { defined($_->{window}) } @nodes), 'no CT_OUTPUT contains a window');
98 ok((all { @{$_->{nodes}} > 0 } @nodes), 'all nodes have at least one leaf (workspace)');
99 my @workspaces;
100 for my $ws (@nodes) {
101 my $content = first { $_->{type} eq 'con' } @{$ws->{nodes}};
102 @workspaces = (@workspaces, @{$content->{nodes}});
103 }
104
105 ok((all { $_->{type} eq 'workspace' } @workspaces), 'all workspaces are of type CT_WORKSPACE');
106 #ok((all { @{$_->{nodes}} == 0 } @workspaces), 'all workspaces are empty yet');
107 ok((none { defined($_->{window}) } @workspaces), 'no CT_OUTPUT contains a window');
108
109 # TODO: get the focused container
110
111 $i3->command('open')->recv;
112
113 # TODO: get the focused container, check if it changed.
114 # TODO: get the old focused container, check if there is a new child
115
116 #diag(Dumper(\@workspaces));
117
118 #diag(Dumper($tree));
119
120
121 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests whether we can switch to a non-existant workspace
17 # (necessary for further tests)
18 #
19 use List::Util qw(first);
20 use i3test;
21
22 # to ensure that workspace 1 stays open
23 cmd 'open';
24
25 my $tmp = fresh_workspace;
26 ok(workspace_exists($tmp), 'workspace created');
27 # if the workspace could not be created, we cannot run any other test
28 # (every test starts by creating its workspace)
29 if (!workspace_exists($tmp)) {
30 BAIL_OUT('Cannot create workspace, further tests make no sense');
31 }
32
33 my $otmp = fresh_workspace;
34 diag("Other temporary workspace name: $otmp\n");
35
36 # As the old workspace was empty, it should get
37 # cleaned up as we switch away from it
38 cmd "workspace $otmp";
39 ok(!workspace_exists($tmp), 'old workspace cleaned up');
40
41 # Switch to the same workspace again to make sure it doesn’t get cleaned up
42 cmd "workspace $otmp";
43 cmd "workspace $otmp";
44 ok(workspace_exists($otmp), 'other workspace still exists');
45
46
47 #####################################################################
48 # check if the workspace next / prev commands work
49 #####################################################################
50
51 cmd 'workspace next';
52
53 ok(!workspace_exists('next'), 'workspace "next" does not exist');
54
55 cmd "workspace $tmp";
56 cmd 'open';
57
58 ok(workspace_exists($tmp), 'workspace created');
59
60 cmd "workspace $otmp";
61 cmd 'open';
62
63 ok(workspace_exists($tmp), 'workspace tmp still exists');
64 ok(workspace_exists($otmp), 'workspace otmp created');
65
66 is(focused_ws(), $otmp, 'focused workspace is otmp');
67
68 cmd 'workspace prev';
69 is(focused_ws(), $tmp, 'focused workspace is tmp after workspace prev');
70
71 cmd 'workspace next';
72 is(focused_ws(), $otmp, 'focused workspace is otmp after workspace next');
73
74
75 #####################################################################
76 # check that wrapping works
77 #####################################################################
78
79 cmd 'workspace next';
80 is(focused_ws(), '1', 'focused workspace is 1 after workspace next');
81
82 cmd 'workspace next';
83 is(focused_ws(), $tmp, 'focused workspace is tmp after workspace next');
84
85 cmd 'workspace next';
86 is(focused_ws(), $otmp, 'focused workspace is otmp after workspace next');
87
88
89 cmd 'workspace prev';
90 is(focused_ws(), $tmp, 'focused workspace is tmp after workspace prev');
91
92 cmd 'workspace prev';
93 is(focused_ws(), '1', 'focused workspace is tmp after workspace prev');
94
95 cmd 'workspace prev';
96 is(focused_ws(), $otmp, 'focused workspace is otmp after workspace prev');
97
98
99 #####################################################################
100 # check if we can change to "next" / "prev"
101 #####################################################################
102
103 cmd 'workspace "next"';
104
105 ok(workspace_exists('next'), 'workspace "next" exists');
106 is(focused_ws(), 'next', 'now on workspace next');
107
108 cmd 'workspace "prev"';
109
110 ok(workspace_exists('prev'), 'workspace "prev" exists');
111 is(focused_ws(), 'prev', 'now on workspace prev');
112
113 #####################################################################
114 # check that the numbers are assigned/recognized correctly
115 #####################################################################
116
117 cmd "workspace 3: $tmp";
118 my $ws = get_ws("3: $tmp");
119 ok(defined($ws), "workspace 3: $tmp was created");
120 is($ws->{num}, 3, 'workspace number is 3');
121
122 cmd "workspace 0: $tmp";
123 $ws = get_ws("0: $tmp");
124 ok(defined($ws), "workspace 0: $tmp was created");
125 is($ws->{num}, 0, 'workspace number is 0');
126
127 cmd "workspace aa: $tmp";
128 $ws = get_ws("aa: $tmp");
129 ok(defined($ws), "workspace aa: $tmp was created");
130 is($ws->{num}, -1, 'workspace number is -1');
131
132 cmd "workspace -42: $tmp";
133 $ws = get_ws("-42: $tmp");
134 ok(defined($ws), "workspace -42: $tmp was created");
135 is($ws->{num}, -1, 'negative workspace number is ignored');
136
137 cmd "workspace 2147483647: $tmp";
138 $ws = get_ws("2147483647: $tmp");
139 ok(defined($ws), "workspace 2147483647: $tmp was created");
140 is($ws->{num}, 2147483647, 'workspace number is 2147483647');
141
142 cmd "workspace 2147483648: $tmp";
143 $ws = get_ws("2147483648: $tmp");
144 ok(defined($ws), "workspace 2147483648: $tmp was created");
145 is($ws->{num}, -1, 'workspace number past the limit is ignored');
146
147 ################################################################################
148 # Check that we can go to workspace "4: foo" with the command
149 # "workspace number 4".
150 ################################################################################
151
152 ok(!workspace_exists('4'), 'workspace 4 does not exist');
153 ok(!workspace_exists('4: foo'), 'workspace 4: foo does not exist yet');
154 cmd 'workspace 4: foo';
155 ok(workspace_exists('4: foo'), 'workspace 4: foo was created');
156 cmd 'open';
157
158 cmd 'workspace 3';
159 ok(workspace_exists('4: foo'), 'workspace 4: foo still open');
160 cmd 'workspace number 4';
161 is(focused_ws(), '4: foo', 'now on workspace 4: foo');
162 ok(!workspace_exists('4'), 'workspace 4 still does not exist');
163
164 ################################################################################
165 # Check that we "workspace number 5" will create workspace 5 if it does not yet
166 # exist.
167 ################################################################################
168
169 ok(!workspace_exists('5'), 'workspace 5 does not exist');
170 cmd 'workspace number 5';
171 ok(workspace_exists('5'), 'workspace 5 was created');
172
173 ################################################################################
174 # Check that we can go to workspace "7: foo" with the command
175 # "workspace number 7: bar", i.e. the additional workspace name is ignored.
176 ################################################################################
177
178 ok(!workspace_exists('7'), 'workspace 7 does not exist');
179 ok(!workspace_exists('7: bar'), 'workspace 7: bar does not exist');
180 ok(!workspace_exists('7: foo'), 'workspace 7: foo does not exist yet');
181 cmd 'workspace 7: foo';
182 ok(workspace_exists('7: foo'), 'workspace 7: foo was created');
183 cmd 'open';
184
185 cmd 'workspace 6';
186 ok(workspace_exists('7: foo'), 'workspace 7: foo still open');
187 cmd 'workspace number 7: bar';
188 is(focused_ws(), '7: foo', 'now on workspace 7: foo');
189 ok(!workspace_exists('7'), 'workspace 7 still does not exist');
190 ok(!workspace_exists('7: bar'), 'workspace 7: bar still does not exist');
191
192 ################################################################################
193 # Check that "workspace number 8: foo" will create workspace "8: foo" if it
194 # does not yet exist (just like "workspace 8: foo" would).
195 ################################################################################
196
197 ok(!workspace_exists('8: foo'), 'workspace 8: foo does not exist');
198 cmd 'workspace number 8: foo';
199 ok(workspace_exists('8: foo'), 'workspace 8: foo was created');
200
201 ################################################################################
202 # Verify that renaming workspaces works.
203 ################################################################################
204
205 sub workspace_numbers_sorted {
206 my ($name) = @_;
207 my $i3 = i3(get_socket_path());
208 my $tree = $i3->get_tree->recv;
209
210 my @outputs = @{$tree->{nodes}};
211 my @workspaces;
212 for my $output (@outputs) {
213 my $content = first { $_->{type} eq 'con' } @{$output->{nodes}};
214 @workspaces = (@workspaces, @{$content->{nodes}});
215 }
216
217 my @numbers = grep { $_ != -1 } map { $_->{num} } @workspaces;
218 is_deeply(
219 [ sort { $a <=> $b } @numbers ],
220 \@numbers,
221 'workspace numbers sorted');
222 }
223
224 # 1: numbered workspace
225 cmd 'workspace 10';
226 cmd 'open';
227 cmd 'workspace 13';
228 cmd 'open';
229
230 workspace_numbers_sorted();
231
232 cmd 'workspace 9';
233 is(focused_ws(), '9', 'now on workspace 9');
234
235 ok(!workspace_exists('12'), 'workspace 12 does not exist yet');
236 cmd 'rename workspace 9 to 12';
237 ok(!workspace_exists('9'), 'workspace 9 does not exist anymore');
238 is(focused_ws(), '12', 'now on workspace 12');
239 $ws = get_ws('12');
240 is($ws->{num}, 12, 'number correctly changed');
241
242 workspace_numbers_sorted();
243
244 # 2: numbered + named workspace
245 cmd 'workspace 9: foo';
246 is(focused_ws(), '9: foo', 'now on workspace 9: foo');
247
248 ok(!workspace_exists('11: bar'), 'workspace 11: bar does not exist yet');
249 cmd 'rename workspace "9: foo" to "11: bar"';
250 ok(!workspace_exists('9: foo'), 'workspace 9 does not exist anymore');
251 is(focused_ws(), '11: bar', 'now on workspace 10');
252 $ws = get_ws('11: bar');
253 is($ws->{num}, 11, 'number correctly changed');
254 workspace_numbers_sorted();
255 # keep that one open, we need it later
256 cmd 'open';
257
258 # 3: named workspace
259 cmd 'workspace bleh';
260 is(focused_ws(), 'bleh', 'now on workspace bleh');
261
262 ok(!workspace_exists('qux'), 'workspace qux does not exist yet');
263 cmd 'rename workspace bleh to qux';
264 ok(!workspace_exists('bleh'), 'workspace 9 does not exist anymore');
265 is(focused_ws(), 'qux', 'now on workspace qux');
266 $ws = get_ws('qux');
267 is($ws->{num}, -1, 'number correctly changed');
268 workspace_numbers_sorted();
269
270 # 4: rename current workspace
271 cmd 'workspace 4711';
272 is(focused_ws(), '4711', 'now on workspace 4711');
273
274 ok(!workspace_exists('42'), 'workspace 42 does not exist yet');
275 cmd 'rename workspace to 42';
276 ok(!workspace_exists('4711'), 'workspace 4711 does not exist anymore');
277 is(focused_ws(), '42', 'now on workspace 42');
278 $ws = get_ws('42');
279 is($ws->{num}, 42, 'number correctly changed');
280 workspace_numbers_sorted();
281
282 # 5: special cases
283 cmd 'workspace bla';
284 is(focused_ws(), 'bla', 'now on workspace to');
285
286 ok(!workspace_exists('to'), 'workspace to does not exist yet');
287 cmd 'rename workspace bla to to';
288 ok(!workspace_exists('bla'), 'workspace bla does not exist anymore');
289 is(focused_ws(), 'to', 'now on workspace to');
290 cmd 'rename workspace to to bla';
291 ok(!workspace_exists('to'), 'workspace to does not exist anymore');
292 is(focused_ws(), 'bla', 'now on workspace bla');
293 cmd 'rename workspace to to';
294 ok(!workspace_exists('bla'), 'workspace bla does not exist anymore');
295 is(focused_ws(), 'to', 'now on workspace to');
296 cmd 'rename workspace to bla';
297 ok(!workspace_exists('to'), 'workspace to does not exist anymore');
298 is(focused_ws(), 'bla', 'now on workspace bla');
299 cmd 'rename workspace to tosomething';
300 ok(!workspace_exists('bla'), 'workspace bla does not exist anymore');
301 is(focused_ws(), 'tosomething', 'now on workspace tosomething');
302
303 # 6: already existing workspace
304 my $result = cmd 'rename workspace qux to 11: bar';
305 ok(!$result->[0]->{success}, 'renaming workspace to an already existing one failed');
306
307 # 7: non-existing old workspace (verify command result)
308 $result = cmd 'rename workspace notexistant to bleh';
309 ok(!$result->[0]->{success}, 'renaming workspace which does not exist failed');
310
311 # 8: change case
312 ok(!workspace_exists('11: BAR'), 'workspace 11: BAR does not exist yet');
313 $result = cmd 'rename workspace "11: bar" to "11: BAR"';
314 ok($result->[0]->{success}, 'renaming workspace from 11: bar to 11: BAR worked');
315 ok(workspace_exists('11: BAR'), 'workspace 11: BAR now exists');
316
317 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests whether opening an empty container and killing it again works
17 #
18 use List::Util qw(first);
19 use i3test;
20
21 my $tmp = fresh_workspace;
22
23 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
24
25 # Open a new container
26 cmd 'open';
27
28 ok(@{get_ws_content($tmp)} == 1, 'container opened');
29
30 cmd 'kill';
31 ok(@{get_ws_content($tmp)} == 0, 'container killed');
32
33 ##############################################################
34 # open two containers and kill the one which is not focused
35 # by its ID to test if the parser correctly matches the window
36 ##############################################################
37
38 cmd 'open';
39 cmd 'open';
40 ok(@{get_ws_content($tmp)} == 2, 'two containers opened');
41
42 my $content = get_ws_content($tmp);
43 my $not_focused = first { !$_->{focused} } @{$content};
44 my $id = $not_focused->{id};
45
46 cmd "[con_id=\"$id\"] kill";
47
48 $content = get_ws_content($tmp);
49 ok(@{$content} == 1, 'one container killed');
50 ok($content->[0]->{id} != $id, 'correct window killed');
51
52 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests all kinds of matching methods
17 #
18 use i3test;
19
20 my $tmp = fresh_workspace;
21
22 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
23
24 # Open a new window
25 my $window = open_window;
26 my $content = get_ws_content($tmp);
27 ok(@{$content} == 1, 'window mapped');
28 my $win = $content->[0];
29
30 ######################################################################
31 # first test that matches which should not match this window really do
32 # not match it
33 ######################################################################
34 # TODO: specify more match types
35 # Try matching with an empty pattern since there isn't a WM_CLASS set.
36 cmd q|[con_id="99999"] kill|;
37
38 is_num_children($tmp, 1, 'window still there');
39
40 # now kill the window
41 cmd 'nop now killing the window';
42 my $id = $win->{id};
43 cmd qq|[con_id="$id"] kill|;
44
45 wait_for_unmap $window;
46
47 cmd 'nop checking if its gone';
48 is_num_children($tmp, 0, 'window killed');
49
50 # TODO: same test, but with pcre expressions
51
52 ######################################################################
53 # check that multiple criteria work are checked with a logical AND,
54 # not a logical OR (that is, matching is not cancelled after the first
55 # criterion matches).
56 ######################################################################
57
58 $tmp = fresh_workspace;
59
60 my $left = open_window(wm_class => 'special', name => 'left');
61 ok($left->mapped, 'left window mapped');
62
63 my $right = open_window(wm_class => 'special', name => 'right');
64 ok($right->mapped, 'right window mapped');
65
66 # two windows should be here
67 is_num_children($tmp, 2, 'two windows opened');
68
69 cmd '[class="special" title="left"] kill';
70
71 sync_with_i3;
72
73 is_num_children($tmp, 1, 'one window still there');
74
75 ######################################################################
76 # check that regular expressions work
77 ######################################################################
78
79 $tmp = fresh_workspace;
80
81 $left = open_window(name => 'left', wm_class => 'special7');
82 ok($left->mapped, 'left window mapped');
83 is_num_children($tmp, 1, 'window opened');
84
85 cmd '[class="^special[0-9]$"] kill';
86 wait_for_unmap $left;
87 is_num_children($tmp, 0, 'window killed');
88
89 ######################################################################
90 # check that UTF-8 works when matching
91 ######################################################################
92
93 $tmp = fresh_workspace;
94
95 $left = open_window(name => 'ä 3', wm_class => 'special7');
96 ok($left->mapped, 'left window mapped');
97 is_num_children($tmp, 1, 'window opened');
98
99 cmd '[title="^\w [3]$"] kill';
100 wait_for_unmap $left;
101 is_num_children($tmp, 0, 'window killed');
102
103 ######################################################################
104 # check that we can match empty properties
105 ######################################################################
106
107 $tmp = fresh_workspace;
108
109 $left = open_window(name => 'class is empty', wm_class => '');
110 ok($left->mapped, 'left window mapped');
111 is_num_children($tmp, 1, 'window opened');
112
113 cmd '[class="^$"] kill';
114 wait_for_unmap $left;
115 is_num_children($tmp, 0, 'window killed');
116
117 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests multiple commands (using ';') and multiple operations (using ',')
17 #
18 use i3test;
19
20 my $tmp = fresh_workspace;
21
22 sub multiple_cmds {
23 my ($cmd) = @_;
24
25 cmd 'open';
26 cmd 'open';
27 ok(@{get_ws_content($tmp)} == 2, 'two containers opened');
28
29 cmd $cmd;
30 ok(@{get_ws_content($tmp)} == 0, "both containers killed (cmd = $cmd)");
31 }
32 multiple_cmds('kill;kill');
33 multiple_cmds('kill; kill');
34 multiple_cmds('kill ; kill');
35 multiple_cmds('kill ;kill');
36 multiple_cmds('kill ;kill');
37 multiple_cmds('kill ; kill');
38 multiple_cmds("kill;\tkill");
39 multiple_cmds("kill\t;kill");
40 multiple_cmds("kill\t;\tkill");
41 multiple_cmds("kill\t ;\tkill");
42 multiple_cmds("kill\t ;\t kill");
43 multiple_cmds("kill \t ; \t kill");
44
45 #####################################################################
46 # test if un-quoted strings are handled correctly
47 #####################################################################
48
49 $tmp = fresh_workspace;
50 cmd 'open';
51 my $unused = get_unused_workspace;
52 ok(!($unused ~~ @{get_workspace_names()}), 'workspace does not exist yet');
53 cmd "move workspace $unused; nop parser test";
54 ok(($unused ~~ @{get_workspace_names()}), 'workspace exists after moving');
55
56 #####################################################################
57 # quote the workspace name and use a ; (command separator) in its name
58 #####################################################################
59
60 cmd 'open';
61 $unused = get_unused_workspace;
62 $unused .= ';a';
63 ok(!($unused ~~ @{get_workspace_names()}), 'workspace does not exist yet');
64 cmd qq|move workspace "$unused"; nop parser test|;
65 ok(($unused ~~ @{get_workspace_names()}), 'workspace exists after moving');
66
67 # TODO: need a non-invasive command before implementing a test which uses ','
68
69 ################################################################################
70 # regression test: 10 invalid commands should not crash i3 (10 is the stack
71 # depth)
72 ################################################################################
73
74 cmd 'move gibberish' for (0 .. 10);
75
76 does_i3_live;
77
78 ################################################################################
79 # regression test: an invalid command should come back with an error.
80 ################################################################################
81
82 my $reply = cmd 'bullshit-command-which-we-never-implement meh';
83 is(scalar @$reply, 1, 'got one command reply');
84 ok(!$reply->[0]->{success}, 'reply has success == false');
85
86 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests focus switching (next/prev)
17 #
18 use i3test;
19
20 my $tmp = fresh_workspace;
21
22 ######################################################################
23 # Open one container, verify that 'focus down' and 'focus right' do nothing
24 ######################################################################
25 cmd 'open';
26
27 my ($nodes, $focus) = get_ws_content($tmp);
28 my $old_focused = $focus->[0];
29
30 cmd 'focus down';
31 ($nodes, $focus) = get_ws_content($tmp);
32 is($focus->[0], $old_focused, 'focus did not change with only one con');
33
34 cmd 'focus right';
35 ($nodes, $focus) = get_ws_content($tmp);
36 is($focus->[0], $old_focused, 'focus did not change with only one con');
37
38 ######################################################################
39 # Open another container, verify that 'focus right' switches
40 ######################################################################
41 my $left = $old_focused;
42
43 cmd 'open';
44 ($nodes, $focus) = get_ws_content($tmp);
45 isnt($old_focused, $focus->[0], 'new container is focused');
46 my $mid = $focus->[0];
47
48 cmd 'open';
49 ($nodes, $focus) = get_ws_content($tmp);
50 isnt($old_focused, $focus->[0], 'new container is focused');
51 my $right = $focus->[0];
52
53 cmd 'focus right';
54 ($nodes, $focus) = get_ws_content($tmp);
55 isnt($focus->[0], $right, 'focus did change');
56 is($focus->[0], $left, 'left container focused (wrapping)');
57
58 cmd 'focus right';
59 ($nodes, $focus) = get_ws_content($tmp);
60 is($focus->[0], $mid, 'middle container focused');
61
62 cmd 'focus right';
63 ($nodes, $focus) = get_ws_content($tmp);
64 is($focus->[0], $right, 'right container focused');
65
66 cmd 'focus left';
67 ($nodes, $focus) = get_ws_content($tmp);
68 is($focus->[0], $mid, 'middle container focused');
69
70 cmd 'focus left';
71 ($nodes, $focus) = get_ws_content($tmp);
72 is($focus->[0], $left, 'left container focused');
73
74 cmd 'focus left';
75 ($nodes, $focus) = get_ws_content($tmp);
76 is($focus->[0], $right, 'right container focused');
77
78
79 ######################################################################
80 # Test focus command
81 ######################################################################
82
83 cmd qq|[con_id="$mid"] focus|;
84 ($nodes, $focus) = get_ws_content($tmp);
85 is($focus->[0], $mid, 'middle container focused');
86
87
88 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests splitting
17 #
18 use i3test;
19 use List::Util qw(first);
20
21 my $tmp;
22 my $ws;
23
24 ################################################################################
25 # Open two containers, split, open another container. Then verify
26 # the layout is like we expect it to be
27 ################################################################################
28
29 sub verify_split_layout {
30 my (%args) = @_;
31
32 $tmp = fresh_workspace;
33
34 $ws = get_ws($tmp);
35 is($ws->{layout}, 'splith', 'orientation horizontal by default');
36 cmd 'split v';
37 $ws = get_ws($tmp);
38 is($ws->{layout}, 'splitv', 'split v changes workspace orientation');
39
40 cmd 'open';
41 cmd 'open';
42 my $content = get_ws_content($tmp);
43
44 is(@{$content}, 2, 'two containers on workspace level');
45 my $first = $content->[0];
46 my $second = $content->[1];
47
48 is(@{$first->{nodes}}, 0, 'first container has no children');
49 is(@{$second->{nodes}}, 0, 'second container has no children (yet)');
50 my $old_id = $second->{id};
51
52 cmd $args{split_command};
53 cmd 'open';
54
55 $content = get_ws_content($tmp);
56
57 is(@{$content}, 2, 'two containers on workspace level');
58 $first = $content->[0];
59 $second = $content->[1];
60
61 is(@{$first->{nodes}}, 0, 'first container has no children');
62 isnt($second->{id}, $old_id, 'second container was replaced');
63 is($second->{layout}, 'splith', 'orientation is horizontal');
64 is(@{$second->{nodes}}, 2, 'second container has 2 children');
65 is($second->{nodes}->[0]->{id}, $old_id, 'found old second container');
66 }
67
68 verify_split_layout(split_command => 'split h');
69 verify_split_layout(split_command => 'split horizontal');
70
71 # TODO: extend this test-case (test next/prev)
72 # - wrapping (no horizontal switch possible, goes level-up)
73 # - going level-up "manually"
74
75 ######################################################################
76 # Test splitting multiple times without actually creating windows
77 ######################################################################
78
79 $tmp = fresh_workspace;
80
81 $ws = get_ws($tmp);
82 is($ws->{layout}, 'splith', 'orientation horizontal by default');
83 cmd 'split v';
84 $ws = get_ws($tmp);
85 is($ws->{layout}, 'splitv', 'split v changes workspace orientation');
86
87 cmd 'open';
88 my @content = @{get_ws_content($tmp)};
89
90 # recursively sums up all nodes and their children
91 sub sum_nodes {
92 my ($nodes) = @_;
93
94 return 0 if !@{$nodes};
95
96 my @children = (map { @{$_->{nodes}} } @{$nodes},
97 map { @{$_->{'floating_nodes'}} } @{$nodes});
98
99 return @{$nodes} + sum_nodes(\@children);
100 }
101
102 my $old_count = sum_nodes(\@content);
103 cmd 'split v';
104
105 @content = @{get_ws_content($tmp)};
106 $old_count = sum_nodes(\@content);
107
108 cmd 'split v';
109
110 @content = @{get_ws_content($tmp)};
111 my $count = sum_nodes(\@content);
112 is($count, $old_count, 'not more windows after splitting again');
113
114 ######################################################################
115 # In the special case of being inside a stacked or tabbed container, we don’t
116 # want this to happen.
117 ######################################################################
118
119 $tmp = fresh_workspace;
120
121 cmd 'open';
122 @content = @{get_ws_content($tmp)};
123 is(scalar @content, 1, 'Precisely one container on this ws');
124 cmd 'layout stacked';
125 @content = @{get_ws_content($tmp)};
126 is(scalar @content, 1, 'Still one container on this ws');
127 is(scalar @{$content[0]->{nodes}}, 1, 'Stacked con has one child node');
128
129 cmd 'split h';
130 cmd 'open';
131 @content = @{get_ws_content($tmp)};
132 is(scalar @content, 1, 'Still one container on this ws');
133 is(scalar @{$content[0]->{nodes}}, 1, 'Stacked con still has one child node');
134
135 ################################################################################
136 # When focusing the workspace, changing the layout should have an effect on the
137 # workspace, not on the parent (CT_CONTENT) container.
138 ################################################################################
139
140 sub get_output_content {
141 my $tree = i3(get_socket_path())->get_tree->recv;
142
143 my @outputs = grep { $_->{name} !~ /^__/ } @{$tree->{nodes}};
144 is(scalar @outputs, 1, 'exactly one output (testcase not multi-monitor capable)');
145 my $output = $outputs[0];
146 # get the first (and only) CT_CON
147 return first { $_->{type} eq 'con' } @{$output->{nodes}};
148 }
149
150 $tmp = fresh_workspace;
151
152 cmd 'open';
153 cmd 'split v';
154 cmd 'open';
155 cmd 'focus parent';
156 is(get_output_content()->{layout}, 'splith', 'content container layout ok');
157 cmd 'layout stacked';
158 is(get_output_content()->{layout}, 'splith', 'content container layout still ok');
159
160 ######################################################################
161 # Splitting a workspace that has more than one child
162 ######################################################################
163
164 $tmp = fresh_workspace;
165
166 cmd 'open';
167 cmd 'open';
168 cmd 'focus parent';
169 cmd 'split v';
170 cmd 'open';
171
172 my $content = get_ws_content($tmp);
173 my $fst = $content->[0];
174 my $snd = $content->[1];
175
176 is(@{$content}, 2, 'two containers on workspace');
177 is(@{$fst->{nodes}}, 2, 'first child has two children');
178 is(@{$snd->{nodes}}, 0, 'second child has no children');
179
180 ######################################################################
181 # Test split toggle
182 ######################################################################
183
184 $tmp = fresh_workspace;
185 cmd 'split h';
186 cmd 'split toggle';
187 $ws = get_ws($tmp);
188 is($ws->{layout}, 'splitv', 'toggled workspace split');
189
190 $tmp = fresh_workspace;
191 cmd 'split h';
192 cmd 'split toggle';
193 cmd 'split toggle';
194 $ws = get_ws($tmp);
195 is($ws->{layout}, 'splith', 'toggled workspace back and forth');
196
197 cmd 'open';
198 cmd 'open';
199 cmd 'split toggle';
200
201 $content = get_ws_content($tmp);
202 my $second = $content->[1];
203 is($second->{layout}, 'splitv', 'toggled container orientation to vertical');
204
205 cmd 'split toggle';
206 $content = get_ws_content($tmp);
207 $second = $content->[1];
208 is($second->{layout}, 'splith', 'toggled container orientation back to horizontal');
209
210 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests moving. Basically, there are four different code-paths:
17 # 1) move a container which cannot be moved (single container on a workspace)
18 # 2) move a container before another single container
19 # 3) move a container inside another container
20 # 4) move a container in a different direction so that we need to go up in tree
21 #
22 use i3test;
23
24 my $i3 = i3(get_socket_path());
25
26 my $tmp = fresh_workspace;
27
28 ######################################################################
29 # 1) move a container which cannot be moved
30 ######################################################################
31
32 cmd 'open';
33
34 my $old_content = get_ws_content($tmp);
35 is(@{$old_content}, 1, 'one container on this workspace');
36
37 my $first = $old_content->[0]->{id};
38
39 cmd 'move left';
40 cmd 'move right';
41 cmd 'move up';
42 cmd 'move down';
43
44 my $content = get_ws_content($tmp);
45 is_deeply($old_content, $content, 'workspace unmodified after useless moves');
46
47 ######################################################################
48 # 2) move a container before another single container
49 ######################################################################
50
51 cmd 'open';
52 $content = get_ws_content($tmp);
53 is(@{$content}, 2, 'two containers on this workspace');
54 my $second = $content->[1]->{id};
55
56 is($content->[0]->{id}, $first, 'first container unmodified');
57
58 # Move the second container before the first one (→ swap them)
59 cmd 'move left';
60 $content = get_ws_content($tmp);
61 is($content->[0]->{id}, $second, 'first container modified');
62
63 # We should not be able to move any further
64 cmd 'move left';
65 $content = get_ws_content($tmp);
66 is($content->[0]->{id}, $second, 'first container unmodified');
67
68 # Now move in the other direction
69 cmd 'move right';
70 $content = get_ws_content($tmp);
71 is($content->[0]->{id}, $first, 'first container modified');
72
73 # We should not be able to move any further
74 cmd 'move right';
75 $content = get_ws_content($tmp);
76 is($content->[0]->{id}, $first, 'first container unmodified');
77
78 ######################################################################
79 # 3) move a container inside another container
80 ######################################################################
81
82 # Split the current (second) container and create a new container on workspace
83 # level. Our layout looks like this now:
84 # --------------------------
85 # | | second | |
86 # | first | ------ | third |
87 # | | | |
88 # --------------------------
89 cmd 'split v';
90 cmd 'focus parent';
91 cmd 'open';
92
93 $content = get_ws_content($tmp);
94 is(@{$content}, 3, 'three containers on this workspace');
95 my $third = $content->[2]->{id};
96
97 cmd 'move left';
98 $content = get_ws_content($tmp);
99 is(@{$content}, 2, 'only two containers on this workspace');
100 my $nodes = $content->[1]->{nodes};
101 is($nodes->[0]->{id}, $second, 'second container on top');
102 is($nodes->[1]->{id}, $third, 'third container on bottom');
103
104 ######################################################################
105 # move it inside the split container
106 ######################################################################
107
108 cmd 'move up';
109 $nodes = get_ws_content($tmp)->[1]->{nodes};
110 is($nodes->[0]->{id}, $third, 'third container on top');
111 is($nodes->[1]->{id}, $second, 'second container on bottom');
112
113 # move it outside again
114 cmd 'move left';
115 is_num_children($tmp, 3, 'three containers after moving left');
116
117 # due to automatic flattening/cleanup, the remaining split container
118 # will be replaced by the con itself, so we will still have 3 nodes
119 cmd 'move right';
120 is_num_children($tmp, 2, 'two containers after moving right (flattening)');
121
122 ######################################################################
123 # 4) We create two v-split containers on the workspace, then we move
124 # all Cons from the left v-split to the right one. The old vsplit
125 # container needs to be closed. Verify that it will be closed.
126 ######################################################################
127
128 my $otmp = fresh_workspace;
129
130 cmd "open";
131 cmd "open";
132 cmd "split v";
133 cmd "open";
134 cmd 'focus left';
135 cmd "split v";
136 cmd "open";
137 cmd "move right";
138 cmd 'focus left';
139 cmd "move right";
140
141 is_num_children($otmp, 1, 'only one node on this workspace');
142
143 ######################################################################
144 # 5) test moving floating containers.
145 ######################################################################
146
147 $tmp = fresh_workspace;
148 my $floatwin = open_floating_window;
149 my ($absolute_before, $top_before) = $floatwin->rect;
150
151 cmd 'move left';
152
153 sync_with_i3;
154
155 my ($absolute, $top) = $floatwin->rect;
156
157 is($absolute->x, ($absolute_before->x - 10), 'moved 10 px to the left');
158 is($absolute->y, $absolute_before->y, 'y not changed');
159 is($absolute->width, $absolute_before->width, 'width not changed');
160 is($absolute->height, $absolute_before->height, 'height not changed');
161
162 $absolute_before = $absolute;
163 $top_before = $top;
164
165 cmd 'move right';
166
167 sync_with_i3;
168
169 ($absolute, $top) = $floatwin->rect;
170
171 is($absolute->x, ($absolute_before->x + 10), 'moved 10 px to the right');
172 is($absolute->y, $absolute_before->y, 'y not changed');
173 is($absolute->width, $absolute_before->width, 'width not changed');
174 is($absolute->height, $absolute_before->height, 'height not changed');
175
176 $absolute_before = $absolute;
177 $top_before = $top;
178
179 cmd 'move up';
180
181 sync_with_i3;
182
183 ($absolute, $top) = $floatwin->rect;
184
185 is($absolute->x, $absolute_before->x, 'x not changed');
186 is($absolute->y, ($absolute_before->y - 10), 'moved 10 px up');
187 is($absolute->width, $absolute_before->width, 'width not changed');
188 is($absolute->height, $absolute_before->height, 'height not changed');
189
190 $absolute_before = $absolute;
191 $top_before = $top;
192
193 cmd 'move down';
194
195 sync_with_i3;
196
197 ($absolute, $top) = $floatwin->rect;
198
199 is($absolute->x, $absolute_before->x, 'x not changed');
200 is($absolute->y, ($absolute_before->y + 10), 'moved 10 px up');
201 is($absolute->width, $absolute_before->width, 'width not changed');
202 is($absolute->height, $absolute_before->height, 'height not changed');
203
204 $absolute_before = $absolute;
205 $top_before = $top;
206
207 ######################################################################
208 # 6) test moving floating containers with a specific amount of px
209 ######################################################################
210
211 cmd 'move left 20 px';
212
213 sync_with_i3;
214
215 ($absolute, $top) = $floatwin->rect;
216
217 is($absolute->x, ($absolute_before->x - 20), 'moved 20 px to the left');
218 is($absolute->y, $absolute_before->y, 'y not changed');
219 is($absolute->width, $absolute_before->width, 'width not changed');
220 is($absolute->height, $absolute_before->height, 'height not changed');
221
222 ######################################################################
223 # 6) test moving floating window to a specified position
224 # and to absolute center
225 ######################################################################
226
227 $tmp = fresh_workspace;
228 open_floating_window; my @floatcon;
229
230 cmd 'move position 5 px 15 px';
231
232 @floatcon = @{get_ws($tmp)->{floating_nodes}};
233
234 is($floatcon[0]->{rect}->{x}, 5, 'moved to position 5 x');
235 is($floatcon[0]->{rect}->{y}, 15, 'moved to position 15 y');
236
237 cmd 'move absolute position center';
238
239 @floatcon = @{get_ws($tmp)->{floating_nodes}};
240
241 my $center_x = int($x->root->rect->width/2) - int($floatcon[0]->{rect}->{width}/2);
242 my $center_y = int($x->root->rect->height/2) - int($floatcon[0]->{rect}->{height}/2);
243
244 is($floatcon[0]->{rect}->{x}, $center_x, "moved to center at position $center_x x");
245 is($floatcon[0]->{rect}->{y}, $center_y, "moved to center at position $center_y y");
246
247 # Make sure the command works with criteria
248 open_floating_window;
249
250 @floatcon = @{get_ws($tmp)->{floating_nodes}};
251
252 cmd '[con_id="' . $floatcon[0]->{nodes}[0]->{id} . '"] move position 25 px 30 px';
253 cmd '[con_id="' . $floatcon[1]->{nodes}[0]->{id} . '"] move position 35 px 40 px';
254
255 @floatcon = @{get_ws($tmp)->{floating_nodes}};
256
257 is($floatcon[0]->{rect}->{x}, 25, 'moved to position 25 x with criteria');
258 is($floatcon[0]->{rect}->{y}, 30, 'moved to position 30 y with criteria');
259
260 is($floatcon[1]->{rect}->{x}, 35, 'moved to position 35 x with criteria');
261 is($floatcon[1]->{rect}->{y}, 40, 'moved to position 40 y with criteria');
262
263 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression: closing of floating clients did crash i3 when closing the
17 # container which contained this client.
18 #
19 use i3test;
20
21 fresh_workspace;
22
23 cmd 'open';
24 cmd 'mode toggle';
25 cmd 'kill';
26 cmd 'kill';
27
28 does_i3_live;
29
30 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression: make a container floating, kill its parent, make it tiling again
17 #
18 use i3test;
19
20 my $tmp = fresh_workspace;
21
22 cmd 'open';
23 my $left = get_focused($tmp);
24 cmd 'open';
25 my $old = get_focused($tmp);
26 cmd 'split v';
27 cmd 'open';
28 my $floating = get_focused($tmp);
29 diag("focused floating: " . get_focused($tmp));
30 cmd 'mode toggle';
31 sync_with_i3;
32
33 # kill old container
34 cmd qq|[con_id="$old"] focus|;
35 is(get_focused($tmp), $old, 'old container focused');
36 cmd 'kill';
37
38 # kill left container
39 cmd qq|[con_id="$left"] focus|;
40 is(get_focused($tmp), $left, 'old container focused');
41 cmd 'kill';
42
43 # focus floating window, make it tiling again
44 cmd qq|[con_id="$floating"] focus|;
45 is(get_focused($tmp), $floating, 'floating window focused');
46
47 sync_with_i3;
48 cmd 'mode toggle';
49
50 does_i3_live;
51
52 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Check if new containers are opened after the currently focused one instead
17 # of always at the end
18 use List::Util qw(first);
19 use i3test;
20
21 my $i3 = i3(get_socket_path());
22
23 my $tmp = fresh_workspace;
24
25 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
26
27 # Open two new container
28 my $first = open_empty_con($i3);
29
30 ok(@{get_ws_content($tmp)} == 1, 'containers opened');
31
32 my $second = open_empty_con($i3);
33
34 isnt($first, $second, 'different container focused');
35
36 ##############################################################
37 # see if new containers open after the currently focused
38 ##############################################################
39
40 cmd qq|[con_id="$first"] focus|;
41 cmd 'open';
42 my $content = get_ws_content($tmp);
43 ok(@{$content} == 3, 'three containers opened');
44
45 is($content->[0]->{id}, $first, 'first container unmodified');
46 isnt($content->[1]->{id}, $second, 'second container replaced');
47 is($content->[2]->{id}, $second, 'third container unmodified');
48
49 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Check if the focus is correctly restored after closing windows.
17 #
18 use i3test;
19 use List::Util qw(first);
20
21 my $i3 = i3(get_socket_path());
22
23 my $tmp = fresh_workspace;
24
25 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
26
27 my $first = open_empty_con($i3);
28 my $second = open_empty_con($i3);
29
30 cmd 'split v';
31
32 my ($nodes, $focus) = get_ws_content($tmp);
33
34 ok(!$nodes->[1]->{focused}, 'split container not focused');
35 cmd 'focus parent';
36 ($nodes, $focus) = get_ws_content($tmp);
37 ok($nodes->[1]->{focused}, 'split container focused after focus parent');
38
39 my $third = open_empty_con($i3);
40
41 isnt(get_focused($tmp), $second, 'different container focused');
42
43 # We have the following layout now (con is focused):
44 # .----------------.
45 # | split | |
46 # | .----. | con |
47 # | | cn | | |
48 # | `----' | |
49 # `----------------'
50
51 ##############################################################
52 # see if the focus goes down to $first (not to its split parent)
53 # when closing $second
54 ##############################################################
55
56 cmd 'kill';
57 sync_with_i3;
58
59 ($nodes, $focus) = get_ws_content($tmp);
60 is($nodes->[1]->{nodes}->[0]->{id}, $second, 'second container found');
61 ok($nodes->[1]->{nodes}->[0]->{focused}, 'second container focused');
62
63 ##############################################################
64 # another case, using a slightly different layout (regression)
65 ##############################################################
66
67 $tmp = fresh_workspace;
68
69 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
70
71 cmd 'split v';
72 $first = open_empty_con($i3);
73 my $bottom = open_empty_con($i3);
74
75 cmd 'focus up';
76 cmd 'split h';
77 my $middle = open_empty_con($i3);
78 my $right = open_empty_con($i3);
79 cmd 'focus down';
80
81 # We have the following layout now (second is focused):
82 # .----------------------------.
83 # | .------------------------. |
84 # | | first | middle | right | |
85 # | `------------------------' |
86 # |----------------------------|
87 # | |
88 # | second |
89 # | |
90 # `----------------------------'
91
92 # Check if the focus is restored to $right when we close $second
93 cmd 'kill';
94
95 is(get_focused($tmp), $right, 'top right container focused (in focus stack)');
96
97 ($nodes, $focus) = get_ws_content($tmp);
98 my $tr = first { $_->{id} eq $right } @{$nodes->[0]->{nodes}};
99 is($tr->{focused}, 1, 'top right container really has focus');
100
101 ##############################################################
102 # check if focus is correct after closing an unfocused window
103 ##############################################################
104
105 $tmp = fresh_workspace;
106
107 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
108
109 $first = open_empty_con($i3);
110 $middle = open_empty_con($i3);
111 # XXX: the $right empty con will be filled with the x11 window we are creating afterwards
112 $right = open_empty_con($i3);
113 my $win = open_window({ background_color => '#00ff00' });
114
115 cmd qq|[con_id="$middle"] focus|;
116 $win->destroy;
117 sync_with_i3;
118
119 is(get_focused($tmp), $middle, 'middle container focused');
120
121 ##############################################################
122 # check if the workspace container can be closed
123 ##############################################################
124
125 $tmp = fresh_workspace;
126
127 my $window = open_window();
128
129 # one window opened on the current workspace
130 ($nodes, $focus) = get_ws_content($tmp);
131 is(scalar @$nodes, 1, 'workspace contains one node');
132
133 # focus the workspace
134 cmd "focus parent";
135 cmd "focus parent";
136
137 # try to kill the workspace
138 cmd "kill";
139 sync_with_i3;
140
141 # the workspace should now be empty
142 ($nodes, $focus) = get_ws_content($tmp);
143 is(scalar @$nodes, 0, 'workspace is empty');
144
145 ################################################################################
146 # check if killing a workspace also closes floating windows.
147 ################################################################################
148
149 $tmp = fresh_workspace;
150
151 $window = open_window;
152 my $floating_window = open_floating_window;
153
154 # one window opened on the current workspace
155 ($nodes, $focus) = get_ws_content($tmp);
156 is(scalar @$focus, 2, 'workspace contains two nodes');
157
158 # focus the workspace
159 cmd "focus parent";
160 cmd "focus parent";
161
162 # try to kill the workspace
163 cmd "kill";
164 sync_with_i3;
165
166 # the workspace should now be empty
167 ($nodes, $focus) = get_ws_content($tmp);
168 is(scalar @$focus, 0, 'workspace is empty');
169
170 ##############################################################
171 # and now for something completely different:
172 # check if the pointer position is relevant when restoring focus
173 # (it should not be relevant, of course)
174 ##############################################################
175
176 # TODO: add test code as soon as I can reproduce it
177
178 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Check if empty split containers are automatically closed.
17 #
18 use i3test;
19
20 my $i3 = i3(get_socket_path());
21
22 my $tmp = fresh_workspace;
23
24 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
25
26 my $first = open_empty_con($i3);
27 my $second = open_empty_con($i3);
28 cmd qq|[con_id="$first"] focus|;
29
30 cmd 'split v';
31
32 my ($nodes, $focus) = get_ws_content($tmp);
33
34 is($nodes->[0]->{focused}, 0, 'split container not focused');
35
36 # focus the split container
37 cmd 'focus parent';
38 ($nodes, $focus) = get_ws_content($tmp);
39 my $split = $focus->[0];
40 cmd 'focus child';
41
42 $second = open_empty_con($i3);
43
44 isnt($first, $second, 'different container focused');
45
46 ##############################################################
47 # close both windows and see if the split container still exists
48 ##############################################################
49
50 cmd 'kill';
51 cmd 'kill';
52 ($nodes, $focus) = get_ws_content($tmp);
53 isnt($nodes->[0]->{id}, $split, 'split container closed');
54
55 # clean up the remaining containers to ensure this workspace will be garbage
56 # collected.
57 cmd 'kill';
58 cmd 'kill';
59
60 ##############################################################
61 # same thing but this time we are moving the cons away instead
62 # of killing them
63 ##############################################################
64
65 $tmp = fresh_workspace;
66
67 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
68
69 $first = open_empty_con($i3);
70 $second = open_empty_con($i3);
71 cmd qq|[con_id="$first"] focus|;
72
73 cmd 'split v';
74
75 ($nodes, $focus) = get_ws_content($tmp);
76
77 is($nodes->[0]->{focused}, 0, 'split container not focused');
78
79 # focus the split container
80 cmd 'focus parent';
81 ($nodes, $focus) = get_ws_content($tmp);
82 $split = $focus->[0];
83 cmd 'focus child';
84
85 $second = open_empty_con($i3);
86
87 isnt($first, $second, 'different container focused');
88
89 ##############################################################
90 # close both windows and see if the split container still exists
91 ##############################################################
92
93 my $otmp = get_unused_workspace();
94 cmd "move workspace $otmp";
95 cmd "move workspace $otmp";
96 ($nodes, $focus) = get_ws_content($tmp);
97 isnt($nodes->[0]->{id}, $split, 'split container closed');
98
99 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Check if stacking containers can be used independently of
17 # the split mode (horizontal/vertical) of the underlying
18 # container.
19 #
20 use i3test;
21
22 my $i3 = i3(get_socket_path());
23
24 my $tmp = fresh_workspace;
25
26 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
27
28 # Enforce vertical split mode
29 cmd 'split v';
30
31 my $first = open_empty_con($i3);
32 my $second = open_empty_con($i3);
33
34 isnt($first, $second, 'two different containers opened');
35
36 ##############################################################
37 # change mode to stacking and cycle through the containers
38 ##############################################################
39
40 cmd 'layout stacking';
41 is(get_focused($tmp), $second, 'second container still focused');
42
43 cmd 'focus down';
44 is(get_focused($tmp), $first, 'first container focused');
45
46 cmd 'focus up';
47 is(get_focused($tmp), $second, 'second container focused again');
48
49 ##############################################################
50 # now change the orientation to horizontal and cycle
51 ##############################################################
52
53 cmd 'focus parent';
54 cmd 'split h';
55 cmd 'focus child';
56
57 cmd 'focus down';
58 is(get_focused($tmp), $first, 'first container focused');
59
60 cmd 'focus up';
61 is(get_focused($tmp), $second, 'second container focused again');
62
63
64 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Checks if the 'move [window/container] to workspace' command works correctly
17 #
18 use i3test;
19
20 my $i3 = i3(get_socket_path());
21
22 # We move the pointer out of our way to avoid a bug where the focus will
23 # be set to the window under the cursor
24 sync_with_i3;
25 $x->root->warp_pointer(0, 0);
26 sync_with_i3;
27
28 sub move_workspace_test {
29 my ($movecmd) = @_;
30
31 my $tmp = get_unused_workspace();
32 my $tmp2 = get_unused_workspace();
33 cmd "workspace $tmp";
34
35 is_num_children($tmp, 0, 'no containers yet');
36
37 my $first = open_empty_con($i3);
38 my $second = open_empty_con($i3);
39 is_num_children($tmp, 2, 'two containers on first ws');
40
41 cmd "workspace $tmp2";
42 is_num_children($tmp2, 0, 'no containers on second ws yet');
43
44 cmd "workspace $tmp";
45
46 cmd "$movecmd $tmp2";
47 is_num_children($tmp, 1, 'one container on first ws anymore');
48 is_num_children($tmp2, 1, 'one container on second ws');
49 my ($nodes, $focus) = get_ws_content($tmp2);
50
51 is($focus->[0], $second, 'same container on different ws');
52
53 ($nodes, $focus) = get_ws_content($tmp);
54 ok($nodes->[0]->{focused}, 'first container focused on first ws');
55 }
56
57 move_workspace_test('move workspace'); # supported for legacy reasons
58 move_workspace_test('move to workspace');
59 # Those are just synonyms and more verbose ways of saying the same thing:
60 move_workspace_test('move window to workspace');
61 move_workspace_test('move container to workspace');
62
63 ################################################################################
64 # Check that 'move to workspace number <number>' works to move a window to
65 # named workspaces which start with <number>.
66 ################################################################################
67
68 cmd 'workspace 13: meh';
69 cmd 'open';
70 is_num_children('13: meh', 1, 'one container on 13: meh');
71
72 ok(!workspace_exists('13'), 'workspace 13 does not exist yet');
73
74 cmd 'workspace 12';
75 cmd 'open';
76
77 cmd 'move to workspace number 13';
78 is_num_children('13: meh', 2, 'one container on 13: meh');
79 is_num_children('12', 0, 'no container on 12 anymore');
80
81 ok(!workspace_exists('13'), 'workspace 13 does still not exist');
82
83 ################################################################################
84 # Check that 'move to workspace number <number><name>' works to move a window to
85 # named workspaces which start with <number>.
86 ################################################################################
87
88 cmd 'workspace 15: meh';
89 cmd 'open';
90 is_num_children('15: meh', 1, 'one container on 15: meh');
91
92 ok(!workspace_exists('15'), 'workspace 15 does not exist yet');
93 ok(!workspace_exists('15: duh'), 'workspace 15: duh does not exist yet');
94
95 cmd 'workspace 14';
96 cmd 'open';
97
98 cmd 'move to workspace number 15: duh';
99 is_num_children('15: meh', 2, 'two containers on 15: meh');
100 is_num_children('14', 0, 'no container on 14 anymore');
101
102 ok(!workspace_exists('15'), 'workspace 15 does still not exist');
103 ok(!workspace_exists('15: duh'), 'workspace 15 does still not exist');
104
105 ###################################################################
106 # check if 'move workspace next' and 'move workspace prev' work
107 ###################################################################
108
109 # Open two containers on the first workspace, one container on the second
110 # workspace. Because the workspaces are named, they will be sorted by order of
111 # creation.
112 my $tmp = get_unused_workspace();
113 my $tmp2 = get_unused_workspace();
114 cmd "workspace $tmp";
115 is_num_children($tmp, 0, 'no containers yet');
116 my $first = open_empty_con($i3);
117 my $second = open_empty_con($i3);
118 is_num_children($tmp, 2, 'two containers');
119
120 cmd "workspace $tmp2";
121 is_num_children($tmp2, 0, 'no containers yet');
122 my $third = open_empty_con($i3);
123 is_num_children($tmp2, 1, 'one container on second ws');
124
125 # go back to the first workspace, move one of the containers to the next one
126 cmd "workspace $tmp";
127 cmd 'move workspace next';
128 is_num_children($tmp, 1, 'one container on first ws');
129 is_num_children($tmp2, 2, 'two containers on second ws');
130
131 # go to the second workspace and move two containers to the first one
132 cmd "workspace $tmp2";
133 cmd 'move workspace prev';
134 cmd 'move workspace prev';
135 is_num_children($tmp, 3, 'three containers on first ws');
136 is_num_children($tmp2, 0, 'no containers on second ws');
137
138 ###################################################################
139 # check if 'move workspace current' works
140 ###################################################################
141
142 $tmp = get_unused_workspace();
143 $tmp2 = get_unused_workspace();
144
145 cmd "workspace $tmp";
146 $first = open_window(name => 'win-name');
147 is_num_children($tmp, 1, 'one container on first ws');
148
149 cmd "workspace $tmp2";
150 is_num_children($tmp2, 0, 'no containers yet');
151
152 cmd qq|[title="win-name"] move workspace $tmp2|;
153 is_num_children($tmp2, 1, 'one container on second ws');
154
155 cmd qq|[title="win-name"] move workspace $tmp|;
156 is_num_children($tmp2, 0, 'no containers on second ws');
157
158 ###################################################################
159 # check if floating cons are moved to new workspaces properly
160 # (that is, if they are floating on the target ws, too)
161 ###################################################################
162
163 $tmp = get_unused_workspace();
164 $tmp2 = get_unused_workspace();
165 cmd "workspace $tmp";
166
167 cmd "open";
168 cmd "floating toggle";
169
170 my $ws = get_ws($tmp);
171 is(@{$ws->{nodes}}, 0, 'no nodes on workspace');
172 is(@{$ws->{floating_nodes}}, 1, 'one floating node on workspace');
173
174 cmd "move workspace $tmp2";
175
176 $ws = get_ws($tmp2);
177 is(@{$ws->{nodes}}, 0, 'no nodes on workspace');
178 is(@{$ws->{floating_nodes}}, 1, 'one floating node on workspace');
179
180 ################################################################################
181 # Check that 'move workspace number' works correctly.
182 ################################################################################
183
184 $tmp = get_unused_workspace();
185 cmd 'open';
186
187 cmd 'workspace 16';
188 cmd 'open';
189 is_num_children('16', 1, 'one node on ws 16');
190
191 cmd "workspace $tmp";
192 cmd 'open';
193 cmd 'move workspace number 16';
194 is_num_children('16', 2, 'two nodes on ws 16');
195
196 ok(!workspace_exists('17'), 'workspace 17 does not exist yet');
197 cmd 'open';
198 cmd 'move workspace number 17';
199 ok(workspace_exists('17'), 'workspace 17 created by moving');
200 is(@{get_ws('17')->{nodes}}, 1, 'one node on ws 16');
201
202 ################################################################################
203 # The following four tests verify the various 'move workspace' commands when
204 # the selection is itself a workspace.
205 ################################################################################
206
207 # borrowed from 122-split.t
208 # recursively sums up all nodes and their children
209 sub sum_nodes {
210 my ($nodes) = @_;
211
212 return 0 if !@{$nodes};
213
214 my @children = (map { @{$_->{nodes}} } @{$nodes},
215 map { @{$_->{'floating_nodes'}} } @{$nodes});
216
217 return @{$nodes} + sum_nodes(\@children);
218 }
219
220 ############################################################
221 # move workspace 'next|prev'
222 ############################################################
223 $tmp = get_unused_workspace();
224 $tmp2 = get_unused_workspace();
225
226 cmd "workspace $tmp";
227 cmd 'open';
228 is_num_children($tmp, 1, 'one container on first ws');
229
230 cmd "workspace $tmp2";
231 cmd 'open';
232 is_num_children($tmp2, 1, 'one container on second ws');
233 cmd 'open';
234 is_num_children($tmp2, 2, 'two containers on second ws');
235
236 cmd 'focus parent';
237 cmd 'move workspace prev';
238
239 is_num_children($tmp, 2, 'two child containers on first ws');
240 is(sum_nodes(get_ws_content($tmp)), 4, 'four total containers on first ws');
241 is_num_children($tmp2, 0, 'no containers on second ws');
242
243 ############################################################
244 # move workspace current
245 # This is a special case that should be a no-op.
246 ############################################################
247 $tmp = fresh_workspace();
248
249 cmd 'open';
250 is_num_children($tmp, 1, 'one container on first ws');
251 my $tmpcount = sum_nodes(get_ws_content($tmp));
252
253 cmd 'focus parent';
254 cmd "move workspace $tmp";
255
256 is(sum_nodes(get_ws_content($tmp)), $tmpcount, 'number of containers in first ws unchanged');
257
258 ############################################################
259 # move workspace '<name>'
260 ############################################################
261 $tmp2 = get_unused_workspace();
262 $tmp = fresh_workspace();
263
264 cmd 'open';
265 is_num_children($tmp, 1, 'one container on first ws');
266
267 cmd "workspace $tmp2";
268 cmd 'open';
269 is_num_children($tmp2, 1, 'one container on second ws');
270 cmd 'open';
271 is_num_children($tmp2, 2, 'two containers on second ws');
272
273 cmd 'focus parent';
274 cmd "move workspace $tmp";
275
276 is_num_children($tmp, 2, 'two child containers on first ws');
277 is(sum_nodes(get_ws_content($tmp)), 4, 'four total containers on first ws');
278 is_num_children($tmp2, 0, 'no containers on second ws');
279
280 ############################################################
281 # move workspace number '<number>'
282 ############################################################
283 cmd 'workspace 18';
284 cmd 'open';
285 is_num_children('18', 1, 'one container on ws 18');
286
287 cmd 'workspace 19';
288 cmd 'open';
289 is_num_children('19', 1, 'one container on ws 19');
290 cmd 'open';
291 is_num_children('19', 2, 'two containers on ws 19');
292
293 cmd 'focus parent';
294 cmd 'move workspace number 18';
295
296 is_num_children('18', 2, 'two child containers on ws 18');
297 is(sum_nodes(get_ws_content('18')), 4, 'four total containers on ws 18');
298 is_num_children('19', 0, 'no containers on ws 19');
299
300 ###################################################################
301 # move workspace '<name>' with a floating child
302 ###################################################################
303 $tmp2 = get_unused_workspace();
304 $tmp = fresh_workspace();
305 cmd 'open';
306 cmd 'floating toggle';
307 cmd 'open';
308 cmd 'floating toggle';
309 cmd 'open';
310
311 $ws = get_ws($tmp);
312 is_num_children($tmp, 1, 'one container on first workspace');
313 is(@{$ws->{floating_nodes}}, 2, 'two floating nodes on first workspace');
314
315 cmd 'focus parent';
316 cmd "move workspace $tmp2";
317
318 $ws = get_ws($tmp2);
319 is_num_children($tmp2, 1, 'one container on second workspace');
320 is(@{$ws->{floating_nodes}}, 2, 'two floating nodes on second workspace');
321
322 ###################################################################
323 # same as the above, but with only floating children
324 ###################################################################
325 $tmp2 = get_unused_workspace();
326 $tmp = fresh_workspace();
327 cmd 'open';
328 cmd 'floating toggle';
329
330 $ws = get_ws($tmp);
331 is_num_children($tmp, 0, 'no regular nodes on first workspace');
332 is(@{$ws->{floating_nodes}}, 1, 'one floating node on first workspace');
333
334 cmd 'focus parent';
335 cmd "move workspace $tmp2";
336
337 $ws = get_ws($tmp2);
338 is_num_children($tmp2, 0, 'no regular nodes on second workspace');
339 is(@{$ws->{floating_nodes}}, 1, 'one floating node on second workspace');
340
341 ###################################################################
342 # Check that moving an empty workspace using criteria doesn't
343 # create unfocused empty workspace.
344 ###################################################################
345 $tmp2 = get_unused_workspace();
346 $tmp = fresh_workspace();
347 cmd 'mark a';
348 cmd "[con_mark=a] move to workspace $tmp2";
349
350 is (get_ws($tmp2), undef, 'No empty workspace created');
351
352 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Checks if size hints are interpreted correctly.
17 #
18 use i3test i3_config => <<EOT;
19 # i3 config file (v4)
20 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
21
22 default_floating_border none
23 floating_minimum_size -1 x -1
24 floating_maximum_size -1 x -1
25 EOT
26
27 sub open_with_aspect {
28 my ($min_num, $min_den, $max_num, $max_den) = @_;
29 open_floating_window(
30 rect => [0, 0, 100, 100],
31 before_map => sub {
32 my ($window) = @_;
33 my $aspect = X11::XCB::Sizehints::Aspect->new;
34 $aspect->min_num($min_num);
35 $aspect->min_den($min_den);
36 $aspect->max_num($max_num);
37 $aspect->max_den($max_den);
38 $window->hints->aspect($aspect);
39 });
40 }
41
42 ################################################################################
43 # Test aspect ratio set exactly to 2.0
44 ################################################################################
45
46 fresh_workspace;
47 my $win = open_with_aspect(600, 300, 600, 300);
48
49 my $rect = $win->rect;
50 my $ar = $rect->width / $rect->height;
51 cmp_float($ar, 2, 'Window set to floating with aspect ratio 2.0');
52
53 cmd 'resize set 100';
54 $rect = $win->rect;
55 $ar = $rect->width / $rect->height;
56 cmp_float($ar, 2, 'Window resized with aspect ratio kept to 2.0');
57
58 cmd 'resize set 400 100';
59 $rect = $win->rect;
60 $ar = $rect->width / $rect->height;
61 cmp_float($ar, 2, 'Window resized with aspect ratio kept to 2.0');
62
63 # Also check that it is possible to resize by height only
64 cmd 'resize set height 400';
65 $rect = $win->rect;
66 $ar = $rect->width / $rect->height;
67 is($rect->height, 400, 'Window height is 400px');
68 cmp_float($ar, 2, 'Window resized with aspect ratio kept to 2.0');
69
70 cmd 'resize grow height 10';
71 $rect = $win->rect;
72 $ar = $rect->width / $rect->height;
73 is($rect->height, 410, 'Window grew by 10px');
74 cmp_float($ar, 2, 'Window resized with aspect ratio kept to 2.0');
75
76 ################################################################################
77 # Test aspect ratio between 0.5 and 2.0
78 ################################################################################
79
80 fresh_workspace;
81 $win = open_with_aspect(1, 2, 2, 1);
82
83 $rect = $win->rect;
84 $ar = $rect->width / $rect->height;
85 cmp_float($ar, 1, 'Window set to floating with aspect ratio 1.0');
86
87 cmd 'resize set 200';
88 $rect = $win->rect;
89 $ar = $rect->width / $rect->height;
90 is($rect->width, 200, 'Window width is 200px');
91 is($rect->height, 100, 'Window height stayed 100px');
92 cmp_float($ar, 2, 'Window resized, aspect ratio changed to 2.0');
93
94 cmd 'resize set 100 200';
95 $rect = $win->rect;
96 $ar = $rect->width / $rect->height;
97 is($rect->width, 100, 'Window width is 100px');
98 is($rect->height, 200, 'Window height is 200px');
99 cmp_float($ar, 0.5, 'Window resized, aspect ratio changed to 0.5');
100
101 cmd 'resize set 500';
102 $rect = $win->rect;
103 $ar = $rect->width / $rect->height;
104 cmp_float($ar, 2, 'Window resized, aspect ratio changed to maximum 2.0');
105
106 cmd 'resize set 100 400';
107 $rect = $win->rect;
108 $ar = $rect->width / $rect->height;
109 cmp_float($ar, 0.5, 'Window resized, aspect ratio changed to minimum 0.5');
110
111 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 #
4 # Please read the following documents before working on tests:
5 # • https://build.i3wm.org/docs/testsuite.html
6 # (or docs/testsuite)
7 #
8 # • https://build.i3wm.org/docs/lib-i3test.html
9 # (alternatively: perldoc ./testcases/lib/i3test.pm)
10 #
11 # • https://build.i3wm.org/docs/ipc.html
12 # (or docs/ipc)
13 #
14 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
15 # (unless you are already familiar with Perl)
16 #
17 #
18 use i3test;
19
20 cmd 'blargh!';
21
22 does_i3_live;
23
24 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17
18 my $tmp = fresh_workspace;
19
20 #############################################################################
21 # 1: see if focus stays the same when toggling tiling/floating mode
22 #############################################################################
23
24 my $first = open_window;
25 my $second = open_window;
26
27 is($x->input_focus, $second->id, 'second window focused');
28
29 cmd 'floating enable';
30 cmd 'floating disable';
31
32 is($x->input_focus, $second->id, 'second window still focused after mode toggle');
33
34 #############################################################################
35 # 2: see if focus stays on the current floating window if killing another
36 # floating window
37 #############################################################################
38
39 $tmp = fresh_workspace;
40
41 $first = open_window; # window 2
42 $second = open_window; # window 3
43 my $third = open_window; # window 4
44
45 is($x->input_focus, $third->id, 'last container focused');
46
47 cmd 'floating enable';
48
49 cmd '[id="' . $second->id . '"] focus';
50
51 is($x->input_focus, $second->id, 'second con focused');
52
53 cmd 'floating enable';
54
55 # now kill the third one (it's floating). focus should stay unchanged
56 cmd '[id="' . $third->id . '"] kill';
57
58 wait_for_unmap($third);
59
60 is($x->input_focus, $second->id, 'second con still focused after killing third');
61
62
63 #############################################################################
64 # 3: see if the focus gets reverted correctly when closing floating clients
65 # (first to the next floating client, then to the last focused tiling client)
66 #############################################################################
67
68 $tmp = fresh_workspace;
69
70 $first = open_window({ background_color => '#ff0000' }); # window 5
71 $second = open_window({ background_color => '#00ff00' }); # window 6
72 $third = open_window({ background_color => '#0000ff' }); # window 7
73
74 is($x->input_focus, $third->id, 'last container focused');
75
76 cmd 'floating enable';
77
78 cmd '[id="' . $second->id . '"] focus';
79
80 is($x->input_focus, $second->id, 'second con focused');
81
82 cmd 'floating enable';
83
84 # now kill the second one. focus should fall back to the third one, which is
85 # also floating
86 cmd 'kill';
87 wait_for_unmap($second);
88
89 is($x->input_focus, $third->id, 'third con focused');
90
91 cmd 'kill';
92 wait_for_unmap($third);
93
94 is($x->input_focus, $first->id, 'first con focused after killing all floating cons');
95
96 #############################################################################
97 # 4: same test as 3, but with another split con
98 #############################################################################
99
100 $tmp = fresh_workspace;
101
102 $first = open_window({ background_color => '#ff0000' }); # window 5
103 cmd 'split v';
104 cmd 'layout stacked';
105 $second = open_window({ background_color => '#00ff00' }); # window 6
106 $third = open_window({ background_color => '#0000ff' }); # window 7
107 is($x->input_focus, $third->id, 'last container focused');
108
109 cmd '[id="' . $second->id . '"] focus';
110 cmd 'floating enable';
111 cmd '[id="' . $third->id . '"] floating enable';
112
113 sync_with_i3;
114 is($x->input_focus, $second->id, 'second con focused');
115
116 # now kill the second one. focus should fall back to the third one, which is
117 # also floating
118 cmd 'kill';
119 wait_for_unmap($second);
120
121 is($x->input_focus, $third->id, 'third con focused');
122
123 cmd 'kill';
124 wait_for_unmap($third);
125
126 is($x->input_focus, $first->id, 'first con focused after killing all floating cons');
127
128 #############################################################################
129 # 5: see if the 'focus tiling' and 'focus floating' commands work
130 #############################################################################
131
132 $tmp = fresh_workspace;
133
134 $first = open_window({ background_color => '#ff0000' }); # window 8
135 $second = open_window({ background_color => '#00ff00' }); # window 9
136
137 is($x->input_focus, $second->id, 'second container focused');
138
139 cmd 'floating enable';
140
141 is($x->input_focus, $second->id, 'second container focused');
142
143 cmd 'focus tiling';
144
145 is($x->input_focus, $first->id, 'first (tiling) container focused');
146
147 cmd 'focus floating';
148
149 is($x->input_focus, $second->id, 'second (floating) container focused');
150
151 cmd 'focus floating';
152
153 is($x->input_focus, $second->id, 'second (floating) container still focused');
154
155 cmd 'focus mode_toggle';
156
157 is($x->input_focus, $first->id, 'first (tiling) container focused');
158
159 cmd 'focus mode_toggle';
160
161 is($x->input_focus, $second->id, 'second (floating) container focused');
162
163 #############################################################################
164 # 6: see if switching floating focus using the focus left/right command works
165 #############################################################################
166
167 $tmp = fresh_workspace;
168
169 $first = open_floating_window({ background_color => '#ff0000' });# window 10
170 $second = open_floating_window({ background_color => '#00ff00' }); # window 11
171 $third = open_floating_window({ background_color => '#0000ff' }); # window 12
172
173 is($x->input_focus, $third->id, 'third container focused');
174
175 cmd 'focus left';
176
177 is($x->input_focus, $second->id, 'second container focused');
178
179 cmd 'focus left';
180
181 is($x->input_focus, $first->id, 'first container focused');
182
183 cmd 'focus left';
184
185 is($x->input_focus, $third->id, 'focus wrapped to third container');
186
187 cmd 'focus right';
188
189 is($x->input_focus, $first->id, 'focus wrapped to first container');
190
191 cmd 'focus right';
192
193 is($x->input_focus, $second->id, 'focus on second container');
194
195 #############################################################################
196 # 7: verify that focusing the parent of a window inside a floating con goes
197 # up to the grandparent (workspace) and that focusing child from the ws
198 # goes back down to the child of the floating con
199 #############################################################################
200
201 $tmp = fresh_workspace;
202
203 my $tiled = open_window;
204 my $floating = open_floating_window;
205 is($x->input_focus, $floating->id, 'floating window focused');
206
207 cmd 'focus parent';
208
209 is(get_ws($tmp)->{focused}, 1, 'workspace is focused');
210 cmd 'focus child';
211
212 is($x->input_focus, $floating->id, 'floating window focused');
213
214 #############################################################################
215 # 8: verify that focusing a floating window raises it to the top.
216 # This test can't verify that the floating container is visually on top, just
217 # that it is placed on the tail of the floating_head.
218 # See issue: 2572
219 #############################################################################
220
221 $tmp = fresh_workspace;
222
223 $first = open_floating_window;
224 $second = open_floating_window;
225
226 is($x->input_focus, $second->id, 'second floating window focused');
227 my $ws = get_ws($tmp);
228 is($ws->{floating_nodes}->[1]->{nodes}->[0]->{window}, $second->id, 'second on top');
229 is($ws->{floating_nodes}->[0]->{nodes}->[0]->{window}, $first->id, 'first behind');
230
231 cmd '[id=' . $first->id . '] focus';
232
233 is($x->input_focus, $first->id, 'first floating window focused');
234 $ws = get_ws($tmp);
235 is($ws->{floating_nodes}->[1]->{nodes}->[0]->{window}, $first->id, 'first on top');
236 is($ws->{floating_nodes}->[0]->{nodes}->[0]->{window}, $second->id, 'second behind');
237
238 #############################################################################
239 # 9: verify that disabling / enabling floating for a window from a different
240 # workspace maintains the correct focus order.
241 #############################################################################
242
243 sub open_window_helper {
244 my $floating = shift if @_;
245 if ($floating){
246 return open_floating_window;
247 }
248 else {
249 return open_window;
250 }
251 }
252
253 for my $floating (0, 1){
254 $tmp = fresh_workspace;
255 $first = open_window;
256 $second = open_window_helper($floating);
257 is($x->input_focus, $second->id, "second window focused");
258
259 fresh_workspace;
260 cmd "[id=" . $second->id . "] floating toggle";
261 cmd "workspace $tmp";
262 sync_with_i3;
263
264 my $workspace = get_ws($tmp);
265 is($workspace->{floating_nodes}->[0]->{nodes}->[0]->{window}, $second->id, 'second window on first workspace, floating') unless $floating;
266 is($workspace->{nodes}->[1]->{window}, $second->id, 'second window on first workspace, right') unless !$floating;
267 is($x->input_focus, $second->id, 'second window still focused');
268 }
269
270 #############################################################################
271 # 10: verify that toggling floating for an unfocused window on another
272 # workspace doesn't make it focused.
273 #############################################################################
274
275 for my $floating (0, 1){
276 $tmp = fresh_workspace;
277 $first = open_window_helper($floating);
278 $second = open_window;
279 is($x->input_focus, $second->id, 'second (tiling) window focused');
280
281 fresh_workspace;
282 cmd "[id=" . $first->id . "] floating toggle";
283 cmd "workspace $tmp";
284 sync_with_i3;
285
286 my $workspace = get_ws($tmp);
287 is($workspace->{floating_nodes}->[0]->{nodes}->[0]->{window}, $first->id, 'first window on first workspace, floating') unless $floating;
288 is($workspace->{nodes}->[1]->{window}, $first->id, 'first window on first workspace, right') unless !$floating;
289 is($x->input_focus, $second->id, 'second window still focused');
290 }
291
292 #############################################################################
293 # 11: verify that toggling floating for a focused window on another workspace
294 # which has another, unfocused floating window maintains the focus of the
295 # first window.
296 #############################################################################
297 for my $floating (0, 1){
298 $tmp = fresh_workspace;
299 $first = open_window;
300 $second = open_floating_window;
301 is($x->input_focus, $second->id, 'second (floating) window focused');
302 $third = open_window_helper($floating);
303 is($x->input_focus, $third->id, "third (floating = $floating) window focused");
304
305 fresh_workspace;
306 cmd "[id=" . $third->id . "] floating toggle";
307 cmd "workspace $tmp";
308 sync_with_i3;
309
310 my $workspace = get_ws($tmp);
311 is($workspace->{floating_nodes}->[0]->{nodes}->[0]->{window}, $third->id, 'third window on first workspace, floating') unless $floating;
312 is($workspace->{nodes}->[1]->{window}, $third->id, 'third window on first workspace, right') unless !$floating;
313 is($x->input_focus, $third->id, 'third window still focused');
314 }
315
316 #############################################################################
317 # 12: verify that toggling floating for an unfocused window on another
318 # workspace which has another, focused floating window doesn't change focus.
319 #############################################################################
320
321 for my $floating (0, 1){
322 $tmp = fresh_workspace;
323 $first = open_window;
324 $second = open_window_helper($floating);
325 is($x->input_focus, $second->id, "second (floating = $floating) window focused");
326 $third = open_floating_window;
327 is($x->input_focus, $third->id, 'third (floating) window focused');
328
329 fresh_workspace;
330 cmd "[id=" . $second->id . "] floating toggle";
331 cmd "workspace $tmp";
332 sync_with_i3;
333
334 my $workspace = get_ws($tmp);
335 is($workspace->{floating_nodes}->[0]->{nodes}->[0]->{window}, $second->id, 'second window on first workspace, floating') unless $floating;
336 is($workspace->{nodes}->[1]->{window}, $second->id, 'second window on first workspace, right') unless !$floating;
337 is($x->input_focus, $third->id, 'third window still focused');
338 }
339
340 #############################################################################
341 # 13: For layout [H1 [A V1[ B F ] ] ] verify that toggling F's floating
342 # mode maintains its focus.
343 #############################################################################
344
345 for my $floating (0, 1){
346 $tmp = fresh_workspace;
347 $first = open_window;
348 $second = open_window;
349 cmd "split v";
350 sync_with_i3;
351 is($x->input_focus, $second->id, "second (floating = $floating) window focused");
352 $third = open_window_helper($floating);
353 is($x->input_focus, $third->id, 'third (floating) window focused');
354
355 fresh_workspace;
356 cmd "[id=" . $third->id . "] floating toggle";
357 cmd "workspace $tmp";
358 sync_with_i3;
359
360 my $workspace = get_ws($tmp);
361 is($workspace->{floating_nodes}->[0]->{nodes}->[0]->{window}, $third->id, 'third window on first workspace, floating') unless $floating;
362 is($workspace->{nodes}->[1]->{nodes}->[1]->{window}, $third->id, 'third window on first workspace') unless !$floating;
363 is($x->input_focus, $third->id, 'third window still focused');
364 }
365
366 #############################################################################
367 # 14: For layout [H1 [A V1[ H2 [B H2 [ C V2 [ F D ] ] ] ] ] ] verify that
368 # toggling F's floating mode maintains its focus.
369 #############################################################################
370
371 sub kill_and_confirm_focus {
372 my $focus = shift;
373 my $msg = shift;
374 cmd "kill";
375 sync_with_i3;
376 is($x->input_focus, $focus, $msg);
377 }
378
379 $tmp = fresh_workspace;
380 my $A = open_window;
381 my $B = open_window;
382 cmd "split v";
383 my $C = open_window;
384 cmd "split h";
385 my $F = open_window;
386 cmd "split v";
387 my $D = open_window;
388 is($x->input_focus, $D->id, "D is focused");
389
390 sync_with_i3;
391 my $workspace = get_ws($tmp);
392 is($workspace->{nodes}->[1]->{nodes}->[1]->{nodes}->[1]->{nodes}->[0]->{window}, $F->id, 'F opened in its expected position');
393
394 fresh_workspace;
395 cmd "[id=" . $F->id . "] floating enable";
396 cmd "workspace $tmp";
397 sync_with_i3;
398
399 $workspace = get_ws($tmp);
400 is($workspace->{floating_nodes}->[0]->{nodes}->[0]->{window}, $F->id, 'F on first workspace, floating');
401 is($workspace->{nodes}->[1]->{nodes}->[1]->{nodes}->[1]->{nodes}->[0]->{window}, $D->id, 'D where F used to be');
402 is($x->input_focus, $D->id, 'D still focused');
403
404 fresh_workspace;
405 cmd "[id=" . $F->id . "] floating disable";
406 cmd "workspace $tmp";
407 sync_with_i3;
408
409 $workspace = get_ws($tmp);
410 is($workspace->{nodes}->[1]->{nodes}->[1]->{nodes}->[1]->{nodes}->[1]->{window}, $F->id, 'F where D used to be');
411 is($x->input_focus, $D->id, 'D still focused');
412
413 kill_and_confirm_focus($F->id, 'F focused after D is killed');
414 kill_and_confirm_focus($C->id, 'C focused after F is killed');
415 kill_and_confirm_focus($B->id, 'B focused after C is killed');
416 kill_and_confirm_focus($A->id, 'A focused after B is killed');
417
418 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test: when only having a floating window on a workspace, it should
17 # not be deleted.
18
19 use i3test;
20
21 my $i3 = i3(get_socket_path());
22
23 my $tmp = fresh_workspace;
24
25 #############################################################################
26 # 1: open a floating window, get it mapped
27 #############################################################################
28
29 ok(workspace_exists($tmp), "workspace $tmp exists");
30
31 # Create a floating window which is smaller than the minimum enforced size of i3
32 my $window = open_floating_window;
33 ok($window->mapped, 'Window is mapped');
34
35 # switch to a different workspace, see if the window is still mapped?
36
37 my $otmp = fresh_workspace;
38
39 ok(workspace_exists($otmp), "new workspace $otmp exists");
40 ok(workspace_exists($tmp), "old workspace $tmp still exists");
41
42 ################################################################################
43 # 2: Similar test: Have two floating windows on a workspace, close one of them.
44 # The workspace should not be closed. Regression present until (including) commit
45 # 1f2c9306a27cced83ad960e929bb9e9a163b7843
46 ################################################################################
47
48 $tmp = fresh_workspace;
49
50 ok(workspace_exists($tmp), "workspace $tmp exists");
51
52 # Create a floating window which is smaller than the minimum enforced size of i3
53 my $first = open_floating_window;
54 my $second = open_floating_window;
55 ok($first->mapped, 'Window is mapped');
56 ok($second->mapped, 'Window is mapped');
57
58 $otmp = fresh_workspace;
59
60 ok(workspace_exists($otmp), "new workspace $otmp exists");
61 ok(workspace_exists($tmp), "old workspace $tmp still exists");
62
63 $first->unmap;
64 wait_for_unmap $first;
65
66 ok(workspace_exists($otmp), "new workspace $otmp exists");
67 ok(workspace_exists($tmp), "old workspace $tmp still exists");
68
69 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test: Floating windows were not correctly unmapped when switching
17 # to a different workspace.
18
19 use i3test;
20
21 my $i3 = i3(get_socket_path());
22
23 my $tmp = fresh_workspace;
24
25 #############################################################################
26 # 1: open a floating window, get it mapped
27 #############################################################################
28
29 # Create a floating window which is smaller than the minimum enforced size of i3
30 my $window = open_floating_window;
31 ok($window->mapped, 'Window is mapped');
32
33 # switch to a different workspace, see if the window is still mapped?
34
35 my $otmp = fresh_workspace;
36
37 sync_with_i3;
38
39 ok(!$window->mapped, 'Window is not mapped after switching ws');
40
41 cmd "nop testcase done";
42
43 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test: New windows were attached to the container of a floating window
17 # if only a floating window is present on the workspace.
18
19 use i3test;
20
21 my $i3 = i3(get_socket_path());
22
23 my $tmp = fresh_workspace;
24
25 #############################################################################
26 # 1: open a floating window, get it mapped
27 #############################################################################
28
29 # Create a floating window
30 my $window = open_floating_window;
31 ok($window->mapped, 'Window is mapped');
32
33 my $ws = get_ws($tmp);
34 my ($nodes, $focus) = get_ws_content($tmp);
35
36 is(@{$ws->{floating_nodes}}, 1, 'one floating node');
37 is(@{$nodes}, 0, 'no tiling nodes');
38
39 # Create a tiling window
40 my $twindow = open_window;
41
42 ($nodes, $focus) = get_ws_content($tmp);
43
44 is(@{$nodes}, 1, 'one tiling node');
45
46 #############################################################################
47 # 2: similar case: floating windows should be attached at the currently focused
48 # position in the workspace (for example a stack), not just at workspace level.
49 #############################################################################
50
51 $tmp = fresh_workspace;
52
53 my $first = open_window;
54 my $second = open_window;
55
56 cmd 'layout stacked';
57
58 $ws = get_ws($tmp);
59 is(@{$ws->{floating_nodes}}, 0, 'no floating nodes so far');
60 is(@{$ws->{nodes}}, 1, 'one tiling node (stacked con)');
61
62 # Create a floating window
63 $window = open_floating_window;
64 ok($window->mapped, 'Window is mapped');
65
66 $ws = get_ws($tmp);
67 is(@{$ws->{floating_nodes}}, 1, 'one floating nodes');
68 is(@{$ws->{nodes}}, 1, 'one tiling node (stacked con)');
69
70 my $third = open_window;
71
72
73 $ws = get_ws($tmp);
74 is(@{$ws->{floating_nodes}}, 1, 'one floating nodes');
75 is(@{$ws->{nodes}}, 1, 'one tiling node (stacked con)');
76
77 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Check if numbered workspaces and named workspaces are sorted in the right way
17 # in get_workspaces IPC output (necessary for i3bar etc.).
18 use i3test;
19
20 my $i3 = i3(get_socket_path());
21
22 sub check_order {
23 my ($msg) = @_;
24
25 my @ws = @{$i3->get_workspaces->recv};
26 my @nums = map { $_->{num} } grep { $_->{num} != -1 } @ws;
27 my @sorted = sort @nums;
28
29 is_deeply(\@nums, \@sorted, $msg);
30 }
31
32 check_order('workspace order alright before testing');
33
34 #############################################################################
35 # open a window to keep this ws open
36 #############################################################################
37
38 cmd "workspace 93";
39
40 open_window;
41
42 my @ws = @{$i3->get_workspaces->recv};
43 my @f = grep { defined($_->{num}) && $_->{num} == 93 } @ws;
44 is(@f, 1, 'ws 93 found by num');
45 check_order('workspace order alright after opening 93');
46
47 cmd "workspace 92";
48 open_window;
49 check_order('workspace order alright after opening 92');
50
51 cmd "workspace 94";
52 open_window;
53 check_order('workspace order alright after opening 94');
54
55 cmd "workspace 96";
56 open_window;
57 check_order('workspace order alright after opening 96');
58
59 cmd "workspace foo";
60 open_window;
61 check_order('workspace order alright after opening foo');
62
63 cmd "workspace 91";
64 open_window;
65 check_order('workspace order alright after opening 91');
66
67 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression: Check if the focus stays the same when switching the layout
17 # bug introduced by 77d0d42ed2d7ac8cafe267c92b35a81c1b9491eb
18 use i3test;
19
20 my $i3 = i3(get_socket_path());
21
22 sub check_order {
23 my ($msg) = @_;
24
25 my @ws = @{$i3->get_workspaces->recv};
26 my @nums = map { $_->{num} } grep { defined($_->{num}) } @ws;
27 my @sorted = sort @nums;
28
29 is_deeply(\@nums, \@sorted, $msg);
30 }
31
32 my $tmp = fresh_workspace;
33
34 my $left = open_window;
35 my $mid = open_window;
36 my $right = open_window;
37
38 diag("left = " . $left->id . ", mid = " . $mid->id . ", right = " . $right->id);
39
40 is($x->input_focus, $right->id, 'Right window focused');
41
42 cmd 'focus left';
43
44 is($x->input_focus, $mid->id, 'Mid window focused');
45
46 cmd 'layout stacked';
47
48 is($x->input_focus, $mid->id, 'Mid window focused');
49
50 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests resizing tiling containers
17 use i3test;
18
19 my ($left, $right);
20 my $tmp = fresh_workspace;
21
22 cmd 'split v';
23
24 my $top = open_window;
25 my $bottom = open_window;
26
27 diag("top = " . $top->id . ", bottom = " . $bottom->id);
28
29 is($x->input_focus, $bottom->id, 'Bottom window focused');
30
31 ############################################################
32 # resize
33 ############################################################
34
35 cmd 'resize grow up 10 px or 25 ppt';
36
37 my ($nodes, $focus) = get_ws_content($tmp);
38
39 cmp_float($nodes->[0]->{percent}, 0.25, 'top window got only 25%');
40 cmp_float($nodes->[1]->{percent}, 0.75, 'bottom window got 75%');
41
42
43 ############################################################
44 # split and check if the 'percent' factor is still correct
45 ############################################################
46
47 cmd 'split h';
48
49 ($nodes, $focus) = get_ws_content($tmp);
50
51 cmp_float($nodes->[0]->{percent}, 0.25, 'top window got only 25%');
52 cmp_float($nodes->[1]->{percent}, 0.75, 'bottom window got 75%');
53
54 ############################################################
55 # checks that resizing within stacked/tabbed cons works
56 ############################################################
57
58 $tmp = fresh_workspace;
59
60 cmd 'split v';
61
62 $top = open_window;
63 $bottom = open_window;
64
65 cmd 'split h';
66 cmd 'layout stacked';
67
68 ($nodes, $focus) = get_ws_content($tmp);
69 cmp_float($nodes->[0]->{percent}, 0.5, 'top window got 50%');
70 cmp_float($nodes->[1]->{percent}, 0.5, 'bottom window got 50%');
71
72 cmd 'resize grow up 10 px or 25 ppt';
73
74 ($nodes, $focus) = get_ws_content($tmp);
75 cmp_float($nodes->[0]->{percent}, 0.25, 'top window got 25%');
76 cmp_float($nodes->[1]->{percent}, 0.75, 'bottom window got 75%');
77
78 ############################################################
79 # Checks that resizing in the parent's parent's orientation works.
80 # Take for example a horizontal workspace with one window on the left side and
81 # a v-split container with two windows on the right side. Focus is on the
82 # bottom right window, use 'resize left'.
83 ############################################################
84
85 $tmp = fresh_workspace;
86
87 $left = open_window;
88 $right = open_window;
89
90 cmd 'split v';
91
92 $top = open_window;
93 $bottom = open_window;
94
95 ($nodes, $focus) = get_ws_content($tmp);
96 cmp_float($nodes->[0]->{percent}, 0.5, 'left window got 50%');
97 cmp_float($nodes->[1]->{percent}, 0.5, 'right window got 50%');
98
99 cmd 'resize grow left 10 px or 25 ppt';
100
101 ($nodes, $focus) = get_ws_content($tmp);
102 cmp_float($nodes->[0]->{percent}, 0.25, 'left window got 25%');
103 cmp_float($nodes->[1]->{percent}, 0.75, 'right window got 75%');
104
105 ################################################################################
106 # Check that the resize grow/shrink width/height syntax works.
107 ################################################################################
108
109 # Use two windows
110 $tmp = fresh_workspace;
111
112 $left = open_window;
113 $right = open_window;
114
115 cmd 'resize grow width 10 px or 25 ppt';
116
117 ($nodes, $focus) = get_ws_content($tmp);
118 cmp_float($nodes->[0]->{percent}, 0.25, 'left window got 25%');
119 cmp_float($nodes->[1]->{percent}, 0.75, 'right window got 75%');
120
121 # Now test it with four windows
122 $tmp = fresh_workspace;
123
124 open_window for (1..4);
125
126 cmd 'resize grow width 10 px or 25 ppt';
127
128 ($nodes, $focus) = get_ws_content($tmp);
129 cmp_float($nodes->[0]->{percent}, 0.166666666666667, 'first window got 16%');
130 cmp_float($nodes->[1]->{percent}, 0.166666666666667, 'second window got 16%');
131 cmp_float($nodes->[2]->{percent}, 0.166666666666667, 'third window got 16%');
132 cmp_float($nodes->[3]->{percent}, 0.50, 'fourth window got 50%');
133
134 # height should be a no-op in this situation
135 cmd 'resize grow height 10 px or 25 ppt';
136
137 ($nodes, $focus) = get_ws_content($tmp);
138 cmp_float($nodes->[0]->{percent}, 0.166666666666667, 'first window got 16%');
139 cmp_float($nodes->[1]->{percent}, 0.166666666666667, 'second window got 16%');
140 cmp_float($nodes->[2]->{percent}, 0.166666666666667, 'third window got 16%');
141 cmp_float($nodes->[3]->{percent}, 0.50, 'fourth window got 50%');
142
143 ################################################################################
144 # Same but using pixels instead of ppt.
145 ################################################################################
146
147 # Use two windows
148 $tmp = fresh_workspace;
149
150 $left = open_window;
151 $right = open_window;
152
153 ($nodes, $focus) = get_ws_content($tmp);
154 my @widths = ($nodes->[0]->{rect}->{width}, $nodes->[1]->{rect}->{width});
155
156 cmd 'resize grow width 10 px';
157
158 ($nodes, $focus) = get_ws_content($tmp);
159 cmp_float($nodes->[0]->{rect}->{width}, $widths[0] - 10, 'left window is 10px smaller');
160 cmp_float($nodes->[1]->{rect}->{width}, $widths[1] + 10, 'right window is 10px larger');
161
162 # Now test it with four windows
163 $tmp = fresh_workspace;
164
165 open_window for (1..4);
166
167 ($nodes, $focus) = get_ws_content($tmp);
168 my $width = $nodes->[0]->{rect}->{width};
169
170 cmd 'resize grow width 10 px';
171
172 ($nodes, $focus) = get_ws_content($tmp);
173 cmp_float($nodes->[3]->{rect}->{width}, $width + 10, 'last window is 10px larger');
174
175 ################################################################################
176 # Same but for height
177 ################################################################################
178
179 # Use two windows
180 $tmp = fresh_workspace;
181 cmd 'split v';
182
183 $left = open_window;
184 $right = open_window;
185
186 ($nodes, $focus) = get_ws_content($tmp);
187 my @heights = ($nodes->[0]->{rect}->{height}, $nodes->[1]->{rect}->{height});
188
189 cmd 'resize grow height 10 px';
190
191 ($nodes, $focus) = get_ws_content($tmp);
192 cmp_float($nodes->[0]->{rect}->{height}, $heights[0] - 10, 'left window is 10px smaller');
193 cmp_float($nodes->[1]->{rect}->{height}, $heights[1] + 10, 'right window is 10px larger');
194
195 # Now test it with four windows
196 $tmp = fresh_workspace;
197 cmd 'split v';
198
199 open_window for (1..4);
200
201 ($nodes, $focus) = get_ws_content($tmp);
202 my $height = $nodes->[0]->{rect}->{height};
203
204 cmd 'resize grow height 10 px';
205
206 ($nodes, $focus) = get_ws_content($tmp);
207 cmp_float($nodes->[3]->{rect}->{height}, $height + 10, 'last window is 10px larger');
208
209 ################################################################################
210 # Check that we can grow tiled windows by pixels
211 ################################################################################
212
213 $tmp = fresh_workspace;
214
215 $left = open_window;
216 $right = open_window;
217
218 ($nodes, $focus) = get_ws_content($tmp);
219 cmp_float($nodes->[0]->{rect}->{width}, 640, 'left window is 640px');
220 cmp_float($nodes->[1]->{rect}->{width}, 640, 'right window is 640px');
221
222 cmd 'resize grow left 10px';
223 ($nodes, $focus) = get_ws_content($tmp);
224 cmp_float($nodes->[0]->{rect}->{width}, 630, 'left window is 630px');
225 cmp_float($nodes->[1]->{rect}->{width}, 650, 'right window is 650px');
226
227 ################################################################################
228 # Check that we can shrink tiled windows by pixels
229 ################################################################################
230
231 $tmp = fresh_workspace;
232
233 $left = open_window;
234 $right = open_window;
235
236 ($nodes, $focus) = get_ws_content($tmp);
237 cmp_float($nodes->[0]->{rect}->{width}, 640, 'left window is 640px');
238 cmp_float($nodes->[1]->{rect}->{width}, 640, 'right window is 640px');
239
240 cmd 'resize shrink left 10px';
241 ($nodes, $focus) = get_ws_content($tmp);
242 cmp_float($nodes->[0]->{rect}->{width}, 650, 'left window is 650px');
243 cmp_float($nodes->[1]->{rect}->{width}, 630, 'right window is 630px');
244
245
246 ################################################################################
247 # Check that we can shrink vertical tiled windows by pixels
248 ################################################################################
249
250 $tmp = fresh_workspace;
251
252 cmd 'split v';
253
254 $top = open_window;
255 $bottom = open_window;
256
257 ($nodes, $focus) = get_ws_content($tmp);
258 my @heights = ($nodes->[0]->{rect}->{height}, $nodes->[1]->{rect}->{height});
259
260 cmd 'resize grow up 10px';
261 ($nodes, $focus) = get_ws_content($tmp);
262 cmp_float($nodes->[0]->{rect}->{height}, $heights[0] - 10, 'top window is 10px larger');
263 cmp_float($nodes->[1]->{rect}->{height}, $heights[1] + 10, 'bottom window is 10px smaller');
264
265 ################################################################################
266 # Check that we can shrink vertical tiled windows by pixels
267 ################################################################################
268
269 $tmp = fresh_workspace;
270
271 cmd 'split v';
272
273 $top = open_window;
274 $bottom = open_window;
275
276 ($nodes, $focus) = get_ws_content($tmp);
277 my @heights = ($nodes->[0]->{rect}->{height}, $nodes->[1]->{rect}->{height});
278
279 cmd 'resize shrink up 10px';
280 ($nodes, $focus) = get_ws_content($tmp);
281 cmp_float($nodes->[0]->{rect}->{height}, $heights[0] + 10, 'top window is 10px smaller');
282 cmp_float($nodes->[1]->{rect}->{height}, $heights[1] - 10, 'bottom window is 10px larger');
283
284 ################################################################################
285 # Check that the resize grow/shrink width/height syntax works if a nested split
286 # was set on the container, but no sibling has been opened yet. See #2015.
287 ################################################################################
288
289 $tmp = fresh_workspace;
290 $left = open_window;
291 $right = open_window;
292
293 cmd 'split h';
294 cmd 'resize grow width 10px or 25 ppt';
295
296 ($nodes, $focus) = get_ws_content($tmp);
297 cmp_float($nodes->[0]->{percent}, 0.25, 'left window got 25%');
298 cmp_float($nodes->[1]->{percent}, 0.75, 'right window got 75%');
299
300 ############################################################
301 # checks that resizing floating windows works
302 ############################################################
303
304 $tmp = fresh_workspace;
305
306 $top = open_window;
307
308 cmd 'floating enable';
309
310 my @content = @{get_ws($tmp)->{floating_nodes}};
311 cmp_ok(@content, '==', 1, 'one floating node on this ws');
312
313 # up
314 my $oldrect = $content[0]->{rect};
315
316 cmd 'resize grow up 10 px or 25 ppt';
317
318 @content = @{get_ws($tmp)->{floating_nodes}};
319 cmp_ok($content[0]->{rect}->{y}, '<', $oldrect->{y}, 'y smaller than before');
320 cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y} - 10, 'y exactly 10 px smaller');
321 cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x untouched');
322 cmp_ok($content[0]->{rect}->{height}, '>', $oldrect->{height}, 'height bigger than before');
323 cmp_ok($content[0]->{rect}->{height}, '==', $oldrect->{height} + 10, 'height exactly 10 px higher');
324 cmp_ok($content[0]->{rect}->{width}, '==', $oldrect->{width}, 'x untouched');
325
326 # up, but with a different amount of px
327 $oldrect = $content[0]->{rect};
328
329 cmd 'resize grow up 12 px or 25 ppt';
330
331 @content = @{get_ws($tmp)->{floating_nodes}};
332 cmp_ok($content[0]->{rect}->{y}, '<', $oldrect->{y}, 'y smaller than before');
333 cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y} - 12, 'y exactly 10 px smaller');
334 cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x untouched');
335 cmp_ok($content[0]->{rect}->{height}, '>', $oldrect->{height}, 'height bigger than before');
336 cmp_ok($content[0]->{rect}->{height}, '==', $oldrect->{height} + 12, 'height exactly 10 px higher');
337 cmp_ok($content[0]->{rect}->{width}, '==', $oldrect->{width}, 'x untouched');
338
339 # left
340 $oldrect = $content[0]->{rect};
341
342 cmd 'resize grow left 10 px or 25 ppt';
343
344 @content = @{get_ws($tmp)->{floating_nodes}};
345 cmp_ok($content[0]->{rect}->{x}, '<', $oldrect->{x}, 'x smaller than before');
346 cmp_ok($content[0]->{rect}->{width}, '>', $oldrect->{width}, 'width bigger than before');
347
348 # right
349 $oldrect = $content[0]->{rect};
350
351 cmd 'resize grow right 10 px or 25 ppt';
352
353 @content = @{get_ws($tmp)->{floating_nodes}};
354 cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x the same as before');
355 cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y the same as before');
356 cmp_ok($content[0]->{rect}->{width}, '>', $oldrect->{width}, 'width bigger than before');
357 cmp_ok($content[0]->{rect}->{height}, '==', $oldrect->{height}, 'height the same as before');
358
359 # down
360 $oldrect = $content[0]->{rect};
361
362 cmd 'resize grow down 10 px or 25 ppt';
363
364 @content = @{get_ws($tmp)->{floating_nodes}};
365 cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x the same as before');
366 cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y the same as before');
367 cmp_ok($content[0]->{rect}->{height}, '>', $oldrect->{height}, 'height bigger than before');
368 cmp_ok($content[0]->{rect}->{width}, '==', $oldrect->{width}, 'width the same as before');
369
370 # grow width
371 $oldrect = $content[0]->{rect};
372
373 cmd 'resize grow width 10px or 10ppt';
374
375 @content = @{get_ws($tmp)->{floating_nodes}};
376 cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x the same as before');
377 cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y the same as before');
378 cmp_ok($content[0]->{rect}->{height}, '==', $oldrect->{height}, 'height the same as before');
379 cmp_ok($content[0]->{rect}->{width}, '>', $oldrect->{width}, 'width bigger than before');
380
381 # shrink width
382 $oldrect = $content[0]->{rect};
383
384 cmd 'resize shrink width 10px or 10ppt';
385
386 @content = @{get_ws($tmp)->{floating_nodes}};
387 cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x the same as before');
388 cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y the same as before');
389 cmp_ok($content[0]->{rect}->{height}, '==', $oldrect->{height}, 'height the same as before');
390 cmp_ok($content[0]->{rect}->{width}, '<', $oldrect->{width}, 'width smaller than before');
391
392 # grow height
393 $oldrect = $content[0]->{rect};
394
395 cmd 'resize grow height 10px or 10ppt';
396
397 @content = @{get_ws($tmp)->{floating_nodes}};
398 cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x the same as before');
399 cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y the same as before');
400 cmp_ok($content[0]->{rect}->{height}, '>', $oldrect->{height}, 'height bigger than before');
401 cmp_ok($content[0]->{rect}->{width}, '==', $oldrect->{width}, 'width the same as before');
402
403 # shrink height
404 $oldrect = $content[0]->{rect};
405
406 cmd 'resize shrink height 10px or 10ppt';
407
408 @content = @{get_ws($tmp)->{floating_nodes}};
409 cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x the same as before');
410 cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y the same as before');
411 cmp_ok($content[0]->{rect}->{height}, '<', $oldrect->{height}, 'height smaller than before');
412 cmp_ok($content[0]->{rect}->{width}, '==', $oldrect->{width}, 'width the same as before');
413
414 ################################################################################
415 # Check that resizing with criteria works
416 ################################################################################
417
418 $tmp = fresh_workspace;
419
420 $left = open_floating_window;
421 $right = open_floating_window;
422
423 sub get_floating_rect {
424 my ($window_id) = @_;
425
426 my $floating_nodes = get_ws($tmp)->{floating_nodes};
427 for my $floating_node (@$floating_nodes) {
428 # Get all the windows within that floating container
429 my @window_ids = map { $_->{window} } @{$floating_node->{nodes}};
430 if ($window_id ~~ @window_ids) {
431 return $floating_node->{rect};
432 }
433 }
434
435 return undef;
436 }
437
438 # focus is on the right window, so we resize the left one using criteria
439 my $leftold = get_floating_rect($left->id);
440 my $rightold = get_floating_rect($right->id);
441 cmd '[id="' . $left->id . '"] resize grow height 10px or 10ppt';
442
443 my $leftnew = get_floating_rect($left->id);
444 my $rightnew = get_floating_rect($right->id);
445 is($rightnew->{height}, $rightold->{height}, 'height of right container unchanged');
446 is($leftnew->{height}, $leftold->{height} + 10, 'height of left container changed');
447
448 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression: move a floating window to a different workspace crashes i3
17 #
18 use i3test;
19
20 my $tmp = fresh_workspace;
21 my $otmp = get_unused_workspace();
22
23 cmd 'open';
24 cmd 'mode toggle';
25 cmd "move workspace $otmp";
26
27 does_i3_live;
28
29 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression: floating windows are tiling after restarting, closing them crashes i3
17 #
18 use i3test;
19
20 my $tmp = fresh_workspace;
21
22 cmd 'open';
23 cmd 'floating toggle';
24
25 my $ws = get_ws($tmp);
26 is(scalar @{$ws->{nodes}}, 0, 'no tiling nodes');
27 is(scalar @{$ws->{floating_nodes}}, 1, 'precisely one floating node');
28
29 cmd 'restart';
30
31 diag('Checking if i3 still lives');
32
33 does_i3_live;
34
35 $ws = get_ws($tmp);
36 is(scalar @{$ws->{nodes}}, 0, 'no tiling nodes');
37 is(scalar @{$ws->{floating_nodes}}, 1, 'precisely one floating node');
38
39 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression: when resizing two containers on a workspace, opening a floating
17 # client, then closing it again, i3 will re-distribute the space on the
18 # workspace as if a tiling container was closed, leading to the containers
19 # taking much more space than they possibly could.
20 #
21 use i3test;
22 use List::Util qw(sum);
23
24 my $tmp = fresh_workspace;
25
26 my $first = open_window;
27 my $second = open_window;
28
29 my ($nodes, $focus) = get_ws_content($tmp);
30 my $old_sum = sum map { $_->{rect}->{width} } @{$nodes};
31
32 cmd 'resize grow left 10 px or 25 ppt';
33 cmd 'split v';
34
35 sync_with_i3;
36
37 my $third = open_window;
38
39 cmd 'mode toggle';
40 sync_with_i3;
41
42 cmd 'kill';
43 sync_with_i3;
44
45 ($nodes, $focus) = get_ws_content($tmp);
46 my $new_sum = sum map { $_->{rect}->{width} } @{$nodes};
47
48 is($old_sum, $new_sum, 'combined container width is still equal');
49
50 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # by moving the window in the opposite orientation that its parent has, we
17 # force i3 to create a new split container with the appropriate orientation.
18 # However, when doing that two times in a row, we end up with two split
19 # containers which are then redundant (workspace is horizontal, then v-split,
20 # then h-split – we could just append the children of the latest h-split to the
21 # workspace itself).
22 #
23 # This testcase checks that the tree is properly flattened after moving.
24 #
25 use i3test;
26
27 my $tmp = fresh_workspace;
28
29 my $left = open_window;
30 my $mid = open_window;
31 my $right = open_window;
32
33 cmd 'move up';
34 cmd 'move right';
35 my $ws = get_ws($tmp);
36
37 is($ws->{layout}, 'splith', 'workspace layout is splith');
38 is(@{$ws->{nodes}}, 3, 'all three windows on workspace level');
39
40 ################################################################################
41 # Ticket #1053 provides a sequence of operations where the flattening does not
42 # work correctly:
43 ################################################################################
44
45 $tmp = fresh_workspace;
46
47 my $tab1 = open_window;
48 my $tab2 = open_window;
49 $mid = open_window;
50 $right = open_window;
51 cmd 'focus right';
52 cmd 'split v';
53 cmd 'focus right';
54 cmd 'move left';
55 cmd 'layout tabbed';
56 cmd 'focus parent';
57 cmd 'split v';
58
59 $ws = get_ws($tmp);
60 my @nodes = @{$ws->{nodes}};
61 is(@nodes, 3, 'all three windows on workspace level');
62 is($nodes[0]->{layout}, 'splitv', 'first node is splitv');
63 is(@{$nodes[0]->{nodes}}, 1, 'one node in the first node');
64 is($nodes[0]->{nodes}->[0]->{layout}, 'tabbed', 'tabbed layout');
65 is(@{$nodes[0]->{nodes}->[0]->{nodes}}, 2, 'two nodes in that node');
66
67 cmd 'focus right';
68 cmd 'move left';
69
70 $ws = get_ws($tmp);
71 @nodes = @{$ws->{nodes}};
72 is(@nodes, 2, 'all three windows on workspace level');
73
74 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 use i3test;
17
18 my $tmp = fresh_workspace;
19
20 my $left = open_window;
21 my $mid = open_window;
22
23 cmd 'split v';
24 my $bottom = open_window;
25
26 my ($nodes, $focus) = get_ws_content($tmp);
27
28 #############################################################################
29 # 1: open a floating window, get it mapped
30 #############################################################################
31
32 # Create a floating window
33 my $window = open_floating_window;
34 ok($window->mapped, 'Window is mapped');
35
36 ($nodes, $focus) = get_ws_content($tmp);
37 is(@{$nodes->[1]->{nodes}}, 2, 'two windows in split con');
38
39 #############################################################################
40 # 2: make it tiling, see where it ends up
41 #############################################################################
42
43 cmd 'floating toggle';
44
45 ($nodes, $focus) = get_ws_content($tmp);
46
47 is(@{$nodes->[1]->{nodes}}, 3, 'three windows in split con after floating toggle');
48
49 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test for moving a con outside of a floating con when there are no
17 # tiling cons on a workspace
18 #
19 use i3test;
20
21 sub sync_cmd {
22 cmd @_;
23 sync_with_i3;
24 }
25
26 my $tmp = fresh_workspace;
27
28 my $left = open_window;
29 my $mid = open_window;
30 my $right = open_window;
31
32 # go to workspace level
33 sync_cmd 'focus parent';
34
35 # make it floating
36 sync_cmd 'mode toggle';
37
38 # move the con outside the floating con
39 sync_cmd 'move up';
40
41 does_i3_live;
42
43 # move another con outside
44 sync_cmd '[id="' . $mid->id . '"] focus';
45 sync_cmd 'move up';
46
47 does_i3_live;
48
49 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test for correct focus behaviour when moving a floating con to
17 # another workspace.
18 #
19 use i3test;
20
21 my $tmp = fresh_workspace;
22
23 # open a tiling window on the first workspace
24 open_window;
25 my $first = get_focused($tmp);
26
27 # on a different ws, open a floating window
28 my $otmp = fresh_workspace;
29 open_window;
30 my $float = get_focused($otmp);
31 cmd 'mode toggle';
32 sync_with_i3;
33
34 # move the floating con to first workspace
35 cmd "move workspace $tmp";
36 sync_with_i3;
37
38 # switch to the first ws and check focus
39 is(get_focused($tmp), $float, 'floating client correctly focused');
40
41 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test for inplace restarting with dock clients
17 #
18 use i3test;
19
20 my $tmp = fresh_workspace;
21
22 #####################################################################
23 # verify that there is no dock window yet
24 #####################################################################
25
26 # Children of all dockareas
27 my @docked = get_dock_clients;
28
29 is(@docked, 0, 'no dock clients yet');
30
31 # open a dock client
32
33 my $window = open_window({
34 background_color => '#FF0000',
35 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
36 });
37
38 #####################################################################
39 # check that we can find it in the layout tree at the expected position
40 #####################################################################
41
42 @docked = get_dock_clients;
43 is(@docked, 1, 'one dock client found');
44
45 # verify the height
46 my $docknode = $docked[0];
47
48 is($docknode->{rect}->{height}, 30, 'dock node has unchanged height');
49
50 # perform an inplace-restart
51 cmd 'restart';
52
53 does_i3_live;
54
55
56 #####################################################################
57 # check that we can still find the dock client
58 #####################################################################
59
60 @docked = get_dock_clients;
61 is(@docked, 1, 'one dock client found');
62 $docknode = $docked[0];
63
64 is($docknode->{rect}->{height}, 30, 'dock node has unchanged height after restart');
65
66 $window->destroy;
67
68 wait_for_unmap $window;
69
70 @docked = get_dock_clients;
71 is(@docked, 0, 'no dock clients found');
72
73 #####################################################################
74 # create a dock client with a 1px border
75 #####################################################################
76
77 $window = open_window({
78 border => 1,
79 rect => [ 0, 0, 30, 20 ],
80 background_color => '#00FF00',
81 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
82 });
83
84 @docked = get_dock_clients;
85 is(@docked, 1, 'one dock client found');
86 $docknode = $docked[0];
87
88 is($docknode->{rect}->{height}, 20, 'dock node has unchanged height');
89
90 cmd 'restart';
91
92 @docked = get_dock_clients;
93 is(@docked, 1, 'one dock client found');
94 $docknode = $docked[0];
95
96 is($docknode->{rect}->{height}, 20, 'dock node has unchanged height');
97
98
99 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test for setting a window to floating, tiling and opening a new window
17 #
18 use i3test;
19
20 fresh_workspace;
21
22 cmd 'open';
23 cmd 'mode toggle';
24 cmd 'mode toggle';
25 cmd 'open';
26
27 does_i3_live;
28
29 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test for using level-up to get to the 'content'-container and
17 # toggle floating
18 #
19 use i3test;
20
21 fresh_workspace;
22
23 cmd 'open';
24 cmd 'focus parent';
25 cmd 'focus parent';
26 cmd 'mode toggle';
27
28 does_i3_live;
29
30 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test if the requested width/height is set after making the window floating.
17 #
18 use i3test;
19
20 my $tmp = fresh_workspace;
21
22 # Create a floating window which is smaller than the minimum enforced size of i3
23 my $window = open_window({ rect => [ 0, 0, 400, 150 ] });
24
25 my ($absolute, $top) = $window->rect;
26
27 ok($window->mapped, 'Window is mapped');
28 cmp_ok($absolute->{width}, '>', 400, 'i3 raised the width');
29 cmp_ok($absolute->{height}, '>', 150, 'i3 raised the height');
30
31 cmd 'floating toggle';
32 sync_with_i3;
33
34 ($absolute, $top) = $window->rect;
35
36 diag('new width: ' . $absolute->{width});
37 diag('new height: ' . $absolute->{height});
38
39 # we compare with a tolerance of ± 20 pixels for borders in each direction
40 # (overkill, but hey)
41 cmp_ok($absolute->{width}, '>', 400-20, 'width now > 380');
42 cmp_ok($absolute->{width}, '<', 400+20, 'width now < 420');
43 cmp_ok($absolute->{height}, '>', 150-20, 'height now > 130');
44 cmp_ok($absolute->{height}, '<', 150+20, 'height now < 170');
45
46 #cmp_ok($absolute->{width}, '>=', 75, 'i3 raised the width to 75');
47 #cmp_ok($absolute->{height}, '>=', 50, 'i3 raised the height to 50');
48
49 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test for closing one of multiple dock clients
17 #
18 use i3test;
19
20 my $tmp = fresh_workspace;
21
22 #####################################################################
23 # verify that there is no dock window yet
24 #####################################################################
25
26 # Children of all dockareas
27 my @docked = get_dock_clients;
28
29 is(@docked, 0, 'no dock clients yet');
30
31 #####################################################################
32 # open a dock client
33 #####################################################################
34
35 my $first = open_window({
36 background_color => '#FF0000',
37 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
38 });
39
40 #####################################################################
41 # Open a second dock client
42 #####################################################################
43
44 my $second = open_window({
45 background_color => '#FF0000',
46 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
47 });
48
49 #####################################################################
50 # Kill the second dock client
51 #####################################################################
52 cmd "nop destroying dock client";
53 $second->destroy;
54
55 #####################################################################
56 # Now issue a focus command
57 #####################################################################
58 cmd 'focus right';
59
60 does_i3_live;
61
62 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test to see if i3 combines the geometry of all children in a split container
17 # when setting the split container to floating
18 #
19 use i3test;
20
21 my $tmp = fresh_workspace;
22
23 open_window;
24 cmd 'split v';
25
26 #####################################################################
27 # open a window with 200x80
28 #####################################################################
29
30 my $first = open_window({
31 rect => [ 0, 0, 200, 80],
32 background_color => '#FF0000',
33 });
34
35 cmd 'split h';
36
37 #####################################################################
38 # Open a second window with 300x90
39 #####################################################################
40
41 my $second = open_window({
42 rect => [ 0, 0, 300, 90],
43 background_color => '#00FF00',
44 });
45
46 #####################################################################
47 # Set the parent to floating
48 #####################################################################
49 cmd 'nop setting floating';
50 cmd 'focus parent';
51 cmd 'floating enable';
52
53 #####################################################################
54 # Get geometry of the first floating node (the split container)
55 #####################################################################
56
57 my @nodes = @{get_ws($tmp)->{floating_nodes}};
58 my $rect = $nodes[0]->{rect};
59
60 # we compare the width with ± 20 pixels for borders
61 cmp_ok($rect->{width}, '>', 500-20, 'width now > 480');
62 cmp_ok($rect->{width}, '<', 500+20, 'width now < 520');
63 # we compare the height with ± 40 pixels for decorations
64 cmp_ok($rect->{height}, '>', 90-40, 'width now > 50');
65 cmp_ok($rect->{height}, '<', 90+40, 'width now < 130');
66
67 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test if new containers get focused when there is a fullscreen container at
17 # the time of launching the new one. Also make sure that focusing containers
18 # in other workspaces work even when there is a fullscreen container.
19 #
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 fake-outputs 1024x768+0+0,1024x768+1024+0
25 EOT
26 # Screen setup looks like this:
27 # +----+----+
28 # | S1 | S2 |
29 # +----+----+
30
31 sub verify_focus {
32 # Report original line
33 local $Test::Builder::Level = $Test::Builder::Level + 1;
34
35 my ($expected, $msg) = @_;
36 $expected = $expected->id;
37
38 # Ensure the expected focus if the test fails.
39 cmd "[id=$expected] focus" unless is($x->input_focus, $expected, $msg);
40 }
41
42 ################################################################################
43 # Verify that window opened behind fullscreen window will get focus after the
44 # fullscreen window gets moved to a different workspace.
45 ################################################################################
46
47 fresh_workspace;
48 my $left = open_window;
49 verify_focus($left, 'left window focused');
50 diag("left = " . $left->id);
51
52 my $right = open_window;
53 cmd 'fullscreen';
54 diag("right = " . $right->id);
55
56 # Open a third window. Since we're fullscreen, the window won't be mapped, so
57 # don't wait for it to be mapped. Instead, just send the map request and sync
58 # with i3 to make sure i3 recognizes it.
59 my $third = open_window({dont_map => 1});
60 $third->map;
61 sync_with_i3;
62 diag("third = " . $third->id);
63
64 # Move the window to a different workspace, and verify that the third window now
65 # gets focused in the current workspace.
66 my $tmp2 = get_unused_workspace;
67 cmd "move workspace $tmp2";
68 verify_focus($third, 'third window focused');
69
70 kill_all_windows;
71
72 ################################################################################
73 # Ensure that moving a window to a workspace which has a fullscreen window does
74 # not focus it (otherwise the user cannot get out of fullscreen mode anymore).
75 ################################################################################
76
77 my $tmp = fresh_workspace;
78
79 open_window;
80 cmd 'fullscreen';
81
82 my $nodes = get_ws_content($tmp);
83 is(scalar @$nodes, 1, 'precisely one window');
84 is($nodes->[0]->{focused}, 1, 'fullscreen window focused');
85 my $old_id = $nodes->[0]->{id};
86
87 $tmp2 = fresh_workspace;
88 my $move_window = open_window;
89 cmd "move workspace $tmp";
90
91 cmd "workspace $tmp";
92
93 $nodes = get_ws_content($tmp);
94 is(scalar @$nodes, 2, 'precisely two windows');
95 is($nodes->[0]->{id}, $old_id, 'id unchanged');
96 is($nodes->[0]->{focused}, 1, 'fullscreen window focused');
97
98 kill_all_windows;
99
100 ################################################################################
101 # Ensure it's possible to change focus if it doesn't escape the fullscreen
102 # container with fullscreen global. We can't even focus a container in a
103 # different workspace.
104 ################################################################################
105
106 $tmp = fresh_workspace(output => 1);
107 my $diff_ws = open_window;
108
109 $tmp2 = fresh_workspace(output => 0);
110 $left = open_window;
111 my $right1 = open_window;
112 cmd 'split v';
113 my $right2 = open_window;
114
115 cmd 'focus parent';
116 cmd 'fullscreen global';
117
118 cmd '[id="' . $right1->id . '"] focus';
119 verify_focus($right1, 'upper right window focused');
120
121 cmd '[id="' . $right2->id . '"] focus';
122 verify_focus($right2, 'bottom right window focused');
123
124 cmd 'focus parent';
125 isnt($x->input_focus, $right2->id, 'bottom right window no longer focused');
126
127 cmd 'focus child';
128 verify_focus($right2, 'bottom right window focused again');
129
130 cmd 'focus up';
131 verify_focus($right1, 'allowed focus up');
132
133 cmd 'focus down';
134 verify_focus($right2, 'allowed focus down');
135
136 cmd 'focus left';
137 verify_focus($right2, 'prevented focus left');
138
139 cmd 'focus right';
140 verify_focus($right2, 'prevented focus right');
141
142 cmd 'focus down';
143 verify_focus($right1, 'allowed focus wrap (down)');
144
145 cmd 'focus up';
146 verify_focus($right2, 'allowed focus wrap (up)');
147
148 ################################################################################
149 # (depends on previous layout)
150 # Same tests when we're in non-global fullscreen mode. It should now be possible
151 # to focus a container in a different workspace.
152 ################################################################################
153
154 cmd 'focus parent';
155 cmd 'fullscreen disable';
156 cmd 'fullscreen';
157
158 cmd '[id="' . $right1->id . '"] focus';
159 verify_focus($right1, 'upper right window focused');
160
161 cmd '[id="' . $right2->id . '"] focus';
162 verify_focus($right2, 'bottom right window focused');
163
164 cmd 'focus parent';
165 isnt($x->input_focus, $right2->id, 'bottom right window no longer focused');
166
167 cmd 'focus child';
168 verify_focus($right2, 'bottom right window focused again');
169
170 cmd 'focus up';
171 verify_focus($right1, 'allowed focus up');
172
173 cmd 'focus down';
174 verify_focus($right2, 'allowed focus down');
175
176 cmd 'focus down';
177 verify_focus($right1, 'allowed focus wrap (down)');
178
179 cmd 'focus up';
180 verify_focus($right2, 'allowed focus wrap (up)');
181
182 cmd 'focus left';
183 verify_focus($right2, 'focus left wrapped (no-op)');
184
185 cmd 'focus right';
186 verify_focus($diff_ws, 'allowed focus change to different ws');
187
188 cmd 'focus left';
189 verify_focus($right2, 'focused back into fullscreen container');
190
191 cmd '[id="' . $diff_ws->id . '"] focus';
192 verify_focus($diff_ws, 'allowed focus change to different ws by id');
193
194 ################################################################################
195 # (depends on previous layout)
196 # More testing of the interaction between wrapping and the fullscreen focus
197 # restrictions.
198 ################################################################################
199
200 cmd '[id="' . $right1->id . '"] focus';
201 verify_focus($right1, 'upper right window focused');
202
203 cmd 'focus parent';
204 cmd 'fullscreen disable';
205 cmd 'focus child';
206
207 cmd 'split v';
208 my $right12 = open_window;
209
210 cmd 'focus down';
211 verify_focus($right2, 'bottom right window focused');
212
213 cmd 'split v';
214 my $right22 = open_window;
215
216 cmd 'focus parent';
217 cmd 'fullscreen';
218 cmd 'focus child';
219
220 cmd 'focus down';
221 verify_focus($right2, 'focus did not leave parent container (1)');
222
223 cmd 'focus down';
224 verify_focus($right22, 'focus did not leave parent container (2)');
225
226 cmd 'focus up';
227 verify_focus($right2, 'focus did not leave parent container (3)');
228
229 cmd 'focus up';
230 verify_focus($right22, 'focus did not leave parent container (4)');
231
232 ################################################################################
233 # (depends on previous layout)
234 # Ensure that moving in a direction doesn't violate the focus restrictions.
235 ################################################################################
236
237 sub verify_move {
238 my $num = shift;
239 my $msg = shift;
240 my $nodes = get_ws_content($tmp2);
241 my $split = $nodes->[1];
242 my $fs = $split->{nodes}->[1];
243 is(scalar @{$fs->{nodes}}, $num, $msg);
244 }
245
246 cmd 'move left';
247 verify_move(2, 'prevented move left');
248 cmd 'move right';
249 verify_move(2, 'prevented move right');
250 cmd 'move down';
251 verify_move(2, 'prevented move down');
252 cmd 'move up';
253 cmd 'move up';
254 verify_move(2, 'prevented move up');
255
256 ################################################################################
257 # (depends on previous layout)
258 # Moving to a different workspace is allowed with per-output fullscreen
259 # containers.
260 ################################################################################
261
262 cmd "move to workspace $tmp";
263 verify_move(1, 'did not prevent move to workspace by name');
264
265 cmd "workspace $tmp";
266 cmd "move to workspace $tmp2";
267 cmd "workspace $tmp2";
268
269 cmd "move to workspace prev";
270 verify_move(1, 'did not prevent move to workspace by position');
271
272 ################################################################################
273 # (depends on previous layout)
274 # Ensure that is not allowed with global fullscreen containers.
275 ################################################################################
276
277 cmd "workspace $tmp";
278 cmd "move to workspace $tmp2";
279 cmd "workspace $tmp2";
280
281 cmd 'focus parent';
282 cmd 'fullscreen disable';
283 cmd 'fullscreen global';
284 cmd 'focus child';
285
286 cmd "move to workspace $tmp";
287 verify_move(2, 'prevented move to workspace by name');
288
289 cmd "move to workspace prev";
290 verify_move(2, 'prevented move to workspace by position');
291
292 kill_all_windows;
293
294 ################################################################################
295 # Ensure it's possible to focus a window using the focus command despite
296 # fullscreen window blocking it. Fullscreen window should lose its fullscreen
297 # mode.
298 ################################################################################
299
300 # first & second tiling, focus using id
301 $tmp = fresh_workspace;
302 my $first = open_window;
303 my $second = open_window;
304 cmd 'fullscreen';
305 verify_focus($second, 'fullscreen window focused');
306 is_num_fullscreen($tmp, 1, '1 fullscreen window');
307
308 cmd '[id="' . $first->id . '"] focus';
309 sync_with_i3;
310
311 verify_focus($first, 'correctly focused using id');
312 is_num_fullscreen($tmp, 0, 'no fullscreen windows');
313
314 kill_all_windows;
315
316 # first floating, second tiling, focus using 'focus floating'
317 $tmp = fresh_workspace;
318 $first = open_floating_window;
319 $second = open_window;
320 cmd 'fullscreen';
321 verify_focus($second, 'fullscreen window focused');
322 is_num_fullscreen($tmp, 1, '1 fullscreen window');
323
324 cmd 'focus floating';
325 sync_with_i3;
326
327 verify_focus($first, 'correctly focused using focus floating');
328 is_num_fullscreen($tmp, 0, 'no fullscreen windows');
329
330 kill_all_windows;
331
332 # first tiling, second floating, focus using 'focus tiling'
333 $tmp = fresh_workspace;
334 $first = open_window;
335 $second = open_floating_window;
336 cmd 'fullscreen';
337 verify_focus($second, 'fullscreen window focused');
338 is_num_fullscreen($tmp, 1, '1 fullscreen window');
339
340 cmd 'focus tiling';
341 sync_with_i3;
342
343 verify_focus($first, 'correctly focused using focus tiling');
344 is_num_fullscreen($tmp, 0, 'no fullscreen windows');
345
346 kill_all_windows;
347
348 ################################################################################
349 # When the fullscreen window is in an other workspace it should maintain its
350 # fullscreen mode since it's not blocking the window to be focused.
351 ################################################################################
352
353 $tmp = fresh_workspace;
354 $first = open_window;
355
356 $tmp2 = fresh_workspace;
357 $second = open_window;
358 cmd 'fullscreen';
359 verify_focus($second, 'fullscreen window focused');
360 is_num_fullscreen($tmp2, 1, '1 fullscreen window');
361
362 cmd '[id="' . $first->id . '"] focus';
363 sync_with_i3;
364
365 verify_focus($first, 'correctly focused using focus id');
366 is_num_fullscreen($tmp, 0, 'no fullscreen windows on first workspace');
367 is_num_fullscreen($tmp2, 1, 'still one fullscreen window on second workspace');
368
369 kill_all_windows;
370
371 ################################################################################
372 # But a global window in another workspace is blocking the window to be focused.
373 # Ensure that it loses its fullscreen mode.
374 ################################################################################
375
376 $tmp = fresh_workspace;
377 $first = open_window;
378
379 $tmp2 = fresh_workspace;
380 $second = open_window;
381 cmd 'fullscreen global';
382 verify_focus($second, 'global window focused');
383 is_num_fullscreen($tmp2, 1, '1 fullscreen window');
384
385 cmd '[id="' . $first->id . '"] focus';
386 sync_with_i3;
387
388 verify_focus($first, 'correctly focused using focus id');
389 is_num_fullscreen($tmp2, 0, 'no fullscreen windows');
390
391
392 # TODO: Tests for "move to output" and "move workspace to output".
393 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests if the WM_TAKE_FOCUS protocol is correctly handled by i3
17 #
18 # For more information on the protocol and input handling, see:
19 # https://tronche.com/gui/x/icccm/sec-4.html#s-4.1.7
20 #
21 use i3test;
22
23 sub recv_take_focus {
24 my ($window) = @_;
25
26 # sync_with_i3 will send a ClientMessage to i3 and i3 will send the same
27 # payload back to $window->id.
28 my $myrnd = sync_with_i3(
29 window_id => $window->id,
30 dont_wait_for_event => 1,
31 );
32
33 # We check whether the first received message has the correct payload — if
34 # not, the received message was a WM_TAKE_FOCUS message.
35 my $first_event_is_clientmessage;
36 wait_for_event 2, sub {
37 my ($event) = @_;
38 # TODO: const
39 return 0 unless $event->{response_type} == 161;
40
41 my ($win, $rnd) = unpack "LL", $event->{data};
42 if (!defined($first_event_is_clientmessage)) {
43 $first_event_is_clientmessage = ($rnd == $myrnd);
44 }
45 return ($rnd == $myrnd);
46 };
47
48 return !$first_event_is_clientmessage;
49 }
50
51 subtest 'Window without WM_TAKE_FOCUS', sub {
52 my $ws = fresh_workspace;
53
54 my $window = open_window;
55
56 ok(!recv_take_focus($window), 'did not receive ClientMessage');
57 ok(is_net_wm_state_focused($window), '_NET_WM_STATE_FOCUSED set');
58
59 my ($nodes) = get_ws_content($ws);
60 my $con = shift @$nodes;
61 ok($con->{focused}, 'con is focused');
62
63 done_testing;
64 };
65
66 # https://tronche.com/gui/x/icccm/sec-4.html#s-4.1.7
67 # > Clients using the Globally Active model can only use a SetInputFocus request
68 # > to acquire the input focus when they do not already have it on receipt of one
69 # > of the following events:
70 # > * ButtonPress
71 # > * ButtonRelease
72 # > * Passive-grabbed KeyPress
73 # > * Passive-grabbed KeyRelease
74 #
75 # Since managing a window happens on a MapNotify (which is absent from this
76 # list), the window cannot accept input focus, so we should not try to focus
77 # the window at all.
78 subtest 'Window with WM_TAKE_FOCUS and without InputHint', sub {
79 my $ws = fresh_workspace;
80
81 my $take_focus = $x->atom(name => 'WM_TAKE_FOCUS');
82
83 my $window = open_window({
84 dont_map => 1,
85 protocols => [ $take_focus ],
86 });
87
88 # add an (empty) WM_HINTS property without the InputHint
89 $window->delete_hint('input');
90
91 $window->map;
92
93 ok(!recv_take_focus($window), 'did not receive ClientMessage');
94 ok(is_net_wm_state_focused($window), '_NET_WM_STATE_FOCUSED set');
95
96 my ($nodes) = get_ws_content($ws);
97 my $con = shift @$nodes;
98 ok($con->{focused}, 'con is focused');
99
100 done_testing;
101 };
102
103 # If the InputHint is unspecified, i3 should use the simpler method of focusing
104 # the window directly rather than using the WM_TAKE_FOCUS protocol.
105 # XXX: The code paths for an unspecified and set InputHint are
106 # nearly identical presently, so this is currently used also as a proxy test
107 # for the latter case.
108 subtest 'Window with WM_TAKE_FOCUS and unspecified InputHint', sub {
109 my $ws = fresh_workspace;
110
111 my $take_focus = $x->atom(name => 'WM_TAKE_FOCUS');
112
113 my $window = open_window({ protocols => [ $take_focus ] });
114
115 ok(!recv_take_focus($window), 'did not receive ClientMessage');
116 ok(is_net_wm_state_focused($window), '_NET_WM_STATE_FOCUSED set');
117
118 my ($nodes) = get_ws_content($ws);
119 my $con = shift @$nodes;
120 ok($con->{focused}, 'con is focused');
121
122 done_testing;
123 };
124
125 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests if the various ipc_socket_path options are correctly handled
17 #
18 use i3test i3_autostart => 0;
19 use File::Temp qw(tempfile tempdir);
20 use File::Basename;
21 use POSIX qw(getuid);
22 use v5.10;
23
24 #####################################################################
25 # default case: socket will be created in /tmp/i3-<username>/ipc-socket.<pid>
26 #####################################################################
27
28 my $config = <<EOT;
29 # i3 config file (v4)
30 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
31 EOT
32
33 # ensure XDG_RUNTIME_DIR is not set
34 delete $ENV{XDG_RUNTIME_DIR};
35
36 my $pid = launch_with_config($config, dont_add_socket_path => 1, dont_create_temp_dir => 1);
37 my $socketpath = get_socket_path(0);
38 my $folder = "/tmp/i3-" . getpwuid(getuid());
39 like(dirname($socketpath), qr/^$folder/, 'temp directory matches expected pattern');
40 $folder = dirname($socketpath);
41
42 ok(-d $folder, "folder $folder exists");
43 $socketpath = "$folder/ipc-socket." . $pid;
44 ok(-S $socketpath, "file $socketpath exists and is a socket");
45
46 exit_gracefully($pid);
47
48 #####################################################################
49 # XDG_RUNTIME_DIR case: socket gets created in $XDG_RUNTIME_DIR/i3/ipc-socket.<pid>
50 #####################################################################
51
52 my $rtdir = tempdir(CLEANUP => 1);
53
54 ok(! -e "$rtdir/i3", "$rtdir/i3 does not exist yet");
55
56 $ENV{XDG_RUNTIME_DIR} = $rtdir;
57
58 $pid = launch_with_config($config, dont_add_socket_path => 1, dont_create_temp_dir => 1);
59
60 ok(-d "$rtdir/i3", "$rtdir/i3 exists and is a directory");
61 $socketpath = "$rtdir/i3/ipc-socket." . $pid;
62 ok(-S $socketpath, "file $socketpath exists and is a socket");
63
64 exit_gracefully($pid);
65
66 #####################################################################
67 # configuration file case: socket gets placed wherever we specify
68 #####################################################################
69
70 my $tmpdir = tempdir(CLEANUP => 1);
71 $socketpath = $tmpdir . "/config.sock";
72 ok(! -e $socketpath, "$socketpath does not exist yet");
73
74 $config = <<EOT;
75 # i3 config file (v4)
76 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
77 ipc-socket $socketpath
78 EOT
79
80 $pid = launch_with_config($config, dont_add_socket_path => 1, dont_create_temp_dir => 1);
81
82 ok(-S $socketpath, "file $socketpath exists and is a socket");
83
84 exit_gracefully($pid);
85
86 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test to check if borders are correctly restored after an inplace
17 # restart.
18 # found in eb8ad348b28e243cba1972e802ca8ee636472fc9
19 #
20 use List::Util qw(first);
21 use i3test;
22
23 my $i3 = i3(get_socket_path());
24 my $tmp = fresh_workspace;
25 my $window = open_window;
26
27 sub get_border_style {
28 my @content = @{get_ws_content($tmp)};
29 my $wininfo = first { $_->{window} == $window->id } @content;
30
31 return $wininfo->{border};
32 }
33
34 is(get_border_style(), 'normal', 'border style normal');
35
36 cmd 'border 1pixel';
37
38 is(get_border_style(), 'pixel', 'border style 1pixel after changing');
39
40 # perform an inplace-restart
41 cmd 'restart';
42
43 does_i3_live;
44
45 is(get_border_style(), 'pixel', 'border style still 1pixel after restart');
46
47 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test for setting the urgent hint on dock clients.
17 # found in 4be3178d4d360c2996217d811e61161c84d25898
18 #
19 use i3test;
20
21 my $i3 = i3(get_socket_path());
22
23 my $tmp = fresh_workspace;
24
25 #####################################################################
26 # verify that there is no dock window yet
27 #####################################################################
28
29 # Children of all dockareas
30 my @docked = get_dock_clients;
31
32 is(@docked, 0, 'no dock clients yet');
33
34 # open a dock client
35
36 my $window = open_window(
37 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
38 );
39
40 #####################################################################
41 # check that we can find it in the layout tree at the expected position
42 #####################################################################
43
44 @docked = get_dock_clients;
45 is(@docked, 1, 'one dock client found');
46
47 # verify the height
48 my $docknode = $docked[0];
49
50 is($docknode->{rect}->{height}, 30, 'dock node has unchanged height');
51
52 $window->add_hint('urgency');
53
54 sync_with_i3;
55
56 does_i3_live;
57
58 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests if WM_STATE is WM_STATE_NORMAL when mapped and WM_STATE_WITHDRAWN when
17 # unmapped.
18 #
19 use i3test;
20 use X11::XCB qw(ICCCM_WM_STATE_NORMAL ICCCM_WM_STATE_WITHDRAWN);
21
22 my $window = open_window;
23
24 is($window->state, ICCCM_WM_STATE_NORMAL, 'WM_STATE normal');
25
26 $window->unmap;
27
28 wait_for_unmap $window;
29
30 is($window->state, ICCCM_WM_STATE_WITHDRAWN, 'WM_STATE withdrawn');
31
32 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests if WM_STATE is WM_STATE_NORMAL when mapped and WM_STATE_WITHDRAWN when
17 # unmapped.
18 #
19 use i3test;
20
21 sub two_windows {
22 my $tmp = fresh_workspace;
23
24 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
25
26 my $first = open_window;
27 my $second = open_window;
28
29 is($x->input_focus, $second->id, 'second window focused');
30 ok(@{get_ws_content($tmp)} == 2, 'two containers opened');
31
32 return $tmp;
33 }
34
35 ##############################################################
36 # 1: open two windows (in the same client), kill one and see if
37 # the other one is still there
38 ##############################################################
39
40 my $tmp = two_windows;
41
42 cmd 'kill';
43 sync_with_i3;
44
45 ok(@{get_ws_content($tmp)} == 1, 'one container left after killing');
46
47 ##############################################################
48 # 2: same test case as test 1, but with the explicit variant
49 # 'kill window'
50 ##############################################################
51
52 $tmp = two_windows;
53
54 cmd 'kill window';
55 sync_with_i3;
56
57 ok(@{get_ws_content($tmp)} == 1, 'one container left after killing');
58
59 ##############################################################
60 # 3: open two windows (in the same client), use 'kill client'
61 # and check if both are gone
62 ##############################################################
63
64 $tmp = two_windows;
65
66 cmd 'kill client';
67 # We need to re-establish the X11 connection which we just killed :).
68 $x = i3test::X11->new;
69 sync_with_i3(no_cache => 1);
70
71 ok(@{get_ws_content($tmp)} == 0, 'no containers left after killing');
72
73 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 use i3test i3_autostart => 0;
17 use X11::XCB qw(PROP_MODE_REPLACE);
18
19 my (@nodes);
20
21 my $config = <<'EOT';
22 # i3 config file (v4)
23 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
24
25 # test 1, test 2
26 for_window [class="borderless$"] border none
27 for_window [title="special borderless title"] border none
28
29 # test 3
30 for_window [class="borderless3$" title="usethis"] border none
31 for_window [class="borderless3$"] border none
32 for_window [title="special borderless title"] border none
33 for_window [title="special mark title"] border none, mark bleh
34
35 # test 4
36 for_window [class="borderless4$" title="usethis"] border none
37
38 # test 5, test 6
39 for_window [class="foo$"] border 1pixel
40
41 # test 6
42 for_window [instance="foo6"] border none
43
44 # test 7
45 for_window [id="asdf"] border none
46
47 # test 8, test 9
48 for_window [window_role="i3test"] border none
49
50 # test 12
51 for_window [workspace="trigger"] floating enable, mark triggered
52 EOT
53
54 # test all window types
55 my %window_types = (
56 'normal' => '_NET_WM_WINDOW_TYPE_NORMAL',
57 'dialog' => '_NET_WM_WINDOW_TYPE_DIALOG',
58 'utility' => '_NET_WM_WINDOW_TYPE_UTILITY',
59 'toolbar' => '_NET_WM_WINDOW_TYPE_TOOLBAR',
60 'splash' => '_NET_WM_WINDOW_TYPE_SPLASH',
61 'menu' => '_NET_WM_WINDOW_TYPE_MENU',
62 'dropdown_menu' => '_NET_WM_WINDOW_TYPE_DROPDOWN_MENU',
63 'popup_menu' => '_NET_WM_WINDOW_TYPE_POPUP_MENU',
64 'tooltip' => '_NET_WM_WINDOW_TYPE_TOOLTIP',
65 'notification' => '_NET_WM_WINDOW_TYPE_NOTIFICATION'
66 );
67
68 for my $window_type (keys %window_types) {
69 $config .= <<EOT;
70 for_window [window_type="$window_type"] floating enable, mark branded-$window_type
71 EOT
72 }
73
74 my $pid = launch_with_config($config);
75
76 ##############################################################
77 # 1: test the following directive:
78 # for_window [class="borderless"] border none
79 # by first creating a window with a different class (should get
80 # the normal border), then creating a window with the class
81 # "borderless" (should get no border)
82 ##############################################################
83
84 my $tmp = fresh_workspace;
85
86 my $window = open_window(name => 'Border window');
87
88 my @content = @{get_ws_content($tmp)};
89 cmp_ok(@content, '==', 1, 'one node on this workspace now');
90 is($content[0]->{border}, 'normal', 'normal border');
91
92 $window->unmap;
93 wait_for_unmap $window;
94
95 @content = @{get_ws_content($tmp)};
96 cmp_ok(@content, '==', 0, 'no more nodes');
97 diag('content = '. Dumper(\@content));
98
99 $window = open_window(
100 name => 'Borderless window',
101 wm_class => 'borderless',
102 );
103
104 @content = @{get_ws_content($tmp)};
105 cmp_ok(@content, '==', 1, 'one node on this workspace now');
106 is($content[0]->{border}, 'none', 'no border');
107
108 $window->unmap;
109 wait_for_unmap $window;
110
111 @content = @{get_ws_content($tmp)};
112 cmp_ok(@content, '==', 0, 'no more nodes');
113
114 kill_all_windows;
115
116 ##############################################################
117 # 2: match on the title, check if for_window is really executed
118 # only once
119 ##############################################################
120
121 $tmp = fresh_workspace;
122
123 $window = open_window(name => 'special title');
124
125 @content = @{get_ws_content($tmp)};
126 cmp_ok(@content, '==', 1, 'one node on this workspace now');
127 is($content[0]->{border}, 'normal', 'normal border');
128
129 $window->name('special borderless title');
130 sync_with_i3;
131
132 @content = @{get_ws_content($tmp)};
133 is($content[0]->{border}, 'none', 'no border');
134
135 $window->name('special title');
136 sync_with_i3;
137
138 cmd 'border normal';
139
140 @content = @{get_ws_content($tmp)};
141 is($content[0]->{border}, 'normal', 'border reset to normal');
142
143 $window->name('special borderless title');
144 sync_with_i3;
145
146 @content = @{get_ws_content($tmp)};
147 is($content[0]->{border}, 'normal', 'still normal border');
148
149 $window->unmap;
150 wait_for_unmap $window;
151
152 @content = @{get_ws_content($tmp)};
153 cmp_ok(@content, '==', 0, 'no more nodes');
154
155 kill_all_windows;
156
157 ##############################################################
158 # 3: match on the title, set border style *and* a mark
159 ##############################################################
160
161 $tmp = fresh_workspace;
162
163 $window = open_window(name => 'special mark title');
164
165 @content = @{get_ws_content($tmp)};
166 cmp_ok(@content, '==', 1, 'one node on this workspace now');
167 is($content[0]->{border}, 'none', 'no border');
168
169 my $other = open_window;
170
171 @content = @{get_ws_content($tmp)};
172 cmp_ok(@content, '==', 2, 'two nodes');
173 is($content[0]->{border}, 'none', 'no border');
174 is($content[1]->{border}, 'normal', 'normal border');
175 ok(!$content[0]->{focused}, 'first one not focused');
176
177 cmd qq|[con_mark="bleh"] focus|;
178
179 @content = @{get_ws_content($tmp)};
180 ok($content[0]->{focused}, 'first node focused');
181
182 kill_all_windows;
183
184 ##############################################################
185 # 4: multiple criteria for the for_window command
186 ##############################################################
187
188 $tmp = fresh_workspace;
189
190 $window = open_window(
191 name => 'usethis',
192 wm_class => 'borderless4',
193 );
194
195 @content = @{get_ws_content($tmp)};
196 cmp_ok(@content, '==', 1, 'one node on this workspace now');
197 is($content[0]->{border}, 'none', 'no border');
198
199 cmd 'kill';
200 wait_for_unmap $window;
201 $window->destroy;
202
203 # give i3 a chance to delete the window from its tree
204 sync_with_i3;
205
206 @content = @{get_ws_content($tmp)};
207 cmp_ok(@content, '==', 0, 'no nodes on this workspace now');
208
209 $window->_create;
210 $window->wm_class('borderless4');
211 $window->name('notthis');
212 $window->map;
213 wait_for_map $window;
214
215 @content = @{get_ws_content($tmp)};
216 cmp_ok(@content, '==', 1, 'one node on this workspace now');
217 is($content[0]->{border}, 'normal', 'no border');
218
219 kill_all_windows;
220
221 ##############################################################
222 # 5: check that a class criterion does not match the instance
223 ##############################################################
224
225 $tmp = fresh_workspace;
226
227 $window = open_window(
228 name => 'usethis',
229 wm_class => 'bar',
230 instance => 'foo',
231 );
232
233 @content = @{get_ws_content($tmp)};
234 cmp_ok(@content, '==', 1, 'one node on this workspace now');
235 is($content[0]->{border}, 'normal', 'normal border, not matched');
236
237 kill_all_windows;
238
239 ##############################################################
240 # 6: check that the 'instance' criterion works
241 ##############################################################
242
243 $tmp = fresh_workspace;
244
245 $window = open_window(
246 name => 'usethis',
247 wm_class => 'bar',
248 instance => 'foo6',
249 );
250
251 @content = @{get_ws_content($tmp)};
252 cmp_ok(@content, '==', 1, 'one node on this workspace now');
253 is($content[0]->{border}, 'none', 'no border');
254
255 kill_all_windows;
256
257 ##############################################################
258 # 7: check that invalid criteria don’t end up matching all windows
259 ##############################################################
260
261 $tmp = fresh_workspace;
262
263 $window = open_window(
264 name => 'usethis',
265 wm_class => 'bar',
266 instance => 'foo',
267 );
268
269 @content = @{get_ws_content($tmp)};
270 cmp_ok(@content, '==', 1, 'one node on this workspace now');
271 is($content[0]->{border}, 'normal', 'normal border');
272
273 kill_all_windows;
274
275 ##############################################################
276 # 8: check that the role criterion works properly
277 ##############################################################
278
279 $tmp = fresh_workspace;
280
281 $window = open_window(
282 name => 'usethis',
283 before_map => sub {
284 my ($window) = @_;
285 my $atomname = $x->atom(name => 'WM_WINDOW_ROLE');
286 my $atomtype = $x->atom(name => 'STRING');
287 $x->change_property(
288 PROP_MODE_REPLACE,
289 $window->id,
290 $atomname->id,
291 $atomtype->id,
292 8,
293 length("i3test") + 1,
294 "i3test\x00"
295 );
296 },
297 );
298
299 @content = @{get_ws_content($tmp)};
300 cmp_ok(@content, '==', 1, 'one node on this workspace now');
301 is($content[0]->{border}, 'none', 'no border (window_role)');
302
303 kill_all_windows;
304
305 ##############################################################
306 # 9: another test for the window_role, but this time it changes
307 # *after* the window has been mapped
308 ##############################################################
309
310 $tmp = fresh_workspace;
311
312 $window = open_window(name => 'usethis');
313
314 @content = @{get_ws_content($tmp)};
315 cmp_ok(@content, '==', 1, 'one node on this workspace now');
316 is($content[0]->{border}, 'normal', 'normal border (window_role 2)');
317
318 my $atomname = $x->atom(name => 'WM_WINDOW_ROLE');
319 my $atomtype = $x->atom(name => 'STRING');
320 $x->change_property(
321 PROP_MODE_REPLACE,
322 $window->id,
323 $atomname->id,
324 $atomtype->id,
325 8,
326 length("i3test") + 1,
327 "i3test\x00"
328 );
329
330 $x->flush;
331
332 sync_with_i3;
333
334 @content = @{get_ws_content($tmp)};
335 cmp_ok(@content, '==', 1, 'one node on this workspace now');
336 is($content[0]->{border}, 'none', 'no border (window_role 2)');
337
338 kill_all_windows;
339
340 ##############################################################
341 # 10: check that the criterion 'window_type' works
342 ##############################################################
343
344 while (my ($window_type, $atom) = each %window_types) {
345 $tmp = fresh_workspace;
346
347 $window = open_window(window_type => $x->atom(name => $atom));
348
349 my @nodes = @{get_ws($tmp)->{floating_nodes}};
350 cmp_ok(@nodes, '==', 1, 'one floating container on this workspace');
351 is_deeply($nodes[0]->{nodes}[0]->{marks}, [ "branded-$window_type" ], "mark set (window_type = $atom)");
352
353 kill_all_windows;
354 }
355
356 ##############################################################
357 # 11: check that the criterion 'window_type' works if the
358 # _NET_WM_WINDOW_TYPE is changed after managing.
359 ##############################################################
360
361 while (my ($window_type, $atom) = each %window_types) {
362 $tmp = fresh_workspace;
363
364 $window = open_window();
365
366 my $atomname = $x->atom(name => '_NET_WM_WINDOW_TYPE');
367 my $atomtype = $x->atom(name => 'ATOM');
368 $x->change_property(PROP_MODE_REPLACE, $window->id, $atomname->id, $atomtype->id,
369 32, 1, pack('L1', $x->atom(name => $atom)->id));
370 $x->flush;
371 sync_with_i3;
372
373 my @nodes = @{get_ws($tmp)->{floating_nodes}};
374 cmp_ok(@nodes, '==', 1, 'one floating container on this workspace');
375 is_deeply($nodes[0]->{nodes}[0]->{marks}, [ "branded-$window_type" ], "mark set (window_type = $atom)");
376
377 kill_all_windows;
378 }
379
380 ##############################################################
381 # 12: check that the criterion 'workspace' works
382 ##############################################################
383
384 cmd 'workspace trigger';
385 $window = open_window;
386
387 @nodes = @{get_ws('trigger')->{floating_nodes}};
388 cmp_ok(@nodes, '==', 1, 'one floating container on this workspace');
389 is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'triggered' ], "mark set for workspace criterion");
390
391 kill_all_windows;
392
393 ##############################################################
394
395 exit_gracefully($pid);
396
397 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests if assignments work
17 #
18 use i3test i3_autostart => 0;
19
20 sub open_special {
21 my %args = @_;
22 $args{name} //= 'special window';
23 $args{wm_class} //= 'special';
24
25 # We use dont_map because i3 will not map the window on the current
26 # workspace. Thus, open_window would time out in wait_for_map (2 seconds).
27 my $window = open_window(
28 %args,
29 dont_map => 1,
30 );
31 $window->map;
32 return $window;
33 }
34
35 sub test_workspace_assignment {
36 my $target_ws = "@_";
37
38 # initialize the target workspace, then go to a fresh one
39 ok(!($target_ws ~~ @{get_workspace_names()}), "$target_ws does not exist yet");
40 cmd "workspace $target_ws";
41 cmp_ok(@{get_ws_content($target_ws)}, '==', 0, "no containers on $target_ws yet");
42 cmd 'open';
43 cmp_ok(@{get_ws_content($target_ws)}, '==', 1, "one container on $target_ws");
44 my $tmp = fresh_workspace;
45
46 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
47 ok($target_ws ~~ @{get_workspace_names()}, "$target_ws does not exist yet");
48
49 # We use sync_with_i3 instead of wait_for_map here because i3 will not actually
50 # map the window -- it will be assigned to a different workspace and will only
51 # be mapped once you switch to that workspace
52 my $window = open_special;
53 sync_with_i3;
54
55 ok(@{get_ws_content($tmp)} == 0, 'still no containers');
56 ok(@{get_ws_content($target_ws)} == 2, "two containers on $target_ws");
57
58 return $window
59 }
60
61 #####################################################################
62 # start a window and see that it does not get assigned with an empty config
63 #####################################################################
64
65 my $config = <<EOT;
66 # i3 config file (v4)
67 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
68 EOT
69
70 my $pid = launch_with_config($config);
71
72 my $tmp = fresh_workspace;
73
74 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
75
76 my $window = open_special;
77 wait_for_map($window);
78
79 ok(@{get_ws_content($tmp)} == 1, 'special window got managed to current (random) workspace');
80
81 exit_gracefully($pid);
82
83 $window->destroy;
84
85 #####################################################################
86 # start a window and see that it gets assigned to a formerly unused
87 # workspace
88 #####################################################################
89
90 $config = <<EOT;
91 # i3 config file (v4)
92 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
93 assign [class="special"] → targetws
94 EOT
95
96 $pid = launch_with_config($config);
97
98 $tmp = fresh_workspace;
99
100 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
101 my $workspaces = get_workspace_names;
102 ok(!("targetws" ~~ @{$workspaces}), 'targetws does not exist yet');
103
104 $window = open_special;
105 sync_with_i3;
106
107 ok(@{get_ws_content($tmp)} == 0, 'still no containers');
108 ok("targetws" ~~ @{get_workspace_names()}, 'targetws exists');
109
110 $window->destroy;
111
112 exit_gracefully($pid);
113
114 #####################################################################
115 # start a window and see that it gets assigned to a formerly unused
116 # numbered workspace
117 #####################################################################
118
119 my $config_numbered = <<EOT;
120 # i3 config file (v4)
121 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
122 assign [class="special"] → workspace number 2
123 EOT
124
125 $pid = launch_with_config($config_numbered);
126
127 $tmp = fresh_workspace;
128
129 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
130 $workspaces = get_workspace_names;
131 ok(!("2" ~~ @{$workspaces}), 'workspace number 2 does not exist yet');
132
133 $window = open_special;
134 sync_with_i3;
135
136 ok(@{get_ws_content($tmp)} == 0, 'still no containers');
137 ok("2" ~~ @{get_workspace_names()}, 'workspace number 2 exists');
138
139 $window->destroy;
140
141 exit_gracefully($pid);
142
143 #####################################################################
144 # start a window and see that it gets assigned to a numbered
145 # workspace which has content already, next to the existing node.
146 #####################################################################
147
148 $pid = launch_with_config($config_numbered);
149
150 $window = test_workspace_assignment("2");
151 $window->destroy;
152
153 exit_gracefully($pid);
154
155 #####################################################################
156 # start a window and see that it gets assigned to a numbered workspace with
157 # a name which has content already, next to the existing node.
158 #####################################################################
159
160 $pid = launch_with_config($config_numbered);
161
162 cmd 'workspace 2'; # Make sure that we are not testing for "2" again.
163 $window = test_workspace_assignment("2: targetws");
164 $window->destroy;
165
166 exit_gracefully($pid);
167
168 #####################################################################
169 # start a window and see that it gets assigned to a workspace which
170 # has content already, next to the existing node.
171 #####################################################################
172
173 $pid = launch_with_config($config);
174
175 test_workspace_assignment("targetws");
176
177 exit_gracefully($pid);
178
179 #####################################################################
180 # start a window and see that it gets assigned to a workspace which has content
181 # already, next to the existing node.
182 #####################################################################
183
184 $config = <<EOT;
185 # i3 config file (v4)
186 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
187 for_window [class="special"] floating enable
188 EOT
189
190 $pid = launch_with_config($config);
191
192 $tmp = fresh_workspace;
193
194 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
195 $workspaces = get_workspace_names;
196 ok(!("targetws" ~~ @{$workspaces}), 'targetws does not exist yet');
197
198 $window = open_special;
199 sync_with_i3;
200
201 my $content = get_ws($tmp);
202 ok(@{$content->{nodes}} == 0, 'no tiling cons');
203 ok(@{$content->{floating_nodes}} == 1, 'one floating con');
204
205 kill_all_windows;
206 exit_gracefully($pid);
207
208 #####################################################################
209 # test assignments to named outputs
210 #####################################################################
211 $config = <<EOT;
212 # i3 config file (v4)
213 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
214
215 fake-outputs 1024x768+0+0,1024x768+1024+0,1024x768+1024+768,1024x768+0+768
216
217 workspace ws-0 output fake-0
218 workspace ws-1 output fake-1
219 workspace ws-2 output fake-2
220 workspace ws-3 output fake-3
221
222 assign [class="special-0"] → output fake-0
223 assign [class="special-1"] → output fake-1
224 assign [class="special-2"] → output fake-2
225 assign [class="special-3"] → output fake-3
226 assign [class="special-4"] → output invalid
227
228 EOT
229
230 $pid = launch_with_config($config);
231
232 sub open_in_output {
233 my ($num, $expected_count) = @_;
234 my $ws = "ws-$num";
235 my $class = "special-$num";
236 my $output = "fake-$num";
237
238 is_num_children($ws, $expected_count - 1,
239 "before: " . ($expected_count - 1) . " containers on output $output");
240 $window = open_special(wm_class => $class);
241 sync_with_i3;
242 is_num_children($ws, $expected_count,
243 "after: $expected_count containers on output $output");
244 }
245
246 cmd "workspace ws-0";
247 open_in_output(0, 1);
248 my $focused = $x->input_focus;
249
250 open_in_output(1, 1);
251 is($x->input_focus, $focused, 'focus remains on output fake-0');
252
253 open_in_output(2, 1);
254 is($x->input_focus, $focused, 'focus remains on output fake-0');
255
256 for my $i (1 .. 5){
257 open_in_output(3, $i);
258 is($x->input_focus, $focused, 'focus remains on output fake-0');
259 }
260
261 # Check invalid output
262 $tmp = fresh_workspace;
263 open_special(wm_class => "special-4");
264 sync_with_i3;
265 is_num_children($tmp, 1, 'window assigned to invalid output opened in current workspace');
266 open_special(wm_class => "special-3");
267 sync_with_i3;
268 is_num_children($tmp, 1, 'but window assigned to valid output did not');
269
270 kill_all_windows;
271 exit_gracefully($pid);
272
273 #####################################################################
274 # Test assignments to outputs with relative names
275 #####################################################################
276 $config = <<EOT;
277 # i3 config file (v4)
278 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
279
280 fake-outputs 1024x768+0+0,1024x768+1024+0,1024x768+1024+768,1024x768+0+768
281
282 workspace left-top output fake-0
283 workspace right-top output fake-1
284 workspace right-bottom output fake-2
285 workspace left-bottom output fake-3
286
287 assign [class="current"] → output current
288 assign [class="left"] → output left
289 assign [class="right"] → output right
290 assign [class="up"] → output up
291 assign [class="down"] → output down
292 EOT
293
294 $pid = launch_with_config($config);
295
296 cmd 'workspace left-top';
297
298 is_num_children('left-top', 0, 'no childreon on left-top');
299 for my $i (1 .. 5){
300 open_special(wm_class => 'current');
301 }
302 sync_with_i3;
303 is_num_children('left-top', 5, 'windows opened in current workspace');
304
305 is_num_children('right-top', 0, 'no children on right-top');
306 open_special(wm_class => 'right');
307 sync_with_i3;
308 is_num_children('right-top', 1, 'one child on right-top');
309
310 is_num_children('left-bottom', 0, 'no children on left-bottom');
311 open_special(wm_class => 'down');
312 sync_with_i3;
313 is_num_children('left-bottom', 1, 'one child on left-bottom');
314
315 cmd 'workspace right-bottom';
316
317 open_special(wm_class => 'up');
318 sync_with_i3;
319 is_num_children('right-top', 2, 'two children on right-top');
320
321 open_special(wm_class => 'left');
322 sync_with_i3;
323 is_num_children('left-bottom', 2, 'two children on left-bottom');
324
325 kill_all_windows;
326 exit_gracefully($pid);
327
328 #####################################################################
329 # regression test: dock clients with floating assignments should not crash
330 # (instead, nothing should happen - dock clients can’t float)
331 # ticket #501
332 #####################################################################
333
334 # Walks /proc to figure out whether a child process of $i3pid with the name
335 # 'i3-nagbar' exists.
336 sub i3nagbar_running {
337 my ($i3pid) = @_;
338
339 my @procfiles = grep { m,^/proc/[0-9]+$, } </proc/*>;
340 for my $path (@procfiles) {
341 open(my $fh, '<', "$path/stat") or next;
342 my $line = <$fh>;
343 close($fh);
344 my ($comm, $ppid) = ($line =~ /^[0-9]+ \(([^)]+)\) . ([0-9]+)/);
345 return 1 if $ppid == $i3pid && $comm eq 'i3-nagbar';
346 }
347 return 0;
348 }
349
350 $config = <<EOT;
351 # i3 config file (v4)
352 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
353 for_window [title="special"] floating enable
354 EOT
355
356 $pid = launch_with_config($config);
357
358 $tmp = fresh_workspace;
359
360 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
361 my @docked = get_dock_clients;
362 is(@docked, 0, 'no dock client yet');
363
364 $window = open_special(
365 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
366 );
367 sync_with_i3;
368
369 $content = get_ws($tmp);
370 ok(@{$content->{nodes}} == 0, 'no tiling cons');
371 ok(@{$content->{floating_nodes}} == 0, 'one floating con');
372 @docked = get_dock_clients;
373 is(@docked, 1, 'one dock client now');
374
375 $window->destroy;
376
377 does_i3_live;
378
379 exit_gracefully($pid);
380
381 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests the workspace_layout config option.
17 #
18
19 use i3test i3_autostart => 0;
20
21 #####################################################################
22 # 1: check that with an empty config, cons are place next to each
23 # other and no split containers are created
24 #####################################################################
25
26 my $config = <<EOT;
27 # i3 config file (v4)
28 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
29 EOT
30
31 my $pid = launch_with_config($config);
32
33 my $tmp = fresh_workspace;
34
35 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
36
37 my $first = open_window;
38 my $second = open_window;
39
40 is($x->input_focus, $second->id, 'second window focused');
41 my @content = @{get_ws_content($tmp)};
42 ok(@content == 2, 'two containers opened');
43 isnt($content[0]->{layout}, 'stacked', 'layout not stacked');
44 isnt($content[1]->{layout}, 'stacked', 'layout not stacked');
45
46 exit_gracefully($pid);
47
48 #####################################################################
49 # 2: set workspace_layout stacked, check that when opening two cons,
50 # they end up in a stacked con
51 #####################################################################
52
53 $config = <<EOT;
54 # i3 config file (v4)
55 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
56 workspace_layout stacked
57 EOT
58
59 $pid = launch_with_config($config);
60
61 $tmp = fresh_workspace;
62
63 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
64
65 $first = open_window;
66 $second = open_window;
67
68 is($x->input_focus, $second->id, 'second window focused');
69 @content = @{get_ws_content($tmp)};
70 ok(@content == 1, 'one con at workspace level');
71 is($content[0]->{layout}, 'stacked', 'layout stacked');
72
73 #####################################################################
74 # 3: focus parent, open two new cons, check that they end up in a stacked
75 # con
76 #####################################################################
77
78 cmd 'focus parent';
79 my $right_top = open_window;
80 my $right_bot = open_window;
81
82 @content = @{get_ws_content($tmp)};
83 is(@content, 2, 'two cons at workspace level after focus parent');
84 is($content[0]->{layout}, 'stacked', 'layout stacked');
85 is($content[1]->{layout}, 'stacked', 'layout stacked');
86
87 #####################################################################
88 # 4: move one of the cons to the right, check that it will end up in
89 # a stacked con
90 #####################################################################
91
92 cmd 'move right';
93
94 @content = @{get_ws_content($tmp)};
95 is(@content, 3, 'three cons at workspace level after move');
96 is($content[0]->{layout}, 'stacked', 'layout stacked');
97 is($content[1]->{layout}, 'stacked', 'layout stacked');
98 is($content[2]->{layout}, 'stacked', 'layout stacked');
99
100 #####################################################################
101 # 5: move it to the left again, check that the stacked con is deleted
102 #####################################################################
103
104 cmd 'move left';
105
106 @content = @{get_ws_content($tmp)};
107 is(@content, 2, 'two cons at workspace level after moving back');
108 is($content[0]->{layout}, 'stacked', 'layout stacked');
109 is($content[1]->{layout}, 'stacked', 'layout stacked');
110
111 #####################################################################
112 # 6: move it to a different workspace, check that it ends up in a
113 # stacked con
114 #####################################################################
115
116 my $otmp = get_unused_workspace;
117
118 cmd "move workspace $otmp";
119
120 @content = @{get_ws_content($tmp)};
121 is(@content, 2, 'still two cons on this workspace');
122 is($content[0]->{layout}, 'stacked', 'layout stacked');
123 is($content[1]->{layout}, 'stacked', 'layout stacked');
124
125 @content = @{get_ws_content($otmp)};
126 is(@content, 1, 'one con on target workspace');
127 is($content[0]->{layout}, 'stacked', 'layout stacked');
128
129 #####################################################################
130 # 7: toggle floating mode and check that we have a stacked con when
131 # re-inserting a floating container.
132 #####################################################################
133
134 $tmp = fresh_workspace;
135
136 $first = open_window;
137 cmd 'floating toggle';
138 cmd 'floating toggle';
139
140 $second = open_window;
141
142 is($x->input_focus, $second->id, 'second window focused');
143 @content = @{get_ws_content($tmp)};
144 ok(@content == 1, 'one con at workspace level');
145 is($content[0]->{layout}, 'stacked', 'layout stacked');
146
147 #####################################################################
148 # 8: when the workspace is empty check that its layout can be changed
149 # from stacked to horizontal split using the 'layout splith' command.
150 #####################################################################
151
152 $tmp = fresh_workspace;
153
154 cmd 'layout stacked';
155 $first = open_window;
156 $second = open_window;
157
158 @content = @{get_ws_content($tmp)};
159 is($content[0]->{layout}, 'stacked', 'layout stacked');
160
161 cmd '[id="' . $first->id . '"] kill';
162 cmd '[id="' . $second->id . '"] kill';
163 sync_with_i3;
164
165 ok(@{get_ws_content($tmp)} == 0, 'workspace is empty');
166
167 cmd 'layout splith';
168 $first = open_window;
169 $second = open_window;
170 @content = @{get_ws_content($tmp)};
171 ok(@content == 2, 'two containers opened');
172 isnt($content[0]->{layout}, 'stacked', 'layout not stacked');
173 isnt($content[1]->{layout}, 'stacked', 'layout not stacked');
174
175 #####################################################################
176 # 9: when the workspace is empty check that its layout can be changed
177 # from stacked to vertical split using the 'layout splitv' command.
178 #####################################################################
179
180 $tmp = fresh_workspace;
181
182 cmd 'layout stacked';
183 $first = open_window;
184 $second = open_window;
185
186 @content = @{get_ws_content($tmp)};
187 is($content[0]->{layout}, 'stacked', 'layout stacked');
188
189 cmd '[id="' . $first->id . '"] kill';
190 cmd '[id="' . $second->id . '"] kill';
191 sync_with_i3;
192
193 ok(@{get_ws_content($tmp)} == 0, 'workspace is empty');
194
195 cmd 'layout splitv';
196 $first = open_window;
197 $second = open_window;
198
199 @content = @{get_ws_content($tmp)};
200 ok(@content == 2, 'two containers opened');
201 isnt($content[0]->{layout}, 'stacked', 'layout not stacked');
202 isnt($content[1]->{layout}, 'stacked', 'layout not stacked');
203
204 #####################################################################
205 # 10: when the workspace is empty check that its layout can be changed
206 # from tabbed to horizontal split using the 'layout splith' command.
207 #####################################################################
208
209 $tmp = fresh_workspace;
210
211 cmd 'layout tabbed';
212 $first = open_window;
213 $second = open_window;
214
215 @content = @{get_ws_content($tmp)};
216 is($content[0]->{layout}, 'tabbed', 'layout tabbed');
217
218 cmd '[id="' . $first->id . '"] kill';
219 cmd '[id="' . $second->id . '"] kill';
220 sync_with_i3;
221
222 ok(@{get_ws_content($tmp)} == 0, 'workspace is empty');
223
224 cmd 'layout splith';
225 $first = open_window;
226 $second = open_window;
227
228 @content = @{get_ws_content($tmp)};
229 ok(@content == 2, 'two containers opened');
230 isnt($content[0]->{layout}, 'tabbed', 'layout not tabbed');
231 isnt($content[1]->{layout}, 'tabbed', 'layout not tabbed');
232
233 #####################################################################
234 # 11: when the workspace is empty check that its layout can be changed
235 # from tabbed to vertical split using the 'layout splitv' command.
236 #####################################################################
237
238 $tmp = fresh_workspace;
239
240 cmd 'layout tabbed';
241 $first = open_window;
242 $second = open_window;
243
244 @content = @{get_ws_content($tmp)};
245 is($content[0]->{layout}, 'tabbed', 'layout tabbed');
246
247 cmd '[id="' . $first->id . '"] kill';
248 cmd '[id="' . $second->id . '"] kill';
249 sync_with_i3;
250
251 ok(@{get_ws_content($tmp)} == 0, 'workspace is empty');
252
253 cmd 'layout splitv';
254 $first = open_window;
255 $second = open_window;
256
257 @content = @{get_ws_content($tmp)};
258 ok(@content == 2, 'two containers opened');
259 isnt($content[0]->{layout}, 'tabbed', 'layout not tabbed');
260 isnt($content[1]->{layout}, 'tabbed', 'layout not tabbed');
261
262 #####################################################################
263 # 12: when the workspace is empty check that its layout can be changed
264 # from stacked to horizontal split using the 'split horizontal' command.
265 #####################################################################
266
267 $tmp = fresh_workspace;
268
269 cmd 'layout stacked';
270 $first = open_window;
271 $second = open_window;
272
273 @content = @{get_ws_content($tmp)};
274 is($content[0]->{layout}, 'stacked', 'layout stacked');
275
276 cmd '[id="' . $first->id . '"] kill';
277 cmd '[id="' . $second->id . '"] kill';
278 sync_with_i3;
279
280 ok(@{get_ws_content($tmp)} == 0, 'workspace is empty');
281
282 cmd 'split horizontal';
283 $first = open_window;
284 $second = open_window;
285 @content = @{get_ws_content($tmp)};
286 ok(@content == 2, 'two containers opened');
287 isnt($content[0]->{layout}, 'stacked', 'layout not stacked');
288 isnt($content[1]->{layout}, 'stacked', 'layout not stacked');
289
290 #####################################################################
291 # 13: when the workspace is empty check that its layout can be changed
292 # from stacked to vertical split using the 'split vertical' command.
293 #####################################################################
294
295 $tmp = fresh_workspace;
296
297 cmd 'layout stacked';
298 $first = open_window;
299 $second = open_window;
300
301 @content = @{get_ws_content($tmp)};
302 is($content[0]->{layout}, 'stacked', 'layout stacked');
303
304 cmd '[id="' . $first->id . '"] kill';
305 cmd '[id="' . $second->id . '"] kill';
306 sync_with_i3;
307
308 ok(@{get_ws_content($tmp)} == 0, 'workspace is empty');
309
310 cmd 'split vertical';
311 $first = open_window;
312 $second = open_window;
313
314 @content = @{get_ws_content($tmp)};
315 ok(@content == 2, 'two containers opened');
316 isnt($content[0]->{layout}, 'stacked', 'layout not stacked');
317 isnt($content[1]->{layout}, 'stacked', 'layout not stacked');
318
319 #####################################################################
320 # 14: when the workspace is empty check that its layout can be changed
321 # from tabbed to horizontal split using the 'split horizontal' command.
322 #####################################################################
323
324 $tmp = fresh_workspace;
325
326 cmd 'layout tabbed';
327 $first = open_window;
328 $second = open_window;
329
330 @content = @{get_ws_content($tmp)};
331 is($content[0]->{layout}, 'tabbed', 'layout tabbed');
332
333 cmd '[id="' . $first->id . '"] kill';
334 cmd '[id="' . $second->id . '"] kill';
335 sync_with_i3;
336
337 ok(@{get_ws_content($tmp)} == 0, 'workspace is empty');
338
339 cmd 'split horizontal';
340 $first = open_window;
341 $second = open_window;
342
343 @content = @{get_ws_content($tmp)};
344 ok(@content == 2, 'two containers opened');
345 isnt($content[0]->{layout}, 'tabbed', 'layout not tabbed');
346 isnt($content[1]->{layout}, 'tabbed', 'layout not tabbed');
347
348 #####################################################################
349 # 15: when the workspace is empty check that its layout can be changed
350 # from tabbed to vertical split using the 'split vertical' command.
351 #####################################################################
352
353 $tmp = fresh_workspace;
354
355 cmd 'layout tabbed';
356 $first = open_window;
357 $second = open_window;
358
359 @content = @{get_ws_content($tmp)};
360 is($content[0]->{layout}, 'tabbed', 'layout tabbed');
361
362 cmd '[id="' . $first->id . '"] kill';
363 cmd '[id="' . $second->id . '"] kill';
364 sync_with_i3;
365
366 ok(@{get_ws_content($tmp)} == 0, 'workspace is empty');
367
368 cmd 'split vertical';
369 $first = open_window;
370 $second = open_window;
371
372 @content = @{get_ws_content($tmp)};
373 ok(@content == 2, 'two containers opened');
374 isnt($content[0]->{layout}, 'tabbed', 'layout not tabbed');
375 isnt($content[1]->{layout}, 'tabbed', 'layout not tabbed');
376
377 exit_gracefully($pid);
378
379 #####################################################################
380 # 16: Check that the command 'layout toggle split' works regardless
381 # of what layout we're using.
382 #####################################################################
383
384 $config = <<EOT;
385 # i3 config file (v4)
386 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
387 workspace_layout default
388 EOT
389
390 $pid = launch_with_config($config);
391
392 $tmp = fresh_workspace;
393
394 my @layouts = ('splith', 'splitv', 'tabbed', 'stacked');
395 my $first_layout;
396
397 foreach $first_layout (@layouts) {
398 cmd 'layout ' . $first_layout;
399 $first = open_window;
400 $second = open_window;
401 cmd 'layout toggle split';
402 @content = @{get_ws_content($tmp)};
403 if ($first_layout eq 'splith') {
404 is($content[0]->{layout}, 'splitv', 'layout toggles to splitv');
405 } else {
406 is($content[0]->{layout}, 'splith', 'layout toggles to splith');
407 }
408
409 cmd '[id="' . $first->id . '"] kill';
410 cmd '[id="' . $second->id . '"] kill';
411 sync_with_i3;
412 }
413
414 exit_gracefully($pid);
415
416 #####################################################################
417 # 17: Check about setting a new layout.
418 #####################################################################
419
420 $config = <<EOT;
421 # i3 config file (v4)
422 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
423 workspace_layout default
424 EOT
425
426 $pid = launch_with_config($config);
427
428 $tmp = fresh_workspace;
429
430 my $second_layout;
431
432 foreach $first_layout (@layouts) {
433 foreach $second_layout (@layouts) {
434 cmd 'layout ' . $first_layout;
435 $first = open_window;
436 $second = open_window;
437 cmd 'layout ' . $second_layout;
438 @content = @{get_ws_content($tmp)};
439 is($content[0]->{layout}, $second_layout, 'layout changes to ' . $second_layout);
440
441 cmd '[id="' . $first->id . '"] kill';
442 cmd '[id="' . $second->id . '"] kill';
443 sync_with_i3;
444 }
445 }
446
447 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that i3 survives inplace restarts with fullscreen containers
17 #
18 use i3test;
19
20 fresh_workspace;
21
22 open_window;
23 open_window;
24
25 cmd 'layout stacking';
26 sync_with_i3;
27
28 cmd 'fullscreen';
29 sync_with_i3;
30
31 cmd 'restart';
32
33 does_i3_live;
34
35 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests if the 'border toggle' command works correctly
17 #
18 use i3test;
19
20 my $tmp = fresh_workspace;
21
22 cmd 'open';
23
24 my @nodes = @{get_ws_content($tmp)};
25 is(@nodes, 1, 'one container on this workspace');
26 is($nodes[0]->{border}, 'normal', 'border style normal');
27
28 cmd 'border 1pixel';
29 @nodes = @{get_ws_content($tmp)};
30 is($nodes[0]->{border}, 'pixel', 'border style pixel');
31 is($nodes[0]->{current_border_width}, 1, 'border width = 1px');
32
33 cmd 'border none';
34 @nodes = @{get_ws_content($tmp)};
35 is($nodes[0]->{border}, 'none', 'border style none');
36 is($nodes[0]->{current_border_width}, 0, 'border width = 0px');
37
38 cmd 'border normal';
39 @nodes = @{get_ws_content($tmp)};
40 is($nodes[0]->{border}, 'normal', 'border style back to normal');
41 is($nodes[0]->{current_border_width}, 2, 'border width = 2px');
42
43 cmd 'border toggle';
44 @nodes = @{get_ws_content($tmp)};
45 is($nodes[0]->{border}, 'none', 'border style none');
46 is($nodes[0]->{current_border_width}, 0, 'border width = 0px');
47
48 cmd 'border toggle';
49 @nodes = @{get_ws_content($tmp)};
50 is($nodes[0]->{border}, 'pixel', 'border style pixel');
51 is($nodes[0]->{current_border_width}, 1, 'border width = 1px');
52
53 cmd 'border toggle';
54 @nodes = @{get_ws_content($tmp)};
55 is($nodes[0]->{border}, 'normal', 'border style back to normal');
56 is($nodes[0]->{current_border_width}, 2, 'border width = 2px');
57
58 cmd 'border toggle 10';
59 @nodes = @{get_ws_content($tmp)};
60 is($nodes[0]->{border}, 'none', 'border style back to none even with width argument');
61 is($nodes[0]->{current_border_width}, 0, 'border width = 0px');
62
63 cmd 'border toggle 10';
64 @nodes = @{get_ws_content($tmp)};
65 is($nodes[0]->{border}, 'pixel', 'border style pixel');
66 is($nodes[0]->{current_border_width}, 10, 'border width = 10px');
67
68 cmd 'border toggle 10';
69 @nodes = @{get_ws_content($tmp)};
70 is($nodes[0]->{border}, 'normal', 'border style back to normal');
71 is($nodes[0]->{current_border_width}, 10, 'border width = 10px');
72
73 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests if the 'force_focus_wrapping' config directive works correctly.
17 #
18 use i3test i3_autostart => 0;
19
20 #####################################################################
21 # 1: test the wrapping behaviour without force_focus_wrapping
22 #####################################################################
23
24 my $config = <<EOT;
25 # i3 config file (v4)
26 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
27 EOT
28
29 my $pid = launch_with_config($config);
30
31 my $tmp = fresh_workspace;
32
33 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
34
35 my $first = open_window;
36 my $second = open_window;
37
38 cmd 'layout tabbed';
39 cmd 'focus parent';
40
41 my $third = open_window;
42 is($x->input_focus, $third->id, 'third window focused');
43
44 cmd 'focus left';
45 is($x->input_focus, $second->id, 'second window focused');
46
47 cmd 'focus left';
48 is($x->input_focus, $first->id, 'first window focused');
49
50 # now test the wrapping
51 cmd 'focus left';
52 is($x->input_focus, $second->id, 'second window focused');
53
54 # but focusing right should not wrap now, but instead focus the third window
55 cmd 'focus right';
56 is($x->input_focus, $third->id, 'third window focused');
57
58 exit_gracefully($pid);
59
60 #####################################################################
61 # 2: test the wrapping behaviour with force_focus_wrapping
62 #####################################################################
63
64 $config = <<EOT;
65 # i3 config file (v4)
66 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
67 force_focus_wrapping true
68 EOT
69
70 $pid = launch_with_config($config);
71
72 $tmp = fresh_workspace;
73
74 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
75
76 $first = open_window;
77 $second = open_window;
78
79 cmd 'layout tabbed';
80 cmd 'focus parent';
81
82 $third = open_window;
83
84 is($x->input_focus, $third->id, 'third window focused');
85
86 cmd 'focus left';
87 is($x->input_focus, $second->id, 'second window focused');
88
89 cmd 'focus left';
90 is($x->input_focus, $first->id, 'first window focused');
91
92 # now test the wrapping
93 cmd 'focus left';
94 is($x->input_focus, $second->id, 'second window focused');
95
96 # focusing right should now be forced to wrap
97 cmd 'focus right';
98 is($x->input_focus, $first->id, 'first window focused');
99
100 exit_gracefully($pid);
101
102 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests if i3-migrate-config-to-v4 correctly migrates all config file
17 # directives and commands
18 #
19 use i3test i3_autostart => 0;
20 use Cwd qw(abs_path);
21 use File::Temp qw(tempfile tempdir);
22 use v5.10;
23
24 sub migrate_config {
25 my ($config) = @_;
26
27 my ($fh, $tmpfile) = tempfile('/tmp/i3-migrate-cfg.XXXXXX', UNLINK => 1);
28 print $fh $config;
29 close($fh);
30
31 my $cmd = "sh -c 'exec i3-migrate-config-to-v4 --v3 <$tmpfile'";
32 return [ split /\n/, qx($cmd) ];
33 }
34
35 sub line_exists {
36 my ($lines, $pattern) = @_;
37
38 for my $line (@$lines) {
39 return 1 if $line =~ $pattern;
40 }
41
42 return 0
43 }
44
45 #####################################################################
46 # check that some directives remain untouched
47 #####################################################################
48
49 my $input = <<EOT;
50 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
51 EOT
52
53 my $output = migrate_config($input);
54 ok(line_exists($output, qr|font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1|), 'font directive unchanged');
55
56 $input = <<EOT;
57 floating_Modifier Mod1
58 focus_follows_mouse true
59 ipc-socket /tmp/i3-ipc.sock
60 ipc_socket /tmp/i3-ipc.sock
61 exec /usr/bin/i3
62 set stuff Mod1
63 assign "XTerm" → 3
64 assign "XTerm" → ~5
65 client.focused #2F343A #900000 #FFFFFF
66 client.focused_inactive #FF0000 #FF0000 #FF0000
67 client.unfocused #00FF00 #00FF00 #00FF00
68 client.urgent #0000FF #0000FF #0000FF
69 client.background #000000
70 EOT
71
72 $output = migrate_config($input);
73 ok(line_exists($output, qr|^floating_Modifier Mod1$|), 'floating_modifier unchanged');
74 ok(line_exists($output, qr|^focus_follows_mouse true$|), 'focus_follows_mouse unchanged');
75 ok(line_exists($output, qr|^ipc-socket /tmp/i3-ipc.sock$|), 'ipc-socket unchanged');
76 ok(line_exists($output, qr|^ipc_socket /tmp/i3-ipc.sock$|), 'ipc_socket unchanged');
77 ok(line_exists($output, qr|^exec /usr/bin/i3|), 'exec unchanged');
78 ok(line_exists($output, qr|^set stuff Mod1|), 'set unchanged');
79 ok(line_exists($output, qr|^assign "XTerm" → 3|), 'assign unchanged');
80 ok(line_exists($output, qr|^assign "XTerm" → ~5|), 'assign unchanged');
81 ok(line_exists($output, qr|^client\.focused #2F343A #900000 #FFFFFF$|), 'client.focused unchanged');
82 ok(line_exists($output, qr|^client\.focused_inactive #FF0000 #FF0000 #FF0000$|), 'client.focused_inactive unchanged');
83 ok(line_exists($output, qr|^client\.unfocused #00FF00 #00FF00 #00FF00$|), 'client.unfocused unchanged');
84 ok(line_exists($output, qr|^client\.urgent #0000FF #0000FF #0000FF$|), 'client.urgent unchanged');
85 ok(line_exists($output, qr|^client\.background #000000$|), 'client.background unchanged');
86
87 #####################################################################
88 # check whether the bar colors get removed properly
89 #####################################################################
90
91 $input = <<EOT;
92 bar.focused #FFFF00 #FFFF00 #FFFF00
93 bar.unfocused #FFFF00 #FFFF00 #FFFF00
94 bar.urgent #FFFF00 #FFFF00 #FFFF00
95 EOT
96
97 $output = migrate_config($input);
98 ok(!line_exists($output, qr|^bar\.|), 'no bar. lines');
99 ok(line_exists($output, qr|^#.*REMOVED bar|), 'note bar. removed');
100
101
102 #####################################################################
103 # check whether the other directives get converted correctly
104 #####################################################################
105
106 $input = <<EOT;
107 new_container stacking
108 workspace_bar no
109 new_window bb
110 EOT
111
112 $output = migrate_config($input);
113 ok(line_exists($output, qr|^workspace_layout stacking$|), 'new_container changed');
114 ok(line_exists($output, qr|REMOVED workspace_bar|), 'workspace_bar removed');
115 ok(!line_exists($output, qr|^workspace_bar|), 'no workspace_bar in the output');
116 ok(line_exists($output, qr|^new_window none$|), 'new_window changed');
117
118 #####################################################################
119 # check whether new_window's parameters get changed correctly
120 #####################################################################
121
122 $input = <<EOT;
123 new_window bb
124 new_window bn
125 new_window bp
126 EOT
127 $output = migrate_config($input);
128 like($output->[0], qr|^new_window none$|, 'new_window bb changed');
129 like($output->[1], qr|^new_window normal$|, 'new_window bn changed');
130 like($output->[2], qr|^new_window 1pixel$|, 'new_window bp changed');
131
132 #####################################################################
133 # check that some commands remain untouched
134 #####################################################################
135
136 $input = <<EOT;
137 bindsym Mod1+s exec /usr/bin/urxvt
138 bindsym Mod1+s mark foo
139 bindsym Mod1+s restart
140 bindsym Mod1+s reload
141 bindsym Mod1+s exit
142 bind Mod1+c exec /usr/bin/urxvt
143 mode "asdf" {
144 bind 36 mode default
145 }
146 EOT
147
148 $output = migrate_config($input);
149 ok(line_exists($output, qr|^bindsym Mod1\+s exec /usr/bin/urxvt$|), 'exec unchanged');
150 ok(line_exists($output, qr|^bindsym Mod1\+s mark foo$|), 'mark unchanged');
151 ok(line_exists($output, qr|^bindsym Mod1\+s restart$|), 'restart unchanged');
152 ok(line_exists($output, qr|^bindsym Mod1\+s reload$|), 'reload unchanged');
153 ok(line_exists($output, qr|^bindsym Mod1\+s exit$|), 'exit unchanged');
154 ok(line_exists($output, qr|^bindcode Mod1\+c exec /usr/bin/urxvt$|), 'bind changed to bindcode');
155 ok(line_exists($output, qr|^mode "asdf" \{$|), 'mode asdf unchanged');
156 ok(line_exists($output, qr|^bindcode 36 mode \"default\"$|), 'mode default unchanged');
157 ok(line_exists($output, qr|^}$|), 'closing mode bracket still there');
158
159 #####################################################################
160 # check the simple command replacements
161 #####################################################################
162
163 $input = <<EOT;
164 bindsym Mod1+s s
165 bindsym Mod1+s d
166 bindsym Mod1+s T
167
168 bindsym Mod1+s f
169 bindsym Mod1+s fg
170
171 bindsym Mod1+s t
172
173 bindsym Mod1+s h
174 bindsym Mod1+s j
175 bindsym Mod1+s k
176 bindsym Mod1+s l
177
178 bindsym Mod1+s mh
179 bindsym Mod1+s mj
180 bindsym Mod1+s mk
181 bindsym Mod1+s ml
182
183 bindsym Mod1+s bn
184 bindsym Mod1+s bp
185 bindsym Mod1+s bb
186 bindsym Mod1+s bt
187
188 bindsym Mod1+j wch
189 bindsym Mod1+j wcml
190
191 bindsym Mod1+k kill
192
193 bindsym Mod1+n nw
194 bindsym Mod1+p pw
195 EOT
196
197 $output = migrate_config($input);
198 ok(line_exists($output, qr|^bindsym Mod1\+s layout stacking$|), 's replaced');
199 ok(line_exists($output, qr|^bindsym Mod1\+s layout toggle split$|), 'd replaced');
200 ok(line_exists($output, qr|^bindsym Mod1\+s layout tabbed$|), 'T replaced');
201 ok(line_exists($output, qr|^bindsym Mod1\+s fullscreen$|), 'f replaced');
202 ok(line_exists($output, qr|^bindsym Mod1\+s fullscreen global$|), 'fg replaced');
203 ok(line_exists($output, qr|^bindsym Mod1\+s floating toggle$|), 't replaced');
204 ok(line_exists($output, qr|^bindsym Mod1\+s focus left$|), 'h replaced');
205 ok(line_exists($output, qr|^bindsym Mod1\+s focus down$|), 'j replaced');
206 ok(line_exists($output, qr|^bindsym Mod1\+s focus up$|), 'k replaced');
207 ok(line_exists($output, qr|^bindsym Mod1\+s focus right$|), 'l replaced');
208 ok(line_exists($output, qr|^bindsym Mod1\+s move left$|), 'mh replaced');
209 ok(line_exists($output, qr|^bindsym Mod1\+s move down$|), 'mj replaced');
210 ok(line_exists($output, qr|^bindsym Mod1\+s move up$|), 'mk replaced');
211 ok(line_exists($output, qr|^bindsym Mod1\+s move right$|), 'ml replaced');
212 ok(line_exists($output, qr|^bindsym Mod1\+s border normal$|), 'bn replaced');
213 ok(line_exists($output, qr|^bindsym Mod1\+s border 1pixel$|), 'bp replaced');
214 ok(line_exists($output, qr|^bindsym Mod1\+s border none$|), 'bb replaced');
215 ok(line_exists($output, qr|^bindsym Mod1\+s border toggle$|), 'bt replaced');
216 ok(line_exists($output, qr|^bindsym Mod1\+j focus parent; focus left$|), 'with container replaced with focus parent; focus left');
217 ok(line_exists($output, qr|^bindsym Mod1\+j focus parent; move right$|), 'with container replaced with focus parent; move right');
218 ok(line_exists($output, qr|^bindsym Mod1\+k kill$|), 'kill unchanged');
219 ok(line_exists($output, qr|^bindsym Mod1\+n workspace next$|), 'nw replaced');
220 ok(line_exists($output, qr|^bindsym Mod1\+p workspace prev$|), 'pw replaced');
221
222 #####################################################################
223 # check more advanced replacements
224 #####################################################################
225
226 $input = <<EOT;
227 bindsym Mod1+s goto foo
228 EOT
229
230 $output = migrate_config($input);
231 ok(line_exists($output, qr|^bindsym Mod1\+s \[con_mark="foo"\] focus$|), 'goto replaced');
232
233 #####################################################################
234 # check whether focus's parameters get changed correctly
235 #####################################################################
236
237 $input = <<EOT;
238 bindsym Mod1+f focus 3
239 bindsym Mod1+f focus floating
240 bindsym Mod1+f focus tiling
241 bindsym Mod1+f focus ft
242 EOT
243
244 $output = migrate_config($input);
245 like($output->[0], qr|^#.*focus.*obsolete.*focus 3$|, 'focus [number] gone');
246 like($output->[1], qr|^bindsym Mod1\+f focus floating$|, 'focus floating unchanged');
247 like($output->[2], qr|^bindsym Mod1\+f focus tiling$|, 'focus tiling unchanged');
248 like($output->[3], qr|^bindsym Mod1\+f focus mode_toggle$|, 'focus ft changed');
249
250 #####################################################################
251 # check whether resize's parameters get changed correctly
252 #####################################################################
253
254 $input = <<EOT;
255 bindsym Mod1+f resize left +10
256 bindsym Mod1+f resize top -20
257 bindsym Mod1+f resize right -20
258 bindsym Mod1+f resize bottom +23
259 bindsym Mod1+f resize left \t +10
260 EOT
261
262 $output = migrate_config($input);
263 like($output->[0], qr|^bindsym Mod1\+f resize grow left 10 px$|, 'resize left changed');
264 like($output->[1], qr|^bindsym Mod1\+f resize shrink up 20 px$|, 'resize top changed');
265 like($output->[2], qr|^bindsym Mod1\+f resize shrink right 20 px$|, 'resize right changed');
266 like($output->[3], qr|^bindsym Mod1\+f resize grow down 23 px$|, 'resize bottom changed');
267
268 #####################################################################
269 # also resizing, but with indention this time
270 #####################################################################
271
272 like($output->[4], qr|^bindsym Mod1\+f resize grow left 10 px$|, 'resize left changed');
273
274 #####################################################################
275 # check whether jump's parameters get changed correctly
276 #####################################################################
277
278 $input = <<EOT;
279 bindsym Mod1+f jump 3
280 bindsym Mod1+f jump 3 4 5
281 bindsym Mod1+f jump "XTerm"
282 bindsym Mod1+f jump "XTerm/irssi"
283 EOT
284
285 $output = migrate_config($input);
286 like($output->[0], qr|^#.*obsolete.*jump 3$|, 'jump to workspace removed');
287 like($output->[1], qr|^#.*obsolete.*jump 3 4 5$|, 'jump to workspace + col/row removed');
288 like($output->[2], qr|^bindsym Mod1\+f \[class="XTerm"\] focus$|, 'jump changed');
289 like($output->[3], qr|^bindsym Mod1\+f \[class="XTerm" title="irssi"\] focus$|, 'jump changed');
290
291 #####################################################################
292 # check whether workspace commands are handled correctly
293 #####################################################################
294
295 $output = migrate_config('workspace 3 output VGA-1');
296 ok(line_exists($output, qr|^workspace 3 output VGA-1$|), 'workspace assignment unchanged');
297
298 $output = migrate_config('workspace 3 work');
299 ok(!line_exists($output, qr|^workspace|), 'workspace name not present');
300 ok(line_exists($output, qr|#.*workspace name.*bindings|), 'note present');
301
302 $input = <<EOT;
303 workspace 3 work
304 bindsym Mod1+3 3
305 EOT
306 $output = migrate_config($input);
307 ok(!line_exists($output, qr|^workspace|), 'workspace name not present');
308 ok(line_exists($output, qr|^bindsym Mod1\+3 workspace work|), 'named workspace in bindings');
309
310 # The same, but in reverse order
311 $input = <<EOT;
312 bindsym Mod1+3 3
313 workspace 3 work
314 EOT
315 $output = migrate_config($input);
316 ok(!line_exists($output, qr|^workspace|), 'workspace name not present');
317 ok(line_exists($output, qr|^bindsym Mod1\+3 workspace work|), 'named workspace in bindings');
318
319 $output = migrate_config('bindsym Mod1+3 3');
320 ok(line_exists($output, qr|^bindsym Mod1\+3 workspace 3|), 'workspace changed');
321
322 $output = migrate_config('bindsym Mod1+3 m3');
323 ok(line_exists($output, qr|^bindsym Mod1\+3 move container to workspace 3|), 'move workspace changed');
324
325 $input = <<EOT;
326 workspace 3 work
327 bindsym Mod1+3 m3
328 EOT
329 $output = migrate_config($input);
330 ok(!line_exists($output, qr|^workspace|), 'workspace name not present');
331 ok(line_exists($output, qr|^bindsym Mod1\+3 move container to workspace work|), 'move to named workspace in bindings');
332
333 #####################################################################
334 # check whether an i3bar call is added if the workspace bar bar was enabled
335 #####################################################################
336
337 $output = migrate_config('');
338 ok(line_exists($output, qr|bar \{|), 'i3bar added');
339
340 $output = migrate_config('workspace_bar enable');
341 ok(line_exists($output, qr|bar \{|), 'i3bar added');
342
343 $output = migrate_config('workspace_bar no');
344 ok(!line_exists($output, qr|bar \{|), 'no i3bar added');
345
346 #####################################################################
347 # check whether the mode command gets quotes
348 #####################################################################
349
350 $output = migrate_config('bindsym Mod1+m mode foobar');
351 ok(line_exists($output, qr|^bindsym Mod1\+m mode "foobar"|), 'mode got quotes');
352
353 done_testing();
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # checks if i3 starts up on workspace '1' or the first configured named workspace
17 #
18 use i3test i3_autostart => 0;
19
20 ##############################################################
21 # 1: i3 should start with workspace '1'
22 ##############################################################
23
24 my $config = <<EOT;
25 # i3 config file (v4)
26 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
27 EOT
28
29 my $pid = launch_with_config($config);
30
31 my @names = @{get_workspace_names()};
32 is_deeply(\@names, [ '1' ], 'i3 starts on workspace 1 without any configuration');
33
34 exit_gracefully($pid);
35
36 ##############################################################
37 # 2: with named workspaces, i3 should start on the first named one
38 ##############################################################
39
40 $config = <<EOT;
41 # i3 config file (v4)
42 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
43
44 bindsym Mod1+1 workspace foobar
45 EOT
46
47 $pid = launch_with_config($config);
48
49 @names = @{get_workspace_names()};
50 is_deeply(\@names, [ 'foobar' ], 'i3 starts on named workspace foobar');
51
52 exit_gracefully($pid);
53
54 ##############################################################
55 # 3: the same test as 2, but with a quoted workspace name
56 ##############################################################
57
58 $config = <<EOT;
59 # i3 config file (v4)
60 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
61
62 bindsym Mod1+1 workspace "foobar"
63 EOT
64
65 $pid = launch_with_config($config);
66
67 @names = @{get_workspace_names()};
68 is_deeply(\@names, [ 'foobar' ], 'i3 starts on named workspace foobar');
69
70 exit_gracefully($pid);
71
72 ################################################################################
73 # 4: now with whitespace in front of the workspace number
74 ################################################################################
75
76 $config = <<EOT;
77 # i3 config file (v4)
78 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
79
80 bindsym Mod1+1 workspace 3
81 EOT
82
83 $pid = launch_with_config($config);
84
85 @names = @{get_workspace_names()};
86 is_deeply(\@names, [ '3' ], 'i3 starts on workspace 3 without whitespace');
87
88 exit_gracefully($pid);
89
90 ################################################################################
91 # 5: now with a binding that contains multiple commands
92 ################################################################################
93
94 $config = <<EOT;
95 # i3 config file (v4)
96 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
97
98 bindsym Mod1+1 workspace 3; exec foo
99 EOT
100
101 $pid = launch_with_config($config);
102
103 @names = @{get_workspace_names()};
104 is_deeply(\@names, [ '3' ], 'i3 starts on workspace 3 without ;exec foo');
105
106 exit_gracefully($pid);
107
108 ################################################################################
109 # 6: verify internal binding reordering does not affect startup workspace
110 ################################################################################
111
112 $config = <<EOT;
113 # i3 config file (v4)
114 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
115
116 bindsym Mod1+1 workspace 3
117 bindsym Shift+Mod1+1 workspace 4
118 EOT
119
120 $pid = launch_with_config($config);
121
122 @names = @{get_workspace_names()};
123 is_deeply(\@names, [ '3' ], 'i3 starts on workspace 3');
124
125 exit_gracefully($pid);
126
127 ##############################################################
128 # 7: verify optional flags do not affect startup workspace
129 ##############################################################
130
131 $config = <<EOT;
132 # i3 config file (v4)
133 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
134
135 bindsym Mod1+1 workspace --no-auto-back-and-forth number 3:three
136 EOT
137
138 $pid = launch_with_config($config);
139
140 @names = @{get_workspace_names()};
141 is_deeply(\@names, [ '3:three' ], 'i3 starts on named workspace 3:three');
142
143 exit_gracefully($pid);
144
145 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # checks if the IPC message type get_marks works correctly
17 #
18 use i3test;
19
20 sub get_marks {
21 return i3(get_socket_path())->get_marks->recv;
22 }
23
24 ##############################################################
25 # 1: check that get_marks returns no marks yet
26 ##############################################################
27
28 my $tmp = fresh_workspace;
29
30 my $marks = get_marks();
31 is_deeply($marks, [], 'no marks set so far');
32
33 ##############################################################
34 # 2: check that setting a mark is reflected in the get_marks reply
35 ##############################################################
36
37 cmd 'open';
38 cmd 'mark foo';
39
40 is_deeply(get_marks(), [ 'foo' ], 'mark foo set');
41
42 ##############################################################
43 # 3: check that the mark is gone after killing the container
44 ##############################################################
45
46 cmd 'kill';
47
48 is_deeply(get_marks(), [ ], 'mark gone');
49
50 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests the new_window and new_float config option.
17 #
18
19 use i3test i3_autostart => 0;
20
21 #####################################################################
22 # 1: check that new windows start with 'normal' border unless configured
23 # otherwise
24 #####################################################################
25
26 my $config = <<EOT;
27 # i3 config file (v4)
28 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
29 EOT
30
31 my $pid = launch_with_config($config);
32
33 my $tmp = fresh_workspace;
34
35 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
36
37 my $first = open_window;
38
39 my @content = @{get_ws_content($tmp)};
40 ok(@content == 1, 'one container opened');
41 is($content[0]->{border}, 'normal', 'border normal by default');
42
43 exit_gracefully($pid);
44
45 #####################################################################
46 # 2: check that new tiling windows start with '1pixel' border when
47 # configured
48 #####################################################################
49
50 $config = <<EOT;
51 # i3 config file (v4)
52 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
53
54 new_window 1pixel
55 EOT
56
57 $pid = launch_with_config($config);
58
59 $tmp = fresh_workspace;
60
61 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
62
63 $first = open_window;
64
65 @content = @{get_ws_content($tmp)};
66 ok(@content == 1, 'one container opened');
67 is($content[0]->{border}, 'pixel', 'border pixel by default');
68 is($content[0]->{current_border_width}, 1, 'border width pixels 1 (default)');
69
70 exit_gracefully($pid);
71
72 #####################################################################
73 # 3: check that new floating windows start with 'normal' border unless
74 # configured otherwise
75 #####################################################################
76
77 $config = <<EOT;
78 # i3 config file (v4)
79 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
80 EOT
81
82 $pid = launch_with_config($config);
83
84 $tmp = fresh_workspace;
85
86 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
87
88 $first = open_floating_window;
89
90 my $wscontent = get_ws($tmp);
91 my @floating = @{$wscontent->{floating_nodes}};
92 ok(@floating == 1, 'one floating container opened');
93 my $floatingcon = $floating[0];
94 is($floatingcon->{nodes}->[0]->{border}, 'normal', 'border normal by default');
95
96 exit_gracefully($pid);
97
98 #####################################################################
99 # 4: check that new floating windows start with '1pixel' border when
100 # configured
101 #####################################################################
102
103 $config = <<EOT;
104 # i3 config file (v4)
105 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
106
107 new_float 1pixel
108 EOT
109
110 $pid = launch_with_config($config);
111
112 $tmp = fresh_workspace;
113
114 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
115
116 $first = open_floating_window;
117
118 $wscontent = get_ws($tmp);
119 @floating = @{$wscontent->{floating_nodes}};
120 ok(@floating == 1, 'one floating container opened');
121 $floatingcon = $floating[0];
122 is($floatingcon->{nodes}->[0]->{border}, 'pixel', 'border pixel by default');
123
124 exit_gracefully($pid);
125
126 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test for the startup notification protocol.
17 #
18
19 use i3test;
20 use POSIX qw(mkfifo);
21 use File::Temp qw(:POSIX);
22
23 SKIP: {
24
25 skip "X11::XCB too old (need >= 0.07)", 24 if $X11::XCB::VERSION < 0.07;
26
27 use ExtUtils::PkgConfig;
28
29 # setup dependency on libstartup-notification using pkg-config
30 my %sn_config;
31 BEGIN {
32 %sn_config = ExtUtils::PkgConfig->find('libstartup-notification-1.0');
33 }
34
35 use Inline C => Config => LIBS => $sn_config{libs}, CCFLAGS => $sn_config{cflags};
36 use Inline C => <<'END_OF_C_CODE';
37
38 #include <xcb/xcb.h>
39
40 #define SN_API_NOT_YET_FROZEN 1
41 #include <libsn/sn-common.h>
42 #include <libsn/sn-launchee.h>
43
44 static SnDisplay *sndisplay;
45 static SnLauncheeContext *ctx;
46 static xcb_connection_t *conn;
47
48 void init_ctx(void *connptr) {
49 conn = (xcb_connection_t*)connptr;
50 sndisplay = sn_xcb_display_new(conn, NULL, NULL);
51 ctx = sn_launchee_context_new_from_environment(sndisplay, 0);
52 }
53
54 const char *get_startup_id() {
55 return sn_launchee_context_get_startup_id(ctx);
56 }
57
58 void mark_window(int window) {
59 sn_launchee_context_setup_window(ctx, (Window)window);
60 xcb_flush(conn);
61 }
62
63 void complete_startup() {
64 /* mark the startup process complete */
65 sn_launchee_context_complete(ctx);
66 }
67 END_OF_C_CODE
68
69 my $first_ws = fresh_workspace;
70
71 is_num_children($first_ws, 0, 'no containers on this workspace yet');
72
73 ######################################################################
74 # 1) initiate startup, switch workspace, create window
75 # (should be placed on the original workspace)
76 ######################################################################
77
78 # Start a new process via i3 (to initialize a new startup notification
79 # context), then steal its DESKTOP_STARTUP_ID variable. We handle the startup
80 # notification in the testcase from there on.
81 #
82 # This works by setting up a FIFO in which the process (started by i3) will
83 # echo its $DESKTOP_STARTUP_ID. We (blockingly) read the variable into
84 # $startup_id in the testcase.
85 my $tmp = tmpnam();
86 mkfifo($tmp, 0600) or BAIL_OUT "Could not create FIFO in $tmp: $!";
87
88 cmd qq|exec echo \$DESKTOP_STARTUP_ID >$tmp|;
89
90 open(my $fh, '<', $tmp);
91 chomp(my $startup_id = <$fh>);
92 close($fh);
93
94 unlink($tmp);
95
96 isnt($startup_id, '', 'startup_id not empty');
97
98 $ENV{DESKTOP_STARTUP_ID} = $startup_id;
99
100 # Create a new libstartup-notification launchee context
101 init_ctx($x->get_xcb_conn());
102
103 # Make sure the context was set up successfully
104 is(get_startup_id(), $startup_id, 'libstartup-notification returns the same id');
105
106 my $second_ws = fresh_workspace;
107
108 is_num_children($second_ws, 0, 'no containers on the second workspace yet');
109
110 my $win = open_window({ dont_map => 1 });
111 mark_window($win->id);
112 $win->map;
113 # We don’t use wait_for_map because the window will not get mapped -- it is on
114 # a different workspace.
115 # We sync with i3 here to make sure $x->input_focus is updated.
116 sync_with_i3;
117
118 is_num_children($second_ws, 0, 'still no containers on the second workspace');
119 is_num_children($first_ws, 1, 'one container on the first workspace');
120
121 ######################################################################
122 # same thing, but with _NET_STARTUP_ID set on the leader
123 ######################################################################
124
125 my $leader = open_window({ dont_map => 1 });
126 mark_window($leader->id);
127
128 $win = open_window({ dont_map => 1, client_leader => $leader });
129 $win->map;
130 sync_with_i3;
131
132 is_num_children($second_ws, 0, 'still no containers on the second workspace');
133 is_num_children($first_ws, 2, 'two containers on the first workspace');
134
135 ######################################################################
136 # verifies that finishing startup doesn't immediately stop windows
137 # from being placed on the sequence's workspace, but that moving
138 # the leader actually deletes the startup sequence mapping
139 ######################################################################
140
141 complete_startup();
142 sync_with_i3;
143
144 # even when renaming the workspace, windows should end up on the correct one
145 cmd "rename workspace $first_ws to temp";
146
147 # Startup has completed but the 30-second deletion time hasn't elapsed,
148 # so this window should still go on the leader's initial workspace.
149 $win = open_window({ dont_map => 1, client_leader => $leader });
150 $win->map;
151 sync_with_i3;
152
153 cmd "rename workspace temp to $first_ws";
154
155 is_num_children($first_ws, 3, 'three containers on the first workspace');
156
157 # empty 'from' workspaces should not crash the renaming of startup sequences
158 cmd "workspace $first_ws";
159 cmd "rename workspace to temp";
160 cmd "rename workspace to $first_ws";
161
162 # Switch to the first workspace and move the focused window to the
163 # second workspace.
164 cmd "workspace $first_ws";
165 cmd "move workspace $second_ws";
166
167 is_num_children($second_ws, 1, 'one container on the second workspace');
168
169 # Create and switch to a new workspace, just to be safe.
170 my $third_ws = fresh_workspace;
171
172 # Moving the window between workspaces should have immediately
173 # removed the startup workspace mapping. New windows with that
174 # leader should be created on the current workspace.
175 $win = open_window({ dont_map => 1, client_leader => $leader });
176 $win->map;
177 sync_with_i3;
178
179 is_num_children($third_ws, 1, 'one container on the third workspace');
180
181 ######################################################################
182 # 2) open another window after the startup process is completed
183 # (should be placed on the current workspace)
184 ######################################################################
185
186 my $otherwin = open_window;
187 is_num_children($third_ws, 2, 'two containers on the third workspace');
188
189 ######################################################################
190 # 3) test that the --no-startup-id flag for exec leads to no DESKTOP_STARTUP_ID
191 # environment variable.
192 ######################################################################
193
194 mkfifo($tmp, 0600) or BAIL_OUT "Could not create FIFO in $tmp: $!";
195
196 cmd qq|exec --no-startup-id echo \$DESKTOP_STARTUP_ID >$tmp|;
197
198 open($fh, '<', $tmp);
199 chomp($startup_id = <$fh>);
200 close($fh);
201
202 unlink($tmp);
203
204 is($startup_id, '', 'startup_id empty');
205
206 ######################################################################
207 # 4) same thing, but with double quotes in exec
208 ######################################################################
209
210 mkfifo($tmp, 0600) or BAIL_OUT "Could not create FIFO in $tmp: $!";
211
212 cmd qq|exec --no-startup-id "echo \$DESKTOP_STARTUP_ID >$tmp"|;
213
214 open($fh, '<', $tmp);
215 chomp($startup_id = <$fh>);
216 close($fh);
217
218 unlink($tmp);
219
220 is($startup_id, '', 'startup_id empty');
221 }
222
223 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Checks if the 'workspace back_and_forth' command and the
17 # 'workspace_auto_back_and_forth' config directive work correctly.
18 #
19
20 use i3test i3_autostart => 0;
21
22 my $config = <<EOT;
23 # i3 config file (v4)
24 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
25 EOT
26
27 my $pid = launch_with_config($config);
28
29 my $first_ws = fresh_workspace;
30 ok(get_ws($first_ws)->{focused}, 'first workspace focused');
31
32 my $second_ws = fresh_workspace;
33 ok(get_ws($second_ws)->{focused}, 'second workspace focused');
34
35 my $third_ws = fresh_workspace;
36 ok(get_ws($third_ws)->{focused}, 'third workspace focused');
37
38 cmd 'workspace back_and_forth';
39 ok(get_ws($second_ws)->{focused}, 'second workspace focused');
40
41 #####################################################################
42 # test that without workspace_auto_back_and_forth switching to the same
43 # workspace that is currently focused is a no-op
44 #####################################################################
45
46 cmd qq|workspace "$second_ws"|;
47 ok(get_ws($second_ws)->{focused}, 'second workspace still focused');
48
49 ################################################################################
50 # verify that 'move workspace back_and_forth' works as expected
51 ################################################################################
52
53 cmd qq|workspace "$first_ws"|;
54 my $first_win = open_window;
55
56 cmd qq|workspace "$second_ws"|;
57 my $second_win = open_window;
58
59 is(@{get_ws_content($first_ws)}, 1, 'one container on ws 1 before moving');
60 cmd 'move workspace back_and_forth';
61 is(@{get_ws_content($first_ws)}, 2, 'two containers on ws 1 before moving');
62
63 my $third_win = open_window;
64
65 ################################################################################
66 # verify that moving to the current ws is a no-op without
67 # workspace_auto_back_and_forth.
68 ################################################################################
69
70 cmd qq|workspace "$first_ws"|;
71
72 is(@{get_ws_content($second_ws)}, 1, 'one container on ws 2 before moving');
73 cmd qq|move workspace "$first_ws"|;
74 is(@{get_ws_content($second_ws)}, 1, 'still one container');
75
76 exit_gracefully($pid);
77
78 #####################################################################
79 # the same test, but with workspace_auto_back_and_forth
80 #####################################################################
81
82 $config = <<EOT;
83 # i3 config file (v4)
84 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
85 workspace_auto_back_and_forth yes
86 EOT
87
88 $pid = launch_with_config($config);
89
90 $first_ws = fresh_workspace;
91 ok(get_ws($first_ws)->{focused}, 'first workspace focused');
92
93 $second_ws = fresh_workspace;
94 ok(get_ws($second_ws)->{focused}, 'second workspace focused');
95
96 $third_ws = fresh_workspace;
97 ok(get_ws($third_ws)->{focused}, 'third workspace focused');
98
99 cmd qq|workspace "$third_ws"|;
100 ok(get_ws($second_ws)->{focused}, 'second workspace focused');
101 $first_win = open_window;
102
103 ################################################################################
104 # verify that moving to the current ws moves to the previous one with
105 # workspace_auto_back_and_forth.
106 ################################################################################
107
108 cmd qq|workspace "$first_ws"|;
109 $second_win = open_window;
110
111 is(@{get_ws_content($second_ws)}, 1, 'one container on ws 2 before moving');
112 cmd qq|move workspace "$first_ws"|;
113 is(@{get_ws_content($second_ws)}, 2, 'two containers on ws 2');
114
115 ################################################################################
116 # Now see if "workspace number <number>" also works as expected with
117 # workspace_auto_back_and_forth enabled.
118 ################################################################################
119
120 cmd 'workspace number 5';
121 ok(get_ws('5')->{focused}, 'workspace 5 focused');
122 # ensure it stays open
123 cmd 'open';
124
125 cmd 'workspace number 6';
126 ok(get_ws('6')->{focused}, 'workspace 6 focused');
127 # ensure it stays open
128 cmd 'open';
129
130 cmd 'workspace number 6';
131 is(focused_ws, '5', 'workspace 5 focused again');
132
133 ################################################################################
134 # Rename the workspaces and see if workspace number still works with BAF.
135 ################################################################################
136
137 cmd 'rename workspace 5 to 5: foo';
138 cmd 'rename workspace 6 to 6: baz';
139
140 is(focused_ws, '5: foo', 'workspace 5 still focused');
141
142 cmd 'workspace number 6';
143 is(focused_ws, '6: baz', 'workspace 6 now focused');
144
145 cmd 'workspace number 6';
146 is(focused_ws, '5: foo', 'workspace 5 focused again');
147
148 ################################################################################
149 # Place a window in the scratchpad, see if BAF works after showing the
150 # scratchpad window.
151 ################################################################################
152
153 my $scratchwin = open_window;
154 cmd 'move scratchpad';
155
156 # show scratchpad window
157 cmd 'scratchpad show';
158
159 # hide scratchpad window
160 cmd 'scratchpad show';
161
162 cmd 'workspace back_and_forth';
163 is(focused_ws, '6: baz', 'workspace 6 now focused');
164
165 ################################################################################
166 # See if BAF is preserved after restart
167 ################################################################################
168
169 cmd 'restart';
170 cmd 'workspace back_and_forth';
171 is(focused_ws, '5: foo', 'workspace 5 focused after restart');
172
173 ################################################################################
174 # Check BAF switching to renamed workspace.
175 # Issue: #3694
176 ################################################################################
177
178 kill_all_windows;
179 cmd 'workspace --no-auto-back-and-forth 1';
180 open_window;
181 cmd 'workspace --no-auto-back-and-forth 2';
182
183 cmd 'rename workspace 1 to 3';
184 cmd 'workspace back_and_forth';
185 is(focused_ws, '3', 'workspace 3 focused after rename');
186
187 ################################################################################
188 # Check BAF switching to renamed and then closed workspace.
189 # Issue: #3694
190 ################################################################################
191
192 kill_all_windows;
193 cmd 'workspace --no-auto-back-and-forth 1';
194 $first_win = open_window;
195 cmd 'workspace --no-auto-back-and-forth 2';
196
197 cmd 'rename workspace 1 to 3';
198 cmd '[id="' . $first_win->id . '"] kill';
199
200 cmd 'workspace back_and_forth';
201 is(focused_ws, '3', 'workspace 3 focused after renaming and destroying');
202
203 ################################################################################
204 # See if renaming current workspace doesn't affect BAF switching to another
205 # renamed workspace.
206 # Issue: #3694
207 ################################################################################
208
209 kill_all_windows;
210 cmd 'workspace --no-auto-back-and-forth 1';
211 $first_win = open_window;
212 cmd 'workspace --no-auto-back-and-forth 2';
213
214 cmd 'rename workspace 1 to 3';
215 cmd 'rename workspace 2 to 4';
216
217 cmd 'workspace back_and_forth';
218 is(focused_ws, '3', 'workspace 3 focused after renaming');
219
220 exit_gracefully($pid);
221
222 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Checks that the bar config is parsed correctly.
17 #
18
19 use i3test i3_autostart => 0;
20
21 #####################################################################
22 # test a config without any bars
23 #####################################################################
24
25 my $config = <<EOT;
26 # i3 config file (v4)
27 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
28 EOT
29
30 my $pid = launch_with_config($config);
31
32 my $i3 = i3(get_socket_path(0));
33 my $bars = $i3->get_bar_config()->recv;
34 is(@$bars, 0, 'no bars configured');
35
36 exit_gracefully($pid);
37
38 #####################################################################
39 # now provide a simple bar configuration
40 #####################################################################
41
42 $config = <<EOT;
43 # i3 config file (v4)
44 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
45
46 bar {
47 # Start a default instance of i3bar which provides workspace buttons.
48 # Additionally, i3status will provide a statusline.
49 status_command i3status --foo
50 }
51 EOT
52
53 $pid = launch_with_config($config);
54
55 $i3 = i3(get_socket_path(0));
56 $bars = $i3->get_bar_config()->recv;
57 is(@$bars, 1, 'one bar configured');
58
59 my $bar_id = shift @$bars;
60
61 my $bar_config = $i3->get_bar_config($bar_id)->recv;
62 is($bar_config->{status_command}, 'i3status --foo', 'status_command correct');
63 ok(!$bar_config->{verbose}, 'verbose off by default');
64 ok($bar_config->{workspace_buttons}, 'workspace buttons enabled per default');
65 is($bar_config->{workspace_min_width}, 0, 'workspace_min_width ok');
66 ok($bar_config->{binding_mode_indicator}, 'mode indicator enabled per default');
67 is($bar_config->{mode}, 'dock', 'dock mode by default');
68 is($bar_config->{position}, 'bottom', 'position bottom by default');
69 is($bar_config->{tray_padding}, 2, 'tray_padding ok');
70
71 #####################################################################
72 # ensure that reloading cleans up the old bar configs
73 #####################################################################
74
75 cmd 'reload';
76 $bars = $i3->get_bar_config()->recv;
77 is(@$bars, 1, 'still one bar configured');
78
79 exit_gracefully($pid);
80
81 #####################################################################
82 # validate a more complex configuration
83 #####################################################################
84
85 $config = <<EOT;
86 # i3 config file (v4)
87 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
88
89 bar {
90 # Start a default instance of i3bar which does not provide
91 # workspace buttons.
92 # Additionally, i3status will provide a statusline.
93 status_command i3status --bar
94
95 output HDMI1
96 output HDMI2
97
98 tray_output LVDS1
99 tray_output HDMI2
100 tray_padding 0
101 position top
102 mode dock
103 font Terminus
104 workspace_buttons no
105 workspace_min_width 30
106 binding_mode_indicator no
107 verbose yes
108 socket_path /tmp/foobar
109
110 colors {
111 background #ff0000
112 statusline #00ff00
113 focused_background #cc0000
114 focused_statusline #cccc00
115 focused_separator #0000cc
116
117 focused_workspace #4c7899 #285577 #ffffff
118 active_workspace #333333 #222222 #888888
119 inactive_workspace #333333 #222222 #888888
120 urgent_workspace #2f343a #900000 #ffffff
121 binding_mode #abc123 #123abc #ababab
122 }
123 }
124 EOT
125
126 $pid = launch_with_config($config);
127
128 $i3 = i3(get_socket_path(0));
129 $bars = $i3->get_bar_config()->recv;
130 is(@$bars, 1, 'one bar configured');
131
132 $bar_id = shift @$bars;
133
134 $bar_config = $i3->get_bar_config($bar_id)->recv;
135 is($bar_config->{status_command}, 'i3status --bar', 'status_command correct');
136 ok($bar_config->{verbose}, 'verbose on');
137 ok(!$bar_config->{workspace_buttons}, 'workspace buttons disabled');
138 is($bar_config->{workspace_min_width}, 30, 'workspace_min_width ok');
139 ok(!$bar_config->{binding_mode_indicator}, 'mode indicator disabled');
140 is($bar_config->{mode}, 'dock', 'dock mode');
141 is($bar_config->{position}, 'top', 'position top');
142 is_deeply($bar_config->{outputs}, [ 'HDMI1', 'HDMI2' ], 'outputs ok');
143 is_deeply($bar_config->{tray_outputs}, [ 'LVDS1', 'HDMI2' ], 'tray_output ok');
144 is($bar_config->{tray_padding}, 0, 'tray_padding ok');
145 is($bar_config->{font}, 'Terminus', 'font ok');
146 is($bar_config->{socket_path}, '/tmp/foobar', 'socket_path ok');
147 is_deeply($bar_config->{colors},
148 {
149 background => '#ff0000',
150 statusline => '#00ff00',
151 focused_background => '#cc0000',
152 focused_statusline=> '#cccc00',
153 focused_separator => '#0000cc',
154 focused_workspace_border => '#4c7899',
155 focused_workspace_text => '#ffffff',
156 focused_workspace_bg => '#285577',
157 active_workspace_border => '#333333',
158 active_workspace_text => '#888888',
159 active_workspace_bg => '#222222',
160 inactive_workspace_border => '#333333',
161 inactive_workspace_text => '#888888',
162 inactive_workspace_bg => '#222222',
163 urgent_workspace_border => '#2f343a',
164 urgent_workspace_text => '#ffffff',
165 urgent_workspace_bg => '#900000',
166 binding_mode_border => '#abc123',
167 binding_mode_text => '#ababab',
168 binding_mode_bg => '#123abc',
169 }, 'colors ok');
170
171 exit_gracefully($pid);
172
173 #####################################################################
174 # ensure that multiple bars get different IDs
175 #####################################################################
176
177 $config = <<EOT;
178 # i3 config file (v4)
179 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
180
181 bar {
182 # Start a default instance of i3bar which provides workspace buttons.
183 # Additionally, i3status will provide a statusline.
184 status_command i3status --bar
185
186 output HDMI1
187 }
188
189 bar {
190 output VGA1
191 }
192 EOT
193
194 $pid = launch_with_config($config);
195
196 $i3 = i3(get_socket_path(0));
197 $bars = $i3->get_bar_config()->recv;
198 is(@$bars, 2, 'two bars configured');
199 isnt($bars->[0], $bars->[1], 'bar IDs are different');
200
201 my $bar1_config = $i3->get_bar_config($bars->[0])->recv;
202 my $bar2_config = $i3->get_bar_config($bars->[1])->recv;
203
204 isnt($bar1_config->{outputs}, $bar2_config->{outputs}, 'outputs different');
205
206 exit_gracefully($pid);
207
208 #####################################################################
209 # make sure comments work properly
210 #####################################################################
211
212 $config = <<EOT;
213 # i3 config file (v4)
214 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
215
216 bar {
217 # Start a default instance of i3bar which provides workspace buttons.
218 # Additionally, i3status will provide a statusline.
219 status_command i3status --bar
220 #status_command i3status --qux
221 #status_command i3status --qux
222
223 output HDMI1
224 colors {
225 background #000000
226 #background #ffffff
227 }
228 }
229 EOT
230
231 $pid = launch_with_config($config);
232
233 $i3 = i3(get_socket_path(0));
234 $bars = $i3->get_bar_config()->recv;
235 $bar_id = shift @$bars;
236
237 $bar_config = $i3->get_bar_config($bar_id)->recv;
238 is($bar_config->{status_command}, 'i3status --bar', 'status_command correct');
239 is($bar_config->{colors}->{background}, '#000000', 'background color ok');
240
241 exit_gracefully($pid);
242
243 #####################################################################
244 # verify that the old syntax still works
245 #####################################################################
246
247 $config = <<EOT;
248 # i3 config file (v4)
249 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
250
251 bar {
252 # Start a default instance of i3bar which does not provide
253 # workspace buttons.
254 # Additionally, i3status will provide a statusline.
255 status_command i3status --bar
256
257 output HDMI1
258 output HDMI2
259
260 tray_output LVDS1
261 tray_output HDMI2
262 position top
263 mode dock
264 font Terminus
265 workspace_buttons no
266 binding_mode_indicator yes
267 verbose yes
268 socket_path /tmp/foobar
269
270 colors {
271 background #ff0000
272 statusline #00ff00
273
274 focused_workspace #ffffff #285577
275 active_workspace #888888 #222222
276 inactive_workspace #888888 #222222
277 urgent_workspace #ffffff #900000
278 }
279 }
280 EOT
281
282 $pid = launch_with_config($config);
283
284 $i3 = i3(get_socket_path(0));
285 $bars = $i3->get_bar_config()->recv;
286 is(@$bars, 1, 'one bar configured');
287
288 $bar_id = shift @$bars;
289
290 cmd 'nop yeah';
291 $bar_config = $i3->get_bar_config($bar_id)->recv;
292 is($bar_config->{status_command}, 'i3status --bar', 'status_command correct');
293 ok($bar_config->{verbose}, 'verbose on');
294 ok(!$bar_config->{workspace_buttons}, 'workspace buttons disabled');
295 ok($bar_config->{binding_mode_indicator}, 'mode indicator enabled');
296 is($bar_config->{mode}, 'dock', 'dock mode');
297 is($bar_config->{position}, 'top', 'position top');
298 is_deeply($bar_config->{outputs}, [ 'HDMI1', 'HDMI2' ], 'outputs ok');
299 is_deeply($bar_config->{tray_outputs}, [ 'LVDS1', 'HDMI2' ], 'tray_output ok');
300 is($bar_config->{font}, 'Terminus', 'font ok');
301 is($bar_config->{socket_path}, '/tmp/foobar', 'socket_path ok');
302 is_deeply($bar_config->{colors},
303 {
304 background => '#ff0000',
305 statusline => '#00ff00',
306 focused_workspace_text => '#ffffff',
307 focused_workspace_bg => '#285577',
308 active_workspace_text => '#888888',
309 active_workspace_bg => '#222222',
310 inactive_workspace_text => '#888888',
311 inactive_workspace_bg => '#222222',
312 urgent_workspace_text => '#ffffff',
313 urgent_workspace_bg => '#900000',
314 }, '(old) colors ok');
315
316 exit_gracefully($pid);
317
318
319 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests if empty workspaces are closed when the last child
17 # exits, as long as they're not empty.
18 #
19 use i3test;
20
21 my $i3 = i3(get_socket_path());
22
23 # Get a workspace and open a container
24 my $ws = fresh_workspace;
25 my $con = open_empty_con($i3);
26
27 # Go to a second workspace, kill the container
28 fresh_workspace;
29 cmd "[con_id=\"$con\"] kill";
30
31 # The first workspace should have been closed
32 ok(!workspace_exists($ws), 'workspace closed');
33
34 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # The command "move workspace prev; workspace prev" will lead to an error.
17 # This regression is present in 7f9b65f6a752e454c492447be4e21e2ee8faf8fd
18 use i3test;
19
20 my $i3 = i3(get_socket_path());
21
22 # Open one workspace to move the con to
23 my $old = fresh_workspace;
24 my $keep_open_con = open_empty_con($i3);
25
26 # Get a workspace and open a container
27 my $tmp = fresh_workspace;
28 my $con = open_empty_con($i3);
29
30 is_num_children($tmp, 1, 'one container');
31 is_num_children($old, 1, 'one container on old ws');
32
33 cmd 'move workspace prev; workspace prev';
34
35 is_num_children($old, 2, 'container moved away');
36
37 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that i3 does not leak any file descriptors in 'exec'.
17 #
18 use i3test;
19 use POSIX qw(mkfifo);
20 use File::Temp qw(:POSIX tempfile);
21
22 SKIP: {
23 skip "Procfs not available on $^O", 1 if $^O eq 'openbsd';
24
25 my $i3 = i3(get_socket_path());
26
27 my $tmp = tmpnam();
28 mkfifo($tmp, 0600) or die "Could not create FIFO in $tmp";
29 my ($outfh, $outname) = tempfile('/tmp/i3-ls-output.XXXXXX', UNLINK => 1);
30
31 # Get fds from a clean shell
32 my $shoutput = `sh -c "ls -l /proc/self/fd"`;
33
34 # Get fds from i3
35 cmd qq|exec ls -l /proc/self/fd >$outname && echo done >$tmp|;
36
37 open(my $fh, '<', $tmp);
38 # Block on the FIFO, this will return exactly when the command is done.
39 <$fh>;
40 close($fh);
41 unlink($tmp);
42
43 # Get the ls /proc/self/fd output
44 my $i3output;
45 {
46 local $/;
47 $i3output = <$outfh>;
48 }
49 close($outfh);
50
51 sub extract_fds {
52 my $output = @_;
53
54 # Split lines, keep only those which are symlinks.
55 my @lines = grep { /->/ } split("\n", $output);
56
57 my %fds = map { /([0-9]+) -> (.+)$/; ($1, $2) } @lines;
58
59 # Filter out 0, 1, 2 (stdin, stdout, stderr).
60 delete $fds{0};
61 delete $fds{1};
62 delete $fds{2};
63
64 # filter out the fd which is caused by ls calling readdir().
65 for my $fd (keys %fds) {
66 delete $fds{$fd} if $fds{$fd} =~ m,^/proc/\d+/fd$,;
67 }
68
69 return %fds;
70 }
71
72 my %i3fds = extract_fds($i3output);
73 my %shfds = extract_fds($shoutput);
74
75 # Diff the fds to account for services that keep fds open, such as the System Security Services Daemon (sssd)
76 is(scalar keys %i3fds, scalar keys %shfds, 'No file descriptors leaked');
77
78 }
79
80 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test: Changing border style should not have an impact on the size
17 # (geometry) of the child window. See ticket https://bugs.i3wm.org/561
18 # Wrong behaviour manifested itself up to (including) commit
19 # d805d1bbeaf89e11f67c981f94c9f55bbb4b89d9
20 #
21 use i3test;
22
23 my $tmp = fresh_workspace;
24
25 my $win = open_floating_window(rect => [10, 10, 200, 100]);
26
27 my $geometry = $win->rect;
28 is($geometry->{width}, 200, 'width correct');
29 is($geometry->{height}, 100, 'height correct');
30
31 cmd 'border 1pixel';
32
33 $geometry = $win->rect;
34 is($geometry->{width}, 200, 'width correct');
35 is($geometry->{height}, 100, 'height correct');
36
37 ################################################################################
38 # When in fullscreen mode, the original position must not be overwritten.
39 ################################################################################
40
41 sub get_floating_con_rect {
42 my ($nodes, $focus) = get_ws($tmp);
43 my $floating_con = $nodes->{floating_nodes}->[0];
44 return $floating_con->{rect};
45 }
46 my $old_rect = get_floating_con_rect();
47
48 cmd 'fullscreen';
49
50 is_deeply(get_floating_con_rect(), $old_rect, 'Rect the same after going into fullscreen');
51
52 cmd 'border pixel 2';
53
54 is_deeply(get_floating_con_rect(), $old_rect, 'Rect the same after changing border style');
55
56 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test: Focusing a dock window should just do nothing, not crash i3.
17 # See ticket https://bugs.i3wm.org/575
18 # Wrong behaviour manifested itself up to (including) commit
19 # 340592a532b5259c3a3f575de5a9639fad4d1459
20 #
21 use i3test;
22
23 fresh_workspace;
24
25 my $window = open_window(
26 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
27 );
28
29 cmd '[title="' . $window->name . '"] focus';
30
31 does_i3_live;
32
33 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Checks that variables are parsed correctly by using for_window rules with
17 # variables in it.
18 #
19
20 use i3test i3_autostart => 0;
21
22 # starts i3 with the given config, opens a window, returns its border style
23 sub launch_get_border {
24 my ($config) = @_;
25
26 my $pid = launch_with_config($config);
27
28 my $i3 = i3(get_socket_path(0));
29 my $tmp = fresh_workspace;
30
31 my $window = open_window(name => 'special title');
32
33 my @content = @{get_ws_content($tmp)};
34 cmp_ok(@content, '==', 1, 'one node on this workspace now');
35 my $border = $content[0]->{border};
36
37 exit_gracefully($pid);
38
39 return $border;
40 }
41
42 #####################################################################
43 # test thet windows get the default border
44 #####################################################################
45
46 my $config = <<EOT;
47 # i3 config file (v4)
48 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
49 EOT
50
51 is(launch_get_border($config), 'normal', 'normal border');
52
53 #####################################################################
54 # now use a variable and for_window
55 #####################################################################
56
57 $config = <<'EOT';
58 # i3 config file (v4)
59 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
60
61 set $vartest special title
62 for_window [title="$vartest"] border none
63 EOT
64
65 is(launch_get_border($config), 'none', 'no border');
66
67 #####################################################################
68 # check that whitespaces and tabs are ignored
69 #####################################################################
70
71 $config = <<'EOT';
72 # i3 config file (v4)
73 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
74
75 set $vartest special title
76 for_window [title="$vartest"] border none
77 EOT
78
79 is(launch_get_border($config), 'none', 'no border');
80
81 #####################################################################
82 # test that longest matching variable name is substituted
83 #####################################################################
84
85 $config = <<'EOT';
86 # i3 config file (v4)
87 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
88
89 set $var normal title
90 set $vartest special title
91 set $vart mundane title
92 for_window [title="$vartest"] border none
93 EOT
94
95 is(launch_get_border($config), 'none', 'no border');
96
97 #####################################################################
98 # test that variables with longer name than value don't crash i3 with
99 # v3 to v4 conversion.
100 # See: #3076
101 #####################################################################
102
103 $config = <<'EOT';
104 set $var a
105 EOT
106
107 my $pid = launch_with_config($config);
108 does_i3_live;
109 exit_gracefully($pid);
110
111 done_testing;
112
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression: resizing a floating split container leads to a crash.
17 # (Ticket #588, present until 4412ccbe5a4fad8a4cd594e6f10f937515a4d37c)
18 #
19 use i3test;
20
21 my $tmp = fresh_workspace;
22
23 my $first = open_window;
24 cmd 'split v';
25 my $second = open_window;
26
27 cmd 'focus parent';
28 cmd 'floating toggle';
29 cmd 'layout stacking';
30
31 cmd 'resize grow up 10 px or 10 ppt';
32
33 does_i3_live;
34
35 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests for the scratchpad functionality.
17 #
18 use i3test;
19 use List::Util qw(first);
20
21 my $i3 = i3(get_socket_path());
22 my $tmp = fresh_workspace;
23
24 ################################################################################
25 # 1: Verify that the __i3 output contains the __i3_scratch workspace and that
26 # it’s empty initially. Also, __i3 should not show up in GET_OUTPUTS so that
27 # tools like i3bar will not handle it. Similarly, __i3_scratch should not show
28 # up in GET_WORKSPACES. After all, you should not be able to switch to it.
29 ################################################################################
30
31 my $tree = $i3->get_tree->recv;
32 is($tree->{name}, 'root', 'root node is the first thing we get');
33
34 my @__i3 = grep { $_->{name} eq '__i3' } @{$tree->{nodes}};
35 is(scalar @__i3, 1, 'output __i3 found');
36
37 my $content = first { $_->{type} eq 'con' } @{$__i3[0]->{nodes}};
38 my @workspaces = @{$content->{nodes}};
39 my @workspace_names = map { $_->{name} } @workspaces;
40 ok('__i3_scratch' ~~ @workspace_names, '__i3_scratch workspace found');
41
42 my $get_outputs = $i3->get_outputs->recv;
43 my $get_ws = $i3->get_workspaces->recv;
44 my @output_names = map { $_->{name} } @$get_outputs;
45 my @ws_names = map { $_->{name} } @$get_ws;
46
47 ok(!('__i3' ~~ @output_names), '__i3 not in GET_OUTPUTS');
48 ok(!('__i3_scratch' ~~ @ws_names), '__i3_scratch ws not in GET_WORKSPACES');
49
50 ################################################################################
51 # 2: Verify that you cannot switch to the __i3_scratch workspace and moving
52 # windows to __i3_scratch does not work (users should be aware of the different
53 # behavior and acknowledge that by using the scratchpad commands).
54 ################################################################################
55
56 # Try focusing the workspace.
57 my $__i3_scratch = get_ws('__i3_scratch');
58 is($__i3_scratch->{focused}, 0, '__i3_scratch ws not focused');
59
60 cmd 'workspace __i3_scratch';
61
62 $__i3_scratch = get_ws('__i3_scratch');
63 is($__i3_scratch->{focused}, 0, '__i3_scratch ws still not focused');
64
65
66 # Try moving a window to it.
67 is(scalar @{$__i3_scratch->{floating_nodes}}, 0, '__i3_scratch ws empty');
68
69 my $window = open_window;
70 cmd 'move workspace __i3_scratch';
71
72 $__i3_scratch = get_ws('__i3_scratch');
73 is(scalar @{$__i3_scratch->{floating_nodes}}, 0, '__i3_scratch ws empty');
74
75
76 # Try moving the window with the 'output <direction>' command.
77 # We hardcode output left since the pseudo-output will be initialized before
78 # every other output, so it will always be the first one.
79 cmd 'move output left';
80
81 $__i3_scratch = get_ws('__i3_scratch');
82 is(scalar @{$__i3_scratch->{floating_nodes}}, 0, '__i3_scratch ws empty');
83
84
85 # Try moving the window with the 'output <name>' command.
86 cmd 'move output __i3';
87
88 $__i3_scratch = get_ws('__i3_scratch');
89 is(scalar @{$__i3_scratch->{floating_nodes}}, 0, '__i3_scratch ws empty');
90
91
92 ################################################################################
93 # 3: Verify that 'scratchpad toggle' sends a window to the __i3_scratch
94 # workspace and sets the scratchpad flag to SCRATCHPAD_FRESH. The window’s size
95 # and position will be changed on the next 'scratchpad show'.
96 ################################################################################
97
98 my ($nodes, $focus) = get_ws_content($tmp);
99 is(scalar @$nodes, 1, 'precisely one window on current ws');
100 is($nodes->[0]->{scratchpad_state}, 'none', 'scratchpad_state none');
101
102 cmd 'move scratchpad';
103
104 $__i3_scratch = get_ws('__i3_scratch');
105 my @scratch_nodes = @{$__i3_scratch->{floating_nodes}};
106 is(scalar @scratch_nodes, 1, '__i3_scratch contains our window');
107 ($nodes, $focus) = get_ws_content($tmp);
108 is(scalar @$nodes, 0, 'no window on current ws anymore');
109
110 is($scratch_nodes[0]->{scratchpad_state}, 'fresh', 'scratchpad_state fresh');
111
112 $tree = $i3->get_tree->recv;
113 my $__i3 = first { $_->{name} eq '__i3' } @{$tree->{nodes}};
114 isnt($tree->{focus}->[0], $__i3->{id}, '__i3 output not focused');
115
116 $get_outputs = $i3->get_outputs->recv;
117 $get_ws = $i3->get_workspaces->recv;
118 @output_names = map { $_->{name} } @$get_outputs;
119 @ws_names = map { $_->{name} } @$get_ws;
120
121 ok(!('__i3' ~~ @output_names), '__i3 not in GET_OUTPUTS');
122 ok(!('__i3_scratch' ~~ @ws_names), '__i3_scratch ws not in GET_WORKSPACES');
123
124 ################################################################################
125 # 4: Verify that 'scratchpad show' makes the window visible.
126 ################################################################################
127
128 # Open another window so that we can check if focus is on the scratchpad window
129 # after showing it.
130 my $second_window = open_window;
131 my $old_focus = get_focused($tmp);
132
133 cmd 'scratchpad show';
134
135 isnt(get_focused($tmp), $old_focus, 'focus changed');
136
137 $__i3_scratch = get_ws('__i3_scratch');
138 @scratch_nodes = @{$__i3_scratch->{floating_nodes}};
139 is(scalar @scratch_nodes, 0, '__i3_scratch is now empty');
140
141 my $ws = get_ws($tmp);
142 my $output = $tree->{nodes}->[1];
143 my $scratchrect = $ws->{floating_nodes}->[0]->{rect};
144 my $outputrect = $output->{rect};
145
146 is($scratchrect->{width}, $outputrect->{width} * 0.5, 'scratch width is 50%');
147 is($scratchrect->{height}, $outputrect->{height} * 0.75, 'scratch height is 75%');
148 is($scratchrect->{x},
149 ($outputrect->{width} / 2) - ($scratchrect->{width} / 2),
150 'scratch window centered horizontally');
151 is($scratchrect->{y},
152 ($outputrect->{height} / 2 ) - ($scratchrect->{height} / 2),
153 'scratch window centered vertically');
154
155 ################################################################################
156 # 5: Another 'scratchpad show' should make that window go to the scratchpad
157 # again.
158 ################################################################################
159
160 cmd 'scratchpad show';
161
162 $__i3_scratch = get_ws('__i3_scratch');
163 @scratch_nodes = @{$__i3_scratch->{floating_nodes}};
164 is(scalar @scratch_nodes, 1, '__i3_scratch contains our window');
165
166 ################################################################################
167 # 6: Resizing the window should disable auto centering on scratchpad show
168 ################################################################################
169
170 cmd 'scratchpad show';
171
172 $ws = get_ws($tmp);
173 is($ws->{floating_nodes}->[0]->{scratchpad_state}, 'fresh',
174 'scratchpad_state fresh');
175
176 cmd 'resize grow width 10 px';
177 cmd 'scratchpad show';
178 cmd 'scratchpad show';
179
180 $ws = get_ws($tmp);
181 $scratchrect = $ws->{floating_nodes}->[0]->{rect};
182 $outputrect = $output->{rect};
183
184 is($ws->{floating_nodes}->[0]->{scratchpad_state}, 'changed',
185 'scratchpad_state changed');
186 is($scratchrect->{width}, $outputrect->{width} * 0.5 + 10, 'scratch width is 50% + 10px');
187
188 cmd 'resize shrink width 10 px';
189 cmd 'scratchpad show';
190
191 ################################################################################
192 # 7: Verify that repeated 'scratchpad show' cycle through the stack, that is,
193 # toggling a visible window should insert it at the bottom of the stack of the
194 # __i3_scratch workspace.
195 ################################################################################
196
197 my $third_window = open_window(name => 'scratch-match');
198 cmd 'move scratchpad';
199
200 $__i3_scratch = get_ws('__i3_scratch');
201 @scratch_nodes = @{$__i3_scratch->{floating_nodes}};
202 is(scalar @scratch_nodes, 2, '__i3_scratch contains both windows');
203
204 is($scratch_nodes[0]->{scratchpad_state}, 'changed', 'changed window first');
205 is($scratch_nodes[1]->{scratchpad_state}, 'fresh', 'fresh window is second');
206
207 my $changed_id = $scratch_nodes[0]->{nodes}->[0]->{id};
208 my $fresh_id = $scratch_nodes[1]->{nodes}->[0]->{id};
209 is($scratch_nodes[0]->{id}, $__i3_scratch->{focus}->[0], 'changed window first');
210 is($scratch_nodes[1]->{id}, $__i3_scratch->{focus}->[1], 'fresh window second');
211
212 # Repeatedly use 'scratchpad show' and check that the windows are different.
213 cmd 'scratchpad show';
214
215 is(get_focused($tmp), $changed_id, 'focus changed');
216
217 $ws = get_ws($tmp);
218 $scratchrect = $ws->{floating_nodes}->[0]->{rect};
219 is($scratchrect->{width}, $outputrect->{width} * 0.5, 'scratch width is 50%');
220 is($scratchrect->{height}, $outputrect->{height} * 0.75, 'scratch height is 75%');
221 is($scratchrect->{x},
222 ($outputrect->{width} / 2) - ($scratchrect->{width} / 2),
223 'scratch window centered horizontally');
224 is($scratchrect->{y},
225 ($outputrect->{height} / 2 ) - ($scratchrect->{height} / 2),
226 'scratch window centered vertically');
227
228 cmd 'scratchpad show';
229
230 isnt(get_focused($tmp), $changed_id, 'focus changed');
231
232 cmd 'scratchpad show';
233
234 is(get_focused($tmp), $fresh_id, 'focus changed');
235
236 cmd 'scratchpad show';
237
238 isnt(get_focused($tmp), $fresh_id, 'focus changed');
239
240 ################################################################################
241 # 8: Show it, move it around, hide it. Verify that the position is retained
242 # when showing it again.
243 ################################################################################
244
245 cmd '[title="scratch-match"] scratchpad show';
246
247 isnt(get_focused($tmp), $old_focus, 'scratchpad window shown');
248
249 my $oldrect = get_ws($tmp)->{floating_nodes}->[0]->{rect};
250
251 cmd 'move left';
252
253 $scratchrect = get_ws($tmp)->{floating_nodes}->[0]->{rect};
254 isnt($scratchrect->{x}, $oldrect->{x}, 'x position changed');
255 $oldrect = $scratchrect;
256
257 # hide it, then show it again
258 cmd '[title="scratch-match"] scratchpad show';
259 cmd '[title="scratch-match"] scratchpad show';
260
261 # verify the position is still the same
262 $scratchrect = get_ws($tmp)->{floating_nodes}->[0]->{rect};
263
264 is_deeply($scratchrect, $oldrect, 'position/size the same');
265
266 # hide it again for the next test
267 cmd '[title="scratch-match"] scratchpad show';
268
269 is(get_focused($tmp), $old_focus, 'scratchpad window hidden');
270
271 is(scalar @{get_ws($tmp)->{nodes}}, 1, 'precisely one window on current ws');
272
273 ################################################################################
274 # 9: restart i3 and verify that the scratchpad show still works
275 ################################################################################
276
277 $__i3_scratch = get_ws('__i3_scratch');
278 my $old_nodes = scalar @{$__i3_scratch->{nodes}};
279 my $old_floating_nodes = scalar @{$__i3_scratch->{floating_nodes}};
280
281 cmd 'restart';
282
283 does_i3_live;
284
285 $__i3_scratch = get_ws('__i3_scratch');
286 is(scalar @{$__i3_scratch->{nodes}}, $old_nodes, "number of nodes matches ($old_nodes)");
287 is(scalar @{$__i3_scratch->{floating_nodes}}, $old_floating_nodes, "number of floating nodes matches ($old_floating_nodes)");
288
289 is(scalar @{get_ws($tmp)->{nodes}}, 1, 'still precisely one window on current ws');
290 is(scalar @{get_ws($tmp)->{floating_nodes}}, 0, 'still no floating windows on current ws');
291
292 # verify that we can display the scratchpad window
293 cmd '[title="scratch-match"] scratchpad show';
294
295 $ws = get_ws($tmp);
296 is(scalar @{$ws->{nodes}}, 1, 'still precisely one window on current ws');
297 is(scalar @{$ws->{floating_nodes}}, 1, 'precisely one floating windows on current ws');
298 is($ws->{floating_nodes}->[0]->{scratchpad_state}, 'changed', 'scratchpad_state is "changed"');
299
300 ################################################################################
301 # 10: on an empty workspace, ensure the 'move scratchpad' command does nothing
302 ################################################################################
303
304 $tmp = fresh_workspace;
305
306 cmd 'move scratchpad';
307
308 does_i3_live;
309
310 ################################################################################
311 # 11: focus a workspace and move all of its children to the scratchpad area
312 ################################################################################
313
314 sub verify_scratchpad_move_multiple_win {
315 my $floating = shift;
316
317 my $first = open_window;
318 my $second = open_window;
319
320 if ($floating) {
321 cmd 'floating toggle';
322 cmd 'focus tiling';
323 }
324
325 cmd 'focus parent';
326 cmd 'move scratchpad';
327
328 does_i3_live;
329
330 $ws = get_ws($tmp);
331 is(scalar @{$ws->{nodes}}, 0, 'no windows on ws');
332 is(scalar @{$ws->{floating_nodes}}, 0, 'no floating windows on ws');
333
334 # show the first window.
335 cmd 'scratchpad show';
336
337 $ws = get_ws($tmp);
338 is(scalar @{$ws->{nodes}}, 0, 'no windows on ws');
339 is(scalar @{$ws->{floating_nodes}}, 1, 'one floating windows on ws');
340
341 $old_focus = get_focused($tmp);
342
343 cmd 'scratchpad show';
344
345 # show the second window.
346 cmd 'scratchpad show';
347
348 $ws = get_ws($tmp);
349 is(scalar @{$ws->{nodes}}, 0, 'no windows on ws');
350 is(scalar @{$ws->{floating_nodes}}, 1, 'one floating windows on ws');
351
352 isnt(get_focused($tmp), $old_focus, 'focus changed');
353 }
354
355 $tmp = fresh_workspace;
356 verify_scratchpad_move_multiple_win(0);
357 $tmp = fresh_workspace;
358 verify_scratchpad_move_multiple_win(1);
359
360 ################################################################################
361 # 12: open a scratchpad window on a workspace, switch to another workspace and
362 # call 'scratchpad show' again
363 ################################################################################
364
365 sub verify_scratchpad_move_with_visible_scratch_con {
366 my ($first, $second, $cross_output) = @_;
367
368 cmd "workspace $first";
369
370 my $window1 = open_window;
371 cmd 'move scratchpad';
372
373 my $window2 = open_window;
374 cmd 'move scratchpad';
375
376 # this should bring up window 1
377 cmd 'scratchpad show';
378
379 $ws = get_ws($first);
380 is(scalar @{$ws->{floating_nodes}}, 1, 'one floating node on ws1');
381 is($x->input_focus, $window1->id, "showed the correct scratchpad window1");
382
383 # this should bring up window 1
384 cmd "workspace $second";
385 cmd 'scratchpad show';
386 is($x->input_focus, $window1->id, "showed the correct scratchpad window1");
387
388 my $ws2 = get_ws($second);
389 is(scalar @{$ws2->{floating_nodes}}, 1, 'one floating node on ws2');
390 unless ($cross_output) {
391 ok(!workspace_exists($first), 'ws1 was empty and therefore closed');
392 } else {
393 $ws = get_ws($first);
394 is(scalar @{$ws->{floating_nodes}}, 0, 'ws1 has no floating nodes');
395 }
396
397 # hide window 1 again
398 cmd 'move scratchpad';
399
400 # this should bring up window 2
401 cmd "workspace $first";
402 cmd 'scratchpad show';
403 is($x->input_focus, $window2->id, "showed the correct scratchpad window");
404 }
405
406 # let's clear the scratchpad first
407 sub clear_scratchpad {
408 while (scalar @{get_ws('__i3_scratch')->{floating_nodes}}) {
409 cmd 'scratchpad show';
410 cmd 'kill';
411 }
412 }
413
414 clear_scratchpad;
415 is (scalar @{get_ws('__i3_scratch')->{floating_nodes}}, 0, "scratchpad is empty");
416
417 my ($first, $second);
418 $first = fresh_workspace;
419 $second = fresh_workspace;
420
421 verify_scratchpad_move_with_visible_scratch_con($first, $second, 0);
422 does_i3_live;
423
424
425 ################################################################################
426 # 13: Test whether scratchpad show moves focus to the scratchpad window
427 # when another window on the same workspace has focus
428 ################################################################################
429
430 clear_scratchpad;
431 $ws = fresh_workspace;
432
433 open_window;
434 my $scratch = get_focused($ws);
435 cmd 'move scratchpad';
436 cmd 'scratchpad show';
437
438 open_window;
439 my $not_scratch = get_focused($ws);
440 is(get_focused($ws), $not_scratch, 'not scratch window has focus');
441
442 cmd 'scratchpad show';
443
444 is(get_focused($ws), $scratch, 'scratchpad is focused');
445
446 # TODO: make i3bar display *something* when a window on the scratchpad has the urgency hint
447
448 ################################################################################
449 # 14: Verify that 'move scratchpad' sends floating containers to scratchpad but
450 # does not resize/resposition the container on the next 'scratchpad show', i.e.,
451 # i3 sets the scratchpad flag to SCRATCHPAD_CHANGED
452 ################################################################################
453
454 clear_scratchpad;
455 $tmp = fresh_workspace;
456 open_window;
457
458 ($nodes, $focus) = get_ws_content($tmp);
459 is(scalar @$nodes, 1, 'precisely one window on current ws');
460 is($nodes->[0]->{scratchpad_state}, 'none', 'scratchpad_state none');
461
462 cmd 'floating toggle';
463 cmd 'move scratchpad';
464
465 $__i3_scratch = get_ws('__i3_scratch');
466 @scratch_nodes = @{$__i3_scratch->{floating_nodes}};
467 is(scalar @scratch_nodes, 1, '__i3_scratch contains our window');
468 ($nodes, $focus) = get_ws_content($tmp);
469 is(scalar @$nodes, 0, 'no window on current ws anymore');
470
471 is($scratch_nodes[0]->{scratchpad_state}, 'changed', 'scratchpad_state changed');
472
473 ################################################################################
474 # 15: Verify that 'scratchpad show' returns correct info.
475 ################################################################################
476
477 kill_all_windows;
478
479 my $result = cmd 'scratchpad show';
480 is($result->[0]->{success}, 0, 'no scratchpad window and call to scratchpad failed');
481
482 open_window;
483 cmd 'move scratchpad';
484 $result = cmd 'scratchpad show';
485 is($result->[0]->{success}, 1, 'call to scratchpad succeeded');
486 $result = cmd 'scratchpad show';
487 is($result->[0]->{success}, 1, 'call to scratchpad succeeded');
488
489 kill_all_windows;
490 $result = cmd 'scratchpad show';
491 is($result->[0]->{success}, 0, 'call to scratchpad failed');
492
493 ################################################################################
494 # 16: Verify that 'scratchpad show' with the criteria returns correct info.
495 ################################################################################
496
497 open_window(name => "scratch-match");
498 cmd 'move scratchpad';
499
500 $result = cmd '[title="scratch-match"] scratchpad show';
501 is($result->[0]->{success}, 1, 'call to scratchpad with the criteria succeeded');
502
503 $result = cmd '[title="nomatch"] scratchpad show';
504 is($result->[0]->{success}, 0, 'call to scratchpad with non-matching criteria failed');
505
506 ################################################################################
507 # 17: Open a scratchpad window on a workspace, switch to another workspace and
508 # call 'scratchpad show' again. Verify that it returns correct info.
509 ################################################################################
510
511 fresh_workspace;
512 open_window;
513 cmd 'move scratchpad';
514
515 fresh_workspace;
516 $result = cmd 'scratchpad show';
517 is($result->[0]->{success}, 1, 'call to scratchpad in another workspace succeeded');
518
519 ################################################################################
520 # 18: Disabling floating for a scratchpad window should not work.
521 ################################################################################
522
523 kill_all_windows;
524
525 $ws = fresh_workspace;
526 $window = open_window;
527 cmd 'move scratchpad';
528 cmd '[id=' . $window->id . '] floating disable';
529
530 is(scalar @{get_ws_content($ws)}, 0, 'no window in workspace');
531 cmd 'scratchpad show';
532 is($x->input_focus, $window->id, 'scratchpad window shown');
533
534 ################################################################################
535 # 19: move position commands do not show scratchpad window
536 # See issue #3832
537 ################################################################################
538
539 kill_all_windows;
540
541 fresh_workspace;
542 $first = open_window;
543 $second = open_window;
544
545 cmd '[id=' . $first->id . '] move to scratchpad, move position 100 100';
546 is ($x->input_focus, $second->id, 'moving scratchpad window does not show it');
547 cmd '[id=' . $first->id . '] move position center';
548 is ($x->input_focus, $second->id, 'centering scratchpad window does not show it');
549
550 ###################################################################################
551 # Verify that a scratchpad container with child containers that was open in
552 # another workspace is moved to the current workspace (with all its children)
553 # after a scratchpad show.
554 ################################################################################
555
556 kill_all_windows;
557 open_window;
558 open_window;
559 # This is to dodge the edge case were the whole workspace is moved
560 # window-by-window into the scratchpad.
561 cmd 'layout tabbed';
562 cmd 'focus parent';
563 cmd 'move to scratchpad';
564 $ws = fresh_workspace;
565 cmd 'scratchpad show';
566 # Case 1: a parent node in the scratchpad does not lose children
567 # Note on the layout: there should be a floating tabbed container, which is
568 # represented as follows:
569 # [workspace object] -> [floating_nodes] -> [tabbed node container] -> [the 2 children we expect]
570 is(scalar @{get_ws($ws)->{floating_nodes}->[0]->{nodes}->[0]->{nodes}}, 2, 'both windows moved from scratchpad to this workspace');
571
572 # Case 2: a parent node in the scratchpad from another workspace does not lose children
573 $ws = fresh_workspace;
574 cmd 'scratchpad show';
575 is(scalar @{get_ws($ws)->{floating_nodes}->[0]->{nodes}->[0]->{nodes}}, 2, 'both windows moved from scratchpad focused on other workspace to this workspace');
576
577 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test: New windows were not opened in the correct place if they
17 # matched an assignment.
18 # Wrong behaviour manifested itself up to (including) commit
19 # f78caf8c5815ae7a66de9e4b734546fd740cc19d
20 #
21 use i3test i3_config => <<EOT;
22 # i3 config file (v4)
23 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
24
25 assign [title="testcase"] targetws
26 EOT
27
28 my $i3 = i3(get_socket_path(0));
29
30 cmd 'workspace targetws';
31
32 open_window(name => "testcase");
33 is_num_children('targetws', 1, 'precisely one window');
34
35 open_window(name => "testcase");
36 is_num_children('targetws', 2, 'precisely two windows');
37
38 cmd 'split v';
39
40 open_window(name => "testcase");
41 is_num_children('targetws', 2, 'still two windows');
42
43 # focus parent. the new window should now be opened right next to the last one.
44 cmd 'focus parent';
45
46 open_window(name => "testcase");
47 is_num_children('targetws', 3, 'new window opened next to last one');
48
49 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests the standalone parser binary to see if it calls the right code when
17 # confronted with various commands, if it prints proper error messages for
18 # wrong commands and if it terminates in every case.
19 #
20 use i3test i3_autostart => 0;
21
22 sub parser_calls {
23 my ($command) = @_;
24
25 # TODO: use a timeout, so that we can error out if it doesn’t terminate
26 # TODO: better way of passing arguments
27 my $stdout = qx(test.commands_parser '$command' 2>&1 >&-);
28
29 # Filter out all debugging output.
30 my @lines = split("\n", $stdout);
31 @lines = grep { not /^# / } @lines;
32
33 # The criteria management calls are irrelevant and not what we want to test
34 # in the first place.
35 @lines = grep { !(/cmd_criteria_init()/ || /cmd_criteria_match_windows/) } @lines;
36 return join("\n", @lines);
37 }
38
39 ################################################################################
40 # 1: First that the parser properly recognizes commands which are ok.
41 ################################################################################
42
43 # The first call has only a single command, the following ones are consolidated
44 # for performance.
45 is(parser_calls('move workspace 3'),
46 'cmd_move_con_to_workspace_name(3, (null))',
47 'single number (move workspace 3) ok');
48
49 is(parser_calls(
50 'move to workspace 3; ' .
51 'move window to workspace 3; ' .
52 'move container to workspace 3; ' .
53 'move workspace foobar; ' .
54 'move workspace torrent; ' .
55 'move workspace to output LVDS1; ' .
56 'move workspace 3: foobar; ' .
57 'move workspace "3: foobar"; ' .
58 'move workspace "3: foobar, baz"; '),
59 "cmd_move_con_to_workspace_name(3, (null))\n" .
60 "cmd_move_con_to_workspace_name(3, (null))\n" .
61 "cmd_move_con_to_workspace_name(3, (null))\n" .
62 "cmd_move_con_to_workspace_name(foobar, (null))\n" .
63 "cmd_move_con_to_workspace_name(torrent, (null))\n" .
64 "cmd_move_workspace_to_output(LVDS1)\n" .
65 "cmd_move_con_to_workspace_name(3: foobar, (null))\n" .
66 "cmd_move_con_to_workspace_name(3: foobar, (null))\n" .
67 "cmd_move_con_to_workspace_name(3: foobar, baz, (null))",
68 'move ok');
69
70 is(parser_calls('move workspace 3: foobar, nop foo'),
71 "cmd_move_con_to_workspace_name(3: foobar, (null))\n" .
72 "cmd_nop(foo)",
73 'multiple ops (move workspace 3: foobar, nop foo) ok');
74
75 is(parser_calls(
76 'exec i3-sensible-terminal; ' .
77 'exec --no-startup-id i3-sensible-terminal'),
78 "cmd_exec((null), i3-sensible-terminal)\n" .
79 "cmd_exec(--no-startup-id, i3-sensible-terminal)",
80 'exec ok');
81
82 is(parser_calls(
83 'resize shrink left; ' .
84 'resize shrink left 25 px; ' .
85 'resize shrink left 25 px or 33 ppt; ' .
86 'resize shrink left 25'),
87 "cmd_resize(shrink, left, 10, 10)\n" .
88 "cmd_resize(shrink, left, 25, 0)\n" .
89 "cmd_resize(shrink, left, 25, 33)\n" .
90 "cmd_resize(shrink, left, 25, 0)",
91 'simple resize ok');
92
93 is(parser_calls('resize shrink left 25 px or 33 ppt,'),
94 'cmd_resize(shrink, left, 25, 33)',
95 'trailing comma resize ok');
96
97 is(parser_calls('resize shrink left 25 px or 33 ppt;'),
98 'cmd_resize(shrink, left, 25, 33)',
99 'trailing semicolon resize ok');
100
101 is(parser_calls('[con_mark=yay] focus'),
102 "cmd_criteria_add(con_mark, yay)\n" .
103 "cmd_focus()",
104 'criteria focus ok');
105
106 is(parser_calls("[con_mark=yay con_mark=bar] focus"),
107 "cmd_criteria_add(con_mark, yay)\n" .
108 "cmd_criteria_add(con_mark, bar)\n" .
109 "cmd_focus()",
110 'criteria focus ok');
111
112 is(parser_calls("[con_mark=yay\tcon_mark=bar] focus"),
113 "cmd_criteria_add(con_mark, yay)\n" .
114 "cmd_criteria_add(con_mark, bar)\n" .
115 "cmd_focus()",
116 'criteria focus ok');
117
118 is(parser_calls("[con_mark=yay\tcon_mark=bar]\tfocus"),
119 "cmd_criteria_add(con_mark, yay)\n" .
120 "cmd_criteria_add(con_mark, bar)\n" .
121 "cmd_focus()",
122 'criteria focus ok');
123
124 is(parser_calls('[con_mark="yay"] focus'),
125 "cmd_criteria_add(con_mark, yay)\n" .
126 "cmd_focus()",
127 'quoted criteria focus ok');
128
129 # Make sure trailing whitespace is stripped off: While this is not an issue for
130 # commands being parsed due to the configuration, people might send IPC
131 # commands with leading or trailing newlines.
132 is(parser_calls("workspace test\n"),
133 'cmd_workspace_name(test, (null))',
134 'trailing whitespace stripped off ok');
135
136 is(parser_calls("\nworkspace test"),
137 'cmd_workspace_name(test, (null))',
138 'trailing whitespace stripped off ok');
139
140 ################################################################################
141 # 2: Verify that the parser spits out the right error message on commands which
142 # are not ok.
143 ################################################################################
144
145 is(parser_calls('unknown_literal'),
146 "ERROR: Expected one of these tokens: <end>, '[', '" . join("', '", qw(
147 move
148 exec
149 exit
150 restart
151 reload
152 shmlog
153 debuglog
154 border
155 layout
156 append_layout
157 workspace
158 focus
159 kill
160 open
161 fullscreen
162 sticky
163 split
164 floating
165 mark
166 unmark
167 resize
168 rename
169 nop
170 scratchpad
171 swap
172 title_format
173 mode
174 bar
175 gaps
176 )) . "'\n" .
177 "ERROR: Your command: unknown_literal\n" .
178 "ERROR: ^^^^^^^^^^^^^^^",
179 'error for unknown literal ok');
180
181 is(parser_calls('move something to somewhere'),
182 "ERROR: Expected one of these tokens: 'window', 'container', 'to', '--no-auto-back-and-forth', 'workspace', 'output', 'mark', 'scratchpad', 'left', 'right', 'up', 'down', 'position', 'absolute'\n" .
183 "ERROR: Your command: move something to somewhere\n" .
184 "ERROR: ^^^^^^^^^^^^^^^^^^^^^^",
185 'error for unknown literal ok');
186
187 ################################################################################
188 # 3: Verify that escaping works correctly
189 ################################################################################
190
191 is(parser_calls('workspace "foo"'),
192 'cmd_workspace_name(foo, (null))',
193 'Command with simple double quotes ok');
194
195 is(parser_calls('workspace "foo'),
196 'cmd_workspace_name(foo, (null))',
197 'Command without ending double quotes ok');
198
199 is(parser_calls('workspace "foo \"bar"'),
200 'cmd_workspace_name(foo "bar, (null))',
201 'Command with escaped double quotes ok');
202
203 is(parser_calls('workspace "foo \\'),
204 'cmd_workspace_name(foo \\, (null))',
205 'Command with single backslash in the end ok');
206
207 is(parser_calls('workspace "foo\\\\bar"'),
208 'cmd_workspace_name(foo\\bar, (null))',
209 'Command with escaped backslashes ok');
210
211 is(parser_calls('workspace "foo\\\\\\"bar"'),
212 'cmd_workspace_name(foo\\"bar, (null))',
213 'Command with escaped double quotes after escaped backslashes ok');
214
215 ################################################################################
216 # 4: Verify that resize commands with a "px or ppt"-construction are parsed
217 # correctly
218 ################################################################################
219
220 is(parser_calls("resize shrink width 10 px or"),
221 "ERROR: Expected one of these tokens: <number>\n" .
222 "ERROR: Your command: resize shrink width 10 px or\n" .
223 "ERROR: ",
224 "error for resize command with incomplete 'or'-construction ok");
225
226 is(parser_calls("resize grow left 10 px or 20 ppt"),
227 "cmd_resize(grow, left, 10, 20)",
228 "resize command with 'or'-construction ok");
229
230 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that i3 survives inplace restarts with fullscreen containers
17 #
18 use i3test;
19
20 my $tmp = fresh_workspace;
21
22 open_window(name => 'first');
23 open_window(name => 'second');
24
25 cmd 'focus left';
26
27 my ($nodes, $focus) = get_ws_content($tmp);
28 is(scalar @$nodes, 2, 'two tiling nodes on workspace');
29 is($nodes->[0]->{name}, 'first', 'first node name ok');
30 is($nodes->[1]->{name}, 'second', 'second node name ok');
31 is($focus->[0], $nodes->[0]->{id}, 'first node focused');
32 is($focus->[1], $nodes->[1]->{id}, 'second node second in focus stack');
33
34 cmd 'restart';
35
36 does_i3_live;
37
38 ($nodes, $focus) = get_ws_content($tmp);
39 is(scalar @$nodes, 2, 'still two tiling nodes on workspace');
40 is($nodes->[0]->{name}, 'first', 'first node name ok');
41 is($nodes->[1]->{name}, 'second', 'second node name ok');
42 is($focus->[0], $nodes->[0]->{id}, 'first node focused');
43 is($focus->[1], $nodes->[1]->{id}, 'second node second in focus stack');
44
45 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests the floating_{minimum,maximum}_size config options.
17 #
18 # Note that the minimum floating window size is already verified in
19 # t/005-floating.t.
20 #
21
22 use i3test i3_autostart => 0;
23 use X11::XCB qw/PROP_MODE_REPLACE/;
24
25 ################################################################################
26 # 1: check floating_minimum_size (with non-default limits)
27 ################################################################################
28
29 my $config = <<EOT;
30 # i3 config file (v4)
31 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
32
33 # Test with different dimensions than the i3 default.
34 floating_minimum_size 60 x 40
35 EOT
36
37 my $pid = launch_with_config($config);
38
39 my $window = open_floating_window(rect => [ 0, 0, 20, 20 ]);
40 my $rect = $window->rect;
41
42 is($rect->{width}, 60, 'width = 60');
43 is($rect->{height}, 40, 'height = 40');
44
45 exit_gracefully($pid);
46
47 ################################################################################
48 # 2: check floating_minimum_size with -1 (unlimited)
49 ################################################################################
50
51 $config = <<EOT;
52 # i3 config file (v4)
53 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
54
55 floating_minimum_size -1 x -1
56 EOT
57
58 $pid = launch_with_config($config);
59
60 cmd 'nop MEH';
61 $window = open_floating_window(rect => [ 0, 0, 50, 40 ]);
62 $rect = $window->rect;
63
64 is($rect->{width}, 50, 'width = 50');
65 is($rect->{height}, 40, 'height = 40');
66
67 exit_gracefully($pid);
68
69 ################################################################################
70 # 3: check floating_maximum_size
71 ################################################################################
72
73 $config = <<EOT;
74 # i3 config file (v4)
75 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
76
77 # Test with different dimensions than the i3 default.
78 floating_maximum_size 100 x 100
79 EOT
80
81 $pid = launch_with_config($config);
82
83 $window = open_floating_window(rect => [ 0, 0, 150, 150 ]);
84 $rect = $window->rect;
85
86 is($rect->{width}, 100, 'width = 100');
87 is($rect->{height}, 100, 'height = 100');
88
89 exit_gracefully($pid);
90
91 # Test that the feature works at all (without explicit configuration) by
92 # opening a window which is bigger than the testsuite screen (1280x1024).
93
94 $config = <<EOT;
95 # i3 config file (v4)
96 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
97 EOT
98
99 $pid = launch_with_config($config);
100
101 $window = open_floating_window(rect => [ 0, 0, 2048, 2048 ]);
102 $rect = $window->rect;
103
104 cmp_ok($rect->{width}, '<', 2048, 'width < 2048');
105 cmp_ok($rect->{height}, '<', 2048, 'height < 2048');
106
107 exit_gracefully($pid);
108
109 ################################################################################
110 # 4: check floating_maximum_size
111 ################################################################################
112
113 $config = <<EOT;
114 # i3 config file (v4)
115 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
116
117 # Test with different dimensions than the i3 default.
118 floating_maximum_size -1 x -1
119 EOT
120
121 $pid = launch_with_config($config);
122
123 $window = open_floating_window(rect => [ 0, 0, 2048, 2048 ]);
124 $rect = $window->rect;
125
126 is($rect->{width}, 2048, 'width = 2048');
127 is($rect->{height}, 2048, 'height = 2048');
128
129 exit_gracefully($pid);
130
131 ################################################################################
132 # 5: check floating_minimum_size with cmd_resize
133 ################################################################################
134
135 $config = <<EOT;
136 # i3 config file (v4)
137 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
138
139 # Test with different dimensions than the i3 default.
140 floating_minimum_size 60 x 50
141 EOT
142
143 $pid = launch_with_config($config);
144
145 $window = open_floating_window(rect => [ 0, 0, 100, 100 ]);
146 cmd 'border none';
147 cmd 'resize shrink height 80px or 80ppt';
148 cmd 'resize shrink width 80px or 80ppt';
149 sync_with_i3;
150 $rect = $window->rect;
151 is($rect->{width}, 60, 'width = 60');
152 is($rect->{height}, 50, 'height = 50');
153
154 exit_gracefully($pid);
155
156 ################################################################################
157 # 6: check floating_maximum_size with cmd_resize
158 ################################################################################
159
160 $config = <<EOT;
161 # i3 config file (v4)
162 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
163
164 # Test with different dimensions than the i3 default.
165 floating_maximum_size 100 x 100
166 EOT
167
168 $pid = launch_with_config($config);
169
170 $window = open_floating_window(rect => [ 200, 200, 50, 50 ]);
171 cmd 'border none';
172 cmd 'resize grow height 100px or 100ppt';
173 cmd 'resize grow width 100px or 100ppt';
174 sync_with_i3;
175 $rect = $window->rect;
176 is($rect->{width}, 100, 'width = 100');
177 is($rect->{height}, 100, 'height = 100');
178
179 my $old_x = $rect->{x};
180 my $old_y = $rect->{y};
181 cmd 'resize grow up 10px or 10ppt';
182 sync_with_i3;
183 $rect = $window->rect;
184 is($rect->{x}, $old_x, 'window did not move when trying to resize');
185 is($rect->{y}, $old_y, 'window did not move when trying to resize');
186
187 exit_gracefully($pid);
188
189 ################################################################################
190 # 7: check floating_maximum_size with cmd_size
191 ################################################################################
192
193 $config = <<EOT;
194 # i3 config file (v4)
195 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
196
197 # Test with different dimensions than the i3 default.
198 floating_minimum_size 80 x 70
199 floating_maximum_size 100 x 90
200 EOT
201
202 $pid = launch_with_config($config);
203
204 $window = open_floating_window(rect => [ 0, 0, 90, 80 ]);
205 cmd 'border none';
206
207 cmd 'resize set 101 91';
208 sync_with_i3;
209 $rect = $window->rect;
210 is($rect->{width}, 100, 'width did not exceed maximum width');
211 is($rect->{height}, 90, 'height did not exceed maximum height');
212
213 cmd 'resize set 79 69';
214 sync_with_i3;
215 $rect = $window->rect;
216 is($rect->{width}, 80, 'width did not exceed minimum width');
217 is($rect->{height}, 70, 'height did not exceed minimum height');
218
219 exit_gracefully($pid);
220
221 ################################################################################
222 # 8: check minimum_size and maximum_size set by WM_NORMAL_HINTS
223 ################################################################################
224
225 $config = <<EOT;
226 # i3 config file (v4)
227 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
228 EOT
229
230 my $min_width = 150;
231 my $min_height = 100;
232 my $max_width = 250;
233 my $max_height = 200;
234
235 my sub open_with_max_size {
236 # The type of the WM_NORMAL_HINTS property is WM_SIZE_HINTS
237 # https://tronche.com/gui/x/icccm/sec-4.html#s-4.1.2.3
238 my $XCB_ICCCM_SIZE_HINT_P_MIN_SIZE = 0x32;
239 my $XCB_ICCCM_SIZE_HINT_P_MAX_SIZE = 0x16;
240
241 my $flags = $XCB_ICCCM_SIZE_HINT_P_MIN_SIZE | $XCB_ICCCM_SIZE_HINT_P_MAX_SIZE;
242
243 my $pad = 0x00;
244
245 my $window = open_window(
246 before_map => sub {
247 my ($window) = @_;
248
249 my $atomname = $x->atom(name => 'WM_NORMAL_HINTS');
250 my $atomtype = $x->atom(name => 'WM_SIZE_HINTS');
251 $x->change_property(
252 PROP_MODE_REPLACE,
253 $window->id,
254 $atomname->id,
255 $atomtype->id,
256 32,
257 13,
258 pack('C5N8', $flags, $pad, $pad, $pad, $pad, 0, 0, 0, $min_width, $min_height, $max_width, $max_height),
259 );
260 },
261 );
262
263 return $window;
264 }
265
266 my sub check_minsize {
267 sync_with_i3;
268 is($window->rect->{width}, $min_width, 'width = min_width');
269 is($window->rect->{height}, $min_height, 'height = min_height');
270 }
271
272 my sub check_maxsize {
273 sync_with_i3;
274 is($window->rect->{width}, $max_width, 'width = max_width');
275 is($window->rect->{height}, $max_height, 'height = max_height');
276 }
277
278 $pid = launch_with_config($config);
279
280 $window = open_with_max_size;
281 cmd 'floating enable';
282 cmd 'border none';
283
284 cmd "resize set $min_width px $min_height px";
285 check_minsize;
286
287 # Try to resize below minimum width
288 cmd 'resize set ' . ($min_width - 10) . ' px ' . ($min_height - 50) . ' px';
289 check_minsize;
290
291 cmd "resize set $max_width px $max_height px";
292 check_maxsize;
293
294 # Try to resize above maximum width
295 cmd 'resize set ' . ($max_width + 150) . ' px ' . ($max_height + 500) . ' px';
296 check_maxsize;
297
298 exit_gracefully($pid);
299
300 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test for ticket #676: 'scratchpad show' causes a segfault if the scratchpad
17 # window is shown on another workspace.
18 #
19 use i3test;
20
21 my $i3 = i3(get_socket_path());
22 my $tmp = fresh_workspace;
23
24 my $win = open_window;
25
26 my $scratch = open_window(wm_class => 'special');
27 cmd '[class="special"] move scratchpad';
28
29 is_num_children($tmp, 1, 'one window on current ws');
30
31 my $otmp = fresh_workspace;
32 cmd 'scratchpad show';
33
34 cmd "workspace $tmp";
35 cmd '[class="special"] scratchpad show';
36
37 does_i3_live;
38
39 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that you can resize across different levels of containers even when
17 # they are all of the same orientation.
18 # (Ticket #754)
19 use i3test;
20
21 my $tmp = fresh_workspace;
22
23 open_window;
24 open_window;
25 cmd 'split v';
26 my $middle = open_window;
27 open_window;
28 cmd 'focus parent';
29 cmd 'split h';
30 open_window;
31
32 cmd '[id="' . $middle->id . '"] focus';
33 is($x->input_focus, $middle->id, 'middle window focused');
34
35 cmd 'resize grow left 10px or 25ppt';
36
37 my ($nodes, $focus) = get_ws_content($tmp);
38
39 cmp_float($nodes->[0]->{percent}, 0.25, 'left container got only 25%');
40 cmp_float($nodes->[1]->{percent}, 0.75, 'right container got 75%');
41
42 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that switching between the different layouts works as expected.
17 use i3test;
18
19 my $tmp = fresh_workspace;
20
21 open_window;
22 open_window;
23 cmd 'split v';
24 open_window;
25
26 my ($nodes, $focus) = get_ws_content($tmp);
27 is($nodes->[1]->{layout}, 'splitv', 'layout is splitv currently');
28
29 cmd 'layout stacked';
30 ($nodes, $focus) = get_ws_content($tmp);
31 is($nodes->[1]->{layout}, 'stacked', 'layout now stacked');
32
33 cmd 'layout tabbed';
34 ($nodes, $focus) = get_ws_content($tmp);
35 is($nodes->[1]->{layout}, 'tabbed', 'layout now tabbed');
36
37 cmd 'layout toggle split';
38 ($nodes, $focus) = get_ws_content($tmp);
39 is($nodes->[1]->{layout}, 'splitv', 'layout now splitv again');
40
41 cmd 'layout toggle split';
42 ($nodes, $focus) = get_ws_content($tmp);
43 is($nodes->[1]->{layout}, 'splith', 'layout now splith');
44
45 cmd 'layout toggle split';
46 ($nodes, $focus) = get_ws_content($tmp);
47 is($nodes->[1]->{layout}, 'splitv', 'layout now splitv');
48
49 cmd 'layout toggle split';
50 ($nodes, $focus) = get_ws_content($tmp);
51 is($nodes->[1]->{layout}, 'splith', 'layout now splith');
52
53 cmd 'layout toggle';
54 ($nodes, $focus) = get_ws_content($tmp);
55 is($nodes->[1]->{layout}, 'stacked', 'layout now stacked');
56
57 cmd 'layout toggle';
58 ($nodes, $focus) = get_ws_content($tmp);
59 is($nodes->[1]->{layout}, 'tabbed', 'layout now tabbed');
60
61 cmd 'layout toggle';
62 ($nodes, $focus) = get_ws_content($tmp);
63 is($nodes->[1]->{layout}, 'splith', 'layout now splith');
64
65 cmd 'layout toggle';
66 ($nodes, $focus) = get_ws_content($tmp);
67 is($nodes->[1]->{layout}, 'stacked', 'layout now stacked');
68
69 cmd 'layout toggle all';
70 ($nodes, $focus) = get_ws_content($tmp);
71 is($nodes->[1]->{layout}, 'tabbed', 'layout now tabbed');
72
73 cmd 'layout toggle all';
74 ($nodes, $focus) = get_ws_content($tmp);
75 is($nodes->[1]->{layout}, 'splith', 'layout now splith');
76
77 cmd 'layout toggle all';
78 ($nodes, $focus) = get_ws_content($tmp);
79 is($nodes->[1]->{layout}, 'splitv', 'layout now splitv');
80
81 cmd 'layout toggle all';
82 ($nodes, $focus) = get_ws_content($tmp);
83 is($nodes->[1]->{layout}, 'stacked', 'layout now stacked');
84
85 cmd 'layout toggle all';
86 ($nodes, $focus) = get_ws_content($tmp);
87 is($nodes->[1]->{layout}, 'tabbed', 'layout now tabbed');
88
89 cmd 'layout toggle all';
90 ($nodes, $focus) = get_ws_content($tmp);
91 is($nodes->[1]->{layout}, 'splith', 'layout now splith');
92
93 cmd 'layout toggle all';
94 ($nodes, $focus) = get_ws_content($tmp);
95 is($nodes->[1]->{layout}, 'splitv', 'layout now splitv');
96
97 cmd 'layout toggle splith splitv';
98 ($nodes, $focus) = get_ws_content($tmp);
99 is($nodes->[1]->{layout}, 'splith', 'layout now splith');
100
101 cmd 'layout toggle splith splitv';
102 ($nodes, $focus) = get_ws_content($tmp);
103 is($nodes->[1]->{layout}, 'splitv', 'layout now splitv');
104
105 cmd 'layout toggle stacked splitv tabbed';
106 ($nodes, $focus) = get_ws_content($tmp);
107 is($nodes->[1]->{layout}, 'tabbed', 'layout now tabbed');
108
109 cmd 'layout toggle stacking splitv tabbed';
110 ($nodes, $focus) = get_ws_content($tmp);
111 is($nodes->[1]->{layout}, 'stacked', 'layout now stacked');
112
113 cmd 'layout toggle stacking splitv tabbed';
114 ($nodes, $focus) = get_ws_content($tmp);
115 is($nodes->[1]->{layout}, 'splitv', 'layout now splitv');
116
117 cmd 'layout toggle splitv i stacking tabbed';
118 ($nodes, $focus) = get_ws_content($tmp);
119 is($nodes->[1]->{layout}, 'stacked', 'layout now stacked');
120
121 cmd 'layout toggle stacked';
122 ($nodes, $focus) = get_ws_content($tmp);
123 # this is correct if it does nothing
124 is($nodes->[1]->{layout}, 'stacked', 'layout now stacked');
125
126 cmd 'layout toggle tabbed stacked';
127 ($nodes, $focus) = get_ws_content($tmp);
128 is($nodes->[1]->{layout}, 'tabbed', 'layout now tabbed');
129
130 # obsoletes 'split' ;)
131 cmd 'layout toggle splith splitv';
132 ($nodes, $focus) = get_ws_content($tmp);
133 is($nodes->[1]->{layout}, 'splith', 'layout now splith');
134
135 # nonsense but works expectedly
136 cmd 'layout toggle split split';
137 ($nodes, $focus) = get_ws_content($tmp);
138 is($nodes->[1]->{layout}, 'splitv', 'layout now splitv');
139
140 cmd 'layout toggle split split';
141 ($nodes, $focus) = get_ws_content($tmp);
142 is($nodes->[1]->{layout}, 'splith', 'layout now splith');
143
144 # testing with arbitrary length and garbage
145 cmd 'layout toggle stacking splith tabbed splitv stacking';
146 ($nodes, $focus) = get_ws_content($tmp);
147 is($nodes->[1]->{layout}, 'tabbed', 'layout now tabbed');
148
149 cmd 'layout toggle stacking splith garbage tabbed splitv stacking';
150 ($nodes, $focus) = get_ws_content($tmp);
151 is($nodes->[1]->{layout}, 'splitv', 'layout now splitv');
152
153 cmd 'layout toggle stacking splith garbage tabbed splitv stacking';
154 ($nodes, $focus) = get_ws_content($tmp);
155 is($nodes->[1]->{layout}, 'stacked', 'layout now stacked');
156
157 cmd 'layout toggle splitv splith garbage splitv tabbed stacking splitv';
158 ($nodes, $focus) = get_ws_content($tmp);
159 is($nodes->[1]->{layout}, 'splitv', 'layout now splitv');
160
161 cmd 'layout toggle splitv garbage tabbed';
162 ($nodes, $focus) = get_ws_content($tmp);
163 is($nodes->[1]->{layout}, 'tabbed', 'layout now tabbed');
164
165 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that we can get the version number of i3 via IPC.
17 use i3test;
18
19 my $i3 = i3(get_socket_path());
20 $i3->connect->recv;
21 # We explicitly send the version message because AnyEvent::I3’s 'version' sugar
22 # method has a fallback which tries to parse the version number from i3
23 # --version for older versions, and we want to avoid using that.
24 my $version = $i3->message(7, "")->recv;
25
26 # We need to change this when the major version changes (but we need to touch a
27 # lot of changes then anyways).
28 is($version->{major}, 4, 'major version is 4');
29
30 cmp_ok($version->{minor}, '>', 0, 'minor version > 0');
31
32 is(int($version->{minor}), $version->{minor}, 'minor version is an integer');
33 is(int($version->{patch}), $version->{patch}, 'patch version is an integer');
34 like($version->{human_readable}, qr/branch/, 'human readable version contains branch name');
35
36 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that the size requested by floating windows is set by i3, no matter
17 # to which value the new_window option is set.
18 # ticket #770, bug still present in commit ae88accf6fe3817ff42d0d51be1965071194766e
19 use i3test i3_autostart => 0;
20
21 sub test_with_config {
22 my ($value) = @_;
23
24 my $config = <<EOT;
25 # i3 config file (v4)
26 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
27 EOT
28
29 if (defined($value)) {
30 $config .= "$value\n";
31 diag("testing with $value");
32 } else {
33 diag("testing without new_window");
34 }
35
36 my $pid = launch_with_config($config);
37
38 my $tmp = fresh_workspace;
39
40 my $window = open_floating_window({ rect => [ 0, 0, 400, 150 ] });
41
42 my ($absolute, $top) = $window->rect;
43
44 ok($window->mapped, 'Window is mapped');
45 cmp_ok($absolute->{width}, '==', 400, 'requested width kept');
46 cmp_ok($absolute->{height}, '==', 150, 'requested height kept');
47
48 exit_gracefully($pid);
49 }
50
51 test_with_config(undef);
52 test_with_config('new_window 1pixel');
53 test_with_config('new_window normal');
54 test_with_config('new_window none');
55 test_with_config('hide_edge_borders both');
56
57 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that the _NET_ACTIVE_WINDOW message only changes focus when the
17 # window is on a visible workspace and that focus changes properly update this
18 # property on the root window.
19 # ticket #774, bug still present in commit 1e49f1b08a3035c1f238fcd6615e332216ab582e
20 # ticket #1136, bug still present in commit fd07f989fdf441ef335245dd3436a70ff60e8896
21 use i3test;
22
23 sub send_net_active_window {
24 my ($id, $source) = @_;
25
26 $source = (((defined $source) && ($source eq 'pager')) ? 2 : 0);
27
28 my $msg = pack "CCSLLLLLLL",
29 X11::XCB::CLIENT_MESSAGE, # response_type
30 32, # format
31 0, # sequence
32 $id, # destination window
33 $x->atom(name => '_NET_ACTIVE_WINDOW')->id,
34 $source,
35 0,
36 0,
37 0,
38 0;
39
40 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
41 sync_with_i3;
42 }
43
44 sub get_net_active_window {
45 my $cookie = $x->get_property(
46 0,
47 $x->get_root_window(),
48 $x->atom(name => '_NET_ACTIVE_WINDOW')->id,
49 $x->atom(name => 'WINDOW')->id,
50 0,
51 4096,
52 );
53 my $reply = $x->get_property_reply($cookie->{sequence});
54 my $len = $reply->{length};
55
56 return -1 if $len == 0;
57 return unpack("L", $reply->{value});
58
59 }
60
61 my $ws1 = fresh_workspace;
62 my $win1 = open_window;
63 my $win2 = open_window;
64
65 ################################################################################
66 # Ensure that the _NET_ACTIVE_WINDOW ClientMessage works when windows are visible
67 ################################################################################
68
69 is($x->input_focus, $win2->id, 'window 2 has focus');
70
71 send_net_active_window($win1->id);
72
73 is($x->input_focus, $win1->id, 'window 1 has focus');
74
75 ################################################################################
76 # Switch to a different workspace and ensure sending the _NET_ACTIVE_WINDOW
77 # ClientMessage switches to that workspaces only if source indicates it is a
78 # pager and otherwise sets the urgent hint.
79 ################################################################################
80
81 my $ws2 = fresh_workspace;
82 my $win3 = open_window;
83
84 is($x->input_focus, $win3->id, 'window 3 has focus');
85
86 send_net_active_window($win1->id, 'pager');
87
88 is($x->input_focus, $win1->id, 'focus switched to window 1 when message source was a pager');
89
90 cmd '[id="' . $win3->id . '"] focus';
91
92 send_net_active_window($win1->id);
93
94 is($x->input_focus, $win3->id,
95 'focus did not switch to window 1 on a hidden workspace when message source was an application');
96
97 ok(get_ws($ws1)->{urgent}, 'urgent hint set on ws 1');
98
99
100 ################################################################################
101 # Make sure the ClientMessage only works with managed windows, and specifying a
102 # window that is not managed does not crash i3 (#774)
103 ################################################################################
104
105 my $dock = open_window(window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'));
106
107 send_net_active_window($dock->id);
108
109 does_i3_live;
110 is($x->input_focus, $win3->id, 'dock did not get input focus');
111
112 send_net_active_window($x->get_root_window());
113
114 does_i3_live;
115 is($x->input_focus, $win3->id, 'root window did not get input focus');
116
117 ################################################################################
118 # Move a window to the scratchpad, send a _NET_ACTIVE_WINDOW for it and verify
119 # that focus is still unchanged.
120 ################################################################################
121
122 my $scratch = open_window;
123
124 is($x->input_focus, $scratch->id, 'to-scratchpad window has focus');
125
126 cmd 'move scratchpad';
127
128 is($x->input_focus, $win3->id, 'focus reverted to window 3');
129
130 send_net_active_window($scratch->id);
131
132 is($x->input_focus, $win3->id, 'window 3 still focused');
133
134 ################################################################################
135 # A scratchpad window should be shown if _NET_ACTIVE_WINDOW from a pager
136 # is received.
137 ################################################################################
138
139 $scratch = open_window;
140
141 is($x->input_focus, $scratch->id, 'to-scratchpad window has focus');
142
143 cmd 'move scratchpad';
144
145 is($x->input_focus, $win3->id, 'focus reverted to window 3');
146
147 send_net_active_window($scratch->id, 'pager');
148
149 is($x->input_focus, $scratch->id, 'scratchpad window is shown');
150
151 ################################################################################
152 # Send a _NET_ACTIVE_WINDOW ClientMessage for a window behind a fullscreen
153 # window
154 ################################################################################
155
156 $ws1 = fresh_workspace;
157 $win1 = open_window;
158 $win2 = open_window;
159 cmd 'fullscreen enable';
160 is_num_fullscreen($ws1, 1, '1 fullscreen window in workspace');
161
162 send_net_active_window($win1->id);
163
164 is($x->input_focus, $win1->id, 'window behind fullscreen window is now focused');
165 is_num_fullscreen($ws1, 0, 'no fullscreen windows in workspace');
166
167 ################################################################################
168 # Verify that the _NET_ACTIVE_WINDOW property is updated on the root window
169 # correctly.
170 ################################################################################
171
172 fresh_workspace;
173
174 sync_with_i3;
175
176 is(get_net_active_window(), 0, 'workspace content focus is indicated by the root property as "None" window');
177
178 my $win4 = open_window;
179
180 cmd '[id="' . $win4->id . '"] focus';
181
182 sync_with_i3;
183
184 is(get_net_active_window(), $win4->id, 'window 4 is indicated as focused by the root property');
185
186 # make a branch
187 open_window;
188 open_window;
189 cmd 'split h';
190 open_window;
191 cmd 'focus parent';
192
193 sync_with_i3;
194
195 is(get_net_active_window(), 0, 'branch focus is indicated by the root property as "None" window');
196
197 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verify that i3 allows strange RandR output names such as DVI-I_1/digital.
17 # Ticket: #785
18 # Bug still in: 4.2-256-ga007283
19 use i3test i3_autostart => 0;
20 use File::Temp qw(tempfile);
21
22 my ($fh, $filename) = tempfile(UNLINK => 1);
23 print $fh <<EOT;
24 # i3 config file (v4)
25 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
26
27 workspace 2 output DVI-I_1/digital
28 EOT
29
30 my $output = qx(i3 -C -c $filename);
31 unlike($output, qr/ERROR/, 'no errors in i3 -C');
32
33 close($fh);
34
35 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test: moving a window to the right out of a splitv container would
17 # make it vanish.
18 # Ticket: #790
19 # Bug still in: 4.2-277-ga598544
20 use i3test;
21
22 my $ws = fresh_workspace;
23
24 my $top = open_window;
25 cmd 'split v';
26 my $bottom = open_window;
27
28 is_num_children($ws, 2, 'two windows on workspace level');
29
30 cmd 'move right';
31
32 is_num_children($ws, 2, 'still two windows on workspace level');
33
34 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # When using a command which moves a window to scratchpad from an invisible
17 # (e.g. unfocused) workspace and immediately shows that window again, i3
18 # crashed.
19 # Bug still in: 4.2-305-g22922a9
20 use i3test;
21
22 my $ws1 = fresh_workspace;
23 my $invisible_window = open_window;
24 my $other_focusable_window = open_window;
25
26 my $ws2 = fresh_workspace;
27 my $id = $invisible_window->id;
28 cmd qq|[id="$id"] move scratchpad, scratchpad show|;
29
30 does_i3_live;
31
32 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that the IPC 'mode' event is sent when modes are changed.
17 use i3test i3_config => <<EOT;
18 # i3 config file (v4)
19 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
20
21 mode "m1" {
22 bindsym Mod1+x nop foo
23 }
24
25 mode "with spaces" {
26 bindsym Mod1+y nop bar
27 }
28 EOT
29
30 my @events = events_for(
31 sub { cmd 'mode "m1"' },
32 'mode');
33
34 my @changes = map { $_->{change} } @events;
35 is_deeply(\@changes, [ 'm1' ], 'Mode event received');
36
37 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 #
17 # Tests whether the urgency timer works as expected and does not break
18 # urgency handling.
19 #
20
21 use List::Util qw(first);
22 use i3test i3_config => <<EOT;
23 # i3 config file (v4)
24 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
25
26 force_display_urgency_hint 500ms
27 EOT
28 use Time::HiRes qw(sleep);
29
30 #####################################################################
31 # Initial setup: one window on ws1, empty ws2
32 #####################################################################
33
34 my $tmp1 = fresh_workspace;
35 my $w = open_window;
36
37 my $tmp2 = fresh_workspace;
38 cmd "workspace $tmp2";
39
40 $w->add_hint('urgency');
41 sync_with_i3;
42
43 #######################################################################
44 # Create a window on ws1, then switch to ws2, set urgency, switch back
45 #######################################################################
46
47 isnt($x->input_focus, $w->id, 'window not focused');
48
49 my @content = @{get_ws_content($tmp1)};
50 my @urgent = grep { $_->{urgent} } @content;
51 is(@urgent, 1, "window marked as urgent");
52
53 # switch to ws1
54 cmd "workspace $tmp1";
55
56 # this will start the timer
57 sleep(0.1);
58 @content = @{get_ws_content($tmp1)};
59 @urgent = grep { $_->{urgent} } @content;
60 is(@urgent, 1, 'window still marked as urgent');
61
62 # now check if the timer was triggered
63 cmd "workspace $tmp2";
64
65 sleep(0.5);
66 @content = @{get_ws_content($tmp1)};
67 @urgent = grep { $_->{urgent} } @content;
68 is(@urgent, 0, 'window not marked as urgent anymore');
69
70 #######################################################################
71 # Create another window on ws1, focus it, switch to ws2, make the other
72 # window urgent, and switch back. This should not trigger the timer.
73 #######################################################################
74
75 cmd "workspace $tmp1";
76 my $w2 = open_window;
77 is($x->input_focus, $w2->id, 'window 2 focused');
78
79 cmd "workspace $tmp2";
80 $w->delete_hint('urgency');
81 $w->add_hint('urgency');
82 sync_with_i3;
83
84 @content = @{get_ws_content($tmp1)};
85 @urgent = grep { $_->{urgent} } @content;
86 is(@urgent, 1, 'window 1 marked as urgent');
87
88 # Switch back to ws1. This should focus w2.
89 cmd "workspace $tmp1";
90 is($x->input_focus, $w2->id, 'window 2 focused');
91
92 @content = @{get_ws_content($tmp1)};
93 @urgent = grep { $_->{urgent} } @content;
94 is(@urgent, 1, 'window 1 still marked as urgent');
95
96 # explicitly focusing the window should result in immediate urgency reset
97 cmd '[id="' . $w->id . '"] focus';
98 @content = @{get_ws_content($tmp1)};
99 @urgent = grep { $_->{urgent} } @content;
100 is(@urgent, 0, 'window 1 not marked as urgent anymore');
101
102 ################################################################################
103 # open a stack, mark one window as urgent, switch to that workspace and verify
104 # it’s cleared correctly.
105 ################################################################################
106
107 sub count_total_urgent {
108 my ($con) = @_;
109
110 my $urgent = ($con->{urgent} ? 1 : 0);
111 $urgent += count_total_urgent($_) for (@{$con->{nodes}}, @{$con->{floating_nodes}});
112 return $urgent;
113 }
114
115 my $tmp3 = fresh_workspace;
116 open_window;
117 open_window;
118 cmd 'split v';
119 my $split_left = open_window;
120 cmd 'layout stacked';
121
122 cmd "workspace $tmp2";
123
124 is(count_total_urgent(get_ws($tmp3)), 0, "no urgent windows on workspace $tmp3");
125
126 $split_left->add_hint('urgency');
127 sync_with_i3;
128
129 cmp_ok(count_total_urgent(get_ws($tmp3)), '>=', 0, "more than one urgent window on workspace $tmp3");
130
131 cmd "workspace $tmp3";
132
133 # Remove the urgency hint.
134 $split_left->delete_hint('urgency');
135 sync_with_i3;
136
137 sleep(0.6);
138 is(count_total_urgent(get_ws($tmp3)), 0, "no more urgent windows on workspace $tmp3");
139
140 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests the standalone parser binary to see if it calls the right code when
17 # confronted with various commands, if it prints proper error messages for
18 # wrong commands and if it terminates in every case.
19 #
20 use i3test i3_autostart => 0;
21 use IPC::Run qw(run);
22
23 sub parser_calls {
24 my ($command) = @_;
25
26 my $stdout;
27 run [ 'test.config_parser', $command ],
28 '>/dev/null',
29 '2>', \$stdout;
30 # TODO: use a timeout, so that we can error out if it doesn’t terminate
31
32 # Filter out all debugging output.
33 my @lines = split("\n", $stdout);
34 @lines = grep { not /^# / } @lines;
35
36 # The criteria management calls are irrelevant and not what we want to test
37 # in the first place.
38 @lines = grep { !(/cfg_criteria_init/ || /cfg_criteria_pop_state/) } @lines;
39 return join("\n", @lines) . "\n";
40 }
41
42 my $config = <<'EOT';
43 mode "meh" {
44 bindsym Mod1 + Shift + x resize grow
45 bindcode Mod1+44 resize shrink
46 bindsym --release Mod1+x exec foo
47 bindsym --whole-window button3 nop
48 bindsym --release --whole-window button3 nop
49 bindsym --border button3 nop
50 bindsym --release --border button3 nop
51 bindsym --exclude-titlebar button3 nop
52 bindsym --whole-window --border --exclude-titlebar button3 nop
53 }
54 EOT
55
56 my $expected = <<'EOT';
57 cfg_enter_mode((null), meh)
58 cfg_mode_binding(bindsym, Mod1,Shift, x, (null), (null), (null), (null), resize grow)
59 cfg_mode_binding(bindcode, Mod1, 44, (null), (null), (null), (null), resize shrink)
60 cfg_mode_binding(bindsym, Mod1, x, --release, (null), (null), (null), exec foo)
61 cfg_mode_binding(bindsym, (null), button3, (null), (null), --whole-window, (null), nop)
62 cfg_mode_binding(bindsym, (null), button3, --release, (null), --whole-window, (null), nop)
63 cfg_mode_binding(bindsym, (null), button3, (null), --border, (null), (null), nop)
64 cfg_mode_binding(bindsym, (null), button3, --release, --border, (null), (null), nop)
65 cfg_mode_binding(bindsym, (null), button3, (null), (null), (null), --exclude-titlebar, nop)
66 cfg_mode_binding(bindsym, (null), button3, (null), --border, --whole-window, --exclude-titlebar, nop)
67 EOT
68
69 is(parser_calls($config),
70 $expected,
71 'mode bindings ok');
72
73 ################################################################################
74 # exec and exec_always
75 ################################################################################
76
77 $config = <<'EOT';
78 exec geeqie
79 exec --no-startup-id /tmp/foo.sh
80 exec_always firefox
81 exec_always --no-startup-id /tmp/bar.sh
82 EOT
83
84 $expected = <<'EOT';
85 cfg_exec(exec, (null), geeqie)
86 cfg_exec(exec, --no-startup-id, /tmp/foo.sh)
87 cfg_exec(exec_always, (null), firefox)
88 cfg_exec(exec_always, --no-startup-id, /tmp/bar.sh)
89 EOT
90
91 is(parser_calls($config),
92 $expected,
93 'exec okay');
94
95 ################################################################################
96 # for_window
97 ################################################################################
98
99 $config = <<'EOT';
100 for_window [] nop empty
101 for_window [class="^Chrome"] floating enable
102 for_window [class=^Chrome] floating enable
103 for_window [floating_from = "auto" class= ==Class== ] nop floating
104 for_window [tiling_from=auto class="==Class=="]nop floating
105 EOT
106
107 $expected = <<'EOT';
108 cfg_for_window(nop empty)
109 cfg_criteria_add(class, ^Chrome)
110 cfg_for_window(floating enable)
111 cfg_criteria_add(class, ^Chrome)
112 cfg_for_window(floating enable)
113 cfg_criteria_add(floating_from, auto)
114 cfg_criteria_add(class, ==Class==)
115 cfg_for_window(nop floating)
116 cfg_criteria_add(tiling_from, auto)
117 cfg_criteria_add(class, ==Class==)
118 cfg_for_window(nop floating)
119 EOT
120
121 is(parser_calls($config),
122 $expected,
123 'for_window okay');
124
125 $config = <<'EOT';
126 for_window [tiling_from=typo] nop typo
127 for_window [tiling_from="typo"] nop typo
128 EOT
129
130 $expected = <<'EOT';
131 ERROR: CONFIG: Expected one of these tokens: '"', 'auto', 'user'
132 ERROR: CONFIG: (in file <stdin>)
133 ERROR: CONFIG: Line 1: for_window [tiling_from=typo] nop typo
134 ERROR: CONFIG: ^^^^^^^^^^^^^^
135 ERROR: CONFIG: Line 2: for_window [tiling_from="typo"] nop typo
136 ERROR: CONFIG: Expected one of these tokens: 'auto', 'user'
137 ERROR: CONFIG: (in file <stdin>)
138 ERROR: CONFIG: Line 1: for_window [tiling_from=typo] nop typo
139 ERROR: CONFIG: Line 2: for_window [tiling_from="typo"] nop typo
140 ERROR: CONFIG: ^^^^^^^^^^^^^^^
141 EOT
142
143 is(parser_calls($config),
144 $expected,
145 'for_window errors okay');
146
147 ################################################################################
148 # assign
149 ################################################################################
150
151 $config = <<'EOT';
152 assign [class="^Chrome"] 4
153 assign [class="^Chrome"] workspace number 3
154 assign [class="^Chrome"] named workspace
155 assign [class="^Chrome"] "quoted named workspace"
156 assign [class="^Chrome"] → "quoted named workspace"
157 EOT
158
159 $expected = <<'EOT';
160 cfg_criteria_add(class, ^Chrome)
161 cfg_assign(4, 0)
162 cfg_criteria_add(class, ^Chrome)
163 cfg_assign(3, 1)
164 cfg_criteria_add(class, ^Chrome)
165 cfg_assign(named workspace, 0)
166 cfg_criteria_add(class, ^Chrome)
167 cfg_assign(quoted named workspace, 0)
168 cfg_criteria_add(class, ^Chrome)
169 cfg_assign(quoted named workspace, 0)
170 EOT
171
172 is(parser_calls($config),
173 $expected,
174 'for_window okay');
175
176 ################################################################################
177 # floating_minimum_size / floating_maximum_size
178 ################################################################################
179
180 $config = <<'EOT';
181 floating_minimum_size 80x55
182 floating_minimum_size 80 x 55
183 floating_maximum_size 73 x 10
184 EOT
185
186 $expected = <<'EOT';
187 cfg_floating_minimum_size(80, 55)
188 cfg_floating_minimum_size(80, 55)
189 cfg_floating_maximum_size(73, 10)
190 EOT
191
192 is(parser_calls($config),
193 $expected,
194 'floating_minimum_size ok');
195
196 ################################################################################
197 # popup_during_fullscreen
198 ################################################################################
199
200 $config = <<'EOT';
201 popup_during_fullscreen ignore
202 popup_during_fullscreen leave_fullscreen
203 popup_during_fullscreen SMArt
204 EOT
205
206 $expected = <<'EOT';
207 cfg_popup_during_fullscreen(ignore)
208 cfg_popup_during_fullscreen(leave_fullscreen)
209 cfg_popup_during_fullscreen(smart)
210 EOT
211
212 is(parser_calls($config),
213 $expected,
214 'popup_during_fullscreen ok');
215
216
217 ################################################################################
218 # floating_modifier
219 ################################################################################
220
221 $config = <<'EOT';
222 floating_modifier Mod1
223 floating_modifier mOd1
224 EOT
225
226 $expected = <<'EOT';
227 cfg_floating_modifier(Mod1)
228 cfg_floating_modifier(Mod1)
229 EOT
230
231 is(parser_calls($config),
232 $expected,
233 'floating_modifier ok');
234
235 ################################################################################
236 # default_orientation
237 ################################################################################
238
239 $config = <<'EOT';
240 default_orientation horizontal
241 default_orientation vertical
242 default_orientation auto
243 EOT
244
245 $expected = <<'EOT';
246 cfg_default_orientation(horizontal)
247 cfg_default_orientation(vertical)
248 cfg_default_orientation(auto)
249 EOT
250
251 is(parser_calls($config),
252 $expected,
253 'default_orientation ok');
254
255 ################################################################################
256 # workspace_layout
257 ################################################################################
258
259 $config = <<'EOT';
260 workspace_layout default
261 workspace_layout stacked
262 workspace_layout stacking
263 workspace_layout tabbed
264 EOT
265
266 $expected = <<'EOT';
267 cfg_workspace_layout(default)
268 cfg_workspace_layout(stacked)
269 cfg_workspace_layout(stacking)
270 cfg_workspace_layout(tabbed)
271 EOT
272
273 is(parser_calls($config),
274 $expected,
275 'workspace_layout ok');
276
277 ################################################################################
278 # workspace assignments, with trailing whitespace (ticket #921)
279 ################################################################################
280
281 $config = <<'EOT';
282 workspace "3" output DP-1
283 workspace "3" output VGA-1
284 EOT
285
286 $expected = <<'EOT';
287 cfg_workspace(3, DP-1)
288 cfg_workspace(3, VGA-1)
289 EOT
290
291 is(parser_calls($config),
292 $expected,
293 'workspace assignment ok');
294
295 ################################################################################
296 # new_window
297 ################################################################################
298
299 $config = <<'EOT';
300 new_window 1pixel
301 new_window normal
302 new_window none
303 default_border 1pixel
304 default_border normal
305 default_border none
306 new_float 1pixel
307 new_float normal
308 new_float none
309 default_floating_border 1pixel
310 default_floating_border normal
311 default_floating_border none
312 EOT
313
314 $expected = <<'EOT';
315 cfg_default_border(new_window, 1pixel, -1)
316 cfg_default_border(new_window, normal, 2)
317 cfg_default_border(new_window, none, -1)
318 cfg_default_border(default_border, 1pixel, -1)
319 cfg_default_border(default_border, normal, 2)
320 cfg_default_border(default_border, none, -1)
321 cfg_default_border(new_float, 1pixel, -1)
322 cfg_default_border(new_float, normal, 2)
323 cfg_default_border(new_float, none, -1)
324 cfg_default_border(default_floating_border, 1pixel, -1)
325 cfg_default_border(default_floating_border, normal, 2)
326 cfg_default_border(default_floating_border, none, -1)
327 EOT
328
329 # TODO: are there no tests for "border pixel 1" etc?
330
331 is(parser_calls($config),
332 $expected,
333 'new_window ok');
334
335 ################################################################################
336 # hide_edge_borders
337 ################################################################################
338
339 $config = <<'EOT';
340 hide_edge_borders none
341 hide_edge_borders vertical
342 hide_edge_borders horizontal
343 hide_edge_borders both
344 hide_edge_borders smart
345 EOT
346
347 $expected = <<'EOT';
348 cfg_hide_edge_borders(none)
349 cfg_hide_edge_borders(vertical)
350 cfg_hide_edge_borders(horizontal)
351 cfg_hide_edge_borders(both)
352 cfg_hide_edge_borders(smart)
353 EOT
354
355 is(parser_calls($config),
356 $expected,
357 'hide_edge_borders ok');
358
359 ################################################################################
360 # focus_follows_mouse
361 ################################################################################
362
363 $config = <<'EOT';
364 focus_follows_mouse yes
365 focus_follows_mouse no
366 EOT
367
368 $expected = <<'EOT';
369 cfg_focus_follows_mouse(yes)
370 cfg_focus_follows_mouse(no)
371 EOT
372
373 is(parser_calls($config),
374 $expected,
375 'focus_follows_mouse ok');
376
377 ################################################################################
378 # mouse_warping
379 ################################################################################
380
381 $config = <<'EOT';
382 mouse_warping output
383 mouse_warping none
384 EOT
385
386 $expected = <<'EOT';
387 cfg_mouse_warping(output)
388 cfg_mouse_warping(none)
389 EOT
390
391 is(parser_calls($config),
392 $expected,
393 'mouse_warping ok');
394
395 ################################################################################
396 # force_display_urgency_hint
397 ################################################################################
398
399 is(parser_calls('force_display_urgency_hint 300'),
400 "cfg_force_display_urgency_hint(300)\n",
401 'force_display_urgency_hint ok');
402
403 is(parser_calls('force_display_urgency_hint 500 ms'),
404 "cfg_force_display_urgency_hint(500)\n",
405 'force_display_urgency_hint ok');
406
407 is(parser_calls('force_display_urgency_hint 700ms'),
408 "cfg_force_display_urgency_hint(700)\n",
409 'force_display_urgency_hint ok');
410
411 $config = <<'EOT';
412 force_display_urgency_hint 300
413 force_display_urgency_hint 500 ms
414 force_display_urgency_hint 700ms
415 force_display_urgency_hint 700
416 EOT
417
418 $expected = <<'EOT';
419 cfg_force_display_urgency_hint(300)
420 cfg_force_display_urgency_hint(500)
421 cfg_force_display_urgency_hint(700)
422 cfg_force_display_urgency_hint(700)
423 EOT
424
425 is(parser_calls($config),
426 $expected,
427 'force_display_urgency_hint ok');
428
429 ################################################################################
430 # workspace
431 ################################################################################
432
433 $config = <<'EOT';
434 workspace 3 output VGA-1
435 workspace "4: output" output VGA-2
436 workspace bleh output LVDS1/I_1
437 # See #3646
438 workspace foo output a b c "a b c"
439 EOT
440
441 $expected = <<'EOT';
442 cfg_workspace(3, VGA-1)
443 cfg_workspace(4: output, VGA-2)
444 cfg_workspace(bleh, LVDS1/I_1)
445 cfg_workspace(foo, a)
446 cfg_workspace((null), b)
447 cfg_workspace((null), c)
448 cfg_workspace((null), a b c)
449 EOT
450
451 is(parser_calls($config),
452 $expected,
453 'workspace ok');
454
455 ################################################################################
456 # ipc-socket
457 ################################################################################
458
459 $config = <<'EOT';
460 ipc-socket /tmp/i3.sock
461 ipc_socket ~/.i3/i3.sock
462 EOT
463
464 $expected = <<'EOT';
465 cfg_ipc_socket(/tmp/i3.sock)
466 cfg_ipc_socket(~/.i3/i3.sock)
467 EOT
468
469 is(parser_calls($config),
470 $expected,
471 'ipc-socket ok');
472
473 ################################################################################
474 # colors
475 ################################################################################
476
477 $config = <<'EOT';
478 client.focused #4c7899 #285577 #ffffff #2e9ef4 #b34d4c
479 client.focused_inactive #333333 #5f676a #ffffff #484e50
480 client.unfocused #333333 #222222 #888888 #292d2e
481 client.urgent #2f343a #900000 #ffffff #900000 #c00000
482 client.placeholder #000000 #0c0c0c #ffffff #000000
483 EOT
484
485 $expected = <<'EOT';
486 cfg_color(client.focused, #4c7899, #285577, #ffffff, #2e9ef4, #b34d4c)
487 cfg_color(client.focused_inactive, #333333, #5f676a, #ffffff, #484e50, NULL)
488 cfg_color(client.unfocused, #333333, #222222, #888888, #292d2e, NULL)
489 cfg_color(client.urgent, #2f343a, #900000, #ffffff, #900000, #c00000)
490 cfg_color(client.placeholder, #000000, #0c0c0c, #ffffff, #000000, NULL)
491 EOT
492
493 is(parser_calls($config),
494 $expected,
495 'colors ok');
496
497 ################################################################################
498 # Verify that errors don’t harm subsequent valid statements
499 ################################################################################
500
501 $config = <<'EOT';
502 hide_edge_border both
503 client.focused #4c7899 #285577 #ffffff #2e9ef4
504 EOT
505
506 my $expected_all_tokens = "ERROR: CONFIG: Expected one of these tokens: <end>, '#', '" . join("', '", 'set ', 'set ', qw(
507 set_from_resource
508 bindsym
509 bindcode
510 bind
511 bar
512 font
513 mode
514 gaps
515 smart_borders
516 smart_gaps
517 floating_minimum_size
518 floating_maximum_size
519 floating_modifier
520 default_orientation
521 workspace_layout
522 default_border
523 new_window
524 default_floating_border
525 new_float
526 hide_edge_borders
527 for_window
528 assign
529 no_focus
530 focus_follows_mouse
531 mouse_warping
532 focus_wrapping
533 force_focus_wrapping
534 force_xinerama
535 force-xinerama
536 disable_randr15
537 disable-randr15
538 workspace_auto_back_and_forth
539 fake_outputs
540 fake-outputs
541 force_display_urgency_hint
542 focus_on_window_activation
543 title_align
544 show_marks
545 workspace
546 ipc_socket
547 ipc-socket
548 ipc_kill_timeout
549 restart_state
550 popup_during_fullscreen
551 exec_always
552 exec
553 client.background
554 client.focused_inactive
555 client.focused
556 client.unfocused
557 client.urgent
558 client.placeholder
559 )) . "'\n";
560
561 my $expected_end = <<'EOT';
562 ERROR: CONFIG: (in file <stdin>)
563 ERROR: CONFIG: Line 1: hide_edge_border both
564 ERROR: CONFIG: ^^^^^^^^^^^^^^^^^^^^^
565 ERROR: CONFIG: Line 2: client.focused #4c7899 #285577 #ffffff #2e9ef4
566 cfg_color(client.focused, #4c7899, #285577, #ffffff, #2e9ef4, NULL)
567 EOT
568
569 $expected = $expected_all_tokens . $expected_end;
570
571 is(parser_calls($config),
572 $expected,
573 'errors dont harm subsequent statements');
574
575 $config = <<'EOT';
576 hide_edge_borders FOOBAR
577 client.focused #4c7899 #285577 #ffffff #2e9ef4
578 EOT
579
580 $expected = <<'EOT';
581 ERROR: CONFIG: Expected one of these tokens: 'none', 'vertical', 'horizontal', 'both', 'smart_no_gaps', 'smart', '1', 'yes', 'true', 'on', 'enable', 'active'
582 ERROR: CONFIG: (in file <stdin>)
583 ERROR: CONFIG: Line 1: hide_edge_borders FOOBAR
584 ERROR: CONFIG: ^^^^^^
585 ERROR: CONFIG: Line 2: client.focused #4c7899 #285577 #ffffff #2e9ef4
586 cfg_color(client.focused, #4c7899, #285577, #ffffff, #2e9ef4, NULL)
587 EOT
588
589 is(parser_calls($config),
590 $expected,
591 'errors dont harm subsequent statements');
592
593 ################################################################################
594 # Regression: semicolons end comments, but shouldn’t
595 ################################################################################
596
597 $config = <<'EOT';
598 # "foo" client.focused #4c7899 #285577 #ffffff #2e9ef4
599 EOT
600
601 $expected = <<'EOT';
602
603 EOT
604
605 is(parser_calls($config),
606 $expected,
607 'semicolon does not end a comment line');
608
609 ################################################################################
610 # Error message with 2+2 lines of context
611 ################################################################################
612
613 $config = <<'EOT';
614 # i3 config file (v4)
615
616 font foobar
617
618 unknown qux
619
620 # yay
621 # this should not show up
622 EOT
623
624 my $expected_head = <<'EOT';
625 cfg_font(foobar)
626 EOT
627
628 my $expected_tail = <<'EOT';
629 ERROR: CONFIG: (in file <stdin>)
630 ERROR: CONFIG: Line 3: font foobar
631 ERROR: CONFIG: Line 4:
632 ERROR: CONFIG: Line 5: unknown qux
633 ERROR: CONFIG: ^^^^^^^^^^^
634 ERROR: CONFIG: Line 6:
635 ERROR: CONFIG: Line 7: # yay
636 EOT
637
638 $expected = $expected_head . $expected_all_tokens . $expected_tail;
639
640 is(parser_calls($config),
641 $expected,
642 'error message (2+2 context) ok');
643
644 ################################################################################
645 # Error message with 0+0 lines of context
646 ################################################################################
647
648 $config = <<'EOT';
649 unknown qux
650 EOT
651
652 $expected_tail = <<'EOT';
653 ERROR: CONFIG: (in file <stdin>)
654 ERROR: CONFIG: Line 1: unknown qux
655 ERROR: CONFIG: ^^^^^^^^^^^
656 EOT
657
658 $expected = $expected_all_tokens . $expected_tail;
659
660 is(parser_calls($config),
661 $expected,
662 'error message (0+0 context) ok');
663
664 ################################################################################
665 # Error message with 1+0 lines of context
666 ################################################################################
667
668 $config = <<'EOT';
669 # context before
670 unknown qux
671 EOT
672
673 $expected_tail = <<'EOT';
674 ERROR: CONFIG: (in file <stdin>)
675 ERROR: CONFIG: Line 1: # context before
676 ERROR: CONFIG: Line 2: unknown qux
677 ERROR: CONFIG: ^^^^^^^^^^^
678 EOT
679
680 $expected = $expected_all_tokens . $expected_tail;
681
682 is(parser_calls($config),
683 $expected,
684 'error message (1+0 context) ok');
685
686 ################################################################################
687 # Error message with 0+1 lines of context
688 ################################################################################
689
690 $config = <<'EOT';
691 unknown qux
692 # context after
693 EOT
694
695 $expected_tail = <<'EOT';
696 ERROR: CONFIG: (in file <stdin>)
697 ERROR: CONFIG: Line 1: unknown qux
698 ERROR: CONFIG: ^^^^^^^^^^^
699 ERROR: CONFIG: Line 2: # context after
700 EOT
701
702 $expected = $expected_all_tokens . $expected_tail;
703
704 is(parser_calls($config),
705 $expected,
706 'error message (0+1 context) ok');
707
708 ################################################################################
709 # Error message with 0+2 lines of context
710 ################################################################################
711
712 $config = <<'EOT';
713 unknown qux
714 # context after
715 # context 2 after
716 EOT
717
718 $expected_tail = <<'EOT';
719 ERROR: CONFIG: (in file <stdin>)
720 ERROR: CONFIG: Line 1: unknown qux
721 ERROR: CONFIG: ^^^^^^^^^^^
722 ERROR: CONFIG: Line 2: # context after
723 ERROR: CONFIG: Line 3: # context 2 after
724 EOT
725
726 $expected = $expected_all_tokens . $expected_tail;
727
728 is(parser_calls($config),
729 $expected,
730 'error message (0+2 context) ok');
731
732 ################################################################################
733 # Error message within mode blocks
734 ################################################################################
735
736 $config = <<'EOT';
737 mode "yo" {
738 bindsym x resize shrink left
739 unknown qux
740 }
741 EOT
742
743 $expected = <<'EOT';
744 cfg_enter_mode((null), yo)
745 cfg_mode_binding(bindsym, (null), x, (null), (null), (null), (null), resize shrink left)
746 ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'bindsym', 'bindcode', 'bind', '}'
747 ERROR: CONFIG: (in file <stdin>)
748 ERROR: CONFIG: Line 1: mode "yo" {
749 ERROR: CONFIG: Line 2: bindsym x resize shrink left
750 ERROR: CONFIG: Line 3: unknown qux
751 ERROR: CONFIG: ^^^^^^^^^^^
752 ERROR: CONFIG: Line 4: }
753 EOT
754
755 is(parser_calls($config),
756 $expected,
757 'error message (mode block) ok');
758
759 ################################################################################
760 # Error message within bar blocks
761 ################################################################################
762
763 $config = <<'EOT';
764 bar {
765 output LVDS-1
766 unknown qux
767 }
768 EOT
769
770 $expected = <<'EOT';
771 cfg_bar_start()
772 cfg_bar_output(LVDS-1)
773 ERROR: CONFIG: Expected one of these tokens: <end>, '#', 'set', 'i3bar_command', 'status_command', 'socket_path', 'mode', 'hidden_state', 'id', 'modifier', 'wheel_up_cmd', 'wheel_down_cmd', 'bindsym', 'position', 'output', 'tray_output', 'tray_padding', 'font', 'separator_symbol', 'binding_mode_indicator', 'workspace_buttons', 'workspace_min_width', 'strip_workspace_numbers', 'strip_workspace_name', 'verbose', 'height', 'colors', '}'
774 ERROR: CONFIG: (in file <stdin>)
775 ERROR: CONFIG: Line 1: bar {
776 ERROR: CONFIG: Line 2: output LVDS-1
777 ERROR: CONFIG: Line 3: unknown qux
778 ERROR: CONFIG: ^^^^^^^^^^^
779 ERROR: CONFIG: Line 4: }
780 cfg_bar_finish()
781 EOT
782
783 is(parser_calls($config),
784 $expected,
785 'error message (bar block) ok');
786
787 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that using criteria to address scratchpad windows works.
17 use i3test;
18
19 my $i3 = i3(get_socket_path());
20
21 #####################################################################
22 # Verify that using scratchpad show with criteria works as expected:
23 # - When matching a scratchpad window which is visible,
24 # it should hide it.
25 # - When matching a scratchpad window which is on __i3_scratch,
26 # it should show it.
27 # - When matching a non-scratchpad window, it should be a no-op.
28 # - When matching a scratchpad window,
29 # non-matching windows shouldn't appear
30 ######################################################################
31
32 my $tmp = fresh_workspace;
33
34 my $third_window = open_window(name => 'scratch-match');
35 cmd 'move scratchpad';
36
37 #####################################################################
38 # Verify that using 'scratchpad show' without any matching windows is
39 # a no-op.
40 #####################################################################
41 my $old_focus = get_focused($tmp);
42
43 cmd '[title="nomatch"] scratchpad show';
44
45 is(get_focused($tmp), $old_focus, 'non-matching criteria have no effect');
46
47 #####################################################################
48 # Verify that we can use criteria to show a scratchpad window.
49 #####################################################################
50 cmd '[title="scratch-match"] scratchpad show';
51
52 my $scratch_focus = get_focused($tmp);
53 isnt($scratch_focus, $old_focus, 'matching criteria works');
54
55 # Check that the window was centered and resized too.
56 my $tree = $i3->get_tree->recv;
57 my $ws = get_ws($tmp);
58 my $scratchrect = $ws->{floating_nodes}->[0]->{rect};
59 my $output = $tree->{nodes}->[1];
60 my $outputrect = $output->{rect};
61
62 is($scratchrect->{width}, $outputrect->{width} * 0.5, 'scratch width is 50%');
63 is($scratchrect->{height}, $outputrect->{height} * 0.75, 'scratch height is 75%');
64 is($scratchrect->{x},
65 ($outputrect->{width} / 2) - ($scratchrect->{width} / 2),
66 'scratch window centered horizontally');
67 is($scratchrect->{y},
68 ($outputrect->{height} / 2 ) - ($scratchrect->{height} / 2),
69 'scratch window centered vertically');
70
71 cmd '[title="scratch-match"] scratchpad show';
72
73 isnt(get_focused($tmp), $scratch_focus, 'matching criteria works');
74 is(get_focused($tmp), $old_focus, 'focus restored');
75
76
77 #####################################################################
78 # Verify that we cannot use criteria to show a non-scratchpad window.
79 #####################################################################
80 my $tmp2 = fresh_workspace;
81 my $non_scratch_window = open_window(name => 'non-scratch');
82 cmd "workspace $tmp";
83 is(get_focused($tmp), $old_focus, 'focus still ok');
84 cmd '[title="non-scratch"] scratchpad show';
85 is(get_focused($tmp), $old_focus, 'focus unchanged');
86
87 #####################################################################
88 # Verify that non-matching windows doesn't appear
89 #####################################################################
90 # Subroutine to clear scratchpad
91 sub clear_scratchpad {
92 while (scalar @{get_ws('__i3_scratch')->{floating_nodes}}) {
93 cmd 'scratchpad show';
94 cmd 'kill';
95 }
96 }
97
98 #Start from an empty fresh workspace
99 my $empty_ws = fresh_workspace;
100 cmd "workspace $empty_ws";
101
102 my $no_focused = get_focused($empty_ws);
103 cmd '[title="nothingmatchthistitle"] scratchpad show';
104 #Check nothing match
105 is(get_focused($empty_ws), $no_focused, "no window to focus on");
106
107 clear_scratchpad;
108
109 open_window(name => "my-scratch-window");
110 my $w1_focus = get_focused($empty_ws);
111 cmd 'move scratchpad';
112 cmd '[title="my-scratch-window"] scratchpad show';
113 #Check we created and shown a scratchpad window
114 is(get_focused($empty_ws), $w1_focus, "focus on scratchpad window");
115
116 #Switching workspace
117 my $empty_ws2 = fresh_workspace;
118 cmd "workspace $empty_ws2";
119 open_window(name => "my-second-scratch-window");
120
121 my $w2_focus = get_focused($empty_ws2);
122 cmd 'move scratchpad';
123 cmd '[title="my-second-scratch-window"] scratchpad show';
124
125 #Check we got the correct window
126 is(get_focused($empty_ws2), $w2_focus, "focus is on second window");
127
128 #####################################################################
129 # Verify that 'scratchpad show' correctly hide multiple scratchpad
130 # windows
131 #####################################################################
132 clear_scratchpad;
133
134 sub check_floating {
135 my($rws, $n) = @_;
136 my $ws = get_ws($rws);
137 is(scalar @{$ws->{nodes}}, 0, 'no windows on ws');
138 is(scalar @{$ws->{floating_nodes}}, $n, "$n floating windows on ws");
139 }
140
141 my $empty_ws3 = fresh_workspace;
142 cmd "workspace $empty_ws3";
143
144 check_floating($empty_ws3, 0);
145
146 #Creating two scratchpad windows
147 open_window(name => "toggle-1");
148 cmd 'move scratchpad';
149 open_window(name => "toggle-2");
150 cmd 'move scratchpad';
151 check_floating($empty_ws3, 0);
152 #Showing both
153 cmd '[title="toggle-"] scratchpad show';
154
155 check_floating($empty_ws3, 2);
156
157 #Hiding both
158 cmd '[title="toggle-"] scratchpad show';
159 check_floating($empty_ws3, 0);
160
161 #Showing both again
162 cmd '[title="toggle-"] scratchpad show';
163 check_floating($empty_ws3, 2);
164
165
166 #Hiding one
167 cmd 'scratchpad show';
168 check_floating($empty_ws3, 1);
169
170 #Hiding the last
171 cmd 'scratchpad show';
172 check_floating($empty_ws3, 0);
173
174 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that you can assign a window _and_ use for_window with a move
17 # command.
18 # Ticket: #909
19 # Bug still in: 4.4-69-g6856b23
20 use i3test i3_autostart => 0;
21
22 my $config = <<EOT;
23 # i3 config file (v4)
24 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
25
26 assign [instance=__i3-test-window] 2
27 for_window [instance=__i3-test-window] move workspace 1
28 EOT
29
30 my $pid = launch_with_config($config);
31
32 # We use dont_map because i3 will not map the window on the current
33 # workspace. Thus, open_window would time out in wait_for_map (2 seconds).
34 my $window = open_window(
35 wm_class => '__i3-test-window',
36 dont_map => 1,
37 );
38 $window->map;
39
40 does_i3_live;
41
42 exit_gracefully($pid);
43
44 ################################################################################
45 # Related bug: multiple for_window assignments caused a crash
46 ################################################################################
47
48 $config = <<EOT;
49 # i3 config file (v4)
50 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
51
52 for_window [instance=__i3-test-window1] move workspace 3
53 for_window [instance=__i3-test-window2] move workspace 2
54 EOT
55
56 $pid = launch_with_config($config);
57
58 my $window1 = open_window(
59 wm_class => '__i3-test-window1',
60 dont_map => 1,
61 );
62 $window1->map;
63
64 my $window2 = open_window(
65 wm_class => '__i3-test-window2',
66 dont_map => 1,
67 );
68 $window2->map;
69
70 does_i3_live;
71
72 exit_gracefully($pid);
73
74 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Moves the last window of a workspace to the scratchpad. The workspace will be
17 # cleaned up and previously, the subsequent focusing of a destroyed container
18 # would crash i3.
19 # Ticket: #913
20 # Bug still in: 4.4-97-gf767ac3
21 use i3test;
22
23 my $tmp = fresh_workspace;
24
25 # Open a new window which we can identify later on based on its WM_CLASS.
26 my $scratch = open_window(wm_class => 'special');
27
28 my $tmp2 = fresh_workspace;
29
30 cmd '[class="special"] move scratchpad';
31
32 does_i3_live;
33
34 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17
18 my $new = AnyEvent->condvar;
19 my $focus = AnyEvent->condvar;
20
21 my @events = events_for(
22 sub { open_window },
23 'window');
24
25 is(scalar @events, 2, 'Received 2 events');
26 is($events[0]->{container}->{focused}, 0, 'Window "new" event received');
27 is($events[1]->{container}->{focused}, 1, 'Window "focus" event received');
28
29 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Assure that no window is in fullscreen mode after showing a scratchpad window
17 # Bug still in: 4.5.1-54-g0f6b5fe
18
19 use i3test;
20
21 my $tmp = fresh_workspace;
22
23 ###############################################################################
24 # map two windows in one container, fullscreen one of them and then move it to
25 # scratchpad
26 ###############################################################################
27
28 my $first_win = open_window;
29 my $second_win = open_window;
30
31 # fullscreen the focused window
32 cmd 'fullscreen';
33
34 # see if the window really is in fullscreen mode
35 is_num_fullscreen($tmp, 1, 'amount of fullscreen windows after enabling fullscreen');
36
37 # move window to scratchpad
38 cmd 'move scratchpad';
39
40 ###############################################################################
41 # show the scratchpad window again; it should not be in fullscreen mode anymore
42 ###############################################################################
43
44 # show window from scratchpad
45 cmd 'scratchpad show';
46
47 # switch window back to tiling mode
48 cmd 'floating toggle';
49
50 # see if no window is in fullscreen mode
51 is_num_fullscreen($tmp, 0, 'amount of fullscreen windows after showing previously fullscreened scratchpad window');
52
53 ###############################################################################
54 # move a window to scratchpad, focus parent container, make it fullscreen,
55 # focus a child
56 ###############################################################################
57
58 # make layout tabbed
59 cmd 'layout tabbed';
60
61 # move one window to scratchpad
62 cmd 'move scratchpad';
63
64 # focus parent
65 cmd 'focus parent';
66
67 # fullscreen the container
68 cmd 'fullscreen';
69
70 # focus child
71 cmd 'focus child';
72
73 # see if the window really is in fullscreen mode
74 is_num_fullscreen($tmp, 1, 'amount of fullscreen windows after enabling fullscreen on parent');
75
76 ###############################################################################
77 # show a scratchpad window; no window should be in fullscreen mode anymore
78 ###############################################################################
79
80 # show the scratchpad window
81 cmd 'scratchpad show';
82
83 # see if no window is in fullscreen mode
84 is_num_fullscreen($tmp, 0, 'amount of fullscreen windows after showing a scratchpad window while a parent container was in fullscreen mode');
85
86 ###############################################################################
87 # Moving window to scratchpad with command criteria does not unfullscreen
88 # currently focused container
89 # See https://github.com/i3/i3/issues/2857#issuecomment-496264445
90 ###############################################################################
91
92 kill_all_windows;
93 $tmp = fresh_workspace;
94
95 $first_win = open_window;
96 $second_win = open_window;
97 cmd 'fullscreen';
98 cmd '[id=' . $first_win->id . '] move scratchpad';
99
100 is_num_fullscreen($tmp, 1, 'second window still fullscreen');
101 my $__i3_scratch = get_ws('__i3_scratch');
102 my @scratch_nodes = @{$__i3_scratch->{floating_nodes}};
103 is(scalar @scratch_nodes, 1, 'one window in scratchpad');
104
105 cmd '[id=' . $first_win->id . '] scratchpad show';
106 is_num_fullscreen($tmp, 0, 'second window not fullscreen');
107 $__i3_scratch = get_ws('__i3_scratch');
108 @scratch_nodes = @{$__i3_scratch->{floating_nodes}};
109 is(scalar @scratch_nodes, 0, 'windows in scratchpad');
110
111 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 use i3test;
17 use IPC::Run qw(run);
18 use File::Temp;
19
20 ################################################################################
21 # 1: test that shared memory logging does not work yet
22 ################################################################################
23
24 # NB: launch_with_config (called in i3test) sets --shmlog-size=0 because the
25 # logfile gets redirected via stdout redirection anyways.
26
27 my $stdout;
28 my $stderr;
29 run [ 'i3-dump-log' ],
30 '>', \$stdout,
31 '2>', \$stderr;
32
33 like($stderr, qr#^i3-dump-log: i3 is running, but SHM logging is not enabled\.#,
34 'shm logging not enabled');
35
36 ################################################################################
37 # 2: enable shared memory logging and verify new content shows up
38 ################################################################################
39
40 cmd 'shmlog on';
41
42 my $random_nop = mktemp('nop.XXXXXX');
43 cmd "nop $random_nop";
44
45 run [ 'i3-dump-log' ],
46 '>', \$stdout,
47 '2>', \$stderr;
48
49 like($stdout, qr#$random_nop#, 'random nop found in shm log');
50 like($stderr, qr#^$#, 'stderr empty');
51
52 ################################################################################
53 # 3: change size of the shared memory log buffer and verify old content is gone
54 ################################################################################
55
56 cmd 'shmlog ' . (1 * 1024 * 1024);
57
58 run [ 'i3-dump-log' ],
59 '>', \$stdout,
60 '2>', \$stderr;
61
62 unlike($stdout, qr#$random_nop#, 'random nop not found in shm log');
63 like($stderr, qr#^$#, 'stderr empty');
64
65 ################################################################################
66 # 4: disable logging and verify it no longer works
67 ################################################################################
68
69 cmd 'shmlog off';
70
71 run [ 'i3-dump-log' ],
72 '>', \$stdout,
73 '2>', \$stderr;
74
75 like($stderr, qr#^i3-dump-log: i3 is running, but SHM logging is not enabled\.#,
76 'shm logging not enabled');
77
78 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test for focus handling when using floating enable/disable with
17 # criteria for windows on non-visible workspaces.
18 # Ticket: #1027
19 # Bug still in: 4.5.1-90-g6582da9
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 assign [class="^special$"] → mail
25 for_window [class="^special$"] floating enable, floating disable
26 EOT
27
28 my $window = open_window(
29 name => 'Borderless window',
30 wm_class => 'special',
31 dont_map => 1,
32 );
33 $window->map;
34
35 sync_with_i3;
36
37 cmd '[class="^special$"] focus';
38
39 does_i3_live;
40
41 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies the _NET_WORKAREA hint is deleted in case it is already set on the
17 # root window.
18 # Ticket: #1038
19 # Bug still in: 4.5.1-103-g1f8a860
20 use i3test i3_autostart => 0;
21 use X11::XCB qw(PROP_MODE_REPLACE);
22
23 my $atom_cookie = $x->intern_atom(
24 0, # create!
25 length('_NET_WORKAREA'),
26 '_NET_WORKAREA',
27 );
28
29 my $_net_workarea_id = $x->intern_atom_reply($atom_cookie->{sequence})->{atom};
30
31 $x->change_property(
32 PROP_MODE_REPLACE,
33 $x->get_root_window(),
34 $_net_workarea_id,
35 $x->atom(name => 'CARDINAL')->id,
36 32,
37 4,
38 pack('L4', 0, 0, 1024, 768));
39 $x->flush;
40
41 sub is_net_workarea_set {
42 my $cookie = $x->get_property(
43 0,
44 $x->get_root_window(),
45 $x->atom(name => '_NET_WORKAREA')->id,
46 $x->atom(name => 'CARDINAL')->id,
47 0,
48 4096,
49 );
50 my $reply = $x->get_property_reply($cookie->{sequence});
51 return 0 if $reply->{value_len} == 0;
52 return 0 if $reply->{format} == 0;
53 return 1
54 }
55
56 ok(is_net_workarea_set(), '_NET_WORKAREA is set before starting i3');
57
58 my $config = <<EOT;
59 # i3 config file (v4)
60 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
61 fake-outputs 1024x768+0+0
62 EOT
63
64 my $pid = launch_with_config($config);
65
66 ok(!is_net_workarea_set(), '_NET_WORKAREA not set after starting i3');
67
68 exit_gracefully($pid);
69
70 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # checks if mark and unmark work correctly
17 use i3test;
18 use List::Util qw(first);
19
20 my ($con, $first, $second);
21
22 sub get_marks {
23 return i3(get_socket_path())->get_marks->recv;
24 }
25
26 sub get_mark_for_window_on_workspace {
27 my ($ws, $con) = @_;
28
29 my $current = first { $_->{window} == $con->{id} } @{get_ws_content($ws)};
30 return $current->{marks};
31 }
32
33 ##############################################################
34 # 1: check that there are no marks set yet
35 ##############################################################
36
37 my $tmp = fresh_workspace;
38
39 cmd 'split h';
40
41 is_deeply(get_marks(), [], 'no marks set yet');
42
43 ##############################################################
44 # 2: mark a con, check that it's marked, unmark it, check that
45 ##############################################################
46
47 my $one = open_window;
48 cmd 'mark foo';
49
50 is_deeply(get_marks(), ["foo"], 'mark foo set');
51
52 cmd 'unmark foo';
53
54 is_deeply(get_marks(), [], 'mark foo removed');
55
56 ##############################################################
57 # 3: mark three cons, check that they are marked
58 # unmark one con, check that it's unmarked
59 # unmark all cons, check that they are unmarked
60 ##############################################################
61
62 my $left = open_window;
63 my $middle = open_window;
64 my $right = open_window;
65
66 cmd 'mark right';
67 cmd 'focus left';
68 cmd 'mark middle';
69 cmd 'focus left';
70 cmd 'mark left';
71
72 #
73 # get_marks replys an array of marks, whose order is undefined,
74 # so we use sort to be able to compare the output
75 #
76
77 is_deeply(sort(get_marks()), ["left","middle","right"], 'all three marks set');
78
79 cmd 'unmark right';
80
81 is_deeply(sort(get_marks()), ["left","middle"], 'mark right removed');
82
83 cmd 'unmark';
84
85 is_deeply(get_marks(), [], 'all marks removed');
86
87 ##############################################################
88 # 4: mark a con, use same mark to mark another con,
89 # check that only the latter is marked
90 ##############################################################
91
92 $first = open_window;
93 $second = open_window;
94
95 cmd 'mark important';
96 cmd 'focus left';
97 cmd 'mark important';
98
99 is_deeply(get_mark_for_window_on_workspace($tmp, $first), [ 'important' ], 'first container now has the mark');
100 is_deeply(get_mark_for_window_on_workspace($tmp, $second), [], 'second container lost the mark');
101
102 ##############################################################
103 # 5: mark a con, toggle the mark, check that the mark is gone
104 ##############################################################
105
106 $con = open_window;
107 cmd 'mark important';
108 cmd 'mark --toggle important';
109 is_deeply(get_mark_for_window_on_workspace($tmp, $con), [], 'container no longer has the mark');
110
111 ##############################################################
112 # 6: toggle a mark on an unmarked con, check it is marked
113 ##############################################################
114
115 $con = open_window;
116 cmd 'mark --toggle important';
117 is_deeply(get_mark_for_window_on_workspace($tmp, $con), [ 'important' ], 'container now has the mark');
118
119 ##############################################################
120 # 7: mark a con, toggle a different mark, check it is marked
121 # with the new mark
122 ##############################################################
123
124 $con = open_window;
125 cmd 'mark boring';
126 cmd 'mark --replace --toggle important';
127 is_deeply(get_mark_for_window_on_workspace($tmp, $con), [ 'important' ], 'container has the most recent mark');
128
129 ##############################################################
130 # 8: mark a con, toggle the mark on another con,
131 # check only the latter has the mark
132 ##############################################################
133
134 $first = open_window;
135 $second = open_window;
136
137 cmd 'mark important';
138 cmd 'focus left';
139 cmd 'mark --toggle important';
140
141 is_deeply(get_mark_for_window_on_workspace($tmp, $first), [ 'important' ], 'left container has the mark now');
142 is_deeply(get_mark_for_window_on_workspace($tmp, $second), [], 'second containr no longer has the mark');
143
144 ##############################################################
145 # 9: try to mark two cons with the same mark and check that
146 # it fails
147 ##############################################################
148
149 $first = open_window(wm_class => 'iamnotunique');
150 $second = open_window(wm_class => 'iamnotunique');
151
152 my $result = cmd "[instance=iamnotunique] mark important";
153
154 is($result->[0]->{success}, 0, 'command was unsuccessful');
155 is($result->[0]->{error}, 'A mark must not be put onto more than one window', 'correct error is returned');
156 is_deeply(get_mark_for_window_on_workspace($tmp, $first), [], 'first container is not marked');
157 is_deeply(get_mark_for_window_on_workspace($tmp, $second), [], 'second containr is not marked');
158
159 ##############################################################
160
161 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that windows are properly recognized as urgent when they start up
17 # with the urgency hint already set (and are assigned to a non-visible
18 # workspace).
19 #
20 # Ticket: #1086
21 # Bug still in: 4.6-62-g7098ef6
22 use i3test i3_config => <<EOT;
23 # i3 config file (v4)
24 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
25
26 assign [class="special"] nonvisible
27 EOT
28
29 sub open_special {
30 my %args = @_;
31 $args{name} //= 'special window';
32
33 # We use dont_map because i3 will not map the window on the current
34 # workspace. Thus, open_window would time out in wait_for_map (2 seconds).
35 my $window = open_window(
36 %args,
37 wm_class => 'special',
38 dont_map => 1,
39 );
40 $window->add_hint('urgency');
41 $window->map;
42 return $window;
43 }
44
45 my $tmp = fresh_workspace;
46
47 ok((scalar grep { $_ eq 'nonvisible' } @{get_workspace_names()}) == 0,
48 'assignment destination workspace does not exist yet');
49
50 my $window = open_special;
51 sync_with_i3;
52
53 ok((scalar grep { $_ eq 'nonvisible' } @{get_workspace_names()}) > 0,
54 'assignment destination workspace exists');
55
56 my @urgent = grep { $_->{urgent} } @{get_ws_content('nonvisible')};
57 isnt(@urgent, 0, 'urgent window(s) found on destination workspace');
58
59 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests if the urgency hint will be set appropriately when opening a window
17 # assigned to a workspace.
18 #
19 use i3test i3_autostart => 0;
20
21 # Based on the eponymous function in t/166-assign.t
22 sub open_special {
23 my %args = @_;
24 $args{name} //= 'special window';
25
26 # We use dont_map because i3 will not map the window on the current
27 # workspace. Thus, open_window would time out in wait_for_map (2 seconds).
28 my $window = open_window(
29 %args,
30 wm_class => 'special',
31 dont_map => 1,
32 );
33 $window->map;
34 return $window;
35 }
36
37 #####################################################################
38 # start a window assigned to a non-visible workspace and see that the urgency
39 # hint is set.
40 #####################################################################
41
42 my $config = <<EOT;
43 # i3 config file (v4)
44 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
45 assign [class="special"] → targetws
46 EOT
47
48 my $pid = launch_with_config($config);
49
50 cmd 'workspace ordinaryws';
51 my $window = open_special;
52 sync_with_i3;
53
54 ok(get_ws('targetws')->{urgent}, 'target workspace is urgent');
55
56 $window->destroy;
57
58 exit_gracefully($pid);
59
60
61 #####################################################################
62 # start a window assigned to a visible workspace and see that the urgency hint
63 # is not set.
64 #####################################################################
65
66 $config = <<EOT;
67 # i3 config file (v4)
68 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
69 assign [class="special"] → targetws
70 EOT
71
72 $pid = launch_with_config($config);
73
74 cmd 'workspace targetws';
75 $window = open_special;
76 sync_with_i3;
77
78 ok(!get_ws('targetws')->{urgent}, 'visible workspace is not urgent');
79
80 $window->destroy;
81
82 exit_gracefully($pid);
83
84 #####################################################################
85 # start a window assigned to a visible workspace on a different output and see
86 # that the urgency hint is not set.
87 #####################################################################
88
89 $config = <<EOT;
90 # i3 config file (v4)
91 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
92
93 fake-outputs 1024x768+0+0,1024x768+1024+0
94 workspace targetws output fake-0
95 workspace ordinaryws output fake-1
96
97 assign [class="special"] → targetws
98 EOT
99
100 $pid = launch_with_config($config);
101
102 cmd 'workspace ordinaryws';
103 $window = open_special;
104 sync_with_i3;
105
106 ok(!get_ws('targetws')->{urgent}, 'target workspace is not urgent');
107
108 $window->destroy;
109
110 exit_gracefully($pid);
111
112 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Restores a simple layout from a JSON file.
17 use i3test;
18 use File::Temp qw(tempfile);
19 use IO::Handle;
20
21 ################################################################################
22 # empty layout file.
23 ################################################################################
24
25 my ($fh, $filename) = tempfile(UNLINK => 1);
26 cmd "append_layout $filename";
27
28 does_i3_live;
29
30 close($fh);
31
32 ################################################################################
33 # simple vsplit layout
34 ################################################################################
35
36 my $ws = fresh_workspace;
37
38 my @content = @{get_ws_content($ws)};
39 is(@content, 0, 'no nodes on the new workspace yet');
40
41 ($fh, $filename) = tempfile(UNLINK => 1);
42 print $fh <<EOT;
43 {
44 "layout": "splitv",
45 "nodes": [
46 {
47 },
48 {
49 }
50 ]
51 }
52 EOT
53 $fh->flush;
54 cmd "append_layout $filename";
55
56 does_i3_live;
57
58 @content = @{get_ws_content($ws)};
59 is(@content, 1, 'one node on the workspace now');
60 is($content[0]->{layout}, 'splitv', 'node has splitv layout');
61 is(@{$content[0]->{nodes}}, 2, 'node has two children');
62
63 close($fh);
64
65 ################################################################################
66 # two simple vsplit containers in the same file
67 ################################################################################
68
69 $ws = fresh_workspace;
70
71 @content = @{get_ws_content($ws)};
72 is(@content, 0, 'no nodes on the new workspace yet');
73
74 ($fh, $filename) = tempfile(UNLINK => 1);
75 print $fh <<EOT;
76 {
77 "layout": "splitv",
78 "nodes": [
79 {
80 },
81 {
82 }
83 ]
84 }
85
86 {
87 "layout": "splitv"
88 }
89 EOT
90 $fh->flush;
91 cmd "append_layout $filename";
92
93 does_i3_live;
94
95 @content = @{get_ws_content($ws)};
96 is(@content, 2, 'one node on the workspace now');
97 is($content[0]->{layout}, 'splitv', 'first node has splitv layout');
98 is(@{$content[0]->{nodes}}, 2, 'first node has two children');
99 is($content[1]->{layout}, 'splitv', 'second node has splitv layout');
100 is(@{$content[1]->{nodes}}, 0, 'first node has no children');
101
102 close($fh);
103
104 ################################################################################
105 # simple vsplit layout with swallow specifications
106 ################################################################################
107
108 $ws = fresh_workspace;
109
110 @content = @{get_ws_content($ws)};
111 is(@content, 0, 'no nodes on the new workspace yet');
112
113 ($fh, $filename) = tempfile(UNLINK => 1);
114 print $fh <<EOT;
115 {
116 "layout": "splitv",
117 "nodes": [
118 {
119 "swallows": [
120 {
121 "class": "top"
122 }
123 ]
124 },
125 {
126 "swallows": [
127 {
128 "class": "bottom"
129 }
130 ]
131 }
132 ]
133 }
134 EOT
135 $fh->flush;
136 cmd "append_layout $filename";
137
138 does_i3_live;
139
140 @content = @{get_ws_content($ws)};
141 is(@content, 1, 'one node on the workspace now');
142
143 my $top = open_window(
144 name => 'top window',
145 wm_class => 'top',
146 instance => 'top',
147 );
148
149 my $bottom = open_window(
150 name => 'bottom window',
151 wm_class => 'bottom',
152 instance => 'bottom',
153 );
154
155 @content = @{get_ws_content($ws)};
156 is(@content, 1, 'still one node on the workspace now');
157 my @nodes = @{$content[0]->{nodes}};
158 is($nodes[0]->{name}, 'top window', 'top window on top');
159
160 close($fh);
161
162 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests all supported criteria for the "swallows" key.
17 use i3test;
18 use File::Temp qw(tempfile);
19 use IO::Handle;
20 use X11::XCB qw(PROP_MODE_REPLACE);
21
22 sub verify_swallow_criterion {
23 my ($cfgline, $open_window_cb) = @_;
24
25 my $ws = fresh_workspace;
26
27 my @content = @{get_ws_content($ws)};
28 is(@content, 0, "no nodes on the new workspace yet ($cfgline)");
29
30 my ($fh, $filename) = tempfile(UNLINK => 1);
31 print $fh <<EOT;
32 {
33 "layout": "splitv",
34 "nodes": [
35 {
36 "swallows": [
37 {
38 $cfgline
39 }
40 ]
41 }
42 ]
43 }
44 EOT
45 $fh->flush;
46 cmd "append_layout $filename";
47
48 does_i3_live;
49
50 @content = @{get_ws_content($ws)};
51 is(@content, 1, "one node on the workspace now ($cfgline)");
52
53 my $top = $open_window_cb->();
54
55 @content = @{get_ws_content($ws)};
56 is(@content, 1, "still one node on the workspace now ($cfgline)");
57 my @nodes = @{$content[0]->{nodes}};
58 is($nodes[0]->{window}, $top->id, "top window on top ($cfgline)");
59
60 close($fh);
61 }
62
63 verify_swallow_criterion(
64 '"class": "^special_class$"',
65 sub { open_window(wm_class => 'special_class') }
66 );
67
68 # Run the same test again to verify that the window is not being swallowed by
69 # the first container. Each swallow condition should only swallow precisely one
70 # window.
71 verify_swallow_criterion(
72 '"class": "^special_class$"',
73 sub { open_window(wm_class => 'special_class') }
74 );
75
76 verify_swallow_criterion(
77 '"instance": "^special_instance$"',
78 sub { open_window(wm_class => '', instance => 'special_instance') }
79 );
80
81 verify_swallow_criterion(
82 '"title": "^special_title$"',
83 sub { open_window(name => 'special_title') }
84 );
85
86 verify_swallow_criterion(
87 '"window_role": "^special_role$"',
88 sub {
89 open_window(
90 name => 'roletest',
91 before_map => sub {
92 my ($window) = @_;
93 my $atomname = $x->atom(name => 'WM_WINDOW_ROLE');
94 my $atomtype = $x->atom(name => 'STRING');
95 $x->change_property(
96 PROP_MODE_REPLACE,
97 $window->id,
98 $atomname->id,
99 $atomtype->id,
100 8,
101 length("special_role") + 1,
102 "special_role\x00"
103 );
104 },
105 );
106 }
107 );
108
109 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that i3 does not crash when a layout is partially loadable.
17 # ticket #1145, bug still present in commit b109b1b20dd51401dc929407453d3acdd8ff5566
18 use i3test;
19 use File::Temp qw(tempfile);
20 use IO::Handle;
21
22 ################################################################################
23 # empty layout file.
24 ################################################################################
25
26 my ($fh, $filename) = tempfile(UNLINK => 1);
27 cmd "append_layout $filename";
28
29 does_i3_live;
30
31 close($fh);
32
33 ################################################################################
34 # file with a superfluous trailing comma
35 ################################################################################
36
37 my $ws = fresh_workspace;
38
39 my @content = @{get_ws_content($ws)};
40 is(@content, 0, 'no nodes on the new workspace yet');
41
42 ($fh, $filename) = tempfile(UNLINK => 1);
43 print $fh <<'EOT';
44 // vim:ts=4:sw=4:et
45 {
46 "border": "pixel",
47 "floating": "auto_off",
48 "geometry": {
49 "height": 777,
50 "width": 199,
51 "x": 0,
52 "y": 0
53 },
54 "name": "Buddy List",
55 "percent": 0.116145833333333,
56 "swallows": [
57 {
58 "class": "^Pidgin$",
59 "window_role": "^buddy_list$"
60 }
61 ],
62 "type": "con"
63 }
64
65 {
66 // splitv split container with 1 children
67 "border": "pixel",
68 "floating": "auto_off",
69 "layout": "splitv",
70 "percent": 0.883854166666667,
71 "swallows": [
72 {}
73 ],
74 "type": "con",
75 "nodes": [
76 {
77 // splitv split container with 2 children
78 "border": "pixel",
79 "floating": "auto_off",
80 "layout": "splitv",
81 "percent": 1,
82 "swallows": [
83 {}
84 ],
85 "type": "con",
86 "nodes": [
87 {
88 "border": "pixel",
89 "floating": "auto_off",
90 "geometry": {
91 "height": 318,
92 "width": 566,
93 "x": 0,
94 "y": 0
95 },
96 "name": "zsh",
97 "percent": 0.5,
98 "swallows": [
99 {
100 "class": "^URxvt$",
101 "instance": "^IRC$",
102 }
103 ],
104 "type": "con"
105 },
106 {
107 "border": "pixel",
108 "floating": "auto_off",
109 "geometry": {
110 "height": 1057,
111 "width": 636,
112 "x": 0,
113 "y": 0
114 },
115 "name": "Michael Stapelberg",
116 "percent": 0.5,
117 "swallows": [
118 {
119 "class": "^Pidgin$",
120 "window_role": "^conversation$"
121 }
122 ],
123 "type": "con"
124 }
125 ]
126 }
127 ]
128 }
129
130 EOT
131 $fh->flush;
132 my $reply = cmd "append_layout $filename";
133 ok(!$reply->[0]->{success}, 'IPC reply did not indicate success');
134
135 does_i3_live;
136
137
138 close($fh);
139
140 ################################################################################
141 # another file with a superfluous trailing comma (issue #2755)
142 ################################################################################
143
144 subtest 'issue 2755' => sub {
145 plan tests => 4;
146 $ws = fresh_workspace;
147
148 @content = @{get_ws_content($ws)};
149 is(@content, 0, 'no nodes on the new workspace yet');
150
151 ($fh, $filename) = tempfile(UNLINK => 1);
152 print $fh <<'EOT';
153 // vim:ts=4:sw=4:et
154 {
155 // splith split container with 2 children
156 "border": "normal",
157 "floating": "auto_off",
158 "layout": "splith",
159 "percent": null,
160 "type": "con",
161 "nodes": [
162 {
163 "border": "normal",
164 "current_border_width": 2,
165 "floating": "auto_off",
166 "geometry": {
167 "height": 860,
168 "width": 1396,
169 "x": 1922,
170 "y": 38
171 },
172 "name": "Chromium1",
173 "percent": 0.5,
174 "swallows": [
175 {
176 "class": "^Chromium$",
177 // "instance": "^chromium$",
178 // "title": "^Git\\ Tutorial\\ \\-\\ corp\\ \\-\\ Chromium$",
179 // "transient_for": "^$",
180 // "window_role": "^browser$"
181 }
182 ],
183 "type": "con"
184 },
185 {
186 "border": "normal",
187 "current_border_width": 2,
188 "floating": "auto_off",
189 "geometry": {
190 "height": 1040,
191 "width": 956,
192 "x": 2,
193 "y": 38
194 },
195 "name": "Chromium2",
196 "percent": 0.5,
197 "swallows": [
198 {
199 "class": "^Chromium$",
200 // "instance": "^chromium$",
201 // "title": "^Nutanix\\ \\-\\ Prod\\ \\-\\ Sign\\ In\\ \\-\\ Chromium$",
202 // "transient_for": "^$",
203 // "window_role": "^browser$"
204 }
205 ],
206 "type": "con"
207 }
208 ]
209 }
210
211 EOT
212 $fh->flush;
213 $reply = cmd "append_layout $filename";
214 ok(!$reply->[0]->{success}, 'IPC reply did not indicate success');
215
216 does_i3_live;
217
218 # Move to a different workspace rendered the half-attached con’s con->parent
219 # invalid.
220 fresh_workspace;
221
222 cmd '[urgent=latest] focus';
223 $reply = cmd 'scratchpad show';
224
225 does_i3_live;
226
227 close($fh);
228 };
229
230 ################################################################################
231 # wrong percent key in a child node
232 ################################################################################
233
234 $ws = fresh_workspace;
235
236 @content = @{get_ws_content($ws)};
237 is(@content, 0, 'no nodes on the new workspace yet');
238
239 ($fh, $filename) = tempfile(UNLINK => 1);
240 print $fh <<'EOT';
241 // vim:ts=4:sw=4:et
242 {
243 "border": "pixel",
244 "floating": "auto_off",
245 "layout": "splitv",
246 "type": "con",
247 "nodes": [
248 {
249 "border": "pixel",
250 "floating": "auto_off",
251 "geometry": {
252 "height": 318,
253 "width": 566,
254 "x": 0,
255 "y": 0
256 },
257 "name": "zsh",
258 "percent": 0.833333,
259 "swallows": [
260 {
261 "class": "^URxvt$",
262 "instance": "^IRC$"
263 }
264 ],
265 "type": "con"
266 }
267 ]
268 }
269
270 EOT
271 $fh->flush;
272 cmd "append_layout $filename";
273
274 does_i3_live;
275
276 close($fh);
277
278 ################################################################################
279 # Issue with floating key being set, without proper parent
280 # See #3901
281 ################################################################################
282 subtest 'issue 3901' => sub {
283 kill_all_windows;
284 $ws = fresh_workspace;
285 is(scalar @{get_ws($ws)->{floating_nodes}}, 0, 'No floating nodes yet');
286
287 ($fh, $filename) = tempfile(UNLINK => 1);
288 print $fh <<'EOT';
289 // vim:ts=4:sw=4:et
290 {
291 "border": "pixel",
292 "current_border_width": 1,
293 "floating": "auto_on", // crashes: user_on, auto_on, no crash: user_off, auto_off
294 "geometry": {
295 "height": 400,
296 "width": 300,
297 "x": 820,
298 "y": 350
299 },
300 "name": "Click me to crash",
301 "percent": 0.5, // still crashes if this field is absent
302 "swallows": [
303 {
304 "class": "^this doesn't matter as long as it doesn't match a new window$"
305 }
306 ],
307 "type": "con"
308 }
309
310 EOT
311 $fh->flush;
312 $reply = cmd "append_layout $filename";
313 ok($reply->[0]->{success}, 'IPC reply indicated success');
314
315 cmd '[floating] focus';
316 is(scalar @{get_ws($ws)->{floating_nodes}}, 1, 'one floating node on this ws');
317
318 does_i3_live;
319
320 close($fh);
321 };
322
323 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that i3 removes swallows specifications for split containers.
17 # ticket #1149, bug still present in commit 2fea5ef82bd3528ed62681f9ac64f45830f4acdf
18 use i3test;
19 use File::Temp qw(tempfile);
20 use IO::Handle;
21
22 my $ws = fresh_workspace;
23
24 my @content = @{get_ws_content($ws)};
25 is(@content, 0, 'no nodes on the new workspace yet');
26
27 my ($fh, $filename) = tempfile(UNLINK => 1);
28 print $fh <<'EOT';
29 // vim:ts=4:sw=4:et
30 {
31 "border": "pixel",
32 "floating": "auto_off",
33 "geometry": {
34 "height": 777,
35 "width": 199,
36 "x": 0,
37 "y": 0
38 },
39 "name": "Buddy List",
40 "percent": 0.116145833333333,
41 "swallows": [
42 {
43 "class": "^Pidgin$",
44 "window_role": "^buddy_list$"
45 }
46 ],
47 "type": "con"
48 }
49
50 {
51 // splitv split container with 1 children
52 "border": "pixel",
53 "floating": "auto_off",
54 "layout": "splitv",
55 "percent": 0.883854166666667,
56 "type": "con",
57 "nodes": [
58 {
59 // splitv split container with 2 children
60 "border": "pixel",
61 "floating": "auto_off",
62 "layout": "splitv",
63 "percent": 1,
64 "type": "con",
65 "nodes": [
66 {
67 "border": "pixel",
68 "floating": "auto_off",
69 "geometry": {
70 "height": 318,
71 "width": 566,
72 "x": 0,
73 "y": 0
74 },
75 "name": "zsh",
76 "percent": 0.5,
77 "swallows": [
78 {
79 "class": "^URxvt$",
80 "instance": "^IRC$"
81 }
82 ],
83 "type": "con"
84 },
85 {
86 "border": "pixel",
87 "floating": "auto_off",
88 "geometry": {
89 "height": 1057,
90 "width": 636,
91 "x": 0,
92 "y": 0
93 },
94 "name": "Michael Stapelberg",
95 "percent": 0.5,
96 "swallows": [
97 {
98 "class": "^Pidgin$",
99 "window_role": "^conversation$"
100 }
101 ],
102 "type": "con"
103 }
104 ]
105 }
106 ]
107 }
108
109 EOT
110 $fh->flush;
111 my $reply = cmd "append_layout $filename";
112
113 does_i3_live;
114
115 ok($reply->[0]->{success}, 'IPC reply indicates success');
116
117 my @nodes = @{get_ws_content($ws)};
118
119 is_deeply($nodes[0]->{swallows},
120 [
121 {
122 class => '^Pidgin$',
123 window_role => '^buddy_list$',
124 },
125 ],
126 'swallows specification not parsed correctly');
127
128 is_deeply($nodes[1]->{swallows},
129 [],
130 'swallows specification empty on split container');
131
132 my @children = @{$nodes[1]->{nodes}->[0]->{nodes}};
133
134 is_deeply($children[0]->{swallows},
135 [
136 {
137 class => '^URxvt$',
138 instance => '^IRC$',
139 },
140 ],
141 'swallows specification not parsed correctly');
142
143 is_deeply($children[1]->{swallows},
144 [
145 {
146 class => '^Pidgin$',
147 window_role => '^conversation$',
148 },
149 ],
150 'swallows specification not parsed correctly');
151
152 close($fh);
153 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies the _NET_CURRENT_DESKTOP property correctly tracks the currently
17 # active workspace. Specifically checks that the property is 0 on startup with
18 # an empty config, tracks changes when switching workspaces and when
19 # workspaces are created and deleted.
20 #
21 # The property not being set on startup was last present in commit
22 # 6578976b6159437c16187cf8d1ea38aa9fec9fc8.
23
24 use i3test i3_autostart => 0;
25 use X11::XCB qw(PROP_MODE_REPLACE);
26
27 my $config = <<EOT;
28 # i3 config file (v4)
29 font font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
30 EOT
31
32 my $root = $x->get_root_window;
33 # Manually intern _NET_CURRENT_DESKTOP as $x->atom will not create atoms if
34 # they are not yet interned.
35 my $atom_cookie = $x->intern_atom(0, length("_NET_CURRENT_DESKTOP"), "_NET_CURRENT_DESKTOP");
36 my $_NET_CURRENT_DESKTOP = $x->intern_atom_reply($atom_cookie->{sequence})->{atom};
37 my $CARDINAL = $x->atom(name => 'CARDINAL')->id;
38
39 $x->delete_property($root, $_NET_CURRENT_DESKTOP);
40
41 $x->flush();
42
43 # Returns the _NET_CURRENT_DESKTOP property from the root window. This is
44 # the 0 based index of the current desktop.
45 sub current_desktop_index {
46 sync_with_i3;
47
48 my $cookie = $x->get_property(0, $root, $_NET_CURRENT_DESKTOP,
49 $CARDINAL, 0, 1);
50 my $reply = $x->get_property_reply($cookie->{sequence});
51
52 return undef if $reply->{value_len} != 1;
53 return undef if $reply->{format} != 32;
54 return undef if $reply->{type} != $CARDINAL;
55
56 return unpack 'L', $reply->{value};
57 }
58
59 my $pid = launch_with_config($config);
60
61 is(current_desktop_index, 0, "Starting on desktop 0");
62 cmd 'workspace 1';
63 is(current_desktop_index, 0, "Change from empty to empty");
64 open_window;
65 cmd 'workspace 0';
66 is(current_desktop_index, 0, "Open on 1 and view 0");
67 open_window;
68 cmd 'workspace 1';
69 is(current_desktop_index, 1, "Open on 0 and view 1");
70 cmd 'workspace 2';
71 is(current_desktop_index, 2, "Open and view empty");
72
73 #########################################################
74 # Test the _NET_CURRENT_DESKTOP client request
75 # This request is sent by pagers and bars to switch the current desktop (which
76 # is like an ersatz workspace) to the given index
77 #########################################################
78
79 sub send_current_desktop_request {
80 my ($idx) = @_;
81
82 my $msg = pack "CCSLLLLLL",
83 X11::XCB::CLIENT_MESSAGE, # response_type
84 32, # format
85 0, # sequence
86 0,
87 $_NET_CURRENT_DESKTOP,
88 $idx, # data32[0] (the desktop index)
89 0, # data32[1] (can be a timestamp)
90 0, # data32[2]
91 0, # data32[3]
92 0; # data32[4]
93
94 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
95 }
96
97 send_current_desktop_request(1);
98 is(current_desktop_index, 1, 'current desktop request switched to desktop 1');
99 # note that _NET_CURRENT_DESKTOP is an index and that in this case, workspace 1
100 # is at index 1 as a convenience for the test
101 is(focused_ws, '1', 'current desktop request switched to workspace 1');
102
103 send_current_desktop_request(0);
104 is(current_desktop_index, 0, 'current desktop request switched to desktop 0');
105 is(focused_ws, '0', 'current desktop request switched to workspace 0');
106
107 exit_gracefully($pid);
108
109 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Make sure floating containers really can't be split.
17 # Ticket: #1177
18 # Bug still in: 4.7.2-81-g905440d
19 use i3test;
20
21 my $ws = fresh_workspace;
22 my $window = open_floating_window;
23 cmd "layout stacked";
24 cmd "splitv";
25
26 my $floating_con = get_ws($ws)->{floating_nodes}[0]->{nodes}[0];
27
28 is(@{$floating_con->{nodes}}, 0, 'floating con is still a leaf');
29
30 cmd 'floating disable';
31
32 does_i3_live;
33
34 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test i3_config => <<EOT;
17 # i3 config file (v4)
18 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
19
20 # fake-1 under fake-0 to not interfere with left/right wraping
21 fake-outputs 1024x768+0+0,1024x768+0+1024
22 workspace X output fake-1
23 EOT
24
25 ################################
26 # Window focus event
27 ################################
28
29 my $ws = fresh_workspace(output => 0);
30 my $win0 = open_window;
31 my $win1 = open_window;
32 my $win2 = open_window;
33
34 # ensure the rightmost window contains input focus
35 cmd '[id="' . $win2->id . '"] focus';
36 is($x->input_focus, $win2->id, "Window 2 focused");
37
38 sub focus_subtest {
39 my ($cmd, $name) = @_;
40
41 my $focus = AnyEvent->condvar;
42
43 my @events = events_for(
44 sub { cmd $cmd },
45 'window');
46
47 is(scalar @events, 1, 'Received 1 event');
48 is($events[0]->{change}, 'focus', 'Focus event received');
49 is($events[0]->{container}->{name}, $name, "$name focused");
50 }
51
52 sub kill_subtest {
53 my ($cmd, $name) = @_;
54
55 my $focus = AnyEvent->condvar;
56
57 my @events = events_for(
58 sub { cmd $cmd },
59 'window');
60
61 is(scalar @events, 1, 'Received 1 event');
62 is($events[0]->{change}, 'close', 'Close event received');
63 is($events[0]->{container}->{name}, $name, "$name closed");
64 }
65
66 subtest 'focus left (1)', \&focus_subtest, 'focus left', $win1->name;
67 subtest 'focus left (2)', \&focus_subtest, 'focus left', $win0->name;
68 subtest 'focus right (1)', \&focus_subtest, 'focus right', $win1->name;
69 subtest 'focus right (2)', \&focus_subtest, 'focus right', $win2->name;
70 subtest 'focus right (3)', \&focus_subtest, 'focus right', $win0->name;
71 subtest 'focus left', \&focus_subtest, 'focus left', $win2->name;
72 subtest 'kill doesn\'t produce focus event', \&kill_subtest, '[id=' . $win1->id . '] kill', $win1->name;
73
74 # See issue #3562. We need to switch to an existing workspace on the second
75 # output to trigger the bug.
76 cmd 'workspace X';
77 subtest 'workspace focus', \&focus_subtest, "workspace $ws", $win2->name;
78
79 sub scratchpad_subtest {
80 my ($cmd, $name) = @_;
81
82 my $focus = AnyEvent->condvar;
83
84 my @events = events_for(
85 sub { cmd $cmd },
86 'window');
87
88 is(scalar @events, 2, 'Received 2 events');
89 is($events[0]->{change}, 'move', 'Move event received');
90 is($events[0]->{container}->{nodes}->[0]->{name}, $name, "$name moved");
91 is($events[1]->{change}, 'focus', 'Focus event received');
92 is($events[1]->{container}->{name}, $name, "$name focused");
93 }
94
95 fresh_workspace;
96 my $win = open_window;
97 cmd 'move scratchpad';
98 subtest 'scratchpad', \&scratchpad_subtest, '[id=' . $win->id . '] scratchpad show', $win->name;
99
100 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15
16 use i3test;
17
18 my $window = open_window(name => 'Window 0');
19
20 my @events = events_for(
21 sub {
22 $window->name('New Window Title');
23 sync_with_i3;
24 },
25 'window');
26
27 is(scalar @events, 1, 'Received 1 event');
28 is($events[0]->{change}, 'title', 'Window title change event received');
29 is($events[0]->{container}->{name}, 'New Window Title', 'Window title changed');
30
31 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that windows with properties that indicate they should be floating
17 # are indeed opened floating.
18 # Ticket: #1182
19 # Bug still in: 4.7.2-97-g84fc808
20 use i3test;
21 use X11::XCB qw(PROP_MODE_REPLACE);
22
23 sub open_with_type {
24 my $window_type = shift;
25
26 my $window = open_window(
27 window_type => $x->atom(name => $window_type),
28 );
29 return $window;
30 }
31
32 sub open_with_state {
33 my $window_state = shift;
34
35 my $window = open_window(
36 before_map => sub {
37 my ($window) = @_;
38
39 my $atomname = $x->atom(name => '_NET_WM_STATE');
40 my $atomtype = $x->atom(name => 'ATOM');
41 $x->change_property(
42 PROP_MODE_REPLACE,
43 $window->id,
44 $atomname->id,
45 $atomtype->id,
46 32,
47 1,
48 pack('L1', $x->atom(name => $window_state)->id),
49 );
50 },
51 );
52
53 return $window;
54 }
55
56 sub open_with_fixed_size {
57 # The type of the WM_NORMAL_HINTS property is WM_SIZE_HINTS
58 # https://tronche.com/gui/x/icccm/sec-4.html#s-4.1.2.3
59 my $XCB_ICCCM_SIZE_HINT_P_MIN_SIZE = 0x32;
60 my $XCB_ICCCM_SIZE_HINT_P_MAX_SIZE = 0x16;
61
62 my $flags = $XCB_ICCCM_SIZE_HINT_P_MIN_SIZE | $XCB_ICCCM_SIZE_HINT_P_MAX_SIZE;
63
64 my $min_width = 150;
65 my $max_width = 150;
66 my $min_height = 100;
67 my $max_height = 100;
68
69 my $pad = 0x00;
70
71 my $window = open_window(
72 before_map => sub {
73 my ($window) = @_;
74
75 my $atomname = $x->atom(name => 'WM_NORMAL_HINTS');
76 my $atomtype = $x->atom(name => 'WM_SIZE_HINTS');
77 $x->change_property(
78 PROP_MODE_REPLACE,
79 $window->id,
80 $atomname->id,
81 $atomtype->id,
82 32,
83 13,
84 pack('C5N8', $flags, $pad, $pad, $pad, $pad, 0, 0, 0, $min_width, $min_height, $max_width, $max_height),
85 );
86 },
87 );
88
89 return $window;
90 }
91
92 my $ws = fresh_workspace;
93
94 my $window = open_with_type '_NET_WM_WINDOW_TYPE_DIALOG';
95 is(get_ws($ws)->{floating_nodes}[0]->{nodes}[0]->{window}, $window->id, 'Dialog window opened floating');
96 $window->unmap;
97
98 $window = open_with_type '_NET_WM_WINDOW_TYPE_UTILITY';
99 is(get_ws($ws)->{floating_nodes}[0]->{nodes}[0]->{window}, $window->id, 'Utility window opened floating');
100 $window->unmap;
101
102 $window = open_with_type '_NET_WM_WINDOW_TYPE_TOOLBAR';
103 is(get_ws($ws)->{floating_nodes}[0]->{nodes}[0]->{window}, $window->id, 'Toolbar window opened floating');
104 $window->unmap;
105
106 $window = open_with_type '_NET_WM_WINDOW_TYPE_SPLASH';
107 is(get_ws($ws)->{floating_nodes}[0]->{nodes}[0]->{window}, $window->id, 'Splash window opened floating');
108 $window->unmap;
109
110 $window = open_with_state '_NET_WM_STATE_MODAL';
111 is(get_ws($ws)->{floating_nodes}[0]->{nodes}[0]->{window}, $window->id, 'Modal window opened floating');
112 $window->unmap;
113
114 $window = open_with_fixed_size;
115 is(get_ws($ws)->{floating_nodes}[0]->{nodes}[0]->{window}, $window->id, 'Fixed size window opened floating');
116 is(get_ws($ws)->{floating_nodes}[0]->{nodes}[0]->{window_rect}->{width}, 150, 'Fixed size window opened with minimum width');
117 is(get_ws($ws)->{floating_nodes}[0]->{nodes}[0]->{window_rect}->{height}, 100, 'Fixed size window opened with minimum height');
118 $window->unmap;
119
120 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that i3 does not crash when a command is issued that would resize a dock
17 # client.
18 # Ticket: #1201
19 # Bug still in: 4.7.2-107-g9b03be6
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23 EOT
24
25 my $window = open_window(
26 wm_class => 'special',
27 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
28 );
29
30 cmd('[class="special"] resize grow height 160 px or 16 ppt');
31
32 does_i3_live;
33
34 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that _NET_CLIENT_LIST is properly updated on the root window as windows
17 # are mapped and unmapped.
18 #
19 # Information on this property can be found here:
20 # https://standards.freedesktop.org/wm-spec/latest/ar01s03.html
21 #
22 # > These arrays contain all X Windows managed by the Window Manager.
23 # > _NET_CLIENT_LIST has initial mapping order, starting with the oldest window.
24 #
25 # Ticket: #1099
26 # Bug still in: 4.7.2-8-ge6cce92
27 use i3test;
28
29 sub get_client_list {
30 my $cookie = $x->get_property(
31 0,
32 $x->get_root_window(),
33 $x->atom(name => '_NET_CLIENT_LIST')->id,
34 $x->atom(name => 'WINDOW')->id,
35 0,
36 4096,
37 );
38 my $reply = $x->get_property_reply($cookie->{sequence});
39 my $len = $reply->{length};
40
41 return () if $len == 0;
42 return unpack("L$len", $reply->{value});
43 }
44
45 # Mapping a window should give us one client in _NET_CLIENT_LIST
46 my $win1 = open_window;
47
48 my @clients = get_client_list;
49
50 is(@clients, 1, 'One client in _NET_CLIENT_LIST');
51 is($clients[0], $win1->{id}, 'Correct client in position one');
52
53 # Mapping another window should give us two clients in the list with the last
54 # client mapped in the last position
55 my $win2 = open_window;
56
57 @clients = get_client_list;
58 is(@clients, 2, 'Added mapped client to list (2)');
59 is($clients[0], $win1->{id}, 'Correct client in position one');
60 is($clients[1], $win2->{id}, 'Correct client in position two');
61
62 # Mapping another window should give us three clients in the list in the order
63 # they were mapped
64 my $win3 = open_window;
65
66 @clients = get_client_list;
67 is(@clients, 3, 'Added mapped client to list (3)');
68 is($clients[0], $win1->{id}, 'Correct client in position one');
69 is($clients[1], $win2->{id}, 'Correct client in position two');
70 is($clients[2], $win3->{id}, 'Correct client in position three');
71
72 # Unmapping the second window should give us the two remaining clients in the
73 # order they were mapped
74 $win2->unmap;
75 wait_for_unmap($win2);
76
77 @clients = get_client_list;
78 is(@clients, 2, 'Removed unmapped client from list (2)');
79 is($clients[0], $win1->{id}, 'Correct client in position one');
80 is($clients[1], $win3->{id}, 'Correct client in position two');
81
82 # Unmapping the first window should give us only the remaining mapped window in
83 # the list
84 $win1->unmap;
85 wait_for_unmap($win1);
86
87 @clients = get_client_list;
88 is(@clients, 1, 'Removed unmapped client from list (1)');
89 is($clients[0], $win3->{id}, 'Correct client in position one');
90
91 # Unmapping the last window should give us an empty list
92 $win3->unmap;
93 wait_for_unmap($win3);
94
95 @clients = get_client_list;
96 is(@clients, 0, 'Removed unmapped client from list (0)');
97
98 # Dock clients should not be included in this list
99
100 my $dock_win = open_window({
101 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
102 });
103
104 @clients = get_client_list;
105 is(@clients, 0, 'Dock clients are not included in the list');
106
107 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that i3 does not crash when resizing a split container
17 # Ticket: #1220
18 # Bug still in: 4.7.2-128-g702906d
19 use i3test;
20
21 open_window;
22 open_window;
23
24 cmd 'split h';
25
26 open_window;
27
28 cmd 'focus parent, resize grow left';
29
30 does_i3_live;
31
32 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that the ipc window::fullscreen_mode event works properly
17 #
18 # Bug still in: 4.7.2-135-g7deb23c
19 use i3test;
20
21 open_window;
22
23 sub fullscreen_subtest {
24 my ($want) = @_;
25 my @events = events_for(
26 sub { cmd 'fullscreen' },
27 'window');
28
29 is(scalar @events, 1, 'Received 1 event');
30 is($events[0]->{container}->{fullscreen_mode}, $want, "fullscreen_mode now $want");
31 }
32
33 subtest 'fullscreen on', \&fullscreen_subtest, 1;
34 subtest 'fullscreen off', \&fullscreen_subtest, 0;
35
36 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that internal workspaces (those whose name starts with __) cannot be
17 # used in all commands that deal with workspaces.
18 # Ticket: #1209
19 # Bug still in: 4.7.2-154-g144e3fb
20 use i3test i3_autostart => 0;
21
22 sub internal_workspaces {
23 scalar grep { /^__/ } @{get_workspace_names()}
24 }
25
26 my $config = <<EOT;
27 # i3 config file (v4)
28 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
29 EOT
30
31 my $pid = launch_with_config($config);
32
33 is(internal_workspaces(), 0, 'No internal workspaces');
34
35 cmd 'workspace __foo';
36 is(internal_workspaces(), 0, 'No internal workspaces');
37
38 cmd 'move to workspace __foo';
39 is(internal_workspaces(), 0, 'No internal workspaces');
40
41 cmd 'rename workspace to __foo';
42 is(internal_workspaces(), 0, 'No internal workspaces');
43
44 exit_gracefully($pid);
45
46 ################################################################################
47 # Verify that new workspace names starting with __ are ignored.
48 ################################################################################
49
50 $config = <<EOT;
51 # i3 config file (v4)
52 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
53
54 bindsym Mod1+1 workspace __foo
55 bindsym Mod1+2 workspace bar
56 EOT
57
58 $pid = launch_with_config($config);
59
60 is_deeply(get_workspace_names(), [ 'bar' ], 'New workspace called bar, not __foo');
61
62 exit_gracefully($pid);
63
64 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Checks the workspace "empty" event semantics.
17 #
18 use i3test;
19
20 ################################################################################
21 # check that the workspace empty event is sent upon workspace switch when the
22 # old workspace is empty
23 ################################################################################
24 subtest 'Workspace empty event upon switch', sub {
25 my $ws2 = fresh_workspace;
26 my $w2 = open_window();
27 my $ws1 = fresh_workspace;
28 my $w1 = open_window();
29
30 cmd '[id="' . $w1->id . '"] kill';
31
32 my $cond = AnyEvent->condvar;
33 my @events = events_for(
34 sub { cmd "workspace $ws2" },
35 'workspace');
36
37 is(scalar @events, 2, 'Received 2 event');
38 is($events[1]->{change}, 'empty', '"Empty" event received upon workspace switch');
39 is($events[1]->{current}->{name}, $ws1, '"current" property should be set to the workspace con');
40 };
41
42 ################################################################################
43 # check that no workspace empty event is sent upon workspace switch if the
44 # workspace is not empty
45 ################################################################################
46 subtest 'No workspace empty event', sub {
47 my $ws2 = fresh_workspace;
48 my $w2 = open_window();
49 my $ws1 = fresh_workspace;
50 my $w1 = open_window();
51
52 my @events = events_for(
53 sub { cmd "workspace $ws2" },
54 'workspace');
55
56 is(scalar @events, 1, 'Received 1 event');
57 is($events[0]->{change}, 'focus', 'Event change is "focus"');
58 };
59
60 ################################################################################
61 # check that workspace empty event is sent when the last window has been closed
62 # on invisible workspace
63 ################################################################################
64 subtest 'Workspace empty event upon window close', sub {
65 my $ws1 = fresh_workspace;
66 my $w1 = open_window();
67 my $ws2 = fresh_workspace;
68 my $w2 = open_window();
69
70 my @events = events_for(
71 sub {
72 $w1->unmap;
73 sync_with_i3;
74 },
75 'workspace');
76
77 is(scalar @events, 1, 'Received 1 event');
78 is($events[0]->{change}, 'empty', '"Empty" event received upon window close');
79 is($events[0]->{current}->{name}, $ws1, '"current" property should be set to the workspace con');
80 };
81
82 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that the border widths can be set separately for floating and
17 # tiled windows
18 # Ticket: #1244
19 # Bug still in: 4.7.2-166-gb69b3fc
20
21 use i3test i3_autostart => 0;
22
23 #####################################################################
24 # 1: check that the border widths can be different for floating and
25 # tiled windows
26 #####################################################################
27
28 my $config = <<EOT;
29 # i3 config file (v4)
30 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
31
32 new_window pixel 5
33 new_float pixel 10
34 EOT
35
36 my $pid = launch_with_config($config);
37
38 my $tmp = fresh_workspace;
39
40 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
41
42 my $tilewindow = open_window;
43 my $floatwindow = open_floating_window;
44
45 my $wscontent = get_ws($tmp);
46
47 my @tiled = @{$wscontent->{nodes}};
48 ok(@tiled == 1, 'one tiled container opened');
49 is($tiled[0]->{current_border_width}, 5, 'tiled current border width set to 5');
50 is($tilewindow->rect->width, $tiled[0]->{rect}->{width} - 2*5, 'tiled border width 5');
51
52 my @floating = @{$wscontent->{floating_nodes}};
53 ok(@floating == 1, 'one floating container opened');
54 is($floating[0]->{nodes}[0]->{current_border_width}, 10, 'floating current border width set to 10');
55 is($floatwindow->rect->width, $floating[0]->{rect}->{width} - 2*10, 'floating border width 10');
56
57 exit_gracefully($pid);
58
59 #####################################################################
60 # 2: make sure the order can also be reverse
61 #####################################################################
62
63 $config = <<EOT;
64 # i3 config file (v4)
65 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
66
67 new_float pixel 7
68 new_window pixel 3
69 EOT
70
71 $pid = launch_with_config($config);
72
73 $tmp = fresh_workspace;
74
75 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
76
77 $tilewindow = open_window;
78 $floatwindow = open_floating_window;
79
80 $wscontent = get_ws($tmp);
81
82 @tiled = @{$wscontent->{nodes}};
83 ok(@tiled == 1, 'one tiled container opened');
84 is($tiled[0]->{current_border_width}, 3, 'tiled current border width set to 3');
85 is($tilewindow->rect->width, $tiled[0]->{rect}->{width} - 2*3, 'tiled border width 3');
86
87 @floating = @{$wscontent->{floating_nodes}};
88 ok(@floating == 1, 'one floating container opened');
89 is($floating[0]->{nodes}[0]->{current_border_width}, 7, 'floating current border width set to 7');
90 is($floatwindow->rect->width, $floating[0]->{rect}->{width} - 2*7, 'floating border width 7');
91
92 exit_gracefully($pid);
93
94 #####################################################################
95 # 3: make sure normal border widths work as well
96 #####################################################################
97
98 $config = <<EOT;
99 # i3 config file (v4)
100 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
101
102 new_float normal 6
103 new_window normal 4
104 EOT
105
106 $pid = launch_with_config($config);
107
108 $tmp = fresh_workspace;
109
110 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
111
112 $tilewindow = open_window;
113 $floatwindow = open_floating_window;
114
115 $wscontent = get_ws($tmp);
116
117 @tiled = @{$wscontent->{nodes}};
118 ok(@tiled == 1, 'one tiled container opened');
119 is($tiled[0]->{current_border_width}, 4, 'tiled current border width set to 4');
120 is($tilewindow->rect->width, $tiled[0]->{rect}->{width} - 2*4, 'tiled border width 4');
121
122 @floating = @{$wscontent->{floating_nodes}};
123 ok(@floating == 1, 'one floating container opened');
124 is($floating[0]->{nodes}[0]->{current_border_width}, 6, 'floating current border width set to 6');
125 is($floatwindow->rect->width, $floating[0]->{rect}->{width} - 2*6, 'floating border width 6');
126
127 exit_gracefully($pid);
128
129 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Makes sure i3 deletes its temporary directory when exiting.
17 # Ticket: #1253
18 # Bug still in: 4.7.2-186-g617afc6
19 use i3test i3_autostart => 0;
20 use File::Basename;
21 use File::Temp qw(tempfile tempdir);
22 use X11::XCB qw(:all);
23
24 my $config = <<EOT;
25 # i3 config file (v4)
26 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
27 EOT
28
29 # ensure XDG_RUNTIME_DIR is not set
30 delete $ENV{XDG_RUNTIME_DIR};
31
32 my $pid = launch_with_config($config, dont_add_socket_path => 1, dont_create_temp_dir => 1);
33 my $socketpath = get_socket_path(0);
34 my $tmpdir = dirname($socketpath);
35
36 ok(-d $tmpdir, "tmpdir $tmpdir exists");
37
38 # Clear the error logfile. The testsuite runs in an environment where RandR is
39 # not supported, so there always is a message about xinerama in the error
40 # logfile.
41 my @errorlogfiles = <$tmpdir/errorlog.*>;
42 for my $fn (@errorlogfiles) {
43 open(my $fh, '>', $fn);
44 close($fh);
45 }
46
47 exit_gracefully($pid);
48
49 ok(! -d $tmpdir, "tmpdir $tmpdir was cleaned up");
50 if (-d $tmpdir) {
51 diag('contents = ' . Dumper(<$tmpdir/*>));
52 }
53
54 $pid = launch_with_config($config, dont_add_socket_path => 1, dont_create_temp_dir => 1);
55 $socketpath = get_socket_path(0);
56 $tmpdir = dirname($socketpath);
57
58 ok(-d $tmpdir, "tmpdir $tmpdir exists");
59
60 # Clear the error logfile. The testsuite runs in an environment where RandR is
61 # not supported, so there always is a message about xinerama in the error
62 # logfile.
63 @errorlogfiles = <$tmpdir/errorlog.*>;
64 for my $fn (@errorlogfiles) {
65 open(my $fh, '>', $fn);
66 close($fh);
67 }
68
69 diag('socket path before restarting is ' . $socketpath);
70
71 cmd 'restart';
72
73 # The socket path will be different, and we use that for checking whether i3 has restarted yet.
74 while (get_socket_path(0) eq $socketpath) {
75 sleep 0.1;
76 }
77
78 my $new_tmpdir = dirname(get_socket_path());
79
80 does_i3_live;
81
82 # Clear the error logfile. The testsuite runs in an environment where RandR is
83 # not supported, so there always is a message about xinerama in the error
84 # logfile.
85 @errorlogfiles = <$new_tmpdir/errorlog.*>;
86 for my $fn (@errorlogfiles) {
87 open(my $fh, '>', $fn);
88 close($fh);
89 }
90
91 exit_gracefully($pid);
92
93 ok(! -d $tmpdir, "old tmpdir $tmpdir was cleaned up");
94 if (-d $tmpdir) {
95 diag('contents = ' . Dumper(<$tmpdir/*>));
96 }
97
98 ok(! -d $new_tmpdir, "new tmpdir $new_tmpdir was cleaned up");
99 if (-d $new_tmpdir) {
100 diag('contents = ' . Dumper(<$new_tmpdir/*>));
101 }
102
103 ################################################################################
104 # Regression: with a socket path outside of tmpdir, i3 would delete the tmpdir
105 # prematurely and could not use it for storing the restart layout.
106 ################################################################################
107
108 # Set XDG_RUNTIME_DIR to a temp directory so that i3 will create its directory
109 # in there and we’ll be able to find it. Necessary because we cannot deduce the
110 # temp directory from the socket path (which we explicitly set).
111 $ENV{XDG_RUNTIME_DIR} = tempdir(CLEANUP => 1);
112
113 my ($outfh, $outname) = tempfile('/tmp/i3-socket.XXXXXX', UNLINK => 1);
114 $config = <<EOT;
115 # i3 config file (v4)
116 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
117
118 ipc-socket $outname
119 EOT
120
121 $pid = launch_with_config($config, dont_add_socket_path => 1, dont_create_temp_dir => 1);
122 $socketpath = get_socket_path(0);
123
124 sub get_config_path {
125 my $atom = $x->atom(name => 'I3_CONFIG_PATH');
126 my $cookie = $x->get_property(0, $x->get_root_window(), $atom->id, GET_PROPERTY_TYPE_ANY, 0, 256);
127 my $reply = $x->get_property_reply($cookie->{sequence});
128 return $reply->{value};
129 }
130
131 my ($outfh2, $outname2) = tempfile('/tmp/i3-socket.XXXXXX', UNLINK => 1);
132 my $config_path = get_config_path();
133 open(my $configfh, '>', $config_path);
134 say $configfh <<EOT;
135 # i3 config file (v4)
136 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
137 ipc-socket $outname2
138 EOT
139 close($configfh);
140 $tmpdir = $ENV{XDG_RUNTIME_DIR} . '/i3';
141
142 ok(-d $tmpdir, "tmpdir $tmpdir exists");
143
144 # Clear the error logfile. The testsuite runs in an environment where RandR is
145 # not supported, so there always is a message about xinerama in the error
146 # logfile.
147 @errorlogfiles = <$tmpdir/errorlog.*>;
148 for my $fn (@errorlogfiles) {
149 open(my $fh, '>', $fn);
150 close($fh);
151 }
152
153 my $tmp = fresh_workspace;
154 my $win = open_window;
155 cmd 'border none';
156 my ($nodes, $focus) = get_ws_content($tmp);
157 is($nodes->[0]->{border}, 'none', 'border is none');
158
159 cmd 'restart';
160
161 # The socket path will be different, and we use that for checking whether i3 has restarted yet.
162 while (get_socket_path(0) eq $socketpath) {
163 sleep 0.1;
164 }
165
166 $new_tmpdir = $ENV{XDG_RUNTIME_DIR} . '/i3';
167
168 does_i3_live;
169
170 ($nodes, $focus) = get_ws_content($tmp);
171 is($nodes->[0]->{border}, 'none', 'border still none after restart');
172
173 exit_gracefully($pid);
174
175 close($outfh);
176 close($outfh2);
177
178 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Ensures floating windows don’t drop out of fullscreen mode when restarting
17 # and that they keep their geometry.
18 # Ticket: #1263
19 # Bug still in: 4.7.2-200-g570b572
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 for_window [instance=__i3-test-window] floating enable, border pixel 1
25 EOT
26
27 my $tmp = fresh_workspace;
28
29 my $window = open_window(wm_class => '__i3-test-window');
30
31 cmd 'fullscreen';
32
33 my ($nodes, $focus) = get_ws($tmp);
34 my $floating_win = $nodes->{floating_nodes}->[0]->{nodes}->[0];
35 is($floating_win->{fullscreen_mode}, 1, 'floating window in fullscreen mode');
36 my $old_geometry = $floating_win->{geometry};
37
38 cmd 'restart';
39
40 ($nodes, $focus) = get_ws($tmp);
41 $floating_win = $nodes->{floating_nodes}->[0]->{nodes}->[0];
42 is($floating_win->{fullscreen_mode}, 1, 'floating window still in fullscreen mode');
43 is_deeply($floating_win->{geometry}, $old_geometry, 'floating window geometry still the same');
44
45 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that the window::floating event works correctly. This event should be
17 # emitted when a window transitions to or from the floating state.
18 # Bug still in: 4.8-7-gf4a8253
19 use i3test;
20
21 sub floating_subtest {
22 my ($win, $cmd, $want) = @_;
23
24 my @events = events_for(
25 sub { cmd $cmd },
26 'window');
27
28 my @floating = grep { $_->{change} eq 'floating' } @events;
29 is(scalar @floating, 1, 'Received 1 floating event');
30 is($floating[0]->{container}->{window}, $win->{id}, "window id matches");
31 is($floating[0]->{container}->{floating}, $want, "floating is $want");
32 }
33
34 my $win = open_window();
35
36 subtest 'floating enable', \&floating_subtest, $win, '[id="' . $win->{id} . '"] floating enable', 'user_on';
37 subtest 'floating disable', \&floating_subtest, $win, '[id="' . $win->{id} . '"] floating disable', 'user_off';
38
39 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that the `move [direction]` command works with criteria
17 # Bug still in: 4.8-16-g6888a1f
18 use i3test;
19
20 my ($ws, $win1, $win2, $win3, $ws_con);
21
22 ###############################################################################
23 # Tets moving with 'id' criterion.
24 ###############################################################################
25
26 $ws = fresh_workspace;
27
28 $win1 = open_window;
29 $win2 = open_window;
30 $win3 = open_window;
31
32 # move win1 from the left to the right
33 cmd '[id="' . $win1->{id} . '"] move right';
34
35 # now they should be switched, with win2 still being focused
36 $ws_con = get_ws($ws);
37
38 # win2 should be on the left
39 is($ws_con->{nodes}[0]->{window}, $win2->{id}, 'the `move [direction]` command should work with criteria');
40 is($x->input_focus, $win3->{id}, 'it should not disturb focus');
41
42 ###############################################################################
43 # Tets moving with 'window_type' criterion.
44 ###############################################################################
45
46 # test all window types
47 my %window_types = (
48 'normal' => '_NET_WM_WINDOW_TYPE_NORMAL',
49 'dialog' => '_NET_WM_WINDOW_TYPE_DIALOG',
50 'utility' => '_NET_WM_WINDOW_TYPE_UTILITY',
51 'toolbar' => '_NET_WM_WINDOW_TYPE_TOOLBAR',
52 'splash' => '_NET_WM_WINDOW_TYPE_SPLASH',
53 'menu' => '_NET_WM_WINDOW_TYPE_MENU',
54 'dropdown_menu' => '_NET_WM_WINDOW_TYPE_DROPDOWN_MENU',
55 'popup_menu' => '_NET_WM_WINDOW_TYPE_POPUP_MENU',
56 'tooltip' => '_NET_WM_WINDOW_TYPE_TOOLTIP',
57 'notification' => '_NET_WM_WINDOW_TYPE_NOTIFICATION'
58 );
59
60 while (my ($window_type, $atom) = each %window_types) {
61
62 $ws = fresh_workspace;
63
64 $win1 = open_window(window_type => $x->atom(name => $atom));
65 $win2 = open_window;
66 $win3 = open_window;
67
68 cmd '[window_type="' . $window_type . '"] move right';
69
70 $ws_con = get_ws($ws);
71 is($ws_con->{nodes}[0]->{window}, $win2->{id}, 'the `move [direction]` command should work with window_type = ' . $window_type);
72 is($x->input_focus, $win3->{id}, 'it should not disturb focus');
73
74 }
75
76 ###############################################################################
77
78 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that an assignment that unmaps a window does not disturb input focus.
17 # This can cause i3 focus to be an unmapped window and different than X focus
18 # which can lead to complications
19 # Ticket: #1283
20 # Bug still in: 4.8-24-g60070de
21 use i3test i3_config => <<'EOT';
22 # i3 config file (v4)
23 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
24
25 for_window [class="^special_kill$"] kill
26 for_window [class="^special_scratchpad$"] move scratchpad
27 EOT
28
29 my $win = open_window;
30
31 my $scratch_window = open_window(
32 wm_class => 'special_scratchpad',
33 dont_map => 1
34 );
35 $scratch_window->map;
36 sync_with_i3;
37
38 is($x->input_focus, $win->{id},
39 'an assignment that sends a window to the scratchpad should not disturb focus');
40
41 my $kill_window = open_window(
42 wm_class => 'special_kill',
43 dont_map => 1
44 );
45 $kill_window->map;
46 sync_with_i3;
47
48 is($x->input_focus, $win->{id},
49 'an assignment that kills a window should not disturb focus');
50
51 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that the EWMH specified property _NET_DESKTOP_NAMES is updated properly
17 # on the root window. We interpret this as a list of the open workspace names.
18 # Ticket: #1241
19 use i3test;
20
21 sub get_desktop_names {
22 # Make sure that i3 pushed its changes to X11 before querying.
23 sync_with_i3;
24
25 my $cookie = $x->get_property(
26 0,
27 $x->get_root_window(),
28 $x->atom(name => '_NET_DESKTOP_NAMES')->id,
29 $x->atom(name => 'UTF8_STRING')->id,
30 0,
31 4096,
32 );
33
34 my $reply = $x->get_property_reply($cookie->{sequence});
35
36 return 0 if $reply->{value_len} == 0;
37
38 # the property is a null-delimited list of utf8 strings ;;
39 return split /\0/, $reply->{value};
40 }
41
42 cmd 'workspace foo';
43
44 my @expected_names = ('foo');
45 my @desktop_names = get_desktop_names;
46
47 is_deeply(\@desktop_names, \@expected_names, '_NET_DESKTOP_NAMES should be an array of the workspace names');
48
49 # open a new workspace and see that the property is updated correctly
50 open_window;
51 cmd 'workspace bar';
52
53 @desktop_names = get_desktop_names;
54 @expected_names = ('foo', 'bar');
55
56 is_deeply(\@desktop_names, \@expected_names, 'it should be updated when a new workspace appears');
57
58 # rename the workspace and see that the property is updated correctly
59 cmd 'rename workspace bar to baz';
60
61 @desktop_names = get_desktop_names;
62 @expected_names = ('foo', 'baz');
63
64 is_deeply(\@desktop_names, \@expected_names, 'it should be updated when a workspace is renamed');
65
66 # empty a workspace and see that the property is updated correctly
67 cmd 'workspace foo';
68
69 @desktop_names = get_desktop_names;
70 @expected_names = ('foo');
71
72 is_deeply(\@desktop_names, \@expected_names, 'it should be updated when a workspace is emptied');
73
74 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Check whether the -C option works without a display and doesn't
17 # accidentally start the nagbar.
18 #
19 use i3test i3_autostart => 0;
20 use File::Temp qw(tempfile);
21
22 my ($cfg, $ret, $out);
23
24 sub check_config {
25 my ($config) = @_;
26 my ($fh, $tmpfile) = tempfile(UNLINK => 1);
27 print $fh $config;
28 my $output = qx(DISPLAY= i3 -C -c $tmpfile 2>&1);
29 my $retval = $?;
30 $fh->flush;
31 close($fh);
32 return ($retval >> 8, $output);
33 }
34
35 ################################################################################
36 # 1: test with a bogus configuration file
37 ################################################################################
38
39 $cfg = <<EOT;
40 # i3 config file (v4)
41 i_am_an_unknown_config option
42 EOT
43
44 ($ret, $out) = check_config($cfg);
45 is($ret, 1, "exit code == 1");
46 like($out, qr/ERROR: *CONFIG: *[Ee]xpected.*tokens/, 'bogus config file');
47
48 ################################################################################
49 # 2: test with a valid configuration file
50 ################################################################################
51
52 $cfg = <<EOT;
53 # i3 config file (v4)
54 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
55 EOT
56
57 ($ret, $out) = check_config($cfg);
58 is($ret, 0, "exit code == 0");
59 is($out, "", 'valid config file');
60
61 ################################################################################
62 # 3: test duplicate keybindings
63 ################################################################################
64
65 $cfg = <<EOT;
66 # i3 config file (v4)
67 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
68 bindsym Shift+a nop 1
69 bindsym Shift+a nop 2
70 EOT
71
72 ($ret, $out) = check_config($cfg);
73 is($ret, 1, "exit code == 1");
74 like($out, qr/ERROR: *Duplicate keybinding in config file/, 'duplicate keybindings');
75
76 ################################################################################
77 # 4: test no duplicate keybindings
78 ################################################################################
79
80 $cfg = <<EOT;
81 # i3 config file (v4)
82 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
83 bindsym Shift+a nop 1
84 EOT
85
86 ($ret, $out) = check_config($cfg);
87 is($ret, 0, "exit code == 0");
88 is($out, "", 'valid config file');
89
90 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that focusing floating windows with the command `focus [direction]`
17 # promotes the focused window to the top of the rendering stack.
18 # Ticket: #1322
19 # Bug still in: 4.8-88-gcc09348
20 use i3test;
21
22 my $ws = fresh_workspace;
23
24 my $win1 = open_floating_window;
25 my $win2 = open_floating_window;
26 my $win3 = open_floating_window;
27
28 # it's a good idea to do this a few times because of the implementation
29 for my $i (1 .. 3) {
30 cmd 'focus left';
31 my $ws_con = get_ws($ws);
32 is($ws_con->{floating_nodes}[-1]->{nodes}[0]->{id}, get_focused($ws),
33 "focus left put the focused window on top of the floating windows (try $i)");
34 }
35
36 for my $i (1 .. 3) {
37 cmd 'focus right';
38 my $ws_con = get_ws($ws);
39 is($ws_con->{floating_nodes}[-1]->{nodes}[0]->{id}, get_focused($ws),
40 "focus right put the focused window on top of the floating windows (try $i)");
41 }
42
43 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that using layout tabbed followed by focus (on a window that is
17 # assigned to an invisible workspace) will not crash i3.
18 # Ticket: #1338
19 # Bug still in: 4.8-91-g294d52e
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 assign [title=".*"] 1
25 for_window [title=".*"] layout tabbed, focus
26 EOT
27
28 # Switch away from workspace 1
29 my $tmp = fresh_workspace;
30
31 my $win = open_window;
32
33 does_i3_live;
34
35 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that the binding event works properly
17 # Ticket: #1210
18 use i3test i3_autostart => 0;
19
20 my $keysym = 't';
21 my $command = 'nop';
22 my @mods = ('Shift', 'Ctrl');
23 my $binding_symbol = join("+", @mods) . "+$keysym";
24
25 my $config = <<EOT;
26 # i3 config file (v4)
27 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
28
29 bindsym $binding_symbol $command
30 EOT
31
32 SKIP: {
33 qx(which xdotool 2> /dev/null);
34
35 skip 'xdotool is required to test the binding event. `[apt-get install|pacman -S] xdotool`', 1 if $?;
36
37 my $pid = launch_with_config($config);
38
39 my $cv = AnyEvent->condvar;
40
41 my @events = events_for(
42 sub {
43 # TODO: this is still flaky: we need to synchronize every X11
44 # connection with i3. Move to XTEST and synchronize that connection.
45 qx(xdotool key $binding_symbol);
46 },
47 'binding');
48
49 is(scalar @events, 1, 'Received 1 event');
50
51 is($events[0]->{change}, 'run',
52 'the `change` field should indicate this binding has run');
53
54 ok($events[0]->{binding},
55 'the `binding` field should be a hash that contains information about the binding');
56
57 is($events[0]->{binding}->{input_type}, 'keyboard',
58 'the input_type field should be the input type of the binding (keyboard or mouse)');
59
60 note 'the `mods` field should contain the symbols for the modifiers of the binding';
61 foreach (@mods) {
62 ok(grep(/$_/i, @{$events[0]->{binding}->{mods}}), "`mods` contains the modifier $_");
63 }
64
65 is($events[0]->{binding}->{command}, $command,
66 'the `command` field should contain the command the binding ran');
67
68 is($events[0]->{binding}->{input_code}, 0,
69 'the input_code should be the specified code if the key was bound with bindcode, and otherwise zero');
70
71 exit_gracefully($pid);
72
73 }
74 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test _NET_CLOSE_WINDOW requests to close a window.
17 # See https://standards.freedesktop.org/wm-spec/wm-spec-latest.html#idm140200472668896
18 # Ticket: #1396
19 # Bug still in: 4.8-116-gbb1f857
20 use i3test;
21
22 sub send_close_window_request {
23 my ($win) = @_;
24
25 my $msg = pack "CCSLLLLLL",
26 X11::XCB::CLIENT_MESSAGE, # response_type
27 32, # format
28 0, # sequence
29 $win->id, # window
30 $x->atom(name => '_NET_CLOSE_WINDOW')->id, # message type
31 0, # data32[0]
32 0, # data32[1]
33 0, # data32[2]
34 0, # data32[3]
35 0; # data32[4]
36
37 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
38 }
39
40 my $ws = fresh_workspace;
41 my $win = open_window;
42
43 send_close_window_request($win);
44 sync_with_i3;
45
46 is(@{get_ws($ws)->{nodes}}, 0, 'When a pager sends a _NET_CLOSE_WINDOW request for a window, the container should be closed');
47
48 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests for the focus_on_window_activation directive
17 # Ticket: #1426
18 use i3test i3_autostart => 0;
19 use List::Util qw(first);
20
21 my ($config, $pid, $first, $second, $ws1, $ws2);
22
23 sub send_net_active_window {
24 my ($id) = @_;
25
26 my $msg = pack "CCSLLLLLLL",
27 X11::XCB::CLIENT_MESSAGE, # response_type
28 32, # format
29 0, # sequence
30 $id, # destination window
31 $x->atom(name => '_NET_ACTIVE_WINDOW')->id,
32 0, # source
33 0, 0, 0, 0;
34
35 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
36 }
37
38 sub get_urgency_for_window_on_workspace {
39 my ($ws, $con) = @_;
40
41 my $current = first { $_->{window} == $con->{id} } @{get_ws_content($ws)};
42 return $current->{urgent};
43 }
44
45 #####################################################################
46 # 1: If mode is set to 'urgent' and the target workspace is visible,
47 # check that the urgent flag is set and focus is not lost.
48 #####################################################################
49
50 $config = <<EOT;
51 # i3 config file (v4)
52 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
53
54 focus_on_window_activation urgent
55 EOT
56
57 $pid = launch_with_config($config);
58
59 my $ws = fresh_workspace;
60 $first = open_window;
61 $second = open_window;
62
63 send_net_active_window($first->id);
64 sync_with_i3;
65
66 is($x->input_focus, $second->id, 'second window is still focused');
67 is(get_urgency_for_window_on_workspace($ws, $first), 1, 'first window is marked urgent');
68
69 exit_gracefully($pid);
70
71 #####################################################################
72 # 2: If mode is set to 'urgent' and the target workspace is not
73 # visible, check that the urgent flag is set and focus is not lost.
74 #####################################################################
75
76 $config = <<EOT;
77 # i3 config file (v4)
78 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
79
80 focus_on_window_activation urgent
81 EOT
82
83 $pid = launch_with_config($config);
84
85 $ws1 = fresh_workspace;
86 $first = open_window;
87 $ws2 = fresh_workspace;
88 $second = open_window;
89
90 send_net_active_window($first->id);
91 sync_with_i3;
92
93 is(focused_ws(), $ws2, 'second workspace is still focused');
94 is($x->input_focus, $second->id, 'second window is still focused');
95 is(get_urgency_for_window_on_workspace($ws1, $first), 1, 'first window is marked urgent');
96
97 exit_gracefully($pid);
98
99 #####################################################################
100 # 3: If mode is set to 'focus' and the target workspace is visible,
101 # check that the focus is switched.
102 #####################################################################
103
104 $config = <<EOT;
105 # i3 config file (v4)
106 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
107
108 focus_on_window_activation focus
109 EOT
110
111 $pid = launch_with_config($config);
112
113 $ws = fresh_workspace;
114 $first = open_window;
115 $second = open_window;
116
117 send_net_active_window($first->id);
118 sync_with_i3;
119
120 is($x->input_focus, $first->id, 'first window is now focused');
121 ok(!get_urgency_for_window_on_workspace($ws, $first), 'first window is not marked urgent');
122
123 exit_gracefully($pid);
124
125 #####################################################################
126 # 4: If mode is set to 'focus' and the target workspace is not
127 # visible, check that the focus switched.
128 #####################################################################
129
130 $config = <<EOT;
131 # i3 config file (v4)
132 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
133
134 focus_on_window_activation focus
135 EOT
136
137 $pid = launch_with_config($config);
138
139 $ws1 = fresh_workspace;
140 $first = open_window;
141 $ws2 = fresh_workspace;
142 $second = open_window;
143
144 send_net_active_window($first->id);
145 sync_with_i3;
146
147 is(focused_ws(), $ws1, 'first workspace is now focused');
148 is($x->input_focus, $first->id, 'first window is now focused');
149 ok(!get_urgency_for_window_on_workspace($ws1, $first), 'first window is not marked urgent');
150
151 exit_gracefully($pid);
152
153 #####################################################################
154 # 5: If mode is set to 'none' and the target workspace is visible,
155 # check that nothing happens.
156 #####################################################################
157
158 $config = <<EOT;
159 # i3 config file (v4)
160 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
161
162 focus_on_window_activation none
163 EOT
164
165 $pid = launch_with_config($config);
166
167 $ws = fresh_workspace;
168 $first = open_window;
169 $second = open_window;
170
171 send_net_active_window($first->id);
172 sync_with_i3;
173
174 is($x->input_focus, $second->id, 'second window is still focused');
175 ok(!get_urgency_for_window_on_workspace($ws, $first), 'first window is not marked urgent');
176
177 exit_gracefully($pid);
178
179 #####################################################################
180 # 6: If mode is set to 'none' and the target workspace is not
181 # visible, check that nothing happens.
182 #####################################################################
183
184 $config = <<EOT;
185 # i3 config file (v4)
186 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
187
188 focus_on_window_activation none
189 EOT
190
191 $pid = launch_with_config($config);
192
193 $ws1 = fresh_workspace;
194 $first = open_window;
195 $ws2 = fresh_workspace;
196 $second = open_window;
197
198 send_net_active_window($first->id);
199 sync_with_i3;
200
201 is(focused_ws(), $ws2, 'second workspace is still focused');
202 is($x->input_focus, $second->id, 'second window is still focused');
203 ok(!get_urgency_for_window_on_workspace($ws1, $first), 'first window is not marked urgent');
204
205 exit_gracefully($pid);
206
207 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that most of i3's centering methods produce consistent results.
17 # Decorations are disabled to avoid floating_enable's logic which shifts
18 # windows upwards dependent on their decoration height.
19 #
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 new_window none
25 new_float none
26 EOT
27
28 #####################################################################
29 # Open a floating window, verifying that its initial position is
30 # centered, and also verify that both centering methods leave it in
31 # its original spot.
32 #####################################################################
33
34 my $first = open_floating_window;
35
36 my $initial = $first->rect;
37 is(int($initial->{x} + $initial->{width} / 2), int($x->root->rect->width / 2),
38 'x coordinates match');
39 is(int($initial->{y} + $initial->{height} / 2), int($x->root->rect->height / 2),
40 'y coordinates match');
41
42 cmd 'move position center';
43
44 my $new = $first->rect;
45 is($initial->{x}, $new->{x}, 'x coordinates match');
46 is($initial->{y}, $new->{y}, 'y coordinates match');
47
48 cmd 'move absolute position center';
49
50 $new = $first->rect;
51 is($initial->{x}, $new->{x}, 'x coordinates match');
52 is($initial->{y}, $new->{y}, 'y coordinates match');
53
54 #####################################################################
55 # Create a second window and move it into and out of the scratchpad.
56 # Because it hasn't been moved or resized, it should be floated in
57 # the center of the screen when pulled out of the scratchpad.
58 #####################################################################
59
60 my $second = open_window;
61
62 cmd 'move scratchpad, scratchpad show';
63
64 $new = $second->rect;
65 my $mid_init = $initial->{x} + int($initial->{width} / 2);
66 my $mid_new = $new->{x} + int($new->{width} / 2);
67 is($mid_init, $mid_new, 'x midpoint is ws center');
68
69 $mid_init = $initial->{y} + int($initial->{height} / 2);
70 $mid_new = $new->{y} + int($new->{height} / 2);
71 is($mid_init, $mid_new, 'y midpoint is ws center');
72
73 #####################################################################
74 # Verify that manually floating a tiled window results in proper
75 # centering.
76 #####################################################################
77
78 my $third = open_window;
79
80 cmd 'floating enable';
81
82 $new = $third->rect;
83 is($initial->{x}, $new->{x}, 'x coordinates match');
84 is($initial->{y}, $new->{y}, 'y coordinates match');
85
86 #####################################################################
87 # Create a child window of the previous window, which should result
88 # in the new window being centered over the last one.
89 #####################################################################
90
91 my $fourth = open_window( dont_map => 1, client_leader => $third );
92 $fourth->map;
93 sync_with_i3;
94
95 my $child = $fourth->rect;
96 is($new->{x}, $child->{x}, 'x coordinates match');
97 is($new->{y}, $child->{y}, 'y coordinates match');
98
99 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test the 'no_focus' directive.
17 # Ticket: #1416
18 use i3test i3_autostart => 0;
19
20 my ($config, $pid, $ws, $first, $second, $focused);
21
22 #####################################################################
23 # 1: open a window and check that it takes focus
24 #####################################################################
25
26 $config = <<EOT;
27 # i3 config file (v4)
28 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
29 EOT
30
31 $pid = launch_with_config($config);
32
33 $ws = fresh_workspace;
34 $first = open_window;
35 $focused = get_focused($ws);
36 $second = open_window;
37
38 sync_with_i3;
39 isnt(get_focused($ws), $focused, 'focus has changed');
40 is($x->input_focus, $second->id, 'input focus has changed');
41
42 exit_gracefully($pid);
43
44 #####################################################################
45 # 2: open a window matched by a no_focus directive and check that
46 # it doesn't take focus
47 #####################################################################
48
49 $config = <<EOT;
50 # i3 config file (v4)
51 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
52
53 no_focus [instance=notme]
54 EOT
55
56 $pid = launch_with_config($config);
57
58 $ws = fresh_workspace;
59 $first = open_window;
60 $focused = get_focused($ws);
61 $second = open_window(wm_class => 'notme');
62
63 sync_with_i3;
64 is(get_focused($ws), $focused, 'focus has not changed');
65 is($x->input_focus, $first->id, 'input focus has not changed');
66
67 exit_gracefully($pid);
68
69 #####################################################################
70 # 3: no_focus doesn't affect the first window opened on a workspace
71 #####################################################################
72
73 $config = <<EOT;
74 # i3 config file (v4)
75 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
76
77 no_focus [instance=focusme]
78 EOT
79
80 $pid = launch_with_config($config);
81
82 $ws = fresh_workspace;
83 $focused = get_focused($ws);
84 $first = open_window(wm_class => 'focusme');
85
86 sync_with_i3;
87 is($x->input_focus, $first->id, 'input focus has changed');
88
89 # Also check that it counts floating windows
90 # See issue #3423.
91 open_floating_window(wm_class => 'focusme');
92
93 sync_with_i3;
94 is($x->input_focus, $first->id, 'input focus didn\'t change to floating window');
95
96 exit_gracefully($pid);
97
98 #####################################################################
99
100 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests for the 'move [window|container] to mark' command
17 # Ticket: #1643
18 use i3test;
19
20 # In the following tests descriptions, we will always use the following names:
21 # * 'S' for the source container which is going to be moved,
22 # * 'M' for the marked target container to which 'S' will be moved.
23
24 my ($A, $B, $S, $M, $F, $source_ws, $target_ws, $ws);
25 my ($nodes, $focus);
26 my $__i3_scratch;
27 my $cmd_result;
28
29 my $_NET_WM_STATE_REMOVE = 0;
30 my $_NET_WM_STATE_ADD = 1;
31 my $_NET_WM_STATE_TOGGLE = 2;
32
33 sub set_urgency {
34 my ($win, $urgent_flag) = @_;
35 my $msg = pack "CCSLLLLLL",
36 X11::XCB::CLIENT_MESSAGE, # response_type
37 32, # format
38 0, # sequence
39 $win->id, # window
40 $x->atom(name => '_NET_WM_STATE')->id, # message type
41 ($urgent_flag ? $_NET_WM_STATE_ADD : $_NET_WM_STATE_REMOVE), # data32[0]
42 $x->atom(name => '_NET_WM_STATE_DEMANDS_ATTENTION')->id, # data32[1]
43 0, # data32[2]
44 0, # data32[3]
45 0; # data32[4]
46
47 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
48 }
49
50 ###############################################################################
51 # Given 'M' and 'S' in a horizontal split, when 'S' is moved to 'M', then
52 # verify that nothing changed.
53 ###############################################################################
54
55 $ws = fresh_workspace;
56 $M = open_window;
57 cmd 'mark target';
58 $S = open_window;
59
60 cmd 'move container to mark target';
61 sync_with_i3;
62
63 ($nodes, $focus) = get_ws_content($ws);
64 is(@{$nodes}, 2, 'there are two containers');
65 is($nodes->[0]->{window}, $M->{id}, 'M is left of S');
66 is($nodes->[1]->{window}, $S->{id}, 'S is right of M');
67
68 ###############################################################################
69 # Given 'S' and 'M' in a horizontal split, when 'S' is moved to 'M', then
70 # both containers switch places.
71 ###############################################################################
72
73 $ws = fresh_workspace;
74 $S = open_window;
75 $M = open_window;
76 cmd 'mark target';
77 cmd 'focus left';
78
79 cmd 'move container to mark target';
80 sync_with_i3;
81
82 ($nodes, $focus) = get_ws_content($ws);
83 is(@{$nodes}, 2, 'there are two containers');
84 is($nodes->[0]->{window}, $M->{id}, 'M is left of S');
85 is($nodes->[1]->{window}, $S->{id}, 'S is right of M');
86
87 ###############################################################################
88 # Given 'S' and no container 'M' exists, when 'S' is moved to 'M', then
89 # the command is unsuccessful.
90 ###############################################################################
91
92 $ws = fresh_workspace;
93 $S = open_window;
94
95 $cmd_result = cmd 'move container to mark absent';
96
97 is($cmd_result->[0]->{success}, 0, 'command was unsuccessful');
98
99 ###############################################################################
100 # Given 'S' and 'M' on different workspaces, when 'S' is moved to 'M', then
101 # 'S' ends up on the same workspace as 'M'.
102 ###############################################################################
103
104 $source_ws = fresh_workspace;
105 $S = open_window;
106 $target_ws = fresh_workspace;
107 $M = open_window;
108 cmd 'mark target';
109
110 cmd '[id="' . $S->{id} . '"] move container to mark target';
111 sync_with_i3;
112
113 ($nodes, $focus) = get_ws_content($source_ws);
114 is(@{$nodes}, 0, 'source workspace is empty');
115
116 ($nodes, $focus) = get_ws_content($target_ws);
117 is(@{$nodes}, 2, 'both containers are on the target workspace');
118 is($nodes->[0]->{window}, $M->{id}, 'M is left of S');
119 is($nodes->[1]->{window}, $S->{id}, 'S is right of M');
120
121 ###############################################################################
122 # Given 'S' and 'M' on different workspaces and 'S' is urgent, when 'S' is
123 # moved to 'M', then the urgency flag is transferred to the target workspace.
124 ###############################################################################
125
126 $source_ws = fresh_workspace;
127 $S = open_window;
128 $F = open_window;
129 $target_ws = fresh_workspace;
130 $M = open_window;
131 cmd 'mark target';
132 cmd 'workspace ' . $source_ws;
133 set_urgency($S, 1);
134
135 cmd '[id="' . $S->{id} . '"] move container to mark target';
136 sync_with_i3;
137
138 $source_ws = get_ws($source_ws);
139 $target_ws = get_ws($target_ws);
140 ok(!$source_ws->{urgent}, 'source workspace is no longer urgent');
141 ok($target_ws->{urgent}, 'target workspace is urgent');
142
143 ###############################################################################
144 # Given 'S' and 'M' where 'M' is inside a tabbed container, when 'S' is moved
145 # to 'M', then 'S' ends up as a new tab.
146 ###############################################################################
147
148 $source_ws = fresh_workspace;
149 $S = open_window;
150
151 # open tabbed container ['A' 'M' 'B']
152 $target_ws = fresh_workspace;
153 $A = open_window;
154 cmd 'layout tabbed';
155 $M = open_window;
156 cmd 'mark target';
157 $B = open_window;
158
159 cmd '[id="' . $S->{id} . '"] move container to mark target';
160 sync_with_i3;
161
162 ($nodes, $focus) = get_ws_content($target_ws);
163 is(@{$nodes}, 1, 'there is a tabbed container');
164
165 $nodes = $nodes->[0]->{nodes};
166 is(@{$nodes}, 4, 'all four containers are on the target workspace');
167 is($nodes->[0]->{window}, $A->{id}, 'A is the first tab');
168 is($nodes->[1]->{window}, $M->{id}, 'M is the second tab');
169 is($nodes->[2]->{window}, $S->{id}, 'S is the third tab');
170 is($nodes->[3]->{window}, $B->{id}, 'B is the fourth tab');
171
172 ###############################################################################
173 # Given 'S' and 'M' where 'M' is a tabbed container where the currently focused
174 # tab is a nested layout, when 'S' is moved to 'M', then 'S' is a new tab
175 # within 'M'.
176 ###############################################################################
177
178 $source_ws = fresh_workspace;
179 $S = open_window;
180
181 $target_ws = fresh_workspace;
182 $A = open_window;
183 cmd 'layout tabbed';
184 cmd 'focus parent';
185 cmd 'mark target';
186 cmd 'focus child';
187 $B = open_window;
188 cmd 'split h';
189 $F = open_window;
190
191 cmd '[id="' . $S->{id} . '"] move container to mark target';
192 sync_with_i3;
193
194 ($nodes, $focus) = get_ws_content($target_ws);
195 is(@{$nodes}, 1, 'there is a tabbed container');
196
197 $nodes = $nodes->[0]->{nodes};
198 is(@{$nodes}, 3, 'there are three tabs');
199
200 is($nodes->[0]->{window}, $A->{id}, 'A is the first tab');
201 is($nodes->[2]->{window}, $S->{id}, 'S is the third tab');
202
203 ###############################################################################
204 # Given 'S' and 'M' where 'M' is inside a split container inside a tabbed
205 # container, when 'S' is moved to 'M', then 'S' ends up as a container
206 # within the same tab as 'M'.
207 ###############################################################################
208
209 $source_ws = fresh_workspace;
210 $S = open_window;
211
212 # open tabbed container ['A'['B' 'M']]
213 $target_ws = fresh_workspace;
214 $A = open_window;
215 cmd 'layout tabbed';
216 $B = open_window;
217 cmd 'split h';
218 $M = open_window;
219 cmd 'mark target';
220
221 cmd '[id="' . $S->{id} . '"] move container to mark target';
222 sync_with_i3;
223
224 ($nodes, $focus) = get_ws_content($target_ws);
225 is(@{$nodes}, 1, 'there is a tabbed container');
226
227 $nodes = $nodes->[0]->{nodes};
228 is(@{$nodes}, 2, 'there are two tabs');
229
230 $nodes = $nodes->[1]->{nodes};
231 is(@{$nodes}, 3, 'the tab with the marked children has three children');
232 is($nodes->[0]->{window}, $B->{id}, 'B is the first tab');
233 is($nodes->[1]->{window}, $M->{id}, 'M is the second tab');
234 is($nodes->[2]->{window}, $S->{id}, 'S is the third tab');
235
236 ###############################################################################
237 # Given 'S', 'A' and 'B' where 'A' and 'B' are inside the tabbed container 'M',
238 # when 'S' is moved to 'M', then 'S' ends up as a new tab in 'M'.
239 ###############################################################################
240
241 $source_ws = fresh_workspace;
242 $S = open_window;
243 $target_ws = fresh_workspace;
244 $A = open_window;
245 cmd 'layout tabbed';
246 $B = open_window;
247 cmd 'focus parent';
248 cmd 'mark target';
249 cmd 'focus child';
250
251 cmd '[id="' . $S->{id} . '"] move container to mark target';
252 sync_with_i3;
253
254 ($nodes, $focus) = get_ws_content($target_ws);
255 is(@{$nodes}, 1, 'there is a tabbed container');
256
257 $nodes = $nodes->[0]->{nodes};
258 is(@{$nodes}, 3, 'there are three tabs');
259
260 is($nodes->[0]->{window}, $A->{id}, 'A is the first tab');
261 is($nodes->[1]->{window}, $B->{id}, 'B is the second tab');
262 is($nodes->[2]->{window}, $S->{id}, 'S is the third tab');
263
264 ###############################################################################
265 # Given 'S', 'A', 'F' and 'M', where 'M' is a workspace containing a tabbed
266 # container, when 'S' is moved to 'M', then 'S' does not end up as a tab, but
267 # rather as a new window next to the tabbed container.
268 ###############################################################################
269
270 $source_ws = fresh_workspace;
271 $S = open_window;
272 $target_ws = fresh_workspace;
273 $A = open_window;
274 cmd 'layout tabbed';
275 $F = open_window;
276 $M = $target_ws;
277 cmd 'focus parent';
278 cmd 'focus parent';
279 cmd 'mark target';
280 cmd 'focus ' . $source_ws;
281
282 cmd '[id="' . $S->{id} . '"] move container to mark target';
283 sync_with_i3;
284
285 ($nodes, $focus) = get_ws_content($target_ws);
286 is(@{$nodes}, 2, 'there is a tabbed container and a window');
287 is($nodes->[1]->{window}, $S->{id}, 'S is the second window');
288
289 ###############################################################################
290 # Given 'S' and 'M' where 'S' is floating and 'M' on a different workspace,
291 # when 'S' is moved to 'M', then 'S' is a floating container on the same
292 # workspaces as 'M'.
293 ###############################################################################
294
295 $source_ws = fresh_workspace;
296 $S = open_floating_window;
297 $target_ws = fresh_workspace;
298 $M = open_window;
299 cmd 'mark target';
300
301 cmd '[id="' . $S->{id} . '"] move container to mark target';
302 sync_with_i3;
303
304 is(@{get_ws($target_ws)->{floating_nodes}}, 1, 'target workspace has the container now');
305
306 ###############################################################################
307 # Given 'S' and 'M' where 'M' is floating and on a different workspace,
308 # when 'S' is moved to 'M', then 'S' ends up as a tiling container on the
309 # same workspace as 'M'.
310 ###############################################################################
311
312 $source_ws = fresh_workspace;
313 $S = open_window;
314 $target_ws = fresh_workspace;
315 $M = open_floating_window;
316 cmd 'mark target';
317
318 cmd '[id="' . $S->{id} . '"] move container to mark target';
319 sync_with_i3;
320
321 ($nodes, $focus) = get_ws_content($target_ws);
322 is(@{$nodes}, 1, 'tiling container moved to the target workspace');
323
324 ###############################################################################
325 # Given 'S' and 'M' where 'M' is inside a floating container but not its direct
326 # child, when 'S' is moved to 'M', i3 should not crash.
327 # See issue: #3402
328 ###############################################################################
329
330 $target_ws = fresh_workspace;
331 $S = open_window;
332 open_window;
333 cmd 'splitv';
334 $M = open_window;
335 cmd 'mark target';
336 cmd 'focus parent, floating enable, focus child';
337
338 cmd '[id="' . $S->{id} . '"] move container to mark target';
339 does_i3_live;
340
341 # Note: this is not actively supported behavior.
342 $nodes = get_ws($target_ws)->{floating_nodes}->[0]->{nodes}->[0]->{nodes};
343 is(1, (grep { $_->{window} == $S->{id} } @{$nodes}), 'tiling container moved inside floating container');
344
345 ###############################################################################
346 # Given 'S' and 'M' are the same container, when 'S' is moved to 'M', then
347 # the command is ignored.
348 ###############################################################################
349
350 $ws = fresh_workspace;
351 $S = open_window;
352 $M = $S;
353 cmd 'mark target';
354
355 cmd '[id="' . $S->{id} . '"] move container to mark target';
356 sync_with_i3;
357
358 does_i3_live;
359
360 ###############################################################################
361 # Given 'S' and 'M' where 'M' is a workspace and 'S' is on a different
362 # workspace, then 'S' ends up as a tiling container on 'M'.
363 # See issue: #2003
364 ###############################################################################
365
366 fresh_workspace;
367 $S = open_window;
368 $target_ws = fresh_workspace;
369 $M = $target_ws;
370 cmd 'mark target';
371
372 cmd '[id="' . $S->{id} . '"] move container to mark target';
373 sync_with_i3;
374
375 does_i3_live;
376
377 ($nodes, $focus) = get_ws_content($target_ws);
378 is(@{$nodes}, 1, 'tiling container moved to the target workspace');
379
380 ###############################################################################
381 # Given 'S' and 'M' where 'S' is a workspace and 'M' is a container on a
382 # different workspace, then all the contents of workspace 'S' end up in 'M's
383 # workspace.
384 ###############################################################################
385
386 $S = fresh_workspace;
387 cmd 'mark S';
388 open_window;
389 open_window;
390 cmd 'splitv';
391 open_window;
392 open_floating_window;
393 $target_ws = fresh_workspace;
394 $M = open_window;
395 cmd 'mark target';
396
397 cmd '[con_mark=S] move container to mark target';
398 sync_with_i3;
399
400 ($nodes, $focus) = get_ws_content($target_ws);
401 is(@{$nodes}, 2, 'there is a window and a container with the contents of the original workspace');
402 is($nodes->[0]->{window}, $M->{id}, 'M remains the first window');
403 is(@{get_ws($target_ws)->{floating_nodes}}, 1, 'target workspace has the floating container');
404
405 ###############################################################################
406 # Given 'S' and 'M', where 'S' is a container and 'M' is a container hidden in
407 # the scratchpad, then move 'S' to the scratchpad
408 ###############################################################################
409
410 $ws = fresh_workspace;
411 $S = open_window;
412 cmd 'mark S';
413 $M = open_window;
414 cmd 'mark target';
415 cmd 'move container to scratchpad';
416
417 cmd '[con_mark=S] move container to mark target';
418 sync_with_i3;
419
420 ($nodes, $focus) = get_ws_content($ws);
421 is(@{$nodes}, 0, 'there are no tiling windows on the workspace');
422 is(@{get_ws($ws)->{floating_nodes}}, 0, 'there are no floating containers on the workspace');
423
424 $__i3_scratch = get_ws('__i3_scratch');
425 is(@{$__i3_scratch->{nodes}}, 0, 'there are no tiling windows on the scratchpad workspace');
426 is(@{$__i3_scratch->{floating_nodes}}, 2, 'there are two floating containers in the scratchpad');
427
428 ###############################################################################
429
430 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Ensures that 'move workspace $new, floating enable' on a marked window
17 # leaves the window centered on the new workspace.
18 # Bug still in: 4.10.2-137-ga4f0ed6
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 new_window none
24 new_float none
25 EOT
26
27 #####################################################################
28 # Open a tiled window, and then simultaneously move it to another
29 # workspace and float it, ensuring that it ends up centered.
30 #####################################################################
31
32 my $window = open_window;
33 my $unused = get_unused_workspace();
34
35 cmd "mark foo; [con_mark=\"foo\"] move workspace $unused, floating enable";
36
37 sync_with_i3;
38
39 my $pos = $window->rect;
40
41 is(int($pos->{x} + $pos->{width} / 2), int($x->root->rect->width / 2),
42 'x coordinates match');
43 is(int($pos->{y} + $pos->{height} / 2), int($x->root->rect->height / 2),
44 'y coordinates match');
45
46 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests the 'move [window|container] [to] position mouse|cursor|pointer command.
17 # Ticket: #1696
18 use i3test i3_autostart => 0;
19 use POSIX qw(floor);
20
21 sub warp_pointer {
22 my ($pos_x, $pos_y) = @_;
23 $x->root->warp_pointer($pos_x, $pos_y);
24 sync_with_i3;
25 }
26
27 my ($pid, $config, $ws, $rect, @cons);
28 my $root_rect = $x->root->rect;
29
30 ##########################################################################
31
32 ##########################################################################
33 # Given a floating container and the cursor far from any edges, when
34 # moving the container to the mouse, then the container is moved such
35 # that the cursor is centered inside it.
36 ##########################################################################
37
38 $config = <<EOT;
39 # i3 config file (v4)
40 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
41 EOT
42 $pid = launch_with_config($config);
43
44 $ws = fresh_workspace;
45 open_floating_window;
46 warp_pointer(100, 100);
47
48 cmd 'move position mouse';
49
50 @cons = @{get_ws($ws)->{floating_nodes}};
51 $rect = $cons[0]->{rect};
52
53 is(floor($rect->{x} + $rect->{width} / 2), 100, "con is centered around cursor horizontally");
54 is(floor($rect->{y} + $rect->{height} / 2), 100, "con is centered around cursor vertically");
55
56 exit_gracefully($pid);
57
58 ##########################################################################
59 # Given a floating container and the cursor is in the left upper edge
60 # of the output, when moving the container to the mouse, then the
61 # container is moved but adjusted to stay in-bounds.
62 ##########################################################################
63
64 $config = <<EOT;
65 # i3 config file (v4)
66 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
67 EOT
68 $pid = launch_with_config($config);
69
70 $ws = fresh_workspace;
71 open_floating_window;
72 warp_pointer(5, 5);
73
74 cmd 'move position mouse';
75
76 @cons = @{get_ws($ws)->{floating_nodes}};
77 $rect = $cons[0]->{rect};
78
79 is($rect->{x}, 0, "con is on the left edge");
80 is($rect->{y}, 0, "con is on the upper edge");
81
82 exit_gracefully($pid);
83
84 ##########################################################################
85 # Given a floating container and the cursor is in the left right lower
86 # edge of the output, when moving the container to the mouse, then the
87 # container is moved but adjusted to stay in-bounds.
88 ##########################################################################
89
90 $config = <<EOT;
91 # i3 config file (v4)
92 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
93 EOT
94 $pid = launch_with_config($config);
95
96 $ws = fresh_workspace;
97 open_floating_window;
98 warp_pointer($root_rect->width - 5, $root_rect->height - 5);
99
100 cmd 'move position mouse';
101
102 @cons = @{get_ws($ws)->{floating_nodes}};
103 $rect = $cons[0]->{rect};
104
105 is($rect->{x} + $rect->{width}, $root_rect->width, "con is on the right edge");
106 is($rect->{y} + $rect->{height}, $root_rect->height, "con is on the lower edge");
107
108 exit_gracefully($pid);
109
110 ##########################################################################
111 # Given a floating container and the cursor being close to the corner of
112 # an output, when the container is moved to the mouse, then the container
113 # is moved but adjusted to the output boundaries.
114 # This test verifies that boundaries of individual outputs are respected
115 # and not just boundaries of the entire X root screen.
116 ##########################################################################
117
118 $config = <<EOT;
119 # i3 config file (v4)
120 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
121 fake-outputs 500x500+0+0,500x500+500+0,500x500+0+500,500x500+500+500
122 EOT
123 $pid = launch_with_config($config);
124
125 $ws = fresh_workspace;
126 open_floating_window;
127 warp_pointer(495, 495);
128
129 cmd 'move position mouse';
130
131 @cons = @{get_ws($ws)->{floating_nodes}};
132 $rect = $cons[0]->{rect};
133
134 is($rect->{x} + $rect->{width}, 500, "con is on the right edge");
135 is($rect->{y} + $rect->{height}, 500, "con is on the lower edge");
136
137 exit_gracefully($pid);
138
139 ##########################################################################
140
141 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Ensure that hovering over the window decoration of a window causes it to focus
17 # correctly.
18 # Ticket: #1056
19 # Bug still in: 4.10.2-174-g8029ff0
20 use i3test;
21
22 my ($ws, $A, $B, $C, $target, $y);
23 my @cons;
24
25 # ==================================================================================
26 # Given the following layout (= denotes the window decoration),
27 # when moving the mouse from 1 to 2,
28 # then the C should be focused.
29 #
30 # This should especially be the case if B is the focus head of its vertically split parent container.
31 #
32 # +===A===+===B===+
33 # | | |
34 # | 1 +=2=C===+
35 # | | |
36 # +-------+-------+
37 #
38 # ==================================================================================
39
40 $ws = fresh_workspace;
41
42 open_window;
43 $B = open_window;
44 cmd 'split v';
45 open_window;
46 $target = get_focused($ws);
47
48 @cons = @{get_ws($ws)->{nodes}};
49 $A = $cons[0];
50 $C = $cons[1]->{nodes}[1];
51
52 $y = $C->{rect}->{y} - 0.5 * $C->{deco_rect}->{height};
53
54 # make sure that B is the focus head of its parent
55 cmd '[id="' . $B->{id} . '"] focus';
56
57 # move pointer to position 1
58 $x->root->warp_pointer($C->{rect}->{x} - 0.5 * $A->{rect}->{width}, $y);
59 sync_with_i3;
60
61 # move pointer to position 2
62 $x->root->warp_pointer($C->{rect}->{x} + 0.5 * $C->{rect}->{width}, $y);
63 sync_with_i3;
64
65 is(get_focused($ws), $target, 'focus switched to container C');
66
67 # ==================================================================================
68 # Given a tabbed container when the mouse is moved onto the window decoration
69 # then the focus head of the tabbed container is focused regardless of which particular
70 # tab's decoration the mouse is on.
71 #
72 # +=========+=========+
73 # | | |
74 # | 1 +=2==|****| <- tab to the right is focus head of tabbed container
75 # | | |
76 # +---------+---------+
77 #
78 # ==================================================================================
79
80 $ws = fresh_workspace;
81
82 open_window;
83 open_window;
84 cmd 'split v';
85 open_window;
86 cmd 'split h';
87 open_window;
88 $target = get_focused($ws);
89 cmd 'layout tabbed';
90
91 @cons = @{get_ws($ws)->{nodes}};
92 $A = $cons[0];
93 $B = $cons[1]->{nodes}[1]->{nodes}[1];
94
95 $y = $B->{rect}->{y} - 0.5 * $B->{deco_rect}->{height};
96
97 $x->root->warp_pointer($B->{rect}->{x} - 0.5 * $A->{rect}->{width}, $y);
98 sync_with_i3;
99
100 $x->root->warp_pointer($B->{rect}->{x} + 0.2 * $B->{rect}->{width}, $y);
101 sync_with_i3;
102
103 is(get_focused($ws), $target, 'focus switched to the focus head of the tabbed container');
104
105 # ==================================================================================
106 # Given a stacked container when the mouse is moved onto the window decoration
107 # then the focus head of the stacked container is focused regardless of which particular
108 # tab's decoration the mouse is on.
109 #
110 # +=========+=========+
111 # | | |
112 # | 1 +=2=======+
113 # | +*********+ <- the lower tab is the focus head of the stacked container
114 # | | |
115 # +---------+---------+
116 #
117 # ==================================================================================
118
119 $ws = fresh_workspace;
120
121 open_window;
122 open_window;
123 cmd 'split v';
124 open_window;
125 cmd 'split h';
126 open_window;
127 $target = get_focused($ws);
128 cmd 'layout stacked';
129
130 @cons = @{get_ws($ws)->{nodes}};
131 $A = $cons[0];
132 $B = $cons[1]->{nodes}[1]->{nodes}[0];
133 $C = $cons[1]->{nodes}[1]->{nodes}[1];
134
135 $y = $B->{rect}->{y} - 1.5 * $B->{deco_rect}->{height};
136
137 $x->root->warp_pointer($B->{rect}->{x} - 0.5 * $A->{rect}->{width}, $y);
138 sync_with_i3;
139
140 $x->root->warp_pointer($B->{rect}->{x} + 0.5 * $B->{rect}->{width}, $y);
141 sync_with_i3;
142
143 is(get_focused($ws), $target, 'focus switched to the focus head of the stacked container');
144
145 # ==================================================================================
146
147 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Checks that the line continuation are parsed correctly
17 #
18
19 use i3test i3_autostart => 0;
20
21 # starts i3 with the given config, opens a window, returns its border style
22 sub launch_get_border {
23 my ($config) = @_;
24
25 my $pid = launch_with_config($config);
26
27 my $i3 = i3(get_socket_path(0));
28 my $tmp = fresh_workspace;
29
30 my $window = open_window(name => '"special title"');
31
32 my @content = @{get_ws_content($tmp)};
33 cmp_ok(@content, '==', 1, 'one node on this workspace now');
34 my $border = $content[0]->{border};
35
36 exit_gracefully($pid);
37
38 return $border;
39 }
40
41 #####################################################################
42 # test string escaping
43 #####################################################################
44
45 my $config = <<'EOT';
46 # i3 config file (v4)
47 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
48
49 set $vartest \"special title\"
50 for_window [title="$vartest"] border none
51 EOT
52
53 is(launch_get_border($config), 'none', 'no border');
54
55 #####################################################################
56 # test the line continuation
57 #####################################################################
58
59 $config = <<'EOT';
60 # i3 config file (v4)
61 font \
62 -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
63
64 # Use line contiuation with too many lines (>4096 characters).
65 # This config is invalid. Use it to ensure no buffer overflow.
66 bindsym Mod1+b \
67 0001-This is a very very very very very very very very very very very very very very very very very long cmd \
68 0002-This is a very very very very very very very very very very very very very very very very very long cmd \
69 0003-This is a very very very very very very very very very very very very very very very very very long cmd \
70 0004-This is a very very very very very very very very very very very very very very very very very long cmd \
71 0005-This is a very very very very very very very very very very very very very very very very very long cmd \
72 0006-This is a very very very very very very very very very very very very very very very very very long cmd \
73 0007-This is a very very very very very very very very very very very very very very very very very long cmd \
74 0008-This is a very very very very very very very very very very very very very very very very very long cmd \
75 0009-This is a very very very very very very very very very very very very very very very very very long cmd \
76 0010-This is a very very very very very very very very very very very very very very very very very long cmd \
77 0011-This is a very very very very very very very very very very very very very very very very very long cmd \
78 0012-This is a very very very very very very very very very very very very very very very very very long cmd \
79 0013-This is a very very very very very very very very very very very very very very very very very long cmd \
80 0014-This is a very very very very very very very very very very very very very very very very very long cmd \
81 0015-This is a very very very very very very very very very very very very very very very very very long cmd \
82 0016-This is a very very very very very very very very very very very very very very very very very long cmd \
83 0017-This is a very very very very very very very very very very very very very very very very very long cmd \
84 0018-This is a very very very very very very very very very very very very very very very very very long cmd \
85 0019-This is a very very very very very very very very very very very very very very very very very long cmd \
86 0020-This is a very very very very very very very very very very very very very very very very very long cmd \
87 0021-This is a very very very very very very very very very very very very very very very very very long cmd \
88 0022-This is a very very very very very very very very very very very very very very very very very long cmd \
89 0023-This is a very very very very very very very very very very very very very very very very very long cmd \
90 0024-This is a very very very very very very very very very very very very very very very very very long cmd \
91 0025-This is a very very very very very very very very very very very very very very very very very long cmd \
92 0026-This is a very very very very very very very very very very very very very very very very very long cmd \
93 0027-This is a very very very very very very very very very very very very very very very very very long cmd \
94 0028-This is a very very very very very very very very very very very very very very very very very long cmd \
95 0029-This is a very very very very very very very very very very very very very very very very very long cmd \
96 0030-This is a very very very very very very very very very very very very very very very very very long cmd \
97 0031-This is a very very very very very very very very very very very very very very very very very long cmd \
98 0032-This is a very very very very very very very very very very very very very very very very very long cmd \
99 0033-This is a very very very very very very very very very very very very very very very very very long cmd \
100 0034-This is a very very very very very very very very very very very very very very very very very long cmd \
101 0035-This is a very very very very very very very very very very very very very very very very very long cmd \
102 0036-This is a very very very very very very very very very very very very very very very very very long cmd \
103 0037-This is a very very very very very very very very very very very very very very very very very long cmd \
104 0038-This is a very very very very very very very very very very very very very very very very very long cmd \
105 0039-This is a very very very very very very very very very very very very very very very very very long cmd \
106 0040-This is a very very very very very very very very very very very very very very very very very long cmd \
107 0041-This is a very very very very very very very very very very very very very very very very very long cmd \
108 0042-This is a very very very very very very very very very very very very very very very very very long cmd \
109 0043-This is a very very very very very very very very very very very very very very very very very long cmd \
110 0044-This is a very very very very very very very very very very very very very very very very very long cmd \
111 0045-This is a very very very very very very very very very very very very very very very very very long cmd \
112 0046-This is a very very very very very very very very very very very very very very very very very long cmd \
113 0047-This is a very very very very very very very very very very very very very very very very very long cmd \
114 0048-This is a very very very very very very very very very very very very very very very very very long cmd \
115 0049-This is a very very very very very very very very very very very very very very very very very long cmd \
116 0050-This is a very very very very very very very very very very very very very very very very very long cmd \
117 0051-This is a very very very very very very very very very very very very very very very very very long cmd \
118 0052-This is a very very very very very very very very very very very very very very very very very long cmd \
119 0053-This is a very very very very very very very very very very very very very very very very very long cmd \
120 0054-This is a very very very very very very very very very very very very very very very very very long cmd \
121 0055-This is a very very very very very very very very very very very very very very very very very long cmd \
122 0056-This is a very very very very very very very very very very very very very very very very very long cmd \
123 0057-This is a very very very very very very very very very very very very very very very very very long cmd \
124 0058-This is a very very very very very very very very very very very very very very very very very long cmd \
125 0059-This is a very very very very very very very very very very very very very very very very very long cmd \
126 0060-This is a very very very very very very very very very very very very very very very very very long cmd \
127 0061-This is a very very very very very very very very very very very very very very very very very long cmd \
128 0062-This is a very very very very very very very very very very very very very very very very very long cmd \
129 0063-This is a very very very very very very very very very very very very very very very very very long cmd \
130 0064-This is a very very very very very very very very very very very very very very very very very long cmd \
131 0065-This is a very very very very very very very very very very very very very very very very very long cmd \
132 0066-This is a very very very very very very very very very very very very very very very very very long cmd \
133 0067-This is a very very very very very very very very very very very very very very very very very long cmd \
134 0068-This is a very very very very very very very very very very very very very very very very very long cmd \
135 0069-This is a very very very very very very very very very very very very very very very very very long cmd \
136 0070-This is a very very very very very very very very very very very very very very very very very long cmd \
137 0071-This is a very very very very very very very very very very very very very very very very very long cmd \
138 0072-This is a very very very very very very very very very very very very very very very very very long cmd \
139 0073-This is a very very very very very very very very very very very very very very very very very long cmd \
140 0074-This is a very very very very very very very very very very very very very very very very very long cmd \
141 0075-This is a very very very very very very very very very very very very very very very very very long cmd \
142 0076-This is a very very very very very very very very very very very very very very very very very long cmd \
143 0077-This is a very very very very very very very very very very very very very very very very very long cmd \
144 0078-This is a very very very very very very very very very very very very very very very very very long cmd \
145 0079-This is a very very very very very very very very very very very very very very very very very long cmd \
146 0080-This is a very very very very very very very very very very very very very very very very very long cmd \
147 0081-This is a very very very very very very very very very very very very very very very very very long cmd \
148 0082-This is a very very very very very very very very very very very very very very very very very long cmd \
149 0083-This is a very very very very very very very very very very very very very very very very very long cmd \
150 0084-This is a very very very very very very very very very very very very very very very very very long cmd \
151 0085-This is a very very very very very very very very very very very very very very very very very long cmd \
152 0086-This is a very very very very very very very very very very very very very very very very very long cmd \
153 0087-This is a very very very very very very very very very very very very very very very very very long cmd \
154 0088-This is a very very very very very very very very very very very very very very very very very long cmd \
155 0089-This is a very very very very very very very very very very very very very very very very very long cmd \
156 0090-This is a very very very very very very very very very very very very very very very very very long cmd \
157 0091-This is a very very very very very very very very very very very very very very very very very long cmd \
158 0092-This is a very very very very very very very very very very very very very very very very very long cmd \
159 0093-This is a very very very very very very very very very very very very very very very very very long cmd \
160 0094-This is a very very very very very very very very very very very very very very very very very long cmd \
161 0095-This is a very very very very very very very very very very very very very very very very very long cmd \
162 0096-This is a very very very very very very very very very very very very very very very very very long cmd \
163 0097-This is a very very very very very very very very very very very very very very very very very long cmd \
164 0098-This is a very very very very very very very very very very very very very very very very very long cmd \
165 0099-This is a very very very very very very very very very very very very very very very very very long cmd
166
167 # Use line continuation for variables
168 set \
169 $vartest \
170 \"special title\"
171
172 # Use line continuation for commands
173 for_window \
174 [title="$vartest"] \
175 border \
176 none
177
178 EOT
179
180 is(launch_get_border($config), 'none', 'no border');
181
182 #####################################################################
183 # test the line continuation within a string
184 #####################################################################
185
186 $config = <<'EOT';
187 # i3 config file (v4)
188 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
189
190 set \
191 $vartest \
192 \"special \
193 title\"
194 for_window [title="$vartest"] border none
195 EOT
196
197 is(launch_get_border($config), 'none', 'no border');
198
199
200 #####################################################################
201 # test ignoring of line continuation within a comment
202 #####################################################################
203
204 $config = <<'EOT';
205 # i3 config file (v4)
206 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
207
208 set $vartest \"special title\"
209 for_window [title="$vartest"] border pixel 1
210 # this line is not continued, so the following is not contained in this comment\
211 for_window [title="$vartest"] border none
212 EOT
213
214 is(launch_get_border($config), 'none', 'no border');
215
216 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Ensures the urgency hint is cleared properly in the case where i3 set it (due
17 # to focus_on_window_activation=urgent), hence the application not clearing it.
18 # Ticket: #1825
19 # Bug still in: 4.10.3-253-g03799dd
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 focus_on_window_activation urgent
25 EOT
26
27 sub send_net_active_window {
28 my ($id) = @_;
29
30 my $msg = pack "CCSLLLLLLL",
31 X11::XCB::CLIENT_MESSAGE, # response_type
32 32, # format
33 0, # sequence
34 $id, # destination window
35 $x->atom(name => '_NET_ACTIVE_WINDOW')->id,
36 0, # source
37 0, 0, 0, 0;
38
39 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
40 }
41
42 my $ws = fresh_workspace;
43 my $first = open_window;
44 my $second = open_window;
45
46 send_net_active_window($first->id);
47 sync_with_i3;
48 is($x->input_focus, $second->id, 'second window still focused');
49
50 cmd '[urgent=latest] focus';
51 sync_with_i3;
52 is($x->input_focus, $first->id, 'first window focused');
53
54 cmd 'focus right';
55 sync_with_i3;
56 is($x->input_focus, $second->id, 'second window focused again');
57
58 cmd '[urgent=latest] focus';
59 sync_with_i3;
60 is($x->input_focus, $second->id, 'second window still focused');
61
62 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies floating containers are restored in the correct place in the
17 # hierarchy and get a non-zero size.
18 # Ticket: #1739
19 # Bug still in: 4.10.3-264-g419b73b
20 use i3test;
21 use File::Temp qw(tempfile);
22 use IO::Handle;
23
24 my $ws = fresh_workspace;
25
26 my @content = @{get_ws_content($ws)};
27 is(@content, 0, 'no nodes on the new workspace yet');
28
29 my ($fh, $filename) = tempfile(UNLINK => 1);
30 print $fh <<'EOT';
31 // vim:ts=4:sw=4:et
32 {
33 // floating_con with 1 children
34 "border": "none",
35 "floating": "auto_off",
36 "layout": "splith",
37 "percent": null,
38 "type": "floating_con",
39 // NOTE that "rect" is missing here.
40 "nodes": [
41 {
42 "border": "none",
43 "current_border_width": 0,
44 "floating": "user_on",
45 "geometry": {
46 "height": 384,
47 "width": 128,
48 "x": 448,
49 "y": 441
50 },
51 "name": "Splash",
52 "percent": 1,
53 "swallows": [
54 {
55 "class": "^Steam$",
56 "instance": "^Steam$",
57 "title": "^Steam$"
58 // "transient_for": "^$"
59 }
60 ],
61 "type": "con"
62 }
63 ]
64 }
65 EOT
66 $fh->flush;
67 my $reply = cmd "append_layout $filename";
68
69 does_i3_live;
70
71 ok($reply->[0]->{success}, 'Layout successfully loaded');
72
73 cmd 'kill';
74
75 ok(workspace_exists($ws), 'Workspace still exists');
76
77 does_i3_live;
78
79 close($fh);
80
81 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # TODO: Description of this file.
17 # Ticket: #1817
18 # Bug still in: 4.10.3-270-g0fb784f
19 use i3test;
20 use File::Temp qw(tempfile);
21 use IO::Handle;
22
23 my $ws = fresh_workspace;
24
25 my @content = @{get_ws_content($ws)};
26 is(@content, 0, 'no nodes on the new workspace yet');
27
28 my ($fh, $filename) = tempfile(UNLINK => 1);
29 print $fh <<'EOT';
30 {
31 // stacked split container with 1 children
32 "border": "normal",
33 "floating": "auto_off",
34 "layout": "stacked",
35 "percent": 0.40,
36 "type": "con",
37 "nodes": [
38 {
39 "border": "normal",
40 "current_border_width": 2,
41 "floating": "auto_off",
42 "geometry": {
43 "height": 460,
44 "width": 804,
45 "x": 0,
46 "y": 0
47 },
48 // "name": "",
49 "percent": 0.5,
50 "swallows": [
51 { "class": "^URxvt$" },
52 { "class": "^Gitk$" },
53 { "class": "^Git-gui$" }
54 ],
55 "type": "con"
56 }
57 ]
58 }
59 EOT
60 $fh->flush;
61 my $reply = cmd "append_layout $filename";
62 close($fh);
63
64 does_i3_live;
65
66 @content = @{get_ws_content($ws)};
67 is(@content, 1, "one node on the workspace now");
68
69 my $should_swallow = open_window(wm_class => 'URxvt');
70
71 @content = @{get_ws_content($ws)};
72 is(@content, 1, "still one node on the workspace now");
73 my @nodes = @{$content[0]->{nodes}};
74 is($nodes[0]->{window}, $should_swallow->id, "swallowed window on top");
75
76 cmd 'focus parent';
77
78 my $should_ignore = open_window(wm_class => 'Gitk');
79
80 @content = @{get_ws_content($ws)};
81 is(@content, 2, "two nodes on the workspace");
82
83 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests for the special value "__focused__" in command criteria.
17 # Ticket: #1770
18 use i3test;
19 use X11::XCB qw(PROP_MODE_REPLACE);
20
21 my ($ws);
22
23 sub open_window_with_role {
24 my ($role) = @_;
25 open_window(
26 before_map => sub {
27 my ($window) = @_;
28 my $atomname = $x->atom(name => 'WM_WINDOW_ROLE');
29 my $atomtype = $x->atom(name => 'STRING');
30 $x->change_property(
31 PROP_MODE_REPLACE,
32 $window->id,
33 $atomname->id,
34 $atomtype->id,
35 8,
36 length($role) + 1,
37 "$role\x00"
38 );
39 }
40 );
41 }
42
43 ###############################################################################
44 # 1: Test __focused__ for window class.
45 ###############################################################################
46
47 $ws = fresh_workspace;
48 open_window(wm_class => 'notme');
49 open_window(wm_class => 'magic');
50 open_window(wm_class => 'magic');
51 is(@{get_ws($ws)->{nodes}}, 3, 'sanity check: workspace contains three windows');
52
53 cmd '[class=__focused__] move to workspace trash';
54 is(@{get_ws($ws)->{nodes}}, 1, '__focused__ works for window class');
55
56 ###############################################################################
57 # 2: Test __focused__ for window instance.
58 ###############################################################################
59
60 $ws = fresh_workspace;
61 open_window(instance => 'notme', wm_class => 'test');
62 open_window(instance => 'magic', wm_class => 'test');
63 open_window(instance => 'magic', wm_class => 'test');
64 is(@{get_ws($ws)->{nodes}}, 3, 'sanity check: workspace contains three windows');
65
66 cmd '[instance=__focused__] move to workspace trash';
67 is(@{get_ws($ws)->{nodes}}, 1, '__focused__ works for window instance');
68
69 ###############################################################################
70 # 3: Test __focused__ for window title.
71 ###############################################################################
72
73 $ws = fresh_workspace;
74 open_window(name => 'notme');
75 open_window(name => 'magic');
76 open_window(name => 'magic');
77 is(@{get_ws($ws)->{nodes}}, 3, 'sanity check: workspace contains three windows');
78
79 cmd '[title=__focused__] move to workspace trash';
80 is(@{get_ws($ws)->{nodes}}, 1, '__focused__ works for title');
81
82 ###############################################################################
83 # 4: Test __focused__ for window role.
84 ###############################################################################
85
86 $ws = fresh_workspace;
87 open_window_with_role("notme");
88 open_window_with_role("magic");
89 open_window_with_role("magic");
90 is(@{get_ws($ws)->{nodes}}, 3, 'sanity check: workspace contains three windows');
91
92 cmd '[window_role=__focused__] move to workspace trash';
93 is(@{get_ws($ws)->{nodes}}, 1, '__focused__ works for window_role');
94
95 ###############################################################################
96 # 5: Test __focused__ for workspace.
97 ###############################################################################
98
99 $ws = fresh_workspace;
100 open_window;
101 open_window;
102 is(@{get_ws($ws)->{nodes}}, 2, 'sanity check: workspace contains two windows');
103
104 cmd '[workspace=__focused__] move to workspace trash';
105 is(@{get_ws($ws)->{nodes}}, 0, '__focused__ works for workspace');
106
107 ###############################################################################
108 # 6: Test that __focused__ in command criteria when no window is focused does
109 # not crash i3.
110 # See issue: #3406
111 ###############################################################################
112
113 fresh_workspace;
114 cmd '[class=__focused__] focus';
115 does_i3_live;
116
117 ###############################################################################
118
119 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test behavior of "resize <width> <height>" command.
17 # Ticket: #1727
18 # Bug still in: 4.10.2-1-gc0dbc5d
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 fake-outputs 1333x999+0+0
24 workspace ws output fake-0
25 EOT
26
27 ################################################################################
28 # Init variables used for all tests.
29 ################################################################################
30
31 my $tmp = fresh_workspace;
32 open_floating_window;
33 my @content = @{get_ws($tmp)->{floating_nodes}};
34 is(@content, 1, 'one floating node on this ws');
35 my $oldrect = $content[0]->{rect};
36
37 sub do_test {
38 my ($width, $height) = @_;
39
40 cmp_ok($content[0]->{rect}->{x}, '==', $oldrect->{x}, 'x unchanged');
41 cmp_ok($content[0]->{rect}->{y}, '==', $oldrect->{y}, 'y unchanged');
42
43 @content = @{get_ws($tmp)->{floating_nodes}};
44 if ($width) {
45 cmp_ok($content[0]->{rect}->{width}, '==', $width, "width changed to $width px");
46 } else {
47 cmp_ok($content[0]->{rect}->{width}, '==', $oldrect->{width}, 'width unchanged');
48 }
49 if ($height) {
50 cmp_ok($content[0]->{rect}->{height}, '==', $height, "height changed to $height px");
51 } else {
52 cmp_ok($content[0]->{rect}->{height}, '==', $oldrect->{height}, 'height unchanged');
53 }
54 $oldrect = $content[0]->{rect};
55 }
56
57 ################################################################################
58 # Check that setting floating windows size works
59 ################################################################################
60
61 cmd 'resize set 100 px 250 px';
62 do_test(100, 250);
63
64 ################################################################################
65 # Same but with ppt instead of px
66 ################################################################################
67
68 cmd 'resize set 33 ppt 20 ppt';
69 do_test(int(0.33 * 1333), int(0.2 * 999));
70
71 ################################################################################
72 # Mix ppt and px in a single resize set command
73 ################################################################################
74
75 cmd 'resize set 44 ppt 111 px';
76 do_test(int(0.44 * 1333), 111);
77
78 cmd 'resize set 222 px 100 ppt';
79 do_test(222, 999);
80
81 ################################################################################
82 # Zero is interpreted as no change.
83 # See issue: #3276.
84 ################################################################################
85
86 cmd 'resize set 0 px 333 px';
87 do_test(0, 333);
88
89 cmd 'resize set 333 px 0 ppt';
90 do_test(333, 0);
91
92 cmd 'resize set 0 px 0 ppt';
93 do_test(0, 0);
94
95 cmd 'resize set 100 ppt 0 px';
96 do_test(1333, 0);
97
98 ################################################################################
99 # Use 'width' and 'height' keywords.
100 # See issue: #3275.
101 ################################################################################
102
103 cmd 'resize set width 200 px';
104 do_test(200, 0);
105
106 cmd 'resize set height 200 px';
107 do_test(0, 200);
108
109 cmd 'resize set width 300 px height 300 px';
110 do_test(300, 300);
111
112 # ppt + keyword used only for height
113 cmd 'resize set 100 ppt height 100 px';
114 do_test(1333, 100);
115
116 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Ticket: #1873
17 use i3test;
18 use X11::XCB qw(:all);
19
20 sub get_wm_state {
21 sync_with_i3;
22
23 my ($con) = @_;
24 my $cookie = $x->get_property(
25 0,
26 $con->{id},
27 $x->atom(name => '_NET_WM_STATE')->id,
28 GET_PROPERTY_TYPE_ANY,
29 0,
30 4096
31 );
32
33 my $reply = $x->get_property_reply($cookie->{sequence});
34 my $len = $reply->{length};
35 return undef if $len == 0;
36
37 my @atoms = unpack("L$len", $reply->{value});
38 return @atoms;
39 }
40
41 my $wm_state_sticky = $x->atom(name => '_NET_WM_STATE_STICKY')->id;
42 my $wm_state_fullscreen = $x->atom(name => '_NET_WM_STATE_FULLSCREEN')->id;
43
44 ##########################################################################
45 # Given a sticky container, when it is fullscreened, then both wm state
46 # atoms are set. When the container is unfullscreened, then only the
47 # sticky atom is still set.
48 ##########################################################################
49
50 fresh_workspace;
51 my $window = open_window;
52 cmd 'sticky enable';
53 my @state = get_wm_state($window);
54 ok((scalar grep { $_ == $wm_state_sticky } @state) > 0, 'sanity check: _NET_WM_STATE_STICKY is set');
55
56 cmd 'fullscreen enable';
57 @state = get_wm_state($window);
58 ok((scalar grep { $_ == $wm_state_sticky } @state) > 0, '_NET_WM_STATE_STICKY is set');
59 ok((scalar grep { $_ == $wm_state_fullscreen } @state) > 0, '_NET_WM_STATE_FULLSCREEN is set');
60
61 cmd 'sticky disable';
62 @state = get_wm_state($window);
63 ok((scalar grep { $_ == $wm_state_sticky } @state) == 0, '_NET_WM_STATE_STICKY is not set');
64 ok((scalar grep { $_ == $wm_state_fullscreen } @state) > 0, '_NET_WM_STATE_FULLSCREEN is set');
65
66 cmd 'sticky enable';
67 cmd 'fullscreen disable';
68 @state = get_wm_state($window);
69 ok((scalar grep { $_ == $wm_state_sticky } @state) > 0, '_NET_WM_STATE_STICKY is set');
70 ok((scalar grep { $_ == $wm_state_fullscreen } @state) == 0, '_NET_WM_STATE_FULLSCREEN is not set');
71
72 ###############################################################################
73 # _NET_WM_STATE is removed when the window is withdrawn.
74 ###############################################################################
75
76 fresh_workspace;
77 $window = open_window;
78 cmd 'sticky enable';
79 @state = get_wm_state($window);
80 ok((scalar grep { $_ == $wm_state_sticky } @state) > 0, '_NET_WM_STATE_STICKY is set');
81
82 $window->unmap;
83 wait_for_unmap($window);
84
85 is(get_wm_state($window), undef, '_NET_WM_STATE is removed');
86
87 ##########################################################################
88
89 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that "move container to output" works correctly when
17 # used with command criteria.
18 # Bug still in: 4.10.4-349-gee5db87
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 fake-outputs 800x600+0+0,800x600+800+0,800x600+0+600,800x600+800+600
24 EOT
25
26 my $ws_top_left = fresh_workspace(output => 0);
27 my $ws_top_right = fresh_workspace(output => 1);
28 my $ws_bottom_left = fresh_workspace(output => 2);
29 my $ws_bottom_right = fresh_workspace(output => 3);
30
31 cmd "workspace " . $ws_top_left;
32 open_window(wm_class => 'moveme');
33 cmd "workspace " . $ws_bottom_left;
34 open_window(wm_class => 'moveme');
35
36 cmd '[class="moveme"] move window to output right';
37
38 is_num_children($ws_top_left, 0, 'no containers on the upper left workspace');
39 is_num_children($ws_top_right, 1, 'one container on the upper right workspace');
40 is_num_children($ws_bottom_left, 0, 'no containers on the lower left workspace');
41 is_num_children($ws_bottom_right, 1, 'one container on the lower right workspace');
42
43 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests for mark/unmark with multiple marks on a single window.
17 # Ticket: #2014
18 use i3test;
19 use List::Util qw(first);
20
21 my ($ws, $con, $first, $second);
22
23 sub get_marks {
24 return i3(get_socket_path())->get_marks->recv;
25 }
26
27 sub get_mark_for_window_on_workspace {
28 my ($ws, $con) = @_;
29
30 my $current = first { $_->{window} == $con->{id} } @{get_ws_content($ws)};
31 return $current->{marks};
32 }
33
34 ###############################################################################
35 # Verify that multiple marks can be set on a window.
36 ###############################################################################
37
38 $ws = fresh_workspace;
39 $con = open_window;
40 cmd 'mark --add A';
41 cmd 'mark --add B';
42
43 is_deeply(sort(get_marks()), [ 'A', 'B' ], 'both marks exist');
44 is_deeply(get_mark_for_window_on_workspace($ws, $con), [ 'A', 'B' ], 'both marks are on the same window');
45
46 cmd 'unmark';
47
48 ###############################################################################
49 # Verify that toggling a mark can affect only the specified mark.
50 ###############################################################################
51
52 $ws = fresh_workspace;
53 $con = open_window;
54 cmd 'mark A';
55
56 cmd 'mark --add --toggle B';
57 is_deeply(get_mark_for_window_on_workspace($ws, $con), [ 'A', 'B' ], 'both marks are on the same window');
58 cmd 'mark --add --toggle B';
59 is_deeply(get_mark_for_window_on_workspace($ws, $con), [ 'A' ], 'only mark B has been removed');
60
61 cmd 'unmark';
62
63 ###############################################################################
64 # Verify that unmarking a mark leaves other marks on the same window intact.
65 ###############################################################################
66
67 $ws = fresh_workspace;
68 $con = open_window;
69 cmd 'mark --add A';
70 cmd 'mark --add B';
71 cmd 'mark --add C';
72
73 cmd 'unmark B';
74 is_deeply(get_mark_for_window_on_workspace($ws, $con), [ 'A', 'C' ], 'only mark B has been removed');
75
76 cmd 'unmark';
77
78 ###############################################################################
79 # Verify that matching via mark works on windows with multiple marks.
80 ###############################################################################
81
82 $ws = fresh_workspace;
83 $con = open_window;
84 cmd 'mark --add A';
85 cmd 'mark --add B';
86 open_window;
87
88 cmd '[con_mark=B] mark --add C';
89 is_deeply(get_mark_for_window_on_workspace($ws, $con), [ 'A', 'B', 'C' ], 'matching on a mark works with multiple marks');
90
91 cmd 'unmark';
92
93 ###############################################################################
94 # Verify that "unmark" can be matched on the focused window.
95 ###############################################################################
96
97 $ws = fresh_workspace;
98 $con = open_window;
99 cmd 'mark --add A';
100 cmd 'mark --add B';
101 open_window;
102 cmd 'mark --add C';
103 cmd 'mark --add D';
104
105 is_deeply(sort(get_marks()), [ 'A', 'B', 'C', 'D' ], 'all marks exist');
106
107 cmd '[con_id=__focused__] unmark';
108
109 is_deeply(sort(get_marks()), [ 'A', 'B' ], 'marks on the unfocused window still exist');
110 is_deeply(get_mark_for_window_on_workspace($ws, $con), [ 'A', 'B' ], 'matching on con_id=__focused__ works for unmark');
111
112 cmd 'unmark';
113
114 ###############################################################################
115
116 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test for the --no-auto-back-and-forth flag.
17 # Ticket: #2028
18 use i3test;
19
20 my ($first, $second, $third, $con);
21 $first = "1:first";
22 $second = "2:second";
23 $third = "3:third";
24
25 ###############################################################################
26 # Switching to another workspace when passing --no-auto-back-and-forth works
27 # as if the flag wasn't set.
28 ###############################################################################
29
30 cmd qq|workspace "$first"|;
31 ok(get_ws($first)->{focused}, 'first workspace is focused');
32
33 cmd qq|workspace --no-auto-back-and-forth "$second"|;
34 ok(get_ws($second)->{focused}, 'second workspace is focused');
35
36 cmd qq|workspace --no-auto-back-and-forth number "$third"|;
37 ok(get_ws($third)->{focused}, 'third workspace is focused');
38
39 ###############################################################################
40 # Switching to the focused workspace when passing --no-auto-back-and-forth
41 # is a no-op.
42 ###############################################################################
43
44 cmd qq|workspace "$second"|;
45 cmd qq|workspace "$first"|;
46 ok(get_ws($first)->{focused}, 'first workspace is focused');
47
48 cmd qq|workspace --no-auto-back-and-forth "$first"|;
49 ok(get_ws($first)->{focused}, 'first workspace is still focused');
50
51 cmd qq|workspace --no-auto-back-and-forth number "$first"|;
52 ok(get_ws($first)->{focused}, 'first workspace is still focused');
53
54 ###############################################################################
55 # Moving a window to another workspace when passing --no-auto-back-and-forth
56 # works as if the flag wasn't set.
57 ###############################################################################
58
59 cmd qq|workspace "$third"|;
60 cmd qq|workspace "$second"|;
61 cmd qq|workspace "$first"|;
62 $con = open_window;
63 cmd 'mark mywindow';
64
65 cmd qq|move --no-auto-back-and-forth window to workspace "$second"|;
66 is(@{get_ws($second)->{nodes}}, 1, 'window was moved to second workspace');
67 cmd qq|[con_mark=mywindow] move window to workspace "$first"|;
68
69 cmd qq|move --no-auto-back-and-forth window to workspace number "$third"|;
70 is(@{get_ws($third)->{nodes}}, 1, 'window was moved to third workspace');
71 cmd qq|[con_mark=mywindow] move window to workspace "$first"|;
72
73 cmd '[con_mark=mywindow] kill';
74
75 ###############################################################################
76 # Moving a window to the same workspace when passing --no-auto-back-and-forth
77 # is a no-op.
78 ###############################################################################
79
80 cmd qq|workspace "$second"|;
81 cmd qq|workspace "$first"|;
82 $con = open_window;
83 cmd 'mark mywindow';
84
85 cmd qq|move --no-auto-back-and-forth window to workspace "$first"|;
86 is(@{get_ws($first)->{nodes}}, 1, 'window is still on first workspace');
87 cmd qq|[con_mark=mywindow] move window to workspace "$first"|;
88
89 cmd qq|move --no-auto-back-and-forth window to workspace number "$first"|;
90 is(@{get_ws($first)->{nodes}}, 1, 'window is still on first workspace');
91 cmd qq|[con_mark=mywindow] move window to workspace "$first"|;
92
93 cmd '[con_mark=mywindow] kill';
94
95 ###############################################################################
96
97 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that when using multiple keyboard layouts at the same time, bindings
17 # without a specified XKB group will work in all XKB groups.
18 # Ticket: #2062
19 # Bug still in: 4.11-103-gc8d51b4
20 # Bug introduced with commit 0e5180cae9e9295678e3f053042b559e82cb8c98
21 use i3test
22 i3_config => <<EOT;
23 # i3 config file (v4)
24 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
25
26 bindsym Print nop Print
27 bindsym Mod4+Return nop Mod4+Return
28 EOT
29 use i3test::XTEST;
30 use ExtUtils::PkgConfig;
31
32 SKIP: {
33 skip "libxcb-xkb too old (need >= 1.11)", 1 unless
34 ExtUtils::PkgConfig->atleast_version('xcb-xkb', '1.11');
35 skip "setxkbmap not found", 1 if
36 system(q|setxkbmap -print >/dev/null|) != 0;
37
38 system(q|setxkbmap us,ru -option grp:alt_shift_toggle|);
39
40 is(listen_for_binding(
41 sub {
42 xtest_key_press(107);
43 xtest_key_release(107);
44 xtest_sync_with_i3;
45 },
46 ),
47 'Print',
48 'triggered the "Print" keybinding');
49
50 is(listen_for_binding(
51 sub {
52 xtest_key_press(133); # Super_L
53 xtest_key_press(36); # Return
54 xtest_key_release(36); # Return
55 xtest_key_release(133); # Super_L
56 xtest_sync_with_i3;
57 },
58 ),
59 'Mod4+Return',
60 'triggered the "Mod4+Return" keybinding');
61
62 # Switch keyboard group to russian.
63 set_xkb_group(1);
64
65 is(listen_for_binding(
66 sub {
67 xtest_key_press(107);
68 xtest_key_release(107);
69 xtest_sync_with_i3;
70 },
71 ),
72 'Print',
73 'triggered the "Print" keybinding');
74
75 is(listen_for_binding(
76 sub {
77 xtest_key_press(133); # Super_L
78 xtest_key_press(36); # Return
79 xtest_key_release(36); # Return
80 xtest_key_release(133); # Super_L
81 xtest_sync_with_i3;
82 },
83 ),
84 'Mod4+Return',
85 'triggered the "Mod4+Return" keybinding');
86
87 # Disable the grp:alt_shift_toggle option, as we use Alt+Shift in other testcases.
88 system(q|setxkbmap us -option|);
89
90 }
91
92 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that --release key bindings are not shadowed by non-release key
17 # bindings for the same key.
18 # Ticket: #2002
19 # Bug still in: 4.11-103-gc8d51b4
20 # Bug introduced with commit bf3cd41b5ddf1e757515ab5fbf811be56e5f69cc
21 use i3test i3_config => <<EOT;
22 # i3 config file (v4)
23 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
24
25 bindsym Print nop Print
26 bindsym --release Control+Print nop Control+Print
27
28 # see issue #2442
29 bindsym Mod1+b nop Mod1+b
30 bindsym --release Mod1+Shift+b nop Mod1+Shift+b release
31
32 bindsym --release Shift+x nop Shift+x
33
34 # see issue #2733
35 # 133 == Mod4
36 bindcode 133 nop 133
37 bindcode --release 133 nop 133 release
38
39 mode "a_mode" {
40 # 27 == r
41 bindcode 27 --release mode "default"
42 }
43 bindsym Mod1+r mode "a_mode"
44 bindcode 27 nop do not receive
45 EOT
46 use i3test::XTEST;
47 use ExtUtils::PkgConfig;
48
49 SKIP: {
50 skip "libxcb-xkb too old (need >= 1.11)", 1 unless
51 ExtUtils::PkgConfig->atleast_version('xcb-xkb', '1.11');
52
53 is(listen_for_binding(
54 sub {
55 xtest_key_press(107); # Print
56 xtest_key_release(107); # Print
57 xtest_sync_with_i3;
58 },
59 ),
60 'Print',
61 'triggered the "Print" keybinding');
62
63 is(listen_for_binding(
64 sub {
65 xtest_key_press(37); # Control_L
66 xtest_key_press(107); # Print
67 xtest_key_release(107); # Print
68 xtest_key_release(37); # Control_L
69 xtest_sync_with_i3;
70 },
71 ),
72 'Control+Print',
73 'triggered the "Control+Print" keybinding');
74
75 is(listen_for_binding(
76 sub {
77 xtest_key_press(64); # Alt_L
78 xtest_key_press(56); # b
79 xtest_key_release(56); # b
80 xtest_key_release(64); # Alt_L
81 xtest_sync_with_i3;
82 },
83 ),
84 'Mod1+b',
85 'triggered the "Mod1+b" keybinding');
86
87 is(listen_for_binding(
88 sub {
89 xtest_key_press(64); # Alt_L
90 xtest_key_press(50); # Shift_L
91 xtest_key_press(56); # b
92 xtest_key_release(56); # b
93 xtest_key_release(50); # Shift_L
94 xtest_key_release(64); # Alt_L
95 xtest_sync_with_i3;
96 },
97 ),
98 'Mod1+Shift+b release',
99 'triggered the "Mod1+Shift+b" release keybinding');
100
101 is(listen_for_binding(
102 sub {
103 xtest_key_press(50); # Shift
104 xtest_key_press(53); # x
105 xtest_key_release(53); # x
106 xtest_key_release(50); # Shift
107 xtest_sync_with_i3;
108 },
109 ),
110 'Shift+x',
111 'triggered the "Shift+x" keybinding by releasing x first');
112
113 is(listen_for_binding(
114 sub {
115 xtest_key_press(50); # Shift
116 xtest_key_press(53); # x
117 xtest_key_release(50); # Shift
118 xtest_key_release(53); # x
119 xtest_sync_with_i3;
120 },
121 ),
122 'Shift+x',
123 'triggered the "Shift+x" keybinding by releasing Shift first');
124
125 is(listen_for_binding(
126 sub {
127 xtest_key_press(133);
128 xtest_sync_with_i3;
129 },
130 ),
131 '133',
132 'triggered the 133 keycode press binding');
133
134 is(listen_for_binding(
135 sub {
136 xtest_key_release(133);
137 xtest_sync_with_i3;
138 },
139 ),
140 '133 release',
141 'triggered the 133 keycode release binding');
142
143 for my $i (1 .. 2) {
144 is(listen_for_binding(
145 sub {
146 xtest_key_press(64); # Alt_l
147 xtest_key_press(27); # r
148 xtest_key_release(27); # r
149 xtest_key_release(64); # Alt_l
150 xtest_sync_with_i3;
151 },
152 ),
153 'mode "a_mode"',
154 "switched to mode \"a_mode\" $i/2");
155
156 is(listen_for_binding(
157 sub {
158 xtest_key_press(27); # r
159 xtest_key_release(27); # r
160 xtest_sync_with_i3;
161 },
162 ),
163 'mode "default"',
164 "switched back to default $i/2");
165 }
166
167 }
168
169 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test for _NET_WM_USER_TIME.
17 # Ticket: #2064
18 use i3test;
19 use X11::XCB 'PROP_MODE_REPLACE';
20
21 my ($ws, $other, $con);
22
23 sub open_window_with_user_time {
24 my $wm_user_time = shift;
25
26 my $window = open_window(
27 before_map => sub {
28 my ($window) = @_;
29
30 my $atomname = $x->atom(name => '_NET_WM_USER_TIME');
31 my $atomtype = $x->atom(name => 'CARDINAL');
32 $x->change_property(
33 PROP_MODE_REPLACE,
34 $window->id,
35 $atomname->id,
36 $atomtype->id,
37 32,
38 1,
39 pack('L1', $wm_user_time),
40 );
41 },
42 );
43
44 return $window;
45 }
46
47 #####################################################################
48 # 1: if _NET_WM_USER_TIME is set to 0, the window is not focused
49 # initially.
50 #####################################################################
51
52 $ws = fresh_workspace;
53
54 open_window;
55 $other = get_focused($ws);
56 open_window_with_user_time(0);
57
58 is(get_focused($ws), $other, 'new window is not focused');
59
60 #####################################################################
61 # 2: if _NET_WM_USER_TIME is set to something other than 0, the
62 # window is focused anyway.
63 #####################################################################
64
65 $ws = fresh_workspace;
66
67 open_window;
68 $other = get_focused($ws);
69 open_window_with_user_time(42);
70
71 isnt(get_focused($ws), $other, 'new window is focused');
72
73 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Ticket: #2091
17 use i3test;
18
19 my $ws = fresh_workspace;
20 open_window;
21
22 my $result = cmd '[con_id=foobar] kill';
23 is($result->[0]->{success}, 0, 'command was unsuccessful');
24 is($result->[0]->{error}, 'Invalid match: invalid con_id', 'correct error is returned');
25
26 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Ticket: #2111
17 use i3test;
18
19 my ($ws);
20
21 ###############################################################################
22 # Verify that con_id can be combined with other criteria
23 ###############################################################################
24
25 $ws = fresh_workspace;
26 open_window(wm_class => 'matchme');
27
28 cmd '[con_id=__focused__ class=doesnotmatch] kill';
29 sync_with_i3;
30 is(@{get_ws($ws)->{nodes}}, 1, 'window was not killed');
31
32 cmd '[con_id=__focused__ class=matchme] kill';
33 sync_with_i3;
34 is(@{get_ws($ws)->{nodes}}, 0, 'window was killed');
35
36 ###############################################################################
37 # Verify that con_mark can be combined with other criteria
38 ###############################################################################
39
40 $ws = fresh_workspace;
41 open_window(wm_class => 'matchme');
42 cmd 'mark marked';
43
44 cmd '[con_mark=marked class=doesnotmatch] kill';
45 sync_with_i3;
46 is(@{get_ws($ws)->{nodes}}, 1, 'window was not killed');
47
48 cmd '[con_mark=marked class=matchme] kill';
49 sync_with_i3;
50 is(@{get_ws($ws)->{nodes}}, 0, 'window was killed');
51
52 ###############################################################################
53
54 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Ensures that calling i3 with the -C switch works (smoke test).
17 # Ticket: #2144
18 use i3test i3_autostart => 0;
19 use POSIX ":sys_wait_h";
20 use Time::HiRes qw(sleep);
21
22 my $config = <<EOT;
23 # i3 config file (v4)
24 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
25
26 invalid
27 EOT
28
29 my $exit_code = launch_with_config($config, validate_config => 1);
30 isnt($exit_code, 0, 'i3 exited with an error code');
31
32 my $log = get_i3_log;
33
34 # We don't care so much about the output (there are tests for this), but rather
35 # that we got correct output at all instead of, e.g., a segfault.
36 ok($log =~ /Expected one of these tokens/, 'an invalid config token was found');
37
38 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that reloading the config reverts to the default
17 # binding mode.
18 # Ticket: #2228
19 # Bug still in: 4.11-262-geb631ce
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 mode "othermode" {
25 }
26 EOT
27
28 cmd 'mode othermode';
29
30 my @events = events_for(
31 sub { cmd 'reload' },
32 'mode');
33
34 is(scalar @events, 1, 'Received 1 event');
35 is($events[0]->{change}, 'default', 'change is "default"');
36
37 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that command or config criteria does not match dock clients
17 # Bug still in: 4.12-38-ge690e3d
18 use i3test i3_config => <<EOT;
19 # i3 config file (v4)
20 for_window [class="dock"] move workspace current
21
22 bar {
23 # Disable i3bar, which is also a dock client.
24 i3bar_command :
25 }
26 EOT
27
28 my $ws = fresh_workspace();
29
30
31 ## command criteria should not match dock windows
32 open_window({
33 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
34 wm_class => "x"
35 });
36
37 is(get_dock_clients, 1, "created one docked client");
38 is_num_children($ws, 0, 'no container on the current workspace');
39
40 cmd '[class="^x$"] move workspace current';
41
42 does_i3_live
43 is(get_dock_clients, 1, "one docked client after move");
44 is_num_children($ws, 0, 'no container on the current workspace');
45
46 cmd '[class="^x$"] fullscreen';
47
48 does_i3_live
49 is(get_dock_clients, 1, "one docked client after fullscreen");
50 is_num_children($ws, 0, 'no container on the current workspace');
51
52 cmd '[class="^x$"] kill';
53
54 does_i3_live
55 is(get_dock_clients, 1, "one docked client after kill");
56 is_num_children($ws, 0, 'no container on the current workspace');
57
58
59 ## config criteria should not match dock windows
60 open_window({
61 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK'),
62 wm_class => "dock"
63 });
64
65 does_i3_live
66 is(get_dock_clients, 2, "created second docked client");
67 is_num_children($ws, 0, 'no container on the current workspace');
68
69
70 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests for the window::mark IPC event.
17 # Ticket: #2501
18 use i3test;
19
20 sub mark_subtest {
21 my ($cmd) = @_;
22
23 my @events = events_for(
24 sub { cmd $cmd },
25 'window');
26
27 my @mark = grep { $_->{change} eq 'mark' } @events;
28 is(scalar @mark, 1, 'Received 1 window::mark event');
29 }
30
31 ###############################################################################
32 # Marking a container triggers a 'mark' event.
33 ###############################################################################
34 fresh_workspace;
35 open_window;
36
37 subtest 'mark', \&mark_subtest, 'mark x';
38
39 ###############################################################################
40 # Unmarking a container triggers a 'mark' event.
41 ###############################################################################
42 fresh_workspace;
43 open_window;
44 cmd 'mark x';
45
46 subtest 'unmark', \&mark_subtest, 'unmark x';
47
48 ###############################################################################
49
50 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests for _NET_MOVERESIZE_WINDOW.
17 # Ticket: #2603
18 use i3test i3_autostart => 0;
19
20 sub moveresize_window {
21 my ($win, $pos_x, $pos_y, $width, $height) = @_;
22
23 my $flags = 0;
24 $flags |= (1 << 8) if $pos_x >= 0;
25 $flags |= (1 << 9) if $pos_y >= 0;
26 $flags |= (1 << 10) if $width >= 0;
27 $flags |= (1 << 11) if $height >= 0;
28
29 my $msg = pack "CCSLLLLLLL",
30 X11::XCB::CLIENT_MESSAGE, # response_type
31 32, # format
32 0, # sequence
33 $win->id, # window
34 $x->atom(name => '_NET_MOVERESIZE_WINDOW')->id, # message type
35 $flags, # data32[0] (flags)
36 $pos_x, # data32[1] (x)
37 $pos_y, # data32[2] (y)
38 $width, # data32[3] (width)
39 $height; # data32[4] (height)
40
41 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
42 sync_with_i3;
43 }
44
45 my $config = <<EOT;
46 # i3 config file (v4)
47 font font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
48
49 new_window none
50 new_float none
51 EOT
52
53 my ($pid, $ws, $window, $content);
54
55 ###############################################################################
56
57 ###############################################################################
58 # A _NET_MOVERESIZE_WINDOW client message can change the position and size
59 # of a floating window.
60 ###############################################################################
61
62 $pid = launch_with_config($config);
63 $ws = fresh_workspace;
64
65 $window = open_floating_window(rect => [50, 50, 100, 100]);
66 moveresize_window($window, 0, 0, 555, 666);
67
68 $content = get_ws($ws);
69 is($content->{floating_nodes}->[0]->{rect}->{x}, 0, 'the x coordinate is correct');
70 is($content->{floating_nodes}->[0]->{rect}->{y}, 0, 'the y coordinate is correct');
71 is($content->{floating_nodes}->[0]->{rect}->{width}, 555, 'the width is correct');
72 is($content->{floating_nodes}->[0]->{rect}->{height}, 666, 'the height is correct');
73
74 exit_gracefully($pid);
75
76 ###############################################################################
77 # A _NET_MOVERESIZE_WINDOW client message can change only the position of a
78 # window.
79 ###############################################################################
80
81 $pid = launch_with_config($config);
82 $ws = fresh_workspace;
83
84 $window = open_floating_window(rect => [50, 50, 100, 100]);
85 moveresize_window($window, 100, 100, -1, -1);
86
87 $content = get_ws($ws);
88 is($content->{floating_nodes}->[0]->{rect}->{x}, 100, 'the x coordinate is correct');
89 is($content->{floating_nodes}->[0]->{rect}->{y}, 100, 'the y coordinate is correct');
90 is($content->{floating_nodes}->[0]->{rect}->{width}, 100, 'the width is unchanged');
91 is($content->{floating_nodes}->[0]->{rect}->{height}, 100, 'the height is unchanged');
92
93 exit_gracefully($pid);
94
95 ###############################################################################
96 # A _NET_MOVERESIZE_WINDOW client message can change only the size of a
97 # window.
98 ###############################################################################
99
100 $pid = launch_with_config($config);
101 $ws = fresh_workspace;
102
103 $window = open_floating_window(rect => [50, 50, 100, 100]);
104 moveresize_window($window, -1, -1, 200, 200);
105
106 $content = get_ws($ws);
107 is($content->{floating_nodes}->[0]->{rect}->{x}, 50, 'the x coordinate is unchanged');
108 is($content->{floating_nodes}->[0]->{rect}->{y}, 50, 'the y coordinate is unchanged');
109 is($content->{floating_nodes}->[0]->{rect}->{width}, 200, 'the width is correct');
110 is($content->{floating_nodes}->[0]->{rect}->{height}, 200, 'the height is correct');
111
112 exit_gracefully($pid);
113
114 ###############################################################################
115
116 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test to check if mark and restart commands crash i3
17 #
18 use i3test;
19
20 cmd 'open';
21 cmd 'mark foo';
22 cmd 'open';
23 cmd 'mark bar';
24
25 cmd 'restart';
26
27 diag('Checking if i3 still lives');
28
29 does_i3_live;
30
31 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that the config file is returned raw via the IPC interface.
17 # Ticket: #2856
18 # Bug still in: 4.13-133-ge4da07e7
19 use i3test i3_autostart => 0;
20 use File::Temp qw(tempdir);
21
22 my $tmpdir = tempdir(CLEANUP => 1);
23 my $socketpath = $tmpdir . "/config.sock";
24 ok(! -e $socketpath, "$socketpath does not exist yet");
25
26 my $config = <<'EOT';
27 # i3 config file (v4)
28 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
29
30 nop foo \
31 continued
32
33 set $var normal title
34 for_window [title="$vartest"] border none
35 EOT
36
37 $config .= "ipc-socket $socketpath";
38
39 my $pid = launch_with_config($config, dont_add_socket_path => 1, dont_create_temp_dir => 1);
40 get_socket_path(0);
41 my $i3 = i3(get_socket_path());
42 $i3->connect->recv;
43
44 my $cv = AnyEvent->condvar;
45 my $timer = AnyEvent->timer(after => 0.5, interval => 0, cb => sub { $cv->send(0); });
46
47 my $last_config = $i3->get_config()->recv;
48 chomp($last_config->{config});
49 is($last_config->{config}, $config,
50 'received config is not equal to written config');
51
52 exit_gracefully($pid);
53
54 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies a ConfigureWindow request with stack-mode=Above is translated into
17 # focusing the target window by i3.
18 # Ticket: #2708
19 # Bug still in: 4.13-207-gafdf6792
20 use i3test;
21 use X11::XCB qw(CONFIG_WINDOW_STACK_MODE STACK_MODE_ABOVE);
22
23 my $ws = fresh_workspace;
24 my $left_window = open_window;
25 my $right_window = open_window;
26
27 is($x->input_focus, $right_window->id, 'right window has focus');
28 my $old_focus = get_focused($ws);
29
30 $x->configure_window($left_window->id, CONFIG_WINDOW_STACK_MODE, (STACK_MODE_ABOVE));
31 $x->flush;
32
33 sync_with_i3;
34
35 is($x->input_focus, $left_window->id, 'left window has focus');
36 isnt(get_focused($ws), $old_focus, 'right window is no longer focused');
37
38 ################################################################################
39 # Verify the ConfigureWindow request is only applied when on the active
40 # workspace.
41 ################################################################################
42
43 $ws = fresh_workspace;
44 my $new_window = open_window;
45
46 is($x->input_focus, $new_window->id, 'new window has focus');
47 $x->configure_window($left_window->id, CONFIG_WINDOW_STACK_MODE, (STACK_MODE_ABOVE));
48 $x->flush;
49
50 sync_with_i3;
51
52 is($x->input_focus, $new_window->id, 'new window still has focus');
53
54 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Make sure that configs that end without a newline don't crash i3.
17 # Ticket: #2934
18 use i3test i3_autostart => 0;
19
20 my $first_lines = <<'EOT';
21 set $workspace0 workspace eggs
22
23 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
24 EOT
25
26 # Intentionally don't add a trailing newline for the last line since this is
27 # what triggered the bug.
28 my $last_line = 'bindsym Mod4+0 $workspace0';
29 my $config = "${first_lines}${last_line}";
30
31 my $pid = launch_with_config($config);
32 does_i3_live;
33
34 my $i3 = i3(get_socket_path());
35 my $ws = $i3->get_workspaces->recv;
36 is($ws->[0]->{name}, 'eggs', 'last line processed correctly');
37
38 exit_gracefully($pid);
39 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 use i3test i3_config => <<EOT;
17 # i3 config file (v4)
18 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
19 for_window [tiling] mark --add tiling
20 for_window [floating] mark --add floating
21
22 for_window [tiling_from="auto"] mark --add tiling_auto
23 for_window [floating_from="auto"] mark --add floating_auto
24
25 for_window [tiling_from="user"] mark --add tiling_user
26 for_window [floating_from="user"] mark --add floating_user
27 EOT
28 use X11::XCB qw(PROP_MODE_REPLACE);
29
30 ##############################################################
31 # Check that the auto tiling / floating criteria work.
32 ##############################################################
33
34 my $tmp = fresh_workspace;
35 my $A = open_window;
36 my $B = open_floating_window;
37
38 my @nodes = @{get_ws($tmp)->{nodes}};
39 cmp_ok(@nodes, '==', 1, 'one tiling container on this workspace');
40 is_deeply($nodes[0]->{marks}, [ 'tiling', 'tiling_auto' ], "mark set for 'tiling' criterion");
41
42 @nodes = @{get_ws($tmp)->{floating_nodes}};
43 cmp_ok(@nodes, '==', 1, 'one floating container on this workspace');
44 is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'floating', 'floating_auto' ], "mark set for 'floating' criterion");
45
46 ################################################################################
47 # Check that the user tiling / floating criteria work.
48 # The following rules are triggered here: 'tiling', 'tiling_user', 'floating',
49 # 'floating_user'. Therefore, the old marks 'tiling' and 'floating' are
50 # replaced but the 'tiling_auto' and 'floating_auto' marks are preserved.
51 ################################################################################
52
53 cmd '[id=' . $A->{id} . '] floating enable';
54 cmd '[id=' . $B->{id} . '] floating disable';
55
56 @nodes = @{get_ws($tmp)->{nodes}};
57 cmp_ok(@nodes, '==', 1, 'one tiling container on this workspace');
58 is_deeply($nodes[0]->{marks}, [ 'floating_auto', 'tiling', 'tiling_user' ], "Marks updated after 'floating_user' criterion");
59
60 @nodes = @{get_ws($tmp)->{floating_nodes}};
61 cmp_ok(@nodes, '==', 1, 'one floating container on this workspace');
62 is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'tiling_auto', 'floating', 'floating_user' ], "Marks updated after 'tiling_user' criterion");
63
64 ################################################################################
65 # Check that the default and auto rules do not re-trigger
66 # Here, the windows are returned to their original state but since the rules
67 # `tiling`, `tiling_auto`, `floating` and `floating_auto` where already
68 # triggered, only the `tiling_user` and `floating_user` rules should trigger.
69 ################################################################################
70
71 # Use 'mark' to clear old marks
72 cmd '[id=' . $A->{id} . '] mark A, floating disable';
73 cmd '[id=' . $B->{id} . '] mark B, floating enable';
74
75 @nodes = @{get_ws($tmp)->{nodes}};
76 cmp_ok(@nodes, '==', 1, 'one tiling container on this workspace');
77 is_deeply($nodes[0]->{marks}, [ 'A', 'tiling_user' ], "Only 'tiling_user' rule triggered");
78
79 @nodes = @{get_ws($tmp)->{floating_nodes}};
80 cmp_ok(@nodes, '==', 1, 'one floating container on this workspace');
81 is_deeply($nodes[0]->{nodes}[0]->{marks}, [ 'B', 'floating_user' ], "Only 'floating_user' rule triggered");
82
83 ##############################################################
84
85 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression: Checks if focus is stolen when a window is managed which is
17 # assigned to an invisible workspace
18 #
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22 assign [class="special"] targetws
23 EOT
24
25 sub open_special {
26 my %args = @_;
27 $args{name} //= 'special window';
28
29 # We use dont_map because i3 will not map the window on the current
30 # workspace. Thus, open_window would time out in wait_for_map (2 seconds).
31 my $window = open_window(
32 %args,
33 wm_class => 'special',
34 dont_map => 1,
35 );
36 $window->map;
37 return $window;
38 }
39
40 #####################################################################
41 # start a window and see that it does not get assigned with an empty config
42 #####################################################################
43
44 my $tmp = fresh_workspace;
45
46 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
47 ok(get_ws($tmp)->{focused}, 'current workspace focused');
48
49 my $window = open_special;
50 sync_with_i3;
51
52 ok(@{get_ws_content($tmp)} == 0, 'special window not on current workspace');
53 ok(@{get_ws_content('targetws')} == 1, 'special window on targetws');
54 ok(get_ws($tmp)->{focused}, 'current workspace still focused');
55
56 #####################################################################
57 # the same test, but with a floating window
58 #####################################################################
59
60 $window = open_special(
61 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_UTILITY'),
62 );
63
64 ok(@{get_ws_content($tmp)} == 0, 'special window not on current workspace');
65 ok(@{get_ws_content('targetws')} == 1, 'special window on targetws');
66 ok(get_ws($tmp)->{focused}, 'current workspace still focused');
67
68 $window->destroy;
69
70 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression: Checks if i3 still lives after using 'focus mode_toggle' on an
17 # empty workspace. This regression was fixed in
18 # 0848844f2d41055f6ffc69af1149d7a873460976.
19 #
20 use i3test;
21 use v5.10;
22
23 my $tmp = fresh_workspace;
24
25 cmd 'focus mode_toggle';
26
27 does_i3_live;
28
29 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that movement of a con into a branch will place the moving con at the
17 # correct position within the branch.
18 #
19 # If the direction of movement is the same as the orientation of the branch
20 # container, append or prepend the container to the branch in the obvious way.
21 # If the movement is to the right or downward, insert the moving container in
22 # the first position (i.e., the leftmost or top position resp.) If the movement
23 # is to the left or upward, insert the moving container in the last position
24 # (i.e., the rightmost or bottom position resp.)
25 #
26 # If the direction of movement is different from the orientation of the branch
27 # container, insert the container into the branch after the focused-inactive
28 # container.
29 #
30 # For testing purposes, we will demonstrate the behavior for tabbed containers
31 # to represent the case of split-horizontal branches and stacked containers to
32 # represent the case of split-vertical branches.
33 #
34 # Ticket: #1060
35 # Bug still in: 4.6-109-g18cfc36
36
37 use i3test;
38
39 # Opens tabs on the presently focused branch and adds several additional
40 # windows. Shifts focus to somewhere in the middle of the tabs so the most
41 # general case can be assumed.
42 sub open_tabs {
43 cmd 'layout tabbed';
44 open_window;
45 open_window;
46 open_window;
47 open_window;
48 cmd 'focus left; focus left'
49 }
50
51 # Likewise for a stack
52 sub open_stack {
53 cmd 'layout stacking';
54 open_window;
55 open_window;
56 open_window;
57 open_window;
58 cmd 'focus up; focus up'
59 }
60
61 # Gets the position of the given leaf within the given branch. The first
62 # position is one (1). Returns negative one (-1) if the leaf cannot be found
63 # within the branch.
64 sub get_leaf_position {
65 my ($branch, $leaf) = @_;
66 my $position = -1;
67 for my $i (0 .. @{$branch->{nodes}}) {
68 if ($branch->{nodes}[$i]->{id} == $leaf) {
69 $position = $i + 1;
70 last;
71 };
72 }
73 return $position;
74 }
75
76 # convenience function to focus a con by id to avoid having to type an ugly
77 # command each time
78 sub focus_con {
79 my $con_id = shift @_;
80 cmd "[con_id=\"$con_id\"] focus";
81 }
82
83 # Places a leaf into a branch and focuses the leaf. The newly created branch
84 # will have orientation specified by the second parameter.
85 sub branchify {
86 my ($con_id, $orientation) = @_;
87 focus_con($con_id);
88 $orientation eq 'horizontal' ? cmd 'splith' : cmd 'splitv';
89 open_window;
90 focus_con($con_id);
91 }
92
93 ##############################################################################
94 # When moving a con right into tabs, the moving con should be placed as the
95 # first tab in the branch
96 ##############################################################################
97 my $ws = fresh_workspace;
98
99 # create the target leaf
100 open_window;
101 my $target_leaf = get_focused($ws);
102
103 # create the tabbed branch container
104 open_window;
105 cmd 'splith';
106 open_tabs;
107
108 # move the target leaf into the tabbed branch
109 focus_con($target_leaf);
110 cmd 'move right';
111
112 # the target leaf should be the first in the branch
113 my $branch = shift @{get_ws_content($ws)};
114 is($branch->{nodes}[0]->{id}, $target_leaf, 'moving con right into tabs placed it as the first tab in the branch');
115
116 # repeat the test when the target is in a branch
117 cmd 'move up; move left';
118 branchify($target_leaf, 'vertical');
119 cmd 'move right';
120
121 $branch = pop @{get_ws_content($ws)};
122 is($branch->{nodes}[0]->{id}, $target_leaf, 'moving con right into tabs from a branch placed it as the first tab in the branch');
123
124 ##############################################################################
125 # When moving a con right into a stack, the moving con should be placed
126 # below the focused-inactive leaf
127 ##############################################################################
128 $ws = fresh_workspace;
129
130 # create the target leaf
131 open_window;
132 $target_leaf = get_focused($ws);
133
134 # create the stacked branch container and find the focused leaf
135 open_window;
136 cmd 'splith';
137 open_stack;
138 my $secondary_leaf = get_focused($ws);
139
140 # move the target leaf into the stacked branch
141 focus_con($target_leaf);
142 cmd 'move right';
143
144 # the secondary focus leaf should be below the target
145 $branch = shift @{get_ws_content($ws)};
146 my $target_leaf_position = get_leaf_position($branch, $target_leaf);
147 my $secondary_leaf_position = get_leaf_position($branch, $secondary_leaf);
148
149 is($target_leaf_position, $secondary_leaf_position + 1, 'moving con right into a stack placed it below the focused-inactive leaf');
150
151 # repeat the test when the target is in a branch
152 cmd 'move up; move left';
153 branchify($target_leaf, 'vertical');
154 cmd 'move right';
155
156 $branch = pop @{get_ws_content($ws)};
157 $target_leaf_position = get_leaf_position($branch, $target_leaf);
158 $secondary_leaf_position = get_leaf_position($branch, $secondary_leaf);
159
160 is($target_leaf_position, $secondary_leaf_position + 1, 'moving con right into a stack from a branch placed it below the focused-inactive leaf');
161
162 ##############################################################################
163 # When moving a con down into a stack, the moving con should be placed at the
164 # top of the stack
165 ##############################################################################
166 $ws = fresh_workspace;
167 cmd 'layout splitv';
168
169 # create the target leaf
170 open_window;
171 $target_leaf = get_focused($ws);
172
173 # create the stacked branch container
174 open_window;
175 cmd 'splitv';
176 open_stack;
177
178 # move the target leaf into the stacked branch
179 focus_con($target_leaf);
180 cmd 'move down';
181
182 # the target leaf should be on the top of the stack
183 $branch = shift @{get_ws_content($ws)};
184 is($branch->{nodes}[0]->{id}, $target_leaf, 'moving con down into a stack placed it on the top of the stack');
185
186 # repeat the test when the target is in a branch
187 cmd 'move right; move up';
188 branchify($target_leaf, 'horizontal');
189 cmd 'move down';
190
191 $branch = pop @{get_ws_content($ws)};
192 is($branch->{nodes}[0]->{id}, $target_leaf, 'moving con down into a stack from a branch placed it on the top of the stack');
193
194 ##############################################################################
195 # When moving a con down into tabs, the moving con should be placed after the
196 # focused-inactive tab
197 ##############################################################################
198 $ws = fresh_workspace;
199 cmd 'layout splitv';
200
201 # create the target leaf
202 open_window;
203 $target_leaf = get_focused($ws);
204
205 # create the tabbed branch container and find the focused tab
206 open_window;
207 cmd 'splitv';
208 open_tabs;
209 $secondary_leaf = get_focused($ws);
210
211 # move the target leaf into the tabbed branch
212 focus_con($target_leaf);
213 cmd 'move down';
214
215 # the secondary focus tab should be to the right
216 $branch = shift @{get_ws_content($ws)};
217 $target_leaf_position = get_leaf_position($branch, $target_leaf);
218 $secondary_leaf_position = get_leaf_position($branch, $secondary_leaf);
219
220 is($target_leaf_position, $secondary_leaf_position + 1, 'moving con down into tabs placed it after the focused-inactive tab');
221
222 # repeat the test when the target is in a branch
223 cmd 'move right; move up';
224 branchify($target_leaf, 'horizontal');
225 cmd 'move down';
226
227 $branch = pop @{get_ws_content($ws)};
228 $target_leaf_position = get_leaf_position($branch, $target_leaf);
229 $secondary_leaf_position = get_leaf_position($branch, $secondary_leaf);
230
231 is($target_leaf_position, $secondary_leaf_position + 1, 'moving con down into tabs from a branch placed it after the focused-inactive tab');
232
233 ##############################################################################
234 # When moving a con left into tabs, the moving con should be placed as the last
235 # tab in the branch
236 ##############################################################################
237 $ws = fresh_workspace;
238
239 # create the tabbed branch container
240 open_window;
241 cmd 'splith';
242 open_tabs;
243
244 # create the target leaf
245 cmd 'focus parent';
246 open_window;
247 $target_leaf = get_focused($ws);
248
249 # move the target leaf into the tabbed branch
250 cmd 'move left';
251
252 # the target leaf should be last in the branch
253 $branch = shift @{get_ws_content($ws)};
254
255 is($branch->{nodes}->[-1]->{id}, $target_leaf, 'moving con left into tabs placed it as the last tab in the branch');
256
257 # repeat the test when the target leaf is in a branch
258 cmd 'move up; move right';
259 branchify($target_leaf, 'vertical');
260 cmd 'move left';
261
262 $branch = shift @{get_ws_content($ws)};
263 is($branch->{nodes}->[-1]->{id}, $target_leaf, 'moving con left into tabs from a branch placed it as the last tab in the branch');
264
265 ##############################################################################
266 # When moving a con left into a stack, the moving con should be placed below
267 # the focused-inactive leaf
268 ##############################################################################
269 $ws = fresh_workspace;
270
271 # create the stacked branch container and find the focused leaf
272 open_window;
273 open_stack;
274 $secondary_leaf = get_focused($ws);
275
276 # create the target leaf to the right
277 cmd 'focus parent';
278 open_window;
279 $target_leaf = get_focused($ws);
280
281 # move the target leaf into the stacked branch
282 cmd 'move left';
283
284 # the secondary focus leaf should be below
285 $branch = shift @{get_ws_content($ws)};
286 $target_leaf_position = get_leaf_position($branch, $target_leaf);
287 $secondary_leaf_position = get_leaf_position($branch, $secondary_leaf);
288
289 is($target_leaf_position, $secondary_leaf_position + 1, 'moving con left into a stack placed it below the focused-inactive leaf');
290
291 # repeat the test when the target leaf is in a branch
292 cmd 'move up; move right';
293 branchify($target_leaf, 'vertical');
294 cmd 'move left';
295
296 $branch = shift @{get_ws_content($ws)};
297 $target_leaf_position = get_leaf_position($branch, $target_leaf);
298 $secondary_leaf_position = get_leaf_position($branch, $secondary_leaf);
299
300 is($target_leaf_position, $secondary_leaf_position + 1, 'moving con left into a stack from a branch placed it below the focused-inactive leaf');
301
302 ##############################################################################
303 # When moving a con up into a stack, the moving con should be placed last in
304 # the stack
305 ##############################################################################
306 $ws = fresh_workspace;
307 cmd 'layout splitv';
308
309 # create the stacked branch container
310 open_window;
311 cmd 'splitv';
312 open_stack;
313
314 # create the target leaf
315 cmd 'focus parent';
316 open_window;
317 $target_leaf = get_focused($ws);
318
319 # move the target leaf into the stacked branch
320 cmd 'move up';
321
322 # the target leaf should be on the bottom of the stack
323 $branch = shift @{get_ws_content($ws)};
324
325 is($branch->{nodes}->[-1]->{id}, $target_leaf, 'moving con up into stack placed it on the bottom of the stack');
326
327 # repeat the test when the target leaf is in a branch
328 cmd 'move right; move down';
329 branchify($target_leaf, 'horizontal');
330 cmd 'move up';
331
332 $branch = shift @{get_ws_content($ws)};
333
334 is($branch->{nodes}->[-1]->{id}, $target_leaf, 'moving con up into stack from a branch placed it on the bottom of the stack');
335
336 ##############################################################################
337 # When moving a con up into tabs, the moving con should be placed after the
338 # focused-inactive tab
339 ##############################################################################
340 $ws = fresh_workspace;
341 cmd 'layout splitv';
342
343 # create the tabbed branch container and find the focused leaf
344 open_window;
345 cmd 'splitv';
346 open_tabs;
347 $secondary_leaf = get_focused($ws);
348
349 # create the target leaf below
350 cmd 'focus parent';
351 open_window;
352 $target_leaf = get_focused($ws);
353
354 # move the target leaf into the tabbed branch
355 cmd 'move up';
356
357 # the secondary focus tab should be to the right
358 $branch = shift @{get_ws_content($ws)};
359 $target_leaf_position = get_leaf_position($branch, $target_leaf);
360 $secondary_leaf_position = get_leaf_position($branch, $secondary_leaf);
361
362 is($target_leaf_position, $secondary_leaf_position + 1, 'moving con up into tabs placed it after the focused-inactive tab');
363
364 # repeat the test when the target leaf is in a branch
365 cmd 'move right; move down';
366 branchify($target_leaf, 'horizontal');
367 cmd 'move up';
368
369 $branch = shift @{get_ws_content($ws)};
370 $target_leaf_position = get_leaf_position($branch, $target_leaf);
371 $secondary_leaf_position = get_leaf_position($branch, $secondary_leaf);
372
373 is($target_leaf_position, $secondary_leaf_position + 1, 'moving con up into tabs from a branch placed it after the focused-inactive tab');
374
375 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that the ipc close event works properly
17 #
18 # Bug still in: 4.8-7-gf4a8253
19 use i3test;
20
21 my $window = open_window;
22
23 my @events = events_for(
24 sub {
25 $window->unmap;
26 sync_with_i3;
27 },
28 'window');
29
30 my @close = grep { $_->{change} eq 'close' } @events;
31 is(scalar @close, 1, 'Received 1 window::close event');
32 is($close[0]->{container}->{window}, $window->{id}, 'the event should contain information about the window');
33
34 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that the ipc window::move event works properly
17 #
18 # Bug still in: 4.8-7-gf4a8253
19 use i3test;
20
21 my $dummy_window = open_window;
22 my $window = open_window;
23
24 sub move_subtest {
25 my ($cmd) = @_;
26 my $cv = AnyEvent->condvar;
27 my @events = events_for(
28 sub { cmd $cmd },
29 'window');
30
31 my @move = grep { $_->{change} eq 'move' } @events;
32 is(scalar @move, 1, 'Received 1 window::move event');
33 is($move[0]->{container}->{window}, $window->{id}, 'window id matches');
34 }
35
36 subtest 'move left', \&move_subtest, 'move left';
37 subtest 'move to workspace', \&move_subtest, 'move to workspace ws_new';
38
39 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that the window::urgent event works correctly. The window::urgent event
17 # should be emitted when a window becomes urgent or loses its urgent status.
18 #
19 use i3test;
20
21 fresh_workspace;
22 my $win = open_window;
23 my $dummy_win = open_window;
24
25 sub urgency_subtest {
26 my ($subscribecb, $win, $want) = @_;
27
28 my @events = events_for(
29 $subscribecb,
30 'window');
31
32 my @urgent = grep { $_->{change} eq 'urgent' } @events;
33 is(scalar @urgent, 1, 'Received 1 window::urgent event');
34 is($urgent[0]->{container}->{window}, $win->{id}, "window id matches");
35 is($urgent[0]->{container}->{urgent}, $want, "urgent is $want");
36 }
37
38 subtest "urgency set", \&urgency_subtest,
39 sub {
40 $win->add_hint('urgency');
41 sync_with_i3;
42 },
43 $win,
44 1;
45
46 subtest "urgency unset", \&urgency_subtest,
47 sub {
48 $win->delete_hint('urgency');
49 sync_with_i3;
50 },
51 $win,
52 0;
53
54 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that entire outputs can be saved and restored properly by i3.
17 # Ticket: #1306
18 # Bug still in: 4.8-26-gf96ec19
19 use i3test;
20 use File::Temp qw(tempfile);
21 use IO::Handle;
22
23 my $ws = fresh_workspace;
24
25 ################################################################################
26 # Append a new workspace with a name.
27 ################################################################################
28
29 ok(!workspace_exists('ws_new'), 'workspace "ws_new" does not exist yet');
30
31 my ($fh, $filename) = tempfile(UNLINK => 1);
32 print $fh <<'EOT';
33 // vim:ts=4:sw=4:et
34 {
35 // workspace with 1 children
36 "border": "pixel",
37 "floating": "auto_off",
38 "layout": "splith",
39 "percent": null,
40 "type": "workspace",
41 "name": "ws_new",
42 "nodes": [
43 {
44 "border": "pixel",
45 "floating": "auto_off",
46 "geometry": {
47 "height": 268,
48 "width": 484,
49 "x": 0,
50 "y": 0
51 },
52 "name": "vals@w00t: ~",
53 "percent": 1,
54 "swallows": [
55 {
56 "class": "^URxvt$"
57 // "instance": "^urxvt$",
58 // "title": "^vals\\@w00t\\:\\ \\~$"
59 }
60 ],
61 "type": "con"
62 }
63 ]
64 }
65 EOT
66 $fh->flush;
67 cmd "append_layout $filename";
68
69 ok(workspace_exists('ws_new'), 'workspace "ws_new" exists now');
70
71 does_i3_live;
72
73 close($fh);
74
75 ################################################################################
76 # Append a new workspace with a name that clashes with an existing workspace.
77 ################################################################################
78
79 my @old_workspaces = @{get_workspace_names()};
80
81 cmd "append_layout $filename";
82
83 my @new_workspaces = @{get_workspace_names()};
84 cmp_ok(scalar @new_workspaces, '>', scalar @old_workspaces, 'more workspaces than before');
85
86 my %created_workspaces = map { ($_, 1) } @new_workspaces;
87 delete $created_workspaces{$_} for @old_workspaces;
88 diag('created workspaces = ' . Dumper(keys %created_workspaces));
89 cmp_ok(scalar keys %created_workspaces, '>', 0, 'new workspaces appeared');
90
91 ################################################################################
92 # Append a new workspace without a name.
93 ################################################################################
94
95 ok(!workspace_exists('unnamed'), 'workspace "unnamed" does not exist yet');
96
97 ($fh, $filename) = tempfile(UNLINK => 1);
98 print $fh <<'EOT';
99 // vim:ts=4:sw=4:et
100 {
101 // workspace with 1 children
102 "border": "pixel",
103 "floating": "auto_off",
104 "layout": "splith",
105 "percent": null,
106 "type": "workspace",
107 "nodes": [
108 {
109 "border": "pixel",
110 "floating": "auto_off",
111 "geometry": {
112 "height": 268,
113 "width": 484,
114 "x": 0,
115 "y": 0
116 },
117 "name": "vals@w00t: ~",
118 "percent": 1,
119 "swallows": [
120 {
121 "class": "^URxvt$"
122 // "instance": "^urxvt$",
123 // "title": "^vals\\@w00t\\:\\ \\~$"
124 }
125 ],
126 "type": "con"
127 }
128 ]
129 }
130 EOT
131 $fh->flush;
132 cmd "append_layout $filename";
133
134 ok(workspace_exists('unnamed'), 'workspace "unnamed" exists now');
135
136 ################################################################################
137 # Append a workspace with a numeric name, ensure it has ->num set.
138 ################################################################################
139
140 ok(!workspace_exists('4'), 'workspace "4" does not exist yet');
141
142 ($fh, $filename) = tempfile(UNLINK => 1);
143 print $fh <<'EOT';
144 // vim:ts=4:sw=4:et
145 {
146 // workspace with 1 children
147 "border": "pixel",
148 "floating": "auto_off",
149 "layout": "splith",
150 "percent": null,
151 "type": "workspace",
152 "name": "4",
153 "nodes": [
154 {
155 "border": "pixel",
156 "floating": "auto_off",
157 "geometry": {
158 "height": 268,
159 "width": 484,
160 "x": 0,
161 "y": 0
162 },
163 "name": "vals@w00t: ~",
164 "percent": 1,
165 "swallows": [
166 {
167 "class": "^URxvt$"
168 // "instance": "^urxvt$",
169 // "title": "^vals\\@w00t\\:\\ \\~$"
170 }
171 ],
172 "type": "con"
173 }
174 ]
175 }
176 EOT
177 $fh->flush;
178 cmd "append_layout $filename";
179
180 ok(workspace_exists('4'), 'workspace "4" exists now');
181 $ws = get_ws("4");
182 is($ws->{num}, 4, 'workspace number is 4');
183
184 ################################################################################
185 # Append a workspace with a numeric name, with the “type” property at the end
186 # of the JSON blurb (which is valid and sometimes happens).
187 ################################################################################
188
189 ok(!workspace_exists('5'), 'workspace "5" does not exist yet');
190
191 ($fh, $filename) = tempfile(UNLINK => 1);
192 print $fh <<'EOT';
193 // vim:ts=4:sw=4:et
194 {
195 // workspace with 1 children
196 "border": "pixel",
197 "floating": "auto_off",
198 "layout": "splith",
199 "percent": null,
200 "name": "5",
201 "nodes": [
202 {
203 "border": "pixel",
204 "floating": "auto_off",
205 "geometry": {
206 "height": 268,
207 "width": 484,
208 "x": 0,
209 "y": 0
210 },
211 "name": "vals@w00t: ~",
212 "percent": 1,
213 "swallows": [
214 {
215 "class": "^URxvt$"
216 // "instance": "^urxvt$",
217 // "title": "^vals\\@w00t\\:\\ \\~$"
218 }
219 ],
220 "type": "con"
221 }
222 ],
223 "type": "workspace"
224 }
225 EOT
226 $fh->flush;
227 cmd "append_layout $filename";
228
229 ok(workspace_exists('5'), 'workspace "5" exists now');
230 $ws = get_ws("5");
231 is($ws->{num}, 5, 'workspace number is 5');
232
233 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # This is a regression test for a bug where a normal floating default border is
17 # not applied when the default tiling border is set to a pixel value.
18 # Ticket: #1305
19 # Bug still in: 4.8-62-g7381b50
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 new_window pixel 5
25 new_float normal
26 EOT
27
28 my $ws = fresh_workspace;
29
30 my $float_window = open_floating_window;
31
32 my @floating = @{get_ws($ws)->{floating_nodes}};
33
34 is($floating[0]->{nodes}[0]->{border}, 'normal', 'default floating border is `normal`');
35
36 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that changes to WM_CLASS are internally processed by i3 by updating the
17 # cached property and running assignments. This allows the property to be used
18 # in criteria selection
19 # Ticket: #1052
20 # Bug still in: 4.8-73-g6bf7f8e
21 use i3test i3_config => <<EOT;
22 # i3 config file (v4)
23 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
24 for_window [class="Special"] mark special_class_mark
25 EOT
26 use X11::XCB qw(PROP_MODE_REPLACE);
27
28 sub change_window_class {
29 my ($window, $class, $length) = @_;
30 my $atomname = $x->atom(name => 'WM_CLASS');
31 my $atomtype = $x->atom(name => 'STRING');
32 $length ||= length($class) + 1;
33 $x->change_property(
34 PROP_MODE_REPLACE,
35 $window->id,
36 $atomname->id,
37 $atomtype->id,
38 8,
39 $length,
40 $class
41 );
42 sync_with_i3;
43 }
44
45 my $ws = fresh_workspace;
46
47 my $win = open_window;
48
49 change_window_class($win, "special\0Special");
50
51 my $con = @{get_ws_content($ws)}[0];
52
53 is($con->{window_properties}->{class}, 'Special',
54 'The container class should be updated when a window changes class');
55
56 is($con->{window_properties}->{instance}, 'special',
57 'The container instance should be updated when a window changes instance');
58
59 # The mark `special_class_mark` is added in a `for_window` assignment in the
60 # config for testing purposes
61 is_deeply($con->{marks}, [ 'special_class_mark' ],
62 'A `for_window` assignment should run for a match when the window changes class');
63
64 change_window_class($win, "abcdefghijklmnopqrstuv\0abcd", 24);
65
66 $con = @{get_ws_content($ws)}[0];
67
68 is($con->{window_properties}->{class}, 'a',
69 'Non-null-terminated strings should be handled correctly');
70
71 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that the binding event works properly
17 # Ticket: #1210
18 use i3test i3_config => <<EOT;
19 # i3 config file (v4)
20 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
21
22 bindsym r reload
23 EOT
24
25 SKIP: {
26 qx(which xdotool 2> /dev/null);
27
28 skip 'xdotool is required to test the binding event. `[apt-get install|pacman -S] xdotool`', 1 if $?;
29
30 qx(xdotool key r);
31
32 does_i3_live;
33
34 }
35 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that i3 does not crash when floating and then unfloating an
17 # unfocused window within a tabbed container.
18 # Ticket: #1484
19 # Bug still in: 4.9.1-124-g856e1f9
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23 workspace_layout tabbed
24 EOT
25
26 open_window;
27 open_window;
28
29 # Mark the second window, then focus the workspace.
30 cmd 'mark foo, focus parent, focus parent';
31
32 # Float and unfloat the marked window (without it being focused).
33 cmd '[con_mark=foo] floating enable, floating disable';
34
35 does_i3_live;
36
37 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests for setting and removing the _NET_WM_STATE_HIDDEN atom properly.
17 # Ticket: #1648
18 use i3test;
19 use X11::XCB qw(:all);
20
21 sub is_hidden {
22 sync_with_i3;
23 my $atom = $x->atom(name => '_NET_WM_STATE_HIDDEN');
24
25 my ($con) = @_;
26 my $cookie = $x->get_property(
27 0,
28 $con->{id},
29 $x->atom(name => '_NET_WM_STATE')->id,
30 GET_PROPERTY_TYPE_ANY,
31 0,
32 4096
33 );
34
35 my $reply = $x->get_property_reply($cookie->{sequence});
36 my $len = $reply->{length};
37 return 0 if $len == 0;
38
39 my @atoms = unpack("L$len", $reply->{value});
40 for (my $i = 0; $i < $len; $i++) {
41 return 1 if $atoms[$i] == $atom->id;
42 }
43
44 return 0;
45 }
46
47 my ($tabA, $tabB, $tabC, $subtabA, $subtabB, $windowA, $windowB);
48
49 ###############################################################################
50 # Given two containers next to each other, when focusing one, then the other
51 # one does not have _NET_WM_STATE_HIDDEN set.
52 ###############################################################################
53
54 fresh_workspace;
55 $windowA = open_window;
56 $windowB = open_window;
57
58 ok(!is_hidden($windowA), 'left window does not have _NET_WM_STATE_HIDDEN set');
59 ok(!is_hidden($windowB), 'right window does not have _NET_WM_STATE_HIDDEN set');
60
61 ###############################################################################
62 # Given two containers on different workspaces, when one is focused, then
63 # the other one does not have _NET_WM_STATE_HIDDEN set.
64 ###############################################################################
65
66 fresh_workspace;
67 $windowA = open_window;
68 fresh_workspace;
69 $windowB = open_window;
70
71 ok(!is_hidden($windowA), 'left window does not have _NET_WM_STATE_HIDDEN set');
72 ok(!is_hidden($windowB), 'right window does not have _NET_WM_STATE_HIDDEN set');
73
74 ###############################################################################
75 # Given two containers in the same tabbed container, when one is focused, then
76 # (only) the other one has _NET_WM_STATE_HIDDEN set.
77 # Given the other tab is focused, then the atom is transferred.
78 ###############################################################################
79
80 fresh_workspace;
81 $tabA = open_window;
82 cmd 'layout tabbed';
83 $tabB = open_window;
84
85 ok(is_hidden($tabA), 'unfocused tab has _NET_WM_STATE_HIDDEN set');
86 ok(!is_hidden($tabB), 'focused tab does not have _NET_WM_STATE_HIDDEN set');
87
88 cmd 'focus left';
89
90 ok(!is_hidden($tabA), 'focused tab does not have _NET_WM_STATE_HIDDEN set');
91 ok(is_hidden($tabB), 'unfocused tab has _NET_WM_STATE_HIDDEN set');
92
93 ###############################################################################
94 # Given three containers in the same stacked container, when the focused tab
95 # is moved to another workspace, then the now focused tab does not have
96 # _NET_WM_STATE_HIDDEN set anymore.
97 ###############################################################################
98
99 fresh_workspace;
100 $tabA = open_window;
101 cmd 'layout stacked';
102 $tabB = open_window;
103 $tabC = open_window;
104 cmd 'move window to workspace unused';
105
106 ok(is_hidden($tabA), 'unfocused tab has _NET_WM_STATE_HIDDEN set');
107 ok(!is_hidden($tabB), 'focused tab does not have _NET_WM_STATE_HIDDEN set');
108 ok(!is_hidden($tabC), 'moved window does not have _NET_WM_STATE_HIDDEN set');
109
110 ###############################################################################
111 # Given three containers in the same stacked container, when a not focused
112 # tab is moved to another workspace, then it does not have _NET_WM_STATE_HIDDEN
113 # set anymore.
114 ###############################################################################
115
116 fresh_workspace;
117 $tabA = open_window;
118 cmd 'layout stacked';
119 $tabB = open_window;
120 cmd 'mark moveme';
121 $tabC = open_window;
122 cmd '[con_mark="moveme"] move window to workspace unused';
123
124 ok(is_hidden($tabA), 'unfocused tab has _NET_WM_STATE_HIDDEN set');
125 ok(!is_hidden($tabB), 'moved window does not have _NET_WM_STATE_HIDDEN set');
126 ok(!is_hidden($tabC), 'focused tab does not have _NET_WM_STATE_HIDDEN set');
127
128 ###############################################################################
129 # Given a tabbed container and some other container, when the latter is moved
130 # into the tabbed container, then all other tabs have _NET_WM_STATE_HIDDEN
131 # set.
132 ###############################################################################
133
134 fresh_workspace;
135 $tabA = open_window;
136 cmd 'layout tabbed';
137 $tabB = open_window;
138 cmd 'focus parent';
139 cmd 'split h';
140 $tabC = open_window;
141 cmd 'move left';
142
143 ok(is_hidden($tabA), 'unfocused tab has _NET_WM_STATE_HIDDEN set');
144 ok(is_hidden($tabB), 'unfocused tab has _NET_WM_STATE_HIDDEN set');
145 ok(!is_hidden($tabC), 'focused tab does not have _NET_WM_STATE_HIDDEN set');
146
147 ###############################################################################
148 # Given a stacked container nested inside another tabbed container with the
149 # inner one being in the currently focused tab, then the focused tab of the
150 # inner container does not have _NET_WM_STATE_HIDDEN set.
151 ###############################################################################
152
153 fresh_workspace;
154 $tabA = open_window;
155 cmd 'layout tabbed';
156 $tabB = open_window;
157 cmd 'split h';
158 open_window;
159 cmd 'split v';
160 cmd 'layout stacked';
161 $subtabA = open_window;
162 $subtabB = open_window;
163
164 ok(is_hidden($tabA), 'unfocused outer tab has _NET_WM_STATE_HIDDEN set');
165 ok(!is_hidden($tabB), 'focused outer tab does not have _NET_WM_STATE_HIDDEN set');
166 ok(is_hidden($subtabA), 'unfocused inner tab has _NET_WM_STATE_HIDDEN set');
167 ok(!is_hidden($subtabB), 'focused inner tab does not have _NET_WM_STATE_HIDDEN set');
168
169 cmd 'focus left';
170
171 ok(!is_hidden($subtabB), 'focused inner tab does not have _NET_WM_STATE_HIDDEN set');
172
173 ###############################################################################
174 # Given a stacked container nested inside another tabbed container with the
175 # inner one being in a currently not focused tab, then all tabs of the inner
176 # container have _NET_WM_STATE_HIDDEN set.
177 ###############################################################################
178
179 fresh_workspace;
180 $tabA = open_window;
181 cmd 'layout tabbed';
182 $tabB = open_window;
183 cmd 'split h';
184 open_window;
185 cmd 'split v';
186 cmd 'layout stacked';
187 $subtabA = open_window;
188 $subtabB = open_window;
189 cmd 'focus parent';
190 cmd 'focus parent';
191 cmd 'focus left';
192
193 ok(!is_hidden($tabA), 'focused outer tab does not have _NET_WM_STATE_HIDDEN set');
194 ok(is_hidden($tabB), 'unfocused outer tab has _NET_WM_STATE_HIDDEN set');
195 ok(is_hidden($subtabA), 'unfocused inner tab has _NET_WM_STATE_HIDDEN set');
196 ok(is_hidden($subtabB), 'unfocused inner tab has _NET_WM_STATE_HIDDEN set');
197
198 ###############################################################################
199
200 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that _NET_WM_VISIBLE_NAME is set correctly.
17 # Ticket: #1872
18 use i3test;
19 use X11::XCB qw(:all);
20
21 my ($con);
22
23 sub get_visible_name {
24 sync_with_i3;
25 my ($con) = @_;
26
27 my $cookie = $x->get_property(
28 0,
29 $con->{id},
30 $x->atom(name => '_NET_WM_VISIBLE_NAME')->id,
31 $x->atom(name => 'UTF8_STRING')->id,
32 0,
33 4096
34 );
35
36 my $reply = $x->get_property_reply($cookie->{sequence});
37 return undef if $reply->{value_len} == 0;
38 return $reply->{value};
39 }
40
41 ###############################################################################
42 # 1: _NET_WM_VISIBLE_NAME is set when the title format of a window is changed.
43 ###############################################################################
44
45 fresh_workspace;
46 $con = open_window(name => 'boring title');
47 is(get_visible_name($con), undef, 'sanity check: initially no visible name is set');
48
49 cmd 'title_format custom';
50 is(get_visible_name($con), 'custom', 'the visible name is updated');
51
52 cmd 'title_format "<s>%title</s>"';
53 is(get_visible_name($con), '<s>boring title</s>', 'markup is returned as is');
54
55 ###############################################################################
56 # 2: _NET_WM_VISIBLE_NAME is removed if not needed.
57 ###############################################################################
58
59 fresh_workspace;
60 $con = open_window(name => 'boring title');
61 cmd 'title_format custom';
62 is(get_visible_name($con), 'custom', 'sanity check: a visible name is set');
63
64 cmd 'title_format %title';
65 is(get_visible_name($con), undef, 'the visible name is removed again');
66
67 ###############################################################################
68
69 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests sticky windows.
17 # Ticket: #1455
18 use i3test i3_config => <<EOT;
19 # i3 config file (v4)
20 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
21
22 workspace ws-on-0 output fake-0
23
24 fake-outputs 1024x768+0+0,1024x768+1024+0
25 EOT
26
27 my ($ws, $tmp, $focused);
28
29 ###############################################################################
30 # 1: Given a sticky tiling container, when the workspace is switched, then
31 # nothing happens.
32 ###############################################################################
33 fresh_workspace;
34 open_window;
35 cmd 'sticky enable';
36 $ws = fresh_workspace;
37
38 is(@{get_ws($ws)->{nodes}}, 0, 'tiling sticky container did not move');
39 is(@{get_ws($ws)->{floating_nodes}}, 0, 'tiling sticky container did not move');
40 kill_all_windows;
41
42 ###############################################################################
43 # 2: Given a sticky floating container, when the workspace is switched, then
44 # the container moves to the new workspace.
45 ###############################################################################
46 $ws = fresh_workspace;
47 open_floating_window;
48 $focused = get_focused($ws);
49 cmd 'sticky enable';
50 $ws = fresh_workspace;
51
52 is(@{get_ws($ws)->{floating_nodes}}, 1, 'floating sticky container moved to new workspace');
53 is(get_focused($ws), $focused, 'sticky container has focus');
54 kill_all_windows;
55
56 ###############################################################################
57 # 3: Given two sticky floating containers, when the workspace is switched,
58 # then both containers move to the new workspace.
59 ###############################################################################
60 fresh_workspace;
61 open_floating_window;
62 cmd 'sticky enable';
63 open_floating_window;
64 cmd 'sticky enable';
65 $ws = fresh_workspace;
66
67 is(@{get_ws($ws)->{floating_nodes}}, 2, 'multiple sticky windows can be used at the same time');
68 kill_all_windows;
69
70 ###############################################################################
71 # 4: Given an unfocused sticky floating container and a tiling container on the
72 # target workspace, when the workspace is switched, then the tiling container
73 # is focused.
74 ###############################################################################
75 $ws = fresh_workspace;
76 open_window;
77 $focused = get_focused($ws);
78 fresh_workspace;
79 open_floating_window;
80 cmd 'sticky enable';
81 open_window;
82 cmd 'workspace ' . $ws;
83
84 is(get_focused($ws), $focused, 'the tiling container has focus');
85 kill_all_windows;
86
87 ###############################################################################
88 # 5: Given a focused sticky floating container and a tiling container on the
89 # target workspace, when the workspace is switched, then the tiling container
90 # is focused.
91 ###############################################################################
92 $ws = fresh_workspace;
93 open_window;
94 $tmp = fresh_workspace;
95 open_floating_window;
96 $focused = get_focused($tmp);
97 cmd 'sticky enable';
98 cmd 'workspace ' . $ws;
99
100 is(get_focused($ws), $focused, 'the sticky container has focus');
101 kill_all_windows;
102
103 ###############################################################################
104 # 6: Given a floating container on a non-visible workspace, when the window
105 # is made sticky, then the window immediately jumps to the currently
106 # visible workspace.
107 ###############################################################################
108 fresh_workspace;
109 open_floating_window;
110 cmd 'mark sticky';
111 $ws = fresh_workspace;
112 cmd '[con_mark=sticky] sticky enable';
113
114 is(@{get_ws($ws)->{floating_nodes}}, 1, 'the sticky window jumps to the front');
115 kill_all_windows;
116
117 ###############################################################################
118 # 7: Given a sticky floating container and a workspace on another output, when
119 # a new workspace assigned to the first output is focused, then the sticky
120 # container should jump to the new workspace and have input focus correctly.
121 ###############################################################################
122 $ws = fresh_workspace(output => 0);
123 open_floating_window;
124 cmd 'sticky enabled';
125 $focused = get_focused($ws);
126 $ws = fresh_workspace(output => 1);
127
128 is(@{get_ws($ws)->{floating_nodes}}, 0, 'the sticky window didn\'t jump to a workspace on a different output');
129 $ws = 'ws-on-0';
130 cmd "workspace $ws";
131 is(@{get_ws($ws)->{floating_nodes}}, 1, 'the sticky window moved to new workspace on first output');
132 is(get_focused($ws), $focused, 'the sticky window has focus');
133 kill_all_windows;
134
135 ###############################################################################
136
137 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that mouse bindings work on the root window if
17 # --whole-window is set.
18 # Ticket: #2115
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 workspace_auto_back_and_forth no
24 bindsym --whole-window button4 workspace special
25 EOT
26 use i3test::XTEST;
27
28 fresh_workspace;
29
30 xtest_button_press(4, 50, 50);
31 xtest_button_release(4, 50, 50);
32 xtest_sync_with_i3;
33
34 is(focused_ws(), 'special', 'the binding was triggered');
35
36 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that the hide_edge_borders smart option works
17 # Ticket: #2188
18
19 use i3test i3_autostart => 0;
20
21 ####################################################################
22 # 1: check that the borders are present on a floating windows
23 #####################################################################
24
25 my $config = <<EOT;
26 # i3 config file (v4)
27 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
28
29 new_window pixel 2
30 new_float pixel 2
31 hide_edge_borders smart
32 EOT
33
34 my $pid = launch_with_config($config);
35
36 my $tmp = fresh_workspace;
37
38 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
39
40 my $floatwindow = open_floating_window;
41
42 my $wscontent = get_ws($tmp);
43
44 my @floating = @{$wscontent->{floating_nodes}};
45 ok(@floating == 1, 'one floating container opened');
46 is($floating[0]->{nodes}[0]->{current_border_width}, 2, 'floating current border width set to 2');
47 is($floatwindow->rect->width, $floating[0]->{rect}->{width} - 2*2, 'floating border width 2');
48
49 exit_gracefully($pid);
50
51 #####################################################################
52 # 2: check that the borders are present on a workspace with two tiled
53 # windows visible
54 #####################################################################
55
56 $config = <<EOT;
57 # i3 config file (v4)
58 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
59
60 new_window pixel 2
61 new_float pixel 2
62 hide_edge_borders smart
63 EOT
64
65 $pid = launch_with_config($config);
66
67 $tmp = fresh_workspace;
68
69 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
70
71 my $tilewindow = open_window;
72 my $tilewindow2 = open_window;
73
74 $wscontent = get_ws($tmp);
75
76 my @tiled = @{$wscontent->{nodes}};
77 ok(@tiled == 2, 'two tiled container opened');
78 is($tiled[0]->{current_border_width}, 2, 'first tiled current border width set to 2');
79 is($tilewindow->rect->width, $tiled[0]->{rect}->{width} - 2*2, 'first tiled border width 2');
80 is($tiled[1]->{current_border_width}, 2, 'second tiled current border width set to 2');
81 is($tilewindow2->rect->width, $tiled[1]->{rect}->{width} - 2*2, 'second tiled border width 2');
82
83 exit_gracefully($pid);
84
85 #####################################################################
86 # 3: check that the borders are hidden on a workspace with one tiled
87 # window visible
88 #####################################################################
89
90 $config = <<EOT;
91 # i3 config file (v4)
92 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
93
94 new_window pixel 2
95 new_float pixel 2
96 hide_edge_borders smart
97 EOT
98
99 $pid = launch_with_config($config);
100
101 $tmp = fresh_workspace;
102
103 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
104
105 $tilewindow = open_window;
106
107 $wscontent = get_ws($tmp);
108
109 @tiled = @{$wscontent->{nodes}};
110 ok(@tiled == 1, 'one tiled container opened');
111 is($tiled[0]->{current_border_width}, 2, 'tiled current border width set to 2');
112 is($tilewindow->rect->width, $tiled[0]->{rect}->{width} - 2*0, 'single tiled border width 0');
113
114 exit_gracefully($pid);
115
116 #####################################################################
117 # 4: check that the borders are present on a workspace with two tiled
118 # windows visible, recursively
119 #####################################################################
120
121 $config = <<EOT;
122 # i3 config file (v4)
123 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
124
125 new_window pixel 2
126 new_float pixel 2
127 hide_edge_borders smart
128 EOT
129
130 $pid = launch_with_config($config);
131
132 $tmp = fresh_workspace;
133
134 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
135
136 $tilewindow = open_window;
137 $tilewindow2 = open_window;
138 ok(@{get_ws_content($tmp)} == 2, 'two containers opened');
139
140 cmd 'layout tabbed';
141 ok(@{get_ws_content($tmp)} == 1, 'layout tabbed -> back to one container');
142
143 cmd 'focus parent';
144 my $tilewindow3 = open_window;
145 ok(@{get_ws_content($tmp)} == 2, 'after split & new window, two containers');
146
147 $wscontent = get_ws($tmp);
148
149 # Ensure i3’s X11 requests are processed before our inquiry via
150 # $tilewindow->rect:
151 sync_with_i3;
152
153 @tiled = @{$wscontent->{nodes}};
154 ok(@tiled == 2, 'two tiled container opened in another container');
155 is($tiled[0]->{current_border_width}, -1, 'first tiled current border width set to -1');
156 is($tilewindow->rect->width, $tiled[0]->{rect}->{width} - 2*2, 'first tiled border width 2');
157 is($tiled[1]->{current_border_width}, 2, 'second tiled current border width set to 2');
158 is($tilewindow2->rect->width, $tiled[1]->{rect}->{width} - 2*2, 'second tiled border width 2');
159
160 exit_gracefully($pid);
161
162 #####################################################################
163 # 5: check that the borders are visible on a workspace with one tiled
164 # window and edge gaps
165 #####################################################################
166
167 $config = <<EOT;
168 # i3 config file (v4)
169 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
170
171 new_window pixel 2
172 new_float pixel 2
173 gaps outer 5
174 hide_edge_borders smart_no_gaps
175 EOT
176
177 $pid = launch_with_config($config);
178
179 $tmp = fresh_workspace;
180
181 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
182
183 $tilewindow = open_window;
184
185 $wscontent = get_ws($tmp);
186
187 @tiled = @{$wscontent->{nodes}};
188 ok(@tiled == 1, 'one tiled container opened');
189 is($tiled[0]->{current_border_width}, 2, 'tiled current border width set to 2');
190 is($tilewindow->rect->width, $tiled[0]->{rect}->{width} - 2*2, 'single tiled border width 2');
191
192 exit_gracefully($pid);
193
194 #####################################################################
195 # 5: check that the borders are hidden on a workspace with one tiled
196 # window with no gaps
197 #####################################################################
198
199 $config = <<EOT;
200 # i3 config file (v4)
201 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
202
203 new_window pixel 2
204 new_float pixel 2
205 hide_edge_borders smart_no_gaps
206 EOT
207
208 $pid = launch_with_config($config);
209
210 $tmp = fresh_workspace;
211
212 ok(@{get_ws_content($tmp)} == 0, 'no containers yet');
213
214 $tilewindow = open_window;
215
216 $wscontent = get_ws($tmp);
217
218 @tiled = @{$wscontent->{nodes}};
219 ok(@tiled == 1, 'one tiled container opened');
220 is($tiled[0]->{current_border_width}, 2, 'tiled current border width set to 2');
221 is($tilewindow->rect->width, $tiled[0]->{rect}->{width} - 2*0, 'single tiled border width 0');
222
223 exit_gracefully($pid);
224
225
226
227 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests for our proprietary atom I3_FLOATING_WINDOW to allow
17 # identifying floating windows.
18 # Ticket: #2223
19 use i3test;
20 use X11::XCB qw(:all);
21
22 my ($con);
23
24 sub has_i3_floating_window {
25 sync_with_i3;
26
27 my ($con) = @_;
28 my $cookie = $x->get_property(
29 0,
30 $con->{id},
31 $x->atom(name => 'I3_FLOATING_WINDOW')->id,
32 $x->atom(name => 'CARDINAL')->id,
33 0,
34 1
35 );
36
37 my $reply = $x->get_property_reply($cookie->{sequence});
38 return 0 if $reply->{length} != 1;
39
40 return unpack("L", $reply->{value});
41 }
42
43 ###############################################################################
44 # Toggling floating on a container adds / removes I3_FLOATING_WINDOW.
45 ###############################################################################
46
47 fresh_workspace;
48
49 $con = open_window;
50 is(has_i3_floating_window($con), 0, 'I3_FLOATING_WINDOW is not set');
51
52 cmd 'floating enable';
53 is(has_i3_floating_window($con), 1, 'I3_FLOATING_WINDOW is set');
54
55 cmd 'floating disable';
56 is(has_i3_floating_window($con), 0, 'I3_FLOATING_WINDOW is not set');
57
58 ###############################################################################
59 # A window that is floated when managed has I3_FLOATING_WINDOW set.
60 ###############################################################################
61 #
62 fresh_workspace;
63
64 $con = open_floating_window;
65 is(has_i3_floating_window($con), 1, 'I3_FLOATING_WINDOW is set');
66
67 ###############################################################################
68
69 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test the ipc shutdown event. This event is triggered when the connection to
17 # the ipc is about to shutdown because of a user action such as with a
18 # `restart` or `exit` command. The `change` field indicates why the ipc is
19 # shutting down. It can be either "restart" or "exit".
20 #
21 # Ticket: #2318
22 # Bug still in: 4.12-46-g2123888
23 use i3test;
24
25 # We cannot use events_for in this test as we cannot send events after
26 # issuing the restart/shutdown command.
27
28 my $i3 = i3(get_socket_path());
29 $i3->connect->recv;
30
31 my $cv = AnyEvent->condvar;
32 my $timer = AnyEvent->timer(after => 0.5, interval => 0, cb => sub { $cv->send(0); });
33
34 $i3->subscribe({
35 shutdown => sub {
36 $cv->send(shift);
37 }
38 })->recv;
39
40 cmd 'restart';
41
42 my $e = $cv->recv;
43
44 diag "Event:\n", Dumper($e);
45 ok($e, 'the shutdown event should emit when the ipc is restarted by command');
46 is($e->{change}, 'restart', 'the `change` field should tell the reason for the shutdown');
47
48 # restarting kills the ipc client so we have to make a new one
49 $i3 = i3(get_socket_path());
50 $i3->connect->recv;
51
52 $cv = AnyEvent->condvar;
53 $timer = AnyEvent->timer(after => 0.5, interval => 0, cb => sub { $cv->send(0); });
54
55 $i3->subscribe({
56 shutdown => sub {
57 $cv->send(shift);
58 }
59 })->recv;
60
61 cmd 'exit';
62
63 $e = $cv->recv;
64
65 diag "Event:\n", Dumper($e);
66 ok($e, 'the shutdown event should emit when the ipc is exited by command');
67 is($e->{change}, 'exit', 'the `change` field should tell the reason for the shutdown');
68
69 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that one can bind on numpad keys in different numlock states.
17 # Ticket: #2346
18 # Bug still in: 4.12-78-g85bb324
19 use i3test i3_autostart => 0;
20 use i3test::XTEST;
21 use ExtUtils::PkgConfig;
22
23 SKIP: {
24 skip "libxcb-xkb too old (need >= 1.11)", 1 unless
25 ExtUtils::PkgConfig->atleast_version('xcb-xkb', '1.11');
26
27 my $config = <<EOT;
28 # i3 config file (v4)
29 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
30
31 # Same key, different numlock states.
32 bindsym Mod2+KP_1 nop KP_1
33 bindsym KP_End nop KP_End
34
35 # Binding which should work with numlock and without.
36 bindsym Mod4+a nop a
37
38 # Binding which should work with numlock and without, see issue #2418.
39 bindsym Escape nop Escape
40
41 # Binding which should work with numlock and without, see issue #2418.
42 bindsym Shift+Escape nop Shift+Escape
43
44 # Binding which should work with numlock and without, see issue #2418.
45 bindsym Mod1+Shift+q nop Mod1+Shift+q
46
47 # Binding which should work with numlock and without, see issue #2559.
48 bindcode 39 nop s
49 EOT
50
51 my $pid = launch_with_config($config);
52
53 is(listen_for_binding(
54 sub {
55 xtest_key_press(87); # KP_End
56 xtest_key_release(87); # KP_End
57 xtest_sync_with_i3;
58 },
59 ),
60 'KP_End',
61 'triggered the "KP_End" keybinding');
62
63 is(listen_for_binding(
64 sub {
65 xtest_key_press(77); # enable Num_Lock
66 xtest_key_release(77); # enable Num_Lock
67 xtest_key_press(87); # KP_1
68 xtest_key_release(87); # KP_1
69 xtest_key_press(77); # disable Num_Lock
70 xtest_key_release(77); # disable Num_Lock
71 xtest_sync_with_i3;
72 },
73 ),
74 'KP_1',
75 'triggered the "KP_1" keybinding');
76
77 is(listen_for_binding(
78 sub {
79 xtest_key_press(133); # Super_L
80 xtest_key_press(38); # a
81 xtest_key_release(38); # a
82 xtest_key_release(133); # Super_L
83 xtest_sync_with_i3;
84 },
85 ),
86 'a',
87 'triggered the "a" keybinding');
88
89 is(listen_for_binding(
90 sub {
91 xtest_key_press(77); # enable Num_Lock
92 xtest_key_release(77); # enable Num_Lock
93 xtest_key_press(133); # Super_L
94 xtest_key_press(38); # a
95 xtest_key_release(38); # a
96 xtest_key_release(133); # Super_L
97 xtest_key_press(77); # disable Num_Lock
98 xtest_key_release(77); # disable Num_Lock
99 xtest_sync_with_i3;
100 },
101 ),
102 'a',
103 'triggered the "a" keybinding');
104
105 is(listen_for_binding(
106 sub {
107 xtest_key_press(9); # Escape
108 xtest_key_release(9); # Escape
109 xtest_sync_with_i3;
110 },
111 ),
112 'Escape',
113 'triggered the "Escape" keybinding');
114
115 is(listen_for_binding(
116 sub {
117 xtest_key_press(77); # enable Num_Lock
118 xtest_key_release(77); # enable Num_Lock
119 xtest_key_press(9); # Escape
120 xtest_key_release(9); # Escape
121 xtest_key_press(77); # disable Num_Lock
122 xtest_key_release(77); # disable Num_Lock
123 xtest_sync_with_i3;
124 },
125 ),
126 'Escape',
127 'triggered the "Escape" keybinding');
128
129 is(listen_for_binding(
130 sub {
131 xtest_key_press(50); # Shift_L
132 xtest_key_press(9); # Escape
133 xtest_key_release(9); # Escape
134 xtest_key_release(50); # Shift_L
135 xtest_sync_with_i3;
136 },
137 ),
138 'Shift+Escape',
139 'triggered the "Escape" keybinding');
140
141 is(listen_for_binding(
142 sub {
143 xtest_key_press(77); # enable Num_Lock
144 xtest_key_release(77); # enable Num_Lock
145 xtest_key_press(50); # Shift_L
146 xtest_key_press(9); # Escape
147 xtest_key_release(9); # Escape
148 xtest_key_release(50); # Shift_L
149 xtest_key_press(77); # disable Num_Lock
150 xtest_key_release(77); # disable Num_Lock
151 xtest_sync_with_i3;
152 },
153 ),
154 'Shift+Escape',
155 'triggered the "Escape" keybinding');
156
157 is(listen_for_binding(
158 sub {
159 xtest_key_press(50); # Shift_L
160 xtest_key_press(64); # Alt_L
161 xtest_key_press(24); # q
162 xtest_key_release(24); # q
163 xtest_key_release(64); # Alt_L
164 xtest_key_release(50); # Shift_L
165 xtest_sync_with_i3;
166 },
167 ),
168 'Mod1+Shift+q',
169 'triggered the "Mod1+Shift+q" keybinding');
170
171 is(listen_for_binding(
172 sub {
173 xtest_key_press(77); # enable Num_Lock
174 xtest_key_release(77); # enable Num_Lock
175 xtest_key_press(50); # Shift_L
176 xtest_key_press(64); # Alt_L
177 xtest_key_press(24); # q
178 xtest_key_release(24); # q
179 xtest_key_release(64); # Alt_L
180 xtest_key_release(50); # Shift_L
181 xtest_key_press(77); # disable Num_Lock
182 xtest_key_release(77); # disable Num_Lock
183 xtest_sync_with_i3;
184 },
185 ),
186 'Mod1+Shift+q',
187 'triggered the "Mod1+Shift+q" keybinding');
188
189 is(listen_for_binding(
190 sub {
191 xtest_key_press(39); # s
192 xtest_key_release(39); # s
193 xtest_sync_with_i3;
194 },
195 ),
196 's',
197 'triggered the "s" keybinding without Num_Lock');
198
199 is(listen_for_binding(
200 sub {
201 xtest_key_press(77); # enable Num_Lock
202 xtest_key_release(77); # enable Num_Lock
203 xtest_key_press(39); # s
204 xtest_key_release(39); # s
205 xtest_key_press(77); # disable Num_Lock
206 xtest_key_release(77); # disable Num_Lock
207 xtest_sync_with_i3;
208 },
209 ),
210 's',
211 'triggered the "s" keybinding with Num_Lock');
212
213 exit_gracefully($pid);
214
215 ################################################################################
216 # Verify bindings for modifiers work
217 ################################################################################
218
219 $config = <<EOT;
220 # i3 config file (v4)
221 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
222
223 bindsym Mod4+Return nop Return
224
225 # Binding which should work with numlock and without, see issue #2559.
226 bindcode --release 133 nop Super_L
227 EOT
228
229 $pid = launch_with_config($config);
230
231 is(listen_for_binding(
232 sub {
233 xtest_key_press(133); # Super_L
234 xtest_key_release(133); # Super_L
235 xtest_sync_with_i3;
236 },
237 ),
238 'Super_L',
239 'triggered the "Super_L" keybinding without Num_Lock');
240
241 is(listen_for_binding(
242 sub {
243 xtest_key_press(77); # enable Num_Lock
244 xtest_key_release(77); # enable Num_Lock
245 xtest_key_press(133); # Super_L
246 xtest_key_release(133); # Super_L
247 xtest_key_press(77); # disable Num_Lock
248 xtest_key_release(77); # disable Num_Lock
249 xtest_sync_with_i3;
250 },
251 ),
252 'Super_L',
253 'triggered the "Super_L" keybinding with Num_Lock');
254
255 is(listen_for_binding(
256 sub {
257 xtest_key_press(133); # Super_L
258 xtest_key_press(36); # Return
259 xtest_key_release(36); # Return
260 xtest_key_release(133); # Super_L
261 xtest_sync_with_i3;
262 },
263 ),
264 'Return',
265 'triggered the "Return" keybinding without Num_Lock');
266
267 is(listen_for_binding(
268 sub {
269 xtest_key_press(77); # enable Num_Lock
270 xtest_key_release(77); # enable Num_Lock
271 xtest_key_press(133); # Super_L
272 xtest_key_press(36); # Return
273 xtest_key_release(36); # Return
274 xtest_key_release(133); # Super_L
275 xtest_key_press(77); # disable Num_Lock
276 xtest_key_release(77); # disable Num_Lock
277 xtest_sync_with_i3;
278 },
279 ),
280 'Return',
281 'triggered the "Return" keybinding with Num_Lock');
282
283 exit_gracefully($pid);
284
285 ################################################################################
286 # Verify the binding is only triggered for KP_End, not KP_1
287 ################################################################################
288
289 $config = <<EOT;
290 # i3 config file (v4)
291 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
292
293 bindsym KP_End nop KP_End
294 bindcode 88 nop KP_Down
295 EOT
296
297 $pid = launch_with_config($config);
298
299 is(listen_for_binding(
300 sub {
301 xtest_key_press(87); # KP_End
302 xtest_key_release(87); # KP_End
303 xtest_sync_with_i3;
304 },
305 ),
306 'KP_End',
307 'triggered the "KP_End" keybinding');
308
309 is(listen_for_binding(
310 sub {
311 xtest_key_press(88); # KP_Down
312 xtest_key_release(88); # KP_Down
313 xtest_sync_with_i3;
314 },
315 ),
316 'KP_Down',
317 'triggered the "KP_Down" keybinding');
318
319 my @unexpected = events_for(
320 sub {
321 xtest_key_press(77); # enable Num_Lock
322 xtest_key_release(77); # enable Num_Lock
323 xtest_key_press(87); # KP_1
324 xtest_key_release(87); # KP_1
325 xtest_key_press(77); # disable Num_Lock
326 xtest_key_release(77); # disable Num_Lock
327 xtest_sync_with_i3;
328 },
329 'binding');
330 is(scalar @unexpected, 0, 'Did not trigger the KP_End keybinding with KP_1');
331
332 my @unexpected2 = events_for(
333 sub {
334 xtest_key_press(77); # enable Num_Lock
335 xtest_key_release(77); # enable Num_Lock
336 xtest_key_press(88); # KP_2
337 xtest_key_release(88); # KP_2
338 xtest_key_press(77); # disable Num_Lock
339 xtest_key_release(77); # disable Num_Lock
340 xtest_sync_with_i3;
341 },
342 'binding');
343
344 is(scalar @unexpected2, 0, 'Did not trigger the KP_Down keybinding with KP_2');
345
346 # TODO: This test does not verify that i3 does _NOT_ grab keycode 87 with Mod2.
347
348 exit_gracefully($pid);
349
350 ################################################################################
351 # Verify mouse bindings are unaffected by NumLock
352 ################################################################################
353
354 $config = <<EOT;
355 # i3 config file (v4)
356 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
357
358 bindsym --whole-window button4 nop button4
359 EOT
360
361 $pid = launch_with_config($config);
362
363 my $win = open_window;
364
365 is(listen_for_binding(
366 sub {
367 xtest_key_press(77); # enable Num_Lock
368 xtest_key_release(77); # enable Num_Lock
369 xtest_button_press(4, 50, 50);
370 xtest_button_release(4, 50, 50);
371 xtest_key_press(77); # disable Num_Lock
372 xtest_key_release(77); # disable Num_Lock
373 xtest_sync_with_i3;
374 },
375 ),
376 'button4',
377 'triggered the button4 keybinding with NumLock');
378
379 is(listen_for_binding(
380 sub {
381 xtest_button_press(4, 50, 50);
382 xtest_button_release(4, 50, 50);
383 xtest_sync_with_i3;
384 },
385 ),
386 'button4',
387 'triggered the button4 keybinding without NumLock');
388
389 exit_gracefully($pid);
390
391 }
392
393 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests the swap command.
17 # Ticket: #917
18 use i3test i3_autostart => 0;
19
20 my $config = <<EOT;
21 # i3 config file (v4)
22 font font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 for_window[class="mark_A"] mark A
25 for_window[class="mark_B"] mark B
26 EOT
27 my $pid = launch_with_config($config);
28
29 my ($ws, $ws1, $ws2, $ws3);
30 my ($node, $nodes, $expected_focus, $A, $B, $F);
31 my ($result);
32 my @fullscreen_permutations = ([], ["A"], ["B"], ["A", "B"]);
33 my $rect_A = [ 100, 100, 100, 100 ];
34 my $rect_B = [ 200, 200, 200, 200 ];
35 my @urgent;
36
37 sub fullscreen_windows {
38 my $ws = shift if @_;
39
40 scalar grep { $_->{fullscreen_mode} != 0 } @{get_ws_content($ws)}
41 }
42
43 sub cmp_floating_rect {
44 my ($window, $rect, $prefix) = @_;
45 sync_with_i3;
46 my ($absolute, $top) = $window->rect;
47
48 is($absolute->{width}, $rect->[2], "$prefix: width matches");
49 is($absolute->{height}, $rect->[3], "$prefix: height matches");
50
51 is($top->{x}, $rect->[0], "$prefix: x matches");
52 is($top->{y}, $rect->[1], "$prefix: y matches");
53 }
54
55 ###############################################################################
56 # Invalid con_id should not crash i3
57 # See issue #2895.
58 ###############################################################################
59
60 $ws = fresh_workspace;
61
62 open_window;
63 cmd "swap container with con_id 1";
64
65 does_i3_live;
66 kill_all_windows;
67
68 ###############################################################################
69 # Swap 2 windows in different workspaces using con_id
70 ###############################################################################
71
72 $ws = fresh_workspace;
73 open_window;
74 $A = get_focused($ws);
75
76 $ws = fresh_workspace;
77 open_window;
78
79 cmd "swap container with con_id $A";
80 is(get_focused($ws), $A, 'A is now focused');
81
82 kill_all_windows;
83
84 ###############################################################################
85 # Swap two containers next to each other.
86 # Focus should stay on B because both windows are on the focused workspace.
87 # The focused container is B.
88 #
89 # +---+---+ Layout: H1[ A B ]
90 # | A | B | Focus Stacks:
91 # +---+---+ H1: B, A
92 ###############################################################################
93 $ws = fresh_workspace;
94
95 $A = open_window(wm_class => 'mark_A');
96 $B = open_window(wm_class => 'mark_B');
97 $expected_focus = get_focused($ws);
98
99 cmd '[con_mark=B] swap container with mark A';
100
101 $nodes = get_ws_content($ws);
102 is($nodes->[0]->{window}, $B->{id}, 'B is on the left');
103 is($nodes->[1]->{window}, $A->{id}, 'A is on the right');
104 is(get_focused($ws), $expected_focus, 'B is still focused');
105
106 kill_all_windows;
107
108 ###############################################################################
109 # Swap two containers with different parents.
110 # In this test, the focus head of the left v-split container is A.
111 # The focused container is B.
112 #
113 # +---+---+ Layout: H1[ V1[ A Y ] V2[ X B ] ]
114 # | A | X | Focus Stacks:
115 # +---+---+ H1: V2, V1
116 # | Y | B | V1: A, Y
117 # +---+---+ V2: B, X
118 ###############################################################################
119 $ws = fresh_workspace;
120
121 $A = open_window(wm_class => 'mark_A');
122 $B = open_window(wm_class => 'mark_B');
123 cmd 'split v';
124 open_window;
125 cmd 'move up, focus left';
126 cmd 'split v';
127 open_window;
128 cmd 'focus up, focus right, focus down';
129 $expected_focus = get_focused($ws);
130
131 cmd '[con_mark=B] swap container with mark A';
132
133 $nodes = get_ws_content($ws);
134 is($nodes->[0]->{nodes}->[0]->{window}, $B->{id}, 'B is on the top left');
135 is($nodes->[1]->{nodes}->[1]->{window}, $A->{id}, 'A is on the bottom right');
136 is(get_focused($ws), $expected_focus, 'B is still focused');
137
138 kill_all_windows;
139
140 ###############################################################################
141 # Swap two containers with different parents.
142 # In this test, the focus head of the left v-split container is _not_ A.
143 # The focused container is B.
144 #
145 # +---+---+ Layout: H1[ V1[ A Y ] V2[ X B ] ]
146 # | A | X | Focus Stacks:
147 # +---+---+ H1: V2, V1
148 # | Y | B | V1: Y, A
149 # +---+---+ V2: B, X
150 ###############################################################################
151 $ws = fresh_workspace;
152
153 $A = open_window(wm_class => 'mark_A');
154 $B = open_window(wm_class => 'mark_B');
155 cmd 'split v';
156 open_window;
157 cmd 'move up, focus left';
158 cmd 'split v';
159 open_window;
160 cmd 'focus right, focus down';
161 $expected_focus = get_focused($ws);
162
163 cmd '[con_mark=B] swap container with mark A';
164
165 $nodes = get_ws_content($ws);
166 is($nodes->[0]->{nodes}->[0]->{window}, $B->{id}, 'B is on the top left');
167 is($nodes->[1]->{nodes}->[1]->{window}, $A->{id}, 'A is on the bottom right');
168 is(get_focused($ws), $expected_focus, 'B is still focused');
169
170 kill_all_windows;
171
172 ###############################################################################
173 # Swap two containers with one being on a different workspace.
174 # The focused container is B.
175 #
176 # Layout: O1[ W1[ H1 ] W2[ H2 ] ]
177 # Focus Stacks:
178 # O1: W2, W1
179 #
180 # +---+---+ Layout: H1[ A X ]
181 # | A | X | Focus Stacks:
182 # +---+---+ H1: A, X
183 #
184 # +---+---+ Layout: H2[ Y, B ]
185 # | Y | B | Focus Stacks:
186 # +---+---+ H2: B, Y
187 ###############################################################################
188 for my $fullscreen (@fullscreen_permutations){
189 $ws1 = fresh_workspace;
190 $A = open_window(wm_class => 'mark_A');
191 $expected_focus = get_focused($ws1);
192 open_window;
193 cmd 'focus left';
194
195 $ws2 = fresh_workspace;
196 open_window;
197 $B = open_window(wm_class => 'mark_B');
198
199 my $A_fullscreen = "A" ~~ @$fullscreen || 0;
200 my $B_fullscreen = "B" ~~ @$fullscreen || 0;
201 $A->fullscreen($A_fullscreen);
202 $B->fullscreen($B_fullscreen);
203 sync_with_i3;
204
205 cmd '[con_mark=B] swap container with mark A';
206
207 $nodes = get_ws_content($ws1);
208 $node = $nodes->[0];
209 is($node->{window}, $B->{id}, 'B is on ws1:left');
210 is_num_fullscreen($ws1, $A_fullscreen, 'amount of fullscreen windows in ws1');
211 is($node->{fullscreen_mode}, $A_fullscreen, 'B got A\'s fullscreen mode');
212
213 $nodes = get_ws_content($ws2);
214 $node = $nodes->[1];
215 is($node->{window}, $A->{id}, 'A is on ws2:right');
216 is(get_focused($ws2), $expected_focus, 'A is focused');
217 is_num_fullscreen($ws2, $B_fullscreen, 'amount of fullscreen windows in ws2');
218 is($node->{fullscreen_mode}, $B_fullscreen, 'A got B\'s fullscreen mode');
219
220 kill_all_windows;
221 }
222
223 ###############################################################################
224 # Swap a non-fullscreen window with a fullscreen one in different workspaces.
225 # Layout: O1[ W1[ H1 ] W2[ B ] ]
226 #
227 # +---+---+ Layout: H1[ A F ]
228 # | A | F | Focus Stacks:
229 # +---+---+ H1: F, A
230 #
231 # +---+---+
232 # | B |
233 # +---+---+
234 ###############################################################################
235 $ws1 = fresh_workspace;
236
237 $A = open_window(wm_class => 'mark_A');
238 $F = open_window();
239 $F->fullscreen(1);
240 $expected_focus = get_focused($ws1);
241
242 $ws2 = fresh_workspace;
243 $B = open_window(wm_class => 'mark_B');
244 $B->fullscreen(1);
245 sync_with_i3;
246
247 cmd '[con_mark=B] swap container with mark A';
248
249 $nodes = get_ws_content($ws1);
250 is($nodes->[0]->{window}, $B->{id}, 'B is on ws1:left');
251 is_num_fullscreen($ws1, 1, 'F still fullscreen in ws1');
252 is(get_focused($ws1), $expected_focus, 'F is still focused');
253
254 $nodes = get_ws_content($ws2);
255 is($nodes->[0]->{window}, $A->{id}, 'A is on ws1');
256
257 ###############################################################################
258 # Try a more exotic layout with fullscreen containers.
259 # A and F are fullscreened as a stack of two vertical containers before the
260 # swap is performed.
261 # A is swapped with fullscreened window B which is in another workspace.
262 #
263 # +---+---+ Layout: H1[ X V1[ A F ] ]
264 # | | A | Focus Stacks:
265 # | X +---+ H1: V1, X
266 # | | F | V1: F, A
267 # +---+---+
268 ###############################################################################
269 $ws1 = fresh_workspace;
270
271 open_window;
272 $A = open_window(wm_class => 'mark_A');
273 cmd "split v";
274 open_window;
275 cmd "focus parent";
276 cmd "fullscreen enable";
277 $expected_focus = get_focused($ws1);
278
279 $ws2 = fresh_workspace;
280 $B = open_window(wm_class => 'mark_B');
281 $B->fullscreen(1);
282 sync_with_i3;
283
284 cmd '[con_mark=B] swap container with mark A';
285
286 does_i3_live;
287
288 $nodes = get_ws_content($ws1);
289 is($nodes->[1]->{nodes}->[0]->{window}, $B->{id}, 'B is on top right in ws1');
290 is(get_focused($ws1), $expected_focus, 'The container of the stacked windows remains focused in ws1');
291 is_num_fullscreen($ws1, 1, 'Same amount of fullscreen windows in ws1');
292
293 $nodes = get_ws_content($ws2);
294 is($nodes->[0]->{window}, $A->{id}, 'A is on ws2');
295 is_num_fullscreen($ws2, 1, 'A is in fullscreen mode');
296
297 ###############################################################################
298 # Swap two non-focused containers within the same workspace.
299 #
300 # +---+---+ Layout: H1[ V1[ A X ] V2[ F B ] ]
301 # | A | F | Focus Stacks:
302 # +---+---+ H1: V2, V1
303 # | X | B | V1: A, X
304 # +---+---+ V2: F, B
305 ###############################################################################
306 $ws = fresh_workspace;
307
308 $A = open_window(wm_class => 'mark_A');
309 $B = open_window(wm_class => 'mark_B');
310 cmd 'split v';
311 open_window;
312 cmd 'move up, focus left';
313 cmd 'split v';
314 open_window;
315 cmd 'focus up, focus right';
316 $expected_focus = get_focused($ws);
317
318 cmd '[con_mark=B] swap container with mark A';
319
320 $nodes = get_ws_content($ws);
321 is($nodes->[0]->{nodes}->[0]->{window}, $B->{id}, 'B is on the top left');
322 is($nodes->[1]->{nodes}->[1]->{window}, $A->{id}, 'A is on the bottom right');
323 is(get_focused($ws), $expected_focus, 'F is still focused');
324
325 kill_all_windows;
326
327 ###############################################################################
328 # Swap two non-focused containers which are both on different workspaces.
329 #
330 # Layout: O1[ W1[ A ] W2[ B ] W3[ F ] ]
331 # Focus Stacks:
332 # O1: W3, W2, W1
333 #
334 # +---+
335 # | A |
336 # +---+
337 #
338 # +---+
339 # | B |
340 # +---+
341 #
342 # +---+
343 # | F |
344 # +---+
345 ###############################################################################
346 for my $fullscreen (@fullscreen_permutations){
347 $ws1 = fresh_workspace;
348 $A = open_window(wm_class => 'mark_A');
349
350 $ws2 = fresh_workspace;
351 $B = open_window(wm_class => 'mark_B');
352
353 $ws3 = fresh_workspace;
354 open_window;
355 $expected_focus = get_focused($ws3);
356
357 my $A_fullscreen = "A" ~~ @$fullscreen || 0;
358 my $B_fullscreen = "B" ~~ @$fullscreen || 0;
359 $A->fullscreen($A_fullscreen);
360 $B->fullscreen($B_fullscreen);
361 sync_with_i3;
362
363 cmd '[con_mark=B] swap container with mark A';
364
365 $nodes = get_ws_content($ws1);
366 $node = $nodes->[0];
367 is($node->{window}, $B->{id}, 'B is on the first workspace');
368 is_num_fullscreen($ws1, $A_fullscreen, 'amount of fullscreen windows in ws1');
369 is($node->{fullscreen_mode}, $A_fullscreen, 'B got A\'s fullscreen mode');
370
371 $nodes = get_ws_content($ws2);
372 $node = $nodes->[0];
373 is($node->{window}, $A->{id}, 'A is on the second workspace');
374 is_num_fullscreen($ws2, $B_fullscreen, 'amount of fullscreen windows in ws2');
375 is($node->{fullscreen_mode}, $B_fullscreen, 'A got B\'s fullscreen mode');
376
377 is(get_focused($ws3), $expected_focus, 'F is still focused');
378
379 kill_all_windows;
380 }
381
382 ###############################################################################
383 # Swap two non-focused containers with one being on a different workspace.
384 #
385 # Layout: O1[ W1[ A ] W2[ H2 ] ]
386 # Focus Stacks:
387 # O1: W2, W1
388 #
389 # +---+
390 # | A |
391 # +---+
392 #
393 # +---+---+ Layout: H2[ B, F ]
394 # | B | F | Focus Stacks:
395 # +---+---+ H2: F, B
396 #
397 # See issue: #3259
398 ###############################################################################
399
400 for my $fullscreen (0..1){
401 $ws1 = fresh_workspace;
402 $A = open_window(wm_class => 'mark_A');
403
404 $ws2 = fresh_workspace;
405 $B = open_window(wm_class => 'mark_B');
406 open_window;
407 cmd 'fullscreen enable' if $fullscreen;
408 $expected_focus = get_focused($ws2);
409
410 cmd '[con_mark=B] swap container with mark A';
411
412 $nodes = get_ws_content($ws1);
413 is($nodes->[0]->{window}, $B->{id}, 'B is on the first workspace');
414
415 $nodes = get_ws_content($ws2);
416 is($nodes->[0]->{window}, $A->{id}, 'A is on the left of the second workspace');
417 is(get_focused($ws2), $expected_focus, 'F is still focused');
418
419 kill_all_windows;
420 }
421
422 ###############################################################################
423 # 1. A container cannot be swapped with its parent.
424 # 2. A container cannot be swapped with one of its children.
425 #
426 # ↓A↓
427 # +---+---+ Layout: H1[ X V1[ Y B ] ]
428 # | | Y | (with A := V1)
429 # | X +---+
430 # | | B |
431 # +---+---+
432 ###############################################################################
433 $ws = fresh_workspace;
434 open_window;
435 open_window;
436 cmd 'split v';
437 $B = open_window(wm_class => 'mark_B');
438 cmd 'focus parent, mark A, focus child';
439
440 $result = cmd '[con_mark=B] swap container with mark A';
441 is($result->[0]->{success}, 0, 'B cannot be swappd with its parent');
442
443 $result = cmd '[con_mark=A] swap container with mark B';
444 is($result->[0]->{success}, 0, 'A cannot be swappd with one of its children');
445
446 kill_all_windows;
447
448 ###############################################################################
449 # Swapping two containers preserves the geometry of the container they are
450 # being swapped with.
451 #
452 # Before:
453 # +---+-------+
454 # | A | B |
455 # +---+-------+
456 #
457 # After:
458 # +---+-------+
459 # | B | A |
460 # +---+-------+
461 ###############################################################################
462 $ws = fresh_workspace;
463 $A = open_window(wm_class => 'mark_A');
464 $B = open_window(wm_class => 'mark_B');
465 cmd 'resize grow width 0 or 25 ppt';
466
467 # sanity checks
468 $nodes = get_ws_content($ws);
469 cmp_float($nodes->[0]->{percent}, 0.25, 'A has 25% width');
470 cmp_float($nodes->[1]->{percent}, 0.75, 'B has 75% width');
471
472 cmd '[con_mark=B] swap container with mark A';
473
474 $nodes = get_ws_content($ws);
475 cmp_float($nodes->[0]->{percent}, 0.25, 'B has 25% width');
476 cmp_float($nodes->[1]->{percent}, 0.75, 'A has 75% width');
477
478 kill_all_windows;
479
480 ###############################################################################
481 # Swapping containers not sharing the same parent preserves the geometry of
482 # the container they are swapped with.
483 #
484 # Before:
485 # +---+-----+
486 # | A | |
487 # +---+ B |
488 # | | |
489 # | Y +-----+
490 # | | X |
491 # +---+-----+
492 #
493 # After:
494 # +---+-----+
495 # | B | |
496 # +---+ A |
497 # | | |
498 # | Y +-----+
499 # | | X |
500 # +---+-----+
501 ###############################################################################
502 $ws = fresh_workspace;
503
504 $A = open_window(wm_class => 'mark_A');
505 $B = open_window(wm_class => 'mark_B');
506 cmd 'split v';
507 open_window;
508 cmd 'focus up, resize grow height 0 or 25 ppt';
509 cmd 'focus left, split v';
510 open_window;
511 cmd 'resize grow height 0 or 25 ppt';
512
513 # sanity checks
514 $nodes = get_ws_content($ws);
515 cmp_float($nodes->[0]->{nodes}->[0]->{percent}, 0.25, 'A has 25% height');
516 cmp_float($nodes->[1]->{nodes}->[0]->{percent}, 0.75, 'B has 75% height');
517
518 cmd '[con_mark=B] swap container with mark A';
519
520 $nodes = get_ws_content($ws);
521 cmp_float($nodes->[0]->{nodes}->[0]->{percent}, 0.25, 'B has 25% height');
522 cmp_float($nodes->[1]->{nodes}->[0]->{percent}, 0.75, 'A has 75% height');
523
524 kill_all_windows;
525
526 ###############################################################################
527 # Swap floating windows in the same workspace. Check that they exchange rects.
528 ###############################################################################
529 $ws = fresh_workspace;
530
531 $A = open_floating_window(wm_class => 'mark_A', rect => $rect_A);
532 $B = open_floating_window(wm_class => 'mark_B', rect => $rect_B);
533
534 cmd '[con_mark=B] swap container with mark A';
535 cmp_floating_rect($A, $rect_B, 'A got B\'s rect');
536 cmp_floating_rect($B, $rect_A, 'B got A\'s rect');
537
538 kill_all_windows;
539
540 ###############################################################################
541 # Swap a fullscreen floating and a normal floating window.
542 ###############################################################################
543 $ws1 = fresh_workspace;
544 $A = open_floating_window(wm_class => 'mark_A', rect => $rect_A, fullscreen => 1);
545 $ws2 = fresh_workspace;
546 $B = open_floating_window(wm_class => 'mark_B', rect => $rect_B);
547
548 cmd '[con_mark=B] swap container with mark A';
549
550 cmp_floating_rect($A, $rect_B, 'A got B\'s rect');
551
552 $nodes = get_ws($ws1);
553 $node = $nodes->{floating_nodes}->[0]->{nodes}->[0];
554 is($node->{window}, $B->{id}, 'B is on the first workspace');
555 is($node->{fullscreen_mode}, 1, 'B is now fullscreened');
556
557 $nodes = get_ws($ws2);
558 $node = $nodes->{floating_nodes}->[0]->{nodes}->[0];
559 is($node->{window}, $A->{id}, 'A is on the second workspace');
560 is($node->{fullscreen_mode}, 0, 'A is not fullscreened anymore');
561
562 kill_all_windows;
563
564 ###############################################################################
565 # Swap a floating window which is in a workspace that has another, regular
566 # window with a regular window in another workspace. A & B focused.
567 #
568 # Before:
569 # +-----------+
570 # | F |
571 # | +---+ |
572 # | | A | |
573 # | +---+ |
574 # | |
575 # +-----------+
576 #
577 # +-----------+
578 # | |
579 # | |
580 # | B |
581 # | |
582 # | |
583 # +-----------+
584 #
585 # After: Same as above but A <-> B. A & B focused.
586 ###############################################################################
587 $ws1 = fresh_workspace;
588 open_window;
589 $A = open_floating_window(wm_class => 'mark_A', rect => $rect_A);
590 $ws2 = fresh_workspace;
591 $B = open_window(wm_class => 'mark_B');
592 $expected_focus = get_focused($ws2);
593
594 cmd '[con_mark=B] swap container with mark A';
595
596 $nodes = get_ws($ws1);
597 $node = $nodes->{floating_nodes}->[0]->{nodes}->[0];
598 is($node->{window}, $B->{id}, 'B is floating on the first workspace');
599 is(get_focused($ws1), $expected_focus, 'B is focused');
600 cmp_floating_rect($B, $rect_A, 'B got A\'s rect');
601
602 $nodes = get_ws_content($ws2);
603 $node = $nodes->[0];
604 is($node->{window}, $A->{id}, 'A is on the second workspace');
605
606 kill_all_windows;
607
608 ###################################################################
609 # Test that swapping a floating window maintains the correct
610 # floating order.
611 ###################################################################
612 $ws = fresh_workspace;
613 $A = open_floating_window(wm_class => 'mark_A', rect => $rect_A);
614 $B = open_window(wm_class => 'mark_B');
615 $F = open_floating_window;
616 $expected_focus = get_focused($ws);
617
618 cmd '[con_mark=B] swap container with mark A';
619
620 $nodes = get_ws($ws);
621
622 $node = $nodes->{floating_nodes}->[0]->{nodes}->[0];
623 is($node->{window}, $B->{id}, 'B is floating, bottom');
624 cmp_floating_rect($B, $rect_A, 'B got A\'s rect');
625
626 $node = $nodes->{floating_nodes}->[1]->{nodes}->[0];
627 is($node->{window}, $F->{id}, 'F is floating, top');
628 is(get_focused($ws), $expected_focus, 'F still focused');
629
630 $node = $nodes->{nodes}->[0];
631 is($node->{window}, $A->{id}, 'A is tiling');
632
633 kill_all_windows;
634
635 ###############################################################################
636 # Swap a sticky, floating container A and a floating fullscreen container B.
637 # A should remain sticky and floating and should be fullscreened.
638 ###############################################################################
639 $ws1 = fresh_workspace;
640 open_window;
641 $A = open_floating_window(wm_class => 'mark_A', rect => $rect_A);
642 $expected_focus = get_focused($ws1);
643 cmd 'sticky enable';
644 $B = open_floating_window(wm_class => 'mark_B', rect => $rect_B);
645 cmd 'fullscreen enable';
646
647 cmd '[con_mark=B] swap container with mark A';
648
649 is(@{get_ws($ws1)->{floating_nodes}}, 2, '2 fullscreen containers on first workspace');
650 is(get_focused($ws1), $expected_focus, 'A is focused');
651
652 $ws2 = fresh_workspace;
653 cmd 'fullscreen disable';
654 cmp_floating_rect($A, $rect_B, 'A got B\'s rect');
655 is(@{get_ws($ws2)->{floating_nodes}}, 1, 'only A in new workspace');
656
657 cmd "workspace $ws1"; # TODO: Why does rect check fails without switching workspaces?
658 cmp_floating_rect($B, $rect_A, 'B got A\'s rect');
659
660 kill_all_windows;
661
662 ###############################################################################
663 # Swapping containers moves the urgency hint correctly.
664 ###############################################################################
665
666 $ws1 = fresh_workspace;
667 $A = open_window(wm_class => 'mark_A');
668 $ws2 = fresh_workspace;
669 $B = open_window(wm_class => 'mark_B');
670 open_window;
671
672 $B->add_hint('urgency');
673 sync_with_i3;
674
675 cmd '[con_mark=B] swap container with mark A';
676
677 @urgent = grep { $_->{urgent} } @{get_ws_content($ws1)};
678 is(@urgent, 1, 'B is marked urgent');
679 is(get_ws($ws1)->{urgent}, 1, 'the first workspace is marked urgent');
680
681 @urgent = grep { $_->{urgent} } @{get_ws_content($ws2)};
682 is(@urgent, 0, 'A is not marked urgent');
683 is(get_ws($ws2)->{urgent}, 0, 'the second workspace is not marked urgent');
684
685 kill_all_windows;
686
687 ###############################################################################
688 # Swapping an urgent container from another workspace with the focused
689 # container removes the urgency hint from both the container and the previous
690 # workspace.
691 ###############################################################################
692
693 $ws2 = fresh_workspace;
694 $B = open_window(wm_class => 'mark_B');
695 $ws1 = fresh_workspace;
696 $A = open_window(wm_class => 'mark_A');
697
698 $B->add_hint('urgency');
699 sync_with_i3;
700
701 cmd '[con_mark=B] swap container with mark A';
702
703 @urgent = grep { $_->{urgent} } @{get_ws_content($ws1)};
704 is(@urgent, 0, 'B is not marked urgent');
705 is(get_ws($ws1)->{urgent}, 0, 'the first workspace is not marked urgent');
706
707 @urgent = grep { $_->{urgent} } @{get_ws_content($ws2)};
708 is(@urgent, 0, 'A is not marked urgent');
709 is(get_ws($ws2)->{urgent}, 0, 'the second workspace is not marked urgent');
710
711 kill_all_windows;
712
713 exit_gracefully($pid);
714
715 ###############################################################################
716 # Test that swapping with workspace_layout doesn't crash i3.
717 # See issue #3280.
718 ###############################################################################
719
720 $config = <<EOT;
721 # i3 config file (v4)
722 font font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
723
724 workspace_layout stacking
725 EOT
726 $pid = launch_with_config($config);
727
728 $ws = fresh_workspace;
729 open_window;
730 open_window;
731 $B = open_window;
732
733 cmd 'move right';
734 cmd 'focus left, focus parent, mark a';
735 cmd 'focus right';
736 cmd 'swap with mark a';
737
738 does_i3_live;
739
740 $nodes = get_ws_content($ws);
741 is($nodes->[0]->{window}, $B->{id}, 'B is on the left');
742
743 exit_gracefully($pid);
744
745 ###############################################################################
746
747 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test: verify layout toggle with invalid parameters does not set
17 # layout to L_DEFAULT, which crashes i3 upon the next IPC message.
18 # Ticket: #2903
19 # Bug still in: 4.14-87-g607e97e6
20 use i3test;
21
22 cmd 'layout toggle 1337 1337';
23
24 fresh_workspace;
25
26 does_i3_live;
27
28 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests the focus_follows_mouse setting.
17 use i3test i3_config => <<EOT;
18 # i3 config file (v4)
19 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
20
21 fake-outputs 1000x1000+0+0
22 EOT
23
24 my ($first, $second);
25
26 sub synced_warp_pointer {
27 my ($x_px, $y_px) = @_;
28 sync_with_i3;
29 $x->root->warp_pointer($x_px, $y_px);
30 sync_with_i3;
31 }
32
33 ###################################################################
34 # Test a simple case with 2 windows.
35 ###################################################################
36
37 synced_warp_pointer(600, 600);
38 $first = open_window;
39 $second = open_window;
40 is($x->input_focus, $second->id, 'second window focused');
41
42 synced_warp_pointer(0, 0);
43 is($x->input_focus, $first->id, 'first window focused');
44
45 ###################################################################
46 # Test that focus isn't changed with tabbed windows.
47 ###################################################################
48
49 fresh_workspace;
50 synced_warp_pointer(600, 600);
51 $first = open_window;
52 cmd 'layout tabbed';
53 $second = open_window;
54 is($x->input_focus, $second->id, 'second (tabbed) window focused');
55
56 synced_warp_pointer(0, 0);
57 is($x->input_focus, $second->id, 'second window still focused');
58
59 ###################################################################
60 # Test that floating windows are focused but not raised to the top.
61 # See issue #2990.
62 ###################################################################
63
64 my $ws;
65 my $tmp = fresh_workspace;
66 my ($first_floating, $second_floating);
67
68 synced_warp_pointer(0, 0);
69 $first_floating = open_floating_window(rect => [ 1, 1, 100, 100 ]);
70 $second_floating = open_floating_window(rect => [ 50, 50, 100, 100 ]);
71 $first = open_window;
72
73 is($x->input_focus, $first->id, 'first (tiling) window focused');
74 $ws = get_ws($tmp);
75 is($ws->{floating_nodes}->[1]->{nodes}->[0]->{window}, $second_floating->id, 'second floating on top');
76 is($ws->{floating_nodes}->[0]->{nodes}->[0]->{window}, $first_floating->id, 'first floating behind');
77
78 synced_warp_pointer(40, 40);
79 is($x->input_focus, $first_floating->id, 'first floating window focused');
80 $ws = get_ws($tmp);
81 is($ws->{floating_nodes}->[1]->{nodes}->[0]->{window}, $second_floating->id, 'second floating still on top');
82 is($ws->{floating_nodes}->[0]->{nodes}->[0]->{window}, $first_floating->id, 'first floating still behind');
83
84 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that i3 does not crash when opening a floating sticky on one output
17 # and then switching empty workspaces on the other output.
18 # Ticket: #3075
19 # Bug still in: 4.14-191-g9d2d602d
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23 fake-outputs 1024x768+0+0,1024x768+1024+0
24 EOT
25
26 # A window on the left output.
27 fresh_workspace(output => 0);
28 open_window;
29 cmd 'sticky enable, floating enable';
30
31 # Switch to the right output and open a new workspace.
32 my $ws = fresh_workspace(output => 1);
33 does_i3_live;
34
35 # Verify results.
36 is(@{get_ws($ws)->{floating_nodes}}, 0, 'workspace in right output is empty');
37 $ws = fresh_workspace(output => 0);
38 is(@{get_ws($ws)->{floating_nodes}}, 1, 'new workspace in left output has the sticky container');
39
40 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verify that the corrent focus stack order is preserved after various
17 # operations.
18 use i3test i3_config => <<EOT;
19 # i3 config file (v4)
20 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
21 fake-outputs 1024x768+0+0,1024x768+1024+0
22 EOT
23
24 sub kill_and_confirm_focus {
25 my $focus = shift;
26 my $msg = shift;
27 cmd "kill";
28 sync_with_i3;
29 is($x->input_focus, $focus, $msg);
30 }
31
32 my @windows;
33 my $ws;
34
35 sub focus_windows {
36 for (my $i = $#windows; $i >= 0; $i--) {
37 cmd '[id=' . $windows[$i]->id . '] focus';
38 }
39 }
40
41 sub confirm_focus {
42 my $msg = shift;
43 sync_with_i3;
44 is($x->input_focus, $windows[0]->id, $msg . ': window 0 focused');
45 foreach my $i (1 .. $#windows) {
46 kill_and_confirm_focus($windows[$i]->id, "$msg: window $i focused");
47 }
48 cmd 'kill';
49 @windows = ();
50 }
51
52 #####################################################################
53 # Open 5 windows, focus them in a custom order and then change to
54 # tabbed layout. The focus order should be preserved.
55 #####################################################################
56
57 fresh_workspace;
58
59 $windows[3] = open_window;
60 $windows[1] = open_window;
61 $windows[0] = open_window;
62 $windows[2] = open_window;
63 $windows[4] = open_window;
64 focus_windows;
65
66 cmd 'layout tabbed';
67 confirm_focus('tabbed');
68
69 #####################################################################
70 # Same as above but with stacked.
71 #####################################################################
72
73 fresh_workspace;
74 $windows[3] = open_window;
75 $windows[1] = open_window;
76 $windows[0] = open_window;
77 $windows[2] = open_window;
78 $windows[4] = open_window;
79 focus_windows;
80
81 cmd 'layout stacked';
82 confirm_focus('stacked');
83
84 #####################################################################
85 # Open 4 windows horizontally, move the last one down. The focus
86 # order should be preserved.
87 #####################################################################
88
89 fresh_workspace;
90 $windows[3] = open_window;
91 $windows[2] = open_window;
92 $windows[1] = open_window;
93 $windows[0] = open_window;
94
95 cmd 'move down';
96 confirm_focus('split-h + move');
97
98 #####################################################################
99 # Same as above but with a vertical split.
100 #####################################################################
101
102 fresh_workspace;
103 $windows[3] = open_window;
104 cmd 'split v';
105 $windows[2] = open_window;
106 $windows[1] = open_window;
107 $windows[0] = open_window;
108
109 cmd 'move left';
110 confirm_focus('split-v + move');
111
112 #####################################################################
113 # Test that moving an unfocused container from another output
114 # maintains the correct focus order.
115 #####################################################################
116
117 fresh_workspace(output => 0);
118 $windows[3] = open_window;
119 fresh_workspace(output => 1);
120 $windows[2] = open_window;
121 $windows[1] = open_window;
122 $windows[0] = open_window;
123
124 cmd '[id=' . $windows[3]->id . '] move right';
125 confirm_focus('unfocused move from other output');
126
127 #####################################################################
128 # Test that moving an unfocused container inside its original parent
129 # maintains the correct focus order.
130 #####################################################################
131
132 fresh_workspace;
133 $windows[0] = open_window;
134 $windows[1] = open_window;
135 cmd 'split v';
136 $windows[2] = open_window;
137 $windows[3] = open_window;
138 focus_windows;
139
140 cmd '[id=' . $windows[2]->id . '] move up';
141 confirm_focus('split-v + unfocused move inside parent');
142
143 ######################################################################
144 # Test that moving an unfocused container maintains the correct focus
145 # order.
146 # Layout: H [ A V1 [ B C D ] ]
147 ######################################################################
148
149 fresh_workspace;
150 $windows[3] = open_window;
151 $windows[2] = open_window;
152 cmd 'split v';
153 $windows[1] = open_window;
154 $windows[0] = open_window;
155
156 cmd '[id=' . $windows[3]->id . '] move right';
157 confirm_focus('split-v + unfocused move');
158
159 ######################################################################
160 # Test that moving an unfocused container from inside a split
161 # container to another workspace doesn't focus sibling.
162 ######################################################################
163
164 $ws = fresh_workspace;
165 $windows[0] = open_window;
166 $windows[1] = open_window;
167 cmd 'split v';
168 open_window;
169 cmd 'mark a';
170
171 cmd '[id=' . $windows[0]->id . '] focus';
172 cmd '[con_mark=a] move to workspace ' . get_unused_workspace;
173
174 is(@{get_ws_content($ws)}, 2, 'Sanity check: marked window moved');
175 confirm_focus('Move unfocused window from split container');
176
177 ######################################################################
178 # Moving containers to another workspace puts them on the top of the
179 # focus stack but behind the focused container.
180 ######################################################################
181
182 for my $new_workspace (0 .. 1) {
183 fresh_workspace;
184 $windows[2] = open_window;
185 $windows[1] = open_window;
186 fresh_workspace if $new_workspace;
187 $windows[3] = open_window;
188 $windows[0] = open_window;
189 cmd 'mark target';
190
191 cmd '[id=' . $windows[2]->id . '] move to mark target';
192 cmd '[id=' . $windows[1]->id . '] move to mark target';
193 confirm_focus('\'move to mark\' focus order' . ($new_workspace ? ' when moving containers from other workspace' : ''));
194 }
195
196 ######################################################################
197 # Same but with workspace commands.
198 ######################################################################
199
200 fresh_workspace;
201 $windows[2] = open_window;
202 $windows[1] = open_window;
203 $ws = fresh_workspace;
204 $windows[3] = open_window;
205 $windows[0] = open_window;
206 cmd 'mark target';
207
208 cmd '[id=' . $windows[2]->id . '] move to workspace ' . $ws;
209 cmd '[id=' . $windows[1]->id . '] move to workspace ' . $ws;
210 confirm_focus('\'move to workspace\' focus order when moving containers from other workspace');
211
212 ######################################################################
213 # Swapping sibling containers correctly swaps focus order.
214 ######################################################################
215
216 sub swap_with_ids {
217 my ($idx1, $idx2) = @_;
218 cmd '[id=' . $windows[$idx1]->id . '] swap container with id ' . $windows[$idx2]->id;
219 }
220
221 $ws = fresh_workspace;
222 $windows[2] = open_window;
223 $windows[0] = open_window;
224 $windows[3] = open_window;
225 $windows[1] = open_window;
226
227 # If one of the swapees is focused we deliberately preserve its focus, switch
228 # workspaces to move focus away from the windows.
229 fresh_workspace;
230
231 # 2 0 3 1 <- focus order in this direction
232 swap_with_ids(3, 1);
233 # 2 0 1 3
234 swap_with_ids(2, 3);
235 # 3 0 1 2
236 swap_with_ids(0, 2);
237 # 3 2 1 0
238
239 # Restore input focus for confirm_focus
240 cmd "workspace $ws";
241
242 # Also confirm swap worked
243 $ws = get_ws($ws);
244 for my $i (0 .. 3) {
245 my $node = $ws->{nodes}->[3 - $i];
246 is($node->{window}, $windows[$i]->id, "window $i in correct position after swap");
247 }
248
249 confirm_focus('\'swap container with id\' focus order');
250
251 ######################################################################
252 # Test focus order with floating and tiling windows.
253 # See issue: 1975
254 ######################################################################
255
256 fresh_workspace;
257 $windows[2] = open_window;
258 $windows[0] = open_window;
259 $windows[3] = open_floating_window;
260 $windows[1] = open_floating_window;
261 focus_windows;
262
263 confirm_focus('mix of floating and tiling windows');
264
265 ######################################################################
266 # Same but an unfocused tiling window is killed first.
267 ######################################################################
268
269 fresh_workspace;
270 $windows[2] = open_window;
271 $windows[0] = open_window;
272 $windows[3] = open_floating_window;
273 $windows[1] = open_floating_window;
274 focus_windows;
275
276 cmd '[id=' . $windows[1]->id . '] focus';
277 cmd '[id=' . $windows[0]->id . '] kill';
278
279 kill_and_confirm_focus($windows[2]->id, 'window 2 focused after tiling killed');
280 kill_and_confirm_focus($windows[3]->id, 'window 3 focused after tiling killed');
281
282 ######################################################################
283 # cmp_tree tests
284 ######################################################################
285
286 cmp_tree(
287 msg => 'Basic test',
288 layout_before => 'S[a b] V[c d T[e f g*]]',
289 layout_after => ' ',
290 cb => sub {
291 @windows = reverse @{$_[0]};
292 confirm_focus('focus order');
293 });
294
295 cmp_tree(
296 msg => 'Focused container that is moved to mark keeps focus',
297 layout_before => 'S[a b] V[2 3 T[4 5* 6]]',
298 layout_after => 'S[a b*]',
299 cb => sub {
300 cmd '[class=' . $_[0][3]->id . '] mark 3';
301 cmd 'move to mark 3';
302
303 $windows[0] = $_[0][5];
304 $windows[1] = $_[0][6];
305 $windows[2] = $_[0][4];
306 $windows[3] = $_[0][3];
307 $windows[4] = $_[0][2];
308 confirm_focus('focus order');
309 });
310
311 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies _NET_DESKTOP_NAMES, _NET_CURRENT_DESKTOP and _NET_CURRENT_DESKTOP
17 # are updated properly when closing an inactive workspace container.
18 # See github issue #3126
19
20 use i3test;
21
22 sub get_desktop_names {
23 sync_with_i3;
24
25 my $cookie = $x->get_property(
26 0,
27 $x->get_root_window(),
28 $x->atom(name => '_NET_DESKTOP_NAMES')->id,
29 $x->atom(name => 'UTF8_STRING')->id,
30 0,
31 4096,
32 );
33
34 my $reply = $x->get_property_reply($cookie->{sequence});
35
36 return 0 if $reply->{value_len} == 0;
37
38 # the property is a null-delimited list of utf8 strings ;;
39 return split /\0/, $reply->{value};
40 }
41
42 sub get_num_of_desktops {
43 sync_with_i3;
44
45 my $cookie = $x->get_property(
46 0,
47 $x->get_root_window(),
48 $x->atom(name => '_NET_NUMBER_OF_DESKTOPS')->id,
49 $x->atom(name => 'CARDINAL')->id,
50 0,
51 4,
52 );
53
54 my $reply = $x->get_property_reply($cookie->{sequence});
55
56 return undef if $reply->{value_len} != 1;
57 return undef if $reply->{format} != 32;
58 return undef if $reply->{type} != $x->atom(name => 'CARDINAL')->id,;
59
60 return unpack 'L', $reply->{value};
61 }
62
63 sub get_current_desktop {
64 sync_with_i3;
65
66 my $cookie = $x->get_property(
67 0,
68 $x->get_root_window(),
69 $x->atom(name => '_NET_CURRENT_DESKTOP')->id,
70 $x->atom(name => 'CARDINAL')->id,
71 0,
72 4,
73 );
74
75 my $reply = $x->get_property_reply($cookie->{sequence});
76
77 return undef if $reply->{value_len} != 1;
78 return undef if $reply->{format} != 32;
79 return undef if $reply->{type} != $x->atom(name => 'CARDINAL')->id,;
80
81 return unpack 'L', $reply->{value};
82 }
83
84 cmd 'workspace 0';
85 my $first = open_window;
86
87 cmd 'workspace 1';
88 my $second = open_window;
89
90 cmd 'workspace 2';
91 my $third = open_window;
92
93 # Sanity check
94 is(get_current_desktop, 2);
95 is(get_num_of_desktops, 3);
96 my @actual_names = get_desktop_names;
97 my @expected_names = ('0', '1', '2');
98 is_deeply(\@actual_names, \@expected_names);
99
100 # Kill first window to close a workspace.
101 cmd '[id="' . $second->id . '"] kill';
102
103 is(get_current_desktop, 1, '_NET_CURRENT_DESKTOP should be updated');
104 is(get_num_of_desktops, 2, '_NET_NUMBER_OF_DESKTOPS should be updated');
105 my @actual_names = get_desktop_names;
106 my @expected_names = ('0', '2');
107 is_deeply(\@actual_names, \@expected_names, '_NET_DESKTOP_NAMES should be updated');
108
109 # Rename workspace to reorder them.
110 cmd 'rename workspace 0 to 5';
111
112 is(get_current_desktop, 0, '_NET_CURRENT_DESKTOP should be updated');
113 is(get_num_of_desktops, 2, '_NET_NUMBER_OF_DESKTOPS should remain the same');
114 my @actual_names = get_desktop_names;
115 my @expected_names = ('2', '5');
116 is_deeply(\@actual_names, \@expected_names, '_NET_DESKTOP_NAMES should be updated');
117
118 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • http://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • http://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • http://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests for setting and removing the _NET_WM_STATE_FOCUSED atom properly.
17 # Ticket: #2273
18 use i3test;
19 use X11::XCB qw(:all);
20
21 my ($windowA, $windowB);
22
23 fresh_workspace;
24 $windowA = open_window;
25 ok(is_net_wm_state_focused($windowA), 'a newly opened window that is focused should have _NET_WM_STATE_FOCUSED set');
26
27 $windowB = open_window;
28 ok(!is_net_wm_state_focused($windowA), 'when a another window is focused, the old window should not have _NET_WM_STATE_FOCUSED set');
29 ok(is_net_wm_state_focused($windowB), 'a newly opened window that is focused should have _NET_WM_STATE_FOCUSED set');
30
31 # See issue #3495.
32 cmd 'kill';
33 ok(is_net_wm_state_focused($windowA), 'when the second window is closed, the first window should have _NET_WM_STATE_FOCUSED set');
34
35 fresh_workspace;
36 ok(!is_net_wm_state_focused($windowA), 'when focus moves to the ewmh support window, no window should have _NET_WM_STATE_FOCUSED set');
37
38 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that directional focus gives focus to floating fullscreen containers when
17 # switching workspaces.
18 # Ticket: #3201
19 # Bug still in: 4.15-59-gb849fe3e
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 fake-outputs 1024x768+0+0,1024x768+1024+0
25 EOT
26
27 fresh_workspace(output => 0);
28 my $ws = fresh_workspace(output => 1);
29 open_window;
30 open_floating_window;
31 cmd 'fullscreen enable';
32 my $expected_focus = get_focused($ws);
33
34 cmd 'focus left';
35 cmd 'focus right';
36
37 is (get_focused($ws), $expected_focus, 'floating fullscreen window focused after directional focus');
38
39 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test assignments of workspaces to outputs.
17 use i3test i3_autostart => 0;
18
19 ################################################################################
20 # Test initial workspaces.
21 ################################################################################
22
23 my $config = <<EOT;
24 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
25
26 fake-outputs 1024x768+0+0,1024x768+1024+0,1024x768+1024+768,1024x768+0+768
27
28 bindsym Mod1+x workspace bindingname
29
30 workspace 9 output doesnotexist
31 workspace special output fake-0
32 workspace 1 output doesnotexist
33 workspace dontusethisname output doesnotexist
34 workspace donotoverride output fake-0
35 workspace 2 output fake-0
36 workspace 3 output fake-0
37 EOT
38
39 my $pid = launch_with_config($config);
40
41 sub check_output {
42 my ($workspace, $output, $msg) = @_;
43 is(get_output_for_workspace($workspace), $output, $msg);
44 }
45
46 check_output('9', '', 'Numbered workspace with a big number that is assigned to output that does not exist is not used');
47 check_output('special', 'fake-0', 'Output gets special workspace because of assignment');
48 check_output('bindingname', 'fake-1', 'Bindings give workspace names');
49 check_output('1', 'fake-2', 'Numbered workspace that is assigned to output that does not exist is used');
50 check_output('2', '', 'Numbered workspace assigned to output with existing workspace is not used');
51 check_output('3', '', 'Numbered workspace assigned to output with existing workspace is not used');
52 check_output('4', 'fake-3', 'First available number that is not assigned to existing output is used');
53 check_output('dontusethisname', '', 'Named workspace that is assigned to output that does not exist is not used');
54 check_output('donotoverride', '', 'Named workspace assigned to already occupied output is not used');
55
56 exit_gracefully($pid);
57
58 ################################################################################
59 # Test multiple assignments
60 ################################################################################
61
62 sub do_test {
63 my ($workspace, $output, $msg) = @_;
64 cmd 'focus output ' . ($output eq 'fake-3' ? 'fake-0' : 'fake-3');
65
66 cmd "workspace $workspace";
67 check_output($workspace, $output, $msg)
68 }
69
70 $config = <<EOT;
71 # i3 config file (v4)
72 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
73
74 fake-outputs 1024x768+0+0P,1024x768+1024+0,1024x768+1024+768,1024x768+0+768
75
76 workspace 1 output fake-0
77 workspace 1 output fake-1 fake-2
78 workspace 2 output fake-3 fake-4 fake-0 fake-1
79 workspace 3 output these outputs do not exist but these do: fake-0 fake-3
80 workspace 4 output whitespace fake-0
81 workspace foo output doesnotexist1 doesnotexist2 doesnotexist3
82 workspace bar output doesnotexist
83 workspace bar output fake-0
84 EOT
85
86 $pid = launch_with_config($config);
87
88 do_test('1', 'fake-0', 'Multiple assignments do not override a single one');
89 do_test('2', 'fake-3', 'First output out of multiple assignments is used');
90 do_test('3', 'fake-0', 'First existing output is used');
91 do_test('4', 'fake-0', 'Excessive whitespace is ok');
92 do_test('5', 'fake-1', 'Numbered initialization for fake-1');
93 do_test('6', 'fake-2', 'Numbered initialization for fake-2');
94
95 cmd 'focus output fake-0, workspace foo';
96 check_output('foo', 'fake-0', 'Workspace with only non-existing assigned outputs opened in current output');
97
98 cmd 'focus output fake-0, workspace bar';
99 check_output('bar', 'fake-0', 'Second workspace assignment line ignored');
100
101 # Moving assigned workspaces.
102 cmd 'workspace 2, move workspace to output left';
103 check_output('2', 'fake-2', 'Moved assigned workspace up');
104
105 exit_gracefully($pid);
106 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests if scrolling the tab bar on a tabbed container works and verifies that
17 # only one window is focused as a result.
18 # Ticket: #3215 (PR)
19 # Bug still in: 4.15-92-g666aa9e0
20 use i3test;
21 use i3test::XTEST;
22
23 sub scroll_down {
24 # button5 = scroll down
25 xtest_button_press(5, 3, 3);
26 xtest_button_release(5, 3, 3);
27 xtest_sync_with_i3;
28 }
29
30 sub scroll_up {
31 # button4 = scroll up
32 xtest_button_press(4, 3, 3);
33 xtest_button_release(4, 3, 3);
34 xtest_sync_with_i3;
35 }
36
37 # Decoration of top left window.
38 $x->root->warp_pointer(3, 3);
39
40 # H [ T [ H [ A B ] C D V [ E F ] ] G ]
41 # Inner horizontal split.
42 open_window;
43 cmd 'layout tabbed';
44 cmd 'splith';
45 my $first = open_window;
46 cmd 'focus parent';
47 # Simple tabs.
48 open_window;
49 my $second_last = open_window;
50 # V-Split container
51 open_window;
52 cmd 'splitv';
53 my $last = open_window;
54 # Second child of the outer horizontal split, next to the tabbed one.
55 my $outside = open_window;
56 cmd 'move right, move right';
57
58 cmd '[id=' . $first->id . '] focus';
59
60 # Scroll from first to last.
61 scroll_down;
62 scroll_down;
63 is($x->input_focus, $second_last->id, 'Sanity check: scrolling');
64 scroll_down;
65 is($x->input_focus, $last->id, 'Last window focused through scrolling');
66 scroll_down;
67 is($x->input_focus, $last->id, 'Scrolling again doesn\'t leave the tabbed container and doesn\'t focus the whole sibling');
68
69 # Scroll from last to first.
70 scroll_up;
71 is($x->input_focus, $second_last->id, 'Scrolling up works');
72 scroll_up;
73 scroll_up;
74 is($x->input_focus, $first->id, 'First window focused through scrolling');
75 scroll_up;
76 is($x->input_focus, $first->id, 'Scrolling again doesn\'t focus the whole sibling');
77
78 # Try scrolling with another window focused
79 cmd '[id=' . $outside->id . '] focus';
80 scroll_up;
81 is($x->input_focus, $first->id, 'Scrolling from outside the tabbed container works');
82
83 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that i3 will not hang if a connected client stops reading from its
17 # subscription socket and that the client is killed after a delay.
18 # Ticket: #2999
19 # Bug still in: 4.15-180-g715cea61
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23 # Set the timeout to 500ms to reduce the duration of this test.
24 ipc_kill_timeout 500
25 EOT
26
27 # Manually connect to i3 so that we can choose to not read events
28 use IO::Socket::UNIX;
29 my $sock = IO::Socket::UNIX->new(Peer => get_socket_path());
30 my $magic = "i3-ipc";
31 my $payload = '["workspace"]';
32 my $message = $magic . pack("LL", length($payload), 2) . $payload;
33 print $sock $message;
34
35 # Constantly switch between 2 workspaces to generate events.
36 fresh_workspace;
37 open_window;
38 fresh_workspace;
39 open_window;
40
41 eval {
42 local $SIG{ALRM} = sub { die "Timeout\n" };
43 # 500 is an arbitrarily large number to make sure that the socket becomes
44 # non-writeable.
45 for (my $i = 0; $i < 500; $i++) {
46 alarm 1;
47 cmd 'workspace back_and_forth';
48 alarm 0;
49 }
50 };
51 ok(!$@, 'i3 didn\'t hang');
52
53 # Wait for connection timeout
54 sleep 1;
55
56 use IO::Select;
57 my $s = IO::Select->new($sock);
58 my $reached_eof = 0;
59 while ($s->can_read(0.05)) {
60 if (read($sock, my $buffer, 100) == 0) {
61 $reached_eof = 1;
62 last;
63 }
64 }
65 ok($reached_eof, 'socket connection closed');
66
67 close $sock;
68 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression test: verify that a scratchpad container that was open in another
17 # workspace and is moved to the current workspace after a 'scratchpad show' is
18 # focused.
19 # Ticket: #3361
20 # Bug still in: 4.15-190-g4b3ff9cd
21 use i3test;
22
23 my $expected_focus = open_window;
24 cmd 'move to scratchpad';
25 cmd 'scratchpad show';
26 my $ws = fresh_workspace;
27 open_window;
28 cmd 'scratchpad show';
29 sync_with_i3;
30 is($x->input_focus, $expected_focus->id, 'scratchpad window brought from other workspace is focused');
31
32 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verify that i3 does not crash when restart is issued while a window with a
17 # title that contains non-UTF8 characters is open.
18 # Ticket: #3156
19 # Bug still in: 4.15-241-g9dc4df81
20 use i3test;
21
22 my $ws = fresh_workspace;
23 open_window(name => "\x{AA} <-- invalid");
24
25 cmd 'restart';
26 does_i3_live;
27
28 # Confirm that the invalid character got replaced with U+FFFD - "REPLACEMENT
29 # CHARACTER"
30 cmd '[title="^' . "\x{fffd}" . ' <-- invalid$"] fullscreen enable';
31 is_num_fullscreen($ws, 1, 'title based criterion works');
32
33 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test shape support.
17 # Ticket: #2742
18 use i3test;
19 use ExtUtils::PkgConfig;
20
21 my %sn_config;
22 BEGIN {
23 %sn_config = ExtUtils::PkgConfig->find('xcb-shape');
24 }
25
26 use Inline C => Config => LIBS => $sn_config{libs}, CCFLAGS => $sn_config{cflags};
27 use Inline C => <<'END_OF_C_CODE';
28 #include <xcb/shape.h>
29
30 static xcb_connection_t *conn;
31
32 void init_ctx(void *connptr) {
33 conn = (xcb_connection_t*)connptr;
34 }
35
36 /*
37 * Set the shape for the window consisting of the following zones:
38 *
39 * +---+---+
40 * | A | B |
41 * +---+---+
42 * | C |
43 * +-------+
44 *
45 * - Zone A is completly opaque.
46 * - Zone B is clickable through (input shape).
47 * - Zone C is completly transparent (bounding shape).
48 */
49 void set_shape(long window_id) {
50 xcb_rectangle_t bounding_rectangle = { 0, 0, 100, 50 };
51 xcb_shape_rectangles(conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING,
52 XCB_CLIP_ORDERING_UNSORTED, window_id,
53 0, 0, 1, &bounding_rectangle);
54 xcb_rectangle_t input_rectangle = { 0, 0, 50, 50 };
55 xcb_shape_rectangles(conn, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT,
56 XCB_CLIP_ORDERING_UNSORTED, window_id,
57 0, 0, 1, &input_rectangle);
58 xcb_flush(conn);
59 }
60 END_OF_C_CODE
61
62 init_ctx($x->get_xcb_conn());
63
64 my ($ws, $win1, $win1_focus, $win2, $win2_focus);
65
66 ################################################################################
67 # Case 1: make floating window, then set shape
68 ################################################################################
69
70 $ws = fresh_workspace;
71
72 $win1 = open_floating_window(rect => [0, 0, 100, 100], background_color => '#ff0000');
73 $win1_focus = get_focused($ws);
74
75 $win2 = open_floating_window(rect => [0, 0, 100, 100], background_color => '#00ff00');
76 $win2_focus = get_focused($ws);
77 set_shape($win2->id);
78
79 $win1->warp_pointer(75, 25);
80 sync_with_i3;
81 is(get_focused($ws), $win1_focus, 'focus switched to the underlying window');
82
83 $win1->warp_pointer(25, 25);
84 sync_with_i3;
85 is(get_focused($ws), $win2_focus, 'focus switched to the top window');
86
87 kill_all_windows;
88
89 ################################################################################
90 # Case 2: set shape first, then make window floating
91 ################################################################################
92
93 $ws = fresh_workspace;
94
95 $win1 = open_window(rect => [0, 0, 100, 100], background_color => '#ff0000');
96 $win1_focus = get_focused($ws);
97 cmd 'floating toggle';
98
99 $win2 = open_window(rect => [0, 0, 100, 100], background_color => '#00ff00');
100 $win2_focus = get_focused($ws);
101 set_shape($win2->id);
102 cmd 'floating toggle';
103 sync_with_i3;
104
105 $win1->warp_pointer(75, 25);
106 sync_with_i3;
107 is(get_focused($ws), $win1_focus, 'focus switched to the underlying window');
108
109 $win1->warp_pointer(25, 25);
110 sync_with_i3;
111 is(get_focused($ws), $win2_focus, 'focus switched to the top window');
112
113 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Contains various tests that use the cmp_tree subroutine.
17 # Ticket: #3503
18 use i3test;
19
20 sub sanity_check {
21 local $Test::Builder::Level = $Test::Builder::Level + 1;
22
23 my ($layout, $focus_idx) = @_;
24 my @windows = cmp_tree(
25 msg => 'Sanity check',
26 layout_before => $layout,
27 layout_after => $layout);
28 is($x->input_focus, $windows[$focus_idx]->id, 'Correct window focused') if $focus_idx >= 0;
29 }
30
31 sanity_check('H[ V[ a* V[ b c ] d ] e ]', 0);
32 sanity_check('H[ a b c d* ]', 3);
33 sanity_check('V[a b] V[c d*]', 3);
34 sanity_check('T[a b] S[c*]', 2);
35
36 cmp_tree(
37 msg => 'Simple focus test',
38 layout_before => 'H[a b] V[c* d]',
39 layout_after => 'H[a* b] V[c d]',
40 cb => sub {
41 cmd '[class=a] focus';
42 });
43
44 cmp_tree(
45 msg => 'Simple move test',
46 layout_before => 'H[a b] V[c* d]',
47 layout_after => 'H[a b] V[d c*]',
48 cb => sub {
49 cmd 'move down';
50 });
51
52 cmp_tree(
53 msg => 'Move from horizontal to vertical',
54 layout_before => 'H[a b] V[c d*]',
55 layout_after => 'H[b] V[c d a*]',
56 cb => sub {
57 cmd '[class=a] focus';
58 cmd 'move right, move right';
59 });
60
61 cmp_tree(
62 msg => 'Move unfocused non-leaf container',
63 layout_before => 'S[a b] V[c d* T[e f g]]',
64 layout_after => 'S[a T[e f g] b] V[c d*]',
65 cb => sub {
66 cmd '[con_mark=T1] move up, move up, move left, move up';
67 });
68
69 cmp_tree(
70 msg => 'Simple swap test',
71 layout_before => 'H[a b] V[c d*]',
72 layout_after => 'H[a d*] V[c b]',
73 cb => sub {
74 cmd '[class=b] swap with id ' . $_[0][3]->{id};
75 });
76
77 cmp_tree(
78 msg => 'Swap non-leaf containers',
79 layout_before => 'S[a b] V[c d*]',
80 layout_after => 'V[c d*] S[a b]',
81 cb => sub {
82 cmd '[con_mark=S1] swap with mark V1';
83 });
84
85 cmp_tree(
86 msg => 'Swap nested non-leaf containers',
87 layout_before => 'S[a b] V[c d* T[e f g]]',
88 layout_after => 'T[e f g] V[c d* S[a b]]',
89 cb => sub {
90 cmd '[con_mark=S1] swap with mark T1';
91 });
92
93 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Regression: moving a container which is the only child of the only child of a
17 # floating container crashes i3.
18 # Ticket: #3556
19 # Bug still in: 4.16-61-g376833db4
20 use i3test;
21
22 my $ws = fresh_workspace;
23 open_window;
24 open_window;
25 cmd 'split v, focus parent, floating toggle, focus child, move right';
26 does_i3_live;
27
28 $ws = get_ws($ws);
29 is(scalar @{$ws->{floating_nodes}}, 0, 'No floating nodes in workspace');
30 is(scalar @{$ws->{nodes}}, 2, 'Two tiling nodes in workspace');
31
32 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that the workspace init event is correctly sent.
17 # Ticket: #3631
18 # Bug still in: 4.16-85-g2d6e09a6
19
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 # fake-1 under fake-0 to not interfere with left/right wraping
25 fake-outputs 1024x768+0+0,1024x768+0+1024
26 workspace X output fake-1
27 EOT
28
29 sub workspace_init_subtest {
30 my $cmd = shift;
31 my $num_events = shift;
32 my @events = events_for(sub { cmd $cmd }, 'workspace');
33
34 my @init = grep { $_->{change} eq 'init' } @events;
35 my $len = scalar @init;
36 is($len, $num_events, "Received $num_events workspace::init event");
37 $num_events = $len if $len < $num_events;
38 for my $idx (0 .. $num_events - 1) {
39 my $name = shift;
40 my $output = shift;
41 is($init[$idx]->{current}->{name}, $name, "workspace name $name matches");
42 is($init[$idx]->{current}->{output}, $output, "workspace output $output matches");
43 }
44 }
45
46 subtest 'focus outputs', \&workspace_init_subtest, 'focus output fake-1, focus output fake-0', 0;
47 subtest 'new workspaces', \&workspace_init_subtest,
48 'workspace a, workspace b, workspace a, workspace a', 3, 'a',
49 'fake-0', 'b', 'fake-0', 'a', 'fake-0';
50 open_window; # Prevent workspace "a" from being deleted.
51 subtest 'return on existing workspace', \&workspace_init_subtest,
52 'workspace a, workspace b, workspace a', 1, 'b', 'fake-0';
53 subtest 'assigned workspace is already open', \&workspace_init_subtest,
54 'workspace X, workspace b, workspace a', 1, 'b', 'fake-1';
55 subtest 'assigned workspace was deleted and now is initialized again', \&workspace_init_subtest,
56 'workspace X, workspace b, workspace a', 2, 'X', 'fake-1', 'b', 'fake-1';
57 subtest 'move workspace to output', \&workspace_init_subtest,
58 'move workspace to output fake-1, move workspace to output fake-0', 2, '1', 'fake-0', 'X',
59 'fake-1';
60 subtest 'move window to workspace', \&workspace_init_subtest, 'move to workspace b', 1, 'b',
61 'fake-0';
62 subtest 'back_and_forth', \&workspace_init_subtest,
63 'workspace b, workspace back_and_forth, workspace b', 1,
64 'a', 'fake-0';
65 subtest 'move window to workspace back_and_forth', \&workspace_init_subtest,
66 'move window to workspace back_and_forth', 1, 'a', 'fake-0';
67
68 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verify that restart produces a reply.
17 # Ticket: #3565
18 # Bug still in: 4.16-143-gca82f958
19 use i3test;
20
21 my $reply = cmd('restart');
22 ok($reply->[0]->{success}, 'restart reply received');
23
24 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Make sure the trick used to move the container to its parent works.
17 # https://github.com/i3/i3/issues/1326#issuecomment-349082811
18 use i3test;
19
20 cmp_tree(
21 msg => 'Move to parent when the parent is a workspace',
22 layout_before => 'a H[b*] c',
23 layout_after => 'a b* c',
24 cb => sub {
25 cmd 'mark _a, focus parent, focus parent, mark _b, [con_mark=_a] move window to mark _b, [con_mark=_a] focus';
26 });
27
28 cmp_tree(
29 msg => 'Move to parent when the parent is a split',
30 layout_before => 'V[a H[b*] c]',
31 layout_after => 'V[a b* c]',
32 cb => sub {
33 cmd 'mark _a, focus parent, focus parent, mark _b, [con_mark=_a] move window to mark _b, [con_mark=_a] focus';
34 });
35
36 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test focus next|prev
17 # Ticket: #2587
18 use i3test;
19
20 cmp_tree(
21 msg => "cmd 'prev' selects leaf 1/2",
22 layout_before => 'S[a b] V[c d* T[e f g]]',
23 layout_after => 'S[a b] V[c* d T[e f g]]',
24 cb => sub {
25 cmd 'focus prev';
26 });
27
28 cmp_tree(
29 msg => "cmd 'prev' selects leaf 2/2",
30 layout_before => 'S[a b] V[c* d T[e f g]]',
31 layout_after => 'S[a b*] V[c d T[e f g]]',
32 cb => sub {
33 # c* -> V -> b*
34 cmd 'focus parent, focus prev';
35 });
36
37 cmp_tree(
38 msg => "cmd 'prev sibling' selects leaf again",
39 layout_before => 'S[a b] V[c d* T[e f g]]',
40 layout_after => 'S[a b] V[c* d T[e f g]]',
41 cb => sub {
42 cmd 'focus prev sibling';
43 });
44
45 cmp_tree(
46 msg => "cmd 'next' selects leaf",
47 # Notice that g is the last to open before focus moves to d*
48 layout_before => 'S[a b] V[c d* T[e f g]]',
49 layout_after => 'S[a b] V[c d T[e f g*]]',
50 cb => sub {
51 cmd 'focus next';
52 });
53
54 cmp_tree(
55 msg => "cmd 'next sibling' selects parent 1/2",
56 layout_before => 'S[a b] V[c d* T[e f g]]',
57 layout_after => 'S[a b] V[c d T*[e f g]]',
58 cb => sub {
59 cmd 'focus next sibling';
60 });
61
62 cmp_tree(
63 msg => "cmd 'next sibling' selects parent 2/2",
64 layout_before => 'S[a b*] V[c d T[e f g]]',
65 layout_after => 'S[a b] V*[c d T[e f g]]',
66 cb => sub {
67 # b* -> S* -> V*
68 cmd 'focus parent, focus next sibling';
69 });
70
71 # See #3997
72 cmd 'workspace 2';
73 open_window;
74 cmd 'workspace 1';
75 open_window;
76 cmd 'focus parent, focus parent, focus next sibling, focus prev sibling';
77 does_i3_live;
78 is(focused_ws, '1', 'Back and forth between workspaces');
79
80 cmd 'focus parent, focus parent, focus next sibling';
81 is(focused_ws, '2', "Workspace 2 focused with 'focus next sibling'");
82
83 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests focus_wrapping yes|no|force|workspace with cmp_tree
17 # Tickets: #2180 #2352
18 use i3test i3_autostart => 0;
19
20 my $pid = 0;
21
22 sub focus_wrapping {
23 my ($setting) = @_;
24
25 print "--------------------------------------------------------------------------------\n";
26 print " focus_wrapping $setting\n";
27 print "--------------------------------------------------------------------------------\n";
28 exit_gracefully($pid) if $pid > 0;
29
30 my $config = <<"EOT";
31 # i3 config file (v4)
32 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
33
34 fake-outputs 1024x768+0+0,1024x768+1024+0,1024x768+1024+768,1024x768+0+768
35 workspace left-top output fake-0
36 workspace right-top output fake-1
37 workspace right-bottom output fake-2
38 workspace left-bottom output fake-3
39
40 focus_wrapping $setting
41 EOT
42 $pid = launch_with_config($config);
43 }
44
45 ###############################################################################
46 focus_wrapping('yes');
47 ###############################################################################
48
49 cmp_tree(
50 msg => 'Normal focus up - should work for all options',
51 layout_before => 'S[a b*] V[c d T[e f g]]',
52 layout_after => 'S[a* b] V[c d T[e f g]]',
53 ws => 'left-top',
54 cb => sub {
55 cmd 'focus up';
56 });
57 cmp_tree(
58 msg => 'Normal focus right - should work for all options',
59 layout_before => 'S[a b] V[c d T[e* f g]]',
60 layout_after => 'S[a b] V[c d T[e f* g]]',
61 ws => 'left-top',
62 cb => sub {
63 cmd 'focus right';
64 });
65 cmp_tree(
66 msg => 'Focus leaves workspace vertically',
67 layout_before => 'S[a b*] V[c d T[e f g]]',
68 layout_after => 'S[a b] V[c d T[e f g]]',
69 ws => 'left-top',
70 cb => sub {
71 cmd 'focus down';
72 is(focused_ws, 'left-bottom', 'Correct workspace focused');
73 });
74 cmp_tree(
75 msg => 'Focus wraps vertically',
76 layout_before => 'S[a* b] V[c d T[e f g]]',
77 layout_after => 'S[a b*] V[c d T[e f g]]',
78 ws => 'left-top',
79 cb => sub {
80 cmd 'focus up';
81 });
82 cmp_tree(
83 msg => 'Focus wraps horizontally',
84 layout_before => 'S[a b*] V[c d T[e f g]]',
85 layout_after => 'S[a b] V[c d T[e f g*]]',
86 ws => 'left-top',
87 cb => sub {
88 cmd 'focus left';
89 });
90 cmp_tree(
91 msg => 'Directional focus in the orientation of the parent does not wrap',
92 layout_before => 'S[a b] V[c d T[e* f g]]',
93 layout_after => 'S[a b*] V[c d T[e f g]]',
94 ws => 'left-top',
95 cb => sub {
96 cmd 'focus left';
97 });
98 cmp_tree(
99 msg => 'Focus leaves workspace horizontally',
100 layout_before => 'S[a b] V[c d* T[e f g*]]',
101 layout_after => 'S[a b] V[c d T[e f g]]',
102 ws => 'left-top',
103 cb => sub {
104 cmd 'focus right';
105 is(focused_ws, 'right-top', 'Correct workspace focused');
106 });
107
108 ###############################################################################
109 focus_wrapping('no');
110 # See issue #2352
111 ###############################################################################
112
113 cmp_tree(
114 msg => 'Normal focus up - should work for all options',
115 layout_before => 'S[a b*] V[c d T[e f g]]',
116 layout_after => 'S[a* b] V[c d T[e f g]]',
117 ws => 'left-top',
118 cb => sub {
119 cmd 'focus up';
120 });
121 cmp_tree(
122 msg => 'Normal focus right - should work for all options',
123 layout_before => 'S[a b] V[c d T[e* f g]]',
124 layout_after => 'S[a b] V[c d T[e f* g]]',
125 ws => 'left-top',
126 cb => sub {
127 cmd 'focus right';
128 });
129 cmp_tree(
130 msg => 'Focus leaves workspace vertically',
131 layout_before => 'S[a b*] V[c d T[e f g]]',
132 layout_after => 'S[a b] V[c d T[e f g]]',
133 ws => 'left-top',
134 cb => sub {
135 cmd 'focus down';
136 is(focused_ws, 'left-bottom', 'Correct workspace focused');
137 });
138 cmp_tree(
139 msg => 'Focus does not wrap vertically',
140 layout_before => 'S[a* b] V[c d T[e f g]]',
141 layout_after => 'S[a* b] V[c d T[e f g]]',
142 ws => 'left-top',
143 cb => sub {
144 cmd 'focus up';
145 });
146 cmp_tree(
147 msg => 'Focus does not wrap horizontally',
148 layout_before => 'S[a b*] V[c d T[e f g]]',
149 layout_after => 'S[a b*] V[c d T[e f g]]',
150 ws => 'left-top',
151 cb => sub {
152 cmd 'focus left';
153 });
154 cmp_tree(
155 msg => 'Directional focus in the orientation of the parent does not wrap',
156 layout_before => 'S[a b] V[c d T[e* f g]]',
157 layout_after => 'S[a b*] V[c d T[e f g]]',
158 ws => 'left-top',
159 cb => sub {
160 cmd 'focus left';
161 });
162 cmp_tree(
163 msg => 'Focus leaves workspace horizontally',
164 layout_before => 'S[a b] V[c d* T[e f g]]',
165 layout_after => 'S[a b] V[c d T[e f g]]',
166 ws => 'left-top',
167 cb => sub {
168 cmd 'focus right';
169 is(focused_ws, 'right-top', 'Correct workspace focused');
170 });
171
172 ###############################################################################
173 focus_wrapping('force');
174 ###############################################################################
175
176 cmp_tree(
177 msg => 'Normal focus up - should work for all options',
178 layout_before => 'S[a b*] V[c d T[e f g]]',
179 layout_after => 'S[a* b] V[c d T[e f g]]',
180 ws => 'left-top',
181 cb => sub {
182 cmd 'focus up';
183 });
184 cmp_tree(
185 msg => 'Normal focus right - should work for all options',
186 layout_before => 'S[a b] V[c d T[e* f g]]',
187 layout_after => 'S[a b] V[c d T[e f* g]]',
188 ws => 'left-top',
189 cb => sub {
190 cmd 'focus right';
191 });
192 cmp_tree(
193 msg => 'Focus does not leave workspace vertically',
194 layout_before => 'S[a b*] V[c d T[e f g]]',
195 layout_after => 'S[a* b] V[c d T[e f g]]',
196 ws => 'left-top',
197 cb => sub {
198 cmd 'focus down';
199 is(focused_ws, 'left-top', 'Correct workspace focused');
200 });
201 cmp_tree(
202 msg => 'Focus wraps vertically',
203 layout_before => 'S[a* b] V[c d T[e f g]]',
204 layout_after => 'S[a b*] V[c d T[e f g]]',
205 ws => 'left-top',
206 cb => sub {
207 cmd 'focus up';
208 });
209 cmp_tree(
210 msg => 'Focus wraps horizontally (focus direction different than parent\'s orientation)',
211 layout_before => 'S[a b*] V[c d T[e f g]]',
212 layout_after => 'S[a b] V[c d T[e f g*]]',
213 ws => 'left-top',
214 cb => sub {
215 cmd 'focus left';
216 });
217 cmp_tree(
218 msg => 'Directional focus in the orientation of the parent wraps',
219 layout_before => 'S[a b] V[c d T[e* f g]]',
220 layout_after => 'S[a b] V[c d T[e f g*]]',
221 ws => 'left-top',
222 cb => sub {
223 cmd 'focus left';
224 });
225 cmp_tree( # 'focus_wrapping force' exclusive test
226 msg => 'But leaves when selecting parent',
227 layout_before => 'S[a b] V[c d T[e* f g]]',
228 layout_after => 'S[a b*] V[c d T[e f g]]',
229 ws => 'left-top',
230 cb => sub {
231 cmd 'focus parent, focus right';
232 });
233 cmp_tree(
234 msg => 'Focus does not leave workspace horizontally',
235 layout_before => 'S[a b] V[c d* T[e f g]]',
236 layout_after => 'S[a b*] V[c d T[e f g]]',
237 ws => 'left-top',
238 cb => sub {
239 cmd 'focus right';
240 is(focused_ws, 'left-top', 'Correct workspace focused');
241 });
242 cmp_tree( # 'focus_wrapping force|workspace' exclusive test
243 msg => 'But leaves when selecting parent x2',
244 layout_before => 'S[a b] V[c d* T[e f g]]',
245 layout_after => 'S[a b] V[c d T[e f g]]',
246 ws => 'left-top',
247 cb => sub {
248 cmd 'focus parent, focus parent, focus right';
249 is(focused_ws, 'right-top', 'Correct workspace focused');
250 });
251
252 ###############################################################################
253 focus_wrapping('workspace');
254 # See issue #2180
255 ###############################################################################
256
257 cmp_tree(
258 msg => 'Normal focus up - should work for all options',
259 layout_before => 'S[a b*] V[c d T[e f g]]',
260 layout_after => 'S[a* b] V[c d T[e f g]]',
261 ws => 'left-top',
262 cb => sub {
263 cmd 'focus up';
264 });
265 cmp_tree(
266 msg => 'Normal focus right - should work for all options',
267 layout_before => 'S[a b] V[c d T[e* f g]]',
268 layout_after => 'S[a b] V[c d T[e f* g]]',
269 ws => 'left-top',
270 cb => sub {
271 cmd 'focus right';
272 });
273 cmp_tree(
274 msg => 'Focus does not leave workspace vertically',
275 layout_before => 'S[a b*] V[c d T[e f g]]',
276 layout_after => 'S[a* b] V[c d T[e f g]]',
277 ws => 'left-top',
278 cb => sub {
279 cmd 'focus down';
280 is(focused_ws, 'left-top', 'Correct workspace focused');
281 });
282 cmp_tree(
283 msg => 'Focus wraps vertically',
284 layout_before => 'S[a* b] V[c d T[e f g]]',
285 layout_after => 'S[a b*] V[c d T[e f g]]',
286 ws => 'left-top',
287 cb => sub {
288 cmd 'focus up';
289 });
290 cmp_tree(
291 msg => 'Focus wraps horizontally',
292 layout_before => 'S[a b*] V[c d T[e f g]]',
293 layout_after => 'S[a b] V[c d T[e f g*]]',
294 ws => 'left-top',
295 cb => sub {
296 cmd 'focus left';
297 });
298 cmp_tree(
299 msg => 'Directional focus in the orientation of the parent does not wrap',
300 layout_before => 'S[a b] V[c d T[e* f g]]',
301 layout_after => 'S[a b*] V[c d T[e f g]]',
302 ws => 'left-top',
303 cb => sub {
304 cmd 'focus left';
305 });
306 cmp_tree(
307 msg => 'Focus does not leave workspace horizontally',
308 layout_before => 'S[a b] V[c d* T[e f g]]',
309 layout_after => 'S[a b*] V[c d T[e f g]]',
310 ws => 'left-top',
311 cb => sub {
312 cmd 'focus right';
313 is(focused_ws, 'left-top', 'Correct workspace focused');
314 });
315 cmp_tree( # 'focus_wrapping force|workspace' exclusive test
316 msg => 'But leaves when selecting parent x2',
317 layout_before => 'S[a b] V[c d* T[e f g]]',
318 layout_after => 'S[a b] V[c d T[e f g]]',
319 ws => 'left-top',
320 cb => sub {
321 cmd 'focus parent, focus parent, focus right';
322 is(focused_ws, 'right-top', 'Correct workspace focused');
323 });
324
325 cmp_tree( # 'focus_wrapping workspace' exclusive test
326 msg => 'x',
327 layout_before => 'S[a* b] V[c d T[e f g]]',
328 layout_after => 'S[a b] V[c d T[e f g]]',
329 ws => 'left-top',
330 cb => sub {
331 subtest 'random tests' => sub {
332 my @directions = qw(left right top down);
333 for my $i (1 .. 50) {
334 my $direction = $directions[rand @directions];
335 cmd "focus $direction";
336
337 return unless is(focused_ws, 'left-top', "'focus $direction' did not change workspace");
338 }
339 };
340 });
341
342 exit_gracefully($pid);
343
344 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that moving a container that is to be flattened does not crash i3
17 # Ticket: #3831
18 # Bug still in: 4.17-199-ga638e0408
19 use i3test;
20
21 cmp_tree(
22 msg => 'Moving a redundant container that is to be flattened does not crash i3',
23 layout_before => 'a H[V[b* c]]', # Not very attached to this result but
24 layout_after => 'H[a] b* c', # mainly checking if the crash happens.
25 cb => sub {
26 cmd 'focus parent, focus parent, move down';
27 does_i3_live;
28 is(get_ws(focused_ws)->{layout}, 'splitv', 'Workspace changed to splitv');
29 });
30
31 cmp_tree(
32 msg => "Same but create the redundant container with a 'split h' command",
33 layout_before => 'a V[b* c]',
34 layout_after => 'H[a] b* c',
35 cb => sub {
36 cmd 'focus parent, split h, focus parent, move down';
37 does_i3_live;
38 is(get_ws(focused_ws)->{layout}, 'splitv', 'Workspace changed to splitv');
39 });
40
41
42 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that the provided X-Server to the t/5??-*.t tests is actually providing
17 # multiple monitors.
18 #
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 fake-outputs 1024x768+0+0,1024x768+1024+0
24 EOT
25
26 my $i3 = i3(get_socket_path());
27
28 ####################
29 # Request tree
30 ####################
31
32 my $tree = $i3->get_tree->recv;
33
34 my @outputs = map { $_->{name} } @{$tree->{nodes}};
35 is_deeply(\@outputs, [ '__i3', 'fake-0', 'fake-1' ],
36 'multi-monitor outputs ok');
37
38
39 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that scratchpad windows show up on the proper output.
17 # ticket #596, bug present until up to commit
18 # 89dded044b4fffe78f9d70778748fabb7ac533e9.
19 #
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 fake-outputs 1024x768+0+0,1024x768+1024+0
25 EOT
26
27 ################################################################################
28 # Open a workspace on the second output, put a window to scratchpad, display
29 # it, verify it’s on the same workspace.
30 ################################################################################
31
32 sub verify_scratchpad_on_same_ws {
33 my ($ws) = @_;
34
35 is_num_children($ws, 0, 'no nodes on this ws');
36
37 my $window = open_window;
38
39 is_num_children($ws, 1, 'one nodes on this ws');
40
41 cmd 'move scratchpad';
42
43 is_num_children($ws, 0, 'no nodes on this ws');
44
45 cmd 'scratchpad show';
46 is_num_children($ws, 0, 'no nodes on this ws');
47 is(scalar @{get_ws($ws)->{floating_nodes}}, 1, 'one floating node on this ws');
48 }
49
50 my $second = fresh_workspace(output => 1);
51
52 verify_scratchpad_on_same_ws($second);
53
54 ################################################################################
55 # The same thing, but on the first output.
56 ################################################################################
57
58 my $first = fresh_workspace(output => 0);
59
60 verify_scratchpad_on_same_ws($first);
61
62 ################################################################################
63 # Now open the scratchpad on one output and switch to another.
64 ################################################################################
65
66 sub verify_scratchpad_switch {
67 my ($first, $second) = @_;
68
69 cmd "workspace $first";
70
71 is_num_children($first, 0, 'no nodes on this ws');
72
73 my $window = open_window;
74
75 is_num_children($first, 1, 'one nodes on this ws');
76
77 cmd 'move scratchpad';
78
79 is_num_children($first, 0, 'no nodes on this ws');
80
81 cmd "workspace $second";
82
83 cmd 'scratchpad show';
84 my $ws = get_ws($second);
85 is_num_children($second, 0, 'no nodes on this ws');
86 is(scalar @{$ws->{floating_nodes}}, 1, 'one floating node on this ws');
87
88 # Verify that the coordinates are within bounds.
89 my $srect = $ws->{floating_nodes}->[0]->{rect};
90 my $rect = $ws->{rect};
91 cmd 'nop before bounds check';
92 cmp_ok($srect->{x}, '>=', $rect->{x}, 'x within bounds');
93 cmp_ok($srect->{y}, '>=', $rect->{y}, 'y within bounds');
94 cmp_ok($srect->{x} + $srect->{width}, '<=', $rect->{x} + $rect->{width},
95 'width within bounds');
96 cmp_ok($srect->{y} + $srect->{height}, '<=', $rect->{y} + $rect->{height},
97 'height within bounds');
98 }
99
100 $first = fresh_workspace(output => 0);
101 $second = fresh_workspace(output => 1);
102
103 verify_scratchpad_switch($first, $second);
104
105 $first = fresh_workspace(output => 1);
106 $second = fresh_workspace(output => 0);
107
108 verify_scratchpad_switch($first, $second);
109
110 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies the 'focus output' command works properly.
17
18 use i3test i3_config => <<EOT;
19 # i3 config file (v4)
20 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
21
22 fake-outputs 1024x768+0+0,1024x768+1024+0
23 EOT
24 use List::Util qw(first);
25
26 my $tmp = fresh_workspace;
27 my $i3 = i3(get_socket_path());
28
29 ################################################################################
30 # use 'focus output' and verify that focus gets changed appropriately
31 ################################################################################
32
33 sub focused_output {
34 my $tree = $i3->get_tree->recv;
35 my $focused = $tree->{focus}->[0];
36 my $output = first { $_->{id} == $focused } @{$tree->{nodes}};
37 return $output->{name};
38 }
39
40 sync_with_i3;
41 $x->root->warp_pointer(0, 0);
42 sync_with_i3;
43
44 is(focused_output, 'fake-0', 'focus on first output');
45
46 cmd 'focus output right';
47 is(focused_output, 'fake-1', 'focus on second output');
48
49 # focus should wrap when we focus to the right again.
50 cmd 'focus output right';
51 is(focused_output, 'fake-0', 'focus on first output again');
52
53 cmd 'focus output left';
54 is(focused_output, 'fake-1', 'focus back on second output');
55
56 cmd 'focus output left';
57 is(focused_output, 'fake-0', 'focus on first output again');
58
59 cmd 'focus output up';
60 is(focused_output, 'fake-0', 'focus still on first output');
61
62 cmd 'focus output down';
63 is(focused_output, 'fake-0', 'focus still on first output');
64
65 cmd 'focus output fake-1';
66 is(focused_output, 'fake-1', 'focus on second output');
67
68 cmd 'focus output fake-0';
69 is(focused_output, 'fake-0', 'focus on first output');
70
71 ################################################################################
72 # use 'focus output' and verify that i3 does not crash when the currently
73 # focused window is floating and is only partially mapped on an output screen
74 ################################################################################
75
76 is(focused_output, 'fake-0', 'focus on first output');
77
78 my $floating_win = open_window;
79 cmd 'floating toggle';
80 cmd 'move to absolute position -10 -10';
81
82 cmd 'focus output right';
83 is(focused_output, 'fake-1', 'focus on second output');
84
85 cmd 'focus output fake-0';
86 is(focused_output, 'fake-0', 'focus on first output');
87
88 ################################################################################
89 # use 'focus output' with command criteria and verify that i3 does not crash
90 # when they don't match any window
91 ################################################################################
92
93 is(focused_output, 'fake-0', 'focus on first output');
94
95 cmd '[con_mark=doesnotexist] focus output right';
96 does_i3_live;
97 is(focused_output, 'fake-0', 'focus remained on first output');
98
99 ################################################################################
100 # use 'focus output' with command criteria and verify that focus gets changed
101 # appropriately
102 ################################################################################
103
104 is(focused_output, 'fake-0', 'focus on first output');
105
106 my $window = open_window;
107
108 cmd 'focus output right';
109 is(focused_output, 'fake-1', 'focus on second output');
110
111 cmd '[id= . ' . $window->id . '] focus output right';
112 is(focused_output, 'fake-1', 'focus on second output after command with criteria');
113
114 cmd 'focus output right';
115 is(focused_output, 'fake-0', 'focus on first output after command without criteria');
116
117 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests whether 'workspace next_on_output' and the like work correctly.
17 #
18 use List::Util qw(first);
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 fake-outputs 1024x768+0+0,1024x768+1024+0
24 EOT
25
26 ################################################################################
27 # Setup workspaces so that they stay open (with an empty container).
28 ################################################################################
29
30 sync_with_i3;
31 $x->root->warp_pointer(0, 0);
32 sync_with_i3;
33
34 is(focused_ws, '1', 'starting on workspace 1');
35 # ensure workspace 1 stays open
36 open_window;
37
38 cmd 'focus output right';
39 is(focused_ws, '2', 'workspace 2 on second output');
40 # ensure workspace 2 stays open
41 open_window;
42
43 cmd 'focus output right';
44 is(focused_ws, '1', 'back on workspace 1');
45
46 # We don’t use fresh_workspace with named workspaces here since they come last
47 # when using 'workspace next'.
48 cmd 'workspace 5';
49 # ensure workspace 5 stays open
50 open_window;
51
52 ################################################################################
53 # Use workspace next and verify the correct order.
54 ################################################################################
55
56 # The current order should be:
57 # output 1: 1, 5
58 # output 2: 2
59 cmd 'workspace 1';
60 cmd 'workspace next';
61 # We need to sync after changing focus to a different output to wait for the
62 # EnterNotify to be processed, otherwise it will be processed at some point
63 # later in time and mess up our subsequent tests.
64 sync_with_i3;
65
66 is(focused_ws, '2', 'workspace 2 focused');
67 cmd 'workspace next';
68 # We need to sync after changing focus to a different output to wait for the
69 # EnterNotify to be processed, otherwise it will be processed at some point
70 # later in time and mess up our subsequent tests.
71 sync_with_i3;
72
73 is(focused_ws, '5', 'workspace 5 focused');
74
75 ################################################################################
76 # Now try the same with workspace next_on_output.
77 ################################################################################
78
79 cmd 'workspace 1';
80 cmd 'workspace next_on_output';
81 is(focused_ws, '5', 'workspace 5 focused');
82 cmd 'workspace next_on_output';
83 is(focused_ws, '1', 'workspace 1 focused');
84
85 cmd 'workspace prev_on_output';
86 is(focused_ws, '5', 'workspace 5 focused');
87 cmd 'workspace prev_on_output';
88 is(focused_ws, '1', 'workspace 1 focused');
89
90 cmd 'workspace 2';
91 # We need to sync after changing focus to a different output to wait for the
92 # EnterNotify to be processed, otherwise it will be processed at some point
93 # later in time and mess up our subsequent tests.
94 sync_with_i3;
95
96 cmd 'workspace prev_on_output';
97 is(focused_ws, '2', 'workspace 2 focused');
98
99 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests whether the 'move workspace <ws> to [output] <output>' command works
17 #
18 use List::Util qw(first);
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 fake-outputs 1024x768+0+0,1024x768+1024+0
24
25 bar {
26 # Disable i3bar.
27 i3bar_command :
28 }
29 EOT
30
31 # TODO: get rid of smartmatch in this test
32
33 ################################################################################
34 # Setup workspaces so that they stay open (with an empty container).
35 ################################################################################
36
37 is(focused_ws, '1', 'starting on workspace 1');
38 # ensure workspace 1 stays open
39 open_window;
40
41 cmd 'focus output right';
42 is(focused_ws, '2', 'workspace 2 on second output');
43 # ensure workspace 2 stays open
44 open_window;
45
46 cmd 'focus output right';
47 is(focused_ws, '1', 'back on workspace 1');
48
49 # We don’t use fresh_workspace with named workspaces here since they come last
50 # when using 'workspace next'.
51 cmd 'workspace 5';
52 # ensure workspace 5 stays open
53 open_window;
54
55 ################################################################################
56 # Move a workspace over and verify that it is on the right output.
57 ################################################################################
58
59 # The current order should be:
60 # output 1: 1, 5
61 # output 2: 2
62 cmd 'workspace 5';
63 is(focused_ws, '5', 'workspace 5 focused');
64
65 my ($x0, $x1) = workspaces_per_screen();
66 ok('5' ~~ @$x0, 'workspace 5 on fake-0');
67
68 cmd 'move workspace to output fake-1';
69
70 sub workspaces_per_screen {
71 my $i3 = i3(get_socket_path());
72 my $tree = $i3->get_tree->recv;
73 my @outputs = @{$tree->{nodes}};
74
75 my $fake0 = first { $_->{name} eq 'fake-0' } @outputs;
76 my $fake0_content = first { $_->{type} eq 'con' } @{$fake0->{nodes}};
77
78 my $fake1 = first { $_->{name} eq 'fake-1' } @outputs;
79 my $fake1_content = first { $_->{type} eq 'con' } @{$fake1->{nodes}};
80
81 my @fake0_workspaces = map { $_->{name} } @{$fake0_content->{nodes}};
82 my @fake1_workspaces = map { $_->{name} } @{$fake1_content->{nodes}};
83
84 return \@fake0_workspaces, \@fake1_workspaces;
85 }
86
87 ($x0, $x1) = workspaces_per_screen();
88 ok('5' ~~ @$x1, 'workspace 5 now on fake-1');
89
90 ################################################################################
91 # Verify that a new workspace will be created when moving the last workspace.
92 ################################################################################
93
94 is_deeply($x0, [ '1' ], 'only workspace 1 remaining on fake-0');
95
96 cmd 'workspace 1';
97 cmd 'move workspace to output fake-1';
98
99 ($x0, $x1) = workspaces_per_screen();
100 ok('1' ~~ @$x1, 'workspace 1 now on fake-1');
101 is_deeply($x0, [ '3' ], 'workspace 2 created on fake-0');
102
103 ################################################################################
104 # Verify that 'move workspace to output <direction>' works
105 ################################################################################
106
107 cmd 'workspace 5';
108 cmd 'move workspace to output left';
109
110 ($x0, $x1) = workspaces_per_screen();
111 ok('5' ~~ @$x0, 'workspace 5 back on fake-0');
112
113 # Verify that wrapping works
114 cmd 'move workspace to output left';
115 ($x0, $x1) = workspaces_per_screen();
116 ok('5' ~~ @$x1, 'workspace 5 on fake-1');
117
118 # Put workspace 5 where it should
119 cmd 'move workspace to output left';
120 ($x0, $x1) = workspaces_per_screen();
121 ok('5' ~~ @$x0, 'workspace 5 on fake-0 again');
122
123 ################################################################################
124 # Verify that coordinates of floating windows are fixed correctly when moving a
125 # workspace to a different output.
126 ################################################################################
127
128 cmd 'workspace 5';
129 my $floating_window = open_floating_window;
130
131 my $old_rect = $floating_window->rect;
132
133 cmd 'move workspace to output right';
134
135 my $new_rect = $floating_window->rect;
136
137 isnt($old_rect->{x}, $new_rect->{x}, 'x coordinate changed');
138 is($old_rect->{y}, $new_rect->{y}, 'y coordinate unchanged');
139 is($old_rect->{width}, $new_rect->{width}, 'width unchanged');
140 is($old_rect->{height}, $new_rect->{height}, 'height unchanged');
141
142 ################################################################################
143 # Verify that empty workspaces get cleaned up when moving a different workspace
144 # to that output.
145 ################################################################################
146
147 my $empty_ws = fresh_workspace(output => 0);
148 my $other_output_ws = fresh_workspace(output => 1);
149 cmd 'open';
150
151 ($x0, $x1) = workspaces_per_screen();
152 ok($empty_ws ~~ @$x0, 'empty_ws on fake-0');
153 ok($other_output_ws ~~ @$x1, 'other_output_ws on fake-1');
154
155 cmd 'move workspace to output left';
156
157 ($x0, $x1) = workspaces_per_screen();
158 ok(!($empty_ws ~~ @$x0), 'empty_ws not on fake-0');
159 ok(!($empty_ws ~~ @$x1), 'empty_ws not on fake-1');
160 ok($other_output_ws ~~ @$x0, 'other_output_ws on fake-0');
161
162 ################################################################################
163 # Verify that the special word 'current' can be used for the output.
164 ################################################################################
165
166 my $ws1 = fresh_workspace(output => 1);
167 open_window;
168 cmd 'mark marked';
169
170 my $ws0 = fresh_workspace(output => 0);
171
172 ($x0, $x1) = workspaces_per_screen();
173 ok($ws0 ~~ @$x0, 'ws0 on fake-0');
174 ok($ws1 ~~ @$x1, 'ws1 on fake-1');
175
176 cmd '[con_mark=marked] move workspace to output current';
177
178 ($x0, $x1) = workspaces_per_screen();
179 ok($ws1 ~~ @$x0, 'ws1 on fake-0');
180
181 ################################################################################
182 # Verify that '[class=".*"] move workspace to output' doesn't fail when
183 # containers in the scratchpad are matched.
184 # See issue: #3064.
185 ################################################################################
186 my $__i3_scratch = get_ws('__i3_scratch');
187 is(scalar @{$__i3_scratch->{floating_nodes}}, 0, 'scratchpad is empty');
188
189 $ws0 = fresh_workspace(output => 0);
190 open_window(wm_class => 'a');
191
192 $ws1 = fresh_workspace(output => 1);
193 open_window(wm_class => 'b');
194 my $scratchpad_window = open_window(wm_class => 'c');
195 cmd 'move to scratchpad';
196
197 ($x0, $x1) = workspaces_per_screen();
198 ok($ws0 ~~ @$x0, 'ws0 on fake-0');
199 ok($ws1 ~~ @$x1, 'ws1 on fake-1');
200
201 my $reply = cmd '[class=".*"] move workspace to output fake-1';
202 ok($reply->[0]->{success}, 'move successful');
203
204 ($x0, $x1) = workspaces_per_screen();
205 ok($ws0 ~~ @$x1, 'ws0 on fake-1');
206 ok($ws1 ~~ @$x1, 'ws1 on fake-1');
207
208 $__i3_scratch = get_ws('__i3_scratch');
209 is(scalar @{$__i3_scratch->{floating_nodes}}, 1, 'window still in scratchpad');
210
211 ################################################################################
212
213 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that scratchpad windows don’t move due to floating point caulcation
17 # errors when repeatedly hiding/showing, no matter what display resolution.
18 #
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 fake-outputs 683x768+0+0,1024x768+683+0
24 EOT
25
26 sync_with_i3;
27 $x->root->warp_pointer(0, 0);
28 sync_with_i3;
29
30 sub verify_scratchpad_doesnt_move {
31 my ($ws) = @_;
32
33 is_num_children($ws, 0, 'no nodes on this ws');
34
35 my $window = open_window;
36 is_num_children($ws, 1, 'one node on this ws');
37
38 cmd 'move scratchpad';
39 is_num_children($ws, 0, 'no nodes on this ws');
40
41 my $last_x = -1;
42 for (1 .. 20) {
43 cmd 'scratchpad show';
44 is(scalar @{get_ws($ws)->{floating_nodes}}, 1, 'one floating node on this ws');
45
46 # Verify that the coordinates are within bounds.
47 my $content = get_ws($ws);
48 my $srect = $content->{floating_nodes}->[0]->{rect};
49 if ($last_x > -1) {
50 is($srect->{x}, $last_x, 'scratchpad window did not move');
51 }
52 $last_x = $srect->{x};
53 cmd 'scratchpad show';
54 }
55
56 # We need to kill the scratchpad window, otherwise scratchpad show in
57 # subsequent calls of verify_scratchpad_doesnt_move will cycle between all
58 # the windows.
59 cmd 'scratchpad show';
60 cmd 'kill';
61 }
62
63 ################################################################################
64 # test it on the left output first (1366x768)
65 ################################################################################
66
67 my $second = fresh_workspace(output => 0);
68 verify_scratchpad_doesnt_move($second);
69
70 ################################################################################
71 # now on the right output (1024x768)
72 ################################################################################
73
74 sync_with_i3;
75 $x->root->warp_pointer(683 + 10, 0);
76 sync_with_i3;
77
78 my $third = fresh_workspace(output => 1);
79 verify_scratchpad_doesnt_move($third);
80
81 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that focus output right works with monitor setups that don’t line up
17 # on their x/y coordinates.
18 #
19 # ticket #771, bug still present in commit dd743f3b55b2f86d9f1f69ef7952ae8ece4de504
20 #
21 use i3test i3_autostart => 0;
22
23 sub test_focus_left_right {
24 my ($config) = @_;
25
26 my $pid = launch_with_config($config);
27
28 my $i3 = i3(get_socket_path(0));
29
30 sync_with_i3;
31 $x->root->warp_pointer(0, 0);
32 sync_with_i3;
33
34 ############################################################################
35 # Ensure that moving left and right works.
36 ############################################################################
37
38 # First ensure both workspaces have something to focus
39 cmd "workspace 1";
40 my $left_win = open_window;
41
42 cmd "workspace 2";
43 my $right_win = open_window;
44
45 is($x->input_focus, $right_win->id, 'right window focused');
46
47 cmd "focus output left";
48 is($x->input_focus, $left_win->id, 'left window focused');
49
50 cmd "focus output right";
51 is($x->input_focus, $right_win->id, 'right window focused');
52
53 cmd "focus output right";
54 is($x->input_focus, $left_win->id, 'left window focused (wrapping)');
55
56 cmd "focus output left";
57 is($x->input_focus, $right_win->id, 'right window focused (wrapping)');
58
59 ############################################################################
60 # Ensure that moving down/up from S0 doesn’t crash i3 and is a no-op.
61 ############################################################################
62
63 my $second = fresh_workspace(output => 1);
64 my $third_win = open_window;
65
66 cmd "focus output down";
67 is($x->input_focus, $third_win->id, 'right window still focused');
68
69 cmd "focus output up";
70 is($x->input_focus, $third_win->id, 'right window still focused');
71
72 does_i3_live;
73
74 exit_gracefully($pid);
75 }
76
77 # Screen setup looks like this:
78 # +----+
79 # | |--------+
80 # | S1 | S2 |
81 # | |--------+
82 # +----+
83 #
84 my $config = <<EOT;
85 # i3 config file (v4)
86 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
87
88 fake-outputs 1080x1920+0+0,1920x1080+1080+500
89 EOT
90
91 test_focus_left_right($config);
92
93 # Screen setup looks like this:
94 # +----+--------+
95 # | | S2 |
96 # | S1 |--------+
97 # | |
98 # +----+
99 #
100 $config = <<EOT;
101 # i3 config file (v4)
102 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
103
104 fake-outputs 1080x1920+0+0,1920x200+1080+0
105 EOT
106
107 test_focus_left_right($config);
108
109 # Screen setup looks like this:
110 # +----+
111 # | |
112 # | S1 |--------+
113 # | | S2 |
114 # +----+--------+
115 #
116 $config = <<EOT;
117 # i3 config file (v4)
118 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
119
120 fake-outputs 1080x1920+0+0,1920x200+1080+1720
121 EOT
122
123 test_focus_left_right($config);
124
125 # Screen setup looks like this:
126 # +----+ +----+
127 # | | | |
128 # | S1 |--------+ S3 |
129 # | | S2 | |
130 # +----+--------+----+
131 #
132 $config = <<EOT;
133 # i3 config file (v4)
134 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
135
136 fake-outputs 1080x1920+0+0,1920x200+1080+1720,1080x1920+1280+0
137 EOT
138
139 my $pid = launch_with_config($config);
140
141 my $i3 = i3(get_socket_path(0));
142
143 sync_with_i3;
144 $x->root->warp_pointer(0, 0);
145 sync_with_i3;
146
147 ############################################################################
148 # Ensure that focusing right/left works in the expected order.
149 ############################################################################
150
151 sub get_focused_output {
152 my $tree = i3(get_socket_path())->get_tree->recv;
153 my ($focused_id) = @{$tree->{focus}};
154 my ($output) = grep { $_->{id} == $focused_id } @{$tree->{nodes}};
155 return $output->{name};
156 }
157
158 is(get_focused_output(), 'fake-0', 'focus on fake-0');
159
160 cmd 'focus output right';
161 is(get_focused_output(), 'fake-1', 'focus on fake-1');
162
163 cmd 'focus output right';
164 is(get_focused_output(), 'fake-2', 'focus on fake-2');
165
166 cmd 'focus output left';
167 is(get_focused_output(), 'fake-1', 'focus on fake-1');
168
169 cmd 'focus output left';
170 is(get_focused_output(), 'fake-0', 'focus on fake-0');
171
172 cmd 'focus output left';
173 is(get_focused_output(), 'fake-2', 'focus on fake-2 (wrapping)');
174
175 cmd 'focus output right';
176 is(get_focused_output(), 'fake-0', 'focus on fake-0 (wrapping)');
177
178 exit_gracefully($pid);
179
180 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests whether i3 crashes on cross-output moves with one workspace per output.
17 # Ticket: #827
18 # Bug still in: 4.3-78-g66b389c
19 #
20 use List::Util qw(first);
21 use i3test i3_config => <<EOT;
22 # i3 config file (v4)
23 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
24
25 fake-outputs 1024x768+0+0,1024x768+1024+0
26 EOT
27
28 ################################################################################
29 # Setup workspaces so that they stay open (with an empty container).
30 ################################################################################
31
32 is(focused_ws, '1', 'starting on workspace 1');
33
34 cmd 'move workspace to output fake-1';
35
36 does_i3_live;
37
38 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests whether workspace_layout is properly set after startup.
17 #
18 use List::Util qw(first);
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 fake-outputs 1024x768+0+0
24 workspace_layout tabbed
25 EOT
26
27 ################################################################################
28 # Test that workspace_layout is properly set
29 ################################################################################
30
31 is(focused_ws, '1', 'starting on workspace 1');
32 my $ws = get_ws(1);
33 is($ws->{workspace_layout}, 'tabbed', 'workspace layout is "tabbed"');
34
35 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that switching workspaces via 'focus $dir' never leaves a floating
17 # window focused.
18 #
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 fake-outputs 1024x768+0+0,1024x768+1024+0,1024x768+0+768,1024x768+1024+768
24 EOT
25
26 my $s0_ws = fresh_workspace;
27 my $first = open_window;
28 my $second = open_window;
29 my $third = open_window;
30 cmd 'floating toggle';
31
32 # Focus screen 1
33 sync_with_i3;
34 $x->root->warp_pointer(1025, 0);
35 sync_with_i3;
36 my $s1_ws = fresh_workspace;
37
38 my $fourth = open_window;
39
40 # Focus screen 2
41 sync_with_i3;
42 $x->root->warp_pointer(0, 769);
43 sync_with_i3;
44 my $s2_ws = fresh_workspace;
45
46 my $fifth = open_window;
47
48 # Focus screen 3
49 sync_with_i3;
50 $x->root->warp_pointer(1025, 769);
51 sync_with_i3;
52 my $s3_ws = fresh_workspace;
53
54 my $sixth = open_window;
55 my $seventh = open_window;
56 my $eighth = open_window;
57 cmd 'floating toggle';
58
59 # Layout should look like this (windows 3 and 8 are floating):
60 # S0 S1
61 # ┌───┬───┬───────┐
62 # │ ┌─┴─┐ │ │
63 # │1│ 3 │2│ 4 │
64 # │ └─┬─┘ │ │
65 # ├───┴───┼───┬───┤
66 # │ │ ┌─┴─┐ │
67 # │ 5 │6│ 8 │7│
68 # │ │ └─┬─┘ │
69 # └───────┴───┴───┘
70 # S2 S3
71 #
72 ###################################################################
73 # Test that focus (left|down|right|up) doesn't focus floating
74 # windows when moving into horizontally-split workspaces.
75 ###################################################################
76
77 sub reset_focus {
78 my $ws = shift;
79 cmd "workspace $ws; focus floating";
80 }
81
82 cmd "workspace $s1_ws";
83 cmd 'focus left';
84 is($x->input_focus, $second->id, 'second window focused');
85 reset_focus $s0_ws;
86
87 cmd "workspace $s1_ws";
88 cmd 'focus down';
89 is($x->input_focus, $seventh->id, 'seventh window focused');
90 reset_focus $s3_ws;
91
92 cmd "workspace $s2_ws";
93 cmd 'focus right';
94 is($x->input_focus, $seventh->id, 'seventh window focused');
95 reset_focus $s3_ws;
96
97 cmd "workspace $s2_ws";
98 cmd 'focus up';
99 is($x->input_focus, $second->id, 'second window focused');
100 reset_focus $s0_ws;
101
102 ###################################################################
103 # Put the workspaces on screens 0 and 3 into vertical split mode
104 # and test focus (left|down|right|up) again.
105 ###################################################################
106
107 cmd "workspace $s0_ws";
108 is($x->input_focus, $third->id, 'third window focused');
109 cmd 'focus parent';
110 cmd 'focus parent';
111 cmd 'split v';
112 # Focus second or else $first gets to the top of the focus stack.
113 cmd '[id=' . $second->id . '] focus';
114 reset_focus $s0_ws;
115
116 cmd "workspace $s3_ws";
117 is($x->input_focus, $eighth->id, 'eighth window focused');
118 cmd 'focus parent';
119 cmd 'focus parent';
120 cmd 'split v';
121 cmd '[id=' . $sixth->id . '] focus';
122 reset_focus $s3_ws;
123
124 cmd "workspace $s1_ws";
125 cmd 'focus left';
126 is($x->input_focus, $second->id, 'second window focused');
127 reset_focus $s0_ws;
128
129 cmd "workspace $s1_ws";
130 cmd 'focus down';
131 is($x->input_focus, $sixth->id, 'sixth window focused');
132 reset_focus $s3_ws;
133
134 cmd "workspace $s2_ws";
135 cmd 'focus right';
136 is($x->input_focus, $sixth->id, 'sixth window focused');
137
138 cmd "workspace $s2_ws";
139 cmd 'focus up';
140 is($x->input_focus, $second->id, 'second window focused');
141
142 ###################################################################
143 # Test that focus (left|down|right|up), when focusing across
144 # outputs, doesn't focus the next window in the given direction but
145 # the most focused window of the container in the given direction.
146 # In the following layout:
147 # [ WS1*[ ] WS2[ H[ A B* ] ] ]
148 # (where the asterisk denotes the focused container within its
149 # parent) moving right from WS1 should focus B which is focused
150 # inside WS2, not A which is the next window on the right of WS1.
151 # See issue #1160.
152 ###################################################################
153
154 kill_all_windows;
155
156 sync_with_i3;
157 $x->root->warp_pointer(1025, 0); # Second screen.
158 sync_with_i3;
159 $s1_ws = fresh_workspace;
160 $first = open_window;
161 $second = open_window;
162
163 sync_with_i3;
164 $x->root->warp_pointer(0, 0); # First screen.
165 sync_with_i3;
166 $s0_ws = fresh_workspace;
167 open_window;
168 $third = open_window;
169
170 cmd 'focus right';
171 is($x->input_focus, $second->id, 'second window (rightmost) focused');
172 cmd 'focus left';
173 is($x->input_focus, $first->id, 'first window focused');
174 cmd 'focus left';
175 is($x->input_focus, $third->id, 'third window focused');
176
177
178 ###################################################################
179 # Similar but with a tabbed layout.
180 ###################################################################
181
182 cmd 'layout tabbed';
183 $fourth = open_window;
184 cmd 'focus left';
185 is($x->input_focus, $third->id, 'third window (tabbed) focused');
186 cmd "workspace $s1_ws";
187 cmd 'focus left';
188 is($x->input_focus, $third->id, 'third window (tabbed) focused');
189
190
191 ###################################################################
192 # Similar but with a stacked layout on the bottom screen.
193 ###################################################################
194
195 sync_with_i3;
196 $x->root->warp_pointer(0, 769); # Third screen.
197 sync_with_i3;
198 $s2_ws = fresh_workspace;
199 cmd 'layout stacked';
200 $fifth = open_window;
201 $sixth = open_window;
202
203 cmd "workspace $s0_ws";
204 cmd 'focus down';
205 is($x->input_focus, $sixth->id, 'sixth window (stacked) focused');
206
207 ###################################################################
208 # Similar but with a more complex layout.
209 ###################################################################
210
211 sync_with_i3;
212 $x->root->warp_pointer(1025, 769); # Fourth screen.
213 sync_with_i3;
214 $s3_ws = fresh_workspace;
215 open_window;
216 open_window;
217 cmd 'split v';
218 open_window;
219 open_window;
220 cmd 'split h';
221 my $nested = open_window;
222 open_window;
223 cmd 'focus left';
224 is($x->input_focus, $nested->id, 'nested window focused');
225
226 cmd "workspace $s1_ws";
227 cmd 'focus down';
228 is($x->input_focus, $nested->id, 'nested window focused from workspace above');
229
230 cmd "workspace $s2_ws";
231 cmd 'focus right';
232 is($x->input_focus, $nested->id, 'nested window focused from workspace on the left');
233
234 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that ConfigureRequests don’t make windows fall out of the scratchpad.
17 # Ticket: #898
18 # Bug still in: 4.4-15-g770ead6
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 fake-outputs 1024x768+0+0,1024x768+1024+0
24 EOT
25
26 my $left_ws = fresh_workspace(output => 0);
27 my $right_ws = fresh_workspace(output => 1);
28
29 my $window = open_window;
30 cmd 'move scratchpad';
31
32 # Cause a ConfigureRequest by setting the window’s position/size.
33 my ($a, $t) = $window->rect;
34 $window->rect(X11::XCB::Rect->new(x => 0, y => 0, width => $a->width, height => $a->height));
35
36 sync_with_i3;
37
38 my $ws = get_ws($left_ws);
39 is(scalar @{$ws->{floating_nodes}}, 0, 'scratchpad window still in scratchpad after ConfigureRequest');
40 $ws = get_ws($right_ws);
41 is(scalar @{$ws->{floating_nodes}}, 0, 'scratchpad window still in scratchpad after ConfigureRequest');
42
43 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that moving containers wraps across outputs.
17 # E.g. when you have a container on the right output and you move it to the
18 # right, it should appear on the left output.
19 # Bug still in: 4.4-106-g3cd4b8c
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 fake-outputs 1024x768+0+0,1024x768+1024+0
25 EOT
26
27 my $right = fresh_workspace(output => 1);
28 my $left = fresh_workspace(output => 0);
29
30 my $win = open_window;
31
32 is_num_children($left, 1, 'one container on left workspace');
33
34 cmd 'move container to output right';
35 cmd 'focus output right';
36
37 is_num_children($left, 0, 'no containers on left workspace');
38 is_num_children($right, 1, 'one container on right workspace');
39
40 cmd 'move container to output right';
41
42 is_num_children($left, 1, 'one container on left workspace');
43 is_num_children($right, 0, 'no containers on right workspace');
44
45 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests whether moving workspaces between outputs works correctly.
17 use i3test i3_config => <<EOT;
18 # i3 config file (v4)
19 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
20
21 fake-outputs 1024x768+0+0,1024x768+1024+0
22 EOT
23 use List::Util qw(first);
24
25 sub workspaces_per_screen {
26 my $i3 = i3(get_socket_path());
27 my $tree = $i3->get_tree->recv;
28 my @outputs = @{$tree->{nodes}};
29
30 my $fake0 = first { $_->{name} eq 'fake-0' } @outputs;
31 my $fake0_content = first { $_->{type} eq 'con' } @{$fake0->{nodes}};
32
33 my $fake1 = first { $_->{name} eq 'fake-1' } @outputs;
34 my $fake1_content = first { $_->{type} eq 'con' } @{$fake1->{nodes}};
35
36 my @fake0_workspaces = map { $_->{name} } @{$fake0_content->{nodes}};
37 my @fake1_workspaces = map { $_->{name} } @{$fake1_content->{nodes}};
38
39 return \@fake0_workspaces, \@fake1_workspaces;
40 }
41
42 # Switch to temporary workspaces on both outputs so the numbers are free.
43 my $tmp_right = fresh_workspace(output => 1);
44 my $tmp_left = fresh_workspace(output => 0);
45
46 cmd 'workspace 1';
47 # Keep that workspace open.
48 my $win1 = open_window;
49
50 cmd 'workspace 5';
51 # Keep that workspace open.
52 open_window;
53
54 cmd "workspace $tmp_right";
55 cmd 'workspace 2';
56 # Keep that workspace open.
57 open_window;
58
59 my ($x0, $x1) = workspaces_per_screen();
60 is_deeply($x0, [ '1', '5' ], 'workspace 1 and 5 on fake-0');
61 is_deeply($x1, [ '2' ], 'workspace 2 on fake-1');
62
63 cmd 'workspace 1';
64
65 my ($nodes, $focus) = get_ws_content('1');
66 is($nodes->[0]->{window}, $win1->id, 'window 1 on workspace 1');
67
68 cmd 'move workspace next';
69 cmd '[id="' . $win1->id . '"] focus';
70
71 ($nodes, $focus) = get_ws_content('2');
72 is($nodes->[1]->{window}, $win1->id, 'window 1 on workspace 2 after moving');
73
74 cmd 'move workspace prev';
75 cmd '[id="' . $win1->id . '"] focus';
76
77 ($nodes, $focus) = get_ws_content('1');
78 is($nodes->[0]->{window}, $win1->id, 'window 1 on workspace 1');
79
80 cmd 'move workspace next_on_output';
81 cmd '[id="' . $win1->id . '"] focus';
82
83 ($nodes, $focus) = get_ws_content('5');
84 is($nodes->[1]->{window}, $win1->id, 'window 1 on workspace 5 after moving');
85
86 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Ticket: #990
17 # Bug still in: 4.5.1-23-g82b5978
18
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22 fake-outputs 1024x768+0+0,1024x768+1024+0
23 EOT
24
25 my $old_ws = get_ws(focused_ws);
26
27 my $focus = AnyEvent->condvar;
28 my @events = events_for(
29 sub { cmd 'focus output right' },
30 'workspace');
31
32 my $current_ws = get_ws(focused_ws);
33
34 is(scalar @events, 1, 'Received 1 event');
35 is($events[0]->{current}->{id}, $current_ws->{id}, 'Event gave correct current workspace');
36 is($events[0]->{old}->{id}, $old_ws->{id}, 'Event gave correct old workspace');
37
38 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that new workspace names are taken from the config,
17 # then from the first free number starting with 1.
18 #
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 fake-outputs 1024x768+0+0,1024x768+1024+0
24
25 bindsym 1 workspace 1: eggs
26 EOT
27
28 my $i3 = i3(get_socket_path());
29 my $ws = $i3->get_workspaces->recv;
30
31 is($ws->[0]->{name}, '1: eggs', 'new workspace uses config name');
32 is($ws->[1]->{name}, '2', 'naming continues with next free number');
33
34 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests if a simple 'move <direction>' command will move containers across outputs.
17 #
18 use i3test i3_config => <<EOT;
19 # i3 config file (v4)
20 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
21
22 fake-outputs 1024x768+0+0,1024x768+1024+0,1024x768+1024+768,1024x768+0+768
23
24 workspace left-top output fake-0
25 workspace right-top output fake-1
26 workspace right-bottom output fake-2
27 workspace left-bottom output fake-3
28 EOT
29
30 # Ensure the pointer is at (0, 0) so that we really start on the first
31 # (the left) workspace.
32 $x->root->warp_pointer(0, 0);
33
34 #####################################################################
35 # Try to move a single window across outputs in each direction
36 #####################################################################
37
38 cmd('workspace left-top');
39 my $alone_window = open_window;
40
41 cmd('move right');
42 is(scalar @{get_ws_content('right-top')}, 1, 'moved individual window to right-top workspace');
43
44 cmd('move down');
45 is(scalar @{get_ws_content('right-bottom')}, 1, 'moved individual window to right-bottom workspace');
46
47 cmd('move left');
48 is(scalar @{get_ws_content('left-bottom')}, 1, 'moved individual window to left-bottom workspace');
49
50 cmd('move up');
51 is(scalar @{get_ws_content('left-top')}, 1, 'moved individual window to left-top workspace');
52
53 $alone_window->unmap;
54 wait_for_unmap;
55
56 #####################################################################
57 # Try to move a window on a workspace with two windows across outputs in each
58 # direction
59 #####################################################################
60
61 # from left-top to right-top
62 cmd('workspace left-top');
63 cmd('split h');
64 my $first_window = open_window;
65 my $social_window = open_window( name => 'CORRECT_WINDOW' );
66 cmd('move right');
67 is(scalar @{get_ws_content('right-top')}, 1, 'moved some window to right-top workspace');
68 my $compare_window = shift @{get_ws_content('right-top')};
69 is($compare_window->{window}, $social_window->id, 'moved correct window to right-top workspace');
70 # unmap the first window so we don't confuse it when we move back here
71 $first_window->unmap;
72 wait_for_unmap;
73
74 # from right-top to right-bottom
75 cmd('split v');
76 open_window;
77 # this window opened above - we need to move down twice
78 cmd('focus up; move down; move down');
79 is(scalar @{get_ws_content('right-bottom')}, 1, 'moved some window to right-bottom workspace');
80 $compare_window = shift @{get_ws_content('right-bottom')};
81 is($compare_window->{name}, $social_window->name, 'moved correct window to right-bottom workspace');
82
83 # from right-bottom to left-bottom
84 cmd('split h');
85 open_window;
86 cmd('focus left; move left');
87 is(scalar @{get_ws_content('left-bottom')}, 1, 'moved some window to left-bottom workspace');
88 $compare_window = shift @{get_ws_content('left-bottom')};
89 is($social_window->name, $compare_window->{name}, 'moved correct window to left-bottom workspace');
90
91 # from left-bottom to left-top
92 cmd('split v');
93 open_window;
94 cmd('focus up; move up');
95 is(scalar @{get_ws_content('left-top')}, 1, 'moved some window to left-bottom workspace');
96 $compare_window = shift @{get_ws_content('left-top')};
97 is($social_window->name, $compare_window->{name}, 'moved correct window to left-bottom workspace');
98
99 #####################################################################
100 # Moving a fullscreen container should change its output.
101 #####################################################################
102
103 kill_all_windows;
104
105 cmd 'workspace left-top';
106 open_window;
107 my $fs_window = open_window;
108 open_window;
109
110 cmd '[id=' . $fs_window->id . '] fullscreen enable, move right';
111 is(scalar @{get_ws_content('right-top')}, 1, 'moved fullscreen window to right-top workspace');
112
113 #####################################################################
114 # Moving a global fullscreen container should not change its output.
115 #####################################################################
116
117 kill_all_windows;
118
119 cmd 'workspace left-top';
120 open_window;
121 open_window;
122 open_window;
123
124 cmd 'fullscreen global, move right, fullscreen disable';
125 is(scalar @{get_ws_content('right-top')}, 0, 'global fullscreen window didn\'t change workspace with move');
126
127 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Make sure the command `move <direction>` properly sends the workspace focus
17 # ipc event required for i3bar to be properly updated and redrawn.
18 #
19 # Bug still in: 4.6-195-g34232b8
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 fake-outputs 1024x768+0+0,1024x768+1024+0
25 workspace ws-left output fake-0
26 workspace ws-right output fake-1
27 EOT
28
29 # open two windows on the left output
30 cmd 'workspace ws-left';
31 open_window;
32 open_window;
33
34 sub focus_subtest {
35 my ($cmd, $want) = @_;
36
37 my @events = events_for(
38 sub { cmd $cmd },
39 'workspace');
40
41 my @focus = grep { $_->{change} eq 'focus' } @events;
42 is(scalar @focus, 1, 'Received 1 workspace::focus event');
43 is($focus[0]->{current}->{name}, 'ws-right', 'focus event gave the right workspace');
44 is(@{$focus[0]->{current}->{nodes}}, $want, 'focus event gave the right number of windows on the workspace');
45 }
46
47 # move a window over to the right output
48 subtest 'move right (1)', \&focus_subtest, 'move right', 1;
49
50 # move another window
51 cmd 'workspace ws-left';
52 subtest 'move right (2)', \&focus_subtest, 'move right', 2;
53
54 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that workspace assignment config directives for plain numbers will
17 # assign any workspace of that number to the specified output.
18 # Ticket: #1238
19 # Bug still in: 4.7.2-147-g3760a48
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 workspace 1:override output fake-0
25 workspace 2 output fake-0
26 workspace 1 output fake-1
27 workspace 2:override output fake-1
28 workspace 3 output fake-0
29 workspace 3:override output doesnotexist fake-1
30
31 fake-outputs 1024x768+0+0,1024x768+1024+0
32 EOT
33
34 ################################################################################
35 # Workspace assignments with bare numbers should be interpreted as `workspace
36 # number` config directives. Any workspace beginning with that number should be
37 # assigned to the specified output.
38 ################################################################################
39
40 cmd 'focus output fake-1';
41 cmd 'workspace "2:foo"';
42 is(get_output_for_workspace('2:foo'), 'fake-0',
43 'Workspaces should be assigned by number when the assignment is a plain number')
44 or diag 'Since workspace number 2 is assigned to fake-0, 2:foo should open on fake-0';
45
46 cmd 'focus output fake-0';
47 cmd 'workspace "2:override"';
48 is(get_output_for_workspace('2:override'), 'fake-1',
49 'Workspace assignments by name should override numbered assignments')
50 or diag 'Since workspace "2:override" is assigned by name to fake-1, it should open on fake-1';
51
52 cmd 'focus output fake-1';
53 cmd 'workspace "1:override"';
54 is(get_output_for_workspace('1:override'), 'fake-0',
55 'Assignment rules should not be affected by the order assignments are declared')
56 or diag 'Since workspace "1:override" is assigned by name to fake-0, it should open on fake-0';
57
58 cmd 'focus output fake-1';
59 cmd 'workspace "3:override"';
60 is(get_output_for_workspace('3:override'), 'fake-1',
61 'Assignment rules should not be affected by multiple output assignments')
62 or diag 'Since workspace "3:override" is assigned by name to fake-1, it should open on fake-1';
63
64 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
11 # (unless you are already familiar with Perl)
12
13 use i3test i3_config => <<EOT;
14 # i3 config file (v4)
15 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
16 fake-outputs 1024x768+0+0,1024x768+1024+0
17 mouse_warping none
18 EOT
19
20 # Ensure the pointer is at (0, 0) so that we really start on the first
21 # (the left) workspace.
22 $x->root->warp_pointer(0, 0);
23
24 ######################################################
25 # Open one workspace with one window on both outputs #
26 ######################################################
27
28 # Open window on workspace 1, left output
29 is(focused_ws, '1', 'starting with focus on workspace 1');
30 open_window;
31
32 # Open window on workspace 2, right output
33 cmd 'focus output right';
34 is(focused_ws, '2', 'moved focus to workspace 2');
35 open_window;
36
37 # If mouse_warping is disabled, the pointer has not moved from
38 # position (0, 0) when focus was switched to workspace 2
39 $x->root->warp_pointer(0, 0);
40
41 # Ensure focus is still on workspace 2
42 is(focused_ws, '2', 'warped mouse cursor to (0, 0), focus still in workspace 2');
43
44 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Ensure that `focus [direction]` will focus an existing floating con when no
17 # tiling con exists on the output in [direction] when focusing across outputs
18 # Bug still in: 4.7.2-204-g893dbae
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 workspace ws_left output fake-0
24 workspace ws_right output fake-1
25
26 mouse_warping none
27
28 fake-outputs 1024x768+0+0,1024x768+1024+0
29 EOT
30
31 cmd 'workspace ws_left';
32 my $win = open_window();
33
34 cmd 'floating enable';
35 cmd 'focus output right';
36 cmd 'focus left';
37
38 is($x->input_focus, $win->id,
39 'Focusing across outputs with `focus [direction]` should focus an existing floating con when no tiling con exists on the output in [direction].');
40
41 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test that the EWMH specified property _NET_DESKTOP_VIEWPORT is updated
17 # properly on the root window. We interpret this as a list of x/y coordinate
18 # pairs for the upper left corner of the respective outputs of the workspaces
19 # Ticket: #1241
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 workspace 0 output fake-0
25 workspace 1 output fake-1
26
27 fake-outputs 1024x768+0+0,1024x768+1024+0
28 EOT
29
30 sub get_desktop_viewport {
31 # Make sure that i3 pushed its changes to X11 before querying.
32 sync_with_i3;
33
34 my $cookie = $x->get_property(
35 0,
36 $x->get_root_window(),
37 $x->atom(name => '_NET_DESKTOP_VIEWPORT')->id,
38 $x->atom(name => 'CARDINAL')->id,
39 0,
40 4096
41 );
42
43 my $reply = $x->get_property_reply($cookie->{sequence});
44
45 return 0 if $reply->{value_len} == 0;
46
47 my $len = $reply->{length};
48
49 return unpack ("L$len", $reply->{value});
50 }
51
52 ################################################################################
53 # Initialize the workspaces
54 ################################################################################
55
56 cmd 'workspace 1';
57 cmd 'workspace 0';
58
59 my @expected_viewport = (0, 0, 1024, 0);
60 my @desktop_viewport = get_desktop_viewport;
61
62 is_deeply(\@desktop_viewport, \@expected_viewport,
63 '_NET_DESKTOP_VIEWPORT should be an array of x/y coordinate pairs for the upper left corner of the respective outputs of the workspaces');
64
65 ################################################################################
66 # Create workspace
67 ################################################################################
68
69 cmd 'workspace 0';
70 open_window;
71 cmd 'workspace 3';
72
73 @expected_viewport = (0, 0, 0, 0, 1024, 0);
74 @desktop_viewport = get_desktop_viewport;
75
76 is_deeply(\@desktop_viewport, \@expected_viewport,
77 'it should be updated when a new workspace appears');
78
79 ################################################################################
80 # Rename workspace
81 ################################################################################
82
83 cmd 'rename workspace 3 to 2';
84
85 @expected_viewport = (0, 0, 0, 0, 1024, 0);
86 @desktop_viewport = get_desktop_viewport;
87
88 is_deeply(\@desktop_viewport, \@expected_viewport,
89 'it should stay up to date when a workspace is renamed');
90
91 ################################################################################
92 # Empty workspace
93 ################################################################################
94
95 cmd 'workspace 0';
96
97 @expected_viewport = (0, 0, 1024, 0);
98 @desktop_viewport = get_desktop_viewport;
99
100 is_deeply(\@desktop_viewport, \@expected_viewport,
101 'it should be updated when a workspace is emptied');
102
103 ################################################################################
104 # Move workspace
105 # See #4001
106 ################################################################################
107
108 # Keep workspace 1 open to have 3 workspaces in total
109 cmd 'workspace 1';
110 open_window;
111 cmd 'workspace 0, move workspace to output right';
112 @expected_viewport = (0, 0, 1024, 0, 1024, 0);
113 @desktop_viewport = get_desktop_viewport;
114 is_deeply(\@desktop_viewport, \@expected_viewport,
115 'it should be updated when a workspace is moved');
116
117 ################################################################################
118
119 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 #
17 # Tests that workspaces are moved to the assigned output if they
18 # are renamed to an assigned name.
19 # Ticket: #1473
20
21 use i3test i3_config => <<EOT;
22 # i3 config file (v4)
23 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
24 fake-outputs 1024x768+0+0,1024x768+1024+0
25
26 workspace 1 output fake-0
27 workspace 2 output fake-1
28 workspace 3:foo output fake-1
29 workspace baz output fake-1
30 workspace 5 output left
31 workspace 6 output doesnotexist fake-0
32 workspace 7 output fake-1 fake-0
33 EOT
34
35 ##########################################################################
36 # Renaming the workspace to an unassigned name does not move the workspace
37 # (regression test)
38 ##########################################################################
39
40 cmd 'focus output fake-0';
41 cmd 'rename workspace to unassigned';
42 is(get_output_for_workspace('unassigned'), 'fake-0',
43 'Unassigned workspace should stay on its output when being renamed');
44
45 ##########################################################################
46 # Renaming a workspace by number only triggers the assignment
47 ##########################################################################
48
49 cmd 'focus output fake-0';
50 cmd 'rename workspace to 2';
51 is(get_output_for_workspace('2'), 'fake-1',
52 'Renaming the workspace to a number should move it to the assigned output');
53
54 ##########################################################################
55 # Renaming a workspace by number and name triggers the assignment
56 ##########################################################################
57
58 cmd 'focus output fake-0';
59 cmd 'rename workspace to "2:foo"';
60 is(get_output_for_workspace('2:foo'), 'fake-1',
61 'Renaming the workspace to a number and name should move it to the assigned output');
62
63 ##########################################################################
64 # Renaming a workspace by name only triggers the assignment
65 ##########################################################################
66
67 cmd 'focus output fake-0';
68 cmd 'rename workspace to baz';
69 is(get_output_for_workspace('baz'), 'fake-1',
70 'Renaming the workspace to a number and name should move it to the assigned output');
71
72 ##########################################################################
73 # Renaming a workspace so that it is assigned a directional output does
74 # not move the workspace or crash
75 ##########################################################################
76
77 cmd 'focus output fake-0';
78 cmd 'workspace bar';
79 cmd 'rename workspace to 5';
80 is(get_output_for_workspace('5'), 'fake-0',
81 'Renaming the workspace to a workspace assigned to a directional output should not move the workspace');
82
83 ##########################################################################
84 # Renaming an unfocused workspace, triggering an assignment to the output
85 # which holds the currently focused empty workspace should result in the
86 # original workspace replacing the empty one.
87 # See issue #3228.
88 ##########################################################################
89
90 cmd 'workspace baz';
91 cmd 'rename workspace 5 to 2';
92 is(get_output_for_workspace('2'), 'fake-1',
93 'Renaming an unfocused workspace, triggering an assignment to the output which holds the currently focused empty workspace should result in the original workspace replacing the empty one');
94
95 ##########################################################################
96 # Renaming an unfocused empty workspace, triggering an assignment to the
97 # output which holds the currently focused non-empty workspace should
98 # close the empty workspace and not crash i3.
99 # See issue #3248.
100 ##########################################################################
101
102 cmd 'workspace 1';
103 cmd 'workspace 2';
104 open_window;
105 cmd 'rename workspace 1 to baz';
106 is(get_output_for_workspace('baz'), '',
107 'Renaming an unfocused empty workspace, triggering an assignment to the output which holds the currently focused non-empty workspace should close the empty workspace and not crash i3');
108 kill_all_windows;
109
110 ##########################################################################
111 # Renaming a workspace with multiple assignments, where the first output
112 # doesn't exist.
113 ##########################################################################
114
115 cmd 'focus output fake-1';
116 cmd 'rename workspace to 6';
117 is(get_output_for_workspace('6'), 'fake-0',
118 'Renaming the workspace while first target output doesn\'t exist moves it to the second assigned output');
119
120 ##########################################################################
121 # Renaming a workspace with multiple assignments, where both outputs exist
122 # moves it to the first output.
123 ##########################################################################
124
125 cmd 'focus output fake-0';
126 cmd 'rename workspace to 7';
127 is(get_output_for_workspace('7'), 'fake-1',
128 'Renaming a workspace with multiple assignments, where both outputs exist moves it to the first output.');
129
130 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies that 'move position center' moves floating cons to the center of
17 # the appropriate output.
18 # Ticket: #1211
19 # Bug still in: 4.9.1-108-g037cb31
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 fake-outputs 1024x768+0+0,1024x768+1024+0
25
26 workspace left output fake-0
27 workspace right output fake-1
28 EOT
29
30 #####################################################################
31 # Verify that 'move position center' on a floating window does not
32 # move it to another output.
33 #####################################################################
34
35 cmd 'workspace left';
36
37 # Sync in case focus switched outputs due to the workspace change.
38 sync_with_i3;
39
40 my $floating = open_floating_window;
41
42 # Center the window on the left workspace
43 cmd 'move position center';
44 sync_with_i3;
45
46 is(scalar @{get_ws('left')->{floating_nodes}}, 1, 'one floating node on left ws');
47 is(scalar @{get_ws('right')->{floating_nodes}}, 0, 'no floating nodes on right ws');
48
49 # Center the window on the right workspace
50 cmd 'move workspace right; workspace right; move position center';
51 sync_with_i3;
52
53 is(scalar @{get_ws('left')->{floating_nodes}}, 0, 'no floating nodes on left ws');
54 is(scalar @{get_ws('right')->{floating_nodes}}, 1, 'one floating node on right ws');
55
56 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests the behaviour of 'move <direction>' when moving containers across
17 # outputs on workspaces that have non-default layouts.
18 # Ticket: #1603
19 # Bug still in: 4.10.1-40-g0ad097e
20 use List::Util qw(first);
21 use i3test i3_config => <<EOT;
22 # i3 config file (v4)
23 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
24
25 fake-outputs 1024x768+0+0,1024x768+1024+0,1024x768+1024+768,1024x768+0+768
26
27 workspace left-top output fake-0
28 workspace right-top output fake-1
29 workspace right-bottom output fake-2
30 workspace left-bottom output fake-3
31
32 workspace_layout stacked
33 EOT
34
35 #####################################################################
36 # Create two windows in the upper left workspace and move them
37 # clockwise around the workspaces until the end up where they began.
38 #####################################################################
39
40 cmd 'workspace left-top';
41
42 my $first = open_window(wm_class => 'first');
43 my $second = open_window(wm_class => 'second');
44
45 is_num_children('left-top', 1, 'one child on left-top');
46 is_num_children('right-top', 0, 'no children on right-top');
47
48 # Move the second window into its own stacked container.
49 cmd 'move right';
50 is_num_children('left-top', 2, 'two children on left-top');
51
52 # Move the second window onto the upper right workspace.
53 cmd 'move right';
54 is_num_children('left-top', 1, 'one child on left-top');
55 is_num_children('right-top', 1, 'one child on right-top');
56
57 # Move the first window onto the upper right workspace.
58 cmd '[class="first"] move right';
59 is_num_children('left-top', 0, 'no children on left-top');
60 is_num_children('right-top', 2, 'two children on right-top');
61
62 # Move the second window onto the lower right workspace.
63 cmd '[class="second"] move down, move down';
64 is_num_children('right-top', 1, 'one child on right-top');
65 is_num_children('right-bottom', 1, 'two children on right-bottom');
66
67 # Move the first window onto the lower right workspace.
68 cmd '[class="first"] move down';
69 is_num_children('right-top', 0, 'no children on right-top');
70 is_num_children('right-bottom', 2, 'two children on right-bottom');
71
72 # Move the second windo onto the lower left workspace.
73 cmd '[class="second"] move left, move left';
74 is_num_children('right-bottom', 1, 'one child on right-bottom');
75 is_num_children('left-bottom', 1, 'one on left-bottom');
76
77 # Move the first window onto the lower left workspace.
78 cmd '[class="first"] move left';
79 is_num_children('right-bottom', 0, 'no children on right-bottom');
80 is_num_children('left-bottom', 2, 'two children on left-bottom');
81
82 # Move the second window onto the upper left workspace.
83 cmd '[class="second"] move up, move up';
84 is_num_children('left-bottom', 1, 'one child on left-bottom');
85 is_num_children('left-top', 1, 'one child on left-top');
86
87 # Move the first window onto the upper left workspace.
88 cmd '[class="first"] move up';
89 is_num_children('left-bottom', 0, 'no children on left-bottom');
90 is_num_children('left-top', 2, 'two children on left-top');
91
92 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Ensures that mouse bindings on the i3bar work correctly.
17 # Ticket: #1695
18 use i3test i3_config => <<EOT;
19 # i3 config file (v4)
20 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
21 focus_follows_mouse no
22
23 bar {
24 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
25 position top
26
27 bindsym button1 focus left
28 bindsym button2 focus right
29 bindsym button3 focus left
30 bindsym button4 focus right
31 bindsym button5 focus left
32 bindsym --release button6 focus right
33 bindsym button7 focus left
34 bindsym button7 --release focus right
35 }
36 EOT
37 use i3test::XTEST;
38
39 my $i3 = i3(get_socket_path());
40 $i3->connect()->recv;
41 my $ws = fresh_workspace;
42
43 my $cv = AnyEvent->condvar;
44 my $timer = AnyEvent->timer(after => 1, interval => 0, cb => sub { $cv->send(0) });
45 $i3->subscribe({
46 window => sub {
47 my ($event) = @_;
48 if ($event->{change} eq 'focus') {
49 $cv->send($event->{container});
50 }
51 if ($event->{change} eq 'new') {
52 if (defined($event->{container}->{window_properties}->{class}) &&
53 $event->{container}->{window_properties}->{class} eq 'i3bar') {
54 $cv->send($event->{container});
55 }
56 }
57 },
58 })->recv;
59
60 sub i3bar_present {
61 my ($nodes) = @_;
62
63 for my $node (@{$nodes}) {
64 my $props = $node->{window_properties};
65 if (defined($props) && $props->{class} eq 'i3bar') {
66 return $node->{window};
67 }
68 }
69
70 return 0 if !@{$nodes};
71
72 my @children = (map { @{$_->{nodes}} } @{$nodes},
73 map { @{$_->{'floating_nodes'}} } @{$nodes});
74
75 return i3bar_present(\@children);
76 }
77
78 my $i3bar_window = i3bar_present($i3->get_tree->recv->{nodes});
79 if ($i3bar_window) {
80 ok(1, 'i3bar present');
81 } else {
82 my $con = $cv->recv;
83 ok($con, 'i3bar appeared');
84 $i3bar_window = $con->{window};
85 }
86
87 diag('i3bar window = ' . $i3bar_window);
88
89 my $left = open_window;
90 my $right = open_window;
91 sync_with_i3;
92
93 sub focus_subtest {
94 my ($subscribecb, $want, $msg) = @_;
95 my @events = events_for(
96 $subscribecb,
97 'window');
98 my @focus = map { $_->{container}->{window} } grep { $_->{change} eq 'focus' } @events;
99 is_deeply(\@focus, $want, $msg);
100 }
101
102 sub sync {
103 # Ensure XTEST events were sent to i3, which grabs and hence needs to
104 # forward any events to i3bar:
105 xtest_sync_with_i3;
106 # Ensure any pending i3bar IPC messages were handled by i3:
107 xtest_sync_with($i3bar_window);
108 }
109
110 subtest 'button 1 moves focus left', \&focus_subtest,
111 sub {
112 xtest_button_press(1, 3, 3);
113 xtest_button_release(1, 3, 3);
114 sync;
115 },
116 [ $left->{id} ],
117 'button 1 moves focus left';
118
119 subtest 'button 2 moves focus right', \&focus_subtest,
120 sub {
121 xtest_button_press(2, 3, 3);
122 xtest_button_release(2, 3, 3);
123 sync;
124 },
125 [ $right->{id} ],
126 'button 2 moves focus right';
127
128 subtest 'button 3 moves focus left', \&focus_subtest,
129 sub {
130 xtest_button_press(3, 3, 3);
131 xtest_button_release(3, 3, 3);
132 sync;
133 },
134 [ $left->{id} ],
135 'button 3 moves focus left';
136
137 subtest 'button 4 moves focus right', \&focus_subtest,
138 sub {
139 xtest_button_press(4, 3, 3);
140 xtest_button_release(4, 3, 3);
141 sync;
142 },
143 [ $right->{id} ],
144 'button 4 moves focus right';
145
146 subtest 'button 5 moves focus left', \&focus_subtest,
147 sub {
148 xtest_button_press(5, 3, 3);
149 xtest_button_release(5, 3, 3);
150 sync;
151 },
152 [ $left->{id} ],
153 'button 5 moves focus left';
154
155 # Test --release flag with bar bindsym.
156 # See issue: #3068.
157
158 my $old_focus = get_focused($ws);
159 subtest 'button 6 does not move focus while pressed', \&focus_subtest,
160 sub {
161 xtest_button_press(6, 3, 3);
162 sync;
163 },
164 [],
165 'button 6 does not move focus while pressed';
166 is(get_focused($ws), $old_focus, 'focus unchanged');
167
168 subtest 'button 6 release moves focus right', \&focus_subtest,
169 sub {
170 xtest_button_release(6, 3, 3);
171 sync;
172 },
173 [ $right->{id} ],
174 'button 6 release moves focus right';
175
176 # Test same bindsym button with and without --release.
177
178 subtest 'button 7 press moves focus left', \&focus_subtest,
179 sub {
180 xtest_button_press(7, 3, 3);
181 sync;
182 },
183 [ $left->{id} ],
184 'button 7 press moves focus left';
185
186 subtest 'button 7 release moves focus right', \&focus_subtest,
187 sub {
188 xtest_button_release(7, 3, 3);
189 sync;
190 },
191 [ $right->{id} ],
192 'button 7 release moves focus right';
193
194 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Test reconfiguration of dock clients.
17 # Ticket: #1883
18 use i3test i3_config => <<EOT;
19 # i3 config file (v4)
20 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
21
22 fake-outputs 1024x768+0+0,1024x768+1024+0
23
24 bar {
25 # Disable i3bar, which is also a dock client.
26 i3bar_command :
27 }
28 EOT
29
30 my ($window, $rect);
31 my (@docks);
32
33 ###############################################################################
34 # 1: Given two screens A and B and a dock client on screen A, when the dock
35 # client is reconfigured to be positioned on screen B, then the client is
36 # moved to the correct position.
37 ###############################################################################
38
39 $window = open_window({
40 window_type => $x->atom(name => '_NET_WM_WINDOW_TYPE_DOCK')
41 });
42
43 $rect = $window->rect;
44 is($rect->x, 0, 'sanity check: dock client is on the left screen');
45
46 $window->rect(X11::XCB::Rect->new(x => 1024, y => 0, width => 1024, height => 30));
47 sync_with_i3;
48
49 @docks = get_dock_clients;
50 is(@docks, 1, 'there is still exactly one dock');
51
52 is($docks[0]->{rect}->{x}, 1024, 'dock client has moved to the other screen');
53
54 ###############################################################################
55
56 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Ticket: #1378
17 use i3test;
18 use X11::XCB qw(:all);
19
20 sub get_ewmh_window {
21 my $cookie = $x->get_property(
22 0,
23 $x->get_root_window(),
24 $x->atom(name => '_NET_SUPPORTING_WM_CHECK')->id,
25 $x->atom(name => 'WINDOW')->id,
26 0,
27 4096
28 );
29
30 my $reply = $x->get_property_reply($cookie->{sequence});
31 my $len = $reply->{length};
32 return undef if $len == 0;
33
34 return unpack("L", $reply->{value});
35 }
36
37 my $window = open_window;
38 sync_with_i3;
39 is($x->input_focus, $window->id, 'sanity check: window has input focus');
40 cmd 'kill';
41 sync_with_i3;
42 is($x->input_focus, get_ewmh_window(), 'focus falls back to the EWMH window');
43
44 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests whether 'workspace next' works correctly.
17 #
18 use List::Util qw(first);
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 fake-outputs 1024x768+0+0,1024x768+1024+0
24 EOT
25
26 sub assert_next {
27 my ($expected) = @_;
28
29 cmd 'workspace next';
30 # We need to sync after changing focus to a different output to wait for the
31 # EnterNotify to be processed, otherwise it will be processed at some point
32 # later in time and mess up our subsequent tests.
33 sync_with_i3;
34
35 is(focused_ws, $expected, "workspace $expected focused");
36 }
37
38 sub assert_prev {
39 my ($expected) = @_;
40
41 cmd 'workspace prev';
42 # We need to sync after changing focus to a different output to wait for the
43 # EnterNotify to be processed, otherwise it will be processed at some point
44 # later in time and mess up our subsequent tests.
45 sync_with_i3;
46
47 is(focused_ws, $expected, "workspace $expected focused");
48 }
49
50 sync_with_i3;
51 $x->root->warp_pointer(0, 0);
52 sync_with_i3;
53
54 ################################################################################
55 # Setup workspaces so that they stay open (with an empty container).
56 # open_window ensures, this
57 #
58 # numbered named
59 # output 1 (left) : 1, 2, 3, 6, 7, B, F, C
60 # output 2 (right): 4, 5, A, D, E
61 #
62 ################################################################################
63
64 cmd 'focus output left';
65 cmd 'workspace A'; open_window;
66 cmd 'workspace D'; open_window;
67 cmd 'workspace 4'; open_window;
68 cmd 'workspace 5'; open_window;
69 cmd 'workspace E'; open_window;
70
71 cmd 'focus output right';
72 cmd 'workspace 1'; open_window;
73 cmd 'workspace 2'; open_window;
74 cmd 'workspace B'; open_window;
75 cmd 'workspace 3'; open_window;
76 cmd 'workspace F'; open_window;
77 cmd 'workspace 6'; open_window;
78 cmd 'workspace C'; open_window;
79 cmd 'workspace 7'; open_window;
80
81 ################################################################################
82 # Use workspace next and verify the correct order.
83 # numbered -> numerical sort
84 # named -> sort by creation time
85 ################################################################################
86 cmd 'workspace 1';
87 is(focused_ws, '1', 'back on workspace 1');
88
89 assert_next('2');
90 assert_next('3');
91 assert_next('4');
92 assert_next('5');
93 assert_next('6');
94 assert_next('7');
95
96 assert_next('B');
97 assert_next('F');
98 assert_next('C');
99 assert_next('A');
100 assert_next('D');
101 assert_next('E');
102 assert_next('1');
103
104 cmd 'workspace 1';
105 is(focused_ws, '1', 'back on workspace 1');
106
107 assert_prev('E');
108 assert_prev('D');
109 assert_prev('A');
110 assert_prev('C');
111 assert_prev('F');
112 assert_prev('B');
113
114 assert_prev('7');
115 assert_prev('6');
116 assert_prev('5');
117 assert_prev('4');
118 assert_prev('3');
119 assert_prev('2');
120 assert_prev('1');
121
122
123 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests for _NET_WM_DESKTOP.
17 # Ticket: #2153
18 use i3test i3_config => <<EOT;
19 # i3 config file (v4)
20 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
21
22 bar {
23 status_command i3status
24 }
25 EOT
26 use X11::XCB qw(:all);
27
28 ###############################################################################
29
30 sub get_net_wm_desktop {
31 sync_with_i3;
32
33 my ($con) = @_;
34 my $cookie = $x->get_property(
35 0,
36 $con->{id},
37 $x->atom(name => '_NET_WM_DESKTOP')->id,
38 $x->atom(name => 'CARDINAL')->id,
39 0,
40 1
41 );
42
43 my $reply = $x->get_property_reply($cookie->{sequence});
44 return undef if $reply->{length} != 1;
45
46 return unpack("L", $reply->{value});
47 }
48
49 sub send_net_wm_desktop {
50 my ($con, $idx) = @_;
51 my $msg = pack "CCSLLLLLL",
52 X11::XCB::CLIENT_MESSAGE, 32, 0,
53 $con->{id},
54 $x->atom(name => '_NET_WM_DESKTOP')->id,
55 $idx, 0, 0, 0, 0;
56
57 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
58 sync_with_i3;
59 }
60
61 sub open_window_with_net_wm_desktop {
62 my $idx = shift;
63 my $window = open_window(
64 before_map => sub {
65 my ($window) = @_;
66 $x->change_property(
67 PROP_MODE_REPLACE,
68 $window->id,
69 $x->atom(name => '_NET_WM_DESKTOP')->id,
70 $x->atom(name => 'CARDINAL')->id,
71 32, 1,
72 pack('L', $idx),
73 );
74 },
75 dont_map => 1,
76 );
77
78 # We don’t wait for MapNotify and instead sync with i3 so that we don’t need
79 # to encounter the full timeout of 4s when opening a window on a non-visible
80 # workspace.
81 $window->map;
82 sync_with_i3;
83
84 return $window;
85 }
86
87 ###############################################################################
88 # Upon managing a window which does not set _NET_WM_DESKTOP, the property is
89 # set on the window.
90 ###############################################################################
91
92 cmd 'workspace 1';
93 my $con = open_window;
94
95 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set upon managing a window');
96
97 kill_all_windows;
98
99 ###############################################################################
100 # Upon managing a window which sets _NET_WM_DESKTOP, the window is moved to
101 # the specified desktop.
102 ###############################################################################
103
104 cmd 'workspace 0';
105 open_window;
106 cmd 'workspace 1';
107 open_window;
108 cmd 'workspace 2';
109 open_window;
110
111 $con = open_window_with_net_wm_desktop(1);
112
113 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP still has the correct value');
114 is_num_children('1', 2, 'The window was moved to workspace 1');
115
116 kill_all_windows;
117
118 ###############################################################################
119 # Upon managing a window which sets _NET_WM_DESKTOP to the appropriate value,
120 # the window is made sticky and floating.
121 ###############################################################################
122
123 cmd 'workspace 0';
124 $con = open_window_with_net_wm_desktop(0xFFFFFFFF);
125
126 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP still has the correct value');
127 is(@{get_ws('0')->{floating_nodes}}, 1, 'The window is floating');
128 ok(get_ws('0')->{floating_nodes}->[0]->{nodes}->[0]->{sticky}, 'The window is sticky');
129
130 kill_all_windows;
131
132 ###############################################################################
133 # _NET_WM_DESKTOP is updated when the window is moved to another workspace
134 # on the same output.
135 ###############################################################################
136
137 cmd 'workspace 0';
138 open_window;
139 cmd 'workspace 1';
140 open_window;
141 cmd 'workspace 0';
142 $con = open_window;
143
144 cmd 'move window to workspace 1';
145
146 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated when moving the window');
147
148 kill_all_windows;
149
150 ###############################################################################
151 # _NET_WM_DESKTOP is updated when the floating window is moved to another
152 # workspace on the same output.
153 ###############################################################################
154
155 cmd 'workspace 0';
156 open_window;
157 cmd 'workspace 1';
158 open_window;
159 cmd 'workspace 0';
160 $con = open_window;
161 cmd 'floating enable';
162
163 cmd 'move window to workspace 1';
164
165 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated when moving the window');
166
167 kill_all_windows;
168
169 ###############################################################################
170 # _NET_WM_DESKTOP is removed when the window is withdrawn.
171 ###############################################################################
172
173 $con = open_window;
174 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set (sanity check)');
175
176 $con->unmap;
177 wait_for_unmap($con);
178
179 is(get_net_wm_desktop($con), undef, '_NET_WM_DESKTOP is removed');
180
181 kill_all_windows;
182
183 ###############################################################################
184 # A _NET_WM_DESKTOP client message sent to the root window moves a window
185 # to the correct workspace.
186 ###############################################################################
187
188 cmd 'workspace 0';
189 open_window;
190 cmd 'workspace 1';
191 open_window;
192 cmd 'workspace 0';
193
194 $con = open_window;
195 is_num_children('0', 2, 'The window is on workspace 0');
196
197 send_net_wm_desktop($con, 1);
198
199 is_num_children('0', 1, 'The window is no longer on workspace 0');
200 is_num_children('1', 2, 'The window is now on workspace 1');
201 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated');
202
203 kill_all_windows;
204
205 ###############################################################################
206 # A _NET_WM_DESKTOP client message sent to the root window can make a window
207 # sticky.
208 ###############################################################################
209
210 cmd 'workspace 0';
211 $con = open_window;
212
213 send_net_wm_desktop($con, 0xFFFFFFFF);
214
215 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
216 is(@{get_ws('0')->{floating_nodes}}, 1, 'The window is floating');
217 ok(get_ws('0')->{floating_nodes}->[0]->{nodes}->[0]->{sticky}, 'The window is sticky');
218
219 kill_all_windows;
220
221 ###############################################################################
222 # _NET_WM_DESKTOP is updated when a new workspace with a lower number is
223 # opened and closed.
224 ###############################################################################
225
226 cmd 'workspace 1';
227 $con = open_window;
228 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
229
230 cmd 'workspace 0';
231 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated');
232
233 kill_all_windows;
234
235 ###############################################################################
236 # _NET_WM_DESKTOP is updated when a window is made sticky by command.
237 ###############################################################################
238
239 cmd 'workspace 0';
240 $con = open_window;
241 cmd 'floating enable';
242 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
243
244 cmd 'sticky enable';
245 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
246
247 kill_all_windows;
248
249 ###############################################################################
250 # _NET_WM_DESKTOP is updated when a window is made sticky by client message.
251 ###############################################################################
252
253 cmd 'workspace 0';
254 $con = open_window;
255 cmd 'floating enable';
256 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
257
258 my $msg = pack "CCSLLLLLL",
259 X11::XCB::CLIENT_MESSAGE, 32, 0,
260 $con->{id},
261 $x->atom(name => '_NET_WM_STATE')->id,
262 1,
263 $x->atom(name => '_NET_WM_STATE_STICKY')->id,
264 0, 0, 0;
265
266 $x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
267 sync_with_i3;
268
269 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
270
271 kill_all_windows;
272
273 ###############################################################################
274 # _NET_WM_DESKTOP is updated when a window is moved to the scratchpad.
275 ###############################################################################
276
277 cmd 'workspace 0';
278 $con = open_window;
279 cmd 'floating enable';
280 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
281
282 cmd 'move scratchpad';
283 is(get_net_wm_desktop($con), 0xFFFFFFFF, '_NET_WM_DESKTOP is updated');
284
285 cmd 'scratchpad show';
286 is(get_net_wm_desktop($con), 0, '_NET_WM_DESKTOP is set sanity check)');
287
288 kill_all_windows;
289
290 ###############################################################################
291
292 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Ticket: #2229
17 # Bug still in: 4.11-262-geb631ce
18 use i3test i3_config => <<EOT;
19 # i3 config file (v4)
20 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
21
22 fake-outputs 400x400+0+0,400x400+400+0
23 workspace_auto_back_and_forth no
24 EOT
25
26 # Set it up such that workspace 3 is on the left output and
27 # workspace 4 is on the right output
28 cmd 'focus output fake-0';
29 open_window;
30 cmd 'workspace 3';
31 cmd 'focus output fake-1';
32 cmd 'workspace 4';
33 open_window;
34
35 cmd 'move workspace to output left';
36
37 ok(!workspace_exists('3'), 'workspace 3 has been closed');
38
39 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that fullscreen windows appear on the output indicated by
17 # their geometry
18 use i3test i3_config => <<EOT;
19 # i3 config file (v4)
20 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
21
22 fake-outputs 1024x768+0+0,1024x768+1024+0
23 EOT
24 use List::Util qw(first);
25
26 # Helper functions
27 sub fullscreen($) {
28 my ($window) = @_;
29 $window->fullscreen(1);
30 }
31
32 sub find_window {
33 my ($nodes, $id) = @_;
34
35 foreach (@{$nodes}) {
36 return $_ if ($_->{window} // 0) == $id;
37 my $node = find_window($_->{nodes}, $id);
38 return $node if $node;
39 };
40 return undef;
41 }
42
43 # Create two fullscreen windows, each on different output
44 my $orig_rect1 = X11::XCB::Rect->new(x => 0, y => 0, width => 1024, height => 768);
45 my $orig_rect2 = X11::XCB::Rect->new(x => 1024, y => 0, width => 1024, height => 768);
46
47 my $win_on_first_output = open_window(rect => $orig_rect1,
48 before_map => \&fullscreen);
49
50 my $win_on_second_output = open_window(rect => $orig_rect2,
51 before_map => \&fullscreen);
52
53 sync_with_i3;
54
55 # Check that the windows are on the correct output
56 is_deeply(scalar $win_on_first_output->rect, $orig_rect1, "first window spans the first output");
57 is_deeply(scalar $win_on_second_output->rect, $orig_rect2, "second window spans the sencond output");
58
59 # Check that both windows remained fullscreen
60 my $tree = i3(get_socket_path())->get_tree->recv;
61
62 my $node1 = find_window($tree->{nodes}, $win_on_first_output->{id});
63 my $node2 = find_window($tree->{nodes}, $win_on_second_output->{id});
64
65 is($node1->{fullscreen_mode}, 1, "first window is fullscreen");
66 is($node2->{fullscreen_mode}, 1, "second window is fullscreen");
67
68 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests for using X resources in the config.
17 # Ticket: #2130
18 use i3test i3_autostart => 0;
19 use X11::XCB qw(PROP_MODE_REPLACE);
20
21 sub get_marks {
22 return i3(get_socket_path())->get_marks->recv;
23 }
24
25 my $config = <<EOT;
26 # i3 config file (v4)
27 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
28
29 # This isn't necessarily what X resources are intended for, but it'll do the
30 # job for the test.
31 set_from_resource \$mark i3wm.mark none
32 for_window [class=worksforme] mark \$mark
33
34 set_from_resource \$othermark i3wm.doesnotexist none
35 for_window [class=doesnotworkforme] mark \$othermark
36
37 EOT
38
39 $x->change_property(
40 PROP_MODE_REPLACE,
41 $x->get_root_window(),
42 $x->atom(name => 'RESOURCE_MANAGER')->id,
43 $x->atom(name => 'STRING')->id,
44 32,
45 length('*mark: works'),
46 '*mark: works');
47 $x->flush;
48
49 my $pid = launch_with_config($config);
50
51 open_window(wm_class => 'worksforme');
52 sync_with_i3;
53 is_deeply(get_marks(), [ 'works' ], 'the resource has loaded correctly');
54
55 cmd 'kill';
56
57 open_window(wm_class => 'doesnotworkforme');
58 sync_with_i3;
59 is_deeply(get_marks(), [ 'none' ], 'the resource fallback was used');
60
61 exit_gracefully($pid);
62
63 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # TODO: Description of this file.
17 # Ticket: #999
18 # Bug still in: 4.13-12-g2ff3d9d
19 use File::Temp qw(tempfile);
20 use i3test i3_autostart => 0;
21
22 my $monitor_name = 'i3-fake-monitor';
23 my $output_name = 'i3-fake-output';
24
25 my $config = <<EOT;
26 # i3 config file (v4)
27 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
28
29 bar {
30 output $output_name
31 }
32 EOT
33
34 my ($outfh, $outname) = tempfile('i3-randr15reply-XXXXXX', UNLINK => 1);
35
36 # Prepare a RRGetMonitors reply, see A.2.4 in
37 # https://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt
38 my $reply = pack('cxSLLLLx[LLL]',
39 1, # reply
40 0, # sequence (will be filled in by inject_randr15)
41 # 60 = length($reply) + length($monitor1)
42 # 32 = minimum X11 reply length
43 (60-32) / 4, # length in words
44 0, # timestamp TODO
45 1, # nmonitors
46 1); # noutputs
47
48 # Manually intern _NET_CURRENT_DESKTOP as $x->atom will not create atoms if
49 # they are not yet interned.
50 my $atom_cookie = $x->intern_atom(0, length($monitor_name), $monitor_name);
51 my $monitor_name_atom = $x->intern_atom_reply($atom_cookie->{sequence})->{atom};
52
53 # MONITORINFO is defined in A.1.1 in
54 # https://cgit.freedesktop.org/xorg/proto/randrproto/tree/randrproto.txt
55 my $monitor1 = pack('LccSssSSLLL',
56 $monitor_name_atom, # name (ATOM)
57 1, # primary
58 1, # automatic
59 1, # ncrtcs
60 0, # x
61 0, # y
62 3840, # width in pixels
63 2160, # height in pixels
64 520, # width in millimeters
65 290, # height in millimeters
66 12345); # output ID #0
67
68 print $outfh $reply;
69 print $outfh $monitor1;
70
71 close($outfh);
72
73 # Prepare a RRGetOutputInfo reply as well; see RRGetOutputInfo in
74 # https://www.x.org/releases/current/doc/randrproto/randrproto.txt
75 ($outfh, my $outname_moninfo) = tempfile('i3-randr15reply-XXXXXX', UNLINK => 1);
76 my $moninfo = pack('cxSLLLx[LLccSSSS]S a* x!4',
77 1, # reply
78 0, # sequence (will be filled in by inject_randr15)
79 # 36 = length($moninfo) (without name and padding)
80 # 32 = minimum X11 reply length
81 ((36 + length($output_name) - 32) + 3) / 4, # length in words
82 0, # timestamp TODO
83 12345, # CRTC
84 length($output_name), # length of name
85 $output_name); # name
86
87 print $outfh $moninfo;
88 close($outfh);
89
90 my $pid = launch_with_config($config,
91 inject_randr15 => $outname,
92 inject_randr15_outputinfo => $outname_moninfo);
93
94 my $tree = i3->get_tree->recv;
95 my @outputs = map { $_->{name} } @{$tree->{nodes}};
96 is_deeply(\@outputs, [ '__i3', $monitor_name ], 'outputs are __i3 and the fake monitor');
97
98 my ($output_data) = grep { $_->{name} eq $monitor_name } @{$tree->{nodes}};
99 is_deeply($output_data->{rect}, {
100 width => 3840,
101 height => 2160,
102 x => 0,
103 y => 0,
104 }, "Fake output at 3840x2160+0+0");
105
106 # Verify that i3 canonicalizes RandR output names to i3 output names
107 # (RandR monitor names) for bar configs
108
109 my $bars = i3->get_bar_config()->recv;
110 is(@$bars, 1, 'one bar configured');
111
112 my $bar_id = shift @$bars;
113
114 my $bar_config = i3->get_bar_config($bar_id)->recv;
115 is_deeply($bar_config->{outputs}, [ $monitor_name ], 'bar_config output name is normalized');
116
117 exit_gracefully($pid);
118
119 ################################################################################
120 # Verify that adding monitors with RandR 1.5 results in i3 outputs.
121 ################################################################################
122
123 # When inject_randr15 is defined but false, fake-xinerama will be turned off,
124 # but inject_randr15 will not actually be used.
125 $pid = launch_with_config($config, inject_randr15 => '');
126
127 $tree = i3->get_tree->recv;
128 @outputs = map { $_->{name} } @{$tree->{nodes}};
129 is_deeply(\@outputs, [ '__i3', 'default' ], 'outputs are __i3 and default');
130
131 SKIP: {
132 my @events = events_for(
133 sub {
134 skip 'xrandr --setmonitor failed (xrandr too old?)', 1
135 unless system(q|xrandr --setmonitor up2414q 3840/527x2160/296+1280+0 none|) == 0;
136 },
137 "workspace");
138
139 my @init = grep { $_->{change} eq 'init' } @events;
140 is(scalar @init, 1, 'Received 1 workspace::init event');
141 is($init[0]->{current}->{output}, 'up2414q', 'Workspace initialized in up2414q');
142
143 $tree = i3->get_tree->recv;
144 @outputs = map { $_->{name} } @{$tree->{nodes}};
145 is_deeply(\@outputs, [ '__i3', 'default', 'up2414q' ], 'outputs are __i3, default and up2414q');
146 }
147
148 exit_gracefully($pid);
149
150 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Verifies i3 doesn’t warp when a new floating window is opened under the cursor
17 # over an unfocused workspace.
18 # Ticket: #2681
19 # Bug still in: 4.13-210-g80c23afa
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 fake-outputs 1024x768+0+0,1024x768+1024+0
25
26 focus_follows_mouse no
27 EOT
28
29 cmd 'focus output fake-0';
30 my $s0_ws = fresh_workspace;
31
32 cmd 'focus output fake-1';
33 my $s1_ws = fresh_workspace;
34 open_window;
35
36 # Move mouse to fake-0
37 sync_with_i3;
38 $x->root->warp_pointer(500, 0);
39 sync_with_i3;
40
41 my $dropdown = open_floating_window;
42 $dropdown->rect(X11::XCB::Rect->new(x => 1, y => 1, width => 100, height => 100));
43 sync_with_i3;
44
45 my $cookie = $x->query_pointer($dropdown->{id});
46 my $reply = $x->query_pointer_reply($cookie->{sequence});
47 cmp_ok($reply->{root_x}, '<', 1024, 'pointer still on fake-0');
48 cmp_ok($reply->{root_y}, '<', 768, 'pointer still on fake-0');
49
50 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests whether 'workspace next' works correctly.
17 #
18 use List::Util qw(first);
19 use i3test i3_config => <<EOT;
20 # i3 config file (v4)
21 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
22
23 fake-outputs 1024x768+0+0,1024x768+1024+0
24 EOT
25
26 sub assert_next {
27 my ($expected) = @_;
28
29 cmd 'workspace next';
30 # We need to sync after changing focus to a different output to wait for the
31 # EnterNotify to be processed, otherwise it will be processed at some point
32 # later in time and mess up our subsequent tests.
33 sync_with_i3;
34
35 is(focused_ws, $expected, "workspace $expected focused");
36 }
37
38 sub assert_prev {
39 my ($expected) = @_;
40
41 cmd 'workspace prev';
42 # We need to sync after changing focus to a different output to wait for the
43 # EnterNotify to be processed, otherwise it will be processed at some point
44 # later in time and mess up our subsequent tests.
45 sync_with_i3;
46
47 is(focused_ws, $expected, "workspace $expected focused");
48 }
49
50 sync_with_i3;
51 $x->root->warp_pointer(0, 0);
52 sync_with_i3;
53
54 ################################################################################
55 # Setup workspaces so that they stay open (with an empty container).
56 # open_window ensures, this
57 #
58 # numbered named
59 # output 1 (left) : 1, 2, 3, 6, 7, B, F, C
60 # output 2 (right): 4, 5, A, D, E
61 #
62 ################################################################################
63
64 cmd 'focus output right';
65 cmd 'workspace A'; open_window;
66 cmd 'workspace D'; open_window;
67 cmd 'workspace 4'; open_window;
68 cmd 'workspace 5'; open_window;
69 cmd 'workspace E'; open_window;
70
71 cmd 'focus output left';
72 cmd 'workspace 1'; open_window;
73 cmd 'workspace 2'; open_window;
74 cmd 'workspace B'; open_window;
75 cmd 'workspace 3'; open_window;
76 cmd 'workspace F'; open_window;
77 cmd 'workspace 6'; open_window;
78 cmd 'workspace C'; open_window;
79 cmd 'workspace 7'; open_window;
80
81 ################################################################################
82 # Use workspace next and verify the correct order.
83 # numbered -> numerical sort
84 # named -> sort by creation time
85 ################################################################################
86 cmd 'workspace 1';
87 is(focused_ws, '1', 'back on workspace 1');
88
89 assert_next('2');
90 assert_next('3');
91 assert_next('4');
92 assert_next('5');
93 assert_next('6');
94 assert_next('7');
95
96 assert_next('B');
97 assert_next('F');
98 assert_next('C');
99 assert_next('A');
100 assert_next('D');
101 assert_next('E');
102 assert_next('1');
103
104 cmd 'workspace 1';
105 is(focused_ws, '1', 'back on workspace 1');
106
107 assert_prev('E');
108 assert_prev('D');
109 assert_prev('A');
110 assert_prev('C');
111 assert_prev('F');
112 assert_prev('B');
113
114 assert_prev('7');
115 assert_prev('6');
116 assert_prev('5');
117 assert_prev('4');
118 assert_prev('3');
119 assert_prev('2');
120 assert_prev('1');
121
122
123 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests for _NET_WM_DESKTOP.
17 # Ticket: #2153
18 use i3test i3_config => <<EOT;
19 # i3 config file (v4)
20 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
21
22 workspace "0" output "fake-0"
23 workspace "1" output "fake-0"
24 workspace "2" output "fake-0"
25 workspace "10" output "fake-1"
26 workspace "11" output "fake-1"
27 workspace "12" output "fake-1"
28
29 fake-outputs 1024x768+0+0,1024x768+1024+0
30 EOT
31 use X11::XCB qw(:all);
32
33 sub get_net_wm_desktop {
34 sync_with_i3;
35
36 my ($con) = @_;
37 my $cookie = $x->get_property(
38 0,
39 $con->{id},
40 $x->atom(name => '_NET_WM_DESKTOP')->id,
41 $x->atom(name => 'CARDINAL')->id,
42 0,
43 1
44 );
45
46 my $reply = $x->get_property_reply($cookie->{sequence});
47 return undef if $reply->{length} != 1;
48
49 return unpack("L", $reply->{value});
50 }
51
52 ###############################################################################
53 # _NET_WM_DESKTOP is updated when the window is moved to another workspace
54 # on another output.
55 ###############################################################################
56
57 cmd 'workspace 0';
58 open_window;
59 cmd 'workspace 10';
60 open_window;
61 cmd 'workspace 0';
62 my $con = open_window;
63
64 cmd 'move window to workspace 10';
65
66 is(get_net_wm_desktop($con), 1, '_NET_WM_DESKTOP is updated when moving the window');
67
68 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that windows inside containers with a single child do not jump
17 # over other containers and erratically move across outputs.
18 # Ticket: #2466
19 # Bug still in: 4.14-63-g75d11820
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 fake-outputs 640x480+0+0,640x480+640+0
25
26 workspace left output fake-0
27 workspace right output fake-1
28 EOT
29
30 cmd 'workspace right';
31
32 # ┌───────────────────────────┐ ┌───────────────────────────┐
33 # │ Output 1 │ │ Output 2 - splith │
34 # │ │ │┌───────────┐┌────────────┐│
35 # │ │ ││ ││ splitv ││
36 # │ │ ││ ││╔══════════╗││
37 # │ │ ││ ││║ ║││
38 # │ (empty workspace) │ ││ first ││║ second ║││
39 # │ │ ││ ││║ ║││
40 # │ │ ││ ││║ ║││
41 # │ │ ││ ││╚══════════╝││
42 # │ │ │└───────────┘└────────────┘│
43 # └───────────────────────────┘ └───────────────────────────┘
44 #
45 # Moving "second" left shouldn't cause it to jump over to output 1.
46
47 my $first = open_window;
48 my $second = open_window;
49
50 # Put the second window into its own splitv container
51 cmd 'split v';
52
53 is_num_children('left', 0, 'No children on left');
54 is_num_children('right', 2, 'Two children on right');
55
56 # Move the second window to the left
57 cmd 'move left';
58
59 is_num_children('left', 0, 'Still no children on left');
60 is_num_children('right', 2, 'Still two children on right');
61
62 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that i3bars configured to use the primary output do not have
17 # their output names canonicalized to something other than "primary".
18 # Ticket: #2948
19 # Bug still in: 4.14-93-ga3a7d04a
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 fake-outputs 1024x768+0+0P
25
26 bar {
27 output primary
28 }
29 EOT
30
31 my $bars = i3->get_bar_config()->recv;
32 is(@$bars, 1, 'one bar configured');
33
34 my $bar_id = shift @$bars;
35
36 my $bar_config = i3->get_bar_config($bar_id)->recv;
37 is_deeply($bar_config->{outputs}, [ "primary" ], 'bar_config output is primary');
38
39 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • http://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • http://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • http://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that focus does not wrap when focus_wrapping is disabled in
17 # the configuration.
18 # Ticket: #2352
19 # Bug still in: 4.14-72-g6411130c
20 use i3test i3_config => <<EOT;
21 # i3 config file (v4)
22 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
23
24 focus_wrapping no
25 EOT
26
27 sub test_orientation {
28 my ($orientation, $prev, $next) = @_;
29 my $tmp = fresh_workspace;
30
31 cmd "split $orientation";
32
33 my $win1 = open_window;
34 my $win2 = open_window;
35
36 is($x->input_focus, $win2->id, "Second window focused initially");
37 cmd "focus $prev";
38 is($x->input_focus, $win1->id, "First window focused");
39 cmd "focus $prev";
40 is($x->input_focus, $win1->id, "First window still focused");
41 cmd "focus $next";
42 is($x->input_focus, $win2->id, "Second window focused");
43 cmd "focus $next";
44 is($x->input_focus, $win2->id, "Second window still focused");
45 }
46
47 test_orientation('v', 'up', 'down');
48 test_orientation('h', 'left', 'right');
49
50 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that the socket file is cleaned up properly after gracefully
17 # shutting down i3 via SIGTERM.
18 # Ticket: #3049
19 use i3test i3_autostart => 0;
20
21 my $config = <<EOT;
22 # i3 config file (v4)
23 font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1
24 EOT
25
26 my $pid = launch_with_config($config, dont_add_socket_path => 1);
27 my $socket = get_socket_path();
28 ok(-S $socket, "socket $socket exists");
29
30 exit_forcefully($pid, 'TERM');
31
32 ok(!-e $socket, "socket $socket no longer exists");
33
34 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests resizing tiling containers
17 use i3test;
18
19 ############################################################
20 # resize horizontally
21 ############################################################
22
23 my $tmp = fresh_workspace;
24
25 cmd 'split h';
26
27 my $left = open_window;
28 my $right = open_window;
29
30 diag("left = " . $left->id . ", right = " . $right->id);
31
32 is($x->input_focus, $right->id, 'Right window focused');
33
34 cmd 'resize set 75 ppt 0 ppt';
35
36 my ($nodes, $focus) = get_ws_content($tmp);
37
38 cmp_float($nodes->[0]->{percent}, 0.25, 'left window got only 25%');
39 cmp_float($nodes->[1]->{percent}, 0.75, 'right window got 75%');
40
41 # Same but use the 'width' keyword.
42 cmd 'resize set width 80 ppt';
43
44 ($nodes, $focus) = get_ws_content($tmp);
45
46 cmp_float($nodes->[0]->{percent}, 0.20, 'left window got 20%');
47 cmp_float($nodes->[1]->{percent}, 0.80, 'right window got 80%');
48
49 # Same but with px.
50 cmd 'resize set width 200 px';
51
52 ($nodes, $focus) = get_ws_content($tmp);
53
54 cmp_float($nodes->[1]->{rect}->{width}, 200, 'right window got 200 px');
55
56 ############################################################
57 # resize vertically
58 ############################################################
59
60 $tmp = fresh_workspace;
61
62 cmd 'split v';
63
64 my $top = open_window;
65 my $bottom = open_window;
66
67 diag("top = " . $top->id . ", bottom = " . $bottom->id);
68
69 is($x->input_focus, $bottom->id, 'Bottom window focused');
70
71 cmd 'resize set 0 ppt 75 ppt';
72
73 ($nodes, $focus) = get_ws_content($tmp);
74
75 cmp_float($nodes->[0]->{percent}, 0.25, 'top window got only 25%');
76 cmp_float($nodes->[1]->{percent}, 0.75, 'bottom window got 75%');
77
78 # Same but use the 'height' keyword.
79 cmd 'resize set height 80 ppt';
80
81 ($nodes, $focus) = get_ws_content($tmp);
82
83 cmp_float($nodes->[0]->{percent}, 0.20, 'top window got 20%');
84 cmp_float($nodes->[1]->{percent}, 0.80, 'bottom window got 80%');
85
86 # Same but with px.
87 cmd 'resize set height 200 px';
88
89 ($nodes, $focus) = get_ws_content($tmp);
90
91 cmp_float($nodes->[1]->{rect}->{height}, 200, 'bottom window got 200 px');
92
93 ############################################################
94 # resize horizontally and vertically
95 ############################################################
96
97 $tmp = fresh_workspace;
98
99 cmd 'split h';
100 $left = open_window;
101 my $top_right = open_window;
102 cmd 'split v';
103 my $bottom_right = open_window;
104
105 diag("left = " . $left->id . ", top-right = " . $top_right->id . ", bottom-right = " . $bottom_right->id);
106
107 is($x->input_focus, $bottom_right->id, 'Bottom-right window focused');
108
109 cmd 'resize set 75 ppt 75 ppt';
110
111 ($nodes, $focus) = get_ws_content($tmp);
112
113 cmp_float($nodes->[0]->{percent}, 0.25, 'left container got 25%');
114 cmp_float($nodes->[1]->{percent}, 0.75, 'right container got 75%');
115 cmp_float($nodes->[1]->{nodes}->[0]->{percent}, 0.25, 'top-right window got 25%');
116 cmp_float($nodes->[1]->{nodes}->[1]->{percent}, 0.75, 'bottom-right window got 75%');
117
118 # Same but with px.
119 cmd 'resize set 155 px 135 px';
120
121 ($nodes, $focus) = get_ws_content($tmp);
122
123 cmp_float($nodes->[1]->{nodes}->[1]->{rect}->{width}, 155, 'bottom-right window got 155 px width');
124 cmp_float($nodes->[1]->{nodes}->[1]->{rect}->{height}, 135, 'bottom-right window got 135 px height');
125
126 # Without specifying mode
127 cmd 'resize set 201 131';
128
129 ($nodes, $focus) = get_ws_content($tmp);
130
131 cmp_float($nodes->[1]->{nodes}->[1]->{rect}->{width}, 201, 'bottom-right window got 201 px width');
132 cmp_float($nodes->[1]->{nodes}->[1]->{rect}->{height}, 131, 'bottom-right window got 131 px height');
133
134 # Mix ppt and px
135 cmd 'resize set 75 ppt 200 px';
136
137 ($nodes, $focus) = get_ws_content($tmp);
138
139 cmp_float($nodes->[0]->{percent}, 0.25, 'left container got 25%');
140 cmp_float($nodes->[1]->{percent}, 0.75, 'right container got 75%');
141 cmp_float($nodes->[1]->{nodes}->[1]->{rect}->{height}, 200, 'bottom-right window got 200 px height');
142
143 ############################################################
144 # resize from inside a tabbed container
145 ############################################################
146
147 $tmp = fresh_workspace;
148
149 cmd 'split h';
150
151 $left = open_window;
152 my $right1 = open_window;
153
154 cmd 'split h';
155 cmd 'layout tabbed';
156
157 my $right2 = open_window;
158
159 diag("left = " . $left->id . ", right1 = " . $right1->id . ", right2 = " . $right2->id);
160
161 is($x->input_focus, $right2->id, '2nd right window focused');
162
163 cmd 'resize set 75 ppt 0 ppt';
164
165 ($nodes, $focus) = get_ws_content($tmp);
166
167 cmp_float($nodes->[0]->{percent}, 0.25, 'left container got 25%');
168 cmp_float($nodes->[1]->{percent}, 0.75, 'right container got 75%');
169
170 # Same but with px.
171 cmd 'resize set 155 px';
172
173 ($nodes, $focus) = get_ws_content($tmp);
174
175 cmp_float($nodes->[1]->{rect}->{width}, 155, 'right container got 155 px');
176
177 ############################################################
178 # resize from inside a stacked container
179 ############################################################
180
181 $tmp = fresh_workspace;
182
183 cmd 'split h';
184
185 $left = open_window;
186 $right1 = open_window;
187
188 cmd 'split h';
189 cmd 'layout stacked';
190
191 $right2 = open_window;
192
193 diag("left = " . $left->id . ", right1 = " . $right1->id . ", right2 = " . $right2->id);
194
195 is($x->input_focus, $right2->id, '2nd right window focused');
196
197 cmd 'resize set 75 ppt 0 ppt';
198
199 ($nodes, $focus) = get_ws_content($tmp);
200
201 cmp_float($nodes->[0]->{percent}, 0.25, 'left container got 25%');
202 cmp_float($nodes->[1]->{percent}, 0.75, 'right container got 75%');
203
204 # Same but with px.
205 cmd 'resize set 130 px';
206
207 ($nodes, $focus) = get_ws_content($tmp);
208
209 cmp_float($nodes->[1]->{rect}->{width}, 130, 'right container got 130 px');
210
211 done_testing;
0 #!perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # Please read the following documents before working on tests:
4 # • https://build.i3wm.org/docs/testsuite.html
5 # (or docs/testsuite)
6 #
7 # • https://build.i3wm.org/docs/lib-i3test.html
8 # (alternatively: perldoc ./testcases/lib/i3test.pm)
9 #
10 # • https://build.i3wm.org/docs/ipc.html
11 # (or docs/ipc)
12 #
13 # • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf
14 # (unless you are already familiar with Perl)
15 #
16 # Tests that swallowing still works after a window gets managed and its property
17 # updated.
18 use i3test;
19 use File::Temp qw(tempfile);
20 use IO::Handle;
21 use X11::XCB qw(PROP_MODE_REPLACE);
22
23 sub change_window_title {
24 my ($window, $title, $length) = @_;
25 my $atomname = $x->atom(name => '_NET_WM_NAME');
26 my $atomtype = $x->atom(name => 'UTF8_STRING');
27 $length ||= length($title) + 1;
28 $x->change_property(
29 PROP_MODE_REPLACE,
30 $window->id,
31 $atomname->id,
32 $atomtype->id,
33 8,
34 $length,
35 $title
36 );
37 sync_with_i3;
38 }
39
40 my $ws = fresh_workspace;
41
42 my @content = @{get_ws_content($ws)};
43 is(@content, 0, 'no nodes on the new workspace yet');
44
45 my ($fh, $filename) = tempfile(UNLINK => 1);
46 print $fh <<EOT;
47 {
48 "layout": "splitv",
49 "nodes": [
50 {
51 "swallows": [
52 {
53 "title": "different_title"
54 }
55 ]
56 }
57 ]
58 }
59 EOT
60 $fh->flush;
61 cmd "append_layout $filename";
62
63 @content = @{get_ws_content($ws)};
64 is(@content, 1, 'one node on the workspace now');
65
66 my $window = open_window(
67 name => 'original_title',
68 wm_class => 'a',
69 );
70
71 @content = @{get_ws_content($ws)};
72 is(@content, 2, 'two nodes on the workspace now');
73
74 change_window_title($window, "different_title");
75
76 does_i3_live;
77
78 @content = @{get_ws_content($ws)};
79 my @nodes = @{$content[0]->{nodes}};
80 is(@content, 1, 'only one node on the workspace now');
81 is($nodes[0]->{name}, 'different_title', 'test window got swallowed');
82
83 close($fh);
84
85 done_testing;
0 #
1 # Valgrind suppression file for i3 testcases
2 #
3 # Format specification:
4 # http://valgrind.org/docs/manual/manual-core.html#manual-core.suppress
5 #
6
7 #
8 # GLib
9 #
10 {
11 Ignore fundamental GType registration
12 Memcheck:Leak
13 ...
14 fun:g_type_register_fundamental
15 ...
16 }
17
18 {
19 Ignore static GType registration
20 Memcheck:Leak
21 match-leak-kinds: possible
22 ...
23 fun:g_type_register_static
24 ...
25 }
26
27 {
28 Ignore GObject init function
29 Memcheck:Leak
30 match-leak-kinds: possible
31 ...
32 obj:/usr/lib/libgobject-2.0*
33 ...
34 fun:call_init.part.0
35 ...
36 }
0 {
1 "package": {
2 "name": "i3-wm",
3 "repo": "i3-autobuild",
4 "subject": "i3"
5 },
6
7 "version": {
8 "name": "%version%",
9 "desc": "TODO",
10 "gpgSign": false
11 },
12
13 "files": [
14 {
15 "includePattern": "build/deb/debian-amd64/(.*\\.deb)$",
16 "matrixParams": {
17 "deb_distribution": "sid",
18 "deb_component": "main",
19 "deb_architecture": "amd64"
20 },
21 "uploadPattern": "$1"
22 },
23 {
24 "includePattern": "build/deb/debian-i386/(.*\\.deb)$",
25 "matrixParams": {
26 "deb_distribution": "sid",
27 "deb_component": "main",
28 "deb_architecture": "i386"
29 },
30 "uploadPattern": "$1"
31 }
32 ],
33
34 "publish": true
35 }
0 {
1 "package": {
2 "name": "i3-wm",
3 "repo": "i3-autobuild-ubuntu",
4 "subject": "i3"
5 },
6
7 "version": {
8 "name": "%version%",
9 "desc": "TODO",
10 "gpgSign": false
11 },
12
13 "files": [
14 {
15 "includePattern": "build/deb/ubuntu-amd64/(.*\\.deb)$",
16 "matrixParams": {
17 "deb_distribution": "bionic",
18 "deb_component": "main",
19 "deb_architecture": "amd64"
20 },
21 "uploadPattern": "$1"
22 },
23 {
24 "includePattern": "build/deb/ubuntu-i386/(.*\\.deb)$",
25 "matrixParams": {
26 "deb_distribution": "bionic",
27 "deb_component": "main",
28 "deb_architecture": "i386"
29 },
30 "uploadPattern": "$1"
31 }
32 ],
33
34 "publish": true
35 }
0 #!/bin/sh
1
2 set -e
3 set -x
4
5 clang-format-6.0 -i $(find . -name "*.[ch]" | tr '\n' ' ') && git diff --exit-code || (echo 'Code was not formatted using clang-format!'; false)
0 #!/bin/sh
1 funcs='malloc|calloc|realloc|strdup|strndup|asprintf|write'
2 cstring='"([^"\\]|\\.)*"'
3 cchar="'[^\\\\]'|'\\\\.[^']*'"
4 regex="^([^'\"]|${cstring}|${cchar})*\<(${funcs})\>"
5 detected=0
6 while IFS= read -r file; do
7 if { cpp -w -fpreprocessed "$file" || exit "$?"; } | grep -E -- "$regex"; then
8 echo "^ $file calls a function that has a safe counterpart."
9 detected=1
10 fi
11 done << EOF
12 $(find -name '*.c' -not -name safewrappers.c -not -name strndup.c)
13 EOF
14 if [ "$detected" -ne 0 ]; then
15 echo
16 echo "Calls of functions that have safe counterparts were detected."
17 exit 1
18 fi
0 #!/usr/bin/env perl
1 # vim:ts=4:sw=4:expandtab
2 #
3 # © 2016 Michael Stapelberg
4 #
5 # Checks for spelling errors in binaries and manpages (to be run by continuous
6 # integration to point out spelling errors before accepting contributions).
7
8 use strict;
9 use warnings;
10 use v5.10;
11 use autodie;
12 use lib 'testcases/lib';
13 use i3test::Util qw(slurp);
14 use Lintian::Spelling qw(check_spelling);
15
16 # Lintian complains if we don’t set a vendor.
17 use Lintian::Data;
18 use Lintian::Profile;
19
20 my $profile = Lintian::Profile->new;
21 $profile->load('debian', ['/usr/share/lintian']);
22
23 Lintian::Data->set_vendor($profile);
24
25 my $exitcode = 0;
26
27 # Whitelist for spelling errors in manpages, in case the spell checker has
28 # false-positives.
29 my $binary_spelling_exceptions = {
30 #'exmaple' => 1, # Example for how to add entries to this whitelist.
31 'betwen' => 1, # asan_flags.inc contains this spelling error.
32 };
33 my @binaries = qw(
34 build/i3
35 build/i3-config-wizard/i3-config-wizard
36 build/i3-dump-log/i3-dump-log
37 build/i3-input/i3-input
38 build/i3-msg/i3-msg
39 build/i3-nagbar/i3-nagbar
40 build/i3bar/i3bar
41 );
42 for my $binary (@binaries) {
43 check_spelling(slurp($binary), $binary_spelling_exceptions, sub {
44 my ($current, $fixed) = @_;
45 say STDERR qq|Binary "$binary" contains a spelling error: "$current" should be "$fixed"|;
46 $exitcode = 1;
47 });
48 }
49
50 # Whitelist for spelling errors in manpages, in case the spell checker has
51 # false-positives.
52 my $manpage_spelling_exceptions = {
53 };
54
55 for my $name (glob('build/man/*.1')) {
56 for my $line (split(/\n/, slurp($name))) {
57 next if $line =~ /^\.\\\"/o;
58 check_spelling($line, $manpage_spelling_exceptions, sub {
59 my ($current, $fixed) = @_;
60 say STDERR qq|Manpage "$name" contains a spelling error: "$current" should be "$fixed"|;
61 $exitcode = 1;
62 });
63 }
64 }
65
66 exit $exitcode;
0 #!/usr/bin/env perl
1 # vim:ts=4:sw=4:expandtab
2
3 use strict;
4 use warnings;
5 use Data::Dumper;
6 use HTTP::Tiny; # in core since v5.13.9
7 use JSON::PP; # in core since v5.13.9
8 use MIME::Base64; # in core since v5.7
9 use v5.13;
10
11 my $repo = shift;
12
13 my $auth = $ENV{'BINTRAY_USER'} . ':' . $ENV{'BINTRAY_KEY'};
14 die "BINTRAY_USER and/or BINTRAY_KEY environment variables not set" if $auth eq ':';
15 # TODO(stapelberg): switch to putting $auth into the URL once perl-modules ≥
16 # 5.20 is available on travis (Ubuntu Wily or newer).
17 my $auth_header = 'Basic ' . MIME::Base64::encode_base64($auth, "");
18 my $apiurl = 'https://api.bintray.com/packages/i3/' . $repo . '/i3-wm';
19 my $client = HTTP::Tiny->new(
20 verify_SSL => 1,
21 default_headers => {
22 'authorization' => $auth_header,
23 });
24 my $resp = $client->get($apiurl);
25 die "Getting versions failed: HTTP status $resp->{status} (content: $resp->{content})" unless $resp->{success};
26 my $decoded = decode_json($resp->{content});
27 my @versions = reverse sort {
28 (system("/usr/bin/dpkg", "--compare-versions", "$a", "gt", "$b") == 0) ? 1 : -1
29 } @{$decoded->{versions}};
30
31 # Keep the most recent 5 versions.
32 splice(@versions, 0, 5);
33
34 for my $version (@versions) {
35 say "Deleting old version $version";
36 $resp = $client->request('DELETE', "$apiurl/versions/$version");
37 die "Deletion of version $version failed: HTTP status $resp->{status} (content: $resp->{content})" unless $resp->{success};
38 }
0 #!/bin/sh
1
2 set -e
3 set -x
4
5 DEST=$1
6
7 mkdir -p build
8 cd build
9 ../configure
10 make echo-version > ../I3_VERSION
11 make dist-bzip2
12 # unpack dist tarball
13 mkdir -p "${DEST}"
14 tar xf *.tar.bz2 -C "${DEST}" --strip-components=1
15 cp -r ../debian "${DEST}"
16 sed -i '/^\s*libxcb-xrm-dev/d' deb/ubuntu-*/DIST/debian/control || true
17 cd "${DEST}"
18 debchange -m -l+g$(git describe --tags) 'Automatically built'
19 dpkg-buildpackage -b
0 #!/bin/sh
1
2 set -e
3 set -x
4
5 GITVERSION=$(git describe --tags)
6
7 mkdir build.i3wm.org
8 cp -r deb/COPY-DOCS build.i3wm.org/docs
9 cd build.i3wm.org
10 echo build.i3wm.org > CNAME
11 git init
12
13 git config user.name "Travis CI"
14 git config user.email "[email protected]"
15 git add .
16 git commit -m "Publish docs/static analysis for github.com/i3/i3 v${GITVERSION}"
17
18 # Hide stdout/stderr because it might contain sensitive info.
19 set +x
20 echo "git push"
21 git push --force --quiet "https://${GH_TOKEN}@github.com/i3/build.i3wm.org.git" master:gh-pages >/dev/null 2>&1
0 #!/bin/sh
1
2 set -e
3
4 BASENAME=$1
5 DOCKERFILE=$2
6
7 # .dockerignore is created on demand so that release.sh and other scripts are
8 # not influenced by our travis setup.
9 echo .git > .dockerignore
10
11 docker build --pull --no-cache --rm -t=${BASENAME} -f ${DOCKERFILE} .
12 # For pull requests, travis does not add secure environment variables to the
13 # environment (because pull requests could then steal their values), so skip
14 # the login+push step when the variable isn’t set.
15 if [ -n "${DOCKER_PASS}" ]
16 then
17 docker login -u ${DOCKER_USER} -p ${DOCKER_PASS}
18 docker push ${BASENAME}
19 fi
0 #!/bin/sh
1
2 set -e
3 set -x
4
5 for f in $(grep '\.html$' debian/i3-wm.docs | grep -v 'docs/refcard.html' | grep -v 'docs/lib-i3test')
6 do
7 asciidoc -a linkcss -a stylesdir=https://i3wm.org/css -a scriptsdir=https://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf $(dirname $f)/$(basename $f .html)
8 done
9 ./docs/i3-pod2html --stylesurl=https://i3wm.org/css i3-dmenu-desktop man/i3-dmenu-desktop.html
10 ./docs/i3-pod2html --stylesurl=https://i3wm.org/css i3-save-tree man/i3-save-tree.html
11 ./docs/i3-pod2html --stylesurl=https://i3wm.org/css build/testcases/lib/i3test.pm docs/lib-i3test.html
12 ./docs/i3-pod2html --stylesurl=https://i3wm.org/css testcases/lib/i3test/Test.pm docs/lib-i3test-test.html
13 for file in $(sed 's/\.1$/.man/g' debian/i3-wm.manpages)
14 do
15 [ -f "$file" ] && asciidoc -a linkcss -a stylesdir=https://i3wm.org/css -a scriptsdir=https://i3wm.org/js --backend=xhtml11 -f docs/asciidoc-git.conf "$file"
16 done
17
18 mkdir -p deb/COPY-DOCS
19
20 cp $(tr "\n" ' ' < debian/i3-wm.docs) deb/COPY-DOCS/
21 cp $(sed 's/\.1$/.html/g' debian/i3-wm.manpages | tr "\n" ' ') deb/COPY-DOCS/
0 #!/bin/sh
1 # Returns a hash to be used as version number suffix for the i3/travis-base
2 # docker container. The hash is over all files which influence what gets
3 # installed in the container, so that any changes in what needs to be installed
4 # will result in a cache invalidation.
5
6 cat debian/control "$1" | sha256sum | dd bs=1 count=8 status=none
0 #!/bin/sh
1
2 set -e
3 set -x
4
5 sed -i "s,%version%,$(git describe --tags),g" travis/bintray-autobuild-*.json
0 #!/bin/sh
1
2 set -e
3 set -x
4
5 cd build
6
7 # TODO: remove this workaround once https://bugs.debian.org/836723 is fixed
8 # Found at https://llvm.org/bugs/show_bug.cgi?id=27310#c8:
9 if [ "$CC" = "clang" ]
10 then
11 cat >fixasan.c <<EOT
12 void __isoc99_printf() {}
13 void __isoc99_sprintf() {}
14 void __isoc99_snprintf() {}
15 void __isoc99_fprintf() {}
16 void __isoc99_vprintf() {}
17 void __isoc99_vsprintf() {}
18 void __isoc99_vsnprintf() {}
19 void __isoc99_vfprintf() {}
20 void __cxa_throw() {} // NEW
21 EOT
22 gcc fixasan.c -o fixasan.so -fPIC -shared -nostdlib
23 export LD_PRELOAD=$PWD/fixasan.so
24 fi
25
26 # Try running the tests in parallel so that the common case (tests pass) is
27 # quick, but fall back to running them in sequence to make debugging easier.
28 if ! make check
29 then
30 ./testcases/complete-run.pl --parallel=1 || (cat latest/complete-run.log; false)
31 fi
0 #!/bin/sh
1 # Returns true if Debian/Ubuntu packages should be skipped because this CI run
2 # was triggered by a pull request.
3
4 # Verify BINTRAY_USER is present (only set on github.com/i3/i3),
5 # otherwise the CI run was triggered by a pull request.
6 # Verify CC=gcc so that we only build packages once for each commit,
7 # not twice (with gcc and clang).
8 if [ ! -z "$BINTRAY_USER" ] && [ "$CC" = "gcc" ]
9 then
10 exit 1
11 fi
12
13 exit 0
0 # vim:ft=Dockerfile
1 # Same as travis-base.Dockerfile, but without the test suite dependencies since
2 # we only build Debian packages on i386, we don’t run the tests.
3 FROM i386/debian:sid
4
5 RUN echo force-unsafe-io > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup
6 # Paper over occasional network flakiness of some mirrors.
7 RUN echo 'APT::Acquire::Retries "5";' > /etc/apt/apt.conf.d/80retry
8
9 # NOTE: I tried exclusively using gce_debian_mirror.storage.googleapis.com
10 # instead of httpredir.debian.org, but the results (Fetched 123 MB in 36s (3357
11 # kB/s)) are not any better than httpredir.debian.org (Fetched 123 MB in 34s
12 # (3608 kB/s)). Hence, let’s stick with httpredir.debian.org (default) for now.
13
14 # Install mk-build-deps (for installing the i3 build dependencies),
15 # clang and clang-format-6.0 (for checking formatting and building with clang),
16 # lintian (for checking spelling errors),
17 RUN linux32 apt-get update && \
18 DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
19 dpkg-dev devscripts git equivs \
20 clang clang-format-6.0 \
21 lintian && \
22 rm -rf /var/lib/apt/lists/*
23
24 # Install i3 build dependencies.
25 COPY debian/control /usr/src/i3-debian-packaging/control
26 RUN linux32 apt-get update && \
27 DEBIAN_FRONTEND=noninteractive mk-build-deps --install --remove --tool 'apt-get --no-install-recommends -y' /usr/src/i3-debian-packaging/control && \
28 rm -rf /var/lib/apt/lists/*
0 # vim:ft=Dockerfile
1 # Same as travis-base.Dockerfile, but without the test suite dependencies since
2 # we only build Debian packages on Ubuntu i386, we don’t run the tests.
3 FROM i386/ubuntu:bionic
4
5 RUN echo force-unsafe-io > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup
6 # Paper over occasional network flakiness of some mirrors.
7 RUN echo 'APT::Acquire::Retries "5";' > /etc/apt/apt.conf.d/80retry
8
9 # NOTE: I tried exclusively using gce_debian_mirror.storage.googleapis.com
10 # instead of httpredir.debian.org, but the results (Fetched 123 MB in 36s (3357
11 # kB/s)) are not any better than httpredir.debian.org (Fetched 123 MB in 34s
12 # (3608 kB/s)). Hence, let’s stick with httpredir.debian.org (default) for now.
13
14 # Install mk-build-deps (for installing the i3 build dependencies),
15 # clang and clang-format-6.0 (for checking formatting and building with clang),
16 # lintian (for checking spelling errors),
17 RUN linux32 apt-get update && \
18 DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
19 dpkg-dev devscripts git equivs \
20 clang clang-format-6.0 \
21 lintian && \
22 rm -rf /var/lib/apt/lists/*
23
24 # Install i3 build dependencies.
25 COPY debian/control /usr/src/i3-debian-packaging/control
26 RUN linux32 apt-get update && \
27 DEBIAN_FRONTEND=noninteractive mk-build-deps --install --remove --tool 'apt-get --no-install-recommends -y' /usr/src/i3-debian-packaging/control && \
28 rm -rf /var/lib/apt/lists/*
0 # vim:ft=Dockerfile
1 # Same as travis-base.Dockerfile, but without the test suite dependencies since
2 # we only build Debian packages on Ubuntu, we don’t run the tests.
3 FROM ubuntu:bionic
4
5 RUN echo force-unsafe-io > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup
6 # Paper over occasional network flakiness of some mirrors.
7 RUN echo 'APT::Acquire::Retries "5";' > /etc/apt/apt.conf.d/80retry
8
9 # NOTE: I tried exclusively using gce_debian_mirror.storage.googleapis.com
10 # instead of httpredir.debian.org, but the results (Fetched 123 MB in 36s (3357
11 # kB/s)) are not any better than httpredir.debian.org (Fetched 123 MB in 34s
12 # (3608 kB/s)). Hence, let’s stick with httpredir.debian.org (default) for now.
13
14 # Install mk-build-deps (for installing the i3 build dependencies),
15 # clang and clang-format-6.0 (for checking formatting and building with clang),
16 # lintian (for checking spelling errors),
17 # test suite dependencies (for running tests)
18 RUN apt-get update && \
19 DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
20 dpkg-dev devscripts git equivs \
21 clang clang-format-6.0 \
22 lintian && \
23 rm -rf /var/lib/apt/lists/*
24
25 # Install i3 build dependencies.
26 COPY debian/control /usr/src/i3-debian-packaging/control
27 RUN apt-get update && \
28 DEBIAN_FRONTEND=noninteractive mk-build-deps --install --remove --tool 'apt-get --no-install-recommends -y' /usr/src/i3-debian-packaging/control && \
29 rm -rf /var/lib/apt/lists/*
0 # vim:ft=Dockerfile
1 FROM debian:sid
2
3 RUN echo force-unsafe-io > /etc/dpkg/dpkg.cfg.d/docker-apt-speedup
4 # Paper over occasional network flakiness of some mirrors.
5 RUN echo 'APT::Acquire::Retries "5";' > /etc/apt/apt.conf.d/80retry
6
7 # NOTE: I tried exclusively using gce_debian_mirror.storage.googleapis.com
8 # instead of httpredir.debian.org, but the results (Fetched 123 MB in 36s (3357
9 # kB/s)) are not any better than httpredir.debian.org (Fetched 123 MB in 34s
10 # (3608 kB/s)). Hence, let’s stick with httpredir.debian.org (default) for now.
11
12 # Install mk-build-deps (for installing the i3 build dependencies),
13 # clang and clang-format-6.0 (for checking formatting and building with clang),
14 # lintian (for checking spelling errors),
15 # test suite dependencies (for running tests)
16 RUN apt-get update && \
17 DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
18 dpkg-dev devscripts git equivs \
19 clang clang-format-6.0 \
20 lintian \
21 libmodule-install-perl libanyevent-perl libextutils-pkgconfig-perl xcb-proto cpanminus xvfb xserver-xephyr xauth libinline-perl libinline-c-perl libxml-simple-perl libmouse-perl libmousex-nativetraits-perl libextutils-depends-perl perl libtest-deep-perl libtest-exception-perl libxml-parser-perl libtest-simple-perl libtest-fatal-perl libdata-dump-perl libtest-differences-perl libxml-tokeparser-perl libipc-run-perl libxcb-xtest0-dev libx11-xcb-perl libjson-xs-perl x11-xserver-utils && \
22 rm -rf /var/lib/apt/lists/*
23
24 # Install i3 build dependencies.
25 COPY debian/control /usr/src/i3-debian-packaging/control
26 COPY debian/changelog /usr/src/i3-debian-packaging/changelog
27 RUN apt-get update && \
28 DEBIAN_FRONTEND=noninteractive mk-build-deps --install --remove --tool 'apt-get --no-install-recommends -y' /usr/src/i3-debian-packaging/control && \
29 rm -rf /var/lib/apt/lists/*