User:Dan Nessett/Technical/Notes on Refactoring CZ: Difference between revisions
imported>Dan Nessett |
No edit summary |
||
(6 intermediate revisions by one other user not shown) | |||
Line 1: | Line 1: | ||
{{AccountNotLive}} | |||
==Things to do for MW standard extension upgrade== | |||
On Special:Version the line: | |||
:<pre>MediaWiki 1.13.2 (modified) (r99)</pre> | |||
has a link next to r99. This points to svn.wikimedia. It should point to svn.citizendium. This needs to be fixed. | |||
==Where to get svn_load_dirs.pl and configure it== | ==Where to get svn_load_dirs.pl and configure it== | ||
Line 10: | Line 19: | ||
<pre>< my $svn = '/usr/bin/svn';</pre> | <pre>< my $svn = '/usr/bin/svn';</pre> | ||
==Steps for upgrade== | |||
===Pre-upgrade=== | |||
* merge LocalSettings on the live wiki with that on the test wiki and keep the results around for use during the upgrade process. ('''Done''') | |||
* install php-xml on both locke and reid ('''Done''') | |||
===Upgrade process=== | |||
* Switch en.citizendium.org so it points only to reid. | |||
* On locke: | |||
:* Change /etc/httpd/conf.d/en.citizendium.org to comment out /wiki Alias and add testing Alias | |||
:* Change LocalSettings so $wgScript equals testing path | |||
:* move mediawiki to mediawikibackup. | |||
:* create a new mediawiki directory. | |||
:* checkout CZ_Refactor_1_13_2_0 into the new mediawiki directory (this is the revision currently running on the test wiki). | |||
:* soft link images and fix up the logo pointers. | |||
:* test locke.citizendium.org using the test data in section below. | |||
:* If the tests pass: | |||
::* Change /etc/httpd/conf.d/en.citizendium.org to restore /wiki Alias | |||
::* Change LocalSettings so $wgScript equals /wiki | |||
::* switch en.citizendium.org to point to locke. | |||
:* Wait 24 hours to see if any problems arise. | |||
* During 24 hour wait period, perform same upgrade steps on reid that were applied to locke. | |||
* If no problems arise during 24 test period, switch en.citizendium.org back into round-robin dns. | |||
This process is flexible in the following ways: | |||
* If problems arise, it is easy to switch back to the old code by simply renaming the new mediawiki directory to something else and mediawikibackup to mediawiki. | |||
* If the new code somehow corrupts the db ('''extremely unlikely'''), we have the back up, which we can use to restore the wiki to its pre-upgrade state. | |||
==MW standard extensions to check== | ==MW standard extensions to check== | ||
Line 170: | Line 210: | ||
<pre>SELECT column_name FROM information_schema.columns WHERE table_name ='table';</pre> | <pre>SELECT column_name FROM information_schema.columns WHERE table_name ='table';</pre> | ||
===An idea to improve test suite performance=== | ===An idea to improve test suite performance=== | ||
Line 268: | Line 236: | ||
* There may be other changes to the db state that occur outside the auspices of the BEGIN/COMMIT transaction scope. This requires investigation. | * There may be other changes to the db state that occur outside the auspices of the BEGIN/COMMIT transaction scope. This requires investigation. | ||
* It isn't clear that all supported database allow dirty reads inside of transaction blocks. This is another issue that requires investigation. | * It isn't clear that all supported database allow dirty reads inside of transaction blocks. This is another issue that requires investigation. | ||
After some thought, I think the best way to approach this problem is create a small CZ db that has only the minimum data necessary for defining a test. A test designer would then copy this db and modify the resulting wiki with data necessary for the test to run. The modified db could then be dumped using pg_dump and put in a standard or configurable location. When the test is run, the test (or a context manager) drops the existing wiki db, recreates it and uses psql to load the test db into the wiki db. The test is then run. | |||
If it is useful to run tests in parallel, this approach requires some modification. In particular, each test needs to run off a unique db. So, you can't use the standard wiki db name. Each test would have to define a db name. It would then call psql to drop any existing version of this db, recreate it and use psql to load the test db into this newly created db. The test would than have to change $wgDBname to equal the test db name. Since LocalSettings defines $wgDBname, the extension approach specified in the Selenium Framework notes of 5/15/2010 where a test extension is called at the end of LocalSettings must be used to override $wgDBname (and perhaps $wgDBuser and $wgDBpassword ). | |||
==Testing data for MW standard extensions== | ==Testing data for MW standard extensions== |
Latest revision as of 02:39, 22 November 2023
The account of this former contributor was not re-activated after the server upgrade of March 2022.
Things to do for MW standard extension upgrade
On Special:Version the line:
MediaWiki 1.13.2 (modified) (r99)
has a link next to r99. This points to svn.wikimedia. It should point to svn.citizendium. This needs to be fixed.
Where to get svn_load_dirs.pl and configure it
You can get svn_load_dirs.ph.in here: svn_load_dirs directory
Edit the file and (around line 26) change the following line:
< my $svn = '@SVN_BINDIR@/svn';
by replacing @SVN_BINDIR@/svn by the directory in which svn resides. For Ubuntu the line would like like:
< my $svn = '/usr/bin/svn';
Steps for upgrade
Pre-upgrade
- merge LocalSettings on the live wiki with that on the test wiki and keep the results around for use during the upgrade process. (Done)
- install php-xml on both locke and reid (Done)
Upgrade process
- Switch en.citizendium.org so it points only to reid.
- On locke:
- Change /etc/httpd/conf.d/en.citizendium.org to comment out /wiki Alias and add testing Alias
- Change LocalSettings so $wgScript equals testing path
- move mediawiki to mediawikibackup.
- create a new mediawiki directory.
- checkout CZ_Refactor_1_13_2_0 into the new mediawiki directory (this is the revision currently running on the test wiki).
- soft link images and fix up the logo pointers.
- test locke.citizendium.org using the test data in section below.
- If the tests pass:
- Change /etc/httpd/conf.d/en.citizendium.org to restore /wiki Alias
- Change LocalSettings so $wgScript equals /wiki
- switch en.citizendium.org to point to locke.
- Wait 24 hours to see if any problems arise.
- During 24 hour wait period, perform same upgrade steps on reid that were applied to locke.
- If no problems arise during 24 test period, switch en.citizendium.org back into round-robin dns.
This process is flexible in the following ways:
- If problems arise, it is easy to switch back to the old code by simply renaming the new mediawiki directory to something else and mediawikibackup to mediawiki.
- If the new code somehow corrupts the db (extremely unlikely), we have the back up, which we can use to restore the wiki to its pre-upgrade state.
MW standard extensions to check
Extension Name | Notes | Status |
---|---|---|
CategoryTree | The default limit on entries displayed is 200. This is controlled by $wgCategoryTreeMaxChildren |
Works |
CharInsert | Works | |
CheckUser | Requires db schema changes First execute php CheckUser/install.php |
Works |
Cite | Works | |
ConfirmAccount | Works | |
ConfirmEdit | Need to move setting of $wgGroupPermissions['sysop']['skipcaptcha'] = false; into LocalSettings.php, since the defaults of the MW standard |
Works |
EmbedVideo | Works | |
ExpandTemplates | The default size of the input box is 11 chars. Have to add the following to Mediawiki:common.css: body.page-Special_ExpandTemplates textarea { width: 100%; padding-top: 0.1em; padding-right: 0.1em; padding-bottom: 0.1em; padding-left: 0.1em; } Tested on: |
Works |
ImageMap | Must have php-xml module installed. ImageMap uses class DOMDocument and that is supplied by the php-xml module. Don't forget to restart |
Works Fixed problem with this extension by installing php-xml using |
inputbox | Works | |
Newuserlog | This extension is obsolete and replaced by core functionality starting in 1.14. |
Works |
ParserFunctions | Works | |
Renameuser | Works | |
Timeline | Works | |
TreeAndMenu | This extension replaces Treeview4 which is obsolete. TreeAndMenu is backwards |
Works |
wikihiero | Works |
Refactoring issues
- It appears many pages (including the Request Account page) has constables@citizendium.org hardwired in. There is no magic word available to access the $wgPasswordSender global variable or any other email address. This is something that the Citizendium extension should add (i.e., a magic word for the site's configured complaint email address).
- It also appears that many Mediawiki namespace pages have http://en.citizendium.org hardwired. These should be changed to: {{SERVER}}{{SCRIPTPATH}}
- For some reason Special:Popularpages doesn't work in the MW version, nor does it appear in the SpecialPages list.
- Solved. Had $wgDisableCounters=true in LocalSettings. Changed it to false.
- Conversely, Special:ExpandTemplates doesn't work in the CZ version, nor does it appear in the SpecialPages list.
- Actually, it does work. However, it doesn't show up in the Special:SpecialPages list
- Actually, it does show up in the Special:SpecialPages list. However, it is under "Other special pages", rather than "Wiki data and tools".
- Actually, it does work. However, it doesn't show up in the Special:SpecialPages list
Test harness notes
Useful SQL commands
To display a list of all tables in a schema use:
MySQL
SHOW TABLES;
Postgresql
SELECT table_name FROM information_schema.tables WHERE table_schema = 'mediawiki';
To display a list of all databases use:
MySQL
SHOW DATABASES;
Postgresql
SELECT datname FROM pg_database;
To display a list of all columns in a table use:
MySQL
SHOW COLUMNS
Postgresql
SELECT column_name FROM information_schema.columns WHERE table_name ='table';
An idea to improve test suite performance
Dropping tables and repopulating them or dropping the database and recreating it is a pretty expensive operation. Doing so could significantly slow down the time it takes to run a test suite. Here is another option. I am not a db expert, so this idea may make no sense at all, but for the record:
- Before the test suite runs, setup starts a transaction with an SQL BEGIN statement.
- Setup notes the value of $wgDBtype and copies that value to $wgDBActualtype. It then changes $wgDBtype to point to a new class that implements the logic described here.
- When the methods of the new class (which extends class Database) are called, most simply forward the call to methods in the class specified by $wgDBActualtype.
- However, when doQuery() is called, the new class methods check to see if the operation is either a BEGIN or a COMMIT. If so, it is not executed (so all of the test suite traffic belongs to a single transaction).
- All reads to the database are then dirty reads, so they return non-committed data.
- When the test suite completes, a tear down facility CANCELs the transaction.
Here are some pros and cons of this scheme:
Pros
- Each time a test runs the database (or a set of tables) need not be dropped and repopulated. This should significantly speedup the execution of a test suite.
- With this facility tests could be run against a real database, which would relieve the test designer from creating a test database configuration for each test/test suite.
- This approach allows fuzz testing of random data, since a test suite could run against a real database, not just a database architected specifically for the purpose of testing.
Cons
- Introducing the intervening Database class changes the software under test. This would lessen the confidence that the test suite verifies that software.
- It isn't clear this strategy will actually work. Since all tests run under the same transaction, the transaction sequence could get quite long and it may be the case that some DB software will croak.
- There may be other changes to the db state that occur outside the auspices of the BEGIN/COMMIT transaction scope. This requires investigation.
- It isn't clear that all supported database allow dirty reads inside of transaction blocks. This is another issue that requires investigation.
After some thought, I think the best way to approach this problem is create a small CZ db that has only the minimum data necessary for defining a test. A test designer would then copy this db and modify the resulting wiki with data necessary for the test to run. The modified db could then be dumped using pg_dump and put in a standard or configurable location. When the test is run, the test (or a context manager) drops the existing wiki db, recreates it and uses psql to load the test db into the wiki db. The test is then run.
If it is useful to run tests in parallel, this approach requires some modification. In particular, each test needs to run off a unique db. So, you can't use the standard wiki db name. Each test would have to define a db name. It would then call psql to drop any existing version of this db, recreate it and use psql to load the test db into this newly created db. The test would than have to change $wgDBname to equal the test db name. Since LocalSettings defines $wgDBname, the extension approach specified in the Selenium Framework notes of 5/15/2010 where a test extension is called at the end of LocalSettings must be used to override $wgDBname (and perhaps $wgDBuser and $wgDBpassword ).
Testing data for MW standard extensions
Data for CategoryTree Special Page
Biology_tag
Engineering tag
Health Sciences tag
Sports tag
References to EmbedVideo
- Donegal fiddle tradition/Video
- Butler/Video
- Atom (science)/Video
- John Akii-Bua/Video
- Information overload
- Vocal learning/Video
- Human uniqueness/Video
- Entrainment (biomusicology)/Video
- Capercaillie (band)/Video
- Ari Babakhanov/Video
- Kawir/Video
- Altan/Video
- A-ha/Video
- Google Chrome/Video
- The Weavers/Video
- Accelerated early childhood education
- Wikipedia/Video
- Kingston Trio/Video
- Arudou Debito/Video
- Penguin/Video
- Open access/Video
- Embryo/Video
- Brain/Video
- Law/Video
- Bioinformatics/Video
- Ecology/Video
- CZ:Ref:DOI:10.1007/s10329-008-0117-y/Video
- Try (rugby)/Video
- Neuron/Video
- Ecological Indian
- Talk:HUBO
- HUBO/Video
- Scarborough Castle/Video
- Scarborough, North Yorkshire/Video
- Doctor Who/Video
- Science 2.0/Video
- Science/Video
- Music perception/Video
- Music production/Video
- Scientometrics/Video
- Global warming/Video
- Sue Savage-Rumbaugh/Video
- Doctor Who (1960s-1990s)/Video
- Doctor Who (2000s-)/Video
- Spiel/Video
- ASIMO/Video
- Intelligence (biology)/Video
- Article-level metrics/Video
- Cosmology/Video
- Research peer review/Video
- Magnetic field/Video
- Saturn (planet)/Video
- Brain plasticity/Video
- Prisoner's dilemma/Video
- Universe/Video
- Jupiter (planet)/Video
- Stroke/Video
- Telemedicine/Video
- Autism/Video
References to CharInsert
References to <ref>
- Aristotle
- Agriculture
- Albert Einstein
- Archaea
- Acupuncture
- Augustine of Hippo
- Amphetamine -- two references do not have proper backpointers on both the live and test wiki
- Biology
- Brain
- Bacteria
- Book
References to ImageMap
- United States of America
- Kingdom (biology)
- Template talk:Elem Infobox
- Bolognese sauce
- Species (biology)
- Origins and architecture of the Taj Mahal
- Taxon
- CZ:Citizen/V1-N4
- CZ:How To
- CZ Talk:How To
- Template talk:Periodic
- Gyrification
- Talk:Chief of Naval Operations
- Taxonomy
- Music perception
- Template:Biology open house
- Genus (biology)
- Template:CEC
References to InputBox
- CZ:Start Article
- CZ:Eduzendium
- CZ:Start article with subpages
- CZ Talk:Start article with subpages
- CZ:Templates
- CZ:Userinfo System
- CZ Talk:Sp08UniversityofColoradoatBoulderANTH4110HumanEvolutionaryBiology
- Template:Infobox/doc
- CZ:POL 214: US Political Parties and Interest Groups/Article starter
- Template:R EZ
References to ParserFunctions
#exp
#if
#ifeq
- Template:CategoryTOC
- Template:Cite book
- Template:Editor list
- Template:Workgroup
- Template:ToApprove
- Template:Taxobox
- Template:Disambig
- Talk:United Kingdom
#iferror
No References.
#ifexpr
- Template:MONTHNUMBER
- Template:AddDays/LeadZero
- Template talk:Subpage style
- Template:CC
- Template:Licence box
- Template:Featured Article Candidate
- Template:Precision
#ifexist
#rel2abs
No References.
#switch
- Template:Tableheader
- MediaWiki:Category header
- Template:Taxobox
- Template:MONTHNAME
- Template:MONTHNUMBER
- Template:Nbsp
- Template:Checklist
#time
#timel
No References.
#titleparts
No References.
References to Timeline
- Joan of Arc/Timelines
- Civil society/Timelines
- Theodor Lohmann/Timelines
- Electric motor/Timelines
- Origins and architecture of the Taj Mahal/Timelines
- Pseudoscience/Timelines
References to TreeAndMenu
{{#tree}}
- CZ Talk:Extensions/Treeview extension
- CZ Talk:Anthropology Workgroup/Priority list
- CZ:Personal Galleries
{{#menu:
- Root1
- Sub-item
- Another sub-item
- Root2
- Sub-item
- Another sub-item
}}
References to Wikihiero
<hiero> D:d-=i-=n -Sms-w-A1 -i-q:r:Y1 -w-DA-A-Y1 -! -ib*Z1:=V31A -HAt:a-A1 -m-a:V31A -pH:D54-=n:=n:=Z2 -! -Xn:n-nw-w-pr -Ssp:p-a -x:r-p*W:xt -! -H-A25-A24 -mn:n-i-t-P11-xt -HAt:t*t-W -r:a:t -! -Hr:Z1 -tA:Z1*N23 -r:a -H-V31A:n-nw:W-A2 -nTr -dwA-! -A30-A2 -z:A1*Z1 -nb -Hr:Z1 -H-p:t-D32:a -sn-n:nw-w-A1-=y:=f -! -iz-w:t-A1-Z2-=t:=n:=Z2 -ii-i-t:D54 -aD:d-t:Y1 -D35:n -! -n:h-w-wr:=n -mSa-A1:Z2-=n:=Z2 -pH:D54-=n:=n:=Z2 -! -pH-w-y -wA-wA-t:xAst -z:n-X5:D54-=n:=n:=Z2 -! -z:n-mwt-t:xAst -m-a:V31A -r:f -n:Z2 -ii-i-D54-=n:=Z2 -! -m -Htp:t-p:Y1 -tA:N23*Z1-=n:=Z2 -pH:D54-=n:=Z2 -sw-W -! -sDm-m -r:V31A -n:=A1 -HAt:a-A1 -nw:V31A-A1 -Sw-W:wr -! -HA-A-w-Y1:Z2 -i-a:mw -a:t*W -i-im-m-a -! -mw -Hr:Z1 -D50-Z2:=V31A -i-x:Y1 -w-S-b-A2-=V31A -! -w-Sd:d:t-A2-=V31A -md-d-w-A2:=V31A -n -! -sw-t:n-G7 -ib*Z1:=V31A -m-a:=V31A -w-S-! -b-A2-=V31A -D35:n -n -i-t-i-t-A2 -i-w -r:Z1 :n -z:A1*Z1 -! -n:N42-m-a:=f -sw-w -i-w -md-d-w-! -A2-=f -a:=f -TA-A-m-S28 -n:=f -Hr:Z1 -! -ir:r-=V31A -m -x:r-t:Y1:Z2 -ib*Z1:=V31A -s-wr-! -r:d-G37 -p:W -D:d -n:=V31A -s-D:d-=A1 -r:f -! -n:=V31A -mi-i-t*t:Y1 -i-r:y -xpr:r -m-a-=A1 -! -D:z-=A1 -..-Sm-m-D54:=V31A-=w-=A1 -r -b-i-! -id:Hw-xAst -n -sAq:sAq-G7 -h-A-! -D54:=V31A-=w-=A1 -r -M14-wr:r-S -m -d:p*t-P1 -! -n:t -mH:a -V1-mD:mD -m -Aw-W-=s -mH:a -mD:mD-mD:mD -m -s-x-! -w-iab-=s -s-qd-d-A30-A1 -V1-V20:V20 -i-m-=s -! -m -stp:Y1 -n -km-m-t:niwt -mA:ir-A-=s-=n:=Z2 -! -p*t:pt -mA:ir-A-=s-=n:=Z2 -tA:N23*Z1 -m-a:V31A-A-a -! -ib:Z1-=s-=n:=Z2 -r -mA:ir-A-w-F27:Z2 -z:r-! -E27-A2-=s-=n:=3 -D:a-TAw -D35 -ii-i-t:D54 -n:S-! -n:y-E20-A24 -D35 -xpr:r-t:=f -D:a-TAw -pr:r-D54 -! -i-w-=n:=3 -m -M14-wr:r-S -tp:Z1 -a:Z1 -! -sAH-Y1-=n:=3 -tA:N23*Z1 -f-A-t-A9-a -TAw-w -! -ir:=f -wHm-m-i-i-t-A2 -n:U19-nw-W-i-i-t-mw -! -i-m-=f -n:t -mH:a -Z1:Z1-Z1:Z1-Z1:Z1-Z1:Z1 -i-n -xt:t*Z1 -H-H-! -A25-A24 -n-=A1 -s -aHa-a:=n -d:p*t-P1 -! -m-t:Z6 -n:t-tyw-Z2 -i-m-=s -D35 -z:p-zp -! -wa:a-A1-Z1 -i-m -aHa-a:=n-=A1 -r:a-=V31A-=w-=A1 -! -r -iw:N23*Z1 -i-n -wA-A-w-mw -n -M14-! -wr:r-S -ir:=n-=A1 -h:r-w-ra -Z1-Z1-Z1 -wa:a-Z1-wr-=k\:=W-=A1 -! -ib:Z1-=A1 -m -sn-n:nw-w-A1-Z1-Z1-=A1 -z:Dr:r-A55-=V31A-! -=w-=A1 -m -Xn:n-nw*W:pr -n -V31A-A-p-! -Aa19-pr -n -xt:t*Z1 -q:n-i-D32:a-=n-=A1 -Sw-W-! -i-i-t:ra -aHa-a:=n -d-wn:n-D54-=n-=A1 -r:d-! -D56-D56-=A1 -r -r:x-Y1 -a:t-=A1 -m -r:Z1-=A1 -! -gm-m-=n-=A1 -d-A-b-M43-N33:Z2 -i-A-! -r:r-t:D5-N33:Z2 -i-m -i-A-q:t-Hn-Z3A -nb:t -Sps-s-t:Y1 -! -V31A-A-w-N33:Z2 -i-m -H-n:a -n:q-w-t-N33:Z2 -! -Ssp-p:t-N33:Z2 -mi-i-ir:t-=s -r-m-W-K5:Z2 -! -i-m -H-n:a -A-p:d-w-zA:Z2 -D35:n -n:t*t -! -D35:n -s-t -m -Xn:n-nw-w-pr:=f -aHa-a:=n -! -s-s-Aa18-A-A2-=n -w-A1 -r:a-=n-=A1 -r -tA:N23*Z1 -! -n -wr:r -Hr:Z1 -a:Z1-w-y-=A1 -! -Sd:d-t:a-=A1 -DA-A-Z9:xt -s-xpr-r:=n-=A1 -x:t-Q7 -ir:=n-=A1 -! -zb:wr -n :Z9*t-Q7 -n -nTr-Z1:Z2 -aHa-a:=n -F21-m-=n:=A1 -! -x:r-P8-E23-w-A2 -q:r-i-E21-A24 -i-b-! -E8-=V31A-=w-=A1 -wA-A-w-mw -p:W -! -n -M14-wr-r:N36 -xt:t*Z1:Z2 -Hr-Z1 -gm-m-gm-m-Z9 -! -tA:N23*Z1 -Hr-Z1 -mn:n-mn:n-D54 -V31A:f-S28-=n:=A1 -! -Hr-Z1-=A1 -gm-m-=n-=A1 -H-f-A-w-I15 -! -p-w -i-w-=f :m-ii-i-t:D54 -n:ns-sw-W -! -V22:a -V20*V20:V20 -x-b-z:w-t:Sny-=f -wr:r-=s -! -r :mH-a :Z1*Z1 -H-a:F51-Z2:=f -z:x:r-w-T11-A24 -! -m -nbw:N33:Z2 -i-K1:n-D13:y-=f:=y -m -x-s-b-d:N33:Z2 -! -mA:Aa11:a-H2:Y1 -a:r:q-V12:Y1 -sw-w -r -xnt-n:t -! -$r-i-w -wp:p-Z9:=n:=f -$b-r*Z1:=f -r:=A1 -i-W:=A1 -! -Hr-Z1 -X:t*Z1-=A1 -m-b-bA-A-H-D53:Y1-=f -! -D:d-=f :n-=A1 -n-m:a -ini-n :t*w -zp :Z1*Z1 -n:D-z:wr-A1 -! -n-m:a -ini-n :t*w -i-r -w-d:f-gb-D54-! -=V31A :m-D:d -n:=A1 -ini-n :t*w -r -iw:N23*Z1 -p:n -! -r:a-=A1 -r:x-Y1:=V31A -t-w -i-w-=V31A :m -z:z-Q7 -! -xpr-r-t -m -n:t*y :D35 -mA:ir-A-t :f -i-W -md:d-! -w-A2-=V31A -n:=A1 -D35:n -w-A1 -Hr-Z1 -F21-m-=A1 -! -s-t -i-w-=A1 -m -b-bA-A-H-D53-Y1:=V31A -! -x:m-D35:=n -w-A1 -aHa-a:=n -r:a-=f -w-A1 -m-r*Z1:=f -! -iTi:t-A24-=f -w-A1 -r -st-t*pr:=f -! -n:t -s-nDm-m-Xrd -wA-A-H-wAH-! -A24-=f -w-A1 -D35:n -d-mi-i-t:a-=A1 -w-DA-! -A-Y1:=V31A-=w-=A1 -D35:n -iTi:t*t-A24 -i-m-=A1 -! -$r-i-w -wp:p-Z9:=n:=f -$b-r*Z1:=f -r-=A1 -i-w-=A1 -! -Hr-Z1 -X:t*Z1-=A1 -m -b-bA-A-H-D53:Y1-=f -! -aHa-a:n -D:d-=n:=f -n:=A1 -n-m:a -ini-n :t*W -zp -Z1*Z1 -! -n:D:z-wr-A1 -n-m:a -ini-n :t*w -r -iw:N23*Z1 -p:n -! -n -M14-wr:r-N36 -n:t*y -Aa13:Z1-=f:=y -m -n:U19-nw-W-! -i-i-mw -aHa-a:=n -w-S-b-Z9-A2-=n:=A1 -! -n:=f -s-t -a:Z1-w-y-i-i-=A1 -x-xA-A-m-D41 -! -m -b-bA-A-H-D53:Y1-=f -D:d-=A1 -n:=f -! -nw:V31A-A1 -p-w -h-A-D54-=V31A-=w-=A1 -! -r -b-i-N41:F18-N25 -m -wp:p-w-t:D54 -! -sAq:sAq-G7 -m-d:p*t-P1 -n:t -! -mH:a -V1-mD:mD -m -Aw-W-=s -mH:a -mD:mD-mD:mD -m -s-x:w-! -iab:Y1-=s -s-qd-d-A30-A1 -V1-V20:V20 -i-m-=s -! -m -s-t:p-w-U21:Y1 -n :km-m-t:niwt -! -mA:ir-A-=s-=n:=Z2 -p:t-pt -mA:ir-A-=s-=n:=Z2 -tA:N23*Z1 -! -m-a:V31A-A-A24 -ib-Z1-=s-=n:=Z2 -r -mA:ir-A-! -w-F27-Z2 -$r-z:r-E27-A2-=s-=n:=Z2 -$b-D:a:TAw -! -D35 -ii-i-t:D54-=f-n:S-n:y-E21 -D35 -xpr-r*t:=f -! -wa:W:a-A1-Z1 -i-m -nb -m-a:V31A-A-A24 -ib*Z1:=f -! -n:xt:x*t-A24 -a:Z1-=f :r -sn-n:nw-w-A1*Z1*Z1:=f -D35:n -! -w-x-xA-wr:A1 -m -Hr:r -ib-=s-=n:=Z2 -D:a-TAw -! -pr-r:D54 -i-w-=n:=Z2 -m -M14-wr-r:N36 -! -tp-Z1 -a-Z1 -D61-D54-=n:=3 -tA:N23*Z1 -f-A-t-A9-a -! -TAw-w -ir:=f -wHm-m-i-i-t-A2 -n:U19-nw-w-i-i-t-mw -! -i-m-=f -n:t -mH:a -Z1:Z1-Z1:Z1-Z1:Z1-Z1:Z1 -i-n -xt:t*Z1 -H-H-A19-a -! -n:=A1 -s -aHa-a:=n -d:p*t-P1 -m-t:Z6:=t -! -n:t-tyw-Z2 -i-m-=s -D35 :z-p:zp -wa:W:a-A1-Z1 -i-m -! -Hr-Z1 -x-x-x-=A1 -m-a:V31A -w-=A1 -r -gs*Z1:=V31A -! -$r-aHa-a:n -ini-n:=V31A-=w-=A1 -$b-r -iw:N23*Z1 -p:n -i-n -! -wA-A-w-mw-Z1 :n -M14-wr:r-N36 -! -D:d-=i-=n-=f :n-=A1 -m -G54-A2 -m -zp -Z1*Z1 -! -n:D-z:wr-A1 -m -A-t-w-A24 -Hr*Z1:=V31A -! -p-H-F22-=n:=V31A -w-A1 -m-a:V31A -nTr*Z1 -r:a-=n:=f -! -anx-n:x-=V31A -ini-n:=f -t-w -r -iw:N23*Z1 -p:n -n :D28*Z1 -! -D35:n -n:t:t -D35:n -s-t -m -Xn:n-nw-w-pr:=f -! -i-w-=f -mH:Y1 -Xr:r -nfr-f:r-t-Y1:Z2 -nb:t -! -m-a:V31A -t-w -r -ir:t -N11:N14-d:ra*Z1 -Hr-Z1 -! -N11:N14-d:ra*Z1 -r :km-m-t:Y1-=V31A -N11:N14-d:ra *Z1*Z1*Z1*Z1 -! -m -Xn:n-nw-w-pr :n -iw:N23*Z1 -p:n -i-w -! -d:p*t-P1 -r -ii-i-t:D54 -m -Xn:n-nw-w-pr -! -s-qd-d-w-A30-A1:Z2 -i-m-=s -r:x-Y1 :n-=V31A -! -++TXTEGsqdw im=s rx=w n=k +s -Sm-m-D54:=V31A -H-n:a-=s-=n:=Z2 -r -Xn:n-nw-w-pr -! -m-t:Z6-=V31A -m -niwt:t*Z1-=V31A -! -$r-r:S-D20-A2-w-y -$b-s-D:d-A2 -d:p*t-ns-A2-=n:=f -z:n-X5:D54 -x:t-Y1:Z2 -U23-m:r-wr -! -s-D:d-A2-=A1 -r:f -n:=V31A -mi-i-t:t-Y1 -i-r:y -xpr-r-w-m-iw-N23*Z1 -p:n -! -wn:n-=A1 -i-m-=f -H-n:a -sn-n:nw-w-A1*B1:Z2-=A1 -X:r-d-w-A17-A1*B1:Z2 -! -m -q-A-b-F46-=s-=n:=Z2 -km-m-Y1:n-=n:=Z2 -H-f-A-W-I15 -V20*V20*V20*V20:.*V20*V20*V20*.-Z1*Z1*Z1*Z1:.*Z1*Z1*Z1 *.-m -! -ms-s-w-A1*B1:Z2-=A1 -H-n:a -sn-n:nw-w-A1*B1:Z2-=A1 -D35:n -s-x-M12-A2-=A1 -n:=V31A -! -zA-t:B1 -V31A:t*t-wr:B1 -ini-n:t-=n:=A1 -m -z:M8-A-F5-Y1 -$r-aHa-a:n -s-b-A-N14-ra -$b-! -h-A-W-D54 -pr:r-D54:=n -n:A -m -x:t-Q7 -m-a:=f -xpr-r:=n -r-=s -D35:n -w-A1 -H-n:a -! -A-m-Q7-=n:=y -D35:n -w-A1 -m -Hr:r -ib-=s-=n:=Z2 -aHa-a:=n-=A1 -m-t:Z6-=V31A-=W-=A1 -n-=s-=n:=Z2 -gm-m-=n:=A1 -! -s-t -m -XA-A-i-i-t-Aa2:Z2 -wa:W-a:t*Z1 -i-r -q:n-A24-=n:=V31A -T12-A24 -ib-Z1-=V31A -! -mH:Y1-=V31A -q:n-i-D32-=V31A -m-A17-A1*B1:Z2-=V31A -s-n-D20-A2-=V31A -! -N41:t-B1-V31A -mA:ir-A-=V31A -pr-Z1-=V31A -nfr-f:r -s-t -r -x:t-Y1:Z2 -nb:t -! -p-H-pH-D54:=V31A -Xn:n-nw-w-pr -wn:n-=V31A -i-m-=f -! -m -q-A-b-F46:D54 -n -sn-n:nw-w-A1*B1:Z2-=V31A -wn:n-=V31A -r:f -! -d-mA-A-U32-Y1-=V31A-=W-=A1 -Hr-Z1 -X:t*Z1-=A1 -d-mi-i-D41:=n-=A1 -! -z:zA-A-t-w-N23:Z2 -m -b-bA-A-H-D53:Y1-=f -$r-D:d-=A1 -r:f -n:=V31A -$b-! -s-D:d-A2-=A1 -G30-Y1:Z2-=V31A :n -sAq-sAq-G7 -a:=A1 -z:S-A-Y1:=f -! -m -aA:a-A-Y1:=V31A -a:=A1 -ini-n:=t -n:=V31A -i-b-E8-i-Hnqt -H-V31A:n-nw:W-N33:Z2 -! -D54-w-d:n-b-N33:Z2 -X:z-A-i-i-t-N33:Z2 -sn-n:t-r-tr-N33:Z2 -n -Aa13*Z1:Z2 -pr:Z2 -! -s-Htp:t-p-w-Y1 -nTr-Z1 -nb -i-m-=f -s-D:d-=A1 -r:f -xpr-r:t-Y1:Z2 -! -Hr-Z1-=A1 -m -mA:ir-A-t:Z2:=n-=A1 -m -G30-Y1:=f -nTr-dwA-A-A30-=t-=w -n:=V31A -! -m -niwt:t*Z1 -x*t:f -Hr-Z1 -q:n-b-t-O38-A1:Z2 -tA:N23*Z1 -r -M36:r-=f -$r-z:f-t:T30-A24-=A1 -$b-! -n:=V31A -D52-E1-Z1:Z2 -m -zb-wr :n -Z9-t-Q7 -w-S:n-H1:a-n:=A1 -n:=V31A -! -A-p-d-w-zA:Z2 -a:=A1 -ini-n:=t -n:=V31A -H-a-w-P1:Z2 -A-t:p-w-A2-A24 -! -Xr:r -Sps-s-s-Y1:Z2 -nb :n -km-m-t-niwt:t*Z1 -mi-i -ir:r-t -n -nTr-Z1 -mr:r-r-A2 -! -r:T-A1*B1:Z2 -m -tA:N23*Z1 -wA-A-N31 -D35 -r:x-Y1 -sw-W -r-T-A1-B1-Z2 -! -$r-aHa-a:=n -s-b-t:F18-A2-=n:=f -i-m-=A1 -m -M22-M22 -D:d-=n:=A1 -$b-m-n:f-wr -m -ib-Z1-f -! -D:d-=f :n-=A1 -D35 -wr-r -n:=V31A -a:n-G4-W23:Z2 -xpr-r:t-nb-nTr-sn-n:t:r-M6-N33:Z2-! -nw:V31A-A1 -i-s -HqA-q-A-G7 -p-wn:n-t:N25 -a:n-G4-W23:Z2 -n:=A1 -i-m -sw-W -! -H-V31A:n-nw-W-N33:Z2 -p:f -D:d-=n:=V31A -ini-n:t:=f -b-w -p-W -wr-r :n -iw:N23*Z1 -p:n -! -xpr-r -i-s -E9-w-d:D54 -V31A -t-w -r -st-t:pr -t:n -D35 :z-p:zp -! -mA:ir-A-=V31A -iw:N23*Z1 -p:n -xpr-r -m -n:U19-nw:W-i-i-mw -$r-aHa-a:=n -d:p*t-P1 -t:f -$b-! -ii-i-t:D54 -mi-i -z:r*t-E27-A2-=n:=f -xnt-n:t -aHa-a:=n-=A1 -Sm-m-D54-=V31A-=W-=A1 -! -r:a-n :w-=A1 -Hr-Z1 -xt:t*Z1 -q-A-A28 -S32-A2-n :=A1 -n:t-G4-A1:Z2 -m-Xn-n:nw-W-pr-=s -! -aHa-a:=n -Sm-m-D54-=V31A-=w-=A1 -r -s-mi-i-t-A2 -s-t -gm-m-=n:=A1 -sw-W -r:x-Y1 -s-t -! -aHa-a:=n -D:d-=n:=f -n:=A1 -s-n:b-=t -zp :Z1*Z1 -n:D-z:wr-A1 -r-pr-Z1 -=V31A -mA:ir-A-=V31A -! -X:r-d-Xrd-A1*B1:Z2-=V31A -i-Aa13-m:a -r:n-=A1 -nfr-f:r -m -niwt:t*Z1-=V31A -m-a:V31A-Xr:r*t-Y1:Z2-=A1 -! -p-W -i-m-=V31A -! -aHa-a:=n -r:a-=n :w-A1 -Hr-Z1 -X:t*Z1-=A1 -a:Z1-w-y-=A1 -xA-A-m-A24 -m -b-bA-A-H-D53-Y1:=f -! -aHa-a:=n -r:a-=n:=f -n:=A1 -zb-b-t-Y1:Z2 -m -a:n-G4-W23:Z2 -H-V31A-n:nw*W-N33:Z2 -D54-w-d:n-b-N33:Z2 -! -X:z-Aa17-A-i-i-t-N33:Z2-U33 -Sps-s-N33:Z2 -SA-A-a:z-O47 -F31-s-d-m-t-N33:Z2 -s-d-w-M41:3 -! -nw-Z1 -m:a-m:a-F27 -U7:r-r-i-i-t-iw:Z2 -aA:a-A-t-Y1 -n:t -nTr-sn-n:t:r-M6-N33:Z2 -n:D-H-i-i-t-F18:Z2 -! -n:t -Ab-b-w-T19 -T:z-m-W-E14:Z2 -g-w-f-E33-Z3A -V31A-i-i-w-E32-Z3A -A50-s-s-Y1:Z2 -nb -nfr-f:r -! -$r-aHa-a:=n -A-t-p-A9-a:=n-=A1 -s-t -$b-r -d-p-t-P1 -t:n -xpr-r:n-r:a-=t-=w-=A1 -Hr-Z1 -X:t*Z1-=A1 -! -r -nTr-dwA-A-A30 -n:=f -aHa-a:=n -D:d-=n:=f -n:=A1 -m-a:V31A -t:W -r -spr:r-D54 -r-Xn-n:nw-W-pr -! -n :Abd-d:ra -Z1-Z1 -mH:Y1-=V31A -q:n-i-D32-=V31A -m -X:r-d-w-Xrd-A1*B1:Z2-=V31A -r-n:p-i-i-rnp-=V31A -! -m -Xn-n:nw-W-pr -q:r-s-t-Q6:a-=V31A -aHa-a:=n -h-A-D54-=V31A-=w-=A1 -r -mr:r-i-i-t-N23-Z1 -! -m -h-A-w-Y1:Z2 -d:p*t-P1 -t:n -aHa-a:=n-=A1 -Hr-Z1 -i-A-S-A2 -n -mSa-A1:Z2 -! -n:t*y -m -d:p*t-P1 -t:n -r:a-=n:=A1 -H-V31A:n-nw:W-A2 -Hr-Z1 -mr:r-i-i-t-N23-Z1 -n :nb-G7 -n -iw:N23*Z1 -p:n -! -n:t-G4-A1:Z2 -i-m-=s -r -mi-i-t:t-Y1 -i-r:y -$r-n:a-t-P1 -p:W -ir:=n-=n:=Z2 -$b-m -x-d-P1 -! -r -Xn-n:nw-w-pr :n -sAq-sAq-G7 -spr:r-D54-=n:=n-=Z2 :r-Xn-n:nw-W-pr -! -Hr-Z1 -Abd:dwA-d:ra -Z1-Z1 -mi-i -D:d-t:=n:=f -nb:t -aHa-a:=n -aq-q-D54-=V31A-=w-=A1 -Hr-Z1 -sAq-sAq-G7 -! -m:a-zb-D54-=n:=A1 -n:=f -ini-nw:Z2 -p:n -ini-n:=n-=A1 -m -Xn-n:nw-W-pr -n -iw:N23*Z1 -p:n -! -aHa-a:n -nTr-dwA-A-A30-=n:=f -n:=A1 -x*t:f -Hr-Z1 -q:n-b-t-O38-A1:Z2 -tA:N23*Z1 -r -Dr:r-=f -! -aHa-a:=n -r:a-=V31A-=w-A1 -r -Sms-W-A1 -! -s-Aa18-A-H-sAH-Y1:=V31A-=w-=A1 -m -! -tp-A1*B1:Z2-=f -mA:ir-A -w-A1 -r -! -Aa18-#b-Z1 -#e-s-Aa18-A-H-sAH:Y1-=A1 -tA:N23*Z1 -r -Aa18-Z1 -! -mA:ir-A-=A1 -d:p-t:F20-A2-=n:=A1 -sDm-m -r:=V31A -! -#b-n -r:Z1-#e-=A1 -m-a:V31A -nfr-f:r -sDm-m -n -r:T-A1*B1:Z2 -! -aHa-a:=n -D:d-=n:=f -n:=A1 -m -ir -i-q:r-Y1-A1 -! -x:n-T34-m-s-A21-A1 -i-n -m -r:a:t -mw -! -#b-n -A-#e-p:d-zA -HD-D:ra -tA:N23*Z1 -n:z:f-t-! -T31:a-=f -dwA-A-ra -! -D54-w-=f :p*W -HAt:t*Z1-=f -! -r-pH-=f:=y -mi-i -gm-m-i-i-t -m-zS-Y1 -! -#b-m -zS-Y1 -#e-zS-A1 -i-q:r:Y1 -n -Dba-Dba-Dba-=f -! -i-#b-mn:n-#e-i-i -zA -i-mn:n-aA:a-A-Y1-A1 -anx-DA-s -! -D36-Aa16-Z4-X1 -! </hiero>